SurfaceTest.cpp revision 526972ecb5411b84ba2f5e20252f178f9ee2151f
1995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org/* 2995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org * Copyright 2013 Google Inc. 3995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org * 4995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org * Use of this source code is governed by a BSD-style license that can be 5995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org * found in the LICENSE file. 6995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org */ 74ee16bfaedb14aff8cf102f1f0722ff2529a9699tfarina@chromium.org 8e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon#include <functional> 9995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org#include "SkCanvas.h" 100e22eb8e6efc7d7ab7a601ba555947916d139906brianosman#include "SkColorSpace_Base.h" 114f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com#include "SkData.h" 1241e010cb901c0da9066c4df562030808c9ccd7f8reed#include "SkDevice.h" 1355812362f1df3c1f7341f687d5bab0adab8ac954bsalomon#include "SkImage_Base.h" 14d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include "SkPath.h" 15995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org#include "SkRRect.h" 16995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org#include "SkSurface.h" 174f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com#include "SkUtils.h" 18995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org#include "Test.h" 19995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org 20995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org#if SK_SUPPORT_GPU 21179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#include "GrContext.h" 22175dd9b5e3d7d749738dac743d2ac360b5340187robertphillips#include "GrDrawContext.h" 23179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#include "GrGpu.h" 24c4025189d31efcb0d54bf14b7712b38725f86c13ericrk#include "GrResourceProvider.h" 250e22eb8e6efc7d7ab7a601ba555947916d139906brianosman#include <vector> 26995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org#endif 27995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org 28179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#include <initializer_list> 2974f681dce2fbadd481596aea15afb3e0fb36ceffbsalomon 30179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunenstatic void release_direct_surface_storage(void* pixels, void* context) { 31982542dce8acbd2f3e7642268b21e76b93230dafreed SkASSERT(pixels == context); 32982542dce8acbd2f3e7642268b21e76b93230dafreed sk_free(pixels); 33982542dce8acbd2f3e7642268b21e76b93230dafreed} 34e8f3062a36d3682f4019309a32b5b84dc9eddf8creedstatic sk_sp<SkSurface> create_surface(SkAlphaType at = kPremul_SkAlphaType, 35e8f3062a36d3682f4019309a32b5b84dc9eddf8creed SkImageInfo* requestedInfo = nullptr) { 3674f681dce2fbadd481596aea15afb3e0fb36ceffbsalomon const SkImageInfo info = SkImageInfo::MakeN32(10, 10, at); 37c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (requestedInfo) { 38c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org *requestedInfo = info; 39c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 40e8f3062a36d3682f4019309a32b5b84dc9eddf8creed return SkSurface::MakeRaster(info); 41179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 42e8f3062a36d3682f4019309a32b5b84dc9eddf8creedstatic sk_sp<SkSurface> create_direct_surface(SkAlphaType at = kPremul_SkAlphaType, 43e8f3062a36d3682f4019309a32b5b84dc9eddf8creed SkImageInfo* requestedInfo = nullptr) { 44179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen const SkImageInfo info = SkImageInfo::MakeN32(10, 10, at); 45179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen if (requestedInfo) { 46179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen *requestedInfo = info; 47179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen } 48179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen const size_t rowBytes = info.minRowBytes(); 49179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen void* storage = sk_malloc_throw(info.getSafeSize(rowBytes)); 50e8f3062a36d3682f4019309a32b5b84dc9eddf8creed return SkSurface::MakeRasterDirectReleaseProc(info, storage, rowBytes, 51e8f3062a36d3682f4019309a32b5b84dc9eddf8creed release_direct_surface_storage, 52e8f3062a36d3682f4019309a32b5b84dc9eddf8creed storage); 53179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 54179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#if SK_SUPPORT_GPU 55e8f3062a36d3682f4019309a32b5b84dc9eddf8creedstatic sk_sp<SkSurface> create_gpu_surface(GrContext* context, SkAlphaType at = kPremul_SkAlphaType, 56e8f3062a36d3682f4019309a32b5b84dc9eddf8creed SkImageInfo* requestedInfo = nullptr) { 57179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen const SkImageInfo info = SkImageInfo::MakeN32(10, 10, at); 58179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen if (requestedInfo) { 59179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen *requestedInfo = info; 60179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen } 617e922765545f42ce691e4f3d5fbbd4e44ba47ff1robertphillips return SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info); 62179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 63e8f3062a36d3682f4019309a32b5b84dc9eddf8creedstatic sk_sp<SkSurface> create_gpu_scratch_surface(GrContext* context, 64e8f3062a36d3682f4019309a32b5b84dc9eddf8creed SkAlphaType at = kPremul_SkAlphaType, 65e8f3062a36d3682f4019309a32b5b84dc9eddf8creed SkImageInfo* requestedInfo = nullptr) { 66179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen const SkImageInfo info = SkImageInfo::MakeN32(10, 10, at); 67179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen if (requestedInfo) { 68179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen *requestedInfo = info; 69995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org } 707e922765545f42ce691e4f3d5fbbd4e44ba47ff1robertphillips return SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, info); 71995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org} 72179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#endif 73995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org 74179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunenDEF_TEST(SurfaceEmpty, reporter) { 75b2497c2d945c0a5d770865b026e2d5947bf37c91reed const SkImageInfo info = SkImageInfo::Make(0, 0, kN32_SkColorType, kPremul_SkAlphaType); 76e8f3062a36d3682f4019309a32b5b84dc9eddf8creed REPORTER_ASSERT(reporter, nullptr == SkSurface::MakeRaster(info)); 77e8f3062a36d3682f4019309a32b5b84dc9eddf8creed REPORTER_ASSERT(reporter, nullptr == SkSurface::MakeRasterDirect(info, nullptr, 0)); 78b2497c2d945c0a5d770865b026e2d5947bf37c91reed 79179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 80e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon#if SK_SUPPORT_GPU 81ab527a5bbfb1eae4f99a1435d349a44d00477d82egdanielDEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceEmpty_Gpu, reporter, ctxInfo) { 82179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen const SkImageInfo info = SkImageInfo::Make(0, 0, kN32_SkColorType, kPremul_SkAlphaType); 83179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen REPORTER_ASSERT(reporter, nullptr == 847e922765545f42ce691e4f3d5fbbd4e44ba47ff1robertphillips SkSurface::MakeRenderTarget(ctxInfo.grContext(), SkBudgeted::kNo, info)); 85179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 86179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#endif 877a61793d9603f07a9039b5abf814eb25842e211bbsalomon 88179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunenstatic void test_canvas_peek(skiatest::Reporter* reporter, 89e8f3062a36d3682f4019309a32b5b84dc9eddf8creed sk_sp<SkSurface>& surface, 90179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen const SkImageInfo& requestInfo, 91179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen bool expectPeekSuccess) { 92c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org const SkColor color = SK_ColorRED; 93c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org const SkPMColor pmcolor = SkPreMultiplyColor(color); 94179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen surface->getCanvas()->clear(color); 95179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen 966ceeebd37a43d879c120b6ba100ae1febdd67a18reed SkPixmap pmap; 976ceeebd37a43d879c120b6ba100ae1febdd67a18reed bool success = surface->getCanvas()->peekPixels(&pmap); 98179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen REPORTER_ASSERT(reporter, expectPeekSuccess == success); 99179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen 1006ceeebd37a43d879c120b6ba100ae1febdd67a18reed SkPixmap pmap2; 1016ceeebd37a43d879c120b6ba100ae1febdd67a18reed const void* addr2 = surface->peekPixels(&pmap2) ? pmap2.addr() : nullptr; 102179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen 103179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen if (success) { 1046ceeebd37a43d879c120b6ba100ae1febdd67a18reed REPORTER_ASSERT(reporter, requestInfo == pmap.info()); 1056ceeebd37a43d879c120b6ba100ae1febdd67a18reed REPORTER_ASSERT(reporter, requestInfo.minRowBytes() <= pmap.rowBytes()); 1066ceeebd37a43d879c120b6ba100ae1febdd67a18reed REPORTER_ASSERT(reporter, pmcolor == *pmap.addr32()); 107179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen 1086ceeebd37a43d879c120b6ba100ae1febdd67a18reed REPORTER_ASSERT(reporter, pmap.addr() == pmap2.addr()); 1096ceeebd37a43d879c120b6ba100ae1febdd67a18reed REPORTER_ASSERT(reporter, pmap.info() == pmap2.info()); 1106ceeebd37a43d879c120b6ba100ae1febdd67a18reed REPORTER_ASSERT(reporter, pmap.rowBytes() == pmap2.rowBytes()); 111179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen } else { 112179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen REPORTER_ASSERT(reporter, nullptr == addr2); 113179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen } 114179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 115179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunenDEF_TEST(SurfaceCanvasPeek, reporter) { 116179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& surface_func : { &create_surface, &create_direct_surface }) { 117179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkImageInfo requestInfo; 118e8f3062a36d3682f4019309a32b5b84dc9eddf8creed auto surface(surface_func(kPremul_SkAlphaType, &requestInfo)); 119179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen test_canvas_peek(reporter, surface, requestInfo, true); 120179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen } 121179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 122e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon#if SK_SUPPORT_GPU 123ab527a5bbfb1eae4f99a1435d349a44d00477d82egdanielDEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceCanvasPeek_Gpu, reporter, ctxInfo) { 124179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) { 125179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkImageInfo requestInfo; 1268b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon auto surface(surface_func(ctxInfo.grContext(), kPremul_SkAlphaType, &requestInfo)); 127179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen test_canvas_peek(reporter, surface, requestInfo, false); 128c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 129c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 130179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#endif 131c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 132e8f3062a36d3682f4019309a32b5b84dc9eddf8creedstatic void test_snapshot_alphatype(skiatest::Reporter* reporter, const sk_sp<SkSurface>& surface, 13369c166d2ce3f4d2099f35f8e88f1aa56ceeaf960brianosman SkAlphaType expectedAlphaType) { 134179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen REPORTER_ASSERT(reporter, surface); 135179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen if (surface) { 1369ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image(surface->makeImageSnapshot()); 137179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen REPORTER_ASSERT(reporter, image); 138179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen if (image) { 13969c166d2ce3f4d2099f35f8e88f1aa56ceeaf960brianosman REPORTER_ASSERT(reporter, image->alphaType() == expectedAlphaType); 14041e010cb901c0da9066c4df562030808c9ccd7f8reed } 141179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen } 142179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 143179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunenDEF_TEST(SurfaceSnapshotAlphaType, reporter) { 144179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& surface_func : { &create_surface, &create_direct_surface }) { 14569c166d2ce3f4d2099f35f8e88f1aa56ceeaf960brianosman for (auto& at: { kOpaque_SkAlphaType, kPremul_SkAlphaType, kUnpremul_SkAlphaType }) { 14669c166d2ce3f4d2099f35f8e88f1aa56ceeaf960brianosman auto surface(surface_func(at, nullptr)); 14769c166d2ce3f4d2099f35f8e88f1aa56ceeaf960brianosman test_snapshot_alphatype(reporter, surface, at); 14841e010cb901c0da9066c4df562030808c9ccd7f8reed } 14941e010cb901c0da9066c4df562030808c9ccd7f8reed } 15041e010cb901c0da9066c4df562030808c9ccd7f8reed} 15174f681dce2fbadd481596aea15afb3e0fb36ceffbsalomon#if SK_SUPPORT_GPU 152ab527a5bbfb1eae4f99a1435d349a44d00477d82egdanielDEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceSnapshotAlphaType_Gpu, reporter, ctxInfo) { 153179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) { 15469c166d2ce3f4d2099f35f8e88f1aa56ceeaf960brianosman // GPU doesn't support creating unpremul surfaces, so only test opaque + premul 15569c166d2ce3f4d2099f35f8e88f1aa56ceeaf960brianosman for (auto& at : { kOpaque_SkAlphaType, kPremul_SkAlphaType }) { 15669c166d2ce3f4d2099f35f8e88f1aa56ceeaf960brianosman auto surface(surface_func(ctxInfo.grContext(), at, nullptr)); 15769c166d2ce3f4d2099f35f8e88f1aa56ceeaf960brianosman test_snapshot_alphatype(reporter, surface, at); 158179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen } 15974f681dce2fbadd481596aea15afb3e0fb36ceffbsalomon } 160179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 16174f681dce2fbadd481596aea15afb3e0fb36ceffbsalomon#endif 162179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen 163179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunenstatic GrBackendObject get_surface_backend_texture_handle( 164179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkSurface* s, SkSurface::BackendHandleAccess a) { 165179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen return s->getTextureHandle(a); 166179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 167179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunenstatic GrBackendObject get_surface_backend_render_target_handle( 168179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkSurface* s, SkSurface::BackendHandleAccess a) { 169179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen GrBackendObject result; 170179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen if (!s->getRenderTargetHandle(&result, a)) { 171179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen return 0; 17274f681dce2fbadd481596aea15afb3e0fb36ceffbsalomon } 173179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen return result; 17474f681dce2fbadd481596aea15afb3e0fb36ceffbsalomon} 17574f681dce2fbadd481596aea15afb3e0fb36ceffbsalomon 176179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunenstatic void test_backend_handle_access_copy_on_write( 177179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen skiatest::Reporter* reporter, SkSurface* surface, SkSurface::BackendHandleAccess mode, 178179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen GrBackendObject (*func)(SkSurface*, SkSurface::BackendHandleAccess)) { 179e2639089bddc4fbb129ae039cb12c01be087b397fmalita GrBackendObject obj1 = func(surface, mode); 1809ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> snap1(surface->makeImageSnapshot()); 181e2639089bddc4fbb129ae039cb12c01be087b397fmalita 182e2639089bddc4fbb129ae039cb12c01be087b397fmalita GrBackendObject obj2 = func(surface, mode); 1839ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> snap2(surface->makeImageSnapshot()); 184e2639089bddc4fbb129ae039cb12c01be087b397fmalita 185e2639089bddc4fbb129ae039cb12c01be087b397fmalita // If the access mode triggers CoW, then the backend objects should reflect it. 186e2639089bddc4fbb129ae039cb12c01be087b397fmalita REPORTER_ASSERT(reporter, (obj1 == obj2) == (snap1 == snap2)); 187e2639089bddc4fbb129ae039cb12c01be087b397fmalita} 188179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunenDEF_TEST(SurfaceBackendHandleAccessCopyOnWrite, reporter) { 189179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen const SkSurface::BackendHandleAccess accessModes[] = { 190179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkSurface::kFlushRead_BackendHandleAccess, 191179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkSurface::kFlushWrite_BackendHandleAccess, 192179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkSurface::kDiscardWrite_BackendHandleAccess, 193179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen }; 194179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& handle_access_func : 195179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen { &get_surface_backend_texture_handle, &get_surface_backend_render_target_handle }) { 196179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& accessMode : accessModes) { 197e8f3062a36d3682f4019309a32b5b84dc9eddf8creed auto surface(create_surface()); 198e8f3062a36d3682f4019309a32b5b84dc9eddf8creed test_backend_handle_access_copy_on_write(reporter, surface.get(), accessMode, 199179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen handle_access_func); 200179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen } 201179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen } 202179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 203179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#if SK_SUPPORT_GPU 20468d9134bec16e91c4a6cde071bcaa579bc0801a7bsalomonDEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceBackendHandleAccessCopyOnWrite_Gpu, reporter, ctxInfo) { 205179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen const SkSurface::BackendHandleAccess accessModes[] = { 206179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkSurface::kFlushRead_BackendHandleAccess, 207179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkSurface::kFlushWrite_BackendHandleAccess, 208179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkSurface::kDiscardWrite_BackendHandleAccess, 209179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen }; 210179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) { 211179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& handle_access_func : 212179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen { &get_surface_backend_texture_handle, &get_surface_backend_render_target_handle }) { 213179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& accessMode : accessModes) { 2148b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon auto surface(surface_func(ctxInfo.grContext(), kPremul_SkAlphaType, nullptr)); 215e8f3062a36d3682f4019309a32b5b84dc9eddf8creed test_backend_handle_access_copy_on_write(reporter, surface.get(), accessMode, 216179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen handle_access_func); 217179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen } 218179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen } 219179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen } 220179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 221179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#endif 222e2639089bddc4fbb129ae039cb12c01be087b397fmalita 223f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomonstatic bool same_image(SkImage* a, SkImage* b, 224f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon std::function<intptr_t(SkImage*)> getImageBackingStore) { 225f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon return getImageBackingStore(a) == getImageBackingStore(b); 226f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon} 227f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon 228f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomonstatic bool same_image_surf(SkImage* a, SkSurface* b, 229f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon std::function<intptr_t(SkImage*)> getImageBackingStore, 230f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon std::function<intptr_t(SkSurface*)> getSurfaceBackingStore) { 231f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon return getImageBackingStore(a) == getSurfaceBackingStore(b); 232f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon} 233f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon 234f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomonstatic void test_unique_image_snap(skiatest::Reporter* reporter, SkSurface* surface, 235f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon bool surfaceIsDirect, 236f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon std::function<intptr_t(SkImage*)> imageBackingStore, 237f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon std::function<intptr_t(SkSurface*)> surfaceBackingStore) { 238f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon std::function<intptr_t(SkImage*)> ibs = imageBackingStore; 239f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon std::function<intptr_t(SkSurface*)> sbs = surfaceBackingStore; 2405ec26ae9bfca635ccc98283aad5deda11519d826bsalomon static const SkBudgeted kB = SkBudgeted::kNo; 241f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon { 2429ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image(surface->makeImageSnapshot(kB, SkSurface::kYes_ForceUnique)); 2439ce9d6772df650ceb0511f275e1a83dffa78ff72reed REPORTER_ASSERT(reporter, !same_image_surf(image.get(), surface, ibs, sbs)); 244f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon REPORTER_ASSERT(reporter, image->unique()); 245f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon } 246f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon { 2479ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image1(surface->makeImageSnapshot(kB, SkSurface::kYes_ForceUnique)); 2489ce9d6772df650ceb0511f275e1a83dffa78ff72reed REPORTER_ASSERT(reporter, !same_image_surf(image1.get(), surface, ibs, sbs)); 249f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon REPORTER_ASSERT(reporter, image1->unique()); 2509ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image2(surface->makeImageSnapshot(kB, SkSurface::kYes_ForceUnique)); 2519ce9d6772df650ceb0511f275e1a83dffa78ff72reed REPORTER_ASSERT(reporter, !same_image_surf(image2.get(), surface, ibs, sbs)); 2529ce9d6772df650ceb0511f275e1a83dffa78ff72reed REPORTER_ASSERT(reporter, !same_image(image1.get(), image2.get(), ibs)); 253f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon REPORTER_ASSERT(reporter, image2->unique()); 254f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon } 255f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon { 2569ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image1(surface->makeImageSnapshot(kB, SkSurface::kNo_ForceUnique)); 2579ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image2(surface->makeImageSnapshot(kB, SkSurface::kYes_ForceUnique)); 2589ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image3(surface->makeImageSnapshot(kB, SkSurface::kNo_ForceUnique)); 2599ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image4(surface->makeImageSnapshot(kB, SkSurface::kYes_ForceUnique)); 260f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon // Image 1 and 3 ought to be the same (or we're missing an optimization). 2619ce9d6772df650ceb0511f275e1a83dffa78ff72reed REPORTER_ASSERT(reporter, same_image(image1.get(), image3.get(), ibs)); 262f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon // If the surface is not direct then images 1 and 3 should alias the surface's 263f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon // store. 2649ce9d6772df650ceb0511f275e1a83dffa78ff72reed REPORTER_ASSERT(reporter, !surfaceIsDirect == same_image_surf(image1.get(), surface, ibs, sbs)); 265f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon // Image 2 should not be shared with any other image. 2669ce9d6772df650ceb0511f275e1a83dffa78ff72reed REPORTER_ASSERT(reporter, !same_image(image1.get(), image2.get(), ibs) && 2679ce9d6772df650ceb0511f275e1a83dffa78ff72reed !same_image(image3.get(), image2.get(), ibs) && 2689ce9d6772df650ceb0511f275e1a83dffa78ff72reed !same_image(image4.get(), image2.get(), ibs)); 269f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon REPORTER_ASSERT(reporter, image2->unique()); 2709ce9d6772df650ceb0511f275e1a83dffa78ff72reed REPORTER_ASSERT(reporter, !same_image_surf(image2.get(), surface, ibs, sbs)); 271f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon // Image 4 should not be shared with any other image. 2729ce9d6772df650ceb0511f275e1a83dffa78ff72reed REPORTER_ASSERT(reporter, !same_image(image1.get(), image4.get(), ibs) && 2739ce9d6772df650ceb0511f275e1a83dffa78ff72reed !same_image(image3.get(), image4.get(), ibs)); 2749ce9d6772df650ceb0511f275e1a83dffa78ff72reed REPORTER_ASSERT(reporter, !same_image_surf(image4.get(), surface, ibs, sbs)); 275f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon REPORTER_ASSERT(reporter, image4->unique()); 276f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon } 277f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon} 278f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon 279f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomonDEF_TEST(UniqueImageSnapshot, reporter) { 280f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon auto getImageBackingStore = [reporter](SkImage* image) { 281f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon SkPixmap pm; 282f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon bool success = image->peekPixels(&pm); 283f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon REPORTER_ASSERT(reporter, success); 284f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon return reinterpret_cast<intptr_t>(pm.addr()); 285f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon }; 286f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon auto getSufaceBackingStore = [reporter](SkSurface* surface) { 2876ceeebd37a43d879c120b6ba100ae1febdd67a18reed SkPixmap pmap; 2886ceeebd37a43d879c120b6ba100ae1febdd67a18reed const void* pixels = surface->getCanvas()->peekPixels(&pmap) ? pmap.addr() : nullptr; 289f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon REPORTER_ASSERT(reporter, pixels); 290f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon return reinterpret_cast<intptr_t>(pixels); 291f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon }; 292f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon 293e8f3062a36d3682f4019309a32b5b84dc9eddf8creed auto surface(create_surface()); 294e8f3062a36d3682f4019309a32b5b84dc9eddf8creed test_unique_image_snap(reporter, surface.get(), false, getImageBackingStore, 295e8f3062a36d3682f4019309a32b5b84dc9eddf8creed getSufaceBackingStore); 296e8f3062a36d3682f4019309a32b5b84dc9eddf8creed surface = create_direct_surface(); 297e8f3062a36d3682f4019309a32b5b84dc9eddf8creed test_unique_image_snap(reporter, surface.get(), true, getImageBackingStore, 298e8f3062a36d3682f4019309a32b5b84dc9eddf8creed getSufaceBackingStore); 299f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon} 300f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon 301f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon#if SK_SUPPORT_GPU 30268d9134bec16e91c4a6cde071bcaa579bc0801a7bsalomonDEF_GPUTEST_FOR_RENDERING_CONTEXTS(UniqueImageSnapshot_Gpu, reporter, ctxInfo) { 3038b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon GrContext* context = ctxInfo.grContext(); 304f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) { 305e8f3062a36d3682f4019309a32b5b84dc9eddf8creed auto surface(surface_func(context, kOpaque_SkAlphaType, nullptr)); 306f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon 307f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon auto imageBackingStore = [reporter](SkImage* image) { 308f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon GrTexture* texture = as_IB(image)->peekTexture(); 309f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon if (!texture) { 310f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon ERRORF(reporter, "Not texture backed."); 311f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon return static_cast<intptr_t>(0); 312f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon } 3138abb370aca280516f4861c6c942ec453aad018farobertphillips return static_cast<intptr_t>(texture->uniqueID()); 314f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon }; 315f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon 316f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon auto surfaceBackingStore = [reporter](SkSurface* surface) { 317175dd9b5e3d7d749738dac743d2ac360b5340187robertphillips GrDrawContext* dc = surface->getCanvas()->internal_private_accessTopLayerDrawContext(); 318175dd9b5e3d7d749738dac743d2ac360b5340187robertphillips GrRenderTarget* rt = dc->accessRenderTarget(); 319f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon if (!rt) { 320f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon ERRORF(reporter, "Not render target backed."); 321f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon return static_cast<intptr_t>(0); 322f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon } 3238abb370aca280516f4861c6c942ec453aad018farobertphillips return static_cast<intptr_t>(rt->uniqueID()); 324f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon }; 325f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon 326e8f3062a36d3682f4019309a32b5b84dc9eddf8creed test_unique_image_snap(reporter, surface.get(), false, imageBackingStore, 327e8f3062a36d3682f4019309a32b5b84dc9eddf8creed surfaceBackingStore); 328f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon 329f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon // Test again with a "direct" render target; 330f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon GrBackendObject textureObject = context->getGpu()->createTestingOnlyBackendTexture(nullptr, 3310a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel 10, 10, kRGBA_8888_GrPixelConfig, true); 332f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon GrBackendTextureDesc desc; 333f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon desc.fConfig = kRGBA_8888_GrPixelConfig; 334f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon desc.fWidth = 10; 335f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon desc.fHeight = 10; 336f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon desc.fFlags = kRenderTarget_GrBackendTextureFlag; 337f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon desc.fTextureHandle = textureObject; 3387e922765545f42ce691e4f3d5fbbd4e44ba47ff1robertphillips 339f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon { 3407e922765545f42ce691e4f3d5fbbd4e44ba47ff1robertphillips sk_sp<SkSurface> surface(SkSurface::MakeFromBackendTexture(context, desc, nullptr)); 341e8f3062a36d3682f4019309a32b5b84dc9eddf8creed test_unique_image_snap(reporter, surface.get(), true, imageBackingStore, 342f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon surfaceBackingStore); 343f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon } 3447e922765545f42ce691e4f3d5fbbd4e44ba47ff1robertphillips 345f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon context->getGpu()->deleteTestingOnlyBackendTexture(textureObject); 346f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon } 347f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon} 348f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon#endif 349f47b9a3b88a037a481eb70f01a4cf9f5be34dc28bsalomon 350179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#if SK_SUPPORT_GPU 3511f3923e4e5bf9afb9e52a15ced30e3854af73f7brobertphillips 352179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunenstatic void test_backend_handle_unique_id( 353179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen skiatest::Reporter* reporter, SkSurface* surface, 354179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen GrBackendObject (*func)(SkSurface*, SkSurface::BackendHandleAccess)) { 3559ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image0(surface->makeImageSnapshot()); 356179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen GrBackendObject obj = func(surface, SkSurface::kFlushRead_BackendHandleAccess); 357179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen REPORTER_ASSERT(reporter, obj != 0); 3589ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image1(surface->makeImageSnapshot()); 359179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen // just read access should not affect the snapshot 360179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen REPORTER_ASSERT(reporter, image0->uniqueID() == image1->uniqueID()); 361179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen 362179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen obj = func(surface, SkSurface::kFlushWrite_BackendHandleAccess); 363179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen REPORTER_ASSERT(reporter, obj != 0); 3649ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image2(surface->makeImageSnapshot()); 365179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen // expect a new image, since we claimed we would write 366179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen REPORTER_ASSERT(reporter, image0->uniqueID() != image2->uniqueID()); 367179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen 368179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen obj = func(surface, SkSurface::kDiscardWrite_BackendHandleAccess); 369179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen REPORTER_ASSERT(reporter, obj != 0); 3709ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image3(surface->makeImageSnapshot()); 371179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen // expect a new(er) image, since we claimed we would write 372179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen REPORTER_ASSERT(reporter, image0->uniqueID() != image3->uniqueID()); 373179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen REPORTER_ASSERT(reporter, image2->uniqueID() != image3->uniqueID()); 374179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 375179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen// No CPU test. 37668d9134bec16e91c4a6cde071bcaa579bc0801a7bsalomonDEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceBackendHandleAccessIDs_Gpu, reporter, ctxInfo) { 377179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) { 3781f3923e4e5bf9afb9e52a15ced30e3854af73f7brobertphillips for (auto& test_func : { &test_backend_handle_unique_id }) { 379179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& handle_access_func : 380179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen { &get_surface_backend_texture_handle, &get_surface_backend_render_target_handle}) { 3818b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon auto surface(surface_func(ctxInfo.grContext(), kPremul_SkAlphaType, nullptr)); 382e8f3062a36d3682f4019309a32b5b84dc9eddf8creed test_func(reporter, surface.get(), handle_access_func); 383179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen } 384179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen } 385179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen } 386179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 387179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#endif 388179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen 389179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen// Verify that the right canvas commands trigger a copy on write. 390179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunenstatic void test_copy_on_write(skiatest::Reporter* reporter, SkSurface* surface) { 391995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org SkCanvas* canvas = surface->getCanvas(); 392995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org 393995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org const SkRect testRect = 394995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org SkRect::MakeXYWH(SkIntToScalar(0), SkIntToScalar(0), 395995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org SkIntToScalar(4), SkIntToScalar(5)); 396995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org SkPath testPath; 397995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org testPath.addRect(SkRect::MakeXYWH(SkIntToScalar(0), SkIntToScalar(0), 398995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org SkIntToScalar(2), SkIntToScalar(1))); 399995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org 400995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org const SkIRect testIRect = SkIRect::MakeXYWH(0, 0, 2, 1); 401995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org 402995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org SkRegion testRegion; 403995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org testRegion.setRect(testIRect); 404995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org 405995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org 406995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org const SkColor testColor = 0x01020304; 407995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org const SkPaint testPaint; 408995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org const SkPoint testPoints[3] = { 409995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org {SkIntToScalar(0), SkIntToScalar(0)}, 410995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org {SkIntToScalar(2), SkIntToScalar(1)}, 411995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org {SkIntToScalar(0), SkIntToScalar(2)} 412995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org }; 413995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org const size_t testPointCount = 3; 414995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org 415995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org SkBitmap testBitmap; 416deee496cd30070e52556dcb538c2e5eb39b66b81mike@reedtribe.org testBitmap.allocN32Pixels(10, 10); 417d1ce77d548ab098c2f455e9b0fa1f195e75cd8edrobertphillips@google.com testBitmap.eraseColor(0); 418995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org 419995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org SkRRect testRRect; 420995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org testRRect.setRectXY(testRect, SK_Scalar1, SK_Scalar1); 421995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org 422995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org SkString testText("Hello World"); 423995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org const SkPoint testPoints2[] = { 424995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org { SkIntToScalar(0), SkIntToScalar(1) }, 425995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org { SkIntToScalar(1), SkIntToScalar(1) }, 426995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org { SkIntToScalar(2), SkIntToScalar(1) }, 427995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org { SkIntToScalar(3), SkIntToScalar(1) }, 428995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org { SkIntToScalar(4), SkIntToScalar(1) }, 429995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org { SkIntToScalar(5), SkIntToScalar(1) }, 430995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org { SkIntToScalar(6), SkIntToScalar(1) }, 431995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org { SkIntToScalar(7), SkIntToScalar(1) }, 432995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org { SkIntToScalar(8), SkIntToScalar(1) }, 433995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org { SkIntToScalar(9), SkIntToScalar(1) }, 434995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org { SkIntToScalar(10), SkIntToScalar(1) }, 435995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org }; 436995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org 437995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org#define EXPECT_COPY_ON_WRITE(command) \ 438995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org { \ 4399ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> imageBefore = surface->makeImageSnapshot(); \ 4409ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> aur_before(imageBefore); \ 441995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org canvas-> command ; \ 4429ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> imageAfter = surface->makeImageSnapshot(); \ 4439ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> aur_after(imageAfter); \ 444995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org REPORTER_ASSERT(reporter, imageBefore != imageAfter); \ 445995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org } 446995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org 447995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org EXPECT_COPY_ON_WRITE(clear(testColor)) 448995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org EXPECT_COPY_ON_WRITE(drawPaint(testPaint)) 449995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org EXPECT_COPY_ON_WRITE(drawPoints(SkCanvas::kPoints_PointMode, testPointCount, testPoints, \ 450995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org testPaint)) 451995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org EXPECT_COPY_ON_WRITE(drawOval(testRect, testPaint)) 452995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org EXPECT_COPY_ON_WRITE(drawRect(testRect, testPaint)) 453995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org EXPECT_COPY_ON_WRITE(drawRRect(testRRect, testPaint)) 454995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org EXPECT_COPY_ON_WRITE(drawPath(testPath, testPaint)) 455995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org EXPECT_COPY_ON_WRITE(drawBitmap(testBitmap, 0, 0)) 456e47829b6b1eeb6b0c97ccb3df3016d197046824creed EXPECT_COPY_ON_WRITE(drawBitmapRect(testBitmap, testRect, nullptr)) 45796fcdcc219d2a0d3579719b84b28bede76efba64halcanary EXPECT_COPY_ON_WRITE(drawBitmapNine(testBitmap, testIRect, testRect, nullptr)) 458995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org EXPECT_COPY_ON_WRITE(drawText(testText.c_str(), testText.size(), 0, 1, testPaint)) 459995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org EXPECT_COPY_ON_WRITE(drawPosText(testText.c_str(), testText.size(), testPoints2, \ 460995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org testPaint)) 46196fcdcc219d2a0d3579719b84b28bede76efba64halcanary EXPECT_COPY_ON_WRITE(drawTextOnPath(testText.c_str(), testText.size(), testPath, nullptr, \ 462995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org testPaint)) 463179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 464179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunenDEF_TEST(SurfaceCopyOnWrite, reporter) { 465e8f3062a36d3682f4019309a32b5b84dc9eddf8creed test_copy_on_write(reporter, create_surface().get()); 466179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 467179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#if SK_SUPPORT_GPU 468ab527a5bbfb1eae4f99a1435d349a44d00477d82egdanielDEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceCopyOnWrite_Gpu, reporter, ctxInfo) { 469179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) { 4708b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon auto surface(surface_func(ctxInfo.grContext(), kPremul_SkAlphaType, nullptr)); 471e8f3062a36d3682f4019309a32b5b84dc9eddf8creed test_copy_on_write(reporter, surface.get()); 472e2639089bddc4fbb129ae039cb12c01be087b397fmalita } 473995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org} 474179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#endif 475995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org 476179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunenstatic void test_writable_after_snapshot_release(skiatest::Reporter* reporter, 477179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkSurface* surface) { 478af0583528c7dd5344abfe14347377011abe374e2junov@chromium.org // This test succeeds by not triggering an assertion. 479af0583528c7dd5344abfe14347377011abe374e2junov@chromium.org // The test verifies that the surface remains writable (usable) after 480af0583528c7dd5344abfe14347377011abe374e2junov@chromium.org // acquiring and releasing a snapshot without triggering a copy on write. 481af0583528c7dd5344abfe14347377011abe374e2junov@chromium.org SkCanvas* canvas = surface->getCanvas(); 482af0583528c7dd5344abfe14347377011abe374e2junov@chromium.org canvas->clear(1); 4839ce9d6772df650ceb0511f275e1a83dffa78ff72reed surface->makeImageSnapshot(); // Create and destroy SkImage 4844d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org canvas->clear(2); // Must not assert internally 485995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org} 486179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunenDEF_TEST(SurfaceWriteableAfterSnapshotRelease, reporter) { 487e8f3062a36d3682f4019309a32b5b84dc9eddf8creed test_writable_after_snapshot_release(reporter, create_surface().get()); 488179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 489179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#if SK_SUPPORT_GPU 490ab527a5bbfb1eae4f99a1435d349a44d00477d82egdanielDEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceWriteableAfterSnapshotRelease_Gpu, reporter, ctxInfo) { 491179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) { 4928b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon auto surface(surface_func(ctxInfo.grContext(), kPremul_SkAlphaType, nullptr)); 493e8f3062a36d3682f4019309a32b5b84dc9eddf8creed test_writable_after_snapshot_release(reporter, surface.get()); 494179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen } 495179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 496179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#endif 497da90474b5fcc019fb0971d12360bd05213ad4dc8junov@chromium.org 498b516a4177931b8febf859752b49f094f70539eaejunov@chromium.org#if SK_SUPPORT_GPU 499179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunenstatic void test_crbug263329(skiatest::Reporter* reporter, 500179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkSurface* surface1, 501179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkSurface* surface2) { 5024d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org // This is a regression test for crbug.com/263329 5034d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org // Bug was caused by onCopyOnWrite releasing the old surface texture 5044d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org // back to the scratch texture pool even though the texture is used 5054d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org // by and active SkImage_Gpu. 5064d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org SkCanvas* canvas1 = surface1->getCanvas(); 5074d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org SkCanvas* canvas2 = surface2->getCanvas(); 5084d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org canvas1->clear(1); 5099ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image1(surface1->makeImageSnapshot()); 5104d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org // Trigger copy on write, new backing is a scratch texture 5114d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org canvas1->clear(2); 5129ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image2(surface1->makeImageSnapshot()); 5134d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org // Trigger copy on write, old backing should not be returned to scratch 5144d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org // pool because it is held by image2 5154d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org canvas1->clear(3); 5164d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org 5174d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org canvas2->clear(4); 5189ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image3(surface2->makeImageSnapshot()); 5194d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org // Trigger copy on write on surface2. The new backing store should not 5204d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org // be recycling a texture that is held by an existing image. 5214d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org canvas2->clear(5); 5229ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image4(surface2->makeImageSnapshot()); 52384a4e5a8d683bf17d6c3058b977b9dfb000428afbsalomon REPORTER_ASSERT(reporter, as_IB(image4)->peekTexture() != as_IB(image3)->peekTexture()); 5244d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org // The following assertion checks crbug.com/263329 52584a4e5a8d683bf17d6c3058b977b9dfb000428afbsalomon REPORTER_ASSERT(reporter, as_IB(image4)->peekTexture() != as_IB(image2)->peekTexture()); 52684a4e5a8d683bf17d6c3058b977b9dfb000428afbsalomon REPORTER_ASSERT(reporter, as_IB(image4)->peekTexture() != as_IB(image1)->peekTexture()); 52784a4e5a8d683bf17d6c3058b977b9dfb000428afbsalomon REPORTER_ASSERT(reporter, as_IB(image3)->peekTexture() != as_IB(image2)->peekTexture()); 52884a4e5a8d683bf17d6c3058b977b9dfb000428afbsalomon REPORTER_ASSERT(reporter, as_IB(image3)->peekTexture() != as_IB(image1)->peekTexture()); 52984a4e5a8d683bf17d6c3058b977b9dfb000428afbsalomon REPORTER_ASSERT(reporter, as_IB(image2)->peekTexture() != as_IB(image1)->peekTexture()); 5304d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org} 531ab527a5bbfb1eae4f99a1435d349a44d00477d82egdanielDEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceCRBug263329_Gpu, reporter, ctxInfo) { 532179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) { 5338b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon auto surface1(surface_func(ctxInfo.grContext(), kPremul_SkAlphaType, nullptr)); 5348b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon auto surface2(surface_func(ctxInfo.grContext(), kPremul_SkAlphaType, nullptr)); 535e8f3062a36d3682f4019309a32b5b84dc9eddf8creed test_crbug263329(reporter, surface1.get(), surface2.get()); 536179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen } 537179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 538179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#endif 5394d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org 540179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunenDEF_TEST(SurfaceGetTexture, reporter) { 541e8f3062a36d3682f4019309a32b5b84dc9eddf8creed auto surface(create_surface()); 5429ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image(surface->makeImageSnapshot()); 54384a4e5a8d683bf17d6c3058b977b9dfb000428afbsalomon REPORTER_ASSERT(reporter, as_IB(image)->peekTexture() == nullptr); 544179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen surface->notifyContentWillChange(SkSurface::kDiscard_ContentChangeMode); 54584a4e5a8d683bf17d6c3058b977b9dfb000428afbsalomon REPORTER_ASSERT(reporter, as_IB(image)->peekTexture() == nullptr); 546179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 547179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#if SK_SUPPORT_GPU 548ab527a5bbfb1eae4f99a1435d349a44d00477d82egdanielDEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfacepeekTexture_Gpu, reporter, ctxInfo) { 549179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) { 5508b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon auto surface(surface_func(ctxInfo.grContext(), kPremul_SkAlphaType, nullptr)); 5519ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image(surface->makeImageSnapshot()); 55284a4e5a8d683bf17d6c3058b977b9dfb000428afbsalomon GrTexture* texture = as_IB(image)->peekTexture(); 55349f085dddff10473b6ebf832a974288300224e60bsalomon REPORTER_ASSERT(reporter, texture); 554da90474b5fcc019fb0971d12360bd05213ad4dc8junov@chromium.org REPORTER_ASSERT(reporter, 0 != texture->getTextureHandle()); 555179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen surface->notifyContentWillChange(SkSurface::kDiscard_ContentChangeMode); 55684a4e5a8d683bf17d6c3058b977b9dfb000428afbsalomon REPORTER_ASSERT(reporter, as_IB(image)->peekTexture() == texture); 557da90474b5fcc019fb0971d12360bd05213ad4dc8junov@chromium.org } 558da90474b5fcc019fb0971d12360bd05213ad4dc8junov@chromium.org} 559179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#endif 560eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon 561179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#if SK_SUPPORT_GPU 5623582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon#include "GrGpuResourcePriv.h" 563eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon#include "SkGpuDevice.h" 564eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon#include "SkImage_Gpu.h" 565eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon#include "SkSurface_Gpu.h" 566eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon 567e8f3062a36d3682f4019309a32b5b84dc9eddf8creedstatic SkBudgeted is_budgeted(const sk_sp<SkSurface>& surf) { 568e8f3062a36d3682f4019309a32b5b84dc9eddf8creed SkSurface_Gpu* gsurf = (SkSurface_Gpu*)surf.get(); 569ea70c4bb22394c8dcc29a369d3422a2b8f3b3e80robertphillips return gsurf->getDevice()->accessDrawContext()->accessRenderTarget()->resourcePriv().isBudgeted(); 570eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon} 571eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon 5725ec26ae9bfca635ccc98283aad5deda11519d826bsalomonstatic SkBudgeted is_budgeted(SkImage* image) { 57384a4e5a8d683bf17d6c3058b977b9dfb000428afbsalomon return ((SkImage_Gpu*)image)->peekTexture()->resourcePriv().isBudgeted(); 574eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon} 575eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon 5769ce9d6772df650ceb0511f275e1a83dffa78ff72reedstatic SkBudgeted is_budgeted(const sk_sp<SkImage> image) { 5779ce9d6772df650ceb0511f275e1a83dffa78ff72reed return is_budgeted(image.get()); 5789ce9d6772df650ceb0511f275e1a83dffa78ff72reed} 5799ce9d6772df650ceb0511f275e1a83dffa78ff72reed 580ab527a5bbfb1eae4f99a1435d349a44d00477d82egdanielDEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceBudget, reporter, ctxInfo) { 581eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon SkImageInfo info = SkImageInfo::MakeN32Premul(8,8); 5825ec26ae9bfca635ccc98283aad5deda11519d826bsalomon for (auto sbudgeted : { SkBudgeted::kNo, SkBudgeted::kYes }) { 5835ec26ae9bfca635ccc98283aad5deda11519d826bsalomon for (auto ibudgeted : { SkBudgeted::kNo, SkBudgeted::kYes }) { 5848b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon auto surface(SkSurface::MakeRenderTarget(ctxInfo.grContext(), sbudgeted, info)); 585eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon SkASSERT(surface); 586eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon REPORTER_ASSERT(reporter, sbudgeted == is_budgeted(surface)); 587eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon 5889ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image(surface->makeImageSnapshot(ibudgeted)); 589eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon 590eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon // Initially the image shares a texture with the surface, and the surface decides 591eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon // whether it is budgeted or not. 592eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon REPORTER_ASSERT(reporter, sbudgeted == is_budgeted(surface)); 593eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon REPORTER_ASSERT(reporter, sbudgeted == is_budgeted(image)); 594eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon 595eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon // Now trigger copy-on-write 596eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon surface->getCanvas()->clear(SK_ColorBLUE); 597eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon 598eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon // They don't share a texture anymore. They should each have made their own budget 599eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon // decision. 600eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon REPORTER_ASSERT(reporter, sbudgeted == is_budgeted(surface)); 601eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon REPORTER_ASSERT(reporter, ibudgeted == is_budgeted(image)); 602eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon } 603eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon } 604eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon} 605b516a4177931b8febf859752b49f094f70539eaejunov@chromium.org#endif 606da90474b5fcc019fb0971d12360bd05213ad4dc8junov@chromium.org 607179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunenstatic void test_no_canvas1(skiatest::Reporter* reporter, 608179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkSurface* surface, 609179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkSurface::ContentChangeMode mode) { 610179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen // Test passes by not asserting 611179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen surface->notifyContentWillChange(mode); 612179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkDEBUGCODE(surface->validate();) 613179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 614179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunenstatic void test_no_canvas2(skiatest::Reporter* reporter, 615179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkSurface* surface, 616179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkSurface::ContentChangeMode mode) { 617acea3ef448c9903de3aa6a013c839dce577e6ce3junov@chromium.org // Verifies the robustness of SkSurface for handling use cases where calls 618acea3ef448c9903de3aa6a013c839dce577e6ce3junov@chromium.org // are made before a canvas is created. 6199ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image1 = surface->makeImageSnapshot(); 6209ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> aur_image1(image1); 621179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkDEBUGCODE(image1->validate();) 622179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkDEBUGCODE(surface->validate();) 623179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen surface->notifyContentWillChange(mode); 624179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkDEBUGCODE(image1->validate();) 625179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkDEBUGCODE(surface->validate();) 6269ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image2 = surface->makeImageSnapshot(); 6279ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> aur_image2(image2); 628179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkDEBUGCODE(image2->validate();) 629179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkDEBUGCODE(surface->validate();) 630179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen REPORTER_ASSERT(reporter, image1 != image2); 631179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 632179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunenDEF_TEST(SurfaceNoCanvas, reporter) { 633179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkSurface::ContentChangeMode modes[] = 634179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen { SkSurface::kDiscard_ContentChangeMode, SkSurface::kRetain_ContentChangeMode}; 635179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& test_func : { &test_no_canvas1, &test_no_canvas2 }) { 636179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& mode : modes) { 637e8f3062a36d3682f4019309a32b5b84dc9eddf8creed test_func(reporter, create_surface().get(), mode); 638179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen } 639acea3ef448c9903de3aa6a013c839dce577e6ce3junov@chromium.org } 640acea3ef448c9903de3aa6a013c839dce577e6ce3junov@chromium.org} 641b516a4177931b8febf859752b49f094f70539eaejunov@chromium.org#if SK_SUPPORT_GPU 642ab527a5bbfb1eae4f99a1435d349a44d00477d82egdanielDEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceNoCanvas_Gpu, reporter, ctxInfo) { 643179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkSurface::ContentChangeMode modes[] = 644179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen { SkSurface::kDiscard_ContentChangeMode, SkSurface::kRetain_ContentChangeMode}; 645179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) { 646179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& test_func : { &test_no_canvas1, &test_no_canvas2 }) { 647179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& mode : modes) { 6488b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon auto surface(surface_func(ctxInfo.grContext(), kPremul_SkAlphaType, nullptr)); 649e8f3062a36d3682f4019309a32b5b84dc9eddf8creed test_func(reporter, surface.get(), mode); 650e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon } 6513bddb38e6468c6294e40e5307f05e6b56bdd6a6crobertphillips@google.com } 652af0583528c7dd5344abfe14347377011abe374e2junov@chromium.org } 653995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org} 654179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#endif 6559cd016e9b63f3827580d5b19a187dbf26b8e1436reed 6569cd016e9b63f3827580d5b19a187dbf26b8e1436reedstatic void check_rowbytes_remain_consistent(SkSurface* surface, skiatest::Reporter* reporter) { 6576ceeebd37a43d879c120b6ba100ae1febdd67a18reed SkPixmap surfacePM; 6586ceeebd37a43d879c120b6ba100ae1febdd67a18reed REPORTER_ASSERT(reporter, surface->peekPixels(&surfacePM)); 6599cd016e9b63f3827580d5b19a187dbf26b8e1436reed 6609ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image(surface->makeImageSnapshot()); 6616ceeebd37a43d879c120b6ba100ae1febdd67a18reed SkPixmap pm; 6626ceeebd37a43d879c120b6ba100ae1febdd67a18reed REPORTER_ASSERT(reporter, image->peekPixels(&pm)); 6639cd016e9b63f3827580d5b19a187dbf26b8e1436reed 6646ceeebd37a43d879c120b6ba100ae1febdd67a18reed REPORTER_ASSERT(reporter, surfacePM.rowBytes() == pm.rowBytes()); 6659cd016e9b63f3827580d5b19a187dbf26b8e1436reed 6669cd016e9b63f3827580d5b19a187dbf26b8e1436reed // trigger a copy-on-write 6679cd016e9b63f3827580d5b19a187dbf26b8e1436reed surface->getCanvas()->drawPaint(SkPaint()); 6689ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image2(surface->makeImageSnapshot()); 6699cd016e9b63f3827580d5b19a187dbf26b8e1436reed REPORTER_ASSERT(reporter, image->uniqueID() != image2->uniqueID()); 6709cd016e9b63f3827580d5b19a187dbf26b8e1436reed 6716ceeebd37a43d879c120b6ba100ae1febdd67a18reed SkPixmap pm2; 6726ceeebd37a43d879c120b6ba100ae1febdd67a18reed REPORTER_ASSERT(reporter, image2->peekPixels(&pm2)); 6736ceeebd37a43d879c120b6ba100ae1febdd67a18reed REPORTER_ASSERT(reporter, pm2.rowBytes() == pm.rowBytes()); 6749cd016e9b63f3827580d5b19a187dbf26b8e1436reed} 6759cd016e9b63f3827580d5b19a187dbf26b8e1436reed 6769cd016e9b63f3827580d5b19a187dbf26b8e1436reedDEF_TEST(surface_rowbytes, reporter) { 6779cd016e9b63f3827580d5b19a187dbf26b8e1436reed const SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100); 6789cd016e9b63f3827580d5b19a187dbf26b8e1436reed 679e8f3062a36d3682f4019309a32b5b84dc9eddf8creed auto surf0(SkSurface::MakeRaster(info)); 680e8f3062a36d3682f4019309a32b5b84dc9eddf8creed check_rowbytes_remain_consistent(surf0.get(), reporter); 6819cd016e9b63f3827580d5b19a187dbf26b8e1436reed 6829cd016e9b63f3827580d5b19a187dbf26b8e1436reed // specify a larger rowbytes 683e8f3062a36d3682f4019309a32b5b84dc9eddf8creed auto surf1(SkSurface::MakeRaster(info, 500, nullptr)); 684e8f3062a36d3682f4019309a32b5b84dc9eddf8creed check_rowbytes_remain_consistent(surf1.get(), reporter); 6859cd016e9b63f3827580d5b19a187dbf26b8e1436reed 6869cd016e9b63f3827580d5b19a187dbf26b8e1436reed // Try some illegal rowByte values 687e8f3062a36d3682f4019309a32b5b84dc9eddf8creed auto s = SkSurface::MakeRaster(info, 396, nullptr); // needs to be at least 400 6889cd016e9b63f3827580d5b19a187dbf26b8e1436reed REPORTER_ASSERT(reporter, nullptr == s); 689e8f3062a36d3682f4019309a32b5b84dc9eddf8creed s = SkSurface::MakeRaster(info, 1 << 30, nullptr); // allocation to large 6909cd016e9b63f3827580d5b19a187dbf26b8e1436reed REPORTER_ASSERT(reporter, nullptr == s); 6919cd016e9b63f3827580d5b19a187dbf26b8e1436reed} 692e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon 69303912f141fba6a5c17ac7e8fbe5998ac3834e29cfmalitaDEF_TEST(surface_raster_zeroinitialized, reporter) { 69403912f141fba6a5c17ac7e8fbe5998ac3834e29cfmalita sk_sp<SkSurface> s(SkSurface::MakeRasterN32Premul(100, 100)); 69503912f141fba6a5c17ac7e8fbe5998ac3834e29cfmalita SkPixmap pixmap; 69603912f141fba6a5c17ac7e8fbe5998ac3834e29cfmalita REPORTER_ASSERT(reporter, s->peekPixels(&pixmap)); 69703912f141fba6a5c17ac7e8fbe5998ac3834e29cfmalita 69803912f141fba6a5c17ac7e8fbe5998ac3834e29cfmalita for (int i = 0; i < pixmap.info().width(); ++i) { 69903912f141fba6a5c17ac7e8fbe5998ac3834e29cfmalita for (int j = 0; j < pixmap.info().height(); ++j) { 70003912f141fba6a5c17ac7e8fbe5998ac3834e29cfmalita REPORTER_ASSERT(reporter, *pixmap.addr32(i, j) == 0); 70103912f141fba6a5c17ac7e8fbe5998ac3834e29cfmalita } 70203912f141fba6a5c17ac7e8fbe5998ac3834e29cfmalita } 70303912f141fba6a5c17ac7e8fbe5998ac3834e29cfmalita} 70403912f141fba6a5c17ac7e8fbe5998ac3834e29cfmalita 705e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon#if SK_SUPPORT_GPU 706c4025189d31efcb0d54bf14b7712b38725f86c13ericrkstatic sk_sp<SkSurface> create_gpu_surface_backend_texture( 707c4025189d31efcb0d54bf14b7712b38725f86c13ericrk GrContext* context, int sampleCnt, uint32_t color, GrBackendObject* outTexture) { 708c4025189d31efcb0d54bf14b7712b38725f86c13ericrk const int kWidth = 10; 709c4025189d31efcb0d54bf14b7712b38725f86c13ericrk const int kHeight = 10; 710c4025189d31efcb0d54bf14b7712b38725f86c13ericrk SkAutoTDeleteArray<uint32_t> pixels(new uint32_t[kWidth * kHeight]); 711c4025189d31efcb0d54bf14b7712b38725f86c13ericrk sk_memset32(pixels.get(), color, kWidth * kHeight); 712c4025189d31efcb0d54bf14b7712b38725f86c13ericrk GrBackendTextureDesc desc; 713c4025189d31efcb0d54bf14b7712b38725f86c13ericrk desc.fConfig = kRGBA_8888_GrPixelConfig; 714c4025189d31efcb0d54bf14b7712b38725f86c13ericrk desc.fWidth = kWidth; 715c4025189d31efcb0d54bf14b7712b38725f86c13ericrk desc.fHeight = kHeight; 716c4025189d31efcb0d54bf14b7712b38725f86c13ericrk desc.fFlags = kRenderTarget_GrBackendTextureFlag; 717c4025189d31efcb0d54bf14b7712b38725f86c13ericrk desc.fTextureHandle = context->getGpu()->createTestingOnlyBackendTexture( 7180a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel pixels.get(), kWidth, kHeight, kRGBA_8888_GrPixelConfig, true); 719c4025189d31efcb0d54bf14b7712b38725f86c13ericrk desc.fSampleCnt = sampleCnt; 720c4025189d31efcb0d54bf14b7712b38725f86c13ericrk sk_sp<SkSurface> surface = SkSurface::MakeFromBackendTexture(context, desc, nullptr); 721c4025189d31efcb0d54bf14b7712b38725f86c13ericrk if (!surface) { 722c4025189d31efcb0d54bf14b7712b38725f86c13ericrk context->getGpu()->deleteTestingOnlyBackendTexture(desc.fTextureHandle); 723c4025189d31efcb0d54bf14b7712b38725f86c13ericrk return nullptr; 724c4025189d31efcb0d54bf14b7712b38725f86c13ericrk } 725c4025189d31efcb0d54bf14b7712b38725f86c13ericrk *outTexture = desc.fTextureHandle; 726c4025189d31efcb0d54bf14b7712b38725f86c13ericrk return surface; 727c4025189d31efcb0d54bf14b7712b38725f86c13ericrk} 728c4025189d31efcb0d54bf14b7712b38725f86c13ericrk 729c4025189d31efcb0d54bf14b7712b38725f86c13ericrkstatic sk_sp<SkSurface> create_gpu_surface_backend_texture_as_render_target( 730c4025189d31efcb0d54bf14b7712b38725f86c13ericrk GrContext* context, int sampleCnt, uint32_t color, GrBackendObject* outTexture) { 731c4025189d31efcb0d54bf14b7712b38725f86c13ericrk const int kWidth = 10; 732c4025189d31efcb0d54bf14b7712b38725f86c13ericrk const int kHeight = 10; 733c4025189d31efcb0d54bf14b7712b38725f86c13ericrk SkAutoTDeleteArray<uint32_t> pixels(new uint32_t[kWidth * kHeight]); 734c4025189d31efcb0d54bf14b7712b38725f86c13ericrk sk_memset32(pixels.get(), color, kWidth * kHeight); 735c4025189d31efcb0d54bf14b7712b38725f86c13ericrk GrBackendTextureDesc desc; 736c4025189d31efcb0d54bf14b7712b38725f86c13ericrk desc.fConfig = kRGBA_8888_GrPixelConfig; 737c4025189d31efcb0d54bf14b7712b38725f86c13ericrk desc.fWidth = kWidth; 738c4025189d31efcb0d54bf14b7712b38725f86c13ericrk desc.fHeight = kHeight; 739c4025189d31efcb0d54bf14b7712b38725f86c13ericrk desc.fFlags = kRenderTarget_GrBackendTextureFlag; 740c4025189d31efcb0d54bf14b7712b38725f86c13ericrk desc.fTextureHandle = context->getGpu()->createTestingOnlyBackendTexture( 7410a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel pixels.get(), kWidth, kHeight, kRGBA_8888_GrPixelConfig, true); 742c4025189d31efcb0d54bf14b7712b38725f86c13ericrk desc.fSampleCnt = sampleCnt; 743c4025189d31efcb0d54bf14b7712b38725f86c13ericrk sk_sp<SkSurface> surface = SkSurface::MakeFromBackendTextureAsRenderTarget(context, desc, 744c4025189d31efcb0d54bf14b7712b38725f86c13ericrk nullptr); 745c4025189d31efcb0d54bf14b7712b38725f86c13ericrk if (!surface) { 746c4025189d31efcb0d54bf14b7712b38725f86c13ericrk context->getGpu()->deleteTestingOnlyBackendTexture(desc.fTextureHandle); 747c4025189d31efcb0d54bf14b7712b38725f86c13ericrk return nullptr; 748c4025189d31efcb0d54bf14b7712b38725f86c13ericrk } 749c4025189d31efcb0d54bf14b7712b38725f86c13ericrk *outTexture = desc.fTextureHandle; 750c4025189d31efcb0d54bf14b7712b38725f86c13ericrk return surface; 751c4025189d31efcb0d54bf14b7712b38725f86c13ericrk} 752e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon 753c4025189d31efcb0d54bf14b7712b38725f86c13ericrkstatic void test_surface_clear(skiatest::Reporter* reporter, sk_sp<SkSurface> surface, 754c4025189d31efcb0d54bf14b7712b38725f86c13ericrk std::function<GrSurface*(SkSurface*)> grSurfaceGetter, 755c4025189d31efcb0d54bf14b7712b38725f86c13ericrk uint32_t expectedValue) { 756e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon if (!surface) { 757e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon ERRORF(reporter, "Could not create GPU SkSurface."); 758e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon return; 759e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon } 760e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon int w = surface->width(); 761e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon int h = surface->height(); 762e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon SkAutoTDeleteArray<uint32_t> pixels(new uint32_t[w * h]); 763c4025189d31efcb0d54bf14b7712b38725f86c13ericrk sk_memset32(pixels.get(), ~expectedValue, w * h); 764e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon 765e8f3062a36d3682f4019309a32b5b84dc9eddf8creed SkAutoTUnref<GrSurface> grSurface(SkSafeRef(grSurfaceGetter(surface.get()))); 766e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon if (!grSurface) { 767e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon ERRORF(reporter, "Could access render target of GPU SkSurface."); 768e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon return; 769e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon } 7702fba80912027999b560a97a832948c37ab36acfebsalomon surface.reset(); 771e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon grSurface->readPixels(0, 0, w, h, kRGBA_8888_GrPixelConfig, pixels.get()); 772e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon for (int y = 0; y < h; ++y) { 773e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon for (int x = 0; x < w; ++x) { 774e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon uint32_t pixel = pixels.get()[y * w + x]; 775e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon if (pixel != expectedValue) { 776e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon SkString msg; 777e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon if (expectedValue) { 778e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon msg = "SkSurface should have left render target unmodified"; 779e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon } else { 780e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon msg = "SkSurface should have cleared the render target"; 781e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon } 782e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon ERRORF(reporter, 783e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon "%s but read 0x%08x (instead of 0x%08x) at %x,%d", msg.c_str(), pixel, 784e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon expectedValue, x, y); 785e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon return; 786e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon } 787e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon } 788e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon } 789e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon} 790e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon 791758586c7f11a6b3529bd4a1c9b4e982a0d0b0582bsalomonDEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SurfaceClear_Gpu, reporter, ctxInfo) { 7928b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon GrContext* context = ctxInfo.grContext(); 793c4025189d31efcb0d54bf14b7712b38725f86c13ericrk 794e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon std::function<GrSurface*(SkSurface*)> grSurfaceGetters[] = { 795ab527a5bbfb1eae4f99a1435d349a44d00477d82egdaniel [] (SkSurface* s){ 796175dd9b5e3d7d749738dac743d2ac360b5340187robertphillips GrDrawContext* dc = s->getCanvas()->internal_private_accessTopLayerDrawContext(); 797175dd9b5e3d7d749738dac743d2ac360b5340187robertphillips return dc->accessRenderTarget(); }, 7989ce9d6772df650ceb0511f275e1a83dffa78ff72reed [] (SkSurface* s){ sk_sp<SkImage> i(s->makeImageSnapshot()); 799c4025189d31efcb0d54bf14b7712b38725f86c13ericrk return as_IB(i)->peekTexture(); } 800e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon }; 801c4025189d31efcb0d54bf14b7712b38725f86c13ericrk 802e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon for (auto grSurfaceGetter : grSurfaceGetters) { 803c4025189d31efcb0d54bf14b7712b38725f86c13ericrk // Test that non-wrapped RTs are created clear. 804e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon for (auto& surface_func : {&create_gpu_surface, &create_gpu_scratch_surface}) { 805e8f3062a36d3682f4019309a32b5b84dc9eddf8creed auto surface = surface_func(context, kPremul_SkAlphaType, nullptr); 806e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon test_surface_clear(reporter, surface, grSurfaceGetter, 0x0); 807e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon } 808e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon // Wrapped RTs are *not* supposed to clear (to allow client to partially update a surface). 809c4025189d31efcb0d54bf14b7712b38725f86c13ericrk const uint32_t kOrigColor = 0xABABABAB; 810c4025189d31efcb0d54bf14b7712b38725f86c13ericrk for (auto& surfaceFunc : {&create_gpu_surface_backend_texture, 811c4025189d31efcb0d54bf14b7712b38725f86c13ericrk &create_gpu_surface_backend_texture_as_render_target}) { 812c4025189d31efcb0d54bf14b7712b38725f86c13ericrk GrBackendObject textureObject; 813c4025189d31efcb0d54bf14b7712b38725f86c13ericrk auto surface = surfaceFunc(context, 0, kOrigColor, &textureObject); 814c4025189d31efcb0d54bf14b7712b38725f86c13ericrk test_surface_clear(reporter, surface, grSurfaceGetter, kOrigColor); 815c4025189d31efcb0d54bf14b7712b38725f86c13ericrk surface.reset(); 816c4025189d31efcb0d54bf14b7712b38725f86c13ericrk context->getGpu()->deleteTestingOnlyBackendTexture(textureObject); 817c4025189d31efcb0d54bf14b7712b38725f86c13ericrk } 818c4025189d31efcb0d54bf14b7712b38725f86c13ericrk } 819c4025189d31efcb0d54bf14b7712b38725f86c13ericrk} 820c4025189d31efcb0d54bf14b7712b38725f86c13ericrk 821c4025189d31efcb0d54bf14b7712b38725f86c13ericrkstatic void test_surface_draw_partially( 822c4025189d31efcb0d54bf14b7712b38725f86c13ericrk skiatest::Reporter* reporter, sk_sp<SkSurface> surface, uint32_t origColor) { 823c4025189d31efcb0d54bf14b7712b38725f86c13ericrk const int kW = surface->width(); 824c4025189d31efcb0d54bf14b7712b38725f86c13ericrk const int kH = surface->height(); 825c4025189d31efcb0d54bf14b7712b38725f86c13ericrk SkPaint paint; 826c4025189d31efcb0d54bf14b7712b38725f86c13ericrk const SkColor kRectColor = ~origColor | 0xFF000000; 827c4025189d31efcb0d54bf14b7712b38725f86c13ericrk paint.setColor(kRectColor); 828c4025189d31efcb0d54bf14b7712b38725f86c13ericrk surface->getCanvas()->drawRect(SkRect::MakeWH(SkIntToScalar(kW), SkIntToScalar(kH)/2), 829c4025189d31efcb0d54bf14b7712b38725f86c13ericrk paint); 830c4025189d31efcb0d54bf14b7712b38725f86c13ericrk SkAutoTDeleteArray<uint32_t> pixels(new uint32_t[kW * kH]); 831c4025189d31efcb0d54bf14b7712b38725f86c13ericrk sk_memset32(pixels.get(), ~origColor, kW * kH); 832c4025189d31efcb0d54bf14b7712b38725f86c13ericrk // Read back RGBA to avoid format conversions that may not be supported on all platforms. 833c4025189d31efcb0d54bf14b7712b38725f86c13ericrk SkImageInfo readInfo = SkImageInfo::Make(kW, kH, kRGBA_8888_SkColorType, kPremul_SkAlphaType); 834c4025189d31efcb0d54bf14b7712b38725f86c13ericrk SkAssertResult(surface->readPixels(readInfo, pixels.get(), kW * sizeof(uint32_t), 0, 0)); 835c4025189d31efcb0d54bf14b7712b38725f86c13ericrk bool stop = false; 836c4025189d31efcb0d54bf14b7712b38725f86c13ericrk SkPMColor origColorPM = SkPackARGB_as_RGBA((origColor >> 24 & 0xFF), 837c4025189d31efcb0d54bf14b7712b38725f86c13ericrk (origColor >> 0 & 0xFF), 838c4025189d31efcb0d54bf14b7712b38725f86c13ericrk (origColor >> 8 & 0xFF), 839c4025189d31efcb0d54bf14b7712b38725f86c13ericrk (origColor >> 16 & 0xFF)); 840c4025189d31efcb0d54bf14b7712b38725f86c13ericrk SkPMColor rectColorPM = SkPackARGB_as_RGBA((kRectColor >> 24 & 0xFF), 841c4025189d31efcb0d54bf14b7712b38725f86c13ericrk (kRectColor >> 16 & 0xFF), 842c4025189d31efcb0d54bf14b7712b38725f86c13ericrk (kRectColor >> 8 & 0xFF), 843c4025189d31efcb0d54bf14b7712b38725f86c13ericrk (kRectColor >> 0 & 0xFF)); 844c4025189d31efcb0d54bf14b7712b38725f86c13ericrk for (int y = 0; y < kH/2 && !stop; ++y) { 845c4025189d31efcb0d54bf14b7712b38725f86c13ericrk for (int x = 0; x < kW && !stop; ++x) { 846c4025189d31efcb0d54bf14b7712b38725f86c13ericrk REPORTER_ASSERT(reporter, rectColorPM == pixels[x + y * kW]); 847c4025189d31efcb0d54bf14b7712b38725f86c13ericrk if (rectColorPM != pixels[x + y * kW]) { 848c4025189d31efcb0d54bf14b7712b38725f86c13ericrk stop = true; 849c4025189d31efcb0d54bf14b7712b38725f86c13ericrk } 850c4025189d31efcb0d54bf14b7712b38725f86c13ericrk } 851c4025189d31efcb0d54bf14b7712b38725f86c13ericrk } 852c4025189d31efcb0d54bf14b7712b38725f86c13ericrk stop = false; 853c4025189d31efcb0d54bf14b7712b38725f86c13ericrk for (int y = kH/2; y < kH && !stop; ++y) { 854c4025189d31efcb0d54bf14b7712b38725f86c13ericrk for (int x = 0; x < kW && !stop; ++x) { 855c4025189d31efcb0d54bf14b7712b38725f86c13ericrk REPORTER_ASSERT(reporter, origColorPM == pixels[x + y * kW]); 856c4025189d31efcb0d54bf14b7712b38725f86c13ericrk if (origColorPM != pixels[x + y * kW]) { 857c4025189d31efcb0d54bf14b7712b38725f86c13ericrk stop = true; 858c4025189d31efcb0d54bf14b7712b38725f86c13ericrk } 859c4025189d31efcb0d54bf14b7712b38725f86c13ericrk } 860c4025189d31efcb0d54bf14b7712b38725f86c13ericrk } 861c4025189d31efcb0d54bf14b7712b38725f86c13ericrk} 862e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon 863ab527a5bbfb1eae4f99a1435d349a44d00477d82egdanielDEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfacePartialDraw_Gpu, reporter, ctxInfo) { 8648b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon GrGpu* gpu = ctxInfo.grContext()->getGpu(); 865c4025189d31efcb0d54bf14b7712b38725f86c13ericrk if (!gpu) { 866c4025189d31efcb0d54bf14b7712b38725f86c13ericrk return; 867c4025189d31efcb0d54bf14b7712b38725f86c13ericrk } 868c4025189d31efcb0d54bf14b7712b38725f86c13ericrk static const uint32_t kOrigColor = 0xFFAABBCC; 8690736f3386820f19c0fe90b5dda2094e253780071ericrk 870c4025189d31efcb0d54bf14b7712b38725f86c13ericrk for (auto& surfaceFunc : {&create_gpu_surface_backend_texture, 871c4025189d31efcb0d54bf14b7712b38725f86c13ericrk &create_gpu_surface_backend_texture_as_render_target}) { 872c4025189d31efcb0d54bf14b7712b38725f86c13ericrk // Validate that we can draw to the canvas and that the original texture color is 873c4025189d31efcb0d54bf14b7712b38725f86c13ericrk // preserved in pixels that aren't rendered to via the surface. 874c4025189d31efcb0d54bf14b7712b38725f86c13ericrk // This works only for non-multisampled case. 875c4025189d31efcb0d54bf14b7712b38725f86c13ericrk GrBackendObject textureObject; 8768b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon auto surface = surfaceFunc(ctxInfo.grContext(), 0, kOrigColor, &textureObject); 877c4025189d31efcb0d54bf14b7712b38725f86c13ericrk if (surface) { 878c4025189d31efcb0d54bf14b7712b38725f86c13ericrk test_surface_draw_partially(reporter, surface, kOrigColor); 879c4025189d31efcb0d54bf14b7712b38725f86c13ericrk surface.reset(); 880c4025189d31efcb0d54bf14b7712b38725f86c13ericrk gpu->deleteTestingOnlyBackendTexture(textureObject); 881c4025189d31efcb0d54bf14b7712b38725f86c13ericrk } 882c4025189d31efcb0d54bf14b7712b38725f86c13ericrk } 883c4025189d31efcb0d54bf14b7712b38725f86c13ericrk} 8840736f3386820f19c0fe90b5dda2094e253780071ericrk 885c4025189d31efcb0d54bf14b7712b38725f86c13ericrk 886c4025189d31efcb0d54bf14b7712b38725f86c13ericrkDEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SurfaceAttachStencil_Gpu, reporter, ctxInfo) { 8878b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon GrGpu* gpu = ctxInfo.grContext()->getGpu(); 888c4025189d31efcb0d54bf14b7712b38725f86c13ericrk if (!gpu) { 889c4025189d31efcb0d54bf14b7712b38725f86c13ericrk return; 890c4025189d31efcb0d54bf14b7712b38725f86c13ericrk } 891c4025189d31efcb0d54bf14b7712b38725f86c13ericrk static const uint32_t kOrigColor = 0xFFAABBCC; 892c4025189d31efcb0d54bf14b7712b38725f86c13ericrk 893c4025189d31efcb0d54bf14b7712b38725f86c13ericrk for (auto& surfaceFunc : {&create_gpu_surface_backend_texture, 894c4025189d31efcb0d54bf14b7712b38725f86c13ericrk &create_gpu_surface_backend_texture_as_render_target}) { 895c4025189d31efcb0d54bf14b7712b38725f86c13ericrk for (int sampleCnt : {0, 4, 8}) { 896c4025189d31efcb0d54bf14b7712b38725f86c13ericrk GrBackendObject textureObject; 8978b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon auto surface = surfaceFunc(ctxInfo.grContext(), sampleCnt, kOrigColor, &textureObject); 898c4025189d31efcb0d54bf14b7712b38725f86c13ericrk 899c4025189d31efcb0d54bf14b7712b38725f86c13ericrk if (!surface && sampleCnt > 0) { 900c4025189d31efcb0d54bf14b7712b38725f86c13ericrk // Certain platforms don't support MSAA, skip these. 901c4025189d31efcb0d54bf14b7712b38725f86c13ericrk continue; 902c4025189d31efcb0d54bf14b7712b38725f86c13ericrk } 903c4025189d31efcb0d54bf14b7712b38725f86c13ericrk 904c4025189d31efcb0d54bf14b7712b38725f86c13ericrk // Validate that we can attach a stencil buffer to an SkSurface created by either of 905c4025189d31efcb0d54bf14b7712b38725f86c13ericrk // our surface functions. 906c4025189d31efcb0d54bf14b7712b38725f86c13ericrk GrRenderTarget* rt = surface->getCanvas()->internal_private_accessTopLayerDrawContext() 907c4025189d31efcb0d54bf14b7712b38725f86c13ericrk ->accessRenderTarget(); 908c4025189d31efcb0d54bf14b7712b38725f86c13ericrk REPORTER_ASSERT(reporter, 9098b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon ctxInfo.grContext()->resourceProvider()->attachStencilAttachment(rt)); 910c4025189d31efcb0d54bf14b7712b38725f86c13ericrk gpu->deleteTestingOnlyBackendTexture(textureObject); 911c4025189d31efcb0d54bf14b7712b38725f86c13ericrk } 912e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon } 913e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon} 914e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon#endif 9150e22eb8e6efc7d7ab7a601ba555947916d139906brianosman 9160e22eb8e6efc7d7ab7a601ba555947916d139906brianosmanstatic void test_surface_creation_and_snapshot_with_color_space( 9170e22eb8e6efc7d7ab7a601ba555947916d139906brianosman skiatest::Reporter* reporter, 9180e22eb8e6efc7d7ab7a601ba555947916d139906brianosman const char* prefix, 9190e22eb8e6efc7d7ab7a601ba555947916d139906brianosman bool f16Support, 9200e22eb8e6efc7d7ab7a601ba555947916d139906brianosman std::function<sk_sp<SkSurface>(const SkImageInfo&)> surfaceMaker) { 9210e22eb8e6efc7d7ab7a601ba555947916d139906brianosman 922526972ecb5411b84ba2f5e20252f178f9ee2151fBrian Osman auto srgbColorSpace = SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named); 923526972ecb5411b84ba2f5e20252f178f9ee2151fBrian Osman auto adobeColorSpace = SkColorSpace::MakeNamed(SkColorSpace::kAdobeRGB_Named); 9249488833428e83c93a7e6002f4d056084fb57112fraftias const SkMatrix44* srgbMatrix = as_CSB(srgbColorSpace)->toXYZD50(); 9259488833428e83c93a7e6002f4d056084fb57112fraftias SkASSERT(srgbMatrix); 9260e22eb8e6efc7d7ab7a601ba555947916d139906brianosman const float oddGamma[] = { 2.4f, 2.4f, 2.4f }; 927526972ecb5411b84ba2f5e20252f178f9ee2151fBrian Osman auto oddColorSpace = SkColorSpace::MakeRGB(oddGamma, *srgbMatrix); 928526972ecb5411b84ba2f5e20252f178f9ee2151fBrian Osman auto linearColorSpace = SkColorSpace::MakeNamed(SkColorSpace::kSRGBLinear_Named); 9290e22eb8e6efc7d7ab7a601ba555947916d139906brianosman 9300e22eb8e6efc7d7ab7a601ba555947916d139906brianosman const struct { 9310e22eb8e6efc7d7ab7a601ba555947916d139906brianosman SkColorType fColorType; 9320e22eb8e6efc7d7ab7a601ba555947916d139906brianosman sk_sp<SkColorSpace> fColorSpace; 9330e22eb8e6efc7d7ab7a601ba555947916d139906brianosman bool fShouldWork; 9340e22eb8e6efc7d7ab7a601ba555947916d139906brianosman const char* fDescription; 9350e22eb8e6efc7d7ab7a601ba555947916d139906brianosman } testConfigs[] = { 9360e22eb8e6efc7d7ab7a601ba555947916d139906brianosman { kN32_SkColorType, nullptr, true, "N32-nullptr" }, 9370e22eb8e6efc7d7ab7a601ba555947916d139906brianosman { kN32_SkColorType, linearColorSpace, false, "N32-linear" }, 9380e22eb8e6efc7d7ab7a601ba555947916d139906brianosman { kN32_SkColorType, srgbColorSpace, true, "N32-srgb" }, 9390e22eb8e6efc7d7ab7a601ba555947916d139906brianosman { kN32_SkColorType, adobeColorSpace, true, "N32-adobe" }, 9400e22eb8e6efc7d7ab7a601ba555947916d139906brianosman { kN32_SkColorType, oddColorSpace, false, "N32-odd" }, 9410e22eb8e6efc7d7ab7a601ba555947916d139906brianosman { kRGBA_F16_SkColorType, nullptr, false, "F16-nullptr" }, 9420e22eb8e6efc7d7ab7a601ba555947916d139906brianosman { kRGBA_F16_SkColorType, linearColorSpace, true, "F16-linear" }, 9430e22eb8e6efc7d7ab7a601ba555947916d139906brianosman { kRGBA_F16_SkColorType, srgbColorSpace, false, "F16-srgb" }, 9440e22eb8e6efc7d7ab7a601ba555947916d139906brianosman { kRGBA_F16_SkColorType, adobeColorSpace, false, "F16-adobe" }, 9450e22eb8e6efc7d7ab7a601ba555947916d139906brianosman { kRGBA_F16_SkColorType, oddColorSpace, false, "F16-odd" }, 9460e22eb8e6efc7d7ab7a601ba555947916d139906brianosman { kRGB_565_SkColorType, srgbColorSpace, false, "565-srgb" }, 9470e22eb8e6efc7d7ab7a601ba555947916d139906brianosman { kAlpha_8_SkColorType, srgbColorSpace, false, "A8-srgb" }, 9480e22eb8e6efc7d7ab7a601ba555947916d139906brianosman }; 9490e22eb8e6efc7d7ab7a601ba555947916d139906brianosman 9500e22eb8e6efc7d7ab7a601ba555947916d139906brianosman for (auto& testConfig : testConfigs) { 9510e22eb8e6efc7d7ab7a601ba555947916d139906brianosman SkString fullTestName = SkStringPrintf("%s-%s", prefix, testConfig.fDescription); 9520e22eb8e6efc7d7ab7a601ba555947916d139906brianosman SkImageInfo info = SkImageInfo::Make(10, 10, testConfig.fColorType, kPremul_SkAlphaType, 9530e22eb8e6efc7d7ab7a601ba555947916d139906brianosman testConfig.fColorSpace); 9540e22eb8e6efc7d7ab7a601ba555947916d139906brianosman 9550e22eb8e6efc7d7ab7a601ba555947916d139906brianosman // For some GPU contexts (eg ANGLE), we don't have f16 support, so we should fail to create 9560e22eb8e6efc7d7ab7a601ba555947916d139906brianosman // any surface of that type: 9570e22eb8e6efc7d7ab7a601ba555947916d139906brianosman bool shouldWork = testConfig.fShouldWork && 9580e22eb8e6efc7d7ab7a601ba555947916d139906brianosman (f16Support || kRGBA_F16_SkColorType != testConfig.fColorType); 9590e22eb8e6efc7d7ab7a601ba555947916d139906brianosman 9600e22eb8e6efc7d7ab7a601ba555947916d139906brianosman auto surface(surfaceMaker(info)); 9610e22eb8e6efc7d7ab7a601ba555947916d139906brianosman REPORTER_ASSERT_MESSAGE(reporter, SkToBool(surface) == shouldWork, fullTestName.c_str()); 9620e22eb8e6efc7d7ab7a601ba555947916d139906brianosman 9630e22eb8e6efc7d7ab7a601ba555947916d139906brianosman if (shouldWork && surface) { 9640e22eb8e6efc7d7ab7a601ba555947916d139906brianosman sk_sp<SkImage> image(surface->makeImageSnapshot()); 9650e22eb8e6efc7d7ab7a601ba555947916d139906brianosman REPORTER_ASSERT_MESSAGE(reporter, image, testConfig.fDescription); 9660e22eb8e6efc7d7ab7a601ba555947916d139906brianosman SkColorSpace* imageColorSpace = as_IB(image)->onImageInfo().colorSpace(); 9670e22eb8e6efc7d7ab7a601ba555947916d139906brianosman REPORTER_ASSERT_MESSAGE(reporter, imageColorSpace == testConfig.fColorSpace.get(), 9680e22eb8e6efc7d7ab7a601ba555947916d139906brianosman fullTestName.c_str()); 9690e22eb8e6efc7d7ab7a601ba555947916d139906brianosman } 9700e22eb8e6efc7d7ab7a601ba555947916d139906brianosman } 9710e22eb8e6efc7d7ab7a601ba555947916d139906brianosman} 9720e22eb8e6efc7d7ab7a601ba555947916d139906brianosman 9730e22eb8e6efc7d7ab7a601ba555947916d139906brianosmanDEF_TEST(SurfaceCreationWithColorSpace, reporter) { 9740e22eb8e6efc7d7ab7a601ba555947916d139906brianosman auto surfaceMaker = [](const SkImageInfo& info) { 9750e22eb8e6efc7d7ab7a601ba555947916d139906brianosman return SkSurface::MakeRaster(info); 9760e22eb8e6efc7d7ab7a601ba555947916d139906brianosman }; 9770e22eb8e6efc7d7ab7a601ba555947916d139906brianosman 9780e22eb8e6efc7d7ab7a601ba555947916d139906brianosman test_surface_creation_and_snapshot_with_color_space(reporter, "raster", true, surfaceMaker); 9790e22eb8e6efc7d7ab7a601ba555947916d139906brianosman} 9800e22eb8e6efc7d7ab7a601ba555947916d139906brianosman 9810e22eb8e6efc7d7ab7a601ba555947916d139906brianosman#if SK_SUPPORT_GPU 9820e22eb8e6efc7d7ab7a601ba555947916d139906brianosmanDEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceCreationWithColorSpace_Gpu, reporter, ctxInfo) { 9830e22eb8e6efc7d7ab7a601ba555947916d139906brianosman GrContext* context = ctxInfo.grContext(); 9840e22eb8e6efc7d7ab7a601ba555947916d139906brianosman bool f16Support = context->caps()->isConfigRenderable(kRGBA_half_GrPixelConfig, false); 9850e22eb8e6efc7d7ab7a601ba555947916d139906brianosman auto surfaceMaker = [context](const SkImageInfo& info) { 9860e22eb8e6efc7d7ab7a601ba555947916d139906brianosman return SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info); 9870e22eb8e6efc7d7ab7a601ba555947916d139906brianosman }; 9880e22eb8e6efc7d7ab7a601ba555947916d139906brianosman 9890e22eb8e6efc7d7ab7a601ba555947916d139906brianosman test_surface_creation_and_snapshot_with_color_space(reporter, "gpu", f16Support, surfaceMaker); 9900e22eb8e6efc7d7ab7a601ba555947916d139906brianosman 9910e22eb8e6efc7d7ab7a601ba555947916d139906brianosman std::vector<GrBackendObject> textureHandles; 9920e22eb8e6efc7d7ab7a601ba555947916d139906brianosman auto wrappedSurfaceMaker = [context,&textureHandles](const SkImageInfo& info) { 9930e22eb8e6efc7d7ab7a601ba555947916d139906brianosman GrBackendTextureDesc desc; 9940e22eb8e6efc7d7ab7a601ba555947916d139906brianosman desc.fConfig = SkImageInfo2GrPixelConfig(info, *context->caps()); 9950e22eb8e6efc7d7ab7a601ba555947916d139906brianosman desc.fWidth = 10; 9960e22eb8e6efc7d7ab7a601ba555947916d139906brianosman desc.fHeight = 10; 9970e22eb8e6efc7d7ab7a601ba555947916d139906brianosman desc.fFlags = kRenderTarget_GrBackendTextureFlag; 9980e22eb8e6efc7d7ab7a601ba555947916d139906brianosman desc.fTextureHandle = context->getGpu()->createTestingOnlyBackendTexture( 9990e22eb8e6efc7d7ab7a601ba555947916d139906brianosman nullptr, desc.fWidth, desc.fHeight, desc.fConfig, true); 10000e22eb8e6efc7d7ab7a601ba555947916d139906brianosman 10010e22eb8e6efc7d7ab7a601ba555947916d139906brianosman if (!desc.fTextureHandle) { 10020e22eb8e6efc7d7ab7a601ba555947916d139906brianosman return sk_sp<SkSurface>(nullptr); 10030e22eb8e6efc7d7ab7a601ba555947916d139906brianosman } 10040e22eb8e6efc7d7ab7a601ba555947916d139906brianosman textureHandles.push_back(desc.fTextureHandle); 10050e22eb8e6efc7d7ab7a601ba555947916d139906brianosman 10060e22eb8e6efc7d7ab7a601ba555947916d139906brianosman return SkSurface::MakeFromBackendTexture(context, desc, sk_ref_sp(info.colorSpace()), 10070e22eb8e6efc7d7ab7a601ba555947916d139906brianosman nullptr); 10080e22eb8e6efc7d7ab7a601ba555947916d139906brianosman }; 10090e22eb8e6efc7d7ab7a601ba555947916d139906brianosman 10100e22eb8e6efc7d7ab7a601ba555947916d139906brianosman test_surface_creation_and_snapshot_with_color_space(reporter, "wrapped", f16Support, 10110e22eb8e6efc7d7ab7a601ba555947916d139906brianosman wrappedSurfaceMaker); 10120e22eb8e6efc7d7ab7a601ba555947916d139906brianosman 10130e22eb8e6efc7d7ab7a601ba555947916d139906brianosman for (auto textureHandle : textureHandles) { 10140e22eb8e6efc7d7ab7a601ba555947916d139906brianosman context->getGpu()->deleteTestingOnlyBackendTexture(textureHandle); 10150e22eb8e6efc7d7ab7a601ba555947916d139906brianosman } 10160e22eb8e6efc7d7ab7a601ba555947916d139906brianosman} 10170e22eb8e6efc7d7ab7a601ba555947916d139906brianosman#endif 1018