| Index: tests/SurfaceTest.cpp
|
| diff --git a/tests/SurfaceTest.cpp b/tests/SurfaceTest.cpp
|
| index d9138ebca73cc7a0676c32d6c5c9a84181a1060c..41fef617bca9e37669a26dc5716833ff0dde5300 100644
|
| --- a/tests/SurfaceTest.cpp
|
| +++ b/tests/SurfaceTest.cpp
|
| @@ -323,6 +323,133 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceBackendHandleAccessCopyOnWrite_Gpu, re
|
| }
|
| #endif
|
|
|
| +static bool same_image(SkImage* a, SkImage* b,
|
| + std::function<intptr_t(SkImage*)> getImageBackingStore) {
|
| + return getImageBackingStore(a) == getImageBackingStore(b);
|
| +}
|
| +
|
| +static bool same_image_surf(SkImage* a, SkSurface* b,
|
| + std::function<intptr_t(SkImage*)> getImageBackingStore,
|
| + std::function<intptr_t(SkSurface*)> getSurfaceBackingStore) {
|
| + return getImageBackingStore(a) == getSurfaceBackingStore(b);
|
| +}
|
| +
|
| +static void test_unique_image_snap(skiatest::Reporter* reporter, SkSurface* surface,
|
| + bool surfaceIsDirect,
|
| + std::function<intptr_t(SkImage*)> imageBackingStore,
|
| + std::function<intptr_t(SkSurface*)> surfaceBackingStore) {
|
| + std::function<intptr_t(SkImage*)> ibs = imageBackingStore;
|
| + std::function<intptr_t(SkSurface*)> sbs = surfaceBackingStore;
|
| + static const SkSurface::Budgeted kB = SkSurface::kNo_Budgeted;
|
| + {
|
| + SkAutoTUnref<SkImage> image(surface->newImageSnapshot(kB, SkSurface::kYes_ForceUnique));
|
| + REPORTER_ASSERT(reporter, !same_image_surf(image, surface, ibs, sbs));
|
| + REPORTER_ASSERT(reporter, image->unique());
|
| + }
|
| + {
|
| + SkAutoTUnref<SkImage> image1(surface->newImageSnapshot(kB, SkSurface::kYes_ForceUnique));
|
| + REPORTER_ASSERT(reporter, !same_image_surf(image1, surface, ibs, sbs));
|
| + REPORTER_ASSERT(reporter, image1->unique());
|
| + SkAutoTUnref<SkImage> image2(surface->newImageSnapshot(kB, SkSurface::kYes_ForceUnique));
|
| + REPORTER_ASSERT(reporter, !same_image_surf(image2, surface, ibs, sbs));
|
| + REPORTER_ASSERT(reporter, !same_image(image1, image2, ibs));
|
| + REPORTER_ASSERT(reporter, image2->unique());
|
| + }
|
| + {
|
| + SkAutoTUnref<SkImage> image1(surface->newImageSnapshot(kB, SkSurface::kNo_ForceUnique));
|
| + SkAutoTUnref<SkImage> image2(surface->newImageSnapshot(kB, SkSurface::kYes_ForceUnique));
|
| + SkAutoTUnref<SkImage> image3(surface->newImageSnapshot(kB, SkSurface::kNo_ForceUnique));
|
| + SkAutoTUnref<SkImage> image4(surface->newImageSnapshot(kB, SkSurface::kYes_ForceUnique));
|
| + // Image 1 and 3 ought to be the same (or we're missing an optimization).
|
| + REPORTER_ASSERT(reporter, same_image(image1, image3, ibs));
|
| + // If the surface is not direct then images 1 and 3 should alias the surface's
|
| + // store.
|
| + REPORTER_ASSERT(reporter, !surfaceIsDirect == same_image_surf(image1, surface, ibs, sbs));
|
| + // Image 2 should not be shared with any other image.
|
| + REPORTER_ASSERT(reporter, !same_image(image1, image2, ibs) &&
|
| + !same_image(image3, image2, ibs) &&
|
| + !same_image(image4, image2, ibs));
|
| + REPORTER_ASSERT(reporter, image2->unique());
|
| + REPORTER_ASSERT(reporter, !same_image_surf(image2, surface, ibs, sbs));
|
| + // Image 4 should not be shared with any other image.
|
| + REPORTER_ASSERT(reporter, !same_image(image1, image4, ibs) &&
|
| + !same_image(image3, image4, ibs));
|
| + REPORTER_ASSERT(reporter, !same_image_surf(image4, surface, ibs, sbs));
|
| + REPORTER_ASSERT(reporter, image4->unique());
|
| + }
|
| +}
|
| +
|
| +DEF_TEST(UniqueImageSnapshot, reporter) {
|
| + auto getImageBackingStore = [reporter](SkImage* image) {
|
| + SkPixmap pm;
|
| + bool success = image->peekPixels(&pm);
|
| + REPORTER_ASSERT(reporter, success);
|
| + return reinterpret_cast<intptr_t>(pm.addr());
|
| + };
|
| + auto getSufaceBackingStore = [reporter](SkSurface* surface) {
|
| + SkImageInfo info;
|
| + size_t rowBytes;
|
| + const void* pixels = surface->getCanvas()->peekPixels(&info, &rowBytes);
|
| + REPORTER_ASSERT(reporter, pixels);
|
| + return reinterpret_cast<intptr_t>(pixels);
|
| + };
|
| +
|
| + SkAutoTUnref<SkSurface> surface(create_surface());
|
| + test_unique_image_snap(reporter, surface, false, getImageBackingStore, getSufaceBackingStore);
|
| + surface.reset(create_direct_surface());
|
| + test_unique_image_snap(reporter, surface, true, getImageBackingStore, getSufaceBackingStore);
|
| +}
|
| +
|
| +#if SK_SUPPORT_GPU
|
| +DEF_GPUTEST_FOR_RENDERING_CONTEXTS(UniqueImageSnapshot_Gpu, reporter, context) {
|
| + for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) {
|
| + SkAutoTUnref<SkSurface> surface(surface_func(context, kOpaque_SkAlphaType, nullptr));
|
| +
|
| + auto imageBackingStore = [reporter](SkImage* image) {
|
| + GrTexture* texture = as_IB(image)->peekTexture();
|
| + if (!texture) {
|
| + ERRORF(reporter, "Not texture backed.");
|
| + return static_cast<intptr_t>(0);
|
| + }
|
| + return static_cast<intptr_t>(texture->getUniqueID());
|
| + };
|
| +
|
| + auto surfaceBackingStore = [reporter](SkSurface* surface) {
|
| + GrRenderTarget* rt =
|
| + surface->getCanvas()->internal_private_accessTopLayerRenderTarget();
|
| + if (!rt) {
|
| + ERRORF(reporter, "Not render target backed.");
|
| + return static_cast<intptr_t>(0);
|
| + }
|
| + return static_cast<intptr_t>(rt->getUniqueID());
|
| + };
|
| +
|
| + test_unique_image_snap(reporter, surface, false, imageBackingStore, surfaceBackingStore);
|
| +
|
| + // Test again with a "direct" render target;
|
| + GrBackendObject textureObject = context->getGpu()->createTestingOnlyBackendTexture(nullptr,
|
| + 10, 10, kRGBA_8888_GrPixelConfig);
|
| + GrBackendTextureDesc desc;
|
| + desc.fConfig = kRGBA_8888_GrPixelConfig;
|
| + desc.fWidth = 10;
|
| + desc.fHeight = 10;
|
| + desc.fFlags = kRenderTarget_GrBackendTextureFlag;
|
| + desc.fTextureHandle = textureObject;
|
| + GrTexture* texture = context->textureProvider()->wrapBackendTexture(desc);
|
| + {
|
| + SkAutoTUnref<SkSurface> surface(
|
| + SkSurface::NewRenderTargetDirect(texture->asRenderTarget()));
|
| + // We should be able to pass true here, but disallowing copy on write for direct GPU
|
| + // surfaces is not yet implemented.
|
| + test_unique_image_snap(reporter, surface, false, imageBackingStore,
|
| + surfaceBackingStore);
|
| + }
|
| + texture->unref();
|
| + context->getGpu()->deleteTestingOnlyBackendTexture(textureObject);
|
| + }
|
| +}
|
| +#endif
|
| +
|
| #if SK_SUPPORT_GPU
|
| // May we (soon) eliminate the need to keep testing this, by hiding the bloody device!
|
| static uint32_t get_legacy_gen_id(SkSurface* surface) {
|
|
|