Jim Van Verth | 2e5eaf0 | 2017-06-21 15:55:46 -0400 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2017 Google Inc. |
| 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license that can be |
| 5 | * found in the LICENSE file. |
| 6 | */ |
| 7 | |
| 8 | // This is a GPU-backend specific test. It relies on static intializers to work |
| 9 | |
Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 10 | #include "include/core/SkTypes.h" |
Jim Van Verth | 2e5eaf0 | 2017-06-21 15:55:46 -0400 | [diff] [blame] | 11 | |
Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 12 | #include "include/core/SkSurface.h" |
| 13 | #include "include/gpu/GrTexture.h" |
Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 14 | #include "src/gpu/GrContextPriv.h" |
| 15 | #include "src/gpu/GrGpu.h" |
| 16 | #include "src/gpu/GrResourceProvider.h" |
Greg Daniel | f91aeb2 | 2019-06-18 09:58:02 -0400 | [diff] [blame] | 17 | #include "src/gpu/GrSurfaceProxy.h" |
Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 18 | #include "src/gpu/SkGr.h" |
| 19 | #include "tests/Test.h" |
| 20 | #include "tools/gpu/GrContextFactory.h" |
Jim Van Verth | 2e5eaf0 | 2017-06-21 15:55:46 -0400 | [diff] [blame] | 21 | |
| 22 | using sk_gpu_test::GrContextFactory; |
| 23 | |
| 24 | void fill_transfer_data(int left, int top, int width, int height, int bufferWidth, |
| 25 | GrColor* data) { |
| 26 | |
| 27 | // build red-green gradient |
| 28 | for (int j = top; j < top + height; ++j) { |
| 29 | for (int i = left; i < left + width; ++i) { |
| 30 | unsigned int red = (unsigned int)(256.f*((i - left) / (float)width)); |
| 31 | unsigned int green = (unsigned int)(256.f*((j - top) / (float)height)); |
| 32 | data[i + j*bufferWidth] = GrColorPackRGBA(red - (red>>8), |
| 33 | green - (green>>8), 0xff, 0xff); |
| 34 | } |
| 35 | } |
| 36 | } |
| 37 | |
Brian Salomon | e05ba5a | 2019-04-08 11:59:07 -0400 | [diff] [blame] | 38 | bool do_buffers_contain_same_values(const GrColor* bufferA, |
| 39 | const GrColor* bufferB, |
| 40 | int width, |
| 41 | int height, |
| 42 | size_t rowBytesA, |
Brian Salomon | 42cbedd | 2019-04-09 15:00:05 -0400 | [diff] [blame] | 43 | size_t rowBytesB, |
| 44 | bool swiz) { |
Jim Van Verth | 2e5eaf0 | 2017-06-21 15:55:46 -0400 | [diff] [blame] | 45 | for (int j = 0; j < height; ++j) { |
| 46 | for (int i = 0; i < width; ++i) { |
Brian Salomon | 42cbedd | 2019-04-09 15:00:05 -0400 | [diff] [blame] | 47 | auto colorA = bufferA[i]; |
| 48 | if (swiz) { |
| 49 | colorA = GrColorPackRGBA(GrColorUnpackB(colorA), GrColorUnpackG(colorA), |
| 50 | GrColorUnpackR(colorA), GrColorUnpackA(colorA)); |
| 51 | } |
| 52 | if (colorA != bufferB[i]) { |
Jim Van Verth | 2e5eaf0 | 2017-06-21 15:55:46 -0400 | [diff] [blame] | 53 | return false; |
| 54 | } |
| 55 | } |
Brian Salomon | e05ba5a | 2019-04-08 11:59:07 -0400 | [diff] [blame] | 56 | bufferA = reinterpret_cast<const GrColor*>(reinterpret_cast<const char*>(bufferA) + |
| 57 | rowBytesA); |
| 58 | bufferB = reinterpret_cast<const GrColor*>(reinterpret_cast<const char*>(bufferB) + |
| 59 | rowBytesB); |
Jim Van Verth | 2e5eaf0 | 2017-06-21 15:55:46 -0400 | [diff] [blame] | 60 | } |
| 61 | return true; |
| 62 | } |
| 63 | |
Brian Salomon | e05ba5a | 2019-04-08 11:59:07 -0400 | [diff] [blame] | 64 | void basic_transfer_to_test(skiatest::Reporter* reporter, GrContext* context, GrColorType colorType, |
| 65 | bool renderTarget) { |
Robert Phillips | 9da87e0 | 2019-02-04 13:26:26 -0500 | [diff] [blame] | 66 | if (GrCaps::kNone_MapFlags == context->priv().caps()->mapBufferFlags()) { |
Brian Salomon | 7f56d3d | 2017-10-09 13:02:49 -0400 | [diff] [blame] | 67 | return; |
| 68 | } |
| 69 | |
Robert Phillips | 9da87e0 | 2019-02-04 13:26:26 -0500 | [diff] [blame] | 70 | auto resourceProvider = context->priv().resourceProvider(); |
| 71 | GrGpu* gpu = context->priv().getGpu(); |
Robert Phillips | 6be756b | 2018-01-16 15:07:54 -0500 | [diff] [blame] | 72 | |
Jim Van Verth | 2e5eaf0 | 2017-06-21 15:55:46 -0400 | [diff] [blame] | 73 | // set up the data |
| 74 | const int kTextureWidth = 16; |
| 75 | const int kTextureHeight = 16; |
Jim Van Verth | 3a74925 | 2018-12-07 10:57:26 -0500 | [diff] [blame] | 76 | #ifdef SK_BUILD_FOR_IOS |
| 77 | // UNPACK_ROW_LENGTH is broken on iOS so rowBytes needs to match data width |
Robert Phillips | 4217ea7 | 2019-01-30 13:08:28 -0500 | [diff] [blame] | 78 | const int kBufferWidth = GrBackendApi::kOpenGL == context->backend() ? 16 : 20; |
Jim Van Verth | 3a74925 | 2018-12-07 10:57:26 -0500 | [diff] [blame] | 79 | #else |
Jim Van Verth | 2e5eaf0 | 2017-06-21 15:55:46 -0400 | [diff] [blame] | 80 | const int kBufferWidth = 20; |
Jim Van Verth | 3a74925 | 2018-12-07 10:57:26 -0500 | [diff] [blame] | 81 | #endif |
Jim Van Verth | 2e5eaf0 | 2017-06-21 15:55:46 -0400 | [diff] [blame] | 82 | const int kBufferHeight = 16; |
| 83 | size_t rowBytes = kBufferWidth * sizeof(GrColor); |
| 84 | SkAutoTMalloc<GrColor> srcBuffer(kBufferWidth*kBufferHeight); |
| 85 | SkAutoTMalloc<GrColor> dstBuffer(kBufferWidth*kBufferHeight); |
| 86 | |
| 87 | fill_transfer_data(0, 0, kTextureWidth, kTextureHeight, kBufferWidth, srcBuffer.get()); |
| 88 | |
| 89 | // create and fill transfer buffer |
| 90 | size_t size = rowBytes*kBufferHeight; |
Brian Salomon | dbf7072 | 2019-02-07 11:31:24 -0500 | [diff] [blame] | 91 | sk_sp<GrGpuBuffer> buffer(resourceProvider->createBuffer(size, GrGpuBufferType::kXferCpuToGpu, |
| 92 | kDynamic_GrAccessPattern)); |
Jim Van Verth | 2e5eaf0 | 2017-06-21 15:55:46 -0400 | [diff] [blame] | 93 | if (!buffer) { |
| 94 | return; |
| 95 | } |
| 96 | |
| 97 | void* data = buffer->map(); |
| 98 | memcpy(data, srcBuffer.get(), size); |
| 99 | buffer->unmap(); |
| 100 | |
Brian Salomon | c320b15 | 2018-02-20 14:05:36 -0500 | [diff] [blame] | 101 | for (auto srgbEncoding : {GrSRGBEncoded::kNo, GrSRGBEncoded::kYes}) { |
| 102 | // create texture |
| 103 | GrSurfaceDesc desc; |
| 104 | desc.fFlags = renderTarget ? kRenderTarget_GrSurfaceFlag : kNone_GrSurfaceFlags; |
Brian Salomon | c320b15 | 2018-02-20 14:05:36 -0500 | [diff] [blame] | 105 | desc.fWidth = kTextureWidth; |
| 106 | desc.fHeight = kTextureHeight; |
| 107 | desc.fConfig = GrColorTypeToPixelConfig(colorType, srgbEncoding); |
| 108 | desc.fSampleCnt = 1; |
Jim Van Verth | 2e5eaf0 | 2017-06-21 15:55:46 -0400 | [diff] [blame] | 109 | |
Brian Salomon | c320b15 | 2018-02-20 14:05:36 -0500 | [diff] [blame] | 110 | if (kUnknown_GrPixelConfig == desc.fConfig) { |
| 111 | SkASSERT(GrSRGBEncoded::kYes == srgbEncoding); |
| 112 | continue; |
| 113 | } |
Jim Van Verth | 2e5eaf0 | 2017-06-21 15:55:46 -0400 | [diff] [blame] | 114 | |
Robert Phillips | 9da87e0 | 2019-02-04 13:26:26 -0500 | [diff] [blame] | 115 | if (!context->priv().caps()->isConfigTexturable(desc.fConfig) || |
| 116 | (renderTarget && !context->priv().caps()->isConfigRenderable(desc.fConfig))) { |
Brian Salomon | c320b15 | 2018-02-20 14:05:36 -0500 | [diff] [blame] | 117 | continue; |
| 118 | } |
Jim Van Verth | 2e5eaf0 | 2017-06-21 15:55:46 -0400 | [diff] [blame] | 119 | |
Robert Phillips | 9313aa7 | 2019-04-09 18:41:27 -0400 | [diff] [blame] | 120 | sk_sp<GrTexture> tex = resourceProvider->createTexture( |
| 121 | desc, SkBudgeted::kNo, GrResourceProvider::Flags::kNoPendingIO); |
Robert Phillips | 6fc3092 | 2018-07-27 12:21:37 -0400 | [diff] [blame] | 122 | if (!tex) { |
| 123 | continue; |
| 124 | } |
Robert Phillips | 16d8ec6 | 2017-07-27 16:16:25 -0400 | [diff] [blame] | 125 | |
Brian Salomon | c320b15 | 2018-02-20 14:05:36 -0500 | [diff] [blame] | 126 | ////////////////////////// |
| 127 | // transfer full data |
Jim Van Verth | 2e5eaf0 | 2017-06-21 15:55:46 -0400 | [diff] [blame] | 128 | |
Brian Salomon | c320b15 | 2018-02-20 14:05:36 -0500 | [diff] [blame] | 129 | bool result; |
Brian Salomon | e05ba5a | 2019-04-08 11:59:07 -0400 | [diff] [blame] | 130 | result = gpu->transferPixelsTo(tex.get(), 0, 0, kTextureWidth, kTextureHeight, colorType, |
| 131 | buffer.get(), 0, rowBytes); |
Brian Salomon | c320b15 | 2018-02-20 14:05:36 -0500 | [diff] [blame] | 132 | REPORTER_ASSERT(reporter, result); |
Jim Van Verth | 2e5eaf0 | 2017-06-21 15:55:46 -0400 | [diff] [blame] | 133 | |
Brian Salomon | c320b15 | 2018-02-20 14:05:36 -0500 | [diff] [blame] | 134 | memset(dstBuffer.get(), 0xCDCD, size); |
Brian Salomon | a694870 | 2018-06-01 15:33:20 -0400 | [diff] [blame] | 135 | result = gpu->readPixels(tex.get(), 0, 0, kTextureWidth, kTextureHeight, colorType, |
Brian Salomon | c320b15 | 2018-02-20 14:05:36 -0500 | [diff] [blame] | 136 | dstBuffer.get(), rowBytes); |
| 137 | if (result) { |
Brian Salomon | e05ba5a | 2019-04-08 11:59:07 -0400 | [diff] [blame] | 138 | REPORTER_ASSERT(reporter, do_buffers_contain_same_values(srcBuffer, |
| 139 | dstBuffer, |
| 140 | kTextureWidth, |
| 141 | kTextureHeight, |
| 142 | rowBytes, |
Brian Salomon | 42cbedd | 2019-04-09 15:00:05 -0400 | [diff] [blame] | 143 | rowBytes, |
| 144 | false)); |
Brian Salomon | c320b15 | 2018-02-20 14:05:36 -0500 | [diff] [blame] | 145 | } |
Jim Van Verth | 2e5eaf0 | 2017-06-21 15:55:46 -0400 | [diff] [blame] | 146 | |
Brian Salomon | c320b15 | 2018-02-20 14:05:36 -0500 | [diff] [blame] | 147 | ////////////////////////// |
| 148 | // transfer partial data |
Jim Van Verth | 3a74925 | 2018-12-07 10:57:26 -0500 | [diff] [blame] | 149 | #ifdef SK_BUILD_FOR_IOS |
| 150 | // UNPACK_ROW_LENGTH is broken on iOS so we can't do partial transfers |
Robert Phillips | 4217ea7 | 2019-01-30 13:08:28 -0500 | [diff] [blame] | 151 | if (GrBackendApi::kOpenGL == context->backend()) { |
Jim Van Verth | 3a74925 | 2018-12-07 10:57:26 -0500 | [diff] [blame] | 152 | continue; |
| 153 | } |
| 154 | #endif |
Brian Salomon | c320b15 | 2018-02-20 14:05:36 -0500 | [diff] [blame] | 155 | const int kLeft = 2; |
| 156 | const int kTop = 10; |
| 157 | const int kWidth = 10; |
| 158 | const int kHeight = 2; |
| 159 | |
| 160 | // change color of subrectangle |
| 161 | fill_transfer_data(kLeft, kTop, kWidth, kHeight, kBufferWidth, srcBuffer.get()); |
| 162 | data = buffer->map(); |
| 163 | memcpy(data, srcBuffer.get(), size); |
| 164 | buffer->unmap(); |
| 165 | |
| 166 | size_t offset = sizeof(GrColor) * (kTop * kBufferWidth + kLeft); |
Brian Salomon | e05ba5a | 2019-04-08 11:59:07 -0400 | [diff] [blame] | 167 | result = gpu->transferPixelsTo(tex.get(), kLeft, kTop, kWidth, kHeight, colorType, |
| 168 | buffer.get(), offset, rowBytes); |
Brian Salomon | c320b15 | 2018-02-20 14:05:36 -0500 | [diff] [blame] | 169 | REPORTER_ASSERT(reporter, result); |
| 170 | |
| 171 | memset(dstBuffer.get(), 0xCDCD, size); |
Brian Salomon | a694870 | 2018-06-01 15:33:20 -0400 | [diff] [blame] | 172 | result = gpu->readPixels(tex.get(), 0, 0, kTextureWidth, kTextureHeight, colorType, |
Brian Salomon | c320b15 | 2018-02-20 14:05:36 -0500 | [diff] [blame] | 173 | dstBuffer.get(), rowBytes); |
| 174 | if (result) { |
Brian Salomon | e05ba5a | 2019-04-08 11:59:07 -0400 | [diff] [blame] | 175 | REPORTER_ASSERT(reporter, do_buffers_contain_same_values(srcBuffer, |
| 176 | dstBuffer, |
| 177 | kTextureWidth, |
| 178 | kTextureHeight, |
| 179 | rowBytes, |
Brian Salomon | 42cbedd | 2019-04-09 15:00:05 -0400 | [diff] [blame] | 180 | rowBytes, |
| 181 | false)); |
Brian Salomon | c320b15 | 2018-02-20 14:05:36 -0500 | [diff] [blame] | 182 | } |
Jim Van Verth | 52fb02e | 2017-06-27 10:36:56 -0400 | [diff] [blame] | 183 | } |
Jim Van Verth | 2e5eaf0 | 2017-06-21 15:55:46 -0400 | [diff] [blame] | 184 | } |
| 185 | |
Brian Salomon | 42cbedd | 2019-04-09 15:00:05 -0400 | [diff] [blame] | 186 | void basic_transfer_from_test(skiatest::Reporter* reporter, const sk_gpu_test::ContextInfo& ctxInfo, |
Brian Salomon | e05ba5a | 2019-04-08 11:59:07 -0400 | [diff] [blame] | 187 | GrColorType colorType, bool renderTarget) { |
Brian Salomon | 42cbedd | 2019-04-09 15:00:05 -0400 | [diff] [blame] | 188 | auto context = ctxInfo.grContext(); |
Brian Salomon | e05ba5a | 2019-04-08 11:59:07 -0400 | [diff] [blame] | 189 | if (GrCaps::kNone_MapFlags == context->priv().caps()->mapBufferFlags()) { |
| 190 | return; |
| 191 | } |
Jim Van Verth | 686046b | 2019-03-18 15:39:22 -0400 | [diff] [blame] | 192 | |
Brian Salomon | 42cbedd | 2019-04-09 15:00:05 -0400 | [diff] [blame] | 193 | // On OpenGL ES it may not be possible to read back in to BGRA becagse GL_RGBA/GL_UNSIGNED_BYTE |
| 194 | // may be the only allowed format/type params to glReadPixels. So read back into GL_RGBA. |
| 195 | // TODO(bsalomon): Make this work in GrGLGpu. |
| 196 | auto readColorType = colorType; |
| 197 | if (GrColorType::kBGRA_8888 == colorType && |
| 198 | ctxInfo.type() == sk_gpu_test::GrContextFactory::kGLES_ContextType) { |
| 199 | readColorType = GrColorType::kRGBA_8888; |
| 200 | } |
| 201 | |
Brian Salomon | e05ba5a | 2019-04-08 11:59:07 -0400 | [diff] [blame] | 202 | auto resourceProvider = context->priv().resourceProvider(); |
| 203 | GrGpu* gpu = context->priv().getGpu(); |
Jim Van Verth | 2e5eaf0 | 2017-06-21 15:55:46 -0400 | [diff] [blame] | 204 | |
Brian Salomon | e05ba5a | 2019-04-08 11:59:07 -0400 | [diff] [blame] | 205 | const int kTextureWidth = 16; |
| 206 | const int kTextureHeight = 16; |
| 207 | |
| 208 | // We'll do a full texture read into the buffer followed by a partial read. These values |
| 209 | // describe the partial read subrect. |
| 210 | const int kPartialLeft = 2; |
| 211 | const int kPartialTop = 10; |
| 212 | const int kPartialWidth = 10; |
| 213 | const int kPartialHeight = 2; |
| 214 | |
Brian Salomon | 26de56e | 2019-04-10 12:14:26 -0400 | [diff] [blame] | 215 | size_t bpp = GrColorTypeBytesPerPixel(readColorType); |
| 216 | size_t fullBufferRowBytes = kTextureWidth * bpp; |
| 217 | size_t partialBufferRowBytes = kPartialWidth * bpp; |
| 218 | size_t offsetAlignment = context->priv().caps()->transferFromOffsetAlignment(readColorType); |
| 219 | SkASSERT(offsetAlignment); |
Brian Salomon | e05ba5a | 2019-04-08 11:59:07 -0400 | [diff] [blame] | 220 | |
| 221 | size_t bufferSize = fullBufferRowBytes * kTextureHeight; |
| 222 | // Arbitrary starting offset for the partial read. |
Brian Salomon | 26de56e | 2019-04-10 12:14:26 -0400 | [diff] [blame] | 223 | size_t partialReadOffset = GrSizeAlignUp(11, offsetAlignment); |
| 224 | bufferSize = SkTMax(bufferSize, partialReadOffset + partialBufferRowBytes * kPartialHeight); |
Brian Salomon | e05ba5a | 2019-04-08 11:59:07 -0400 | [diff] [blame] | 225 | |
| 226 | sk_sp<GrGpuBuffer> buffer(resourceProvider->createBuffer( |
| 227 | bufferSize, GrGpuBufferType::kXferGpuToCpu, kDynamic_GrAccessPattern)); |
| 228 | REPORTER_ASSERT(reporter, buffer); |
| 229 | if (!buffer) { |
| 230 | return; |
| 231 | } |
| 232 | |
| 233 | int expectedTransferCnt = 0; |
| 234 | gpu->stats()->reset(); |
| 235 | for (auto srgbEncoding : {GrSRGBEncoded::kNo, GrSRGBEncoded::kYes}) { |
| 236 | // create texture |
| 237 | GrSurfaceDesc desc; |
| 238 | desc.fFlags = renderTarget ? kRenderTarget_GrSurfaceFlag : kNone_GrSurfaceFlags; |
| 239 | desc.fWidth = kTextureWidth; |
| 240 | desc.fHeight = kTextureHeight; |
| 241 | desc.fConfig = GrColorTypeToPixelConfig(colorType, srgbEncoding); |
| 242 | desc.fSampleCnt = 1; |
| 243 | |
| 244 | if (kUnknown_GrPixelConfig == desc.fConfig) { |
| 245 | SkASSERT(GrSRGBEncoded::kYes == srgbEncoding); |
| 246 | continue; |
| 247 | } |
| 248 | |
| 249 | if (!context->priv().caps()->isConfigTexturable(desc.fConfig) || |
| 250 | (renderTarget && !context->priv().caps()->isConfigRenderable(desc.fConfig))) { |
| 251 | continue; |
| 252 | } |
| 253 | |
| 254 | SkAutoTMalloc<GrColor> textureData(kTextureWidth * kTextureHeight); |
| 255 | size_t textureDataRowBytes = kTextureWidth * sizeof(GrColor); |
| 256 | fill_transfer_data(0, 0, kTextureWidth, kTextureHeight, kTextureWidth, textureData.get()); |
| 257 | GrMipLevel data; |
| 258 | data.fPixels = textureData.get(); |
| 259 | data.fRowBytes = kTextureWidth * sizeof(GrColor); |
| 260 | sk_sp<GrTexture> tex = resourceProvider->createTexture(desc, SkBudgeted::kNo, &data, 1); |
| 261 | if (!tex) { |
| 262 | continue; |
| 263 | } |
| 264 | |
| 265 | ////////////////////////// |
| 266 | // transfer full data |
Brian Salomon | 26de56e | 2019-04-10 12:14:26 -0400 | [diff] [blame] | 267 | bool result = gpu->transferPixelsFrom(tex.get(), 0, 0, kTextureWidth, kTextureHeight, |
| 268 | readColorType, buffer.get(), 0); |
| 269 | if (!result) { |
| 270 | ERRORF(reporter, "transferPixelsFrom failed."); |
Brian Salomon | e05ba5a | 2019-04-08 11:59:07 -0400 | [diff] [blame] | 271 | continue; |
| 272 | } |
| 273 | ++expectedTransferCnt; |
| 274 | |
Greg Daniel | e6bfb7d | 2019-04-17 15:26:11 -0400 | [diff] [blame] | 275 | GrFlushInfo flushInfo; |
| 276 | flushInfo.fFlags = kSyncCpu_GrFlushFlag; |
Brian Salomon | 105d7c2 | 2019-04-16 13:46:14 -0400 | [diff] [blame] | 277 | if (context->priv().caps()->mapBufferFlags() & GrCaps::kAsyncRead_MapFlag) { |
Greg Daniel | 797efca | 2019-05-09 14:04:20 -0400 | [diff] [blame] | 278 | gpu->finishFlush(nullptr, 0, SkSurface::BackendSurfaceAccess::kNoAccess, flushInfo, |
| 279 | GrPrepareForExternalIORequests()); |
Brian Salomon | 105d7c2 | 2019-04-16 13:46:14 -0400 | [diff] [blame] | 280 | } |
Brian Salomon | e05ba5a | 2019-04-08 11:59:07 -0400 | [diff] [blame] | 281 | |
| 282 | const auto* map = reinterpret_cast<const GrColor*>(buffer->map()); |
| 283 | REPORTER_ASSERT(reporter, map); |
| 284 | if (!map) { |
| 285 | continue; |
| 286 | } |
| 287 | REPORTER_ASSERT(reporter, do_buffers_contain_same_values(textureData.get(), |
| 288 | map, |
| 289 | kTextureWidth, |
| 290 | kTextureHeight, |
| 291 | textureDataRowBytes, |
Brian Salomon | 26de56e | 2019-04-10 12:14:26 -0400 | [diff] [blame] | 292 | fullBufferRowBytes, |
Brian Salomon | 42cbedd | 2019-04-09 15:00:05 -0400 | [diff] [blame] | 293 | readColorType != colorType)); |
Brian Salomon | e05ba5a | 2019-04-08 11:59:07 -0400 | [diff] [blame] | 294 | buffer->unmap(); |
| 295 | |
Brian Salomon | 42cbedd | 2019-04-09 15:00:05 -0400 | [diff] [blame] | 296 | /////////////////////// |
Brian Salomon | e05ba5a | 2019-04-08 11:59:07 -0400 | [diff] [blame] | 297 | // Now test a partial read at an offset into the buffer. |
Brian Salomon | 26de56e | 2019-04-10 12:14:26 -0400 | [diff] [blame] | 298 | result = gpu->transferPixelsFrom(tex.get(), kPartialLeft, kPartialTop, kPartialWidth, |
| 299 | kPartialHeight, readColorType, buffer.get(), |
| 300 | partialReadOffset); |
| 301 | if (!result) { |
| 302 | ERRORF(reporter, "transferPixelsFrom failed."); |
Brian Salomon | e05ba5a | 2019-04-08 11:59:07 -0400 | [diff] [blame] | 303 | continue; |
| 304 | } |
| 305 | ++expectedTransferCnt; |
| 306 | |
Brian Salomon | 105d7c2 | 2019-04-16 13:46:14 -0400 | [diff] [blame] | 307 | if (context->priv().caps()->mapBufferFlags() & GrCaps::kAsyncRead_MapFlag) { |
Greg Daniel | 797efca | 2019-05-09 14:04:20 -0400 | [diff] [blame] | 308 | gpu->finishFlush(nullptr, 0, SkSurface::BackendSurfaceAccess::kNoAccess, flushInfo, |
| 309 | GrPrepareForExternalIORequests()); |
Brian Salomon | 105d7c2 | 2019-04-16 13:46:14 -0400 | [diff] [blame] | 310 | } |
Brian Salomon | e05ba5a | 2019-04-08 11:59:07 -0400 | [diff] [blame] | 311 | |
| 312 | map = reinterpret_cast<const GrColor*>(buffer->map()); |
| 313 | REPORTER_ASSERT(reporter, map); |
| 314 | if (!map) { |
| 315 | continue; |
| 316 | } |
| 317 | const GrColor* textureDataStart = reinterpret_cast<const GrColor*>( |
| 318 | reinterpret_cast<const char*>(textureData.get()) + |
| 319 | textureDataRowBytes * kPartialTop + sizeof(GrColor) * kPartialLeft); |
| 320 | const GrColor* bufferStart = reinterpret_cast<const GrColor*>( |
| 321 | reinterpret_cast<const char*>(map) + partialReadOffset); |
| 322 | REPORTER_ASSERT(reporter, do_buffers_contain_same_values(textureDataStart, |
| 323 | bufferStart, |
| 324 | kPartialWidth, |
| 325 | kPartialHeight, |
| 326 | textureDataRowBytes, |
Brian Salomon | 26de56e | 2019-04-10 12:14:26 -0400 | [diff] [blame] | 327 | partialBufferRowBytes, |
Brian Salomon | 42cbedd | 2019-04-09 15:00:05 -0400 | [diff] [blame] | 328 | readColorType != colorType)); |
Brian Salomon | e05ba5a | 2019-04-08 11:59:07 -0400 | [diff] [blame] | 329 | buffer->unmap(); |
| 330 | } |
| 331 | #if GR_GPU_STATS |
| 332 | REPORTER_ASSERT(reporter, gpu->stats()->transfersFromSurface() == expectedTransferCnt); |
| 333 | #else |
| 334 | (void)expectedTransferCnt; |
| 335 | #endif |
Jim Van Verth | 2e5eaf0 | 2017-06-21 15:55:46 -0400 | [diff] [blame] | 336 | } |
Jim Van Verth | 686046b | 2019-03-18 15:39:22 -0400 | [diff] [blame] | 337 | |
Brian Salomon | e05ba5a | 2019-04-08 11:59:07 -0400 | [diff] [blame] | 338 | DEF_GPUTEST_FOR_RENDERING_CONTEXTS(TransferPixelsToTest, reporter, ctxInfo) { |
| 339 | if (!ctxInfo.grContext()->priv().caps()->transferBufferSupport()) { |
| 340 | return; |
| 341 | } |
| 342 | // RGBA |
| 343 | basic_transfer_to_test(reporter, ctxInfo.grContext(), GrColorType::kRGBA_8888, false); |
| 344 | basic_transfer_to_test(reporter, ctxInfo.grContext(), GrColorType::kRGBA_8888, true); |
| 345 | |
| 346 | // BGRA |
| 347 | basic_transfer_to_test(reporter, ctxInfo.grContext(), GrColorType::kBGRA_8888, false); |
| 348 | basic_transfer_to_test(reporter, ctxInfo.grContext(), GrColorType::kBGRA_8888, true); |
| 349 | } |
| 350 | |
Brian Salomon | a585fe9 | 2019-04-09 14:57:00 -0400 | [diff] [blame] | 351 | // TODO(bsalomon): Metal |
| 352 | DEF_GPUTEST_FOR_RENDERING_CONTEXTS(TransferPixelsFromTest, reporter, ctxInfo) { |
Brian Salomon | e05ba5a | 2019-04-08 11:59:07 -0400 | [diff] [blame] | 353 | if (!ctxInfo.grContext()->priv().caps()->transferBufferSupport()) { |
| 354 | return; |
| 355 | } |
| 356 | // RGBA |
Brian Salomon | 42cbedd | 2019-04-09 15:00:05 -0400 | [diff] [blame] | 357 | basic_transfer_from_test(reporter, ctxInfo, GrColorType::kRGBA_8888, false); |
| 358 | basic_transfer_from_test(reporter, ctxInfo, GrColorType::kRGBA_8888, true); |
Brian Salomon | e05ba5a | 2019-04-08 11:59:07 -0400 | [diff] [blame] | 359 | |
| 360 | // BGRA |
Brian Salomon | 42cbedd | 2019-04-09 15:00:05 -0400 | [diff] [blame] | 361 | basic_transfer_from_test(reporter, ctxInfo, GrColorType::kBGRA_8888, false); |
| 362 | basic_transfer_from_test(reporter, ctxInfo, GrColorType::kBGRA_8888, true); |
Brian Salomon | e05ba5a | 2019-04-08 11:59:07 -0400 | [diff] [blame] | 363 | } |