| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkCanvas.h" | 8 #include "SkCanvas.h" |
| 9 #include "SkData.h" | 9 #include "SkData.h" |
| 10 #include "SkDevice.h" | 10 #include "SkDevice.h" |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 58 release_storage, storag
e); | 58 release_storage, storag
e); |
| 59 } | 59 } |
| 60 case kGpu_SurfaceType: | 60 case kGpu_SurfaceType: |
| 61 return SkSurface::NewRenderTarget(context, SkSurface::kNo_Budgeted,
info, 0, nullptr); | 61 return SkSurface::NewRenderTarget(context, SkSurface::kNo_Budgeted,
info, 0, nullptr); |
| 62 case kGpuScratch_SurfaceType: | 62 case kGpuScratch_SurfaceType: |
| 63 return SkSurface::NewRenderTarget(context, SkSurface::kYes_Budgeted,
info, 0, nullptr); | 63 return SkSurface::NewRenderTarget(context, SkSurface::kYes_Budgeted,
info, 0, nullptr); |
| 64 } | 64 } |
| 65 return nullptr; | 65 return nullptr; |
| 66 } | 66 } |
| 67 | 67 |
| 68 enum ImageType { | |
| 69 kRasterCopy_ImageType, | |
| 70 kRasterData_ImageType, | |
| 71 kRasterProc_ImageType, | |
| 72 kGpu_ImageType, | |
| 73 kCodec_ImageType, | |
| 74 }; | |
| 75 | |
| 76 #include "SkImageGenerator.h" | |
| 77 | |
| 78 class EmptyGenerator : public SkImageGenerator { | |
| 79 public: | |
| 80 EmptyGenerator() : SkImageGenerator(SkImageInfo::MakeN32Premul(0, 0)) {} | |
| 81 }; | |
| 82 | |
| 83 static void test_empty_image(skiatest::Reporter* reporter) { | |
| 84 const SkImageInfo info = SkImageInfo::Make(0, 0, kN32_SkColorType, kPremul_S
kAlphaType); | |
| 85 | |
| 86 REPORTER_ASSERT(reporter, nullptr == SkImage::NewRasterCopy(info, nullptr, 0
)); | |
| 87 REPORTER_ASSERT(reporter, nullptr == SkImage::NewRasterData(info, nullptr, 0
)); | |
| 88 REPORTER_ASSERT(reporter, nullptr == SkImage::NewFromRaster(info, nullptr, 0
, nullptr, nullptr)); | |
| 89 REPORTER_ASSERT(reporter, nullptr == SkImage::NewFromGenerator(new EmptyGene
rator)); | |
| 90 } | |
| 91 | |
| 92 static void test_empty_surface(skiatest::Reporter* reporter, GrContext* ctx) { | 68 static void test_empty_surface(skiatest::Reporter* reporter, GrContext* ctx) { |
| 93 const SkImageInfo info = SkImageInfo::Make(0, 0, kN32_SkColorType, kPremul_S
kAlphaType); | 69 const SkImageInfo info = SkImageInfo::Make(0, 0, kN32_SkColorType, kPremul_S
kAlphaType); |
| 94 | 70 |
| 95 REPORTER_ASSERT(reporter, nullptr == SkSurface::NewRaster(info)); | 71 REPORTER_ASSERT(reporter, nullptr == SkSurface::NewRaster(info)); |
| 96 REPORTER_ASSERT(reporter, nullptr == SkSurface::NewRasterDirect(info, nullpt
r, 0)); | 72 REPORTER_ASSERT(reporter, nullptr == SkSurface::NewRasterDirect(info, nullpt
r, 0)); |
| 97 if (ctx) { | 73 if (ctx) { |
| 98 REPORTER_ASSERT(reporter, nullptr == | 74 REPORTER_ASSERT(reporter, nullptr == |
| 99 SkSurface::NewRenderTarget(ctx, SkSurface::kNo_Budgeted,
info, 0, nullptr)); | 75 SkSurface::NewRenderTarget(ctx, SkSurface::kNo_Budgeted,
info, 0, nullptr)); |
| 100 } | 76 } |
| 101 } | 77 } |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 168 } | 144 } |
| 169 } | 145 } |
| 170 } | 146 } |
| 171 } | 147 } |
| 172 gpu->deleteTestingOnlyBackendTexture(texHandle); | 148 gpu->deleteTestingOnlyBackendTexture(texHandle); |
| 173 | 149 |
| 174 } | 150 } |
| 175 #endif | 151 #endif |
| 176 | 152 |
| 177 | 153 |
| 178 static void test_image(skiatest::Reporter* reporter) { | |
| 179 SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1); | |
| 180 size_t rowBytes = info.minRowBytes(); | |
| 181 size_t size = info.getSafeSize(rowBytes); | |
| 182 SkData* data = SkData::NewUninitialized(size); | |
| 183 | |
| 184 REPORTER_ASSERT(reporter, data->unique()); | |
| 185 SkImage* image = SkImage::NewRasterData(info, data, rowBytes); | |
| 186 REPORTER_ASSERT(reporter, !data->unique()); | |
| 187 image->unref(); | |
| 188 REPORTER_ASSERT(reporter, data->unique()); | |
| 189 data->unref(); | |
| 190 } | |
| 191 | |
| 192 // Want to ensure that our Release is called when the owning image is destroyed | |
| 193 struct ReleaseDataContext { | |
| 194 skiatest::Reporter* fReporter; | |
| 195 SkData* fData; | |
| 196 | |
| 197 static void Release(const void* pixels, void* context) { | |
| 198 ReleaseDataContext* state = (ReleaseDataContext*)context; | |
| 199 REPORTER_ASSERT(state->fReporter, state->fData); | |
| 200 state->fData->unref(); | |
| 201 state->fData = nullptr; | |
| 202 } | |
| 203 }; | |
| 204 | |
| 205 // May we (soon) eliminate the need to keep testing this, by hiding the bloody d
evice! | |
| 206 #include "SkDevice.h" | |
| 207 static uint32_t get_legacy_gen_id(SkSurface* surf) { | |
| 208 SkBaseDevice* device = surf->getCanvas()->getDevice_just_for_deprecated_comp
atibility_testing(); | |
| 209 return device->accessBitmap(false).getGenerationID(); | |
| 210 } | |
| 211 | |
| 212 /* | |
| 213 * Test legacy behavor of bumping the surface's device's bitmap's genID when we
access its | |
| 214 * texture handle for writing. | |
| 215 * | |
| 216 * Note: this needs to be tested separately from checking newImageSnapshot, as
calling that | |
| 217 * can also incidentally bump the genID (when a new backing surface is created)
. | |
| 218 */ | |
| 219 template <class F> | |
| 220 static void test_texture_handle_genID(skiatest::Reporter* reporter, SkSurface* s
urf, F f) { | |
| 221 const uint32_t gen0 = get_legacy_gen_id(surf); | |
| 222 f(surf, SkSurface::kFlushRead_BackendHandleAccess); | |
| 223 const uint32_t gen1 = get_legacy_gen_id(surf); | |
| 224 REPORTER_ASSERT(reporter, gen0 == gen1); | |
| 225 | |
| 226 f(surf, SkSurface::kFlushWrite_BackendHandleAccess); | |
| 227 const uint32_t gen2 = get_legacy_gen_id(surf); | |
| 228 REPORTER_ASSERT(reporter, gen0 != gen2); | |
| 229 | |
| 230 f(surf, SkSurface::kDiscardWrite_BackendHandleAccess); | |
| 231 const uint32_t gen3 = get_legacy_gen_id(surf); | |
| 232 REPORTER_ASSERT(reporter, gen0 != gen3); | |
| 233 REPORTER_ASSERT(reporter, gen2 != gen3); | |
| 234 } | |
| 235 | |
| 236 template <class F> | |
| 237 static void test_backend_handle(skiatest::Reporter* reporter, SkSurface* surf, F
f) { | |
| 238 SkAutoTUnref<SkImage> image0(surf->newImageSnapshot()); | |
| 239 GrBackendObject obj = f(surf, SkSurface::kFlushRead_BackendHandleAccess); | |
| 240 REPORTER_ASSERT(reporter, obj != 0); | |
| 241 SkAutoTUnref<SkImage> image1(surf->newImageSnapshot()); | |
| 242 // just read access should not affect the snapshot | |
| 243 REPORTER_ASSERT(reporter, image0->uniqueID() == image1->uniqueID()); | |
| 244 | |
| 245 obj = f(surf, SkSurface::kFlushWrite_BackendHandleAccess); | |
| 246 REPORTER_ASSERT(reporter, obj != 0); | |
| 247 SkAutoTUnref<SkImage> image2(surf->newImageSnapshot()); | |
| 248 // expect a new image, since we claimed we would write | |
| 249 REPORTER_ASSERT(reporter, image0->uniqueID() != image2->uniqueID()); | |
| 250 | |
| 251 obj = f(surf, SkSurface::kDiscardWrite_BackendHandleAccess); | |
| 252 REPORTER_ASSERT(reporter, obj != 0); | |
| 253 SkAutoTUnref<SkImage> image3(surf->newImageSnapshot()); | |
| 254 // expect a new(er) image, since we claimed we would write | |
| 255 REPORTER_ASSERT(reporter, image0->uniqueID() != image3->uniqueID()); | |
| 256 REPORTER_ASSERT(reporter, image2->uniqueID() != image3->uniqueID()); | |
| 257 } | |
| 258 | |
| 259 static SkImage* create_image(skiatest::Reporter* reporter, | |
| 260 ImageType imageType, GrContext* context, SkColor co
lor, | |
| 261 ReleaseDataContext* releaseContext) { | |
| 262 const SkPMColor pmcolor = SkPreMultiplyColor(color); | |
| 263 const SkImageInfo info = SkImageInfo::MakeN32Premul(10, 10); | |
| 264 const size_t rowBytes = info.minRowBytes(); | |
| 265 const size_t size = rowBytes * info.height(); | |
| 266 | |
| 267 SkAutoTUnref<SkData> data(SkData::NewUninitialized(size)); | |
| 268 void* addr = data->writable_data(); | |
| 269 sk_memset32((SkPMColor*)addr, pmcolor, SkToInt(size >> 2)); | |
| 270 | |
| 271 switch (imageType) { | |
| 272 case kRasterCopy_ImageType: | |
| 273 return SkImage::NewRasterCopy(info, addr, rowBytes); | |
| 274 case kRasterData_ImageType: | |
| 275 return SkImage::NewRasterData(info, data, rowBytes); | |
| 276 case kRasterProc_ImageType: | |
| 277 SkASSERT(releaseContext); | |
| 278 releaseContext->fData = SkRef(data.get()); | |
| 279 return SkImage::NewFromRaster(info, addr, rowBytes, | |
| 280 ReleaseDataContext::Release, releaseCo
ntext); | |
| 281 case kGpu_ImageType: { | |
| 282 SkAutoTUnref<SkSurface> surf( | |
| 283 SkSurface::NewRenderTarget(context, SkSurface::kNo_Budgeted, inf
o, 0)); | |
| 284 surf->getCanvas()->clear(color); | |
| 285 // test our backing texture / rendertarget while were here... | |
| 286 auto textureAccessorFunc = | |
| 287 [](SkSurface* surf, SkSurface::BackendHandleAccess access) -
> GrBackendObject { | |
| 288 return surf->getTextureHandle(access); }; | |
| 289 auto renderTargetAccessorFunc = | |
| 290 [](SkSurface* surf, SkSurface::BackendHandleAccess access) -
> GrBackendObject { | |
| 291 GrBackendObject obj; | |
| 292 SkAssertResult(surf->getRenderTargetHandle(&obj, access)
); | |
| 293 return obj; }; | |
| 294 test_backend_handle(reporter, surf, textureAccessorFunc); | |
| 295 test_backend_handle(reporter, surf, renderTargetAccessorFunc); | |
| 296 test_texture_handle_genID(reporter, surf, textureAccessorFunc); | |
| 297 test_texture_handle_genID(reporter, surf, renderTargetAccessorFunc); | |
| 298 | |
| 299 // redraw so our returned image looks as expected. | |
| 300 surf->getCanvas()->clear(color); | |
| 301 return surf->newImageSnapshot(); | |
| 302 } | |
| 303 case kCodec_ImageType: { | |
| 304 SkBitmap bitmap; | |
| 305 bitmap.installPixels(info, addr, rowBytes); | |
| 306 SkAutoTUnref<SkData> src( | |
| 307 SkImageEncoder::EncodeData(bitmap, SkImageEncoder::kPNG_Type, 1
00)); | |
| 308 return SkImage::NewFromEncoded(src); | |
| 309 } | |
| 310 } | |
| 311 SkASSERT(false); | |
| 312 return nullptr; | |
| 313 } | |
| 314 | |
| 315 static void set_pixels(SkPMColor pixels[], int count, SkPMColor color) { | |
| 316 sk_memset32(pixels, color, count); | |
| 317 } | |
| 318 static bool has_pixels(const SkPMColor pixels[], int count, SkPMColor expected)
{ | |
| 319 for (int i = 0; i < count; ++i) { | |
| 320 if (pixels[i] != expected) { | |
| 321 return false; | |
| 322 } | |
| 323 } | |
| 324 return true; | |
| 325 } | |
| 326 | |
| 327 static void test_image_readpixels(skiatest::Reporter* reporter, SkImage* image, | |
| 328 SkPMColor expected) { | |
| 329 const SkPMColor notExpected = ~expected; | |
| 330 | |
| 331 const int w = 2, h = 2; | |
| 332 const size_t rowBytes = w * sizeof(SkPMColor); | |
| 333 SkPMColor pixels[w*h]; | |
| 334 | |
| 335 SkImageInfo info; | |
| 336 | |
| 337 info = SkImageInfo::MakeUnknown(w, h); | |
| 338 REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, 0, 0)); | |
| 339 | |
| 340 // out-of-bounds should fail | |
| 341 info = SkImageInfo::MakeN32Premul(w, h); | |
| 342 REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, -w, 0))
; | |
| 343 REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, 0, -h))
; | |
| 344 REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, image->
width(), 0)); | |
| 345 REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, 0, imag
e->height())); | |
| 346 | |
| 347 // top-left should succeed | |
| 348 set_pixels(pixels, w*h, notExpected); | |
| 349 REPORTER_ASSERT(reporter, image->readPixels(info, pixels, rowBytes, 0, 0)); | |
| 350 REPORTER_ASSERT(reporter, has_pixels(pixels, w*h, expected)); | |
| 351 | |
| 352 // bottom-right should succeed | |
| 353 set_pixels(pixels, w*h, notExpected); | |
| 354 REPORTER_ASSERT(reporter, image->readPixels(info, pixels, rowBytes, | |
| 355 image->width() - w, image->heigh
t() - h)); | |
| 356 REPORTER_ASSERT(reporter, has_pixels(pixels, w*h, expected)); | |
| 357 | |
| 358 // partial top-left should succeed | |
| 359 set_pixels(pixels, w*h, notExpected); | |
| 360 REPORTER_ASSERT(reporter, image->readPixels(info, pixels, rowBytes, -1, -1))
; | |
| 361 REPORTER_ASSERT(reporter, pixels[3] == expected); | |
| 362 REPORTER_ASSERT(reporter, has_pixels(pixels, w*h - 1, notExpected)); | |
| 363 | |
| 364 // partial bottom-right should succeed | |
| 365 set_pixels(pixels, w*h, notExpected); | |
| 366 REPORTER_ASSERT(reporter, image->readPixels(info, pixels, rowBytes, | |
| 367 image->width() - 1, image->heigh
t() - 1)); | |
| 368 REPORTER_ASSERT(reporter, pixels[0] == expected); | |
| 369 REPORTER_ASSERT(reporter, has_pixels(&pixels[1], w*h - 1, notExpected)); | |
| 370 } | |
| 371 | |
| 372 static void check_legacy_bitmap(skiatest::Reporter* reporter, const SkImage* ima
ge, | |
| 373 const SkBitmap& bitmap, SkImage::LegacyBitmapMod
e mode) { | |
| 374 REPORTER_ASSERT(reporter, image->width() == bitmap.width()); | |
| 375 REPORTER_ASSERT(reporter, image->height() == bitmap.height()); | |
| 376 REPORTER_ASSERT(reporter, image->isOpaque() == bitmap.isOpaque()); | |
| 377 | |
| 378 if (SkImage::kRO_LegacyBitmapMode == mode) { | |
| 379 REPORTER_ASSERT(reporter, bitmap.isImmutable()); | |
| 380 } | |
| 381 | |
| 382 SkAutoLockPixels alp(bitmap); | |
| 383 REPORTER_ASSERT(reporter, bitmap.getPixels()); | |
| 384 | |
| 385 const SkImageInfo info = SkImageInfo::MakeN32(1, 1, bitmap.alphaType()); | |
| 386 SkPMColor imageColor; | |
| 387 REPORTER_ASSERT(reporter, image->readPixels(info, &imageColor, sizeof(SkPMCo
lor), 0, 0)); | |
| 388 REPORTER_ASSERT(reporter, imageColor == *bitmap.getAddr32(0, 0)); | |
| 389 } | |
| 390 | |
| 391 static void test_legacy_bitmap(skiatest::Reporter* reporter, const SkImage* imag
e) { | |
| 392 const SkImage::LegacyBitmapMode modes[] = { | |
| 393 SkImage::kRO_LegacyBitmapMode, | |
| 394 SkImage::kRW_LegacyBitmapMode, | |
| 395 }; | |
| 396 for (size_t i = 0; i < SK_ARRAY_COUNT(modes); ++i) { | |
| 397 SkBitmap bitmap; | |
| 398 REPORTER_ASSERT(reporter, image->asLegacyBitmap(&bitmap, modes[i])); | |
| 399 check_legacy_bitmap(reporter, image, bitmap, modes[i]); | |
| 400 | |
| 401 // Test subsetting to exercise the rowBytes logic. | |
| 402 SkBitmap tmp; | |
| 403 REPORTER_ASSERT(reporter, bitmap.extractSubset(&tmp, SkIRect::MakeWH(ima
ge->width() / 2, | |
| 404 ima
ge->height() / 2))); | |
| 405 SkAutoTUnref<SkImage> subsetImage(SkImage::NewFromBitmap(tmp)); | |
| 406 REPORTER_ASSERT(reporter, subsetImage); | |
| 407 | |
| 408 SkBitmap subsetBitmap; | |
| 409 REPORTER_ASSERT(reporter, subsetImage->asLegacyBitmap(&subsetBitmap, mod
es[i])); | |
| 410 check_legacy_bitmap(reporter, subsetImage, subsetBitmap, modes[i]); | |
| 411 } | |
| 412 } | |
| 413 | |
| 414 static void test_imagepeek(skiatest::Reporter* reporter, GrContextFactory* facto
ry) { | |
| 415 static const struct { | |
| 416 ImageType fType; | |
| 417 bool fPeekShouldSucceed; | |
| 418 const char* fName; | |
| 419 } gRec[] = { | |
| 420 { kRasterCopy_ImageType, true, "RasterCopy" }, | |
| 421 { kRasterData_ImageType, true, "RasterData" }, | |
| 422 { kRasterProc_ImageType, true, "RasterProc" }, | |
| 423 { kGpu_ImageType, false, "Gpu" }, | |
| 424 { kCodec_ImageType, false, "Codec" }, | |
| 425 }; | |
| 426 | |
| 427 const SkColor color = SK_ColorRED; | |
| 428 const SkPMColor pmcolor = SkPreMultiplyColor(color); | |
| 429 | |
| 430 GrContext* ctx = nullptr; | |
| 431 #if SK_SUPPORT_GPU | |
| 432 ctx = factory->get(GrContextFactory::kNative_GLContextType); | |
| 433 if (nullptr == ctx) { | |
| 434 return; | |
| 435 } | |
| 436 #endif | |
| 437 | |
| 438 ReleaseDataContext releaseCtx; | |
| 439 releaseCtx.fReporter = reporter; | |
| 440 | |
| 441 for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) { | |
| 442 SkImageInfo info; | |
| 443 size_t rowBytes; | |
| 444 | |
| 445 releaseCtx.fData = nullptr; | |
| 446 SkAutoTUnref<SkImage> image(create_image(reporter, gRec[i].fType, ctx, c
olor, &releaseCtx)); | |
| 447 if (!image.get()) { | |
| 448 SkDebugf("failed to createImage[%d] %s\n", i, gRec[i].fName); | |
| 449 continue; // gpu may not be enabled | |
| 450 } | |
| 451 if (kRasterProc_ImageType == gRec[i].fType) { | |
| 452 REPORTER_ASSERT(reporter, nullptr != releaseCtx.fData); // we are t
racking the data | |
| 453 } else { | |
| 454 REPORTER_ASSERT(reporter, nullptr == releaseCtx.fData); // we ignor
ed the context | |
| 455 } | |
| 456 | |
| 457 test_legacy_bitmap(reporter, image); | |
| 458 | |
| 459 const void* addr = image->peekPixels(&info, &rowBytes); | |
| 460 bool success = SkToBool(addr); | |
| 461 REPORTER_ASSERT(reporter, gRec[i].fPeekShouldSucceed == success); | |
| 462 if (success) { | |
| 463 REPORTER_ASSERT(reporter, 10 == info.width()); | |
| 464 REPORTER_ASSERT(reporter, 10 == info.height()); | |
| 465 REPORTER_ASSERT(reporter, kN32_SkColorType == info.colorType()); | |
| 466 REPORTER_ASSERT(reporter, kPremul_SkAlphaType == info.alphaType() || | |
| 467 kOpaque_SkAlphaType == info.alphaType()); | |
| 468 REPORTER_ASSERT(reporter, info.minRowBytes() <= rowBytes); | |
| 469 REPORTER_ASSERT(reporter, pmcolor == *(const SkPMColor*)addr); | |
| 470 } | |
| 471 | |
| 472 test_image_readpixels(reporter, image, pmcolor); | |
| 473 } | |
| 474 REPORTER_ASSERT(reporter, nullptr == releaseCtx.fData); // we released the
data | |
| 475 } | |
| 476 | 154 |
| 477 static void test_canvaspeek(skiatest::Reporter* reporter, | 155 static void test_canvaspeek(skiatest::Reporter* reporter, |
| 478 GrContextFactory* factory) { | 156 GrContextFactory* factory) { |
| 479 static const struct { | 157 static const struct { |
| 480 SurfaceType fType; | 158 SurfaceType fType; |
| 481 bool fPeekShouldSucceed; | 159 bool fPeekShouldSucceed; |
| 482 } gRec[] = { | 160 } gRec[] = { |
| 483 { kRaster_SurfaceType, true }, | 161 { kRaster_SurfaceType, true }, |
| 484 { kRasterDirect_SurfaceType, true }, | 162 { kRasterDirect_SurfaceType, true }, |
| 485 #if SK_SUPPORT_GPU | 163 #if SK_SUPPORT_GPU |
| (...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 876 SkImage* image2 = surface->newImageSnapshot(); | 554 SkImage* image2 = surface->newImageSnapshot(); |
| 877 SkAutoTUnref<SkImage> aur_image2(image2); | 555 SkAutoTUnref<SkImage> aur_image2(image2); |
| 878 SkDEBUGCODE(image2->validate();) | 556 SkDEBUGCODE(image2->validate();) |
| 879 SkDEBUGCODE(surface->validate();) | 557 SkDEBUGCODE(surface->validate();) |
| 880 REPORTER_ASSERT(reporter, image1 != image2); | 558 REPORTER_ASSERT(reporter, image1 != image2); |
| 881 } | 559 } |
| 882 | 560 |
| 883 } | 561 } |
| 884 | 562 |
| 885 DEF_GPUTEST(Surface, reporter, factory) { | 563 DEF_GPUTEST(Surface, reporter, factory) { |
| 886 test_image(reporter); | |
| 887 | |
| 888 TestSurfaceCopyOnWrite(reporter, kRaster_SurfaceType, nullptr); | 564 TestSurfaceCopyOnWrite(reporter, kRaster_SurfaceType, nullptr); |
| 889 TestSurfaceWritableAfterSnapshotRelease(reporter, kRaster_SurfaceType, nullp
tr); | 565 TestSurfaceWritableAfterSnapshotRelease(reporter, kRaster_SurfaceType, nullp
tr); |
| 890 TestSurfaceNoCanvas(reporter, kRaster_SurfaceType, nullptr, SkSurface::kDisc
ard_ContentChangeMode); | 566 TestSurfaceNoCanvas(reporter, kRaster_SurfaceType, nullptr, SkSurface::kDisc
ard_ContentChangeMode); |
| 891 TestSurfaceNoCanvas(reporter, kRaster_SurfaceType, nullptr, SkSurface::kReta
in_ContentChangeMode); | 567 TestSurfaceNoCanvas(reporter, kRaster_SurfaceType, nullptr, SkSurface::kReta
in_ContentChangeMode); |
| 892 | 568 |
| 893 test_empty_image(reporter); | 569 |
| 894 test_empty_surface(reporter, nullptr); | 570 test_empty_surface(reporter, nullptr); |
| 895 | 571 |
| 896 test_imagepeek(reporter, factory); | 572 |
| 897 test_canvaspeek(reporter, factory); | 573 test_canvaspeek(reporter, factory); |
| 898 | 574 |
| 899 test_accessPixels(reporter, factory); | 575 test_accessPixels(reporter, factory); |
| 900 | 576 |
| 901 test_snap_alphatype(reporter, factory); | 577 test_snap_alphatype(reporter, factory); |
| 902 | 578 |
| 903 #if SK_SUPPORT_GPU | 579 #if SK_SUPPORT_GPU |
| 904 TestGetTexture(reporter, kRaster_SurfaceType, nullptr); | 580 TestGetTexture(reporter, kRaster_SurfaceType, nullptr); |
| 905 if (factory) { | 581 if (factory) { |
| 906 for (int i= 0; i < GrContextFactory::kGLContextTypeCnt; ++i) { | 582 for (int i= 0; i < GrContextFactory::kGLContextTypeCnt; ++i) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 924 TestGetTexture(reporter, kGpuScratch_SurfaceType, context); | 600 TestGetTexture(reporter, kGpuScratch_SurfaceType, context); |
| 925 test_empty_surface(reporter, context); | 601 test_empty_surface(reporter, context); |
| 926 test_surface_budget(reporter, context); | 602 test_surface_budget(reporter, context); |
| 927 test_wrapped_texture_surface(reporter, context); | 603 test_wrapped_texture_surface(reporter, context); |
| 928 } | 604 } |
| 929 } | 605 } |
| 930 } | 606 } |
| 931 #endif | 607 #endif |
| 932 } | 608 } |
| 933 | 609 |
| 934 #if SK_SUPPORT_GPU | |
| 935 | 610 |
| 936 struct ReleaseTextureContext { | |
| 937 ReleaseTextureContext(skiatest::Reporter* reporter) { | |
| 938 fReporter = reporter; | |
| 939 fIsReleased = false; | |
| 940 } | |
| 941 | |
| 942 skiatest::Reporter* fReporter; | |
| 943 bool fIsReleased; | |
| 944 | |
| 945 void doRelease() { | |
| 946 REPORTER_ASSERT(fReporter, false == fIsReleased); | |
| 947 fIsReleased = true; | |
| 948 } | |
| 949 | |
| 950 static void ReleaseProc(void* context) { | |
| 951 ((ReleaseTextureContext*)context)->doRelease(); | |
| 952 } | |
| 953 }; | |
| 954 | |
| 955 static SkImage* make_desc_image(GrContext* ctx, int w, int h, GrBackendObject te
xID, | |
| 956 ReleaseTextureContext* releaseContext) { | |
| 957 GrBackendTextureDesc desc; | |
| 958 desc.fConfig = kSkia8888_GrPixelConfig; | |
| 959 // need to be a rendertarget for now... | |
| 960 desc.fFlags = kRenderTarget_GrBackendTextureFlag; | |
| 961 desc.fWidth = w; | |
| 962 desc.fHeight = h; | |
| 963 desc.fSampleCnt = 0; | |
| 964 desc.fTextureHandle = texID; | |
| 965 return releaseContext | |
| 966 ? SkImage::NewFromTexture(ctx, desc, kPremul_SkAlphaType, | |
| 967 ReleaseTextureContext::ReleaseProc, re
leaseContext) | |
| 968 : SkImage::NewFromTextureCopy(ctx, desc, kPremul_SkAlphaType); | |
| 969 } | |
| 970 | |
| 971 static void test_image_color(skiatest::Reporter* reporter, SkImage* image, SkPMC
olor expected) { | |
| 972 const SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1); | |
| 973 SkPMColor pixel; | |
| 974 REPORTER_ASSERT(reporter, image->readPixels(info, &pixel, sizeof(pixel), 0,
0)); | |
| 975 REPORTER_ASSERT(reporter, pixel == expected); | |
| 976 } | |
| 977 | |
| 978 DEF_GPUTEST(SkImage_NewFromTexture, reporter, factory) { | |
| 979 GrContext* ctx = factory->get(GrContextFactory::kNative_GLContextType); | |
| 980 if (!ctx) { | |
| 981 REPORTER_ASSERT(reporter, false); | |
| 982 return; | |
| 983 } | |
| 984 GrTextureProvider* provider = ctx->textureProvider(); | |
| 985 | |
| 986 const int w = 10; | |
| 987 const int h = 10; | |
| 988 SkPMColor storage[w * h]; | |
| 989 const SkPMColor expected0 = SkPreMultiplyColor(SK_ColorRED); | |
| 990 sk_memset32(storage, expected0, w * h); | |
| 991 | |
| 992 GrSurfaceDesc desc; | |
| 993 desc.fFlags = kRenderTarget_GrSurfaceFlag; // needs to be a rendertarget fo
r readpixels(); | |
| 994 desc.fOrigin = kDefault_GrSurfaceOrigin; | |
| 995 desc.fWidth = w; | |
| 996 desc.fHeight = h; | |
| 997 desc.fConfig = kSkia8888_GrPixelConfig; | |
| 998 desc.fSampleCnt = 0; | |
| 999 | |
| 1000 SkAutoTUnref<GrTexture> tex(provider->createTexture(desc, false, storage, w
* 4)); | |
| 1001 if (!tex) { | |
| 1002 REPORTER_ASSERT(reporter, false); | |
| 1003 return; | |
| 1004 } | |
| 1005 | |
| 1006 GrBackendObject srcTex = tex->getTextureHandle(); | |
| 1007 ReleaseTextureContext releaseCtx(reporter); | |
| 1008 | |
| 1009 SkAutoTUnref<SkImage> refImg(make_desc_image(ctx, w, h, srcTex, &releaseCtx)
); | |
| 1010 SkAutoTUnref<SkImage> cpyImg(make_desc_image(ctx, w, h, srcTex, nullptr)); | |
| 1011 | |
| 1012 test_image_color(reporter, refImg, expected0); | |
| 1013 test_image_color(reporter, cpyImg, expected0); | |
| 1014 | |
| 1015 // Now lets jam new colors into our "external" texture, and see if the image
s notice | |
| 1016 const SkPMColor expected1 = SkPreMultiplyColor(SK_ColorBLUE); | |
| 1017 sk_memset32(storage, expected1, w * h); | |
| 1018 tex->writePixels(0, 0, w, h, kSkia8888_GrPixelConfig, storage, GrContext::kF
lushWrites_PixelOp); | |
| 1019 | |
| 1020 // The cpy'd one should still see the old color | |
| 1021 #if 0 | |
| 1022 // There is no guarantee that refImg sees the new color. We are free to have
made a copy. Our | |
| 1023 // write pixels call violated the contract with refImg and refImg is now und
efined. | |
| 1024 test_image_color(reporter, refImg, expected1); | |
| 1025 #endif | |
| 1026 test_image_color(reporter, cpyImg, expected0); | |
| 1027 | |
| 1028 // Now exercise the release proc | |
| 1029 REPORTER_ASSERT(reporter, !releaseCtx.fIsReleased); | |
| 1030 refImg.reset(nullptr); // force a release of the image | |
| 1031 REPORTER_ASSERT(reporter, releaseCtx.fIsReleased); | |
| 1032 } | |
| 1033 #endif | |
| OLD | NEW |