| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2012 Google Inc. | 3 * Copyright 2012 Google Inc. |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 #include "Test.h" | 8 #include "Test.h" |
| 9 #include "SkBitmap.h" | 9 #include "SkBitmap.h" |
| 10 #include "SkBitmapProcShader.h" | 10 #include "SkBitmapProcShader.h" |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 bm->setConfig(config, gWidth, gHeight); | 26 bm->setConfig(config, gWidth, gHeight); |
| 27 bm->allocPixels(); | 27 bm->allocPixels(); |
| 28 bm->eraseColor(color); | 28 bm->eraseColor(color); |
| 29 } | 29 } |
| 30 | 30 |
| 31 static void TestDeferredCanvasBitmapAccess(skiatest::Reporter* reporter) { | 31 static void TestDeferredCanvasBitmapAccess(skiatest::Reporter* reporter) { |
| 32 SkBitmap store; | 32 SkBitmap store; |
| 33 | 33 |
| 34 create(&store, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF); | 34 create(&store, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF); |
| 35 SkDevice device(store); | 35 SkDevice device(store); |
| 36 SkDeferredCanvas canvas(&device); | 36 SkAutoTUnref<SkDeferredCanvas> canvas( |
| 37 #if SK_DEFERRED_CANVAS_USES_FACTORIES |
| 38 SkDeferredCanvas::Create(&device)); |
| 39 #else |
| 40 SkNEW_ARGS(SkDeferredCanvas, (&device))); |
| 41 #endif |
| 37 | 42 |
| 38 canvas.clear(0x00000000); | 43 canvas->clear(0x00000000); |
| 39 | 44 |
| 40 SkAutoLockPixels alp(store); | 45 SkAutoLockPixels alp(store); |
| 41 REPORTER_ASSERT(reporter, store.getColor(0,0) == 0xFFFFFFFF); //verify that
clear was deferred | 46 REPORTER_ASSERT(reporter, store.getColor(0,0) == 0xFFFFFFFF); //verify that
clear was deferred |
| 42 SkBitmap accessed = canvas.getDevice()->accessBitmap(false); | 47 SkBitmap accessed = canvas->getDevice()->accessBitmap(false); |
| 43 REPORTER_ASSERT(reporter, store.getColor(0,0) == 0x00000000); //verify that
clear was executed | 48 REPORTER_ASSERT(reporter, store.getColor(0,0) == 0x00000000); //verify that
clear was executed |
| 44 REPORTER_ASSERT(reporter, accessed.pixelRef() == store.pixelRef()); | 49 REPORTER_ASSERT(reporter, accessed.pixelRef() == store.pixelRef()); |
| 45 } | 50 } |
| 46 | 51 |
| 47 static void TestDeferredCanvasFlush(skiatest::Reporter* reporter) { | 52 static void TestDeferredCanvasFlush(skiatest::Reporter* reporter) { |
| 48 SkBitmap store; | 53 SkBitmap store; |
| 49 | 54 |
| 50 create(&store, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF); | 55 create(&store, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF); |
| 51 SkDevice device(store); | 56 SkDevice device(store); |
| 52 SkDeferredCanvas canvas(&device); | 57 SkAutoTUnref<SkDeferredCanvas> canvas( |
| 58 #if SK_DEFERRED_CANVAS_USES_FACTORIES |
| 59 SkDeferredCanvas::Create(&device)); |
| 60 #else |
| 61 SkNEW_ARGS(SkDeferredCanvas, (&device))); |
| 62 #endif |
| 53 | 63 |
| 54 canvas.clear(0x00000000); | 64 canvas->clear(0x00000000); |
| 55 | 65 |
| 56 SkAutoLockPixels alp(store); | 66 SkAutoLockPixels alp(store); |
| 57 REPORTER_ASSERT(reporter, store.getColor(0,0) == 0xFFFFFFFF); //verify that
clear was deferred | 67 REPORTER_ASSERT(reporter, store.getColor(0,0) == 0xFFFFFFFF); //verify that
clear was deferred |
| 58 canvas.flush(); | 68 canvas->flush(); |
| 59 REPORTER_ASSERT(reporter, store.getColor(0,0) == 0x00000000); //verify that
clear was executed | 69 REPORTER_ASSERT(reporter, store.getColor(0,0) == 0x00000000); //verify that
clear was executed |
| 60 } | 70 } |
| 61 | 71 |
| 62 static void TestDeferredCanvasFreshFrame(skiatest::Reporter* reporter) { | 72 static void TestDeferredCanvasFreshFrame(skiatest::Reporter* reporter) { |
| 63 SkBitmap store; | 73 SkBitmap store; |
| 64 SkRect fullRect; | 74 SkRect fullRect; |
| 65 fullRect.setXYWH(SkIntToScalar(0), SkIntToScalar(0), SkIntToScalar(gWidth), | 75 fullRect.setXYWH(SkIntToScalar(0), SkIntToScalar(0), SkIntToScalar(gWidth), |
| 66 SkIntToScalar(gHeight)); | 76 SkIntToScalar(gHeight)); |
| 67 SkRect partialRect; | 77 SkRect partialRect; |
| 68 partialRect.setXYWH(SkIntToScalar(0), SkIntToScalar(0), | 78 partialRect.setXYWH(SkIntToScalar(0), SkIntToScalar(0), |
| 69 SkIntToScalar(1), SkIntToScalar(1)); | 79 SkIntToScalar(1), SkIntToScalar(1)); |
| 70 create(&store, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF); | 80 create(&store, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF); |
| 71 SkDevice device(store); | 81 SkDevice device(store); |
| 72 SkDeferredCanvas canvas(&device); | 82 SkAutoTUnref<SkDeferredCanvas> canvas( |
| 83 #if SK_DEFERRED_CANVAS_USES_FACTORIES |
| 84 SkDeferredCanvas::Create(&device)); |
| 85 #else |
| 86 SkNEW_ARGS(SkDeferredCanvas, (&device))); |
| 87 #endif |
| 73 | 88 |
| 74 // verify that frame is intially fresh | 89 // verify that frame is intially fresh |
| 75 REPORTER_ASSERT(reporter, canvas.isFreshFrame()); | 90 REPORTER_ASSERT(reporter, canvas->isFreshFrame()); |
| 76 // no clearing op since last call to isFreshFrame -> not fresh | 91 // no clearing op since last call to isFreshFrame -> not fresh |
| 77 REPORTER_ASSERT(reporter, !canvas.isFreshFrame()); | 92 REPORTER_ASSERT(reporter, !canvas->isFreshFrame()); |
| 78 | 93 |
| 79 // Verify that clear triggers a fresh frame | 94 // Verify that clear triggers a fresh frame |
| 80 canvas.clear(0x00000000); | 95 canvas->clear(0x00000000); |
| 81 REPORTER_ASSERT(reporter, canvas.isFreshFrame()); | 96 REPORTER_ASSERT(reporter, canvas->isFreshFrame()); |
| 82 | 97 |
| 83 // Verify that clear with saved state triggers a fresh frame | 98 // Verify that clear with saved state triggers a fresh frame |
| 84 canvas.save(SkCanvas::kMatrixClip_SaveFlag); | 99 canvas->save(SkCanvas::kMatrixClip_SaveFlag); |
| 85 canvas.clear(0x00000000); | 100 canvas->clear(0x00000000); |
| 86 canvas.restore(); | 101 canvas->restore(); |
| 87 REPORTER_ASSERT(reporter, canvas.isFreshFrame()); | 102 REPORTER_ASSERT(reporter, canvas->isFreshFrame()); |
| 88 | 103 |
| 89 // Verify that clear within a layer does NOT trigger a fresh frame | 104 // Verify that clear within a layer does NOT trigger a fresh frame |
| 90 canvas.saveLayer(NULL, NULL, SkCanvas::kARGB_ClipLayer_SaveFlag); | 105 canvas->saveLayer(NULL, NULL, SkCanvas::kARGB_ClipLayer_SaveFlag); |
| 91 canvas.clear(0x00000000); | 106 canvas->clear(0x00000000); |
| 92 canvas.restore(); | 107 canvas->restore(); |
| 93 REPORTER_ASSERT(reporter, !canvas.isFreshFrame()); | 108 REPORTER_ASSERT(reporter, !canvas->isFreshFrame()); |
| 94 | 109 |
| 95 // Verify that a clear with clipping triggers a fresh frame | 110 // Verify that a clear with clipping triggers a fresh frame |
| 96 // (clear is not affected by clipping) | 111 // (clear is not affected by clipping) |
| 97 canvas.save(SkCanvas::kMatrixClip_SaveFlag); | 112 canvas->save(SkCanvas::kMatrixClip_SaveFlag); |
| 98 canvas.clipRect(partialRect, SkRegion::kIntersect_Op, false); | 113 canvas->clipRect(partialRect, SkRegion::kIntersect_Op, false); |
| 99 canvas.clear(0x00000000); | 114 canvas->clear(0x00000000); |
| 100 canvas.restore(); | 115 canvas->restore(); |
| 101 REPORTER_ASSERT(reporter, canvas.isFreshFrame()); | 116 REPORTER_ASSERT(reporter, canvas->isFreshFrame()); |
| 102 | 117 |
| 103 // Verify that full frame rects with different forms of opaque paint | 118 // Verify that full frame rects with different forms of opaque paint |
| 104 // trigger frames to be marked as fresh | 119 // trigger frames to be marked as fresh |
| 105 { | 120 { |
| 106 SkPaint paint; | 121 SkPaint paint; |
| 107 paint.setStyle(SkPaint::kFill_Style); | 122 paint.setStyle(SkPaint::kFill_Style); |
| 108 paint.setAlpha(255); | 123 paint.setAlpha(255); |
| 109 canvas.drawRect(fullRect, paint); | 124 canvas->drawRect(fullRect, paint); |
| 110 REPORTER_ASSERT(reporter, canvas.isFreshFrame()); | 125 REPORTER_ASSERT(reporter, canvas->isFreshFrame()); |
| 111 } | 126 } |
| 112 { | 127 { |
| 113 SkPaint paint; | 128 SkPaint paint; |
| 114 paint.setStyle(SkPaint::kFill_Style); | 129 paint.setStyle(SkPaint::kFill_Style); |
| 115 paint.setAlpha(255); | 130 paint.setAlpha(255); |
| 116 paint.setXfermodeMode(SkXfermode::kSrcIn_Mode); | 131 paint.setXfermodeMode(SkXfermode::kSrcIn_Mode); |
| 117 canvas.drawRect(fullRect, paint); | 132 canvas->drawRect(fullRect, paint); |
| 118 REPORTER_ASSERT(reporter, !canvas.isFreshFrame()); | 133 REPORTER_ASSERT(reporter, !canvas->isFreshFrame()); |
| 119 } | 134 } |
| 120 { | 135 { |
| 121 SkPaint paint; | 136 SkPaint paint; |
| 122 paint.setStyle(SkPaint::kFill_Style); | 137 paint.setStyle(SkPaint::kFill_Style); |
| 123 SkBitmap bmp; | 138 SkBitmap bmp; |
| 124 create(&bmp, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF); | 139 create(&bmp, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF); |
| 125 bmp.setIsOpaque(true); | 140 bmp.setIsOpaque(true); |
| 126 SkShader* shader = SkShader::CreateBitmapShader(bmp, | 141 SkShader* shader = SkShader::CreateBitmapShader(bmp, |
| 127 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode); | 142 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode); |
| 128 paint.setShader(shader)->unref(); | 143 paint.setShader(shader)->unref(); |
| 129 canvas.drawRect(fullRect, paint); | 144 canvas->drawRect(fullRect, paint); |
| 130 REPORTER_ASSERT(reporter, canvas.isFreshFrame()); | 145 REPORTER_ASSERT(reporter, canvas->isFreshFrame()); |
| 131 } | 146 } |
| 132 | 147 |
| 133 // Verify that full frame rects with different forms of non-opaque paint | 148 // Verify that full frame rects with different forms of non-opaque paint |
| 134 // do not trigger frames to be marked as fresh | 149 // do not trigger frames to be marked as fresh |
| 135 { | 150 { |
| 136 SkPaint paint; | 151 SkPaint paint; |
| 137 paint.setStyle(SkPaint::kFill_Style); | 152 paint.setStyle(SkPaint::kFill_Style); |
| 138 paint.setAlpha(254); | 153 paint.setAlpha(254); |
| 139 canvas.drawRect(fullRect, paint); | 154 canvas->drawRect(fullRect, paint); |
| 140 REPORTER_ASSERT(reporter, !canvas.isFreshFrame()); | 155 REPORTER_ASSERT(reporter, !canvas->isFreshFrame()); |
| 141 } | 156 } |
| 142 { | 157 { |
| 143 SkPaint paint; | 158 SkPaint paint; |
| 144 paint.setStyle(SkPaint::kFill_Style); | 159 paint.setStyle(SkPaint::kFill_Style); |
| 145 // Defining a cone that partially overlaps the canvas | 160 // Defining a cone that partially overlaps the canvas |
| 146 const SkPoint pt1 = SkPoint::Make(SkIntToScalar(0), SkIntToScalar(0)); | 161 const SkPoint pt1 = SkPoint::Make(SkIntToScalar(0), SkIntToScalar(0)); |
| 147 const SkScalar r1 = SkIntToScalar(1); | 162 const SkScalar r1 = SkIntToScalar(1); |
| 148 const SkPoint pt2 = SkPoint::Make(SkIntToScalar(10), SkIntToScalar(0)); | 163 const SkPoint pt2 = SkPoint::Make(SkIntToScalar(10), SkIntToScalar(0)); |
| 149 const SkScalar r2 = SkIntToScalar(5); | 164 const SkScalar r2 = SkIntToScalar(5); |
| 150 const SkColor colors[2] = {SK_ColorWHITE, SK_ColorWHITE}; | 165 const SkColor colors[2] = {SK_ColorWHITE, SK_ColorWHITE}; |
| 151 const SkScalar pos[2] = {0, SK_Scalar1}; | 166 const SkScalar pos[2] = {0, SK_Scalar1}; |
| 152 SkShader* shader = SkGradientShader::CreateTwoPointConical( | 167 SkShader* shader = SkGradientShader::CreateTwoPointConical( |
| 153 pt1, r1, pt2, r2, colors, pos, 2, SkShader::kClamp_TileMode, NULL); | 168 pt1, r1, pt2, r2, colors, pos, 2, SkShader::kClamp_TileMode, NULL); |
| 154 paint.setShader(shader)->unref(); | 169 paint.setShader(shader)->unref(); |
| 155 canvas.drawRect(fullRect, paint); | 170 canvas->drawRect(fullRect, paint); |
| 156 REPORTER_ASSERT(reporter, !canvas.isFreshFrame()); | 171 REPORTER_ASSERT(reporter, !canvas->isFreshFrame()); |
| 157 } | 172 } |
| 158 { | 173 { |
| 159 SkPaint paint; | 174 SkPaint paint; |
| 160 paint.setStyle(SkPaint::kFill_Style); | 175 paint.setStyle(SkPaint::kFill_Style); |
| 161 SkBitmap bmp; | 176 SkBitmap bmp; |
| 162 create(&bmp, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF); | 177 create(&bmp, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF); |
| 163 bmp.setIsOpaque(false); | 178 bmp.setIsOpaque(false); |
| 164 SkShader* shader = SkShader::CreateBitmapShader(bmp, | 179 SkShader* shader = SkShader::CreateBitmapShader(bmp, |
| 165 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode); | 180 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode); |
| 166 paint.setShader(shader)->unref(); | 181 paint.setShader(shader)->unref(); |
| 167 canvas.drawRect(fullRect, paint); | 182 canvas->drawRect(fullRect, paint); |
| 168 REPORTER_ASSERT(reporter, !canvas.isFreshFrame()); | 183 REPORTER_ASSERT(reporter, !canvas->isFreshFrame()); |
| 169 } | 184 } |
| 170 | 185 |
| 171 // Verify that incomplete coverage does not trigger a fresh frame | 186 // Verify that incomplete coverage does not trigger a fresh frame |
| 172 { | 187 { |
| 173 SkPaint paint; | 188 SkPaint paint; |
| 174 paint.setStyle(SkPaint::kFill_Style); | 189 paint.setStyle(SkPaint::kFill_Style); |
| 175 paint.setAlpha(255); | 190 paint.setAlpha(255); |
| 176 canvas.drawRect(partialRect, paint); | 191 canvas->drawRect(partialRect, paint); |
| 177 REPORTER_ASSERT(reporter, !canvas.isFreshFrame()); | 192 REPORTER_ASSERT(reporter, !canvas->isFreshFrame()); |
| 178 } | 193 } |
| 179 | 194 |
| 180 // Verify that incomplete coverage due to clipping does not trigger a fresh | 195 // Verify that incomplete coverage due to clipping does not trigger a fresh |
| 181 // frame | 196 // frame |
| 182 { | 197 { |
| 183 canvas.save(SkCanvas::kMatrixClip_SaveFlag); | 198 canvas->save(SkCanvas::kMatrixClip_SaveFlag); |
| 184 canvas.clipRect(partialRect, SkRegion::kIntersect_Op, false); | 199 canvas->clipRect(partialRect, SkRegion::kIntersect_Op, false); |
| 185 SkPaint paint; | 200 SkPaint paint; |
| 186 paint.setStyle(SkPaint::kFill_Style); | 201 paint.setStyle(SkPaint::kFill_Style); |
| 187 paint.setAlpha(255); | 202 paint.setAlpha(255); |
| 188 canvas.drawRect(fullRect, paint); | 203 canvas->drawRect(fullRect, paint); |
| 189 canvas.restore(); | 204 canvas->restore(); |
| 190 REPORTER_ASSERT(reporter, !canvas.isFreshFrame()); | 205 REPORTER_ASSERT(reporter, !canvas->isFreshFrame()); |
| 191 } | 206 } |
| 192 { | 207 { |
| 193 canvas.save(SkCanvas::kMatrixClip_SaveFlag); | 208 canvas->save(SkCanvas::kMatrixClip_SaveFlag); |
| 194 SkPaint paint; | 209 SkPaint paint; |
| 195 paint.setStyle(SkPaint::kFill_Style); | 210 paint.setStyle(SkPaint::kFill_Style); |
| 196 paint.setAlpha(255); | 211 paint.setAlpha(255); |
| 197 SkPath path; | 212 SkPath path; |
| 198 path.addCircle(SkIntToScalar(0), SkIntToScalar(0), SkIntToScalar(2)); | 213 path.addCircle(SkIntToScalar(0), SkIntToScalar(0), SkIntToScalar(2)); |
| 199 canvas.clipPath(path, SkRegion::kIntersect_Op, false); | 214 canvas->clipPath(path, SkRegion::kIntersect_Op, false); |
| 200 canvas.drawRect(fullRect, paint); | 215 canvas->drawRect(fullRect, paint); |
| 201 canvas.restore(); | 216 canvas->restore(); |
| 202 REPORTER_ASSERT(reporter, !canvas.isFreshFrame()); | 217 REPORTER_ASSERT(reporter, !canvas->isFreshFrame()); |
| 203 } | 218 } |
| 204 | 219 |
| 205 // Verify that stroked rect does not trigger a fresh frame | 220 // Verify that stroked rect does not trigger a fresh frame |
| 206 { | 221 { |
| 207 SkPaint paint; | 222 SkPaint paint; |
| 208 paint.setStyle(SkPaint::kStroke_Style); | 223 paint.setStyle(SkPaint::kStroke_Style); |
| 209 paint.setAlpha(255); | 224 paint.setAlpha(255); |
| 210 canvas.drawRect(fullRect, paint); | 225 canvas->drawRect(fullRect, paint); |
| 211 REPORTER_ASSERT(reporter, !canvas.isFreshFrame()); | 226 REPORTER_ASSERT(reporter, !canvas->isFreshFrame()); |
| 212 } | 227 } |
| 213 | 228 |
| 214 // Verify kSrcMode triggers a fresh frame even with transparent color | 229 // Verify kSrcMode triggers a fresh frame even with transparent color |
| 215 { | 230 { |
| 216 SkPaint paint; | 231 SkPaint paint; |
| 217 paint.setStyle(SkPaint::kFill_Style); | 232 paint.setStyle(SkPaint::kFill_Style); |
| 218 paint.setAlpha(100); | 233 paint.setAlpha(100); |
| 219 paint.setXfermodeMode(SkXfermode::kSrc_Mode); | 234 paint.setXfermodeMode(SkXfermode::kSrc_Mode); |
| 220 canvas.drawRect(fullRect, paint); | 235 canvas->drawRect(fullRect, paint); |
| 221 REPORTER_ASSERT(reporter, canvas.isFreshFrame()); | 236 REPORTER_ASSERT(reporter, canvas->isFreshFrame()); |
| 222 } | 237 } |
| 223 } | 238 } |
| 224 | 239 |
| 225 class MockDevice : public SkDevice { | 240 class MockDevice : public SkDevice { |
| 226 public: | 241 public: |
| 227 MockDevice(const SkBitmap& bm) : SkDevice(bm) { | 242 MockDevice(const SkBitmap& bm) : SkDevice(bm) { |
| 228 fDrawBitmapCallCount = 0; | 243 fDrawBitmapCallCount = 0; |
| 229 } | 244 } |
| 230 virtual void drawBitmap(const SkDraw&, const SkBitmap&, | 245 virtual void drawBitmap(const SkDraw&, const SkBitmap&, |
| 231 const SkIRect*, | 246 const SkIRect*, |
| 232 const SkMatrix&, const SkPaint&) { | 247 const SkMatrix&, const SkPaint&) { |
| 233 fDrawBitmapCallCount++; | 248 fDrawBitmapCallCount++; |
| 234 } | 249 } |
| 235 | 250 |
| 236 int fDrawBitmapCallCount; | 251 int fDrawBitmapCallCount; |
| 237 }; | 252 }; |
| 238 | 253 |
| 239 // Verifies that the deferred canvas triggers a flush when its memory | 254 // Verifies that the deferred canvas triggers a flush when its memory |
| 240 // limit is exceeded | 255 // limit is exceeded |
| 241 static void TestDeferredCanvasMemoryLimit(skiatest::Reporter* reporter) { | 256 static void TestDeferredCanvasMemoryLimit(skiatest::Reporter* reporter) { |
| 242 SkBitmap store; | 257 SkBitmap store; |
| 243 store.setConfig(SkBitmap::kARGB_8888_Config, 100, 100); | 258 store.setConfig(SkBitmap::kARGB_8888_Config, 100, 100); |
| 244 store.allocPixels(); | 259 store.allocPixels(); |
| 245 MockDevice mockDevice(store); | 260 MockDevice mockDevice(store); |
| 246 SkDeferredCanvas canvas(&mockDevice); | 261 SkAutoTUnref<SkDeferredCanvas> canvas( |
| 247 canvas.setMaxRecordingStorage(160000); | 262 #if SK_DEFERRED_CANVAS_USES_FACTORIES |
| 263 SkDeferredCanvas::Create(&mockDevice)); |
| 264 #else |
| 265 SkNEW_ARGS(SkDeferredCanvas, (&mockDevice))); |
| 266 #endif |
| 267 canvas->setMaxRecordingStorage(160000); |
| 248 | 268 |
| 249 SkBitmap sourceImage; | 269 SkBitmap sourceImage; |
| 250 // 100 by 100 image, takes 40,000 bytes in memory | 270 // 100 by 100 image, takes 40,000 bytes in memory |
| 251 sourceImage.setConfig(SkBitmap::kARGB_8888_Config, 100, 100); | 271 sourceImage.setConfig(SkBitmap::kARGB_8888_Config, 100, 100); |
| 252 sourceImage.allocPixels(); | 272 sourceImage.allocPixels(); |
| 253 | 273 |
| 254 for (int i = 0; i < 5; i++) { | 274 for (int i = 0; i < 5; i++) { |
| 255 sourceImage.notifyPixelsChanged(); // to force re-serialization | 275 sourceImage.notifyPixelsChanged(); // to force re-serialization |
| 256 canvas.drawBitmap(sourceImage, 0, 0, NULL); | 276 canvas->drawBitmap(sourceImage, 0, 0, NULL); |
| 257 } | 277 } |
| 258 | 278 |
| 259 REPORTER_ASSERT(reporter, mockDevice.fDrawBitmapCallCount == 4); | 279 REPORTER_ASSERT(reporter, mockDevice.fDrawBitmapCallCount == 4); |
| 260 } | 280 } |
| 261 | 281 |
| 262 class NotificationCounter : public SkDeferredCanvas::NotificationClient { | 282 class NotificationCounter : public SkDeferredCanvas::NotificationClient { |
| 263 public: | 283 public: |
| 264 NotificationCounter() { | 284 NotificationCounter() { |
| 265 fPrepareForDrawCount = fStorageAllocatedChangedCount = | 285 fPrepareForDrawCount = fStorageAllocatedChangedCount = |
| 266 fFlushedDrawCommandsCount = fSkippedPendingDrawCommandsCount = 0; | 286 fFlushedDrawCommandsCount = fSkippedPendingDrawCommandsCount = 0; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 287 private: | 307 private: |
| 288 typedef SkDeferredCanvas::NotificationClient INHERITED; | 308 typedef SkDeferredCanvas::NotificationClient INHERITED; |
| 289 }; | 309 }; |
| 290 | 310 |
| 291 static void TestDeferredCanvasBitmapCaching(skiatest::Reporter* reporter) { | 311 static void TestDeferredCanvasBitmapCaching(skiatest::Reporter* reporter) { |
| 292 SkBitmap store; | 312 SkBitmap store; |
| 293 store.setConfig(SkBitmap::kARGB_8888_Config, 100, 100); | 313 store.setConfig(SkBitmap::kARGB_8888_Config, 100, 100); |
| 294 store.allocPixels(); | 314 store.allocPixels(); |
| 295 SkDevice device(store); | 315 SkDevice device(store); |
| 296 NotificationCounter notificationCounter; | 316 NotificationCounter notificationCounter; |
| 297 SkDeferredCanvas canvas(&device); | 317 SkAutoTUnref<SkDeferredCanvas> canvas( |
| 298 canvas.setNotificationClient(¬ificationCounter); | 318 #if SK_DEFERRED_CANVAS_USES_FACTORIES |
| 319 SkDeferredCanvas::Create(&device)); |
| 320 #else |
| 321 SkNEW_ARGS(SkDeferredCanvas, (&device))); |
| 322 #endif |
| 323 canvas->setNotificationClient(¬ificationCounter); |
| 299 | 324 |
| 300 const int imageCount = 2; | 325 const int imageCount = 2; |
| 301 SkBitmap sourceImages[imageCount]; | 326 SkBitmap sourceImages[imageCount]; |
| 302 for (int i = 0; i < imageCount; i++) | 327 for (int i = 0; i < imageCount; i++) |
| 303 { | 328 { |
| 304 sourceImages[i].setConfig(SkBitmap::kARGB_8888_Config, 100, 100); | 329 sourceImages[i].setConfig(SkBitmap::kARGB_8888_Config, 100, 100); |
| 305 sourceImages[i].allocPixels(); | 330 sourceImages[i].allocPixels(); |
| 306 } | 331 } |
| 307 | 332 |
| 308 size_t bitmapSize = sourceImages[0].getSize(); | 333 size_t bitmapSize = sourceImages[0].getSize(); |
| 309 | 334 |
| 310 canvas.drawBitmap(sourceImages[0], 0, 0, NULL); | 335 canvas->drawBitmap(sourceImages[0], 0, 0, NULL); |
| 311 REPORTER_ASSERT(reporter, 1 == notificationCounter.fStorageAllocatedChangedC
ount); | 336 REPORTER_ASSERT(reporter, 1 == notificationCounter.fStorageAllocatedChangedC
ount); |
| 312 // stored bitmap + drawBitmap command | 337 // stored bitmap + drawBitmap command |
| 313 REPORTER_ASSERT(reporter, canvas.storageAllocatedForRecording() > bitmapSize
); | 338 REPORTER_ASSERT(reporter, canvas->storageAllocatedForRecording() > bitmapSiz
e); |
| 314 | 339 |
| 315 // verify that nothing can be freed at this point | 340 // verify that nothing can be freed at this point |
| 316 REPORTER_ASSERT(reporter, 0 == canvas.freeMemoryIfPossible(~0U)); | 341 REPORTER_ASSERT(reporter, 0 == canvas->freeMemoryIfPossible(~0U)); |
| 317 | 342 |
| 318 // verify that flush leaves image in cache | 343 // verify that flush leaves image in cache |
| 319 REPORTER_ASSERT(reporter, 0 == notificationCounter.fFlushedDrawCommandsCount
); | 344 REPORTER_ASSERT(reporter, 0 == notificationCounter.fFlushedDrawCommandsCount
); |
| 320 REPORTER_ASSERT(reporter, 0 == notificationCounter.fPrepareForDrawCount); | 345 REPORTER_ASSERT(reporter, 0 == notificationCounter.fPrepareForDrawCount); |
| 321 canvas.flush(); | 346 canvas->flush(); |
| 322 REPORTER_ASSERT(reporter, 1 == notificationCounter.fFlushedDrawCommandsCount
); | 347 REPORTER_ASSERT(reporter, 1 == notificationCounter.fFlushedDrawCommandsCount
); |
| 323 REPORTER_ASSERT(reporter, 1 == notificationCounter.fPrepareForDrawCount); | 348 REPORTER_ASSERT(reporter, 1 == notificationCounter.fPrepareForDrawCount); |
| 324 REPORTER_ASSERT(reporter, canvas.storageAllocatedForRecording() >= bitmapSiz
e); | 349 REPORTER_ASSERT(reporter, canvas->storageAllocatedForRecording() >= bitmapSi
ze); |
| 325 | 350 |
| 326 // verify that after a flush, cached image can be freed | 351 // verify that after a flush, cached image can be freed |
| 327 REPORTER_ASSERT(reporter, canvas.freeMemoryIfPossible(~0U) >= bitmapSize); | 352 REPORTER_ASSERT(reporter, canvas->freeMemoryIfPossible(~0U) >= bitmapSize); |
| 328 | 353 |
| 329 // Verify that caching works for avoiding multiple copies of the same bitmap | 354 // Verify that caching works for avoiding multiple copies of the same bitmap |
| 330 canvas.drawBitmap(sourceImages[0], 0, 0, NULL); | 355 canvas->drawBitmap(sourceImages[0], 0, 0, NULL); |
| 331 REPORTER_ASSERT(reporter, 2 == notificationCounter.fStorageAllocatedChangedC
ount); | 356 REPORTER_ASSERT(reporter, 2 == notificationCounter.fStorageAllocatedChangedC
ount); |
| 332 canvas.drawBitmap(sourceImages[0], 0, 0, NULL); | 357 canvas->drawBitmap(sourceImages[0], 0, 0, NULL); |
| 333 REPORTER_ASSERT(reporter, 2 == notificationCounter.fStorageAllocatedChangedC
ount); | 358 REPORTER_ASSERT(reporter, 2 == notificationCounter.fStorageAllocatedChangedC
ount); |
| 334 REPORTER_ASSERT(reporter, 1 == notificationCounter.fFlushedDrawCommandsCount
); | 359 REPORTER_ASSERT(reporter, 1 == notificationCounter.fFlushedDrawCommandsCount
); |
| 335 REPORTER_ASSERT(reporter, canvas.storageAllocatedForRecording() < 2 * bitmap
Size); | 360 REPORTER_ASSERT(reporter, canvas->storageAllocatedForRecording() < 2 * bitma
pSize); |
| 336 | 361 |
| 337 // Verify partial eviction based on bytesToFree | 362 // Verify partial eviction based on bytesToFree |
| 338 canvas.drawBitmap(sourceImages[1], 0, 0, NULL); | 363 canvas->drawBitmap(sourceImages[1], 0, 0, NULL); |
| 339 REPORTER_ASSERT(reporter, 1 == notificationCounter.fFlushedDrawCommandsCount
); | 364 REPORTER_ASSERT(reporter, 1 == notificationCounter.fFlushedDrawCommandsCount
); |
| 340 canvas.flush(); | 365 canvas->flush(); |
| 341 REPORTER_ASSERT(reporter, 2 == notificationCounter.fFlushedDrawCommandsCount
); | 366 REPORTER_ASSERT(reporter, 2 == notificationCounter.fFlushedDrawCommandsCount
); |
| 342 REPORTER_ASSERT(reporter, canvas.storageAllocatedForRecording() > 2 * bitmap
Size); | 367 REPORTER_ASSERT(reporter, canvas->storageAllocatedForRecording() > 2 * bitma
pSize); |
| 343 size_t bytesFreed = canvas.freeMemoryIfPossible(1); | 368 size_t bytesFreed = canvas->freeMemoryIfPossible(1); |
| 344 REPORTER_ASSERT(reporter, 2 == notificationCounter.fFlushedDrawCommandsCount
); | 369 REPORTER_ASSERT(reporter, 2 == notificationCounter.fFlushedDrawCommandsCount
); |
| 345 REPORTER_ASSERT(reporter, bytesFreed >= bitmapSize); | 370 REPORTER_ASSERT(reporter, bytesFreed >= bitmapSize); |
| 346 REPORTER_ASSERT(reporter, bytesFreed < 2*bitmapSize); | 371 REPORTER_ASSERT(reporter, bytesFreed < 2*bitmapSize); |
| 347 | 372 |
| 348 // Verifiy that partial purge works, image zero is in cache but not reffed b
y | 373 // Verifiy that partial purge works, image zero is in cache but not reffed b
y |
| 349 // a pending draw, while image 1 is locked-in. | 374 // a pending draw, while image 1 is locked-in. |
| 350 canvas.freeMemoryIfPossible(~0U); | 375 canvas->freeMemoryIfPossible(~0U); |
| 351 REPORTER_ASSERT(reporter, 2 == notificationCounter.fFlushedDrawCommandsCount
); | 376 REPORTER_ASSERT(reporter, 2 == notificationCounter.fFlushedDrawCommandsCount
); |
| 352 canvas.drawBitmap(sourceImages[0], 0, 0, NULL); | 377 canvas->drawBitmap(sourceImages[0], 0, 0, NULL); |
| 353 canvas.flush(); | 378 canvas->flush(); |
| 354 canvas.drawBitmap(sourceImages[1], 0, 0, NULL); | 379 canvas->drawBitmap(sourceImages[1], 0, 0, NULL); |
| 355 bytesFreed = canvas.freeMemoryIfPossible(~0U); | 380 bytesFreed = canvas->freeMemoryIfPossible(~0U); |
| 356 // only one bitmap should have been freed. | 381 // only one bitmap should have been freed. |
| 357 REPORTER_ASSERT(reporter, bytesFreed >= bitmapSize); | 382 REPORTER_ASSERT(reporter, bytesFreed >= bitmapSize); |
| 358 REPORTER_ASSERT(reporter, bytesFreed < 2*bitmapSize); | 383 REPORTER_ASSERT(reporter, bytesFreed < 2*bitmapSize); |
| 359 // Clear for next test | 384 // Clear for next test |
| 360 canvas.flush(); | 385 canvas->flush(); |
| 361 canvas.freeMemoryIfPossible(~0U); | 386 canvas->freeMemoryIfPossible(~0U); |
| 362 REPORTER_ASSERT(reporter, canvas.storageAllocatedForRecording() < bitmapSize
); | 387 REPORTER_ASSERT(reporter, canvas->storageAllocatedForRecording() < bitmapSiz
e); |
| 363 | 388 |
| 364 // Verify the image cache is sensitive to genID bumps | 389 // Verify the image cache is sensitive to genID bumps |
| 365 canvas.drawBitmap(sourceImages[1], 0, 0, NULL); | 390 canvas->drawBitmap(sourceImages[1], 0, 0, NULL); |
| 366 sourceImages[1].notifyPixelsChanged(); | 391 sourceImages[1].notifyPixelsChanged(); |
| 367 canvas.drawBitmap(sourceImages[1], 0, 0, NULL); | 392 canvas->drawBitmap(sourceImages[1], 0, 0, NULL); |
| 368 REPORTER_ASSERT(reporter, canvas.storageAllocatedForRecording() > 2*bitmapSi
ze); | 393 REPORTER_ASSERT(reporter, canvas->storageAllocatedForRecording() > 2*bitmapS
ize); |
| 369 | 394 |
| 370 // Verify that nothing in this test caused commands to be skipped | 395 // Verify that nothing in this test caused commands to be skipped |
| 371 REPORTER_ASSERT(reporter, 0 == notificationCounter.fSkippedPendingDrawComman
dsCount); | 396 REPORTER_ASSERT(reporter, 0 == notificationCounter.fSkippedPendingDrawComman
dsCount); |
| 372 } | 397 } |
| 373 | 398 |
| 374 static void TestDeferredCanvasSkip(skiatest::Reporter* reporter) { | 399 static void TestDeferredCanvasSkip(skiatest::Reporter* reporter) { |
| 375 SkBitmap store; | 400 SkBitmap store; |
| 376 store.setConfig(SkBitmap::kARGB_8888_Config, 100, 100); | 401 store.setConfig(SkBitmap::kARGB_8888_Config, 100, 100); |
| 377 store.allocPixels(); | 402 store.allocPixels(); |
| 378 SkDevice device(store); | 403 SkDevice device(store); |
| 379 NotificationCounter notificationCounter; | 404 NotificationCounter notificationCounter; |
| 380 SkDeferredCanvas canvas(&device); | 405 SkAutoTUnref<SkDeferredCanvas> canvas( |
| 381 canvas.setNotificationClient(¬ificationCounter); | 406 #if SK_DEFERRED_CANVAS_USES_FACTORIES |
| 382 canvas.clear(0x0); | 407 SkDeferredCanvas::Create(&device)); |
| 408 #else |
| 409 SkNEW_ARGS(SkDeferredCanvas, (&device))); |
| 410 #endif |
| 411 canvas->setNotificationClient(¬ificationCounter); |
| 412 canvas->clear(0x0); |
| 383 REPORTER_ASSERT(reporter, 1 == notificationCounter.fSkippedPendingDrawComman
dsCount); | 413 REPORTER_ASSERT(reporter, 1 == notificationCounter.fSkippedPendingDrawComman
dsCount); |
| 384 REPORTER_ASSERT(reporter, 0 == notificationCounter.fFlushedDrawCommandsCount
); | 414 REPORTER_ASSERT(reporter, 0 == notificationCounter.fFlushedDrawCommandsCount
); |
| 385 canvas.flush(); | 415 canvas->flush(); |
| 386 REPORTER_ASSERT(reporter, 1 == notificationCounter.fSkippedPendingDrawComman
dsCount); | 416 REPORTER_ASSERT(reporter, 1 == notificationCounter.fSkippedPendingDrawComman
dsCount); |
| 387 REPORTER_ASSERT(reporter, 1 == notificationCounter.fFlushedDrawCommandsCount
); | 417 REPORTER_ASSERT(reporter, 1 == notificationCounter.fFlushedDrawCommandsCount
); |
| 388 | 418 |
| 389 } | 419 } |
| 390 | 420 |
| 391 static void TestDeferredCanvasBitmapShaderNoLeak(skiatest::Reporter* reporter) { | 421 static void TestDeferredCanvasBitmapShaderNoLeak(skiatest::Reporter* reporter) { |
| 392 // This is a regression test for crbug.com/155875 | 422 // This is a regression test for crbug.com/155875 |
| 393 // This test covers a code path that inserts bitmaps into the bitmap heap th
rough the | 423 // This test covers a code path that inserts bitmaps into the bitmap heap th
rough the |
| 394 // flattening of SkBitmapProcShaders. The refcount in the bitmap heap is mai
ntained through | 424 // flattening of SkBitmapProcShaders. The refcount in the bitmap heap is mai
ntained through |
| 395 // the flattening and unflattening of the shader. | 425 // the flattening and unflattening of the shader. |
| 396 SkBitmap store; | 426 SkBitmap store; |
| 397 store.setConfig(SkBitmap::kARGB_8888_Config, 100, 100); | 427 store.setConfig(SkBitmap::kARGB_8888_Config, 100, 100); |
| 398 store.allocPixels(); | 428 store.allocPixels(); |
| 399 SkDevice device(store); | 429 SkDevice device(store); |
| 400 SkDeferredCanvas canvas(&device); | 430 SkAutoTUnref<SkDeferredCanvas> canvas( |
| 431 #if SK_DEFERRED_CANVAS_USES_FACTORIES |
| 432 SkDeferredCanvas::Create(&device)); |
| 433 #else |
| 434 SkNEW_ARGS(SkDeferredCanvas, (&device))); |
| 435 #endif |
| 401 // test will fail if nbIterations is not in sync with | 436 // test will fail if nbIterations is not in sync with |
| 402 // BITMAPS_TO_KEEP in SkGPipeWrite.cpp | 437 // BITMAPS_TO_KEEP in SkGPipeWrite.cpp |
| 403 const int nbIterations = 5; | 438 const int nbIterations = 5; |
| 404 size_t bytesAllocated = 0; | 439 size_t bytesAllocated = 0; |
| 405 for(int pass = 0; pass < 2; ++pass) { | 440 for(int pass = 0; pass < 2; ++pass) { |
| 406 for(int i = 0; i < nbIterations; ++i) { | 441 for(int i = 0; i < nbIterations; ++i) { |
| 407 SkPaint paint; | 442 SkPaint paint; |
| 408 SkBitmap paintPattern; | 443 SkBitmap paintPattern; |
| 409 paintPattern.setConfig(SkBitmap::kARGB_8888_Config, 10, 10); | 444 paintPattern.setConfig(SkBitmap::kARGB_8888_Config, 10, 10); |
| 410 paintPattern.allocPixels(); | 445 paintPattern.allocPixels(); |
| 411 paint.setShader(SkNEW_ARGS(SkBitmapProcShader, | 446 paint.setShader(SkNEW_ARGS(SkBitmapProcShader, |
| 412 (paintPattern, SkShader::kClamp_TileMode, SkShader::kClamp_TileM
ode)))->unref(); | 447 (paintPattern, SkShader::kClamp_TileMode, SkShader::kClamp_TileM
ode)))->unref(); |
| 413 canvas.drawPaint(paint); | 448 canvas->drawPaint(paint); |
| 414 canvas.flush(); | 449 canvas->flush(); |
| 415 | 450 |
| 416 // In the first pass, memory allocation should be monotonically incr
easing as | 451 // In the first pass, memory allocation should be monotonically incr
easing as |
| 417 // the bitmap heap slots fill up. In the second pass memory allocat
ion should be | 452 // the bitmap heap slots fill up. In the second pass memory allocat
ion should be |
| 418 // stable as bitmap heap slots get recycled. | 453 // stable as bitmap heap slots get recycled. |
| 419 size_t newBytesAllocated = canvas.storageAllocatedForRecording(); | 454 size_t newBytesAllocated = canvas->storageAllocatedForRecording(); |
| 420 if (pass == 0) { | 455 if (pass == 0) { |
| 421 REPORTER_ASSERT(reporter, newBytesAllocated > bytesAllocated); | 456 REPORTER_ASSERT(reporter, newBytesAllocated > bytesAllocated); |
| 422 bytesAllocated = newBytesAllocated; | 457 bytesAllocated = newBytesAllocated; |
| 423 } else { | 458 } else { |
| 424 REPORTER_ASSERT(reporter, newBytesAllocated == bytesAllocated); | 459 REPORTER_ASSERT(reporter, newBytesAllocated == bytesAllocated); |
| 425 } | 460 } |
| 426 } | 461 } |
| 427 } | 462 } |
| 428 // All cached resources should be evictable since last canvas call was flush
() | 463 // All cached resources should be evictable since last canvas call was flush
() |
| 429 canvas.freeMemoryIfPossible(~0U); | 464 canvas->freeMemoryIfPossible(~0U); |
| 430 REPORTER_ASSERT(reporter, 0 == canvas.storageAllocatedForRecording()); | 465 REPORTER_ASSERT(reporter, 0 == canvas->storageAllocatedForRecording()); |
| 431 } | 466 } |
| 432 | 467 |
| 433 static void TestDeferredCanvasBitmapSizeThreshold(skiatest::Reporter* reporter)
{ | 468 static void TestDeferredCanvasBitmapSizeThreshold(skiatest::Reporter* reporter)
{ |
| 434 SkBitmap store; | 469 SkBitmap store; |
| 435 store.setConfig(SkBitmap::kARGB_8888_Config, 100, 100); | 470 store.setConfig(SkBitmap::kARGB_8888_Config, 100, 100); |
| 436 store.allocPixels(); | 471 store.allocPixels(); |
| 437 | 472 |
| 438 SkBitmap sourceImage; | 473 SkBitmap sourceImage; |
| 439 // 100 by 100 image, takes 40,000 bytes in memory | 474 // 100 by 100 image, takes 40,000 bytes in memory |
| 440 sourceImage.setConfig(SkBitmap::kARGB_8888_Config, 100, 100); | 475 sourceImage.setConfig(SkBitmap::kARGB_8888_Config, 100, 100); |
| 441 sourceImage.allocPixels(); | 476 sourceImage.allocPixels(); |
| 442 | 477 |
| 443 // 1 under : should not store the image | 478 // 1 under : should not store the image |
| 444 { | 479 { |
| 445 SkDevice device(store); | 480 SkDevice device(store); |
| 446 SkDeferredCanvas canvas(&device); | 481 SkAutoTUnref<SkDeferredCanvas> canvas( |
| 447 canvas.setBitmapSizeThreshold(39999); | 482 #if SK_DEFERRED_CANVAS_USES_FACTORIES |
| 448 canvas.drawBitmap(sourceImage, 0, 0, NULL); | 483 SkDeferredCanvas::Create(&device)); |
| 449 size_t newBytesAllocated = canvas.storageAllocatedForRecording(); | 484 #else |
| 485 SkNEW_ARGS(SkDeferredCanvas, (&device))); |
| 486 #endif |
| 487 canvas->setBitmapSizeThreshold(39999); |
| 488 canvas->drawBitmap(sourceImage, 0, 0, NULL); |
| 489 size_t newBytesAllocated = canvas->storageAllocatedForRecording(); |
| 450 REPORTER_ASSERT(reporter, newBytesAllocated == 0); | 490 REPORTER_ASSERT(reporter, newBytesAllocated == 0); |
| 451 } | 491 } |
| 452 | 492 |
| 453 // exact value : should store the image | 493 // exact value : should store the image |
| 454 { | 494 { |
| 455 SkDevice device(store); | 495 SkDevice device(store); |
| 456 SkDeferredCanvas canvas(&device); | 496 SkAutoTUnref<SkDeferredCanvas> canvas( |
| 457 canvas.setBitmapSizeThreshold(40000); | 497 #if SK_DEFERRED_CANVAS_USES_FACTORIES |
| 458 canvas.drawBitmap(sourceImage, 0, 0, NULL); | 498 SkDeferredCanvas::Create(&device)); |
| 459 size_t newBytesAllocated = canvas.storageAllocatedForRecording(); | 499 #else |
| 500 SkNEW_ARGS(SkDeferredCanvas, (&device))); |
| 501 #endif |
| 502 canvas->setBitmapSizeThreshold(40000); |
| 503 canvas->drawBitmap(sourceImage, 0, 0, NULL); |
| 504 size_t newBytesAllocated = canvas->storageAllocatedForRecording(); |
| 460 REPORTER_ASSERT(reporter, newBytesAllocated > 0); | 505 REPORTER_ASSERT(reporter, newBytesAllocated > 0); |
| 461 } | 506 } |
| 462 | 507 |
| 463 // 1 over : should still store the image | 508 // 1 over : should still store the image |
| 464 { | 509 { |
| 465 SkDevice device(store); | 510 SkDevice device(store); |
| 466 SkDeferredCanvas canvas(&device); | 511 SkAutoTUnref<SkDeferredCanvas> canvas( |
| 467 canvas.setBitmapSizeThreshold(40001); | 512 #if SK_DEFERRED_CANVAS_USES_FACTORIES |
| 468 canvas.drawBitmap(sourceImage, 0, 0, NULL); | 513 SkDeferredCanvas::Create(&device)); |
| 469 size_t newBytesAllocated = canvas.storageAllocatedForRecording(); | 514 #else |
| 515 SkNEW_ARGS(SkDeferredCanvas, (&device))); |
| 516 #endif |
| 517 canvas->setBitmapSizeThreshold(40001); |
| 518 canvas->drawBitmap(sourceImage, 0, 0, NULL); |
| 519 size_t newBytesAllocated = canvas->storageAllocatedForRecording(); |
| 470 REPORTER_ASSERT(reporter, newBytesAllocated > 0); | 520 REPORTER_ASSERT(reporter, newBytesAllocated > 0); |
| 471 } | 521 } |
| 472 } | 522 } |
| 473 | 523 |
| 474 | 524 |
| 475 typedef void* PixelPtr; | 525 typedef void* PixelPtr; |
| 476 // Returns an opaque pointer which, either points to a GrTexture or RAM pixel | 526 // Returns an opaque pointer which, either points to a GrTexture or RAM pixel |
| 477 // buffer. Used to test pointer equality do determine whether a surface points | 527 // buffer. Used to test pointer equality do determine whether a surface points |
| 478 // to the same pixel data storage as before. | 528 // to the same pixel data storage as before. |
| 479 static PixelPtr getSurfacePixelPtr(SkSurface* surface, bool useGpu) { | 529 static PixelPtr getSurfacePixelPtr(SkSurface* surface, bool useGpu) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 496 surface = SkSurface::NewRenderTarget(context, imageSpec); | 546 surface = SkSurface::NewRenderTarget(context, imageSpec); |
| 497 } else { | 547 } else { |
| 498 surface = SkSurface::NewRaster(imageSpec); | 548 surface = SkSurface::NewRaster(imageSpec); |
| 499 } | 549 } |
| 500 #else | 550 #else |
| 501 SkASSERT(!useGpu); | 551 SkASSERT(!useGpu); |
| 502 surface = SkSurface::NewRaster(imageSpec); | 552 surface = SkSurface::NewRaster(imageSpec); |
| 503 #endif | 553 #endif |
| 504 SkASSERT(NULL != surface); | 554 SkASSERT(NULL != surface); |
| 505 SkAutoTUnref<SkSurface> aur(surface); | 555 SkAutoTUnref<SkSurface> aur(surface); |
| 506 SkDeferredCanvas canvas(surface); | 556 SkAutoTUnref<SkDeferredCanvas> canvas( |
| 557 #if SK_DEFERRED_CANVAS_USES_FACTORIES |
| 558 SkDeferredCanvas::Create(surface)); |
| 559 #else |
| 560 SkNEW_ARGS(SkDeferredCanvas, (surface))); |
| 561 #endif |
| 507 | 562 |
| 508 SkImage* image1 = canvas.newImageSnapshot(); | 563 SkImage* image1 = canvas->newImageSnapshot(); |
| 509 SkAutoTUnref<SkImage> aur_i1(image1); | 564 SkAutoTUnref<SkImage> aur_i1(image1); |
| 510 PixelPtr pixels1 = getSurfacePixelPtr(surface, useGpu); | 565 PixelPtr pixels1 = getSurfacePixelPtr(surface, useGpu); |
| 511 // The following clear would normally trigger a copy on write, but | 566 // The following clear would normally trigger a copy on write, but |
| 512 // it won't because rendering is deferred. | 567 // it won't because rendering is deferred. |
| 513 canvas.clear(SK_ColorBLACK); | 568 canvas->clear(SK_ColorBLACK); |
| 514 // Obtaining a snapshot directly from the surface (as opposed to the | 569 // Obtaining a snapshot directly from the surface (as opposed to the |
| 515 // SkDeferredCanvas) will not trigger a flush of deferred draw operations | 570 // SkDeferredCanvas) will not trigger a flush of deferred draw operations |
| 516 // and will therefore return the same image as the previous snapshot. | 571 // and will therefore return the same image as the previous snapshot. |
| 517 SkImage* image2 = surface->newImageSnapshot(); | 572 SkImage* image2 = surface->newImageSnapshot(); |
| 518 SkAutoTUnref<SkImage> aur_i2(image2); | 573 SkAutoTUnref<SkImage> aur_i2(image2); |
| 519 // Images identical because of deferral | 574 // Images identical because of deferral |
| 520 REPORTER_ASSERT(reporter, image1->uniqueID() == image2->uniqueID()); | 575 REPORTER_ASSERT(reporter, image1->uniqueID() == image2->uniqueID()); |
| 521 // Now we obtain a snpshot via the deferred canvas, which triggers a flush. | 576 // Now we obtain a snpshot via the deferred canvas, which triggers a flush. |
| 522 // Because there is a pending clear, this will generate a different image. | 577 // Because there is a pending clear, this will generate a different image. |
| 523 SkImage* image3 = canvas.newImageSnapshot(); | 578 SkImage* image3 = canvas->newImageSnapshot(); |
| 524 SkAutoTUnref<SkImage> aur_i3(image3); | 579 SkAutoTUnref<SkImage> aur_i3(image3); |
| 525 REPORTER_ASSERT(reporter, image1->uniqueID() != image3->uniqueID()); | 580 REPORTER_ASSERT(reporter, image1->uniqueID() != image3->uniqueID()); |
| 526 // Verify that backing store is now a different buffer because of copy on | 581 // Verify that backing store is now a different buffer because of copy on |
| 527 // write | 582 // write |
| 528 PixelPtr pixels2 = getSurfacePixelPtr(surface, useGpu); | 583 PixelPtr pixels2 = getSurfacePixelPtr(surface, useGpu); |
| 529 REPORTER_ASSERT(reporter, pixels1 != pixels2); | 584 REPORTER_ASSERT(reporter, pixels1 != pixels2); |
| 530 // Verify copy-on write with a draw operation that gets deferred by | 585 // Verify copy-on write with a draw operation that gets deferred by |
| 531 // the in order draw buffer. | 586 // the in order draw buffer. |
| 532 SkPaint paint; | 587 SkPaint paint; |
| 533 canvas.drawPaint(paint); | 588 canvas->drawPaint(paint); |
| 534 SkImage* image4 = canvas.newImageSnapshot(); // implicit flush | 589 SkImage* image4 = canvas->newImageSnapshot(); // implicit flush |
| 535 SkAutoTUnref<SkImage> aur_i4(image4); | 590 SkAutoTUnref<SkImage> aur_i4(image4); |
| 536 REPORTER_ASSERT(reporter, image4->uniqueID() != image3->uniqueID()); | 591 REPORTER_ASSERT(reporter, image4->uniqueID() != image3->uniqueID()); |
| 537 PixelPtr pixels3 = getSurfacePixelPtr(surface, useGpu); | 592 PixelPtr pixels3 = getSurfacePixelPtr(surface, useGpu); |
| 538 REPORTER_ASSERT(reporter, pixels2 != pixels3); | 593 REPORTER_ASSERT(reporter, pixels2 != pixels3); |
| 539 // Verify that a direct canvas flush with a pending draw does not trigger | 594 // Verify that a direct canvas flush with a pending draw does not trigger |
| 540 // a copy on write when the surface is not sharing its buffer with an | 595 // a copy on write when the surface is not sharing its buffer with an |
| 541 // SkImage. | 596 // SkImage. |
| 542 canvas.clear(SK_ColorWHITE); | 597 canvas->clear(SK_ColorWHITE); |
| 543 canvas.flush(); | 598 canvas->flush(); |
| 544 PixelPtr pixels4 = getSurfacePixelPtr(surface, useGpu); | 599 PixelPtr pixels4 = getSurfacePixelPtr(surface, useGpu); |
| 545 canvas.drawPaint(paint); | 600 canvas->drawPaint(paint); |
| 546 canvas.flush(); | 601 canvas->flush(); |
| 547 PixelPtr pixels5 = getSurfacePixelPtr(surface, useGpu); | 602 PixelPtr pixels5 = getSurfacePixelPtr(surface, useGpu); |
| 548 REPORTER_ASSERT(reporter, pixels4 == pixels5); | 603 REPORTER_ASSERT(reporter, pixels4 == pixels5); |
| 549 } | 604 } |
| 550 | 605 |
| 551 static void TestDeferredCanvasSetSurface(skiatest::Reporter* reporter, GrContext
Factory* factory) { | 606 static void TestDeferredCanvasSetSurface(skiatest::Reporter* reporter, GrContext
Factory* factory) { |
| 552 SkImage::Info imageSpec = { | 607 SkImage::Info imageSpec = { |
| 553 10, // width | 608 10, // width |
| 554 10, // height | 609 10, // height |
| 555 SkImage::kPMColor_ColorType, | 610 SkImage::kPMColor_ColorType, |
| 556 SkImage::kPremul_AlphaType | 611 SkImage::kPremul_AlphaType |
| (...skipping 14 matching lines...) Expand all Loading... |
| 571 SkASSERT(!useGpu); | 626 SkASSERT(!useGpu); |
| 572 surface = SkSurface::NewRaster(imageSpec); | 627 surface = SkSurface::NewRaster(imageSpec); |
| 573 alternateSurface = SkSurface::NewRaster(imageSpec); | 628 alternateSurface = SkSurface::NewRaster(imageSpec); |
| 574 #endif | 629 #endif |
| 575 SkASSERT(NULL != surface); | 630 SkASSERT(NULL != surface); |
| 576 SkASSERT(NULL != alternateSurface); | 631 SkASSERT(NULL != alternateSurface); |
| 577 SkAutoTUnref<SkSurface> aur1(surface); | 632 SkAutoTUnref<SkSurface> aur1(surface); |
| 578 SkAutoTUnref<SkSurface> aur2(alternateSurface); | 633 SkAutoTUnref<SkSurface> aur2(alternateSurface); |
| 579 PixelPtr pixels1 = getSurfacePixelPtr(surface, useGpu); | 634 PixelPtr pixels1 = getSurfacePixelPtr(surface, useGpu); |
| 580 PixelPtr pixels2 = getSurfacePixelPtr(alternateSurface, useGpu); | 635 PixelPtr pixels2 = getSurfacePixelPtr(alternateSurface, useGpu); |
| 581 SkDeferredCanvas canvas(surface); | 636 SkAutoTUnref<SkDeferredCanvas> canvas( |
| 582 SkAutoTUnref<SkImage> image1(canvas.newImageSnapshot()); | 637 #if SK_DEFERRED_CANVAS_USES_FACTORIES |
| 583 canvas.setSurface(alternateSurface); | 638 SkDeferredCanvas::Create(surface)); |
| 584 SkAutoTUnref<SkImage> image2(canvas.newImageSnapshot()); | 639 #else |
| 640 SkNEW_ARGS(SkDeferredCanvas, (surface))); |
| 641 #endif |
| 642 SkAutoTUnref<SkImage> image1(canvas->newImageSnapshot()); |
| 643 canvas->setSurface(alternateSurface); |
| 644 SkAutoTUnref<SkImage> image2(canvas->newImageSnapshot()); |
| 585 REPORTER_ASSERT(reporter, image1->uniqueID() != image2->uniqueID()); | 645 REPORTER_ASSERT(reporter, image1->uniqueID() != image2->uniqueID()); |
| 586 // Verify that none of the above operations triggered a surface copy on writ
e. | 646 // Verify that none of the above operations triggered a surface copy on writ
e. |
| 587 REPORTER_ASSERT(reporter, getSurfacePixelPtr(surface, useGpu) == pixels1); | 647 REPORTER_ASSERT(reporter, getSurfacePixelPtr(surface, useGpu) == pixels1); |
| 588 REPORTER_ASSERT(reporter, getSurfacePixelPtr(alternateSurface, useGpu) == pi
xels2); | 648 REPORTER_ASSERT(reporter, getSurfacePixelPtr(alternateSurface, useGpu) == pi
xels2); |
| 589 // Verify that a flushed draw command will trigger a copy on write on altern
ateSurface. | 649 // Verify that a flushed draw command will trigger a copy on write on altern
ateSurface. |
| 590 canvas.clear(SK_ColorWHITE); | 650 canvas->clear(SK_ColorWHITE); |
| 591 canvas.flush(); | 651 canvas->flush(); |
| 592 REPORTER_ASSERT(reporter, getSurfacePixelPtr(surface, useGpu) == pixels1); | 652 REPORTER_ASSERT(reporter, getSurfacePixelPtr(surface, useGpu) == pixels1); |
| 593 REPORTER_ASSERT(reporter, getSurfacePixelPtr(alternateSurface, useGpu) != pi
xels2); | 653 REPORTER_ASSERT(reporter, getSurfacePixelPtr(alternateSurface, useGpu) != pi
xels2); |
| 594 } | 654 } |
| 595 | 655 |
| 596 static void TestDeferredCanvasCreateCompatibleDevice(skiatest::Reporter* reporte
r) { | 656 static void TestDeferredCanvasCreateCompatibleDevice(skiatest::Reporter* reporte
r) { |
| 597 SkBitmap store; | 657 SkBitmap store; |
| 598 store.setConfig(SkBitmap::kARGB_8888_Config, 100, 100); | 658 store.setConfig(SkBitmap::kARGB_8888_Config, 100, 100); |
| 599 store.allocPixels(); | 659 store.allocPixels(); |
| 600 SkDevice device(store); | 660 SkDevice device(store); |
| 601 NotificationCounter notificationCounter; | 661 NotificationCounter notificationCounter; |
| 602 SkDeferredCanvas canvas(&device); | 662 SkAutoTUnref<SkDeferredCanvas> canvas( |
| 603 canvas.setNotificationClient(¬ificationCounter); | 663 #if SK_DEFERRED_CANVAS_USES_FACTORIES |
| 604 SkAutoTUnref<SkDevice> secondaryDevice(canvas.createCompatibleDevice( | 664 SkDeferredCanvas::Create(&device)); |
| 665 #else |
| 666 SkNEW_ARGS(SkDeferredCanvas, (&device))); |
| 667 #endif |
| 668 canvas->setNotificationClient(¬ificationCounter); |
| 669 SkAutoTUnref<SkDevice> secondaryDevice(canvas->createCompatibleDevice( |
| 605 SkBitmap::kARGB_8888_Config, 10, 10, device.isOpaque())); | 670 SkBitmap::kARGB_8888_Config, 10, 10, device.isOpaque())); |
| 606 SkCanvas secondaryCanvas(secondaryDevice.get()); | 671 SkCanvas secondaryCanvas(secondaryDevice.get()); |
| 607 SkRect rect = SkRect::MakeWH(5, 5); | 672 SkRect rect = SkRect::MakeWH(5, 5); |
| 608 SkPaint paint; | 673 SkPaint paint; |
| 609 // After spawning a compatible canvas: | 674 // After spawning a compatible canvas: |
| 610 // 1) Verify that secondary canvas is usable and does not report to the noti
fication client. | 675 // 1) Verify that secondary canvas is usable and does not report to the noti
fication client. |
| 611 secondaryCanvas.drawRect(rect, paint); | 676 secondaryCanvas.drawRect(rect, paint); |
| 612 REPORTER_ASSERT(reporter, notificationCounter.fStorageAllocatedChangedCount
== 0); | 677 REPORTER_ASSERT(reporter, notificationCounter.fStorageAllocatedChangedCount
== 0); |
| 613 // 2) Verify that original canvas is usable and still reports to the notific
ation client. | 678 // 2) Verify that original canvas is usable and still reports to the notific
ation client. |
| 614 canvas.drawRect(rect, paint); | 679 canvas->drawRect(rect, paint); |
| 615 REPORTER_ASSERT(reporter, notificationCounter.fStorageAllocatedChangedCount
== 1); | 680 REPORTER_ASSERT(reporter, notificationCounter.fStorageAllocatedChangedCount
== 1); |
| 616 } | 681 } |
| 617 | 682 |
| 618 static void TestDeferredCanvas(skiatest::Reporter* reporter, GrContextFactory* f
actory) { | 683 static void TestDeferredCanvas(skiatest::Reporter* reporter, GrContextFactory* f
actory) { |
| 619 TestDeferredCanvasBitmapAccess(reporter); | 684 TestDeferredCanvasBitmapAccess(reporter); |
| 620 TestDeferredCanvasFlush(reporter); | 685 TestDeferredCanvasFlush(reporter); |
| 621 TestDeferredCanvasFreshFrame(reporter); | 686 TestDeferredCanvasFreshFrame(reporter); |
| 622 TestDeferredCanvasMemoryLimit(reporter); | 687 TestDeferredCanvasMemoryLimit(reporter); |
| 623 TestDeferredCanvasBitmapCaching(reporter); | 688 TestDeferredCanvasBitmapCaching(reporter); |
| 624 TestDeferredCanvasSkip(reporter); | 689 TestDeferredCanvasSkip(reporter); |
| 625 TestDeferredCanvasBitmapShaderNoLeak(reporter); | 690 TestDeferredCanvasBitmapShaderNoLeak(reporter); |
| 626 TestDeferredCanvasBitmapSizeThreshold(reporter); | 691 TestDeferredCanvasBitmapSizeThreshold(reporter); |
| 627 TestDeferredCanvasCreateCompatibleDevice(reporter); | 692 TestDeferredCanvasCreateCompatibleDevice(reporter); |
| 628 TestDeferredCanvasSurface(reporter, NULL); | 693 TestDeferredCanvasSurface(reporter, NULL); |
| 629 TestDeferredCanvasSetSurface(reporter, NULL); | 694 TestDeferredCanvasSetSurface(reporter, NULL); |
| 630 if (NULL != factory) { | 695 if (NULL != factory) { |
| 631 TestDeferredCanvasSurface(reporter, factory); | 696 TestDeferredCanvasSurface(reporter, factory); |
| 632 TestDeferredCanvasSetSurface(reporter, factory); | 697 TestDeferredCanvasSetSurface(reporter, factory); |
| 633 } | 698 } |
| 634 } | 699 } |
| 635 | 700 |
| 636 #include "TestClassDef.h" | 701 #include "TestClassDef.h" |
| 637 DEFINE_GPUTESTCLASS("DeferredCanvas", TestDeferredCanvasClass, TestDeferredCanva
s) | 702 DEFINE_GPUTESTCLASS("DeferredCanvas", TestDeferredCanvasClass, TestDeferredCanva
s) |
| OLD | NEW |