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" |
11 #include "SkDeferredCanvas.h" | 11 #include "SkDeferredCanvas.h" |
12 #include "SkDevice.h" | 12 #include "SkDevice.h" |
13 #include "SkGradientShader.h" | 13 #include "SkGradientShader.h" |
14 #include "SkShader.h" | 14 #include "SkShader.h" |
15 #include "SkSurface.h" | 15 #include "../src/image/SkSurface_Base.h" |
Justin Novosad
2013/08/01 18:48:01
For mocking
| |
16 #include "../src/image/SkImagePriv.h" | |
16 #if SK_SUPPORT_GPU | 17 #if SK_SUPPORT_GPU |
17 #include "GrContextFactory.h" | 18 #include "GrContextFactory.h" |
18 #else | 19 #else |
19 class GrContextFactory; | 20 class GrContextFactory; |
20 #endif | 21 #endif |
21 | 22 |
22 static const int gWidth = 2; | 23 static const int gWidth = 2; |
23 static const int gHeight = 2; | 24 static const int gHeight = 2; |
24 | 25 |
25 static void create(SkBitmap* bm, SkBitmap::Config config, SkColor color) { | 26 static void create(SkBitmap* bm, SkBitmap::Config config, SkColor color) { |
(...skipping 16 matching lines...) Expand all Loading... | |
42 | 43 |
43 canvas->clear(0x00000000); | 44 canvas->clear(0x00000000); |
44 | 45 |
45 SkAutoLockPixels alp(store); | 46 SkAutoLockPixels alp(store); |
46 REPORTER_ASSERT(reporter, store.getColor(0,0) == 0xFFFFFFFF); //verify that clear was deferred | 47 REPORTER_ASSERT(reporter, store.getColor(0,0) == 0xFFFFFFFF); //verify that clear was deferred |
47 SkBitmap accessed = canvas->getDevice()->accessBitmap(false); | 48 SkBitmap accessed = canvas->getDevice()->accessBitmap(false); |
48 REPORTER_ASSERT(reporter, store.getColor(0,0) == 0x00000000); //verify that clear was executed | 49 REPORTER_ASSERT(reporter, store.getColor(0,0) == 0x00000000); //verify that clear was executed |
49 REPORTER_ASSERT(reporter, accessed.pixelRef() == store.pixelRef()); | 50 REPORTER_ASSERT(reporter, accessed.pixelRef() == store.pixelRef()); |
50 } | 51 } |
51 | 52 |
53 class MockSurface : public SkSurface_Base { | |
54 public: | |
55 MockSurface(int width, int height) : SkSurface_Base(width, height) { | |
56 clearCounts(); | |
57 fBitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height); | |
58 fBitmap.allocPixels(); | |
59 } | |
60 | |
61 virtual SkCanvas* onNewCanvas() SK_OVERRIDE { | |
62 return SkNEW_ARGS(SkCanvas, (fBitmap)); | |
63 } | |
64 | |
65 virtual SkSurface* onNewSurface(const SkImage::Info&) SK_OVERRIDE { | |
66 return NULL; | |
67 } | |
68 | |
69 virtual SkImage* onNewImageSnapshot() SK_OVERRIDE { | |
70 return SkNewImageFromBitmap(fBitmap, true); | |
71 } | |
72 | |
73 virtual void onCopyOnWrite(ContentChangeMode mode) SK_OVERRIDE { | |
74 if (mode == SkSurface::kDiscard_ContentChangeMode) { | |
75 fDiscardCount++; | |
76 } else { | |
77 fRetainCount++; | |
78 } | |
79 } | |
80 | |
81 void clearCounts() { | |
82 fDiscardCount = 0; | |
83 fRetainCount = 0; | |
84 } | |
85 | |
86 int fDiscardCount, fRetainCount; | |
87 SkBitmap fBitmap; | |
88 }; | |
89 | |
90 static void TestDeferredCanvasWritePixelsToSurface(skiatest::Reporter* reporter) { | |
91 SkAutoTUnref<MockSurface> surface(SkNEW_ARGS(MockSurface, (10, 10))); | |
92 SkAutoTUnref<SkDeferredCanvas> canvas( | |
93 #if SK_DEFERRED_CANVAS_USES_FACTORIES | |
94 SkDeferredCanvas::Create(surface.get())); | |
95 #else | |
96 SkNEW_ARGS(SkDeferredCanvas, (surface.get()))); | |
97 #endif | |
98 | |
99 SkBitmap srcBitmap; | |
100 srcBitmap.setConfig(SkBitmap::kARGB_8888_Config, 10, 10); | |
101 srcBitmap.allocPixels(); | |
102 srcBitmap.eraseColor(SK_ColorGREEN); | |
103 // Tests below depend on this bitmap being recognized as opaque | |
104 | |
105 // Preliminary sanity check: no copy on write if no active snapshot | |
106 surface->clearCounts(); | |
107 canvas->clear(SK_ColorWHITE); | |
108 REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); | |
109 REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); | |
110 | |
111 surface->clearCounts(); | |
112 canvas->flush(); | |
113 REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); | |
114 REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); | |
115 | |
116 // Case 1: Discard notification happens upon flushing | |
117 // with an Image attached. | |
118 surface->clearCounts(); | |
119 SkAutoTUnref<SkImage> image1(canvas->newImageSnapshot()); | |
120 REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); | |
121 REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); | |
122 | |
123 surface->clearCounts(); | |
124 canvas->clear(SK_ColorWHITE); | |
125 REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); | |
126 REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); | |
127 | |
128 surface->clearCounts(); | |
129 canvas->flush(); | |
130 REPORTER_ASSERT(reporter, 1 == surface->fDiscardCount); | |
131 REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); | |
132 | |
133 // Case 2: Opaque writePixels | |
134 surface->clearCounts(); | |
135 SkAutoTUnref<SkImage> image2(canvas->newImageSnapshot()); | |
136 REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); | |
137 REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); | |
138 | |
139 surface->clearCounts(); | |
140 canvas->writePixels(srcBitmap, 0, 0); | |
141 REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); | |
142 REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); | |
143 | |
144 surface->clearCounts(); | |
145 canvas->flush(); | |
146 REPORTER_ASSERT(reporter, 1 == surface->fDiscardCount); | |
147 REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); | |
148 | |
149 // Case 3: writePixels that partially covers the canvas | |
150 surface->clearCounts(); | |
151 SkAutoTUnref<SkImage> image3(canvas->newImageSnapshot()); | |
152 REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); | |
153 REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); | |
154 | |
155 surface->clearCounts(); | |
156 canvas->writePixels(srcBitmap, 5, 0); | |
157 REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); | |
158 REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); | |
159 | |
160 surface->clearCounts(); | |
161 canvas->flush(); | |
162 REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); | |
163 REPORTER_ASSERT(reporter, 1 == surface->fRetainCount); | |
164 | |
165 // Case 4: unpremultiplied opaque writePixels that entirely | |
166 // covers the canvas | |
167 surface->clearCounts(); | |
168 SkAutoTUnref<SkImage> image4(canvas->newImageSnapshot()); | |
169 REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); | |
170 REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); | |
171 | |
172 surface->clearCounts(); | |
173 canvas->writePixels(srcBitmap, 0, 0, SkCanvas::kRGBA_Unpremul_Config8888); | |
174 REPORTER_ASSERT(reporter, 1 == surface->fDiscardCount); | |
Justin Novosad
2013/08/01 18:48:01
This one failed before the fix
| |
175 REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); | |
176 | |
177 surface->clearCounts(); | |
178 canvas->flush(); | |
179 REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); | |
180 REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); | |
181 | |
182 // Case 5: unpremultiplied opaque writePixels that partially | |
183 // covers the canvas | |
184 surface->clearCounts(); | |
185 SkAutoTUnref<SkImage> image5(canvas->newImageSnapshot()); | |
186 REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); | |
187 REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); | |
188 | |
189 surface->clearCounts(); | |
190 canvas->writePixels(srcBitmap, 5, 0, SkCanvas::kRGBA_Unpremul_Config8888); | |
191 REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); | |
192 REPORTER_ASSERT(reporter, 1 == surface->fRetainCount); | |
Justin Novosad
2013/08/01 18:48:01
This one failed before the fix
| |
193 | |
194 surface->clearCounts(); | |
195 canvas->flush(); | |
196 REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); | |
197 REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); | |
198 | |
199 // Case 6: unpremultiplied opaque writePixels that entirely | |
200 // covers the canvas, preceded by clear | |
201 surface->clearCounts(); | |
202 SkAutoTUnref<SkImage> image6(canvas->newImageSnapshot()); | |
203 REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); | |
204 REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); | |
205 | |
206 surface->clearCounts(); | |
207 canvas->clear(SK_ColorWHITE); | |
208 REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); | |
209 REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); | |
210 | |
211 surface->clearCounts(); | |
212 canvas->writePixels(srcBitmap, 0, 0, SkCanvas::kRGBA_Unpremul_Config8888); | |
213 REPORTER_ASSERT(reporter, 1 == surface->fDiscardCount); | |
214 REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); | |
215 | |
216 surface->clearCounts(); | |
217 canvas->flush(); | |
218 REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); | |
219 REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); | |
220 | |
221 // Case 7: unpremultiplied opaque writePixels that partially | |
222 // covers the canvas, preceeded by a clear | |
223 surface->clearCounts(); | |
224 SkAutoTUnref<SkImage> image7(canvas->newImageSnapshot()); | |
225 REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); | |
226 REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); | |
227 | |
228 surface->clearCounts(); | |
229 canvas->clear(SK_ColorWHITE); | |
230 REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); | |
231 REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); | |
232 | |
233 surface->clearCounts(); | |
234 canvas->writePixels(srcBitmap, 5, 0, SkCanvas::kRGBA_Unpremul_Config8888); | |
235 REPORTER_ASSERT(reporter, 1 == surface->fDiscardCount); // because of the cl ear | |
236 REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); | |
237 | |
238 surface->clearCounts(); | |
239 canvas->flush(); | |
240 REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); | |
241 REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); | |
242 | |
243 // Case 8: unpremultiplied opaque writePixels that partially | |
244 // covers the canvas, preceeded by a drawREct that partially | |
245 // covers the canvas | |
246 surface->clearCounts(); | |
247 SkAutoTUnref<SkImage> image8(canvas->newImageSnapshot()); | |
248 REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); | |
249 REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); | |
250 | |
251 surface->clearCounts(); | |
252 SkPaint paint; | |
253 canvas->drawRect(SkRect::MakeLTRB(0, 0, 5, 5), paint); | |
254 REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); | |
255 REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); | |
256 | |
257 surface->clearCounts(); | |
258 canvas->writePixels(srcBitmap, 5, 0, SkCanvas::kRGBA_Unpremul_Config8888); | |
259 REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); | |
260 REPORTER_ASSERT(reporter, 1 == surface->fRetainCount); | |
261 | |
262 surface->clearCounts(); | |
263 canvas->flush(); | |
264 REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); | |
265 REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); | |
266 } | |
267 | |
52 static void TestDeferredCanvasFlush(skiatest::Reporter* reporter) { | 268 static void TestDeferredCanvasFlush(skiatest::Reporter* reporter) { |
53 SkBitmap store; | 269 SkBitmap store; |
54 | 270 |
55 create(&store, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF); | 271 create(&store, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF); |
56 SkDevice device(store); | 272 SkDevice device(store); |
57 SkAutoTUnref<SkDeferredCanvas> canvas( | 273 SkAutoTUnref<SkDeferredCanvas> canvas( |
58 #if SK_DEFERRED_CANVAS_USES_FACTORIES | 274 #if SK_DEFERRED_CANVAS_USES_FACTORIES |
59 SkDeferredCanvas::Create(&device)); | 275 SkDeferredCanvas::Create(&device)); |
60 #else | 276 #else |
61 SkNEW_ARGS(SkDeferredCanvas, (&device))); | 277 SkNEW_ARGS(SkDeferredCanvas, (&device))); |
(...skipping 620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
682 static void TestDeferredCanvas(skiatest::Reporter* reporter, GrContextFactory* f actory) { | 898 static void TestDeferredCanvas(skiatest::Reporter* reporter, GrContextFactory* f actory) { |
683 TestDeferredCanvasBitmapAccess(reporter); | 899 TestDeferredCanvasBitmapAccess(reporter); |
684 TestDeferredCanvasFlush(reporter); | 900 TestDeferredCanvasFlush(reporter); |
685 TestDeferredCanvasFreshFrame(reporter); | 901 TestDeferredCanvasFreshFrame(reporter); |
686 TestDeferredCanvasMemoryLimit(reporter); | 902 TestDeferredCanvasMemoryLimit(reporter); |
687 TestDeferredCanvasBitmapCaching(reporter); | 903 TestDeferredCanvasBitmapCaching(reporter); |
688 TestDeferredCanvasSkip(reporter); | 904 TestDeferredCanvasSkip(reporter); |
689 TestDeferredCanvasBitmapShaderNoLeak(reporter); | 905 TestDeferredCanvasBitmapShaderNoLeak(reporter); |
690 TestDeferredCanvasBitmapSizeThreshold(reporter); | 906 TestDeferredCanvasBitmapSizeThreshold(reporter); |
691 TestDeferredCanvasCreateCompatibleDevice(reporter); | 907 TestDeferredCanvasCreateCompatibleDevice(reporter); |
908 TestDeferredCanvasWritePixelsToSurface(reporter); | |
692 TestDeferredCanvasSurface(reporter, NULL); | 909 TestDeferredCanvasSurface(reporter, NULL); |
693 TestDeferredCanvasSetSurface(reporter, NULL); | 910 TestDeferredCanvasSetSurface(reporter, NULL); |
694 if (NULL != factory) { | 911 if (NULL != factory) { |
695 TestDeferredCanvasSurface(reporter, factory); | 912 TestDeferredCanvasSurface(reporter, factory); |
696 TestDeferredCanvasSetSurface(reporter, factory); | 913 TestDeferredCanvasSetSurface(reporter, factory); |
697 } | 914 } |
698 } | 915 } |
699 | 916 |
700 #include "TestClassDef.h" | 917 #include "TestClassDef.h" |
701 DEFINE_GPUTESTCLASS("DeferredCanvas", TestDeferredCanvasClass, TestDeferredCanva s) | 918 DEFINE_GPUTESTCLASS("DeferredCanvas", TestDeferredCanvasClass, TestDeferredCanva s) |
OLD | NEW |