Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright 2013 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include <functional>
      9 #include "SkCanvas.h"
     10 #include "SkColorSpace_Base.h"
     11 #include "SkData.h"
     12 #include "SkDevice.h"
     13 #include "SkImage_Base.h"
     14 #include "SkOverdrawCanvas.h"
     15 #include "SkPath.h"
     16 #include "SkRegion.h"
     17 #include "SkRRect.h"
     18 #include "SkSurface.h"
     19 #include "SkUtils.h"
     20 #include "Test.h"
     21 
     22 #if SK_SUPPORT_GPU
     23 #include "GrContext.h"
     24 #include "GrContextPriv.h"
     25 #include "GrRenderTargetContext.h"
     26 #include "GrGpu.h"
     27 #include "GrResourceProvider.h"
     28 #include "GrTest.h"
     29 #include <vector>
     30 #endif
     31 
     32 #include <initializer_list>
     33 
     34 static void release_direct_surface_storage(void* pixels, void* context) {
     35     SkASSERT(pixels == context);
     36     sk_free(pixels);
     37 }
     38 static sk_sp<SkSurface> create_surface(SkAlphaType at = kPremul_SkAlphaType,
     39                                        SkImageInfo* requestedInfo = nullptr) {
     40     const SkImageInfo info = SkImageInfo::MakeN32(10, 10, at);
     41     if (requestedInfo) {
     42         *requestedInfo = info;
     43     }
     44     return SkSurface::MakeRaster(info);
     45 }
     46 static sk_sp<SkSurface> create_direct_surface(SkAlphaType at = kPremul_SkAlphaType,
     47                                               SkImageInfo* requestedInfo = nullptr) {
     48     const SkImageInfo info = SkImageInfo::MakeN32(10, 10, at);
     49     if (requestedInfo) {
     50         *requestedInfo = info;
     51     }
     52     const size_t rowBytes = info.minRowBytes();
     53     void* storage = sk_malloc_throw(info.getSafeSize(rowBytes));
     54     return SkSurface::MakeRasterDirectReleaseProc(info, storage, rowBytes,
     55                                                   release_direct_surface_storage,
     56                                                   storage);
     57 }
     58 #if SK_SUPPORT_GPU
     59 static sk_sp<SkSurface> create_gpu_surface(GrContext* context, SkAlphaType at = kPremul_SkAlphaType,
     60                                            SkImageInfo* requestedInfo = nullptr) {
     61     const SkImageInfo info = SkImageInfo::MakeN32(10, 10, at);
     62     if (requestedInfo) {
     63         *requestedInfo = info;
     64     }
     65     return SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info);
     66 }
     67 static sk_sp<SkSurface> create_gpu_scratch_surface(GrContext* context,
     68                                                    SkAlphaType at = kPremul_SkAlphaType,
     69                                                    SkImageInfo* requestedInfo = nullptr) {
     70     const SkImageInfo info = SkImageInfo::MakeN32(10, 10, at);
     71     if (requestedInfo) {
     72         *requestedInfo = info;
     73     }
     74     return SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, info);
     75 }
     76 #endif
     77 
     78 DEF_TEST(SurfaceEmpty, reporter) {
     79     const SkImageInfo info = SkImageInfo::Make(0, 0, kN32_SkColorType, kPremul_SkAlphaType);
     80     REPORTER_ASSERT(reporter, nullptr == SkSurface::MakeRaster(info));
     81     REPORTER_ASSERT(reporter, nullptr == SkSurface::MakeRasterDirect(info, nullptr, 0));
     82 
     83 }
     84 #if SK_SUPPORT_GPU
     85 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceEmpty_Gpu, reporter, ctxInfo) {
     86     const SkImageInfo info = SkImageInfo::Make(0, 0, kN32_SkColorType, kPremul_SkAlphaType);
     87     REPORTER_ASSERT(reporter, nullptr ==
     88                     SkSurface::MakeRenderTarget(ctxInfo.grContext(), SkBudgeted::kNo, info));
     89 }
     90 #endif
     91 
     92 static void test_canvas_peek(skiatest::Reporter* reporter,
     93                              sk_sp<SkSurface>& surface,
     94                              const SkImageInfo& requestInfo,
     95                              bool expectPeekSuccess) {
     96     const SkColor color = SK_ColorRED;
     97     const SkPMColor pmcolor = SkPreMultiplyColor(color);
     98     surface->getCanvas()->clear(color);
     99 
    100     SkPixmap pmap;
    101     bool success = surface->getCanvas()->peekPixels(&pmap);
    102     REPORTER_ASSERT(reporter, expectPeekSuccess == success);
    103 
    104     SkPixmap pmap2;
    105     const void* addr2 = surface->peekPixels(&pmap2) ? pmap2.addr() : nullptr;
    106 
    107     if (success) {
    108         REPORTER_ASSERT(reporter, requestInfo == pmap.info());
    109         REPORTER_ASSERT(reporter, requestInfo.minRowBytes() <= pmap.rowBytes());
    110         REPORTER_ASSERT(reporter, pmcolor == *pmap.addr32());
    111 
    112         REPORTER_ASSERT(reporter, pmap.addr() == pmap2.addr());
    113         REPORTER_ASSERT(reporter, pmap.info() == pmap2.info());
    114         REPORTER_ASSERT(reporter, pmap.rowBytes() == pmap2.rowBytes());
    115     } else {
    116         REPORTER_ASSERT(reporter, nullptr == addr2);
    117     }
    118 }
    119 DEF_TEST(SurfaceCanvasPeek, reporter) {
    120     for (auto& surface_func : { &create_surface, &create_direct_surface }) {
    121         SkImageInfo requestInfo;
    122         auto surface(surface_func(kPremul_SkAlphaType, &requestInfo));
    123         test_canvas_peek(reporter, surface, requestInfo, true);
    124     }
    125 }
    126 #if SK_SUPPORT_GPU
    127 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceCanvasPeek_Gpu, reporter, ctxInfo) {
    128     for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) {
    129         SkImageInfo requestInfo;
    130         auto surface(surface_func(ctxInfo.grContext(), kPremul_SkAlphaType, &requestInfo));
    131         test_canvas_peek(reporter, surface, requestInfo, false);
    132     }
    133 }
    134 #endif
    135 
    136 static void test_snapshot_alphatype(skiatest::Reporter* reporter, const sk_sp<SkSurface>& surface,
    137                                     SkAlphaType expectedAlphaType) {
    138     REPORTER_ASSERT(reporter, surface);
    139     if (surface) {
    140         sk_sp<SkImage> image(surface->makeImageSnapshot());
    141         REPORTER_ASSERT(reporter, image);
    142         if (image) {
    143             REPORTER_ASSERT(reporter, image->alphaType() == expectedAlphaType);
    144         }
    145     }
    146 }
    147 DEF_TEST(SurfaceSnapshotAlphaType, reporter) {
    148     for (auto& surface_func : { &create_surface, &create_direct_surface }) {
    149         for (auto& at: { kOpaque_SkAlphaType, kPremul_SkAlphaType, kUnpremul_SkAlphaType }) {
    150             auto surface(surface_func(at, nullptr));
    151             test_snapshot_alphatype(reporter, surface, at);
    152         }
    153     }
    154 }
    155 #if SK_SUPPORT_GPU
    156 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceSnapshotAlphaType_Gpu, reporter, ctxInfo) {
    157     for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) {
    158         // GPU doesn't support creating unpremul surfaces, so only test opaque + premul
    159         for (auto& at : { kOpaque_SkAlphaType, kPremul_SkAlphaType }) {
    160             auto surface(surface_func(ctxInfo.grContext(), at, nullptr));
    161             test_snapshot_alphatype(reporter, surface, at);
    162         }
    163     }
    164 }
    165 #endif
    166 
    167 static GrBackendObject get_surface_backend_texture_handle(
    168     SkSurface* s, SkSurface::BackendHandleAccess a) {
    169     return s->getTextureHandle(a);
    170 }
    171 static GrBackendObject get_surface_backend_render_target_handle(
    172     SkSurface* s, SkSurface::BackendHandleAccess a) {
    173     GrBackendObject result;
    174     if (!s->getRenderTargetHandle(&result, a)) {
    175         return 0;
    176     }
    177     return result;
    178 }
    179 
    180 static void test_backend_handle_access_copy_on_write(
    181     skiatest::Reporter* reporter, SkSurface* surface, SkSurface::BackendHandleAccess mode,
    182     GrBackendObject (*func)(SkSurface*, SkSurface::BackendHandleAccess)) {
    183     GrBackendObject obj1 = func(surface, mode);
    184     sk_sp<SkImage> snap1(surface->makeImageSnapshot());
    185 
    186     GrBackendObject obj2 = func(surface, mode);
    187     sk_sp<SkImage> snap2(surface->makeImageSnapshot());
    188 
    189     // If the access mode triggers CoW, then the backend objects should reflect it.
    190     REPORTER_ASSERT(reporter, (obj1 == obj2) == (snap1 == snap2));
    191 }
    192 DEF_TEST(SurfaceBackendHandleAccessCopyOnWrite, reporter) {
    193     const SkSurface::BackendHandleAccess accessModes[] = {
    194         SkSurface::kFlushRead_BackendHandleAccess,
    195         SkSurface::kFlushWrite_BackendHandleAccess,
    196         SkSurface::kDiscardWrite_BackendHandleAccess,
    197     };
    198     for (auto& handle_access_func :
    199             { &get_surface_backend_texture_handle, &get_surface_backend_render_target_handle }) {
    200         for (auto& accessMode : accessModes) {
    201             auto surface(create_surface());
    202             test_backend_handle_access_copy_on_write(reporter, surface.get(), accessMode,
    203                                                      handle_access_func);
    204         }
    205     }
    206 }
    207 #if SK_SUPPORT_GPU
    208 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceBackendHandleAccessCopyOnWrite_Gpu, reporter, ctxInfo) {
    209         const SkSurface::BackendHandleAccess accessModes[] = {
    210         SkSurface::kFlushRead_BackendHandleAccess,
    211         SkSurface::kFlushWrite_BackendHandleAccess,
    212         SkSurface::kDiscardWrite_BackendHandleAccess,
    213     };
    214     for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) {
    215         for (auto& handle_access_func :
    216                 { &get_surface_backend_texture_handle, &get_surface_backend_render_target_handle }) {
    217             for (auto& accessMode : accessModes) {
    218                 auto surface(surface_func(ctxInfo.grContext(), kPremul_SkAlphaType, nullptr));
    219                 test_backend_handle_access_copy_on_write(reporter, surface.get(), accessMode,
    220                                                          handle_access_func);
    221             }
    222         }
    223     }
    224 }
    225 #endif
    226 
    227 #if SK_SUPPORT_GPU
    228 
    229 static void test_backend_handle_unique_id(
    230     skiatest::Reporter* reporter, SkSurface* surface,
    231     GrBackendObject (*func)(SkSurface*, SkSurface::BackendHandleAccess)) {
    232     sk_sp<SkImage> image0(surface->makeImageSnapshot());
    233     GrBackendObject obj = func(surface, SkSurface::kFlushRead_BackendHandleAccess);
    234     REPORTER_ASSERT(reporter, obj != 0);
    235     sk_sp<SkImage> image1(surface->makeImageSnapshot());
    236     // just read access should not affect the snapshot
    237     REPORTER_ASSERT(reporter, image0->uniqueID() == image1->uniqueID());
    238 
    239     obj = func(surface, SkSurface::kFlushWrite_BackendHandleAccess);
    240     REPORTER_ASSERT(reporter, obj != 0);
    241     sk_sp<SkImage> image2(surface->makeImageSnapshot());
    242     // expect a new image, since we claimed we would write
    243     REPORTER_ASSERT(reporter, image0->uniqueID() != image2->uniqueID());
    244 
    245     obj = func(surface, SkSurface::kDiscardWrite_BackendHandleAccess);
    246     REPORTER_ASSERT(reporter, obj != 0);
    247     sk_sp<SkImage> image3(surface->makeImageSnapshot());
    248     // expect a new(er) image, since we claimed we would write
    249     REPORTER_ASSERT(reporter, image0->uniqueID() != image3->uniqueID());
    250     REPORTER_ASSERT(reporter, image2->uniqueID() != image3->uniqueID());
    251 }
    252 // No CPU test.
    253 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceBackendHandleAccessIDs_Gpu, reporter, ctxInfo) {
    254     for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) {
    255         for (auto& test_func : { &test_backend_handle_unique_id }) {
    256             for (auto& handle_access_func :
    257                 { &get_surface_backend_texture_handle, &get_surface_backend_render_target_handle}) {
    258                 auto surface(surface_func(ctxInfo.grContext(), kPremul_SkAlphaType, nullptr));
    259                 test_func(reporter, surface.get(), handle_access_func);
    260             }
    261         }
    262     }
    263 }
    264 #endif
    265 
    266 // Verify that the right canvas commands trigger a copy on write.
    267 static void test_copy_on_write(skiatest::Reporter* reporter, SkSurface* surface) {
    268     SkCanvas* canvas = surface->getCanvas();
    269 
    270     const SkRect testRect =
    271         SkRect::MakeXYWH(SkIntToScalar(0), SkIntToScalar(0),
    272                          SkIntToScalar(4), SkIntToScalar(5));
    273     SkPath testPath;
    274     testPath.addRect(SkRect::MakeXYWH(SkIntToScalar(0), SkIntToScalar(0),
    275                                       SkIntToScalar(2), SkIntToScalar(1)));
    276 
    277     const SkIRect testIRect = SkIRect::MakeXYWH(0, 0, 2, 1);
    278 
    279     SkRegion testRegion;
    280     testRegion.setRect(testIRect);
    281 
    282 
    283     const SkColor testColor = 0x01020304;
    284     const SkPaint testPaint;
    285     const SkPoint testPoints[3] = {
    286         {SkIntToScalar(0), SkIntToScalar(0)},
    287         {SkIntToScalar(2), SkIntToScalar(1)},
    288         {SkIntToScalar(0), SkIntToScalar(2)}
    289     };
    290     const size_t testPointCount = 3;
    291 
    292     SkBitmap testBitmap;
    293     testBitmap.allocN32Pixels(10, 10);
    294     testBitmap.eraseColor(0);
    295 
    296     SkRRect testRRect;
    297     testRRect.setRectXY(testRect, SK_Scalar1, SK_Scalar1);
    298 
    299     SkString testText("Hello World");
    300     const SkPoint testPoints2[] = {
    301         { SkIntToScalar(0), SkIntToScalar(1) },
    302         { SkIntToScalar(1), SkIntToScalar(1) },
    303         { SkIntToScalar(2), SkIntToScalar(1) },
    304         { SkIntToScalar(3), SkIntToScalar(1) },
    305         { SkIntToScalar(4), SkIntToScalar(1) },
    306         { SkIntToScalar(5), SkIntToScalar(1) },
    307         { SkIntToScalar(6), SkIntToScalar(1) },
    308         { SkIntToScalar(7), SkIntToScalar(1) },
    309         { SkIntToScalar(8), SkIntToScalar(1) },
    310         { SkIntToScalar(9), SkIntToScalar(1) },
    311         { SkIntToScalar(10), SkIntToScalar(1) },
    312     };
    313 
    314 #define EXPECT_COPY_ON_WRITE(command)                               \
    315     {                                                               \
    316         sk_sp<SkImage> imageBefore = surface->makeImageSnapshot();  \
    317         sk_sp<SkImage> aur_before(imageBefore);                     \
    318         canvas-> command ;                                          \
    319         sk_sp<SkImage> imageAfter = surface->makeImageSnapshot();   \
    320         sk_sp<SkImage> aur_after(imageAfter);                       \
    321         REPORTER_ASSERT(reporter, imageBefore != imageAfter);       \
    322     }
    323 
    324     EXPECT_COPY_ON_WRITE(clear(testColor))
    325     EXPECT_COPY_ON_WRITE(drawPaint(testPaint))
    326     EXPECT_COPY_ON_WRITE(drawPoints(SkCanvas::kPoints_PointMode, testPointCount, testPoints, \
    327         testPaint))
    328     EXPECT_COPY_ON_WRITE(drawOval(testRect, testPaint))
    329     EXPECT_COPY_ON_WRITE(drawRect(testRect, testPaint))
    330     EXPECT_COPY_ON_WRITE(drawRRect(testRRect, testPaint))
    331     EXPECT_COPY_ON_WRITE(drawPath(testPath, testPaint))
    332     EXPECT_COPY_ON_WRITE(drawBitmap(testBitmap, 0, 0))
    333     EXPECT_COPY_ON_WRITE(drawBitmapRect(testBitmap, testRect, nullptr))
    334     EXPECT_COPY_ON_WRITE(drawBitmapNine(testBitmap, testIRect, testRect, nullptr))
    335     EXPECT_COPY_ON_WRITE(drawString(testText, 0, 1, testPaint))
    336     EXPECT_COPY_ON_WRITE(drawPosText(testText.c_str(), testText.size(), testPoints2, \
    337         testPaint))
    338     EXPECT_COPY_ON_WRITE(drawTextOnPath(testText.c_str(), testText.size(), testPath, nullptr, \
    339         testPaint))
    340 }
    341 DEF_TEST(SurfaceCopyOnWrite, reporter) {
    342     test_copy_on_write(reporter, create_surface().get());
    343 }
    344 #if SK_SUPPORT_GPU
    345 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceCopyOnWrite_Gpu, reporter, ctxInfo) {
    346     for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) {
    347         auto surface(surface_func(ctxInfo.grContext(), kPremul_SkAlphaType, nullptr));
    348         test_copy_on_write(reporter, surface.get());
    349     }
    350 }
    351 #endif
    352 
    353 static void test_writable_after_snapshot_release(skiatest::Reporter* reporter,
    354                                                  SkSurface* surface) {
    355     // This test succeeds by not triggering an assertion.
    356     // The test verifies that the surface remains writable (usable) after
    357     // acquiring and releasing a snapshot without triggering a copy on write.
    358     SkCanvas* canvas = surface->getCanvas();
    359     canvas->clear(1);
    360     surface->makeImageSnapshot();  // Create and destroy SkImage
    361     canvas->clear(2);  // Must not assert internally
    362 }
    363 DEF_TEST(SurfaceWriteableAfterSnapshotRelease, reporter) {
    364     test_writable_after_snapshot_release(reporter, create_surface().get());
    365 }
    366 #if SK_SUPPORT_GPU
    367 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceWriteableAfterSnapshotRelease_Gpu, reporter, ctxInfo) {
    368     for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) {
    369         auto surface(surface_func(ctxInfo.grContext(), kPremul_SkAlphaType, nullptr));
    370         test_writable_after_snapshot_release(reporter, surface.get());
    371     }
    372 }
    373 #endif
    374 
    375 #if SK_SUPPORT_GPU
    376 static void test_crbug263329(skiatest::Reporter* reporter,
    377                              SkSurface* surface1,
    378                              SkSurface* surface2) {
    379     // This is a regression test for crbug.com/263329
    380     // Bug was caused by onCopyOnWrite releasing the old surface texture
    381     // back to the scratch texture pool even though the texture is used
    382     // by and active SkImage_Gpu.
    383     SkCanvas* canvas1 = surface1->getCanvas();
    384     SkCanvas* canvas2 = surface2->getCanvas();
    385     canvas1->clear(1);
    386     sk_sp<SkImage> image1(surface1->makeImageSnapshot());
    387     // Trigger copy on write, new backing is a scratch texture
    388     canvas1->clear(2);
    389     sk_sp<SkImage> image2(surface1->makeImageSnapshot());
    390     // Trigger copy on write, old backing should not be returned to scratch
    391     // pool because it is held by image2
    392     canvas1->clear(3);
    393 
    394     canvas2->clear(4);
    395     sk_sp<SkImage> image3(surface2->makeImageSnapshot());
    396     // Trigger copy on write on surface2. The new backing store should not
    397     // be recycling a texture that is held by an existing image.
    398     canvas2->clear(5);
    399     sk_sp<SkImage> image4(surface2->makeImageSnapshot());
    400     REPORTER_ASSERT(reporter, as_IB(image4)->getTexture() != as_IB(image3)->getTexture());
    401     // The following assertion checks crbug.com/263329
    402     REPORTER_ASSERT(reporter, as_IB(image4)->getTexture() != as_IB(image2)->getTexture());
    403     REPORTER_ASSERT(reporter, as_IB(image4)->getTexture() != as_IB(image1)->getTexture());
    404     REPORTER_ASSERT(reporter, as_IB(image3)->getTexture() != as_IB(image2)->getTexture());
    405     REPORTER_ASSERT(reporter, as_IB(image3)->getTexture() != as_IB(image1)->getTexture());
    406     REPORTER_ASSERT(reporter, as_IB(image2)->getTexture() != as_IB(image1)->getTexture());
    407 }
    408 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceCRBug263329_Gpu, reporter, ctxInfo) {
    409     for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) {
    410         auto surface1(surface_func(ctxInfo.grContext(), kPremul_SkAlphaType, nullptr));
    411         auto surface2(surface_func(ctxInfo.grContext(), kPremul_SkAlphaType, nullptr));
    412         test_crbug263329(reporter, surface1.get(), surface2.get());
    413     }
    414 }
    415 #endif
    416 
    417 DEF_TEST(SurfaceGetTexture, reporter) {
    418     auto surface(create_surface());
    419     sk_sp<SkImage> image(surface->makeImageSnapshot());
    420     REPORTER_ASSERT(reporter, !as_IB(image)->isTextureBacked());
    421     surface->notifyContentWillChange(SkSurface::kDiscard_ContentChangeMode);
    422     REPORTER_ASSERT(reporter, !as_IB(image)->isTextureBacked());
    423 }
    424 #if SK_SUPPORT_GPU
    425 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfacepeekTexture_Gpu, reporter, ctxInfo) {
    426     for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) {
    427         auto surface(surface_func(ctxInfo.grContext(), kPremul_SkAlphaType, nullptr));
    428         sk_sp<SkImage> image(surface->makeImageSnapshot());
    429 
    430         REPORTER_ASSERT(reporter, as_IB(image)->isTextureBacked());
    431         GrBackendObject textureHandle = image->getTextureHandle(false);
    432         REPORTER_ASSERT(reporter, 0 != textureHandle);
    433         surface->notifyContentWillChange(SkSurface::kDiscard_ContentChangeMode);
    434         REPORTER_ASSERT(reporter, as_IB(image)->isTextureBacked());
    435         REPORTER_ASSERT(reporter, textureHandle == image->getTextureHandle(false));
    436     }
    437 }
    438 #endif
    439 
    440 #if SK_SUPPORT_GPU
    441 #include "GrGpuResourcePriv.h"
    442 #include "SkGpuDevice.h"
    443 #include "SkImage_Gpu.h"
    444 #include "SkSurface_Gpu.h"
    445 
    446 static SkBudgeted is_budgeted(const sk_sp<SkSurface>& surf) {
    447     SkSurface_Gpu* gsurf = (SkSurface_Gpu*)surf.get();
    448 
    449     GrRenderTargetProxy* proxy = gsurf->getDevice()->accessRenderTargetContext()
    450                                                                         ->asRenderTargetProxy();
    451     return proxy->isBudgeted();
    452 }
    453 
    454 static SkBudgeted is_budgeted(SkImage* image) {
    455     return ((SkImage_Gpu*)image)->peekProxy()->isBudgeted();
    456 }
    457 
    458 static SkBudgeted is_budgeted(const sk_sp<SkImage> image) {
    459     return is_budgeted(image.get());
    460 }
    461 
    462 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceBudget, reporter, ctxInfo) {
    463     SkImageInfo info = SkImageInfo::MakeN32Premul(8,8);
    464     for (auto budgeted : { SkBudgeted::kNo, SkBudgeted::kYes }) {
    465         auto surface(SkSurface::MakeRenderTarget(ctxInfo.grContext(), budgeted, info));
    466         SkASSERT(surface);
    467         REPORTER_ASSERT(reporter, budgeted == is_budgeted(surface));
    468 
    469         sk_sp<SkImage> image(surface->makeImageSnapshot());
    470 
    471         // Initially the image shares a texture with the surface, and the
    472         // the budgets should always match.
    473         REPORTER_ASSERT(reporter, budgeted == is_budgeted(surface));
    474         REPORTER_ASSERT(reporter, budgeted == is_budgeted(image));
    475 
    476         // Now trigger copy-on-write
    477         surface->getCanvas()->clear(SK_ColorBLUE);
    478 
    479         // They don't share a texture anymore but the budgets should still match.
    480         REPORTER_ASSERT(reporter, budgeted == is_budgeted(surface));
    481         REPORTER_ASSERT(reporter, budgeted == is_budgeted(image));
    482     }
    483 }
    484 #endif
    485 
    486 static void test_no_canvas1(skiatest::Reporter* reporter,
    487                             SkSurface* surface,
    488                             SkSurface::ContentChangeMode mode) {
    489     // Test passes by not asserting
    490     surface->notifyContentWillChange(mode);
    491     SkDEBUGCODE(surface->validate();)
    492 }
    493 static void test_no_canvas2(skiatest::Reporter* reporter,
    494                             SkSurface* surface,
    495                             SkSurface::ContentChangeMode mode) {
    496     // Verifies the robustness of SkSurface for handling use cases where calls
    497     // are made before a canvas is created.
    498     sk_sp<SkImage> image1 = surface->makeImageSnapshot();
    499     sk_sp<SkImage> aur_image1(image1);
    500     SkDEBUGCODE(image1->validate();)
    501     SkDEBUGCODE(surface->validate();)
    502     surface->notifyContentWillChange(mode);
    503     SkDEBUGCODE(image1->validate();)
    504     SkDEBUGCODE(surface->validate();)
    505     sk_sp<SkImage> image2 = surface->makeImageSnapshot();
    506     sk_sp<SkImage> aur_image2(image2);
    507     SkDEBUGCODE(image2->validate();)
    508     SkDEBUGCODE(surface->validate();)
    509     REPORTER_ASSERT(reporter, image1 != image2);
    510 }
    511 DEF_TEST(SurfaceNoCanvas, reporter) {
    512     SkSurface::ContentChangeMode modes[] =
    513             { SkSurface::kDiscard_ContentChangeMode, SkSurface::kRetain_ContentChangeMode};
    514     for (auto& test_func : { &test_no_canvas1, &test_no_canvas2 }) {
    515         for (auto& mode : modes) {
    516             test_func(reporter, create_surface().get(), mode);
    517         }
    518     }
    519 }
    520 #if SK_SUPPORT_GPU
    521 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceNoCanvas_Gpu, reporter, ctxInfo) {
    522     SkSurface::ContentChangeMode modes[] =
    523             { SkSurface::kDiscard_ContentChangeMode, SkSurface::kRetain_ContentChangeMode};
    524     for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) {
    525         for (auto& test_func : { &test_no_canvas1, &test_no_canvas2 }) {
    526             for (auto& mode : modes) {
    527                 auto surface(surface_func(ctxInfo.grContext(), kPremul_SkAlphaType, nullptr));
    528                 test_func(reporter, surface.get(), mode);
    529             }
    530         }
    531     }
    532 }
    533 #endif
    534 
    535 static void check_rowbytes_remain_consistent(SkSurface* surface, skiatest::Reporter* reporter) {
    536     SkPixmap surfacePM;
    537     REPORTER_ASSERT(reporter, surface->peekPixels(&surfacePM));
    538 
    539     sk_sp<SkImage> image(surface->makeImageSnapshot());
    540     SkPixmap pm;
    541     REPORTER_ASSERT(reporter, image->peekPixels(&pm));
    542 
    543     REPORTER_ASSERT(reporter, surfacePM.rowBytes() == pm.rowBytes());
    544 
    545     // trigger a copy-on-write
    546     surface->getCanvas()->drawPaint(SkPaint());
    547     sk_sp<SkImage> image2(surface->makeImageSnapshot());
    548     REPORTER_ASSERT(reporter, image->uniqueID() != image2->uniqueID());
    549 
    550     SkPixmap pm2;
    551     REPORTER_ASSERT(reporter, image2->peekPixels(&pm2));
    552     REPORTER_ASSERT(reporter, pm2.rowBytes() == pm.rowBytes());
    553 }
    554 
    555 DEF_TEST(surface_rowbytes, reporter) {
    556     const SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100);
    557 
    558     auto surf0(SkSurface::MakeRaster(info));
    559     check_rowbytes_remain_consistent(surf0.get(), reporter);
    560 
    561     // specify a larger rowbytes
    562     auto surf1(SkSurface::MakeRaster(info, 500, nullptr));
    563     check_rowbytes_remain_consistent(surf1.get(), reporter);
    564 
    565     // Try some illegal rowByte values
    566     auto s = SkSurface::MakeRaster(info, 396, nullptr);    // needs to be at least 400
    567     REPORTER_ASSERT(reporter, nullptr == s);
    568     s = SkSurface::MakeRaster(info, 1 << 30, nullptr); // allocation to large
    569     REPORTER_ASSERT(reporter, nullptr == s);
    570 }
    571 
    572 DEF_TEST(surface_raster_zeroinitialized, reporter) {
    573     sk_sp<SkSurface> s(SkSurface::MakeRasterN32Premul(100, 100));
    574     SkPixmap pixmap;
    575     REPORTER_ASSERT(reporter, s->peekPixels(&pixmap));
    576 
    577     for (int i = 0; i < pixmap.info().width(); ++i) {
    578         for (int j = 0; j < pixmap.info().height(); ++j) {
    579             REPORTER_ASSERT(reporter, *pixmap.addr32(i, j) == 0);
    580         }
    581     }
    582 }
    583 
    584 #if SK_SUPPORT_GPU
    585 static sk_sp<SkSurface> create_gpu_surface_backend_texture(
    586     GrContext* context, int sampleCnt, uint32_t color, GrBackendObject* outTexture) {
    587     const int kWidth = 10;
    588     const int kHeight = 10;
    589     std::unique_ptr<uint32_t[]> pixels(new uint32_t[kWidth * kHeight]);
    590     sk_memset32(pixels.get(), color, kWidth * kHeight);
    591 
    592     GrBackendObject backendHandle = context->getGpu()->createTestingOnlyBackendTexture(
    593         pixels.get(), kWidth, kHeight, kRGBA_8888_GrPixelConfig, true);
    594 
    595     GrBackendTexture backendTex = GrTest::CreateBackendTexture(context->contextPriv().getBackend(),
    596                                                                kWidth,
    597                                                                kHeight,
    598                                                                kRGBA_8888_GrPixelConfig,
    599                                                                backendHandle);
    600 
    601     sk_sp<SkSurface> surface = SkSurface::MakeFromBackendTexture(context, backendTex,
    602                                                                  kDefault_GrSurfaceOrigin, sampleCnt,
    603                                                                  nullptr, nullptr);
    604     if (!surface) {
    605         context->getGpu()->deleteTestingOnlyBackendTexture(backendHandle);
    606         return nullptr;
    607     }
    608     *outTexture = backendHandle;
    609     return surface;
    610 }
    611 
    612 static sk_sp<SkSurface> create_gpu_surface_backend_texture_as_render_target(
    613     GrContext* context, int sampleCnt, uint32_t color, GrBackendObject* outTexture) {
    614     const int kWidth = 10;
    615     const int kHeight = 10;
    616     std::unique_ptr<uint32_t[]> pixels(new uint32_t[kWidth * kHeight]);
    617     sk_memset32(pixels.get(), color, kWidth * kHeight);
    618 
    619     GrBackendObject backendHandle = context->getGpu()->createTestingOnlyBackendTexture(
    620         pixels.get(), kWidth, kHeight, kRGBA_8888_GrPixelConfig, true);
    621 
    622     GrBackendTexture backendTex = GrTest::CreateBackendTexture(context->contextPriv().getBackend(),
    623                                                                kWidth,
    624                                                                kHeight,
    625                                                                kRGBA_8888_GrPixelConfig,
    626                                                                backendHandle);
    627     sk_sp<SkSurface> surface = SkSurface::MakeFromBackendTextureAsRenderTarget(
    628             context, backendTex, kDefault_GrSurfaceOrigin, sampleCnt, nullptr, nullptr);
    629 
    630     if (!surface) {
    631         context->getGpu()->deleteTestingOnlyBackendTexture(backendHandle);
    632         return nullptr;
    633     }
    634     *outTexture = backendHandle;
    635     return surface;
    636 }
    637 
    638 static void test_surface_clear(skiatest::Reporter* reporter, sk_sp<SkSurface> surface,
    639                                std::function<sk_sp<GrSurfaceContext>(SkSurface*)> grSurfaceGetter,
    640                                uint32_t expectedValue) {
    641     if (!surface) {
    642         ERRORF(reporter, "Could not create GPU SkSurface.");
    643         return;
    644     }
    645     int w = surface->width();
    646     int h = surface->height();
    647     std::unique_ptr<uint32_t[]> pixels(new uint32_t[w * h]);
    648     sk_memset32(pixels.get(), ~expectedValue, w * h);
    649 
    650     sk_sp<GrSurfaceContext> grSurfaceContext(grSurfaceGetter(surface.get()));
    651     if (!grSurfaceContext) {
    652         ERRORF(reporter, "Could access render target of GPU SkSurface.");
    653         return;
    654     }
    655     surface.reset();
    656 
    657     SkImageInfo ii = SkImageInfo::Make(w, h, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
    658     grSurfaceContext->readPixels(ii, pixels.get(), 0, 0, 0);
    659     for (int y = 0; y < h; ++y) {
    660         for (int x = 0; x < w; ++x) {
    661             uint32_t pixel = pixels.get()[y * w + x];
    662             if (pixel != expectedValue) {
    663                 SkString msg;
    664                 if (expectedValue) {
    665                     msg = "SkSurface should have left render target unmodified";
    666                 } else {
    667                     msg = "SkSurface should have cleared the render target";
    668                 }
    669                 ERRORF(reporter,
    670                        "%s but read 0x%08x (instead of 0x%08x) at %x,%d", msg.c_str(), pixel,
    671                        expectedValue, x, y);
    672                 return;
    673             }
    674         }
    675     }
    676 }
    677 
    678 DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SurfaceClear_Gpu, reporter, ctxInfo) {
    679     GrContext* context = ctxInfo.grContext();
    680 
    681     std::function<sk_sp<GrSurfaceContext>(SkSurface*)> grSurfaceContextGetters[] = {
    682         [] (SkSurface* s){
    683             return sk_ref_sp(s->getCanvas()->internal_private_accessTopLayerRenderTargetContext());
    684         },
    685         [] (SkSurface* s){
    686             sk_sp<SkImage> i(s->makeImageSnapshot());
    687             SkImage_Gpu* gpuImage = (SkImage_Gpu *) as_IB(i);
    688             sk_sp<GrTextureProxy> proxy = gpuImage->asTextureProxyRef();
    689             GrContext* context = gpuImage->context();
    690             return context->contextPriv().makeWrappedSurfaceContext(std::move(proxy),
    691                                                                     gpuImage->refColorSpace());
    692         }
    693     };
    694 
    695     for (auto grSurfaceGetter : grSurfaceContextGetters) {
    696         // Test that non-wrapped RTs are created clear.
    697         for (auto& surface_func : {&create_gpu_surface, &create_gpu_scratch_surface}) {
    698             auto surface = surface_func(context, kPremul_SkAlphaType, nullptr);
    699             test_surface_clear(reporter, surface, grSurfaceGetter, 0x0);
    700         }
    701         // Wrapped RTs are *not* supposed to clear (to allow client to partially update a surface).
    702         const uint32_t kOrigColor = 0xABABABAB;
    703         for (auto& surfaceFunc : {&create_gpu_surface_backend_texture,
    704                                   &create_gpu_surface_backend_texture_as_render_target}) {
    705             GrBackendObject textureObject;
    706             auto surface = surfaceFunc(context, 0, kOrigColor, &textureObject);
    707             test_surface_clear(reporter, surface, grSurfaceGetter, kOrigColor);
    708             surface.reset();
    709             context->getGpu()->deleteTestingOnlyBackendTexture(textureObject);
    710         }
    711     }
    712 }
    713 
    714 static void test_surface_draw_partially(
    715     skiatest::Reporter* reporter, sk_sp<SkSurface> surface, uint32_t origColor) {
    716     const int kW = surface->width();
    717     const int kH = surface->height();
    718     SkPaint paint;
    719     const SkColor kRectColor = ~origColor | 0xFF000000;
    720     paint.setColor(kRectColor);
    721     surface->getCanvas()->drawRect(SkRect::MakeWH(SkIntToScalar(kW), SkIntToScalar(kH)/2),
    722                                    paint);
    723     std::unique_ptr<uint32_t[]> pixels(new uint32_t[kW * kH]);
    724     sk_memset32(pixels.get(), ~origColor, kW * kH);
    725     // Read back RGBA to avoid format conversions that may not be supported on all platforms.
    726     SkImageInfo readInfo = SkImageInfo::Make(kW, kH, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
    727     SkAssertResult(surface->readPixels(readInfo, pixels.get(), kW * sizeof(uint32_t), 0, 0));
    728     bool stop = false;
    729     SkPMColor origColorPM = SkPackARGB_as_RGBA((origColor >> 24 & 0xFF),
    730                                                (origColor >>  0 & 0xFF),
    731                                                (origColor >>  8 & 0xFF),
    732                                                (origColor >> 16 & 0xFF));
    733     SkPMColor rectColorPM = SkPackARGB_as_RGBA((kRectColor >> 24 & 0xFF),
    734                                                (kRectColor >> 16 & 0xFF),
    735                                                (kRectColor >>  8 & 0xFF),
    736                                                (kRectColor >>  0 & 0xFF));
    737     for (int y = 0; y < kH/2 && !stop; ++y) {
    738        for (int x = 0; x < kW && !stop; ++x) {
    739             REPORTER_ASSERT(reporter, rectColorPM == pixels[x + y * kW]);
    740             if (rectColorPM != pixels[x + y * kW]) {
    741                 stop = true;
    742             }
    743         }
    744     }
    745     stop = false;
    746     for (int y = kH/2; y < kH && !stop; ++y) {
    747         for (int x = 0; x < kW && !stop; ++x) {
    748             REPORTER_ASSERT(reporter, origColorPM == pixels[x + y * kW]);
    749             if (origColorPM != pixels[x + y * kW]) {
    750                 stop = true;
    751             }
    752         }
    753     }
    754 }
    755 
    756 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfacePartialDraw_Gpu, reporter, ctxInfo) {
    757     GrGpu* gpu = ctxInfo.grContext()->getGpu();
    758     if (!gpu) {
    759         return;
    760     }
    761     static const uint32_t kOrigColor = 0xFFAABBCC;
    762 
    763     for (auto& surfaceFunc : {&create_gpu_surface_backend_texture,
    764                               &create_gpu_surface_backend_texture_as_render_target}) {
    765         // Validate that we can draw to the canvas and that the original texture color is
    766         // preserved in pixels that aren't rendered to via the surface.
    767         // This works only for non-multisampled case.
    768         GrBackendObject textureObject;
    769         auto surface = surfaceFunc(ctxInfo.grContext(), 0, kOrigColor, &textureObject);
    770         if (surface) {
    771             test_surface_draw_partially(reporter, surface, kOrigColor);
    772             surface.reset();
    773             gpu->deleteTestingOnlyBackendTexture(textureObject);
    774         }
    775     }
    776 }
    777 
    778 
    779 DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SurfaceAttachStencil_Gpu, reporter, ctxInfo) {
    780     GrGpu* gpu = ctxInfo.grContext()->getGpu();
    781     if (!gpu) {
    782         return;
    783     }
    784     if (gpu->caps()->avoidStencilBuffers()) {
    785         return;
    786     }
    787     static const uint32_t kOrigColor = 0xFFAABBCC;
    788 
    789     for (auto& surfaceFunc : {&create_gpu_surface_backend_texture,
    790                               &create_gpu_surface_backend_texture_as_render_target}) {
    791         for (int sampleCnt : {0, 4, 8}) {
    792             GrBackendObject textureObject;
    793             auto surface = surfaceFunc(ctxInfo.grContext(), sampleCnt, kOrigColor, &textureObject);
    794 
    795             if (!surface && sampleCnt > 0) {
    796               // Certain platforms don't support MSAA, skip these.
    797               continue;
    798             }
    799 
    800             // Validate that we can attach a stencil buffer to an SkSurface created by either of
    801             // our surface functions.
    802             GrRenderTarget* rt = surface->getCanvas()
    803                 ->internal_private_accessTopLayerRenderTargetContext()->accessRenderTarget();
    804             REPORTER_ASSERT(reporter,
    805                             ctxInfo.grContext()->resourceProvider()->attachStencilAttachment(rt));
    806             gpu->deleteTestingOnlyBackendTexture(textureObject);
    807         }
    808     }
    809 }
    810 #endif
    811 
    812 static void test_surface_creation_and_snapshot_with_color_space(
    813     skiatest::Reporter* reporter,
    814     const char* prefix,
    815     bool f16Support,
    816     std::function<sk_sp<SkSurface>(const SkImageInfo&)> surfaceMaker) {
    817 
    818     auto srgbColorSpace = SkColorSpace::MakeSRGB();
    819     auto adobeColorSpace = SkColorSpace_Base::MakeNamed(SkColorSpace_Base::kAdobeRGB_Named);
    820     const SkMatrix44* srgbMatrix = as_CSB(srgbColorSpace)->toXYZD50();
    821     SkASSERT(srgbMatrix);
    822     SkColorSpaceTransferFn oddGamma;
    823     oddGamma.fA = 1.0f;
    824     oddGamma.fB = oddGamma.fC = oddGamma.fD = oddGamma.fE = oddGamma.fF = 0.0f;
    825     oddGamma.fG = 4.0f;
    826     auto oddColorSpace = SkColorSpace::MakeRGB(oddGamma, *srgbMatrix);
    827     auto linearColorSpace = SkColorSpace::MakeSRGBLinear();
    828 
    829     const struct {
    830         SkColorType         fColorType;
    831         sk_sp<SkColorSpace> fColorSpace;
    832         bool                fShouldWork;
    833         const char*         fDescription;
    834     } testConfigs[] = {
    835         { kN32_SkColorType,       nullptr,          true,  "N32-nullptr" },
    836         { kN32_SkColorType,       linearColorSpace, false, "N32-linear"  },
    837         { kN32_SkColorType,       srgbColorSpace,   true,  "N32-srgb"    },
    838         { kN32_SkColorType,       adobeColorSpace,  true,  "N32-adobe"   },
    839         { kN32_SkColorType,       oddColorSpace,    false, "N32-odd"     },
    840         { kRGBA_F16_SkColorType,  nullptr,          false, "F16-nullptr" },
    841         { kRGBA_F16_SkColorType,  linearColorSpace, true,  "F16-linear"  },
    842         { kRGBA_F16_SkColorType,  srgbColorSpace,   false, "F16-srgb"    },
    843         { kRGBA_F16_SkColorType,  adobeColorSpace,  false, "F16-adobe"   },
    844         { kRGBA_F16_SkColorType,  oddColorSpace,    false, "F16-odd"     },
    845         { kRGB_565_SkColorType,   srgbColorSpace,   false, "565-srgb"    },
    846         { kAlpha_8_SkColorType,   srgbColorSpace,   false, "A8-srgb"     },
    847     };
    848 
    849     for (auto& testConfig : testConfigs) {
    850         SkString fullTestName = SkStringPrintf("%s-%s", prefix, testConfig.fDescription);
    851         SkImageInfo info = SkImageInfo::Make(10, 10, testConfig.fColorType, kPremul_SkAlphaType,
    852                                              testConfig.fColorSpace);
    853 
    854         // For some GPU contexts (eg ANGLE), we don't have f16 support, so we should fail to create
    855         // any surface of that type:
    856         bool shouldWork = testConfig.fShouldWork &&
    857                           (f16Support || kRGBA_F16_SkColorType != testConfig.fColorType);
    858 
    859         auto surface(surfaceMaker(info));
    860         REPORTER_ASSERT_MESSAGE(reporter, SkToBool(surface) == shouldWork, fullTestName.c_str());
    861 
    862         if (shouldWork && surface) {
    863             sk_sp<SkImage> image(surface->makeImageSnapshot());
    864             REPORTER_ASSERT_MESSAGE(reporter, image, testConfig.fDescription);
    865             SkColorSpace* imageColorSpace = as_IB(image)->onImageInfo().colorSpace();
    866             REPORTER_ASSERT_MESSAGE(reporter, imageColorSpace == testConfig.fColorSpace.get(),
    867                                     fullTestName.c_str());
    868         }
    869     }
    870 }
    871 
    872 DEF_TEST(SurfaceCreationWithColorSpace, reporter) {
    873     auto surfaceMaker = [](const SkImageInfo& info) {
    874         return SkSurface::MakeRaster(info);
    875     };
    876 
    877     test_surface_creation_and_snapshot_with_color_space(reporter, "raster", true, surfaceMaker);
    878 }
    879 
    880 #if SK_SUPPORT_GPU
    881 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceCreationWithColorSpace_Gpu, reporter, ctxInfo) {
    882     GrContext* context = ctxInfo.grContext();
    883     bool f16Support = context->caps()->isConfigRenderable(kRGBA_half_GrPixelConfig, false);
    884     auto surfaceMaker = [context](const SkImageInfo& info) {
    885         return SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info);
    886     };
    887 
    888     test_surface_creation_and_snapshot_with_color_space(reporter, "gpu", f16Support, surfaceMaker);
    889 
    890     std::vector<GrBackendObject> textureHandles;
    891     auto wrappedSurfaceMaker = [context,&textureHandles](const SkImageInfo& info) {
    892         static const int kSize = 10;
    893         GrPixelConfig config = SkImageInfo2GrPixelConfig(info, *context->caps());
    894 
    895         GrBackendObject backendHandle = context->getGpu()->createTestingOnlyBackendTexture(
    896                 nullptr, kSize, kSize, config, true);
    897 
    898         if (!backendHandle) {
    899             return sk_sp<SkSurface>(nullptr);
    900         }
    901         textureHandles.push_back(backendHandle);
    902 
    903         GrBackendTexture backendTex = GrTest::CreateBackendTexture(context->contextPriv().getBackend(),
    904                                                                    kSize,
    905                                                                    kSize,
    906                                                                    config,
    907                                                                    backendHandle);
    908 
    909         return SkSurface::MakeFromBackendTexture(context, backendTex,
    910                                                  kDefault_GrSurfaceOrigin, 0,
    911                                                  sk_ref_sp(info.colorSpace()), nullptr);
    912     };
    913 
    914     test_surface_creation_and_snapshot_with_color_space(reporter, "wrapped", f16Support,
    915                                                         wrappedSurfaceMaker);
    916 
    917     context->flush();
    918 
    919     for (auto textureHandle : textureHandles) {
    920         context->getGpu()->deleteTestingOnlyBackendTexture(textureHandle);
    921     }
    922 }
    923 #endif
    924 
    925 static void test_overdraw_surface(skiatest::Reporter* r, SkSurface* surface) {
    926     SkOverdrawCanvas canvas(surface->getCanvas());
    927     canvas.drawPaint(SkPaint());
    928     sk_sp<SkImage> image = surface->makeImageSnapshot();
    929 
    930     SkBitmap bitmap;
    931     image->asLegacyBitmap(&bitmap, SkImage::kRO_LegacyBitmapMode);
    932     for (int y = 0; y < 10; y++) {
    933         for (int x = 0; x < 10; x++) {
    934             REPORTER_ASSERT(r, 1 == SkGetPackedA32(*bitmap.getAddr32(x, y)));
    935         }
    936     }
    937 }
    938 
    939 DEF_TEST(OverdrawSurface_Raster, r) {
    940     sk_sp<SkSurface> surface = create_surface();
    941     test_overdraw_surface(r, surface.get());
    942 }
    943 
    944 #if SK_SUPPORT_GPU
    945 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(OverdrawSurface_Gpu, r, ctxInfo) {
    946     GrContext* context = ctxInfo.grContext();
    947     sk_sp<SkSurface> surface = create_gpu_surface(context);
    948     test_overdraw_surface(r, surface.get());
    949 }
    950 #endif
    951 
    952 DEF_TEST(Surface_null, r) {
    953     REPORTER_ASSERT(r, SkSurface::MakeNull(0, 0) == nullptr);
    954 
    955     const int w = 37;
    956     const int h = 1000;
    957     auto surf = SkSurface::MakeNull(w, h);
    958     auto canvas = surf->getCanvas();
    959 
    960     canvas->drawPaint(SkPaint());   // should not crash, but don't expect anything to draw
    961     REPORTER_ASSERT(r, surf->makeImageSnapshot() == nullptr);
    962 }
    963