SurfaceTest.cpp revision 5965c8ae4ee960275da4bc40189bdba85aab8b5e
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 "SkCanvas.h"
9#include "SkData.h"
10#include "SkImageEncoder.h"
11#include "SkRRect.h"
12#include "SkSurface.h"
13#include "SkUtils.h"
14#include "Test.h"
15
16#if SK_SUPPORT_GPU
17#include "GrContextFactory.h"
18#else
19class GrContextFactory;
20class GrContext;
21#endif
22
23enum SurfaceType {
24    kRaster_SurfaceType,
25    kRasterDirect_SurfaceType,
26    kGpu_SurfaceType,
27    kGpuScratch_SurfaceType,
28};
29
30static void release_storage(void* pixels, void* context) {
31    SkASSERT(pixels == context);
32    sk_free(pixels);
33}
34
35static SkSurface* createSurface(SurfaceType surfaceType, GrContext* context,
36                                SkImageInfo* requestedInfo = NULL) {
37    static const SkImageInfo info = SkImageInfo::MakeN32Premul(10, 10);
38
39    if (requestedInfo) {
40        *requestedInfo = info;
41    }
42
43    switch (surfaceType) {
44        case kRaster_SurfaceType:
45            return SkSurface::NewRaster(info);
46        case kRasterDirect_SurfaceType: {
47            const size_t rowBytes = info.minRowBytes();
48            void* storage = sk_malloc_throw(info.getSafeSize(rowBytes));
49            return SkSurface::NewRasterDirectReleaseProc(info, storage, rowBytes,
50                                                         release_storage, storage);
51        }
52        case kGpu_SurfaceType:
53#if SK_SUPPORT_GPU
54            return context ? SkSurface::NewRenderTarget(context, info, 0, NULL) : NULL;
55#endif
56            break;
57        case kGpuScratch_SurfaceType:
58#if SK_SUPPORT_GPU
59            return context ? SkSurface::NewScratchRenderTarget(context, info) : NULL;
60#endif
61            break;
62    }
63    return NULL;
64}
65
66enum ImageType {
67    kRasterCopy_ImageType,
68    kRasterData_ImageType,
69    kGpu_ImageType,
70    kCodec_ImageType,
71};
72
73#include "SkImageGenerator.h"
74
75class EmptyGenerator : public SkImageGenerator {
76protected:
77    bool onGetInfo(SkImageInfo* info) SK_OVERRIDE {
78        *info = SkImageInfo::Make(0, 0, kN32_SkColorType, kPremul_SkAlphaType);
79        return true;
80    }
81};
82
83static void test_empty_image(skiatest::Reporter* reporter) {
84    const SkImageInfo info = SkImageInfo::Make(0, 0, kN32_SkColorType, kPremul_SkAlphaType);
85
86    REPORTER_ASSERT(reporter, NULL == SkImage::NewRasterCopy(info, NULL, 0));
87    REPORTER_ASSERT(reporter, NULL == SkImage::NewRasterData(info, NULL, 0));
88    REPORTER_ASSERT(reporter, NULL == SkImage::NewFromGenerator(SkNEW(EmptyGenerator)));
89}
90
91static void test_empty_surface(skiatest::Reporter* reporter, GrContext* ctx) {
92    const SkImageInfo info = SkImageInfo::Make(0, 0, kN32_SkColorType, kPremul_SkAlphaType);
93
94    REPORTER_ASSERT(reporter, NULL == SkSurface::NewRaster(info));
95    REPORTER_ASSERT(reporter, NULL == SkSurface::NewRasterDirect(info, NULL, 0));
96    if (ctx) {
97        REPORTER_ASSERT(reporter, NULL == SkSurface::NewRenderTarget(ctx, info, 0, NULL));
98        REPORTER_ASSERT(reporter, NULL == SkSurface::NewScratchRenderTarget(ctx, info, 0, NULL));
99    }
100}
101
102static void test_image(skiatest::Reporter* reporter) {
103    SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1);
104    size_t rowBytes = info.minRowBytes();
105    size_t size = info.getSafeSize(rowBytes);
106    SkData* data = SkData::NewUninitialized(size);
107
108    REPORTER_ASSERT(reporter, data->unique());
109    SkImage* image = SkImage::NewRasterData(info, data, rowBytes);
110    REPORTER_ASSERT(reporter, !data->unique());
111    image->unref();
112    REPORTER_ASSERT(reporter, data->unique());
113    data->unref();
114}
115
116static SkImage* createImage(ImageType imageType, GrContext* context, SkColor color) {
117    const SkPMColor pmcolor = SkPreMultiplyColor(color);
118    const SkImageInfo info = SkImageInfo::MakeN32Premul(10, 10);
119    const size_t rowBytes = info.minRowBytes();
120    const size_t size = rowBytes * info.height();
121
122    SkAutoTUnref<SkData> data(SkData::NewUninitialized(size));
123    void* addr = data->writable_data();
124    sk_memset32((SkPMColor*)addr, pmcolor, SkToInt(size >> 2));
125
126    switch (imageType) {
127        case kRasterCopy_ImageType:
128            return SkImage::NewRasterCopy(info, addr, rowBytes);
129        case kRasterData_ImageType:
130            return SkImage::NewRasterData(info, data, rowBytes);
131        case kGpu_ImageType: {
132            SkAutoTUnref<SkSurface> surf(SkSurface::NewRenderTarget(context, info, 0));
133            surf->getCanvas()->clear(color);
134            return surf->newImageSnapshot();
135        }
136        case kCodec_ImageType: {
137            SkBitmap bitmap;
138            bitmap.installPixels(info, addr, rowBytes);
139            SkAutoTUnref<SkData> src(
140                 SkImageEncoder::EncodeData(bitmap, SkImageEncoder::kPNG_Type, 100));
141            return SkImage::NewFromData(src);
142        }
143    }
144    SkASSERT(false);
145    return NULL;
146}
147
148static void set_pixels(SkPMColor pixels[], int count, SkPMColor color) {
149    sk_memset32(pixels, color, count);
150}
151static bool has_pixels(const SkPMColor pixels[], int count, SkPMColor expected) {
152    for (int i = 0; i < count; ++i) {
153        if (pixels[i] != expected) {
154            return false;
155        }
156    }
157    return true;
158}
159
160static void test_image_readpixels(skiatest::Reporter* reporter, SkImage* image,
161                                  SkPMColor expected) {
162    const SkPMColor notExpected = ~expected;
163
164    const int w = 2, h = 2;
165    const size_t rowBytes = w * sizeof(SkPMColor);
166    SkPMColor pixels[w*h];
167
168    SkImageInfo info;
169
170    info = SkImageInfo::MakeUnknown(w, h);
171    REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, 0, 0));
172
173    // out-of-bounds should fail
174    info = SkImageInfo::MakeN32Premul(w, h);
175    REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, -w, 0));
176    REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, 0, -h));
177    REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, image->width(), 0));
178    REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, 0, image->height()));
179
180    // top-left should succeed
181    set_pixels(pixels, w*h, notExpected);
182    REPORTER_ASSERT(reporter, image->readPixels(info, pixels, rowBytes, 0, 0));
183    REPORTER_ASSERT(reporter, has_pixels(pixels, w*h, expected));
184
185    // bottom-right should succeed
186    set_pixels(pixels, w*h, notExpected);
187    REPORTER_ASSERT(reporter, image->readPixels(info, pixels, rowBytes,
188                                                image->width() - w, image->height() - h));
189    REPORTER_ASSERT(reporter, has_pixels(pixels, w*h, expected));
190
191    // partial top-left should succeed
192    set_pixels(pixels, w*h, notExpected);
193    REPORTER_ASSERT(reporter, image->readPixels(info, pixels, rowBytes, -1, -1));
194    REPORTER_ASSERT(reporter, pixels[3] == expected);
195    REPORTER_ASSERT(reporter, has_pixels(pixels, w*h - 1, notExpected));
196
197    // partial bottom-right should succeed
198    set_pixels(pixels, w*h, notExpected);
199    REPORTER_ASSERT(reporter, image->readPixels(info, pixels, rowBytes,
200                                                image->width() - 1, image->height() - 1));
201    REPORTER_ASSERT(reporter, pixels[0] == expected);
202    REPORTER_ASSERT(reporter, has_pixels(&pixels[1], w*h - 1, notExpected));
203}
204
205static void test_imagepeek(skiatest::Reporter* reporter, GrContextFactory* factory) {
206    static const struct {
207        ImageType   fType;
208        bool        fPeekShouldSucceed;
209        const char* fName;
210    } gRec[] = {
211        { kRasterCopy_ImageType,    true,       "RasterCopy"    },
212        { kRasterData_ImageType,    true,       "RasterData"    },
213        { kGpu_ImageType,           false,      "Gpu"           },
214        { kCodec_ImageType,         false,      "Codec"         },
215    };
216
217    const SkColor color = SK_ColorRED;
218    const SkPMColor pmcolor = SkPreMultiplyColor(color);
219
220    GrContext* ctx = NULL;
221#if SK_SUPPORT_GPU
222    ctx = factory->get(GrContextFactory::kNative_GLContextType);
223#endif
224
225    for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) {
226        SkImageInfo info;
227        size_t rowBytes;
228
229        SkAutoTUnref<SkImage> image(createImage(gRec[i].fType, ctx, color));
230        if (!image.get()) {
231            SkDebugf("failed to createImage[%d] %s\n", i, gRec[i].fName);
232            continue;   // gpu may not be enabled
233        }
234        const void* addr = image->peekPixels(&info, &rowBytes);
235        bool success = SkToBool(addr);
236        REPORTER_ASSERT(reporter, gRec[i].fPeekShouldSucceed == success);
237        if (success) {
238            REPORTER_ASSERT(reporter, 10 == info.width());
239            REPORTER_ASSERT(reporter, 10 == info.height());
240            REPORTER_ASSERT(reporter, kN32_SkColorType == info.colorType());
241            REPORTER_ASSERT(reporter, kPremul_SkAlphaType == info.alphaType() ||
242                            kOpaque_SkAlphaType == info.alphaType());
243            REPORTER_ASSERT(reporter, info.minRowBytes() <= rowBytes);
244            REPORTER_ASSERT(reporter, pmcolor == *(const SkPMColor*)addr);
245        }
246
247        test_image_readpixels(reporter, image, pmcolor);
248    }
249}
250
251static void test_canvaspeek(skiatest::Reporter* reporter,
252                            GrContextFactory* factory) {
253    static const struct {
254        SurfaceType fType;
255        bool        fPeekShouldSucceed;
256    } gRec[] = {
257        { kRaster_SurfaceType,          true    },
258        { kRasterDirect_SurfaceType,    true    },
259#if SK_SUPPORT_GPU
260        { kGpu_SurfaceType,             false   },
261        { kGpuScratch_SurfaceType,      false   },
262#endif
263    };
264
265    const SkColor color = SK_ColorRED;
266    const SkPMColor pmcolor = SkPreMultiplyColor(color);
267
268    int cnt;
269#if SK_SUPPORT_GPU
270    cnt = GrContextFactory::kGLContextTypeCnt;
271#else
272    cnt = 1;
273#endif
274
275    for (int i= 0; i < cnt; ++i) {
276        GrContext* context = NULL;
277#if SK_SUPPORT_GPU
278        GrContextFactory::GLContextType glCtxType = (GrContextFactory::GLContextType) i;
279        if (!GrContextFactory::IsRenderingGLContext(glCtxType)) {
280            continue;
281        }
282        context = factory->get(glCtxType);
283
284        if (NULL == context) {
285            continue;
286        }
287#endif
288        for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) {
289            SkImageInfo info, requestInfo;
290            size_t rowBytes;
291
292            SkAutoTUnref<SkSurface> surface(createSurface(gRec[i].fType, context,
293                                                          &requestInfo));
294            surface->getCanvas()->clear(color);
295
296            const void* addr = surface->getCanvas()->peekPixels(&info, &rowBytes);
297            bool success = SkToBool(addr);
298            REPORTER_ASSERT(reporter, gRec[i].fPeekShouldSucceed == success);
299
300            SkImageInfo info2;
301            size_t rb2;
302            const void* addr2 = surface->peekPixels(&info2, &rb2);
303
304            if (success) {
305                REPORTER_ASSERT(reporter, requestInfo == info);
306                REPORTER_ASSERT(reporter, requestInfo.minRowBytes() <= rowBytes);
307                REPORTER_ASSERT(reporter, pmcolor == *(const SkPMColor*)addr);
308
309                REPORTER_ASSERT(reporter, addr2 == addr);
310                REPORTER_ASSERT(reporter, info2 == info);
311                REPORTER_ASSERT(reporter, rb2 == rowBytes);
312            } else {
313                REPORTER_ASSERT(reporter, NULL == addr2);
314            }
315        }
316    }
317}
318
319static void TestSurfaceCopyOnWrite(skiatest::Reporter* reporter, SurfaceType surfaceType,
320                                   GrContext* context) {
321    // Verify that the right canvas commands trigger a copy on write
322    SkSurface* surface = createSurface(surfaceType, context);
323    SkAutoTUnref<SkSurface> aur_surface(surface);
324    SkCanvas* canvas = surface->getCanvas();
325
326    const SkRect testRect =
327        SkRect::MakeXYWH(SkIntToScalar(0), SkIntToScalar(0),
328                         SkIntToScalar(4), SkIntToScalar(5));
329    SkPath testPath;
330    testPath.addRect(SkRect::MakeXYWH(SkIntToScalar(0), SkIntToScalar(0),
331                                      SkIntToScalar(2), SkIntToScalar(1)));
332
333    const SkIRect testIRect = SkIRect::MakeXYWH(0, 0, 2, 1);
334
335    SkRegion testRegion;
336    testRegion.setRect(testIRect);
337
338
339    const SkColor testColor = 0x01020304;
340    const SkPaint testPaint;
341    const SkPoint testPoints[3] = {
342        {SkIntToScalar(0), SkIntToScalar(0)},
343        {SkIntToScalar(2), SkIntToScalar(1)},
344        {SkIntToScalar(0), SkIntToScalar(2)}
345    };
346    const size_t testPointCount = 3;
347
348    SkBitmap testBitmap;
349    testBitmap.allocN32Pixels(10, 10);
350    testBitmap.eraseColor(0);
351
352    SkRRect testRRect;
353    testRRect.setRectXY(testRect, SK_Scalar1, SK_Scalar1);
354
355    SkString testText("Hello World");
356    const SkPoint testPoints2[] = {
357        { SkIntToScalar(0), SkIntToScalar(1) },
358        { SkIntToScalar(1), SkIntToScalar(1) },
359        { SkIntToScalar(2), SkIntToScalar(1) },
360        { SkIntToScalar(3), SkIntToScalar(1) },
361        { SkIntToScalar(4), SkIntToScalar(1) },
362        { SkIntToScalar(5), SkIntToScalar(1) },
363        { SkIntToScalar(6), SkIntToScalar(1) },
364        { SkIntToScalar(7), SkIntToScalar(1) },
365        { SkIntToScalar(8), SkIntToScalar(1) },
366        { SkIntToScalar(9), SkIntToScalar(1) },
367        { SkIntToScalar(10), SkIntToScalar(1) },
368    };
369
370#define EXPECT_COPY_ON_WRITE(command)                               \
371    {                                                               \
372        SkImage* imageBefore = surface->newImageSnapshot();         \
373        SkAutoTUnref<SkImage> aur_before(imageBefore);              \
374        canvas-> command ;                                          \
375        SkImage* imageAfter = surface->newImageSnapshot();          \
376        SkAutoTUnref<SkImage> aur_after(imageAfter);                \
377        REPORTER_ASSERT(reporter, imageBefore != imageAfter);       \
378    }
379
380    EXPECT_COPY_ON_WRITE(clear(testColor))
381    EXPECT_COPY_ON_WRITE(drawPaint(testPaint))
382    EXPECT_COPY_ON_WRITE(drawPoints(SkCanvas::kPoints_PointMode, testPointCount, testPoints, \
383        testPaint))
384    EXPECT_COPY_ON_WRITE(drawOval(testRect, testPaint))
385    EXPECT_COPY_ON_WRITE(drawRect(testRect, testPaint))
386    EXPECT_COPY_ON_WRITE(drawRRect(testRRect, testPaint))
387    EXPECT_COPY_ON_WRITE(drawPath(testPath, testPaint))
388    EXPECT_COPY_ON_WRITE(drawBitmap(testBitmap, 0, 0))
389    EXPECT_COPY_ON_WRITE(drawBitmapRect(testBitmap, NULL, testRect))
390    EXPECT_COPY_ON_WRITE(drawBitmapNine(testBitmap, testIRect, testRect, NULL))
391    EXPECT_COPY_ON_WRITE(drawSprite(testBitmap, 0, 0, NULL))
392    EXPECT_COPY_ON_WRITE(drawText(testText.c_str(), testText.size(), 0, 1, testPaint))
393    EXPECT_COPY_ON_WRITE(drawPosText(testText.c_str(), testText.size(), testPoints2, \
394        testPaint))
395    EXPECT_COPY_ON_WRITE(drawTextOnPath(testText.c_str(), testText.size(), testPath, NULL, \
396        testPaint))
397}
398
399static void TestSurfaceWritableAfterSnapshotRelease(skiatest::Reporter* reporter,
400                                                    SurfaceType surfaceType,
401                                                    GrContext* context) {
402    // This test succeeds by not triggering an assertion.
403    // The test verifies that the surface remains writable (usable) after
404    // acquiring and releasing a snapshot without triggering a copy on write.
405    SkAutoTUnref<SkSurface> surface(createSurface(surfaceType, context));
406    SkCanvas* canvas = surface->getCanvas();
407    canvas->clear(1);
408    surface->newImageSnapshot()->unref();  // Create and destroy SkImage
409    canvas->clear(2);  // Must not assert internally
410}
411
412#if SK_SUPPORT_GPU
413static void Test_crbug263329(skiatest::Reporter* reporter,
414                             SurfaceType surfaceType,
415                             GrContext* context) {
416    // This is a regression test for crbug.com/263329
417    // Bug was caused by onCopyOnWrite releasing the old surface texture
418    // back to the scratch texture pool even though the texture is used
419    // by and active SkImage_Gpu.
420    SkAutoTUnref<SkSurface> surface1(createSurface(surfaceType, context));
421    SkAutoTUnref<SkSurface> surface2(createSurface(surfaceType, context));
422    SkCanvas* canvas1 = surface1->getCanvas();
423    SkCanvas* canvas2 = surface2->getCanvas();
424    canvas1->clear(1);
425    SkAutoTUnref<SkImage> image1(surface1->newImageSnapshot());
426    // Trigger copy on write, new backing is a scratch texture
427    canvas1->clear(2);
428    SkAutoTUnref<SkImage> image2(surface1->newImageSnapshot());
429    // Trigger copy on write, old backing should not be returned to scratch
430    // pool because it is held by image2
431    canvas1->clear(3);
432
433    canvas2->clear(4);
434    SkAutoTUnref<SkImage> image3(surface2->newImageSnapshot());
435    // Trigger copy on write on surface2. The new backing store should not
436    // be recycling a texture that is held by an existing image.
437    canvas2->clear(5);
438    SkAutoTUnref<SkImage> image4(surface2->newImageSnapshot());
439    REPORTER_ASSERT(reporter, image4->getTexture() != image3->getTexture());
440    // The following assertion checks crbug.com/263329
441    REPORTER_ASSERT(reporter, image4->getTexture() != image2->getTexture());
442    REPORTER_ASSERT(reporter, image4->getTexture() != image1->getTexture());
443    REPORTER_ASSERT(reporter, image3->getTexture() != image2->getTexture());
444    REPORTER_ASSERT(reporter, image3->getTexture() != image1->getTexture());
445    REPORTER_ASSERT(reporter, image2->getTexture() != image1->getTexture());
446}
447
448static void TestGetTexture(skiatest::Reporter* reporter,
449                                 SurfaceType surfaceType,
450                                 GrContext* context) {
451    SkAutoTUnref<SkSurface> surface(createSurface(surfaceType, context));
452    SkAutoTUnref<SkImage> image(surface->newImageSnapshot());
453    GrTexture* texture = image->getTexture();
454    if (surfaceType == kGpu_SurfaceType || surfaceType == kGpuScratch_SurfaceType) {
455        REPORTER_ASSERT(reporter, texture);
456        REPORTER_ASSERT(reporter, 0 != texture->getTextureHandle());
457    } else {
458        REPORTER_ASSERT(reporter, NULL == texture);
459    }
460    surface->notifyContentWillChange(SkSurface::kDiscard_ContentChangeMode);
461    REPORTER_ASSERT(reporter, image->getTexture() == texture);
462}
463#endif
464
465static void TestSurfaceNoCanvas(skiatest::Reporter* reporter,
466                                          SurfaceType surfaceType,
467                                          GrContext* context,
468                                          SkSurface::ContentChangeMode mode) {
469    // Verifies the robustness of SkSurface for handling use cases where calls
470    // are made before a canvas is created.
471    {
472        // Test passes by not asserting
473        SkSurface* surface = createSurface(surfaceType, context);
474        SkAutoTUnref<SkSurface> aur_surface(surface);
475        surface->notifyContentWillChange(mode);
476        SkDEBUGCODE(surface->validate();)
477    }
478    {
479        SkSurface* surface = createSurface(surfaceType, context);
480        SkAutoTUnref<SkSurface> aur_surface(surface);
481        SkImage* image1 = surface->newImageSnapshot();
482        SkAutoTUnref<SkImage> aur_image1(image1);
483        SkDEBUGCODE(image1->validate();)
484        SkDEBUGCODE(surface->validate();)
485        surface->notifyContentWillChange(mode);
486        SkDEBUGCODE(image1->validate();)
487        SkDEBUGCODE(surface->validate();)
488        SkImage* image2 = surface->newImageSnapshot();
489        SkAutoTUnref<SkImage> aur_image2(image2);
490        SkDEBUGCODE(image2->validate();)
491        SkDEBUGCODE(surface->validate();)
492        REPORTER_ASSERT(reporter, image1 != image2);
493    }
494
495}
496
497DEF_GPUTEST(Surface, reporter, factory) {
498    test_image(reporter);
499
500    TestSurfaceCopyOnWrite(reporter, kRaster_SurfaceType, NULL);
501    TestSurfaceWritableAfterSnapshotRelease(reporter, kRaster_SurfaceType, NULL);
502    TestSurfaceNoCanvas(reporter, kRaster_SurfaceType, NULL, SkSurface::kDiscard_ContentChangeMode);
503    TestSurfaceNoCanvas(reporter, kRaster_SurfaceType, NULL, SkSurface::kRetain_ContentChangeMode);
504
505    test_empty_image(reporter);
506    test_empty_surface(reporter, NULL);
507
508    test_imagepeek(reporter, factory);
509    test_canvaspeek(reporter, factory);
510
511#if SK_SUPPORT_GPU
512    TestGetTexture(reporter, kRaster_SurfaceType, NULL);
513    if (factory) {
514        for (int i= 0; i < GrContextFactory::kGLContextTypeCnt; ++i) {
515            GrContextFactory::GLContextType glCtxType = (GrContextFactory::GLContextType) i;
516            if (!GrContextFactory::IsRenderingGLContext(glCtxType)) {
517                continue;
518            }
519            GrContext* context = factory->get(glCtxType);
520            if (context) {
521                Test_crbug263329(reporter, kGpu_SurfaceType, context);
522                Test_crbug263329(reporter, kGpuScratch_SurfaceType, context);
523                TestSurfaceCopyOnWrite(reporter, kGpu_SurfaceType, context);
524                TestSurfaceCopyOnWrite(reporter, kGpuScratch_SurfaceType, context);
525                TestSurfaceWritableAfterSnapshotRelease(reporter, kGpu_SurfaceType, context);
526                TestSurfaceWritableAfterSnapshotRelease(reporter, kGpuScratch_SurfaceType, context);
527                TestSurfaceNoCanvas(reporter, kGpu_SurfaceType, context, SkSurface::kDiscard_ContentChangeMode);
528                TestSurfaceNoCanvas(reporter, kGpuScratch_SurfaceType, context, SkSurface::kDiscard_ContentChangeMode);
529                TestSurfaceNoCanvas(reporter, kGpu_SurfaceType, context, SkSurface::kRetain_ContentChangeMode);
530                TestSurfaceNoCanvas(reporter, kGpuScratch_SurfaceType, context, SkSurface::kRetain_ContentChangeMode);
531                TestGetTexture(reporter, kGpu_SurfaceType, context);
532                TestGetTexture(reporter, kGpuScratch_SurfaceType, context);
533                test_empty_surface(reporter, context);
534            }
535        }
536    }
537#endif
538}
539