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" 12986480a71f4e860663ced7ad90a1fe346a164afbMike Reed#include "SkDevice.h" 1355812362f1df3c1f7341f687d5bab0adab8ac954bsalomon#include "SkImage_Base.h" 14e11b614795bbe707d131ad599ead5be452e7c06fMatt Sarett#include "SkOverdrawCanvas.h" 15d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include "SkPath.h" 16267be7fbc38174652c750ec69d8dc1feaa72db0cMike Reed#include "SkRegion.h" 17995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org#include "SkRRect.h" 18995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org#include "SkSurface.h" 194f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com#include "SkUtils.h" 20995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org#include "Test.h" 21995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org 22995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org#if SK_SUPPORT_GPU 23179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#include "GrContext.h" 242c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips#include "GrContextPriv.h" 251105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman#include "GrRenderTargetContext.h" 26179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#include "GrGpu.h" 27c4025189d31efcb0d54bf14b7712b38725f86c13ericrk#include "GrResourceProvider.h" 287ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel#include "GrTest.h" 290e22eb8e6efc7d7ab7a601ba555947916d139906brianosman#include <vector> 30995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org#endif 31995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org 32179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#include <initializer_list> 3374f681dce2fbadd481596aea15afb3e0fb36ceffbsalomon 34179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunenstatic void release_direct_surface_storage(void* pixels, void* context) { 35982542dce8acbd2f3e7642268b21e76b93230dafreed SkASSERT(pixels == context); 36982542dce8acbd2f3e7642268b21e76b93230dafreed sk_free(pixels); 37982542dce8acbd2f3e7642268b21e76b93230dafreed} 38e8f3062a36d3682f4019309a32b5b84dc9eddf8creedstatic sk_sp<SkSurface> create_surface(SkAlphaType at = kPremul_SkAlphaType, 39e8f3062a36d3682f4019309a32b5b84dc9eddf8creed SkImageInfo* requestedInfo = nullptr) { 4074f681dce2fbadd481596aea15afb3e0fb36ceffbsalomon const SkImageInfo info = SkImageInfo::MakeN32(10, 10, at); 41c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (requestedInfo) { 42c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org *requestedInfo = info; 43c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 44e8f3062a36d3682f4019309a32b5b84dc9eddf8creed return SkSurface::MakeRaster(info); 45179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 46e8f3062a36d3682f4019309a32b5b84dc9eddf8creedstatic sk_sp<SkSurface> create_direct_surface(SkAlphaType at = kPremul_SkAlphaType, 47e8f3062a36d3682f4019309a32b5b84dc9eddf8creed SkImageInfo* requestedInfo = nullptr) { 48179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen const SkImageInfo info = SkImageInfo::MakeN32(10, 10, at); 49179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen if (requestedInfo) { 50179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen *requestedInfo = info; 51179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen } 52179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen const size_t rowBytes = info.minRowBytes(); 53179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen void* storage = sk_malloc_throw(info.getSafeSize(rowBytes)); 54e8f3062a36d3682f4019309a32b5b84dc9eddf8creed return SkSurface::MakeRasterDirectReleaseProc(info, storage, rowBytes, 55e8f3062a36d3682f4019309a32b5b84dc9eddf8creed release_direct_surface_storage, 56e8f3062a36d3682f4019309a32b5b84dc9eddf8creed storage); 57179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 58179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#if SK_SUPPORT_GPU 59e8f3062a36d3682f4019309a32b5b84dc9eddf8creedstatic sk_sp<SkSurface> create_gpu_surface(GrContext* context, SkAlphaType at = kPremul_SkAlphaType, 60e8f3062a36d3682f4019309a32b5b84dc9eddf8creed SkImageInfo* requestedInfo = nullptr) { 61179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen const SkImageInfo info = SkImageInfo::MakeN32(10, 10, at); 62179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen if (requestedInfo) { 63179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen *requestedInfo = info; 64179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen } 657e922765545f42ce691e4f3d5fbbd4e44ba47ff1robertphillips return SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info); 66179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 67e8f3062a36d3682f4019309a32b5b84dc9eddf8creedstatic sk_sp<SkSurface> create_gpu_scratch_surface(GrContext* context, 68e8f3062a36d3682f4019309a32b5b84dc9eddf8creed SkAlphaType at = kPremul_SkAlphaType, 69e8f3062a36d3682f4019309a32b5b84dc9eddf8creed SkImageInfo* requestedInfo = nullptr) { 70179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen const SkImageInfo info = SkImageInfo::MakeN32(10, 10, at); 71179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen if (requestedInfo) { 72179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen *requestedInfo = info; 73995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org } 747e922765545f42ce691e4f3d5fbbd4e44ba47ff1robertphillips return SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, info); 75995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org} 76179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#endif 77995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org 78179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunenDEF_TEST(SurfaceEmpty, reporter) { 79b2497c2d945c0a5d770865b026e2d5947bf37c91reed const SkImageInfo info = SkImageInfo::Make(0, 0, kN32_SkColorType, kPremul_SkAlphaType); 80e8f3062a36d3682f4019309a32b5b84dc9eddf8creed REPORTER_ASSERT(reporter, nullptr == SkSurface::MakeRaster(info)); 81e8f3062a36d3682f4019309a32b5b84dc9eddf8creed REPORTER_ASSERT(reporter, nullptr == SkSurface::MakeRasterDirect(info, nullptr, 0)); 82b2497c2d945c0a5d770865b026e2d5947bf37c91reed 83179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 84e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon#if SK_SUPPORT_GPU 85ab527a5bbfb1eae4f99a1435d349a44d00477d82egdanielDEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceEmpty_Gpu, reporter, ctxInfo) { 86179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen const SkImageInfo info = SkImageInfo::Make(0, 0, kN32_SkColorType, kPremul_SkAlphaType); 87179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen REPORTER_ASSERT(reporter, nullptr == 887e922765545f42ce691e4f3d5fbbd4e44ba47ff1robertphillips SkSurface::MakeRenderTarget(ctxInfo.grContext(), SkBudgeted::kNo, info)); 89179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 90179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#endif 917a61793d9603f07a9039b5abf814eb25842e211bbsalomon 92179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunenstatic void test_canvas_peek(skiatest::Reporter* reporter, 93e8f3062a36d3682f4019309a32b5b84dc9eddf8creed sk_sp<SkSurface>& surface, 94179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen const SkImageInfo& requestInfo, 95179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen bool expectPeekSuccess) { 96c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org const SkColor color = SK_ColorRED; 97c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org const SkPMColor pmcolor = SkPreMultiplyColor(color); 98179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen surface->getCanvas()->clear(color); 99179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen 1006ceeebd37a43d879c120b6ba100ae1febdd67a18reed SkPixmap pmap; 1016ceeebd37a43d879c120b6ba100ae1febdd67a18reed bool success = surface->getCanvas()->peekPixels(&pmap); 102179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen REPORTER_ASSERT(reporter, expectPeekSuccess == success); 103179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen 1046ceeebd37a43d879c120b6ba100ae1febdd67a18reed SkPixmap pmap2; 1056ceeebd37a43d879c120b6ba100ae1febdd67a18reed const void* addr2 = surface->peekPixels(&pmap2) ? pmap2.addr() : nullptr; 106179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen 107179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen if (success) { 1086ceeebd37a43d879c120b6ba100ae1febdd67a18reed REPORTER_ASSERT(reporter, requestInfo == pmap.info()); 1096ceeebd37a43d879c120b6ba100ae1febdd67a18reed REPORTER_ASSERT(reporter, requestInfo.minRowBytes() <= pmap.rowBytes()); 1106ceeebd37a43d879c120b6ba100ae1febdd67a18reed REPORTER_ASSERT(reporter, pmcolor == *pmap.addr32()); 111179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen 1126ceeebd37a43d879c120b6ba100ae1febdd67a18reed REPORTER_ASSERT(reporter, pmap.addr() == pmap2.addr()); 1136ceeebd37a43d879c120b6ba100ae1febdd67a18reed REPORTER_ASSERT(reporter, pmap.info() == pmap2.info()); 1146ceeebd37a43d879c120b6ba100ae1febdd67a18reed REPORTER_ASSERT(reporter, pmap.rowBytes() == pmap2.rowBytes()); 115179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen } else { 116179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen REPORTER_ASSERT(reporter, nullptr == addr2); 117179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen } 118179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 119179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunenDEF_TEST(SurfaceCanvasPeek, reporter) { 120179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& surface_func : { &create_surface, &create_direct_surface }) { 121179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkImageInfo requestInfo; 122e8f3062a36d3682f4019309a32b5b84dc9eddf8creed auto surface(surface_func(kPremul_SkAlphaType, &requestInfo)); 123179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen test_canvas_peek(reporter, surface, requestInfo, true); 124179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen } 125179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 126e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon#if SK_SUPPORT_GPU 127ab527a5bbfb1eae4f99a1435d349a44d00477d82egdanielDEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceCanvasPeek_Gpu, reporter, ctxInfo) { 128179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) { 129179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkImageInfo requestInfo; 1308b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon auto surface(surface_func(ctxInfo.grContext(), kPremul_SkAlphaType, &requestInfo)); 131179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen test_canvas_peek(reporter, surface, requestInfo, false); 132c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 133c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 134179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#endif 135c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 136e8f3062a36d3682f4019309a32b5b84dc9eddf8creedstatic void test_snapshot_alphatype(skiatest::Reporter* reporter, const sk_sp<SkSurface>& surface, 13769c166d2ce3f4d2099f35f8e88f1aa56ceeaf960brianosman SkAlphaType expectedAlphaType) { 138179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen REPORTER_ASSERT(reporter, surface); 139179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen if (surface) { 1409ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image(surface->makeImageSnapshot()); 141179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen REPORTER_ASSERT(reporter, image); 142179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen if (image) { 14369c166d2ce3f4d2099f35f8e88f1aa56ceeaf960brianosman REPORTER_ASSERT(reporter, image->alphaType() == expectedAlphaType); 14441e010cb901c0da9066c4df562030808c9ccd7f8reed } 145179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen } 146179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 147179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunenDEF_TEST(SurfaceSnapshotAlphaType, reporter) { 148179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& surface_func : { &create_surface, &create_direct_surface }) { 14969c166d2ce3f4d2099f35f8e88f1aa56ceeaf960brianosman for (auto& at: { kOpaque_SkAlphaType, kPremul_SkAlphaType, kUnpremul_SkAlphaType }) { 15069c166d2ce3f4d2099f35f8e88f1aa56ceeaf960brianosman auto surface(surface_func(at, nullptr)); 15169c166d2ce3f4d2099f35f8e88f1aa56ceeaf960brianosman test_snapshot_alphatype(reporter, surface, at); 15241e010cb901c0da9066c4df562030808c9ccd7f8reed } 15341e010cb901c0da9066c4df562030808c9ccd7f8reed } 15441e010cb901c0da9066c4df562030808c9ccd7f8reed} 15574f681dce2fbadd481596aea15afb3e0fb36ceffbsalomon#if SK_SUPPORT_GPU 156ab527a5bbfb1eae4f99a1435d349a44d00477d82egdanielDEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceSnapshotAlphaType_Gpu, reporter, ctxInfo) { 157179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) { 15869c166d2ce3f4d2099f35f8e88f1aa56ceeaf960brianosman // GPU doesn't support creating unpremul surfaces, so only test opaque + premul 15969c166d2ce3f4d2099f35f8e88f1aa56ceeaf960brianosman for (auto& at : { kOpaque_SkAlphaType, kPremul_SkAlphaType }) { 16069c166d2ce3f4d2099f35f8e88f1aa56ceeaf960brianosman auto surface(surface_func(ctxInfo.grContext(), at, nullptr)); 16169c166d2ce3f4d2099f35f8e88f1aa56ceeaf960brianosman test_snapshot_alphatype(reporter, surface, at); 162179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen } 16374f681dce2fbadd481596aea15afb3e0fb36ceffbsalomon } 164179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 16574f681dce2fbadd481596aea15afb3e0fb36ceffbsalomon#endif 166179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen 167179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunenstatic GrBackendObject get_surface_backend_texture_handle( 168179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkSurface* s, SkSurface::BackendHandleAccess a) { 169179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen return s->getTextureHandle(a); 170179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 171179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunenstatic GrBackendObject get_surface_backend_render_target_handle( 172179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkSurface* s, SkSurface::BackendHandleAccess a) { 173179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen GrBackendObject result; 174179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen if (!s->getRenderTargetHandle(&result, a)) { 175179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen return 0; 17674f681dce2fbadd481596aea15afb3e0fb36ceffbsalomon } 177179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen return result; 17874f681dce2fbadd481596aea15afb3e0fb36ceffbsalomon} 17974f681dce2fbadd481596aea15afb3e0fb36ceffbsalomon 180179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunenstatic void test_backend_handle_access_copy_on_write( 181179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen skiatest::Reporter* reporter, SkSurface* surface, SkSurface::BackendHandleAccess mode, 182179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen GrBackendObject (*func)(SkSurface*, SkSurface::BackendHandleAccess)) { 183e2639089bddc4fbb129ae039cb12c01be087b397fmalita GrBackendObject obj1 = func(surface, mode); 1849ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> snap1(surface->makeImageSnapshot()); 185e2639089bddc4fbb129ae039cb12c01be087b397fmalita 186e2639089bddc4fbb129ae039cb12c01be087b397fmalita GrBackendObject obj2 = func(surface, mode); 1879ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> snap2(surface->makeImageSnapshot()); 188e2639089bddc4fbb129ae039cb12c01be087b397fmalita 189e2639089bddc4fbb129ae039cb12c01be087b397fmalita // If the access mode triggers CoW, then the backend objects should reflect it. 190e2639089bddc4fbb129ae039cb12c01be087b397fmalita REPORTER_ASSERT(reporter, (obj1 == obj2) == (snap1 == snap2)); 191e2639089bddc4fbb129ae039cb12c01be087b397fmalita} 192179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunenDEF_TEST(SurfaceBackendHandleAccessCopyOnWrite, reporter) { 193179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen const SkSurface::BackendHandleAccess accessModes[] = { 194179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkSurface::kFlushRead_BackendHandleAccess, 195179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkSurface::kFlushWrite_BackendHandleAccess, 196179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkSurface::kDiscardWrite_BackendHandleAccess, 197179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen }; 198179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& handle_access_func : 199179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen { &get_surface_backend_texture_handle, &get_surface_backend_render_target_handle }) { 200179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& accessMode : accessModes) { 201e8f3062a36d3682f4019309a32b5b84dc9eddf8creed auto surface(create_surface()); 202e8f3062a36d3682f4019309a32b5b84dc9eddf8creed test_backend_handle_access_copy_on_write(reporter, surface.get(), accessMode, 203179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen handle_access_func); 204179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen } 205179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen } 206179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 207179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#if SK_SUPPORT_GPU 20868d9134bec16e91c4a6cde071bcaa579bc0801a7bsalomonDEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceBackendHandleAccessCopyOnWrite_Gpu, reporter, ctxInfo) { 209179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen const SkSurface::BackendHandleAccess accessModes[] = { 210179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkSurface::kFlushRead_BackendHandleAccess, 211179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkSurface::kFlushWrite_BackendHandleAccess, 212179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkSurface::kDiscardWrite_BackendHandleAccess, 213179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen }; 214179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) { 215179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& handle_access_func : 216179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen { &get_surface_backend_texture_handle, &get_surface_backend_render_target_handle }) { 217179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& accessMode : accessModes) { 2188b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon auto surface(surface_func(ctxInfo.grContext(), kPremul_SkAlphaType, nullptr)); 219e8f3062a36d3682f4019309a32b5b84dc9eddf8creed test_backend_handle_access_copy_on_write(reporter, surface.get(), accessMode, 220179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen handle_access_func); 221179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen } 222179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen } 223179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen } 224179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 225179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#endif 226e2639089bddc4fbb129ae039cb12c01be087b397fmalita 227179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#if SK_SUPPORT_GPU 2281f3923e4e5bf9afb9e52a15ced30e3854af73f7brobertphillips 229179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunenstatic void test_backend_handle_unique_id( 230179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen skiatest::Reporter* reporter, SkSurface* surface, 231179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen GrBackendObject (*func)(SkSurface*, SkSurface::BackendHandleAccess)) { 2329ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image0(surface->makeImageSnapshot()); 233179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen GrBackendObject obj = func(surface, SkSurface::kFlushRead_BackendHandleAccess); 234179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen REPORTER_ASSERT(reporter, obj != 0); 2359ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image1(surface->makeImageSnapshot()); 236179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen // just read access should not affect the snapshot 237179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen REPORTER_ASSERT(reporter, image0->uniqueID() == image1->uniqueID()); 238179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen 239179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen obj = func(surface, SkSurface::kFlushWrite_BackendHandleAccess); 240179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen REPORTER_ASSERT(reporter, obj != 0); 2419ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image2(surface->makeImageSnapshot()); 242179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen // expect a new image, since we claimed we would write 243179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen REPORTER_ASSERT(reporter, image0->uniqueID() != image2->uniqueID()); 244179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen 245179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen obj = func(surface, SkSurface::kDiscardWrite_BackendHandleAccess); 246179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen REPORTER_ASSERT(reporter, obj != 0); 2479ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image3(surface->makeImageSnapshot()); 248179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen // expect a new(er) image, since we claimed we would write 249179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen REPORTER_ASSERT(reporter, image0->uniqueID() != image3->uniqueID()); 250179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen REPORTER_ASSERT(reporter, image2->uniqueID() != image3->uniqueID()); 251179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 252179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen// No CPU test. 25368d9134bec16e91c4a6cde071bcaa579bc0801a7bsalomonDEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceBackendHandleAccessIDs_Gpu, reporter, ctxInfo) { 254179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) { 2551f3923e4e5bf9afb9e52a15ced30e3854af73f7brobertphillips for (auto& test_func : { &test_backend_handle_unique_id }) { 256179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& handle_access_func : 257179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen { &get_surface_backend_texture_handle, &get_surface_backend_render_target_handle}) { 2588b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon auto surface(surface_func(ctxInfo.grContext(), kPremul_SkAlphaType, nullptr)); 259e8f3062a36d3682f4019309a32b5b84dc9eddf8creed test_func(reporter, surface.get(), handle_access_func); 260179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen } 261179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen } 262179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen } 263179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 264179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#endif 265179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen 266179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen// Verify that the right canvas commands trigger a copy on write. 267179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunenstatic void test_copy_on_write(skiatest::Reporter* reporter, SkSurface* surface) { 268995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org SkCanvas* canvas = surface->getCanvas(); 269995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org 270995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org const SkRect testRect = 271995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org SkRect::MakeXYWH(SkIntToScalar(0), SkIntToScalar(0), 272995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org SkIntToScalar(4), SkIntToScalar(5)); 273995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org SkPath testPath; 274995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org testPath.addRect(SkRect::MakeXYWH(SkIntToScalar(0), SkIntToScalar(0), 275995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org SkIntToScalar(2), SkIntToScalar(1))); 276995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org 277995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org const SkIRect testIRect = SkIRect::MakeXYWH(0, 0, 2, 1); 278995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org 279995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org SkRegion testRegion; 280995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org testRegion.setRect(testIRect); 281995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org 282995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org 283995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org const SkColor testColor = 0x01020304; 284995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org const SkPaint testPaint; 285995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org const SkPoint testPoints[3] = { 286995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org {SkIntToScalar(0), SkIntToScalar(0)}, 287995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org {SkIntToScalar(2), SkIntToScalar(1)}, 288995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org {SkIntToScalar(0), SkIntToScalar(2)} 289995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org }; 290995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org const size_t testPointCount = 3; 291995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org 292995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org SkBitmap testBitmap; 293deee496cd30070e52556dcb538c2e5eb39b66b81mike@reedtribe.org testBitmap.allocN32Pixels(10, 10); 294d1ce77d548ab098c2f455e9b0fa1f195e75cd8edrobertphillips@google.com testBitmap.eraseColor(0); 295995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org 296995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org SkRRect testRRect; 297995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org testRRect.setRectXY(testRect, SK_Scalar1, SK_Scalar1); 298995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org 299995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org SkString testText("Hello World"); 300995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org const SkPoint testPoints2[] = { 301995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org { SkIntToScalar(0), SkIntToScalar(1) }, 302995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org { SkIntToScalar(1), SkIntToScalar(1) }, 303995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org { SkIntToScalar(2), SkIntToScalar(1) }, 304995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org { SkIntToScalar(3), SkIntToScalar(1) }, 305995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org { SkIntToScalar(4), SkIntToScalar(1) }, 306995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org { SkIntToScalar(5), SkIntToScalar(1) }, 307995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org { SkIntToScalar(6), SkIntToScalar(1) }, 308995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org { SkIntToScalar(7), SkIntToScalar(1) }, 309995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org { SkIntToScalar(8), SkIntToScalar(1) }, 310995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org { SkIntToScalar(9), SkIntToScalar(1) }, 311995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org { SkIntToScalar(10), SkIntToScalar(1) }, 312995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org }; 313995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org 314995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org#define EXPECT_COPY_ON_WRITE(command) \ 315995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org { \ 3169ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> imageBefore = surface->makeImageSnapshot(); \ 3179ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> aur_before(imageBefore); \ 318995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org canvas-> command ; \ 3199ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> imageAfter = surface->makeImageSnapshot(); \ 3209ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> aur_after(imageAfter); \ 321995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org REPORTER_ASSERT(reporter, imageBefore != imageAfter); \ 322995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org } 323995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org 324995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org EXPECT_COPY_ON_WRITE(clear(testColor)) 325995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org EXPECT_COPY_ON_WRITE(drawPaint(testPaint)) 326995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org EXPECT_COPY_ON_WRITE(drawPoints(SkCanvas::kPoints_PointMode, testPointCount, testPoints, \ 327995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org testPaint)) 328995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org EXPECT_COPY_ON_WRITE(drawOval(testRect, testPaint)) 329995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org EXPECT_COPY_ON_WRITE(drawRect(testRect, testPaint)) 330995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org EXPECT_COPY_ON_WRITE(drawRRect(testRRect, testPaint)) 331995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org EXPECT_COPY_ON_WRITE(drawPath(testPath, testPaint)) 332995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org EXPECT_COPY_ON_WRITE(drawBitmap(testBitmap, 0, 0)) 333e47829b6b1eeb6b0c97ccb3df3016d197046824creed EXPECT_COPY_ON_WRITE(drawBitmapRect(testBitmap, testRect, nullptr)) 33496fcdcc219d2a0d3579719b84b28bede76efba64halcanary EXPECT_COPY_ON_WRITE(drawBitmapNine(testBitmap, testIRect, testRect, nullptr)) 3352a475eae622adc1e8fa29206be1eaf862c23548eCary Clark EXPECT_COPY_ON_WRITE(drawString(testText, 0, 1, testPaint)) 336995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org EXPECT_COPY_ON_WRITE(drawPosText(testText.c_str(), testText.size(), testPoints2, \ 337995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org testPaint)) 33896fcdcc219d2a0d3579719b84b28bede76efba64halcanary EXPECT_COPY_ON_WRITE(drawTextOnPath(testText.c_str(), testText.size(), testPath, nullptr, \ 339995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org testPaint)) 340179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 341179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunenDEF_TEST(SurfaceCopyOnWrite, reporter) { 342e8f3062a36d3682f4019309a32b5b84dc9eddf8creed test_copy_on_write(reporter, create_surface().get()); 343179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 344179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#if SK_SUPPORT_GPU 345ab527a5bbfb1eae4f99a1435d349a44d00477d82egdanielDEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceCopyOnWrite_Gpu, reporter, ctxInfo) { 346179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) { 3478b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon auto surface(surface_func(ctxInfo.grContext(), kPremul_SkAlphaType, nullptr)); 348e8f3062a36d3682f4019309a32b5b84dc9eddf8creed test_copy_on_write(reporter, surface.get()); 349e2639089bddc4fbb129ae039cb12c01be087b397fmalita } 350995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org} 351179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#endif 352995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org 353179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunenstatic void test_writable_after_snapshot_release(skiatest::Reporter* reporter, 354179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkSurface* surface) { 355af0583528c7dd5344abfe14347377011abe374e2junov@chromium.org // This test succeeds by not triggering an assertion. 356af0583528c7dd5344abfe14347377011abe374e2junov@chromium.org // The test verifies that the surface remains writable (usable) after 357af0583528c7dd5344abfe14347377011abe374e2junov@chromium.org // acquiring and releasing a snapshot without triggering a copy on write. 358af0583528c7dd5344abfe14347377011abe374e2junov@chromium.org SkCanvas* canvas = surface->getCanvas(); 359af0583528c7dd5344abfe14347377011abe374e2junov@chromium.org canvas->clear(1); 3609ce9d6772df650ceb0511f275e1a83dffa78ff72reed surface->makeImageSnapshot(); // Create and destroy SkImage 3614d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org canvas->clear(2); // Must not assert internally 362995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org} 363179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunenDEF_TEST(SurfaceWriteableAfterSnapshotRelease, reporter) { 364e8f3062a36d3682f4019309a32b5b84dc9eddf8creed test_writable_after_snapshot_release(reporter, create_surface().get()); 365179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 366179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#if SK_SUPPORT_GPU 367ab527a5bbfb1eae4f99a1435d349a44d00477d82egdanielDEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceWriteableAfterSnapshotRelease_Gpu, reporter, ctxInfo) { 368179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) { 3698b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon auto surface(surface_func(ctxInfo.grContext(), kPremul_SkAlphaType, nullptr)); 370e8f3062a36d3682f4019309a32b5b84dc9eddf8creed test_writable_after_snapshot_release(reporter, surface.get()); 371179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen } 372179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 373179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#endif 374da90474b5fcc019fb0971d12360bd05213ad4dc8junov@chromium.org 375b516a4177931b8febf859752b49f094f70539eaejunov@chromium.org#if SK_SUPPORT_GPU 376179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunenstatic void test_crbug263329(skiatest::Reporter* reporter, 377179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkSurface* surface1, 378179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkSurface* surface2) { 3794d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org // This is a regression test for crbug.com/263329 3804d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org // Bug was caused by onCopyOnWrite releasing the old surface texture 3814d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org // back to the scratch texture pool even though the texture is used 3824d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org // by and active SkImage_Gpu. 3834d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org SkCanvas* canvas1 = surface1->getCanvas(); 3844d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org SkCanvas* canvas2 = surface2->getCanvas(); 3854d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org canvas1->clear(1); 3869ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image1(surface1->makeImageSnapshot()); 3874d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org // Trigger copy on write, new backing is a scratch texture 3884d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org canvas1->clear(2); 3899ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image2(surface1->makeImageSnapshot()); 3904d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org // Trigger copy on write, old backing should not be returned to scratch 3914d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org // pool because it is held by image2 3924d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org canvas1->clear(3); 3934d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org 3944d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org canvas2->clear(4); 3959ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image3(surface2->makeImageSnapshot()); 3964d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org // Trigger copy on write on surface2. The new backing store should not 3974d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org // be recycling a texture that is held by an existing image. 3984d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org canvas2->clear(5); 3999ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image4(surface2->makeImageSnapshot()); 4008744405448b9402e1368aebd321c4f555543301aRobert Phillips REPORTER_ASSERT(reporter, as_IB(image4)->getTexture() != as_IB(image3)->getTexture()); 4014d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org // The following assertion checks crbug.com/263329 4028744405448b9402e1368aebd321c4f555543301aRobert Phillips REPORTER_ASSERT(reporter, as_IB(image4)->getTexture() != as_IB(image2)->getTexture()); 4038744405448b9402e1368aebd321c4f555543301aRobert Phillips REPORTER_ASSERT(reporter, as_IB(image4)->getTexture() != as_IB(image1)->getTexture()); 4048744405448b9402e1368aebd321c4f555543301aRobert Phillips REPORTER_ASSERT(reporter, as_IB(image3)->getTexture() != as_IB(image2)->getTexture()); 4058744405448b9402e1368aebd321c4f555543301aRobert Phillips REPORTER_ASSERT(reporter, as_IB(image3)->getTexture() != as_IB(image1)->getTexture()); 4068744405448b9402e1368aebd321c4f555543301aRobert Phillips REPORTER_ASSERT(reporter, as_IB(image2)->getTexture() != as_IB(image1)->getTexture()); 4074d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org} 408ab527a5bbfb1eae4f99a1435d349a44d00477d82egdanielDEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceCRBug263329_Gpu, reporter, ctxInfo) { 409179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) { 4108b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon auto surface1(surface_func(ctxInfo.grContext(), kPremul_SkAlphaType, nullptr)); 4118b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon auto surface2(surface_func(ctxInfo.grContext(), kPremul_SkAlphaType, nullptr)); 412e8f3062a36d3682f4019309a32b5b84dc9eddf8creed test_crbug263329(reporter, surface1.get(), surface2.get()); 413179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen } 414179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 415179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#endif 4164d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org 417179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunenDEF_TEST(SurfaceGetTexture, reporter) { 418e8f3062a36d3682f4019309a32b5b84dc9eddf8creed auto surface(create_surface()); 4199ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image(surface->makeImageSnapshot()); 4206de99041f13e87ed440f7db13a07693c6c4c461aRobert Phillips REPORTER_ASSERT(reporter, !as_IB(image)->isTextureBacked()); 421179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen surface->notifyContentWillChange(SkSurface::kDiscard_ContentChangeMode); 4226de99041f13e87ed440f7db13a07693c6c4c461aRobert Phillips REPORTER_ASSERT(reporter, !as_IB(image)->isTextureBacked()); 423179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 424179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#if SK_SUPPORT_GPU 425ab527a5bbfb1eae4f99a1435d349a44d00477d82egdanielDEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfacepeekTexture_Gpu, reporter, ctxInfo) { 426179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) { 4278b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon auto surface(surface_func(ctxInfo.grContext(), kPremul_SkAlphaType, nullptr)); 4289ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image(surface->makeImageSnapshot()); 4296de99041f13e87ed440f7db13a07693c6c4c461aRobert Phillips 4306de99041f13e87ed440f7db13a07693c6c4c461aRobert Phillips REPORTER_ASSERT(reporter, as_IB(image)->isTextureBacked()); 4316de99041f13e87ed440f7db13a07693c6c4c461aRobert Phillips GrBackendObject textureHandle = image->getTextureHandle(false); 4326de99041f13e87ed440f7db13a07693c6c4c461aRobert Phillips REPORTER_ASSERT(reporter, 0 != textureHandle); 433179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen surface->notifyContentWillChange(SkSurface::kDiscard_ContentChangeMode); 4346de99041f13e87ed440f7db13a07693c6c4c461aRobert Phillips REPORTER_ASSERT(reporter, as_IB(image)->isTextureBacked()); 4356de99041f13e87ed440f7db13a07693c6c4c461aRobert Phillips REPORTER_ASSERT(reporter, textureHandle == image->getTextureHandle(false)); 436da90474b5fcc019fb0971d12360bd05213ad4dc8junov@chromium.org } 437da90474b5fcc019fb0971d12360bd05213ad4dc8junov@chromium.org} 438179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#endif 439eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon 440179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#if SK_SUPPORT_GPU 4413582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon#include "GrGpuResourcePriv.h" 442eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon#include "SkGpuDevice.h" 443eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon#include "SkImage_Gpu.h" 444eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon#include "SkSurface_Gpu.h" 445eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon 446e8f3062a36d3682f4019309a32b5b84dc9eddf8creedstatic SkBudgeted is_budgeted(const sk_sp<SkSurface>& surf) { 447e8f3062a36d3682f4019309a32b5b84dc9eddf8creed SkSurface_Gpu* gsurf = (SkSurface_Gpu*)surf.get(); 4486de99041f13e87ed440f7db13a07693c6c4c461aRobert Phillips 4496de99041f13e87ed440f7db13a07693c6c4c461aRobert Phillips GrRenderTargetProxy* proxy = gsurf->getDevice()->accessRenderTargetContext() 4506de99041f13e87ed440f7db13a07693c6c4c461aRobert Phillips ->asRenderTargetProxy(); 4516de99041f13e87ed440f7db13a07693c6c4c461aRobert Phillips return proxy->isBudgeted(); 452eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon} 453eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon 4545ec26ae9bfca635ccc98283aad5deda11519d826bsalomonstatic SkBudgeted is_budgeted(SkImage* image) { 4550ae6faa34d73ffc7ebec3d13f0473703bade821bRobert Phillips return ((SkImage_Gpu*)image)->peekProxy()->isBudgeted(); 456eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon} 457eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon 4589ce9d6772df650ceb0511f275e1a83dffa78ff72reedstatic SkBudgeted is_budgeted(const sk_sp<SkImage> image) { 4599ce9d6772df650ceb0511f275e1a83dffa78ff72reed return is_budgeted(image.get()); 4609ce9d6772df650ceb0511f275e1a83dffa78ff72reed} 4619ce9d6772df650ceb0511f275e1a83dffa78ff72reed 462ab527a5bbfb1eae4f99a1435d349a44d00477d82egdanielDEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceBudget, reporter, ctxInfo) { 463eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon SkImageInfo info = SkImageInfo::MakeN32Premul(8,8); 464ac6b1fa2c8507bfd5f790bccaebab8e4018cb2cdRobert Phillips for (auto budgeted : { SkBudgeted::kNo, SkBudgeted::kYes }) { 465ac6b1fa2c8507bfd5f790bccaebab8e4018cb2cdRobert Phillips auto surface(SkSurface::MakeRenderTarget(ctxInfo.grContext(), budgeted, info)); 466ac6b1fa2c8507bfd5f790bccaebab8e4018cb2cdRobert Phillips SkASSERT(surface); 467ac6b1fa2c8507bfd5f790bccaebab8e4018cb2cdRobert Phillips REPORTER_ASSERT(reporter, budgeted == is_budgeted(surface)); 468ac6b1fa2c8507bfd5f790bccaebab8e4018cb2cdRobert Phillips 469ac6b1fa2c8507bfd5f790bccaebab8e4018cb2cdRobert Phillips sk_sp<SkImage> image(surface->makeImageSnapshot()); 470ac6b1fa2c8507bfd5f790bccaebab8e4018cb2cdRobert Phillips 471ac6b1fa2c8507bfd5f790bccaebab8e4018cb2cdRobert Phillips // Initially the image shares a texture with the surface, and the 472ac6b1fa2c8507bfd5f790bccaebab8e4018cb2cdRobert Phillips // the budgets should always match. 473ac6b1fa2c8507bfd5f790bccaebab8e4018cb2cdRobert Phillips REPORTER_ASSERT(reporter, budgeted == is_budgeted(surface)); 474ac6b1fa2c8507bfd5f790bccaebab8e4018cb2cdRobert Phillips REPORTER_ASSERT(reporter, budgeted == is_budgeted(image)); 475ac6b1fa2c8507bfd5f790bccaebab8e4018cb2cdRobert Phillips 476ac6b1fa2c8507bfd5f790bccaebab8e4018cb2cdRobert Phillips // Now trigger copy-on-write 477ac6b1fa2c8507bfd5f790bccaebab8e4018cb2cdRobert Phillips surface->getCanvas()->clear(SK_ColorBLUE); 478ac6b1fa2c8507bfd5f790bccaebab8e4018cb2cdRobert Phillips 479ac6b1fa2c8507bfd5f790bccaebab8e4018cb2cdRobert Phillips // They don't share a texture anymore but the budgets should still match. 480ac6b1fa2c8507bfd5f790bccaebab8e4018cb2cdRobert Phillips REPORTER_ASSERT(reporter, budgeted == is_budgeted(surface)); 481ac6b1fa2c8507bfd5f790bccaebab8e4018cb2cdRobert Phillips REPORTER_ASSERT(reporter, budgeted == is_budgeted(image)); 482eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon } 483eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon} 484b516a4177931b8febf859752b49f094f70539eaejunov@chromium.org#endif 485da90474b5fcc019fb0971d12360bd05213ad4dc8junov@chromium.org 486179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunenstatic void test_no_canvas1(skiatest::Reporter* reporter, 487179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkSurface* surface, 488179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkSurface::ContentChangeMode mode) { 489179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen // Test passes by not asserting 490179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen surface->notifyContentWillChange(mode); 491179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkDEBUGCODE(surface->validate();) 492179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 493179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunenstatic void test_no_canvas2(skiatest::Reporter* reporter, 494179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkSurface* surface, 495179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkSurface::ContentChangeMode mode) { 496acea3ef448c9903de3aa6a013c839dce577e6ce3junov@chromium.org // Verifies the robustness of SkSurface for handling use cases where calls 497acea3ef448c9903de3aa6a013c839dce577e6ce3junov@chromium.org // are made before a canvas is created. 4989ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image1 = surface->makeImageSnapshot(); 4999ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> aur_image1(image1); 500179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkDEBUGCODE(image1->validate();) 501179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkDEBUGCODE(surface->validate();) 502179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen surface->notifyContentWillChange(mode); 503179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkDEBUGCODE(image1->validate();) 504179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkDEBUGCODE(surface->validate();) 5059ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image2 = surface->makeImageSnapshot(); 5069ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> aur_image2(image2); 507179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkDEBUGCODE(image2->validate();) 508179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkDEBUGCODE(surface->validate();) 509179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen REPORTER_ASSERT(reporter, image1 != image2); 510179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen} 511179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunenDEF_TEST(SurfaceNoCanvas, reporter) { 512179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkSurface::ContentChangeMode modes[] = 513179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen { SkSurface::kDiscard_ContentChangeMode, SkSurface::kRetain_ContentChangeMode}; 514179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& test_func : { &test_no_canvas1, &test_no_canvas2 }) { 515179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& mode : modes) { 516e8f3062a36d3682f4019309a32b5b84dc9eddf8creed test_func(reporter, create_surface().get(), mode); 517179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen } 518acea3ef448c9903de3aa6a013c839dce577e6ce3junov@chromium.org } 519acea3ef448c9903de3aa6a013c839dce577e6ce3junov@chromium.org} 520b516a4177931b8febf859752b49f094f70539eaejunov@chromium.org#if SK_SUPPORT_GPU 521ab527a5bbfb1eae4f99a1435d349a44d00477d82egdanielDEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceNoCanvas_Gpu, reporter, ctxInfo) { 522179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen SkSurface::ContentChangeMode modes[] = 523179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen { SkSurface::kDiscard_ContentChangeMode, SkSurface::kRetain_ContentChangeMode}; 524179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) { 525179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& test_func : { &test_no_canvas1, &test_no_canvas2 }) { 526179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen for (auto& mode : modes) { 5278b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon auto surface(surface_func(ctxInfo.grContext(), kPremul_SkAlphaType, nullptr)); 528e8f3062a36d3682f4019309a32b5b84dc9eddf8creed test_func(reporter, surface.get(), mode); 529e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon } 5303bddb38e6468c6294e40e5307f05e6b56bdd6a6crobertphillips@google.com } 531af0583528c7dd5344abfe14347377011abe374e2junov@chromium.org } 532995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org} 533179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen#endif 5349cd016e9b63f3827580d5b19a187dbf26b8e1436reed 5359cd016e9b63f3827580d5b19a187dbf26b8e1436reedstatic void check_rowbytes_remain_consistent(SkSurface* surface, skiatest::Reporter* reporter) { 5366ceeebd37a43d879c120b6ba100ae1febdd67a18reed SkPixmap surfacePM; 5376ceeebd37a43d879c120b6ba100ae1febdd67a18reed REPORTER_ASSERT(reporter, surface->peekPixels(&surfacePM)); 5389cd016e9b63f3827580d5b19a187dbf26b8e1436reed 5399ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image(surface->makeImageSnapshot()); 5406ceeebd37a43d879c120b6ba100ae1febdd67a18reed SkPixmap pm; 5416ceeebd37a43d879c120b6ba100ae1febdd67a18reed REPORTER_ASSERT(reporter, image->peekPixels(&pm)); 5429cd016e9b63f3827580d5b19a187dbf26b8e1436reed 5436ceeebd37a43d879c120b6ba100ae1febdd67a18reed REPORTER_ASSERT(reporter, surfacePM.rowBytes() == pm.rowBytes()); 5449cd016e9b63f3827580d5b19a187dbf26b8e1436reed 5459cd016e9b63f3827580d5b19a187dbf26b8e1436reed // trigger a copy-on-write 5469cd016e9b63f3827580d5b19a187dbf26b8e1436reed surface->getCanvas()->drawPaint(SkPaint()); 5479ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image2(surface->makeImageSnapshot()); 5489cd016e9b63f3827580d5b19a187dbf26b8e1436reed REPORTER_ASSERT(reporter, image->uniqueID() != image2->uniqueID()); 5499cd016e9b63f3827580d5b19a187dbf26b8e1436reed 5506ceeebd37a43d879c120b6ba100ae1febdd67a18reed SkPixmap pm2; 5516ceeebd37a43d879c120b6ba100ae1febdd67a18reed REPORTER_ASSERT(reporter, image2->peekPixels(&pm2)); 5526ceeebd37a43d879c120b6ba100ae1febdd67a18reed REPORTER_ASSERT(reporter, pm2.rowBytes() == pm.rowBytes()); 5539cd016e9b63f3827580d5b19a187dbf26b8e1436reed} 5549cd016e9b63f3827580d5b19a187dbf26b8e1436reed 5559cd016e9b63f3827580d5b19a187dbf26b8e1436reedDEF_TEST(surface_rowbytes, reporter) { 5569cd016e9b63f3827580d5b19a187dbf26b8e1436reed const SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100); 5579cd016e9b63f3827580d5b19a187dbf26b8e1436reed 558e8f3062a36d3682f4019309a32b5b84dc9eddf8creed auto surf0(SkSurface::MakeRaster(info)); 559e8f3062a36d3682f4019309a32b5b84dc9eddf8creed check_rowbytes_remain_consistent(surf0.get(), reporter); 5609cd016e9b63f3827580d5b19a187dbf26b8e1436reed 5619cd016e9b63f3827580d5b19a187dbf26b8e1436reed // specify a larger rowbytes 562e8f3062a36d3682f4019309a32b5b84dc9eddf8creed auto surf1(SkSurface::MakeRaster(info, 500, nullptr)); 563e8f3062a36d3682f4019309a32b5b84dc9eddf8creed check_rowbytes_remain_consistent(surf1.get(), reporter); 5649cd016e9b63f3827580d5b19a187dbf26b8e1436reed 5659cd016e9b63f3827580d5b19a187dbf26b8e1436reed // Try some illegal rowByte values 566e8f3062a36d3682f4019309a32b5b84dc9eddf8creed auto s = SkSurface::MakeRaster(info, 396, nullptr); // needs to be at least 400 5679cd016e9b63f3827580d5b19a187dbf26b8e1436reed REPORTER_ASSERT(reporter, nullptr == s); 568e8f3062a36d3682f4019309a32b5b84dc9eddf8creed s = SkSurface::MakeRaster(info, 1 << 30, nullptr); // allocation to large 5699cd016e9b63f3827580d5b19a187dbf26b8e1436reed REPORTER_ASSERT(reporter, nullptr == s); 5709cd016e9b63f3827580d5b19a187dbf26b8e1436reed} 571e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon 57203912f141fba6a5c17ac7e8fbe5998ac3834e29cfmalitaDEF_TEST(surface_raster_zeroinitialized, reporter) { 57303912f141fba6a5c17ac7e8fbe5998ac3834e29cfmalita sk_sp<SkSurface> s(SkSurface::MakeRasterN32Premul(100, 100)); 57403912f141fba6a5c17ac7e8fbe5998ac3834e29cfmalita SkPixmap pixmap; 57503912f141fba6a5c17ac7e8fbe5998ac3834e29cfmalita REPORTER_ASSERT(reporter, s->peekPixels(&pixmap)); 57603912f141fba6a5c17ac7e8fbe5998ac3834e29cfmalita 57703912f141fba6a5c17ac7e8fbe5998ac3834e29cfmalita for (int i = 0; i < pixmap.info().width(); ++i) { 57803912f141fba6a5c17ac7e8fbe5998ac3834e29cfmalita for (int j = 0; j < pixmap.info().height(); ++j) { 57903912f141fba6a5c17ac7e8fbe5998ac3834e29cfmalita REPORTER_ASSERT(reporter, *pixmap.addr32(i, j) == 0); 58003912f141fba6a5c17ac7e8fbe5998ac3834e29cfmalita } 58103912f141fba6a5c17ac7e8fbe5998ac3834e29cfmalita } 58203912f141fba6a5c17ac7e8fbe5998ac3834e29cfmalita} 58303912f141fba6a5c17ac7e8fbe5998ac3834e29cfmalita 584e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon#if SK_SUPPORT_GPU 585c4025189d31efcb0d54bf14b7712b38725f86c13ericrkstatic sk_sp<SkSurface> create_gpu_surface_backend_texture( 586c4025189d31efcb0d54bf14b7712b38725f86c13ericrk GrContext* context, int sampleCnt, uint32_t color, GrBackendObject* outTexture) { 587c4025189d31efcb0d54bf14b7712b38725f86c13ericrk const int kWidth = 10; 588c4025189d31efcb0d54bf14b7712b38725f86c13ericrk const int kHeight = 10; 5897ecc59610de72043e9b7ebaf1ef45c43425e54fcBen Wagner std::unique_ptr<uint32_t[]> pixels(new uint32_t[kWidth * kHeight]); 590c4025189d31efcb0d54bf14b7712b38725f86c13ericrk sk_memset32(pixels.get(), color, kWidth * kHeight); 5917ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel 5927ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel GrBackendObject backendHandle = context->getGpu()->createTestingOnlyBackendTexture( 5930a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel pixels.get(), kWidth, kHeight, kRGBA_8888_GrPixelConfig, true); 5947ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel 5957ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel GrBackendTexture backendTex = GrTest::CreateBackendTexture(context->contextPriv().getBackend(), 5967ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel kWidth, 5977ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel kHeight, 5987ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel kRGBA_8888_GrPixelConfig, 5997ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel backendHandle); 6007ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel 6017ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel sk_sp<SkSurface> surface = SkSurface::MakeFromBackendTexture(context, backendTex, 6027ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel kDefault_GrSurfaceOrigin, sampleCnt, 6037ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel nullptr, nullptr); 604c4025189d31efcb0d54bf14b7712b38725f86c13ericrk if (!surface) { 6057ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel context->getGpu()->deleteTestingOnlyBackendTexture(backendHandle); 606c4025189d31efcb0d54bf14b7712b38725f86c13ericrk return nullptr; 607c4025189d31efcb0d54bf14b7712b38725f86c13ericrk } 6087ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel *outTexture = backendHandle; 609c4025189d31efcb0d54bf14b7712b38725f86c13ericrk return surface; 610c4025189d31efcb0d54bf14b7712b38725f86c13ericrk} 611c4025189d31efcb0d54bf14b7712b38725f86c13ericrk 612c4025189d31efcb0d54bf14b7712b38725f86c13ericrkstatic sk_sp<SkSurface> create_gpu_surface_backend_texture_as_render_target( 613c4025189d31efcb0d54bf14b7712b38725f86c13ericrk GrContext* context, int sampleCnt, uint32_t color, GrBackendObject* outTexture) { 614c4025189d31efcb0d54bf14b7712b38725f86c13ericrk const int kWidth = 10; 615c4025189d31efcb0d54bf14b7712b38725f86c13ericrk const int kHeight = 10; 6167ecc59610de72043e9b7ebaf1ef45c43425e54fcBen Wagner std::unique_ptr<uint32_t[]> pixels(new uint32_t[kWidth * kHeight]); 617c4025189d31efcb0d54bf14b7712b38725f86c13ericrk sk_memset32(pixels.get(), color, kWidth * kHeight); 6187ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel 6197ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel GrBackendObject backendHandle = context->getGpu()->createTestingOnlyBackendTexture( 6200a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel pixels.get(), kWidth, kHeight, kRGBA_8888_GrPixelConfig, true); 6217ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel 6227ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel GrBackendTexture backendTex = GrTest::CreateBackendTexture(context->contextPriv().getBackend(), 6237ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel kWidth, 6247ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel kHeight, 6257ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel kRGBA_8888_GrPixelConfig, 6267ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel backendHandle); 6277ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel sk_sp<SkSurface> surface = SkSurface::MakeFromBackendTextureAsRenderTarget( 6287ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel context, backendTex, kDefault_GrSurfaceOrigin, sampleCnt, nullptr, nullptr); 6297ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel 630c4025189d31efcb0d54bf14b7712b38725f86c13ericrk if (!surface) { 6317ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel context->getGpu()->deleteTestingOnlyBackendTexture(backendHandle); 632c4025189d31efcb0d54bf14b7712b38725f86c13ericrk return nullptr; 633c4025189d31efcb0d54bf14b7712b38725f86c13ericrk } 6347ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel *outTexture = backendHandle; 635c4025189d31efcb0d54bf14b7712b38725f86c13ericrk return surface; 636c4025189d31efcb0d54bf14b7712b38725f86c13ericrk} 637e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon 638c4025189d31efcb0d54bf14b7712b38725f86c13ericrkstatic void test_surface_clear(skiatest::Reporter* reporter, sk_sp<SkSurface> surface, 6392c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips std::function<sk_sp<GrSurfaceContext>(SkSurface*)> grSurfaceGetter, 640c4025189d31efcb0d54bf14b7712b38725f86c13ericrk uint32_t expectedValue) { 641e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon if (!surface) { 642e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon ERRORF(reporter, "Could not create GPU SkSurface."); 643e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon return; 644e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon } 645e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon int w = surface->width(); 646e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon int h = surface->height(); 6477ecc59610de72043e9b7ebaf1ef45c43425e54fcBen Wagner std::unique_ptr<uint32_t[]> pixels(new uint32_t[w * h]); 648c4025189d31efcb0d54bf14b7712b38725f86c13ericrk sk_memset32(pixels.get(), ~expectedValue, w * h); 649e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon 6502c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips sk_sp<GrSurfaceContext> grSurfaceContext(grSurfaceGetter(surface.get())); 6512c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips if (!grSurfaceContext) { 652e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon ERRORF(reporter, "Could access render target of GPU SkSurface."); 653e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon return; 654e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon } 6552fba80912027999b560a97a832948c37ab36acfebsalomon surface.reset(); 6562c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips 6572c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips SkImageInfo ii = SkImageInfo::Make(w, h, kRGBA_8888_SkColorType, kPremul_SkAlphaType); 6582c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips grSurfaceContext->readPixels(ii, pixels.get(), 0, 0, 0); 659e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon for (int y = 0; y < h; ++y) { 660e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon for (int x = 0; x < w; ++x) { 661e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon uint32_t pixel = pixels.get()[y * w + x]; 662e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon if (pixel != expectedValue) { 663e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon SkString msg; 664e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon if (expectedValue) { 665e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon msg = "SkSurface should have left render target unmodified"; 666e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon } else { 667e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon msg = "SkSurface should have cleared the render target"; 668e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon } 669e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon ERRORF(reporter, 670e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon "%s but read 0x%08x (instead of 0x%08x) at %x,%d", msg.c_str(), pixel, 671e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon expectedValue, x, y); 672e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon return; 673e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon } 674e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon } 675e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon } 676e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon} 677e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon 678758586c7f11a6b3529bd4a1c9b4e982a0d0b0582bsalomonDEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SurfaceClear_Gpu, reporter, ctxInfo) { 6798b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon GrContext* context = ctxInfo.grContext(); 680c4025189d31efcb0d54bf14b7712b38725f86c13ericrk 6812c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips std::function<sk_sp<GrSurfaceContext>(SkSurface*)> grSurfaceContextGetters[] = { 6822c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips [] (SkSurface* s){ 6832c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips return sk_ref_sp(s->getCanvas()->internal_private_accessTopLayerRenderTargetContext()); 6842c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips }, 685ab527a5bbfb1eae4f99a1435d349a44d00477d82egdaniel [] (SkSurface* s){ 6862c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips sk_sp<SkImage> i(s->makeImageSnapshot()); 6872c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips SkImage_Gpu* gpuImage = (SkImage_Gpu *) as_IB(i); 6886de99041f13e87ed440f7db13a07693c6c4c461aRobert Phillips sk_sp<GrTextureProxy> proxy = gpuImage->asTextureProxyRef(); 6892c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips GrContext* context = gpuImage->context(); 6902c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips return context->contextPriv().makeWrappedSurfaceContext(std::move(proxy), 6912c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips gpuImage->refColorSpace()); 6922c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips } 693e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon }; 694c4025189d31efcb0d54bf14b7712b38725f86c13ericrk 6952c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips for (auto grSurfaceGetter : grSurfaceContextGetters) { 696c4025189d31efcb0d54bf14b7712b38725f86c13ericrk // Test that non-wrapped RTs are created clear. 697e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon for (auto& surface_func : {&create_gpu_surface, &create_gpu_scratch_surface}) { 698e8f3062a36d3682f4019309a32b5b84dc9eddf8creed auto surface = surface_func(context, kPremul_SkAlphaType, nullptr); 699e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon test_surface_clear(reporter, surface, grSurfaceGetter, 0x0); 700e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon } 701e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon // Wrapped RTs are *not* supposed to clear (to allow client to partially update a surface). 702c4025189d31efcb0d54bf14b7712b38725f86c13ericrk const uint32_t kOrigColor = 0xABABABAB; 703c4025189d31efcb0d54bf14b7712b38725f86c13ericrk for (auto& surfaceFunc : {&create_gpu_surface_backend_texture, 704c4025189d31efcb0d54bf14b7712b38725f86c13ericrk &create_gpu_surface_backend_texture_as_render_target}) { 705c4025189d31efcb0d54bf14b7712b38725f86c13ericrk GrBackendObject textureObject; 706c4025189d31efcb0d54bf14b7712b38725f86c13ericrk auto surface = surfaceFunc(context, 0, kOrigColor, &textureObject); 707c4025189d31efcb0d54bf14b7712b38725f86c13ericrk test_surface_clear(reporter, surface, grSurfaceGetter, kOrigColor); 708c4025189d31efcb0d54bf14b7712b38725f86c13ericrk surface.reset(); 709c4025189d31efcb0d54bf14b7712b38725f86c13ericrk context->getGpu()->deleteTestingOnlyBackendTexture(textureObject); 710c4025189d31efcb0d54bf14b7712b38725f86c13ericrk } 711c4025189d31efcb0d54bf14b7712b38725f86c13ericrk } 712c4025189d31efcb0d54bf14b7712b38725f86c13ericrk} 713c4025189d31efcb0d54bf14b7712b38725f86c13ericrk 714c4025189d31efcb0d54bf14b7712b38725f86c13ericrkstatic void test_surface_draw_partially( 715c4025189d31efcb0d54bf14b7712b38725f86c13ericrk skiatest::Reporter* reporter, sk_sp<SkSurface> surface, uint32_t origColor) { 716c4025189d31efcb0d54bf14b7712b38725f86c13ericrk const int kW = surface->width(); 717c4025189d31efcb0d54bf14b7712b38725f86c13ericrk const int kH = surface->height(); 718c4025189d31efcb0d54bf14b7712b38725f86c13ericrk SkPaint paint; 719c4025189d31efcb0d54bf14b7712b38725f86c13ericrk const SkColor kRectColor = ~origColor | 0xFF000000; 720c4025189d31efcb0d54bf14b7712b38725f86c13ericrk paint.setColor(kRectColor); 721c4025189d31efcb0d54bf14b7712b38725f86c13ericrk surface->getCanvas()->drawRect(SkRect::MakeWH(SkIntToScalar(kW), SkIntToScalar(kH)/2), 722c4025189d31efcb0d54bf14b7712b38725f86c13ericrk paint); 7237ecc59610de72043e9b7ebaf1ef45c43425e54fcBen Wagner std::unique_ptr<uint32_t[]> pixels(new uint32_t[kW * kH]); 724c4025189d31efcb0d54bf14b7712b38725f86c13ericrk sk_memset32(pixels.get(), ~origColor, kW * kH); 725c4025189d31efcb0d54bf14b7712b38725f86c13ericrk // Read back RGBA to avoid format conversions that may not be supported on all platforms. 726c4025189d31efcb0d54bf14b7712b38725f86c13ericrk SkImageInfo readInfo = SkImageInfo::Make(kW, kH, kRGBA_8888_SkColorType, kPremul_SkAlphaType); 727c4025189d31efcb0d54bf14b7712b38725f86c13ericrk SkAssertResult(surface->readPixels(readInfo, pixels.get(), kW * sizeof(uint32_t), 0, 0)); 728c4025189d31efcb0d54bf14b7712b38725f86c13ericrk bool stop = false; 729c4025189d31efcb0d54bf14b7712b38725f86c13ericrk SkPMColor origColorPM = SkPackARGB_as_RGBA((origColor >> 24 & 0xFF), 730c4025189d31efcb0d54bf14b7712b38725f86c13ericrk (origColor >> 0 & 0xFF), 731c4025189d31efcb0d54bf14b7712b38725f86c13ericrk (origColor >> 8 & 0xFF), 732c4025189d31efcb0d54bf14b7712b38725f86c13ericrk (origColor >> 16 & 0xFF)); 733c4025189d31efcb0d54bf14b7712b38725f86c13ericrk SkPMColor rectColorPM = SkPackARGB_as_RGBA((kRectColor >> 24 & 0xFF), 734c4025189d31efcb0d54bf14b7712b38725f86c13ericrk (kRectColor >> 16 & 0xFF), 735c4025189d31efcb0d54bf14b7712b38725f86c13ericrk (kRectColor >> 8 & 0xFF), 736c4025189d31efcb0d54bf14b7712b38725f86c13ericrk (kRectColor >> 0 & 0xFF)); 737c4025189d31efcb0d54bf14b7712b38725f86c13ericrk for (int y = 0; y < kH/2 && !stop; ++y) { 738c4025189d31efcb0d54bf14b7712b38725f86c13ericrk for (int x = 0; x < kW && !stop; ++x) { 739c4025189d31efcb0d54bf14b7712b38725f86c13ericrk REPORTER_ASSERT(reporter, rectColorPM == pixels[x + y * kW]); 740c4025189d31efcb0d54bf14b7712b38725f86c13ericrk if (rectColorPM != pixels[x + y * kW]) { 741c4025189d31efcb0d54bf14b7712b38725f86c13ericrk stop = true; 742c4025189d31efcb0d54bf14b7712b38725f86c13ericrk } 743c4025189d31efcb0d54bf14b7712b38725f86c13ericrk } 744c4025189d31efcb0d54bf14b7712b38725f86c13ericrk } 745c4025189d31efcb0d54bf14b7712b38725f86c13ericrk stop = false; 746c4025189d31efcb0d54bf14b7712b38725f86c13ericrk for (int y = kH/2; y < kH && !stop; ++y) { 747c4025189d31efcb0d54bf14b7712b38725f86c13ericrk for (int x = 0; x < kW && !stop; ++x) { 748c4025189d31efcb0d54bf14b7712b38725f86c13ericrk REPORTER_ASSERT(reporter, origColorPM == pixels[x + y * kW]); 749c4025189d31efcb0d54bf14b7712b38725f86c13ericrk if (origColorPM != pixels[x + y * kW]) { 750c4025189d31efcb0d54bf14b7712b38725f86c13ericrk stop = true; 751c4025189d31efcb0d54bf14b7712b38725f86c13ericrk } 752c4025189d31efcb0d54bf14b7712b38725f86c13ericrk } 753c4025189d31efcb0d54bf14b7712b38725f86c13ericrk } 754c4025189d31efcb0d54bf14b7712b38725f86c13ericrk} 755e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon 756ab527a5bbfb1eae4f99a1435d349a44d00477d82egdanielDEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfacePartialDraw_Gpu, reporter, ctxInfo) { 7578b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon GrGpu* gpu = ctxInfo.grContext()->getGpu(); 758c4025189d31efcb0d54bf14b7712b38725f86c13ericrk if (!gpu) { 759c4025189d31efcb0d54bf14b7712b38725f86c13ericrk return; 760c4025189d31efcb0d54bf14b7712b38725f86c13ericrk } 761c4025189d31efcb0d54bf14b7712b38725f86c13ericrk static const uint32_t kOrigColor = 0xFFAABBCC; 7620736f3386820f19c0fe90b5dda2094e253780071ericrk 763c4025189d31efcb0d54bf14b7712b38725f86c13ericrk for (auto& surfaceFunc : {&create_gpu_surface_backend_texture, 764c4025189d31efcb0d54bf14b7712b38725f86c13ericrk &create_gpu_surface_backend_texture_as_render_target}) { 765c4025189d31efcb0d54bf14b7712b38725f86c13ericrk // Validate that we can draw to the canvas and that the original texture color is 766c4025189d31efcb0d54bf14b7712b38725f86c13ericrk // preserved in pixels that aren't rendered to via the surface. 767c4025189d31efcb0d54bf14b7712b38725f86c13ericrk // This works only for non-multisampled case. 768c4025189d31efcb0d54bf14b7712b38725f86c13ericrk GrBackendObject textureObject; 7698b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon auto surface = surfaceFunc(ctxInfo.grContext(), 0, kOrigColor, &textureObject); 770c4025189d31efcb0d54bf14b7712b38725f86c13ericrk if (surface) { 771c4025189d31efcb0d54bf14b7712b38725f86c13ericrk test_surface_draw_partially(reporter, surface, kOrigColor); 772c4025189d31efcb0d54bf14b7712b38725f86c13ericrk surface.reset(); 773c4025189d31efcb0d54bf14b7712b38725f86c13ericrk gpu->deleteTestingOnlyBackendTexture(textureObject); 774c4025189d31efcb0d54bf14b7712b38725f86c13ericrk } 775c4025189d31efcb0d54bf14b7712b38725f86c13ericrk } 776c4025189d31efcb0d54bf14b7712b38725f86c13ericrk} 7770736f3386820f19c0fe90b5dda2094e253780071ericrk 778c4025189d31efcb0d54bf14b7712b38725f86c13ericrk 779c4025189d31efcb0d54bf14b7712b38725f86c13ericrkDEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SurfaceAttachStencil_Gpu, reporter, ctxInfo) { 7808b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon GrGpu* gpu = ctxInfo.grContext()->getGpu(); 781c4025189d31efcb0d54bf14b7712b38725f86c13ericrk if (!gpu) { 782c4025189d31efcb0d54bf14b7712b38725f86c13ericrk return; 783c4025189d31efcb0d54bf14b7712b38725f86c13ericrk } 7845c77975e4c00e18e644c72b56f369858acd11b15Eric Karl if (gpu->caps()->avoidStencilBuffers()) { 7855c77975e4c00e18e644c72b56f369858acd11b15Eric Karl return; 7865c77975e4c00e18e644c72b56f369858acd11b15Eric Karl } 787c4025189d31efcb0d54bf14b7712b38725f86c13ericrk static const uint32_t kOrigColor = 0xFFAABBCC; 788c4025189d31efcb0d54bf14b7712b38725f86c13ericrk 789c4025189d31efcb0d54bf14b7712b38725f86c13ericrk for (auto& surfaceFunc : {&create_gpu_surface_backend_texture, 790c4025189d31efcb0d54bf14b7712b38725f86c13ericrk &create_gpu_surface_backend_texture_as_render_target}) { 791c4025189d31efcb0d54bf14b7712b38725f86c13ericrk for (int sampleCnt : {0, 4, 8}) { 792c4025189d31efcb0d54bf14b7712b38725f86c13ericrk GrBackendObject textureObject; 7938b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon auto surface = surfaceFunc(ctxInfo.grContext(), sampleCnt, kOrigColor, &textureObject); 794c4025189d31efcb0d54bf14b7712b38725f86c13ericrk 795c4025189d31efcb0d54bf14b7712b38725f86c13ericrk if (!surface && sampleCnt > 0) { 796c4025189d31efcb0d54bf14b7712b38725f86c13ericrk // Certain platforms don't support MSAA, skip these. 797c4025189d31efcb0d54bf14b7712b38725f86c13ericrk continue; 798c4025189d31efcb0d54bf14b7712b38725f86c13ericrk } 799c4025189d31efcb0d54bf14b7712b38725f86c13ericrk 800c4025189d31efcb0d54bf14b7712b38725f86c13ericrk // Validate that we can attach a stencil buffer to an SkSurface created by either of 801c4025189d31efcb0d54bf14b7712b38725f86c13ericrk // our surface functions. 8021105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman GrRenderTarget* rt = surface->getCanvas() 8031105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman ->internal_private_accessTopLayerRenderTargetContext()->accessRenderTarget(); 804c4025189d31efcb0d54bf14b7712b38725f86c13ericrk REPORTER_ASSERT(reporter, 8058b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon ctxInfo.grContext()->resourceProvider()->attachStencilAttachment(rt)); 806c4025189d31efcb0d54bf14b7712b38725f86c13ericrk gpu->deleteTestingOnlyBackendTexture(textureObject); 807c4025189d31efcb0d54bf14b7712b38725f86c13ericrk } 808e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon } 809e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon} 810e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon#endif 8110e22eb8e6efc7d7ab7a601ba555947916d139906brianosman 8120e22eb8e6efc7d7ab7a601ba555947916d139906brianosmanstatic void test_surface_creation_and_snapshot_with_color_space( 8130e22eb8e6efc7d7ab7a601ba555947916d139906brianosman skiatest::Reporter* reporter, 8140e22eb8e6efc7d7ab7a601ba555947916d139906brianosman const char* prefix, 8150e22eb8e6efc7d7ab7a601ba555947916d139906brianosman bool f16Support, 8160e22eb8e6efc7d7ab7a601ba555947916d139906brianosman std::function<sk_sp<SkSurface>(const SkImageInfo&)> surfaceMaker) { 8170e22eb8e6efc7d7ab7a601ba555947916d139906brianosman 81877a7a1b57c16c97f056c1e50c03bdc954947778cMatt Sarett auto srgbColorSpace = SkColorSpace::MakeSRGB(); 81977a7a1b57c16c97f056c1e50c03bdc954947778cMatt Sarett auto adobeColorSpace = SkColorSpace_Base::MakeNamed(SkColorSpace_Base::kAdobeRGB_Named); 8209488833428e83c93a7e6002f4d056084fb57112fraftias const SkMatrix44* srgbMatrix = as_CSB(srgbColorSpace)->toXYZD50(); 8219488833428e83c93a7e6002f4d056084fb57112fraftias SkASSERT(srgbMatrix); 82299e3f7d6fcb7b3b4340286455733a7de9eb4ef81Matt Sarett SkColorSpaceTransferFn oddGamma; 82399e3f7d6fcb7b3b4340286455733a7de9eb4ef81Matt Sarett oddGamma.fA = 1.0f; 82499e3f7d6fcb7b3b4340286455733a7de9eb4ef81Matt Sarett oddGamma.fB = oddGamma.fC = oddGamma.fD = oddGamma.fE = oddGamma.fF = 0.0f; 82599e3f7d6fcb7b3b4340286455733a7de9eb4ef81Matt Sarett oddGamma.fG = 4.0f; 826526972ecb5411b84ba2f5e20252f178f9ee2151fBrian Osman auto oddColorSpace = SkColorSpace::MakeRGB(oddGamma, *srgbMatrix); 82777a7a1b57c16c97f056c1e50c03bdc954947778cMatt Sarett auto linearColorSpace = SkColorSpace::MakeSRGBLinear(); 8280e22eb8e6efc7d7ab7a601ba555947916d139906brianosman 8290e22eb8e6efc7d7ab7a601ba555947916d139906brianosman const struct { 8300e22eb8e6efc7d7ab7a601ba555947916d139906brianosman SkColorType fColorType; 8310e22eb8e6efc7d7ab7a601ba555947916d139906brianosman sk_sp<SkColorSpace> fColorSpace; 8320e22eb8e6efc7d7ab7a601ba555947916d139906brianosman bool fShouldWork; 8330e22eb8e6efc7d7ab7a601ba555947916d139906brianosman const char* fDescription; 8340e22eb8e6efc7d7ab7a601ba555947916d139906brianosman } testConfigs[] = { 8350e22eb8e6efc7d7ab7a601ba555947916d139906brianosman { kN32_SkColorType, nullptr, true, "N32-nullptr" }, 8360e22eb8e6efc7d7ab7a601ba555947916d139906brianosman { kN32_SkColorType, linearColorSpace, false, "N32-linear" }, 8370e22eb8e6efc7d7ab7a601ba555947916d139906brianosman { kN32_SkColorType, srgbColorSpace, true, "N32-srgb" }, 8380e22eb8e6efc7d7ab7a601ba555947916d139906brianosman { kN32_SkColorType, adobeColorSpace, true, "N32-adobe" }, 8390e22eb8e6efc7d7ab7a601ba555947916d139906brianosman { kN32_SkColorType, oddColorSpace, false, "N32-odd" }, 840b6759dd16e130cf844c799c96a20f4845a81e072Matt Sarett { kRGBA_F16_SkColorType, nullptr, false, "F16-nullptr" }, 8410e22eb8e6efc7d7ab7a601ba555947916d139906brianosman { kRGBA_F16_SkColorType, linearColorSpace, true, "F16-linear" }, 8420e22eb8e6efc7d7ab7a601ba555947916d139906brianosman { kRGBA_F16_SkColorType, srgbColorSpace, false, "F16-srgb" }, 8430e22eb8e6efc7d7ab7a601ba555947916d139906brianosman { kRGBA_F16_SkColorType, adobeColorSpace, false, "F16-adobe" }, 8440e22eb8e6efc7d7ab7a601ba555947916d139906brianosman { kRGBA_F16_SkColorType, oddColorSpace, false, "F16-odd" }, 8450e22eb8e6efc7d7ab7a601ba555947916d139906brianosman { kRGB_565_SkColorType, srgbColorSpace, false, "565-srgb" }, 8460e22eb8e6efc7d7ab7a601ba555947916d139906brianosman { kAlpha_8_SkColorType, srgbColorSpace, false, "A8-srgb" }, 8470e22eb8e6efc7d7ab7a601ba555947916d139906brianosman }; 8480e22eb8e6efc7d7ab7a601ba555947916d139906brianosman 8490e22eb8e6efc7d7ab7a601ba555947916d139906brianosman for (auto& testConfig : testConfigs) { 8500e22eb8e6efc7d7ab7a601ba555947916d139906brianosman SkString fullTestName = SkStringPrintf("%s-%s", prefix, testConfig.fDescription); 8510e22eb8e6efc7d7ab7a601ba555947916d139906brianosman SkImageInfo info = SkImageInfo::Make(10, 10, testConfig.fColorType, kPremul_SkAlphaType, 8520e22eb8e6efc7d7ab7a601ba555947916d139906brianosman testConfig.fColorSpace); 8530e22eb8e6efc7d7ab7a601ba555947916d139906brianosman 8540e22eb8e6efc7d7ab7a601ba555947916d139906brianosman // For some GPU contexts (eg ANGLE), we don't have f16 support, so we should fail to create 8550e22eb8e6efc7d7ab7a601ba555947916d139906brianosman // any surface of that type: 8560e22eb8e6efc7d7ab7a601ba555947916d139906brianosman bool shouldWork = testConfig.fShouldWork && 8570e22eb8e6efc7d7ab7a601ba555947916d139906brianosman (f16Support || kRGBA_F16_SkColorType != testConfig.fColorType); 8580e22eb8e6efc7d7ab7a601ba555947916d139906brianosman 8590e22eb8e6efc7d7ab7a601ba555947916d139906brianosman auto surface(surfaceMaker(info)); 8600e22eb8e6efc7d7ab7a601ba555947916d139906brianosman REPORTER_ASSERT_MESSAGE(reporter, SkToBool(surface) == shouldWork, fullTestName.c_str()); 8610e22eb8e6efc7d7ab7a601ba555947916d139906brianosman 8620e22eb8e6efc7d7ab7a601ba555947916d139906brianosman if (shouldWork && surface) { 8630e22eb8e6efc7d7ab7a601ba555947916d139906brianosman sk_sp<SkImage> image(surface->makeImageSnapshot()); 8640e22eb8e6efc7d7ab7a601ba555947916d139906brianosman REPORTER_ASSERT_MESSAGE(reporter, image, testConfig.fDescription); 8650e22eb8e6efc7d7ab7a601ba555947916d139906brianosman SkColorSpace* imageColorSpace = as_IB(image)->onImageInfo().colorSpace(); 8660e22eb8e6efc7d7ab7a601ba555947916d139906brianosman REPORTER_ASSERT_MESSAGE(reporter, imageColorSpace == testConfig.fColorSpace.get(), 8670e22eb8e6efc7d7ab7a601ba555947916d139906brianosman fullTestName.c_str()); 8680e22eb8e6efc7d7ab7a601ba555947916d139906brianosman } 8690e22eb8e6efc7d7ab7a601ba555947916d139906brianosman } 8700e22eb8e6efc7d7ab7a601ba555947916d139906brianosman} 8710e22eb8e6efc7d7ab7a601ba555947916d139906brianosman 8720e22eb8e6efc7d7ab7a601ba555947916d139906brianosmanDEF_TEST(SurfaceCreationWithColorSpace, reporter) { 8730e22eb8e6efc7d7ab7a601ba555947916d139906brianosman auto surfaceMaker = [](const SkImageInfo& info) { 8740e22eb8e6efc7d7ab7a601ba555947916d139906brianosman return SkSurface::MakeRaster(info); 8750e22eb8e6efc7d7ab7a601ba555947916d139906brianosman }; 8760e22eb8e6efc7d7ab7a601ba555947916d139906brianosman 8770e22eb8e6efc7d7ab7a601ba555947916d139906brianosman test_surface_creation_and_snapshot_with_color_space(reporter, "raster", true, surfaceMaker); 8780e22eb8e6efc7d7ab7a601ba555947916d139906brianosman} 8790e22eb8e6efc7d7ab7a601ba555947916d139906brianosman 8800e22eb8e6efc7d7ab7a601ba555947916d139906brianosman#if SK_SUPPORT_GPU 8810e22eb8e6efc7d7ab7a601ba555947916d139906brianosmanDEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceCreationWithColorSpace_Gpu, reporter, ctxInfo) { 8820e22eb8e6efc7d7ab7a601ba555947916d139906brianosman GrContext* context = ctxInfo.grContext(); 8830e22eb8e6efc7d7ab7a601ba555947916d139906brianosman bool f16Support = context->caps()->isConfigRenderable(kRGBA_half_GrPixelConfig, false); 8840e22eb8e6efc7d7ab7a601ba555947916d139906brianosman auto surfaceMaker = [context](const SkImageInfo& info) { 8850e22eb8e6efc7d7ab7a601ba555947916d139906brianosman return SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info); 8860e22eb8e6efc7d7ab7a601ba555947916d139906brianosman }; 8870e22eb8e6efc7d7ab7a601ba555947916d139906brianosman 8880e22eb8e6efc7d7ab7a601ba555947916d139906brianosman test_surface_creation_and_snapshot_with_color_space(reporter, "gpu", f16Support, surfaceMaker); 8890e22eb8e6efc7d7ab7a601ba555947916d139906brianosman 8900e22eb8e6efc7d7ab7a601ba555947916d139906brianosman std::vector<GrBackendObject> textureHandles; 8910e22eb8e6efc7d7ab7a601ba555947916d139906brianosman auto wrappedSurfaceMaker = [context,&textureHandles](const SkImageInfo& info) { 8927ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel static const int kSize = 10; 8937ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel GrPixelConfig config = SkImageInfo2GrPixelConfig(info, *context->caps()); 8947ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel 8957ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel GrBackendObject backendHandle = context->getGpu()->createTestingOnlyBackendTexture( 8967ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel nullptr, kSize, kSize, config, true); 8977ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel 8987ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel if (!backendHandle) { 8990e22eb8e6efc7d7ab7a601ba555947916d139906brianosman return sk_sp<SkSurface>(nullptr); 9000e22eb8e6efc7d7ab7a601ba555947916d139906brianosman } 9017ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel textureHandles.push_back(backendHandle); 9027ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel 9037ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel GrBackendTexture backendTex = GrTest::CreateBackendTexture(context->contextPriv().getBackend(), 9047ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel kSize, 9057ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel kSize, 9067ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel config, 9077ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel backendHandle); 9080e22eb8e6efc7d7ab7a601ba555947916d139906brianosman 9097ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel return SkSurface::MakeFromBackendTexture(context, backendTex, 9107ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel kDefault_GrSurfaceOrigin, 0, 9117ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel sk_ref_sp(info.colorSpace()), nullptr); 9120e22eb8e6efc7d7ab7a601ba555947916d139906brianosman }; 9130e22eb8e6efc7d7ab7a601ba555947916d139906brianosman 9140e22eb8e6efc7d7ab7a601ba555947916d139906brianosman test_surface_creation_and_snapshot_with_color_space(reporter, "wrapped", f16Support, 9150e22eb8e6efc7d7ab7a601ba555947916d139906brianosman wrappedSurfaceMaker); 9160e22eb8e6efc7d7ab7a601ba555947916d139906brianosman 9176cdc22cde8e6297d34fdaaa3ed5e69ae86c30a77Robert Phillips context->flush(); 9186cdc22cde8e6297d34fdaaa3ed5e69ae86c30a77Robert Phillips 9190e22eb8e6efc7d7ab7a601ba555947916d139906brianosman for (auto textureHandle : textureHandles) { 9200e22eb8e6efc7d7ab7a601ba555947916d139906brianosman context->getGpu()->deleteTestingOnlyBackendTexture(textureHandle); 9210e22eb8e6efc7d7ab7a601ba555947916d139906brianosman } 9220e22eb8e6efc7d7ab7a601ba555947916d139906brianosman} 9230e22eb8e6efc7d7ab7a601ba555947916d139906brianosman#endif 92422886c493596655d8fd9512951f9010869b7fbc5Matt Sarett 92522886c493596655d8fd9512951f9010869b7fbc5Matt Sarettstatic void test_overdraw_surface(skiatest::Reporter* r, SkSurface* surface) { 926e11b614795bbe707d131ad599ead5be452e7c06fMatt Sarett SkOverdrawCanvas canvas(surface->getCanvas()); 927e11b614795bbe707d131ad599ead5be452e7c06fMatt Sarett canvas.drawPaint(SkPaint()); 92822886c493596655d8fd9512951f9010869b7fbc5Matt Sarett sk_sp<SkImage> image = surface->makeImageSnapshot(); 92922886c493596655d8fd9512951f9010869b7fbc5Matt Sarett 93022886c493596655d8fd9512951f9010869b7fbc5Matt Sarett SkBitmap bitmap; 93122886c493596655d8fd9512951f9010869b7fbc5Matt Sarett image->asLegacyBitmap(&bitmap, SkImage::kRO_LegacyBitmapMode); 93222886c493596655d8fd9512951f9010869b7fbc5Matt Sarett for (int y = 0; y < 10; y++) { 93322886c493596655d8fd9512951f9010869b7fbc5Matt Sarett for (int x = 0; x < 10; x++) { 93422886c493596655d8fd9512951f9010869b7fbc5Matt Sarett REPORTER_ASSERT(r, 1 == SkGetPackedA32(*bitmap.getAddr32(x, y))); 93522886c493596655d8fd9512951f9010869b7fbc5Matt Sarett } 93622886c493596655d8fd9512951f9010869b7fbc5Matt Sarett } 93722886c493596655d8fd9512951f9010869b7fbc5Matt Sarett} 93822886c493596655d8fd9512951f9010869b7fbc5Matt Sarett 93922886c493596655d8fd9512951f9010869b7fbc5Matt SarettDEF_TEST(OverdrawSurface_Raster, r) { 94022886c493596655d8fd9512951f9010869b7fbc5Matt Sarett sk_sp<SkSurface> surface = create_surface(); 94122886c493596655d8fd9512951f9010869b7fbc5Matt Sarett test_overdraw_surface(r, surface.get()); 94222886c493596655d8fd9512951f9010869b7fbc5Matt Sarett} 94322886c493596655d8fd9512951f9010869b7fbc5Matt Sarett 94422886c493596655d8fd9512951f9010869b7fbc5Matt Sarett#if SK_SUPPORT_GPU 94522886c493596655d8fd9512951f9010869b7fbc5Matt SarettDEF_GPUTEST_FOR_RENDERING_CONTEXTS(OverdrawSurface_Gpu, r, ctxInfo) { 94622886c493596655d8fd9512951f9010869b7fbc5Matt Sarett GrContext* context = ctxInfo.grContext(); 94722886c493596655d8fd9512951f9010869b7fbc5Matt Sarett sk_sp<SkSurface> surface = create_gpu_surface(context); 94822886c493596655d8fd9512951f9010869b7fbc5Matt Sarett test_overdraw_surface(r, surface.get()); 94922886c493596655d8fd9512951f9010869b7fbc5Matt Sarett} 95022886c493596655d8fd9512951f9010869b7fbc5Matt Sarett#endif 95144d04bd7ed3be8c39cc7ea02e3789cccf083bb55Mike Reed 95244d04bd7ed3be8c39cc7ea02e3789cccf083bb55Mike ReedDEF_TEST(Surface_null, r) { 95344d04bd7ed3be8c39cc7ea02e3789cccf083bb55Mike Reed REPORTER_ASSERT(r, SkSurface::MakeNull(0, 0) == nullptr); 95444d04bd7ed3be8c39cc7ea02e3789cccf083bb55Mike Reed 95544d04bd7ed3be8c39cc7ea02e3789cccf083bb55Mike Reed const int w = 37; 95644d04bd7ed3be8c39cc7ea02e3789cccf083bb55Mike Reed const int h = 1000; 95744d04bd7ed3be8c39cc7ea02e3789cccf083bb55Mike Reed auto surf = SkSurface::MakeNull(w, h); 95844d04bd7ed3be8c39cc7ea02e3789cccf083bb55Mike Reed auto canvas = surf->getCanvas(); 95944d04bd7ed3be8c39cc7ea02e3789cccf083bb55Mike Reed 96044d04bd7ed3be8c39cc7ea02e3789cccf083bb55Mike Reed canvas->drawPaint(SkPaint()); // should not crash, but don't expect anything to draw 96144d04bd7ed3be8c39cc7ea02e3789cccf083bb55Mike Reed REPORTER_ASSERT(r, surf->makeImageSnapshot() == nullptr); 96244d04bd7ed3be8c39cc7ea02e3789cccf083bb55Mike Reed} 963