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 |