SurfaceTest.cpp revision 5ee449af7448c202cfc6e9a359d8f996392885b2
1 2/* 3 * Copyright 2013 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8#include "SkCanvas.h" 9#include "SkRRect.h" 10#include "SkSurface.h" 11#include "Test.h" 12 13#if SK_SUPPORT_GPU 14#include "GrContextFactory.h" 15#else 16class GrContextFactory; 17class GrContext; 18#endif 19 20enum SurfaceType { 21 kRaster_SurfaceType, 22 kGpu_SurfaceType, 23 kPicture_SurfaceType 24}; 25 26static SkSurface* createSurface(SurfaceType surfaceType, GrContext* context) { 27 static const SkImage::Info imageSpec = { 28 10, // width 29 10, // height 30 SkImage::kPMColor_ColorType, 31 SkImage::kPremul_AlphaType 32 }; 33 34 switch (surfaceType) { 35 case kRaster_SurfaceType: 36 return SkSurface::NewRaster(imageSpec); 37 case kGpu_SurfaceType: 38#if SK_SUPPORT_GPU 39 SkASSERT(NULL != context); 40 return SkSurface::NewRenderTarget(context, imageSpec); 41#else 42 SkASSERT(0); 43#endif 44 case kPicture_SurfaceType: 45 return SkSurface::NewPicture(10, 10); 46 } 47 SkASSERT(0); 48 return NULL; 49} 50 51static void TestSurfaceCopyOnWrite(skiatest::Reporter* reporter, SurfaceType surfaceType, 52 GrContext* context) { 53 // Verify that the right canvas commands trigger a copy on write 54 SkSurface* surface = createSurface(surfaceType, context); 55 SkAutoTUnref<SkSurface> aur_surface(surface); 56 SkCanvas* canvas = surface->getCanvas(); 57 58 const SkRect testRect = 59 SkRect::MakeXYWH(SkIntToScalar(0), SkIntToScalar(0), 60 SkIntToScalar(4), SkIntToScalar(5)); 61 SkMatrix testMatrix; 62 testMatrix.reset(); 63 testMatrix.setScale(SkIntToScalar(2), SkIntToScalar(3)); 64 65 SkPath testPath; 66 testPath.addRect(SkRect::MakeXYWH(SkIntToScalar(0), SkIntToScalar(0), 67 SkIntToScalar(2), SkIntToScalar(1))); 68 69 const SkIRect testIRect = SkIRect::MakeXYWH(0, 0, 2, 1); 70 71 SkRegion testRegion; 72 testRegion.setRect(testIRect); 73 74 75 const SkColor testColor = 0x01020304; 76 const SkPaint testPaint; 77 const SkPoint testPoints[3] = { 78 {SkIntToScalar(0), SkIntToScalar(0)}, 79 {SkIntToScalar(2), SkIntToScalar(1)}, 80 {SkIntToScalar(0), SkIntToScalar(2)} 81 }; 82 const size_t testPointCount = 3; 83 84 SkBitmap testBitmap; 85 testBitmap.setConfig(SkBitmap::kARGB_8888_Config, 10, 10); 86 testBitmap.allocPixels(); 87 88 SkRRect testRRect; 89 testRRect.setRectXY(testRect, SK_Scalar1, SK_Scalar1); 90 91 SkString testText("Hello World"); 92 const SkPoint testPoints2[] = { 93 { SkIntToScalar(0), SkIntToScalar(1) }, 94 { SkIntToScalar(1), SkIntToScalar(1) }, 95 { SkIntToScalar(2), SkIntToScalar(1) }, 96 { SkIntToScalar(3), SkIntToScalar(1) }, 97 { SkIntToScalar(4), SkIntToScalar(1) }, 98 { SkIntToScalar(5), SkIntToScalar(1) }, 99 { SkIntToScalar(6), SkIntToScalar(1) }, 100 { SkIntToScalar(7), SkIntToScalar(1) }, 101 { SkIntToScalar(8), SkIntToScalar(1) }, 102 { SkIntToScalar(9), SkIntToScalar(1) }, 103 { SkIntToScalar(10), SkIntToScalar(1) }, 104 }; 105 106#define EXPECT_COPY_ON_WRITE(command) \ 107 { \ 108 SkImage* imageBefore = surface->newImageSnapshot(); \ 109 SkAutoTUnref<SkImage> aur_before(imageBefore); \ 110 canvas-> command ; \ 111 SkImage* imageAfter = surface->newImageSnapshot(); \ 112 SkAutoTUnref<SkImage> aur_after(imageAfter); \ 113 REPORTER_ASSERT(reporter, imageBefore != imageAfter); \ 114 } 115 116 EXPECT_COPY_ON_WRITE(clear(testColor)) 117 EXPECT_COPY_ON_WRITE(drawPaint(testPaint)) 118 EXPECT_COPY_ON_WRITE(drawPoints(SkCanvas::kPoints_PointMode, testPointCount, testPoints, \ 119 testPaint)) 120 EXPECT_COPY_ON_WRITE(drawOval(testRect, testPaint)) 121 EXPECT_COPY_ON_WRITE(drawRect(testRect, testPaint)) 122 EXPECT_COPY_ON_WRITE(drawRRect(testRRect, testPaint)) 123 EXPECT_COPY_ON_WRITE(drawPath(testPath, testPaint)) 124 EXPECT_COPY_ON_WRITE(drawBitmap(testBitmap, 0, 0)) 125 EXPECT_COPY_ON_WRITE(drawBitmapRect(testBitmap, NULL, testRect)) 126 EXPECT_COPY_ON_WRITE(drawBitmapMatrix(testBitmap, testMatrix, NULL)) 127 EXPECT_COPY_ON_WRITE(drawBitmapNine(testBitmap, testIRect, testRect, NULL)) 128 EXPECT_COPY_ON_WRITE(drawSprite(testBitmap, 0, 0, NULL)) 129 EXPECT_COPY_ON_WRITE(drawText(testText.c_str(), testText.size(), 0, 1, testPaint)) 130 EXPECT_COPY_ON_WRITE(drawPosText(testText.c_str(), testText.size(), testPoints2, \ 131 testPaint)) 132 EXPECT_COPY_ON_WRITE(drawTextOnPath(testText.c_str(), testText.size(), testPath, NULL, \ 133 testPaint)) 134} 135 136static void TestSurfaceWritableAfterSnapshotRelease(skiatest::Reporter* reporter, 137 SurfaceType surfaceType, 138 GrContext* context) { 139 // This test succeeds by not triggering an assertion. 140 // The test verifies that the surface remains writable (usable) after 141 // acquiring and releasing a snapshot without triggering a copy on write. 142 SkSurface* surface = createSurface(surfaceType, context); 143 SkAutoTUnref<SkSurface> aur_surface(surface); 144 SkCanvas* canvas = surface->getCanvas(); 145 canvas->clear(1); 146 surface->newImageSnapshot()->unref(); // Create and destroy SkImage 147 canvas->clear(2); 148} 149 150static void TestSurface(skiatest::Reporter* reporter, GrContextFactory* factory) { 151 TestSurfaceCopyOnWrite(reporter, kRaster_SurfaceType, NULL); 152 TestSurfaceCopyOnWrite(reporter, kPicture_SurfaceType, NULL); 153 TestSurfaceWritableAfterSnapshotRelease(reporter, kRaster_SurfaceType, NULL); 154 TestSurfaceWritableAfterSnapshotRelease(reporter, kPicture_SurfaceType, NULL); 155#if SK_SUPPORT_GPU 156 if (NULL != factory) { 157 GrContext* context = factory->get(GrContextFactory::kNative_GLContextType); 158 TestSurfaceCopyOnWrite(reporter, kGpu_SurfaceType, context); 159 TestSurfaceWritableAfterSnapshotRelease(reporter, kGpu_SurfaceType, context); 160 } 161#endif 162} 163 164#include "TestClassDef.h" 165DEFINE_GPUTESTCLASS("Surface", SurfaceTestClass, TestSurface) 166