OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "Test.h" | 8 #include "Test.h" |
9 #include "TestClassDef.h" | 9 #include "TestClassDef.h" |
10 #include "SkBitmapDevice.h" | 10 #include "SkBitmapDevice.h" |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 } | 58 } |
59 } | 59 } |
60 | 60 |
61 static void init_paint(SkPaint* paint, const SkBitmap &bm) { | 61 static void init_paint(SkPaint* paint, const SkBitmap &bm) { |
62 SkShader* shader = SkShader::CreateBitmapShader(bm, | 62 SkShader* shader = SkShader::CreateBitmapShader(bm, |
63 SkShader::kClamp_TileMode, | 63 SkShader::kClamp_TileMode, |
64 SkShader::kClamp_TileMode); | 64 SkShader::kClamp_TileMode); |
65 paint->setShader(shader)->unref(); | 65 paint->setShader(shader)->unref(); |
66 } | 66 } |
67 | 67 |
68 typedef void (*DrawBitmapProc)(SkCanvas*, const SkBitmap&, const SkBitmap&, cons
t SkPoint&); | 68 typedef void (*DrawBitmapProc)(SkCanvas*, const SkBitmap&, |
| 69 const SkBitmap&, const SkPoint&, |
| 70 SkTDArray<SkPixelRef*>* usedPixRefs); |
69 | 71 |
70 static void drawpaint_proc(SkCanvas* canvas, const SkBitmap& bm, | 72 static void drawpaint_proc(SkCanvas* canvas, const SkBitmap& bm, |
71 const SkBitmap& altBM, const SkPoint& pos) { | 73 const SkBitmap& altBM, const SkPoint& pos, |
| 74 SkTDArray<SkPixelRef*>* usedPixRefs) { |
72 SkPaint paint; | 75 SkPaint paint; |
73 init_paint(&paint, bm); | 76 init_paint(&paint, bm); |
74 | 77 |
75 canvas->drawPaint(paint); | 78 canvas->drawPaint(paint); |
| 79 *usedPixRefs->append() = bm.pixelRef(); |
76 } | 80 } |
77 | 81 |
78 static void drawpoints_proc(SkCanvas* canvas, const SkBitmap& bm, | 82 static void drawpoints_proc(SkCanvas* canvas, const SkBitmap& bm, |
79 const SkBitmap& altBM, const SkPoint& pos) { | 83 const SkBitmap& altBM, const SkPoint& pos, |
| 84 SkTDArray<SkPixelRef*>* usedPixRefs) { |
80 SkPaint paint; | 85 SkPaint paint; |
81 init_paint(&paint, bm); | 86 init_paint(&paint, bm); |
82 | 87 |
83 // draw a slightly inset rect | 88 // draw a rect |
84 SkPoint points[5] = { | 89 SkPoint points[5] = { |
85 { pos.fX + 1, pos.fY + 1 }, | 90 { pos.fX, pos.fY }, |
86 { pos.fX + bm.width() - 2, pos.fY + 1 }, | 91 { pos.fX + bm.width() - 1, pos.fY }, |
87 { pos.fX + bm.width() - 2, pos.fY + bm.height() - 2 }, | 92 { pos.fX + bm.width() - 1, pos.fY + bm.height() - 1 }, |
88 { pos.fX + 1, pos.fY + bm.height() - 2 }, | 93 { pos.fX, pos.fY + bm.height() - 1 }, |
89 { pos.fX + 1, pos.fY + 1 }, | 94 { pos.fX, pos.fY }, |
90 }; | 95 }; |
91 | 96 |
92 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 5, points, paint); | 97 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 5, points, paint); |
| 98 *usedPixRefs->append() = bm.pixelRef(); |
93 } | 99 } |
94 | 100 |
95 static void drawrect_proc(SkCanvas* canvas, const SkBitmap& bm, | 101 static void drawrect_proc(SkCanvas* canvas, const SkBitmap& bm, |
96 const SkBitmap& altBM, const SkPoint& pos) { | 102 const SkBitmap& altBM, const SkPoint& pos, |
| 103 SkTDArray<SkPixelRef*>* usedPixRefs) { |
97 SkPaint paint; | 104 SkPaint paint; |
98 init_paint(&paint, bm); | 105 init_paint(&paint, bm); |
99 | 106 |
100 SkRect r = { 0, 0, SkIntToScalar(bm.width()), SkIntToScalar(bm.height()) }; | 107 SkRect r = { 0, 0, SkIntToScalar(bm.width()), SkIntToScalar(bm.height()) }; |
101 r.offset(pos.fX, pos.fY); | 108 r.offset(pos.fX, pos.fY); |
102 | 109 |
103 canvas->drawRect(r, paint); | 110 canvas->drawRect(r, paint); |
| 111 *usedPixRefs->append() = bm.pixelRef(); |
104 } | 112 } |
105 | 113 |
106 static void drawoval_proc(SkCanvas* canvas, const SkBitmap& bm, | 114 static void drawoval_proc(SkCanvas* canvas, const SkBitmap& bm, |
107 const SkBitmap& altBM, const SkPoint& pos) { | 115 const SkBitmap& altBM, const SkPoint& pos, |
| 116 SkTDArray<SkPixelRef*>* usedPixRefs) { |
108 SkPaint paint; | 117 SkPaint paint; |
109 init_paint(&paint, bm); | 118 init_paint(&paint, bm); |
110 | 119 |
111 SkRect r = { 0, 0, SkIntToScalar(bm.width()), SkIntToScalar(bm.height()) }; | 120 SkRect r = { 0, 0, SkIntToScalar(bm.width()), SkIntToScalar(bm.height()) }; |
112 r.offset(pos.fX, pos.fY); | 121 r.offset(pos.fX, pos.fY); |
113 | 122 |
114 canvas->drawOval(r, paint); | 123 canvas->drawOval(r, paint); |
| 124 *usedPixRefs->append() = bm.pixelRef(); |
115 } | 125 } |
116 | 126 |
117 static void drawrrect_proc(SkCanvas* canvas, const SkBitmap& bm, | 127 static void drawrrect_proc(SkCanvas* canvas, const SkBitmap& bm, |
118 const SkBitmap& altBM, const SkPoint& pos) { | 128 const SkBitmap& altBM, const SkPoint& pos, |
| 129 SkTDArray<SkPixelRef*>* usedPixRefs) { |
119 SkPaint paint; | 130 SkPaint paint; |
120 init_paint(&paint, bm); | 131 init_paint(&paint, bm); |
121 | 132 |
122 SkRect r = { 0, 0, SkIntToScalar(bm.width()), SkIntToScalar(bm.height()) }; | 133 SkRect r = { 0, 0, SkIntToScalar(bm.width()), SkIntToScalar(bm.height()) }; |
123 r.offset(pos.fX, pos.fY); | 134 r.offset(pos.fX, pos.fY); |
124 | 135 |
125 SkRRect rr; | 136 SkRRect rr; |
126 rr.setRectXY(r, SkIntToScalar(bm.width())/4, SkIntToScalar(bm.height())/4); | 137 rr.setRectXY(r, SkIntToScalar(bm.width())/4, SkIntToScalar(bm.height())/4); |
127 canvas->drawRRect(rr, paint); | 138 canvas->drawRRect(rr, paint); |
| 139 *usedPixRefs->append() = bm.pixelRef(); |
128 } | 140 } |
129 | 141 |
130 static void drawpath_proc(SkCanvas* canvas, const SkBitmap& bm, | 142 static void drawpath_proc(SkCanvas* canvas, const SkBitmap& bm, |
131 const SkBitmap& altBM, const SkPoint& pos) { | 143 const SkBitmap& altBM, const SkPoint& pos, |
| 144 SkTDArray<SkPixelRef*>* usedPixRefs) { |
132 SkPaint paint; | 145 SkPaint paint; |
133 init_paint(&paint, bm); | 146 init_paint(&paint, bm); |
134 | 147 |
135 SkPath path; | 148 SkPath path; |
136 path.lineTo(bm.width()/2.0f, SkIntToScalar(bm.height())); | 149 path.lineTo(bm.width()/2.0f, SkIntToScalar(bm.height())); |
137 path.lineTo(SkIntToScalar(bm.width()), 0); | 150 path.lineTo(SkIntToScalar(bm.width()), 0); |
138 path.close(); | 151 path.close(); |
139 path.offset(pos.fX, pos.fY); | 152 path.offset(pos.fX, pos.fY); |
140 | 153 |
141 canvas->drawPath(path, paint); | 154 canvas->drawPath(path, paint); |
| 155 *usedPixRefs->append() = bm.pixelRef(); |
142 } | 156 } |
143 | 157 |
144 static void drawbitmap_proc(SkCanvas* canvas, const SkBitmap& bm, | 158 static void drawbitmap_proc(SkCanvas* canvas, const SkBitmap& bm, |
145 const SkBitmap& altBM, const SkPoint& pos) { | 159 const SkBitmap& altBM, const SkPoint& pos, |
| 160 SkTDArray<SkPixelRef*>* usedPixRefs) { |
146 canvas->drawBitmap(bm, pos.fX, pos.fY, NULL); | 161 canvas->drawBitmap(bm, pos.fX, pos.fY, NULL); |
| 162 *usedPixRefs->append() = bm.pixelRef(); |
147 } | 163 } |
148 | 164 |
149 static void drawbitmap_withshader_proc(SkCanvas* canvas, const SkBitmap& bm, | 165 static void drawbitmap_withshader_proc(SkCanvas* canvas, const SkBitmap& bm, |
150 const SkBitmap& altBM, const SkPoint& pos
) { | 166 const SkBitmap& altBM, const SkPoint& pos
, |
| 167 SkTDArray<SkPixelRef*>* usedPixRefs) { |
151 SkPaint paint; | 168 SkPaint paint; |
152 init_paint(&paint, bm); | 169 init_paint(&paint, bm); |
153 | 170 |
154 // The bitmap in the paint is ignored unless we're drawing an A8 bitmap | 171 // The bitmap in the paint is ignored unless we're drawing an A8 bitmap |
155 canvas->drawBitmap(altBM, pos.fX, pos.fY, &paint); | 172 canvas->drawBitmap(altBM, pos.fX, pos.fY, &paint); |
| 173 *usedPixRefs->append() = bm.pixelRef(); |
| 174 *usedPixRefs->append() = altBM.pixelRef(); |
156 } | 175 } |
157 | 176 |
158 static void drawsprite_proc(SkCanvas* canvas, const SkBitmap& bm, | 177 static void drawsprite_proc(SkCanvas* canvas, const SkBitmap& bm, |
159 const SkBitmap& altBM, const SkPoint& pos) { | 178 const SkBitmap& altBM, const SkPoint& pos, |
| 179 SkTDArray<SkPixelRef*>* usedPixRefs) { |
160 const SkMatrix& ctm = canvas->getTotalMatrix(); | 180 const SkMatrix& ctm = canvas->getTotalMatrix(); |
161 | 181 |
162 SkPoint p(pos); | 182 SkPoint p(pos); |
163 ctm.mapPoints(&p, 1); | 183 ctm.mapPoints(&p, 1); |
164 | 184 |
165 canvas->drawSprite(bm, (int)p.fX, (int)p.fY, NULL); | 185 canvas->drawSprite(bm, (int)p.fX, (int)p.fY, NULL); |
| 186 *usedPixRefs->append() = bm.pixelRef(); |
166 } | 187 } |
167 | 188 |
168 #if 0 | 189 #if 0 |
169 // Although specifiable, this case doesn't seem to make sense (i.e., the | 190 // Although specifiable, this case doesn't seem to make sense (i.e., the |
170 // bitmap in the shader is never used). | 191 // bitmap in the shader is never used). |
171 static void drawsprite_withshader_proc(SkCanvas* canvas, const SkBitmap& bm, | 192 static void drawsprite_withshader_proc(SkCanvas* canvas, const SkBitmap& bm, |
172 const SkBitmap& altBM, const SkPoint& pos
) { | 193 const SkBitmap& altBM, const SkPoint& pos
, |
| 194 SkTDArray<SkPixelRef*>* usedPixRefs) { |
173 SkPaint paint; | 195 SkPaint paint; |
174 init_paint(&paint, bm); | 196 init_paint(&paint, bm); |
175 | 197 |
176 const SkMatrix& ctm = canvas->getTotalMatrix(); | 198 const SkMatrix& ctm = canvas->getTotalMatrix(); |
177 | 199 |
178 SkPoint p(pos); | 200 SkPoint p(pos); |
179 ctm.mapPoints(&p, 1); | 201 ctm.mapPoints(&p, 1); |
180 | 202 |
181 canvas->drawSprite(altBM, (int)p.fX, (int)p.fY, &paint); | 203 canvas->drawSprite(altBM, (int)p.fX, (int)p.fY, &paint); |
| 204 *usedPixRefs->append() = bm.pixelRef(); |
| 205 *usedPixRefs->append() = altBM.pixelRef(); |
182 } | 206 } |
183 #endif | 207 #endif |
184 | 208 |
185 static void drawbitmaprect_proc(SkCanvas* canvas, const SkBitmap& bm, | 209 static void drawbitmaprect_proc(SkCanvas* canvas, const SkBitmap& bm, |
186 const SkBitmap& altBM, const SkPoint& pos) { | 210 const SkBitmap& altBM, const SkPoint& pos, |
| 211 SkTDArray<SkPixelRef*>* usedPixRefs) { |
187 SkRect r = { 0, 0, SkIntToScalar(bm.width()), SkIntToScalar(bm.height()) }; | 212 SkRect r = { 0, 0, SkIntToScalar(bm.width()), SkIntToScalar(bm.height()) }; |
188 | 213 |
189 r.offset(pos.fX, pos.fY); | 214 r.offset(pos.fX, pos.fY); |
190 canvas->drawBitmapRectToRect(bm, NULL, r, NULL); | 215 canvas->drawBitmapRectToRect(bm, NULL, r, NULL); |
| 216 *usedPixRefs->append() = bm.pixelRef(); |
191 } | 217 } |
192 | 218 |
193 static void drawbitmaprect_withshader_proc(SkCanvas* canvas, | 219 static void drawbitmaprect_withshader_proc(SkCanvas* canvas, |
194 const SkBitmap& bm, | 220 const SkBitmap& bm, |
195 const SkBitmap& altBM, | 221 const SkBitmap& altBM, |
196 const SkPoint& pos) { | 222 const SkPoint& pos, |
| 223 SkTDArray<SkPixelRef*>* usedPixRefs)
{ |
197 SkPaint paint; | 224 SkPaint paint; |
198 init_paint(&paint, bm); | 225 init_paint(&paint, bm); |
199 | 226 |
200 SkRect r = { 0, 0, SkIntToScalar(bm.width()), SkIntToScalar(bm.height()) }; | 227 SkRect r = { 0, 0, SkIntToScalar(bm.width()), SkIntToScalar(bm.height()) }; |
201 r.offset(pos.fX, pos.fY); | 228 r.offset(pos.fX, pos.fY); |
202 | 229 |
203 // The bitmap in the paint is ignored unless we're drawing an A8 bitmap | 230 // The bitmap in the paint is ignored unless we're drawing an A8 bitmap |
204 canvas->drawBitmapRectToRect(altBM, NULL, r, &paint); | 231 canvas->drawBitmapRectToRect(altBM, NULL, r, &paint); |
| 232 *usedPixRefs->append() = bm.pixelRef(); |
| 233 *usedPixRefs->append() = altBM.pixelRef(); |
205 } | 234 } |
206 | 235 |
207 static void drawtext_proc(SkCanvas* canvas, const SkBitmap& bm, | 236 static void drawtext_proc(SkCanvas* canvas, const SkBitmap& bm, |
208 const SkBitmap& altBM, const SkPoint& pos) { | 237 const SkBitmap& altBM, const SkPoint& pos, |
| 238 SkTDArray<SkPixelRef*>* usedPixRefs) { |
209 SkPaint paint; | 239 SkPaint paint; |
210 init_paint(&paint, bm); | 240 init_paint(&paint, bm); |
211 paint.setTextSize(SkIntToScalar(1.5*bm.width())); | 241 paint.setTextSize(SkIntToScalar(1.5*bm.width())); |
212 | 242 |
213 canvas->drawText("0", 1, pos.fX, pos.fY+bm.width(), paint); | 243 canvas->drawText("0", 1, pos.fX, pos.fY+bm.width(), paint); |
| 244 *usedPixRefs->append() = bm.pixelRef(); |
214 } | 245 } |
215 | 246 |
216 static void drawpostext_proc(SkCanvas* canvas, const SkBitmap& bm, | 247 static void drawpostext_proc(SkCanvas* canvas, const SkBitmap& bm, |
217 const SkBitmap& altBM, const SkPoint& pos) { | 248 const SkBitmap& altBM, const SkPoint& pos, |
| 249 SkTDArray<SkPixelRef*>* usedPixRefs) { |
218 SkPaint paint; | 250 SkPaint paint; |
219 init_paint(&paint, bm); | 251 init_paint(&paint, bm); |
220 paint.setTextSize(SkIntToScalar(1.5*bm.width())); | 252 paint.setTextSize(SkIntToScalar(1.5*bm.width())); |
221 | 253 |
222 SkPoint point = { pos.fX, pos.fY + bm.height() }; | 254 SkPoint point = { pos.fX, pos.fY + bm.height() }; |
223 canvas->drawPosText("O", 1, &point, paint); | 255 canvas->drawPosText("O", 1, &point, paint); |
| 256 *usedPixRefs->append() = bm.pixelRef(); |
224 } | 257 } |
225 | 258 |
226 static void drawtextonpath_proc(SkCanvas* canvas, const SkBitmap& bm, | 259 static void drawtextonpath_proc(SkCanvas* canvas, const SkBitmap& bm, |
227 const SkBitmap& altBM, const SkPoint& pos) { | 260 const SkBitmap& altBM, const SkPoint& pos, |
| 261 SkTDArray<SkPixelRef*>* usedPixRefs) { |
228 SkPaint paint; | 262 SkPaint paint; |
229 | 263 |
230 init_paint(&paint, bm); | 264 init_paint(&paint, bm); |
231 paint.setTextSize(SkIntToScalar(1.5*bm.width())); | 265 paint.setTextSize(SkIntToScalar(1.5*bm.width())); |
232 | 266 |
233 SkPath path; | 267 SkPath path; |
234 path.lineTo(SkIntToScalar(bm.width()), 0); | 268 path.lineTo(SkIntToScalar(bm.width()), 0); |
235 path.offset(pos.fX, pos.fY+bm.height()); | 269 path.offset(pos.fX, pos.fY+bm.height()); |
236 | 270 |
237 canvas->drawTextOnPath("O", 1, path, NULL, paint); | 271 canvas->drawTextOnPath("O", 1, path, NULL, paint); |
| 272 *usedPixRefs->append() = bm.pixelRef(); |
238 } | 273 } |
239 | 274 |
240 static void drawverts_proc(SkCanvas* canvas, const SkBitmap& bm, | 275 static void drawverts_proc(SkCanvas* canvas, const SkBitmap& bm, |
241 const SkBitmap& altBM, const SkPoint& pos) { | 276 const SkBitmap& altBM, const SkPoint& pos, |
| 277 SkTDArray<SkPixelRef*>* usedPixRefs) { |
242 SkPaint paint; | 278 SkPaint paint; |
243 init_paint(&paint, bm); | 279 init_paint(&paint, bm); |
244 | 280 |
245 SkPoint verts[4] = { | 281 SkPoint verts[4] = { |
246 { pos.fX+1, pos.fY+1 }, | 282 { pos.fX, pos.fY }, |
247 { pos.fX + bm.width()-1, pos.fY+1 }, | 283 { pos.fX + bm.width(), pos.fY }, |
248 { pos.fX + bm.width()-1, pos.fY + bm.height()-1 }, | 284 { pos.fX + bm.width(), pos.fY + bm.height() }, |
249 { pos.fX+1, pos.fY + bm.height()-1 } | 285 { pos.fX, pos.fY + bm.height() } |
250 }; | 286 }; |
251 SkPoint texs[4] = { { 0, 0 }, | 287 SkPoint texs[4] = { { 0, 0 }, |
252 { SkIntToScalar(bm.width()), 0 }, | 288 { SkIntToScalar(bm.width()), 0 }, |
253 { SkIntToScalar(bm.width()), SkIntToScalar(bm.height())
}, | 289 { SkIntToScalar(bm.width()), SkIntToScalar(bm.height())
}, |
254 { 0, SkIntToScalar(bm.height()) } }; | 290 { 0, SkIntToScalar(bm.height()) } }; |
255 uint16_t indices[6] = { 0, 1, 2, 0, 2, 3 }; | 291 uint16_t indices[6] = { 0, 1, 2, 0, 2, 3 }; |
256 | 292 |
257 canvas->drawVertices(SkCanvas::kTriangles_VertexMode, 4, verts, texs, NULL,
NULL, | 293 canvas->drawVertices(SkCanvas::kTriangles_VertexMode, 4, verts, texs, NULL,
NULL, |
258 indices, 6, paint); | 294 indices, 6, paint); |
| 295 *usedPixRefs->append() = bm.pixelRef(); |
259 } | 296 } |
260 | 297 |
261 // Return a picture with the bitmaps drawn at the specified positions. | 298 // Return a picture with the bitmaps drawn at the specified positions. |
262 static SkPicture* record_bitmaps(const SkBitmap bm[], const SkPoint pos[], | 299 static SkPicture* record_bitmaps(const SkBitmap bm[], |
263 int count, DrawBitmapProc proc) { | 300 const SkPoint pos[], |
| 301 SkTDArray<SkPixelRef*> analytic[], |
| 302 int count, |
| 303 DrawBitmapProc proc) { |
264 SkPicture* pic = new SkPicture; | 304 SkPicture* pic = new SkPicture; |
265 SkCanvas* canvas = pic->beginRecording(1000, 1000); | 305 SkCanvas* canvas = pic->beginRecording(1000, 1000); |
266 for (int i = 0; i < count; ++i) { | 306 for (int i = 0; i < count; ++i) { |
| 307 analytic[i].rewind(); |
267 canvas->save(); | 308 canvas->save(); |
268 SkRect clipRect = SkRect::MakeXYWH(pos[i].fX, pos[i].fY, | 309 SkRect clipRect = SkRect::MakeXYWH(pos[i].fX, pos[i].fY, |
269 SkIntToScalar(bm[i].width()), | 310 SkIntToScalar(bm[i].width()), |
270 SkIntToScalar(bm[i].height())); | 311 SkIntToScalar(bm[i].height())); |
271 canvas->clipRect(clipRect, SkRegion::kIntersect_Op); | 312 canvas->clipRect(clipRect, SkRegion::kIntersect_Op); |
272 proc(canvas, bm[i], bm[count+i], pos[i]); | 313 proc(canvas, bm[i], bm[count+i], pos[i], &analytic[i]); |
273 canvas->restore(); | 314 canvas->restore(); |
274 } | 315 } |
275 pic->endRecording(); | 316 pic->endRecording(); |
276 return pic; | 317 return pic; |
277 } | 318 } |
278 | 319 |
279 static void rand_rect(SkRect* rect, SkRandom& rand, SkScalar W, SkScalar H) { | 320 static void rand_rect(SkRect* rect, SkRandom& rand, SkScalar W, SkScalar H) { |
280 rect->fLeft = rand.nextRangeScalar(-W, 2*W); | 321 rect->fLeft = rand.nextRangeScalar(-W, 2*W); |
281 rect->fTop = rand.nextRangeScalar(-H, 2*H); | 322 rect->fTop = rand.nextRangeScalar(-H, 2*H); |
282 rect->fRight = rect->fLeft + rand.nextRangeScalar(0, W); | 323 rect->fRight = rect->fLeft + rand.nextRangeScalar(0, W); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
356 } | 397 } |
357 } | 398 } |
358 | 399 |
359 for (int i = 0; i < count; ++i) { | 400 for (int i = 0; i < count; ++i) { |
360 if (bitarray & (1 << i)) { | 401 if (bitarray & (1 << i)) { |
361 *array->append() = refs[i]; | 402 *array->append() = refs[i]; |
362 } | 403 } |
363 } | 404 } |
364 } | 405 } |
365 | 406 |
366 static void test_gatherpixelrefs(skiatest::Reporter* reporter) { | 407 void gather_from_analytic(const SkPoint pos[], SkScalar w, SkScalar h, |
367 const int IW = 32; | 408 const SkTDArray<SkPixelRef*> analytic[], |
368 const int IH = IW; | 409 int count, |
369 const SkScalar W = SkIntToScalar(IW); | 410 SkTDArray<SkPixelRef*>* result, |
370 const SkScalar H = W; | 411 const SkRect& subset) { |
| 412 for (int i = 0; i < count; ++i) { |
| 413 SkRect rect = SkRect::MakeXYWH(pos[i].fX, pos[i].fY, w, h); |
371 | 414 |
372 static const int N = 4; | 415 if (SkRect::Intersects(subset, rect)) { |
373 SkBitmap bm[2*N]; | 416 result->append(analytic[i].count(), analytic[i].begin()); |
374 SkPixelRef* refs[2*N]; | 417 } |
| 418 } |
| 419 } |
375 | 420 |
376 const SkPoint pos[N] = { | 421 static const DrawBitmapProc gProcs[] = { |
377 { 0, 0 }, { W, 0 }, { 0, H }, { W, H } | 422 drawpaint_proc, |
378 }; | 423 drawpoints_proc, |
| 424 drawrect_proc, |
| 425 drawoval_proc, |
| 426 drawrrect_proc, |
| 427 drawpath_proc, |
| 428 drawbitmap_proc, |
| 429 drawbitmap_withshader_proc, |
| 430 drawsprite_proc, |
| 431 #if 0 |
| 432 drawsprite_withshader_proc, |
| 433 #endif |
| 434 drawbitmaprect_proc, |
| 435 drawbitmaprect_withshader_proc, |
| 436 drawtext_proc, |
| 437 drawpostext_proc, |
| 438 drawtextonpath_proc, |
| 439 drawverts_proc, |
| 440 }; |
379 | 441 |
| 442 static void create_textures(SkBitmap* bm, SkPixelRef** refs, int num, int w, int
h) { |
380 // Our convention is that the color components contain an encoding of | 443 // Our convention is that the color components contain an encoding of |
381 // the index of their corresponding bitmap/pixelref. (0,0,0,0) is | 444 // the index of their corresponding bitmap/pixelref. (0,0,0,0) is |
382 // reserved for the background | 445 // reserved for the background |
383 for (int i = 0; i < N; ++i) { | 446 for (int i = 0; i < num; ++i) { |
384 make_bm(&bm[i], IW, IH, | 447 make_bm(&bm[i], w, h, |
385 SkColorSetARGB(0xFF, | 448 SkColorSetARGB(0xFF, |
386 gColorScale*i+gColorOffset, | 449 gColorScale*i+gColorOffset, |
387 gColorScale*i+gColorOffset, | 450 gColorScale*i+gColorOffset, |
388 gColorScale*i+gColorOffset), | 451 gColorScale*i+gColorOffset), |
389 true); | 452 true); |
390 refs[i] = bm[i].pixelRef(); | 453 refs[i] = bm[i].pixelRef(); |
391 } | 454 } |
392 | 455 |
393 // The A8 alternate bitmaps are all BW checkerboards | 456 // The A8 alternate bitmaps are all BW checkerboards |
394 for (int i = 0; i < N; ++i) { | 457 for (int i = 0; i < num; ++i) { |
395 make_checkerboard(&bm[N+i], IW, IH, true); | 458 make_checkerboard(&bm[num+i], w, h, true); |
396 refs[N+i] = bm[N+i].pixelRef(); | 459 refs[num+i] = bm[num+i].pixelRef(); |
397 } | 460 } |
| 461 } |
398 | 462 |
399 static const DrawBitmapProc procs[] = { | 463 static void test_gatherpixelrefs(skiatest::Reporter* reporter) { |
400 drawpaint_proc, | 464 const int IW = 32; |
401 drawpoints_proc, | 465 const int IH = IW; |
402 drawrect_proc, | 466 const SkScalar W = SkIntToScalar(IW); |
403 drawoval_proc, | 467 const SkScalar H = W; |
404 drawrrect_proc, | 468 |
405 drawpath_proc, | 469 static const int N = 4; |
406 drawbitmap_proc, | 470 SkBitmap bm[2*N]; |
407 drawbitmap_withshader_proc, | 471 SkPixelRef* refs[2*N]; |
408 drawsprite_proc, | 472 SkTDArray<SkPixelRef*> analytic[N]; |
409 #if 0 | 473 |
410 drawsprite_withshader_proc, | 474 const SkPoint pos[N] = { |
411 #endif | 475 { 0, 0 }, { W, 0 }, { 0, H }, { W, H } |
412 drawbitmaprect_proc, | |
413 drawbitmaprect_withshader_proc, | |
414 drawtext_proc, | |
415 drawpostext_proc, | |
416 drawtextonpath_proc, | |
417 drawverts_proc, | |
418 }; | 476 }; |
419 | 477 |
| 478 create_textures(bm, refs, N, IW, IH); |
| 479 |
420 SkRandom rand; | 480 SkRandom rand; |
421 for (size_t k = 0; k < SK_ARRAY_COUNT(procs); ++k) { | 481 for (size_t k = 0; k < SK_ARRAY_COUNT(gProcs); ++k) { |
422 SkAutoTUnref<SkPicture> pic(record_bitmaps(bm, pos, N, procs[k])); | 482 SkAutoTUnref<SkPicture> pic(record_bitmaps(bm, pos, analytic, N, gProcs[
k])); |
423 | 483 |
424 REPORTER_ASSERT(reporter, pic->willPlayBackBitmaps() || N == 0); | 484 REPORTER_ASSERT(reporter, pic->willPlayBackBitmaps() || N == 0); |
425 // quick check for a small piece of each quadrant, which should just | 485 // quick check for a small piece of each quadrant, which should just |
426 // contain 1 bitmap. | 486 // contain 1 or 2 bitmaps. |
427 for (size_t i = 0; i < SK_ARRAY_COUNT(pos); ++i) { | 487 for (size_t i = 0; i < SK_ARRAY_COUNT(pos); ++i) { |
428 SkRect r; | 488 SkRect r; |
429 r.set(2, 2, W - 2, H - 2); | 489 r.set(2, 2, W - 2, H - 2); |
430 r.offset(pos[i].fX, pos[i].fY); | 490 r.offset(pos[i].fX, pos[i].fY); |
431 SkAutoDataUnref data(SkPictureUtils::GatherPixelRefs(pic, r)); | 491 SkAutoDataUnref data(SkPictureUtils::GatherPixelRefs(pic, r)); |
432 REPORTER_ASSERT(reporter, data); | 492 REPORTER_ASSERT(reporter, data); |
433 if (data) { | 493 if (data) { |
434 SkPixelRef** gatheredRefs = (SkPixelRef**)data->data(); | 494 SkPixelRef** gatheredRefs = (SkPixelRef**)data->data(); |
435 int count = static_cast<int>(data->size() / sizeof(SkPixelRef*))
; | 495 int count = static_cast<int>(data->size() / sizeof(SkPixelRef*))
; |
436 REPORTER_ASSERT(reporter, 1 == count || 2 == count); | 496 REPORTER_ASSERT(reporter, 1 == count || 2 == count); |
437 if (1 == count) { | 497 if (1 == count) { |
438 REPORTER_ASSERT(reporter, gatheredRefs[0] == refs[i]); | 498 REPORTER_ASSERT(reporter, gatheredRefs[0] == refs[i]); |
439 } else if (2 == count) { | 499 } else if (2 == count) { |
440 REPORTER_ASSERT(reporter, | 500 REPORTER_ASSERT(reporter, |
441 (gatheredRefs[0] == refs[i] && gatheredRefs[1] == refs[i
+N]) || | 501 (gatheredRefs[0] == refs[i] && gatheredRefs[1] == refs[i
+N]) || |
442 (gatheredRefs[1] == refs[i] && gatheredRefs[0] == refs[i
+N])); | 502 (gatheredRefs[1] == refs[i] && gatheredRefs[0] == refs[i
+N])); |
443 } | 503 } |
444 } | 504 } |
445 } | 505 } |
446 | 506 |
447 SkBitmap image; | 507 SkBitmap image; |
448 draw(pic, 2*IW, 2*IH, &image); | 508 draw(pic, 2*IW, 2*IH, &image); |
449 | 509 |
450 // Test a bunch of random (mostly) rects, and compare the gather results | 510 // Test a bunch of random (mostly) rects, and compare the gather results |
451 // with a deduced list of refs by looking at the colors drawn. | 511 // with a deduced list of refs by looking at the colors drawn. |
452 for (int j = 0; j < 100; ++j) { | 512 for (int j = 0; j < 100; ++j) { |
453 SkRect r; | 513 SkRect r; |
454 rand_rect(&r, rand, 2*W, 2*H); | 514 rand_rect(&r, rand, 2*W, 2*H); |
455 | 515 |
456 SkTDArray<SkPixelRef*> array; | 516 SkTDArray<SkPixelRef*> fromImage; |
| 517 gather_from_image(image, refs, N, &fromImage, r); |
| 518 |
| 519 SkTDArray<SkPixelRef*> fromAnalytic; |
| 520 gather_from_analytic(pos, W, H, analytic, N, &fromAnalytic, r); |
457 | 521 |
458 SkData* data = SkPictureUtils::GatherPixelRefs(pic, r); | 522 SkData* data = SkPictureUtils::GatherPixelRefs(pic, r); |
459 size_t dataSize = data ? data->size() : 0; | 523 size_t dataSize = data ? data->size() : 0; |
460 int gatherCount = static_cast<int>(dataSize / sizeof(SkPixelRef*)); | 524 int gatherCount = static_cast<int>(dataSize / sizeof(SkPixelRef*)); |
461 SkASSERT(gatherCount * sizeof(SkPixelRef*) == dataSize); | 525 SkASSERT(gatherCount * sizeof(SkPixelRef*) == dataSize); |
462 SkPixelRef** gatherRefs = data ? (SkPixelRef**)(data->data()) : NULL
; | 526 SkPixelRef** gatherRefs = data ? (SkPixelRef**)(data->data()) : NULL
; |
463 SkAutoDataUnref adu(data); | 527 SkAutoDataUnref adu(data); |
464 | 528 |
465 gather_from_image(image, refs, N, &array, r); | 529 // Everything that we saw drawn should appear in the analytic list |
| 530 // but the analytic list may contain some pixelRefs that were not |
| 531 // seen in the image (e.g., A8 textures used as masks) |
| 532 for (int i = 0; i < fromImage.count(); ++i) { |
| 533 REPORTER_ASSERT(reporter, -1 != fromAnalytic.find(fromImage[i]))
; |
| 534 } |
466 | 535 |
467 /* | 536 /* |
468 * GatherPixelRefs is conservative, so it can return more bitmaps | 537 * GatherPixelRefs is conservative, so it can return more bitmaps |
469 * that we actually can see (usually because of conservative bounds | 538 * than are strictly required. Thus our check here is only that |
470 * inflation for antialiasing). Thus our check here is only that | 539 * Gather didn't miss any that we actually needed. Even that isn't |
471 * Gather didn't miss any that we actually saw. Even that isn't | |
472 * a strict requirement on Gather, which is meant to be quick and | 540 * a strict requirement on Gather, which is meant to be quick and |
473 * only mostly-correct, but at the moment this test should work. | 541 * only mostly-correct, but at the moment this test should work. |
474 */ | 542 */ |
475 for (int i = 0; i < array.count(); ++i) { | 543 for (int i = 0; i < fromAnalytic.count(); ++i) { |
476 bool found = find(gatherRefs, array[i], gatherCount); | 544 bool found = find(gatherRefs, fromAnalytic[i], gatherCount); |
477 REPORTER_ASSERT(reporter, found); | 545 REPORTER_ASSERT(reporter, found); |
478 #if 0 | 546 #if 0 |
479 // enable this block of code to debug failures, as it will rerun | 547 // enable this block of code to debug failures, as it will rerun |
480 // the case that failed. | 548 // the case that failed. |
481 if (!found) { | 549 if (!found) { |
482 SkData* data = SkPictureUtils::GatherPixelRefs(pic, r); | 550 SkData* data = SkPictureUtils::GatherPixelRefs(pic, r); |
483 size_t dataSize = data ? data->size() : 0; | 551 size_t dataSize = data ? data->size() : 0; |
484 } | 552 } |
485 #endif | 553 #endif |
486 } | 554 } |
487 } | 555 } |
488 } | 556 } |
489 } | 557 } |
490 | 558 |
| 559 static void test_gatherpixelrefsandrects(skiatest::Reporter* reporter) { |
| 560 const int IW = 32; |
| 561 const int IH = IW; |
| 562 const SkScalar W = SkIntToScalar(IW); |
| 563 const SkScalar H = W; |
| 564 |
| 565 static const int N = 4; |
| 566 SkBitmap bm[2*N]; |
| 567 SkPixelRef* refs[2*N]; |
| 568 SkTDArray<SkPixelRef*> analytic[N]; |
| 569 |
| 570 const SkPoint pos[N] = { |
| 571 { 0, 0 }, { W, 0 }, { 0, H }, { W, H } |
| 572 }; |
| 573 |
| 574 create_textures(bm, refs, N, IW, IH); |
| 575 |
| 576 SkRandom rand; |
| 577 for (size_t k = 0; k < SK_ARRAY_COUNT(gProcs); ++k) { |
| 578 SkAutoTUnref<SkPicture> pic(record_bitmaps(bm, pos, analytic, N, gProcs[
k])); |
| 579 |
| 580 REPORTER_ASSERT(reporter, pic->willPlayBackBitmaps() || N == 0); |
| 581 |
| 582 SkAutoTUnref<SkPictureUtils::SkPixelRefContainer> prCont( |
| 583 new SkPictureUtils::SkPixelRefsAndRectsList); |
| 584 |
| 585 SkPictureUtils::GatherPixelRefsAndRects(pic, prCont); |
| 586 |
| 587 // quick check for a small piece of each quadrant, which should just |
| 588 // contain 1 or 2 bitmaps. |
| 589 for (size_t i = 0; i < SK_ARRAY_COUNT(pos); ++i) { |
| 590 SkRect r; |
| 591 r.set(2, 2, W - 2, H - 2); |
| 592 r.offset(pos[i].fX, pos[i].fY); |
| 593 |
| 594 SkTDArray<SkPixelRef*> gatheredRefs; |
| 595 prCont->query(r, &gatheredRefs); |
| 596 |
| 597 int count = gatheredRefs.count(); |
| 598 REPORTER_ASSERT(reporter, 1 == count || 2 == count); |
| 599 if (1 == count) { |
| 600 REPORTER_ASSERT(reporter, gatheredRefs[0] == refs[i]); |
| 601 } else if (2 == count) { |
| 602 REPORTER_ASSERT(reporter, |
| 603 (gatheredRefs[0] == refs[i] && gatheredRefs[1] == refs[i+N])
|| |
| 604 (gatheredRefs[1] == refs[i] && gatheredRefs[0] == refs[i+N])
); |
| 605 } |
| 606 } |
| 607 |
| 608 SkBitmap image; |
| 609 draw(pic, 2*IW, 2*IH, &image); |
| 610 |
| 611 // Test a bunch of random (mostly) rects, and compare the gather results |
| 612 // with the analytic results and the pixel refs seen in a rendering. |
| 613 for (int j = 0; j < 100; ++j) { |
| 614 SkRect r; |
| 615 rand_rect(&r, rand, 2*W, 2*H); |
| 616 |
| 617 SkTDArray<SkPixelRef*> fromImage; |
| 618 gather_from_image(image, refs, N, &fromImage, r); |
| 619 |
| 620 SkTDArray<SkPixelRef*> fromAnalytic; |
| 621 gather_from_analytic(pos, W, H, analytic, N, &fromAnalytic, r); |
| 622 |
| 623 SkTDArray<SkPixelRef*> gatheredRefs; |
| 624 prCont->query(r, &gatheredRefs); |
| 625 |
| 626 // Everything that we saw drawn should appear in the analytic list |
| 627 // but the analytic list may contain some pixelRefs that were not |
| 628 // seen in the image (e.g., A8 textures used as masks) |
| 629 for (int i = 0; i < fromImage.count(); ++i) { |
| 630 REPORTER_ASSERT(reporter, -1 != fromAnalytic.find(fromImage[i]))
; |
| 631 } |
| 632 |
| 633 // Everything in the analytic list should appear in the gathered |
| 634 // list. |
| 635 for (int i = 0; i < fromAnalytic.count(); ++i) { |
| 636 REPORTER_ASSERT(reporter, -1 != gatheredRefs.find(fromAnalytic[i
])); |
| 637 } |
| 638 } |
| 639 } |
| 640 } |
| 641 |
491 #ifdef SK_DEBUG | 642 #ifdef SK_DEBUG |
492 // Ensure that deleting SkPicturePlayback does not assert. Asserts only fire in
debug mode, so only | 643 // Ensure that deleting SkPicturePlayback does not assert. Asserts only fire in
debug mode, so only |
493 // run in debug mode. | 644 // run in debug mode. |
494 static void test_deleting_empty_playback() { | 645 static void test_deleting_empty_playback() { |
495 SkPicture picture; | 646 SkPicture picture; |
496 // Creates an SkPictureRecord | 647 // Creates an SkPictureRecord |
497 picture.beginRecording(0, 0); | 648 picture.beginRecording(0, 0); |
498 // Turns that into an SkPicturePlayback | 649 // Turns that into an SkPicturePlayback |
499 picture.endRecording(); | 650 picture.endRecording(); |
500 // Deletes the old SkPicturePlayback, and creates a new SkPictureRecord | 651 // Deletes the old SkPicturePlayback, and creates a new SkPictureRecord |
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
868 | 1019 |
869 DEF_TEST(Picture, reporter) { | 1020 DEF_TEST(Picture, reporter) { |
870 #ifdef SK_DEBUG | 1021 #ifdef SK_DEBUG |
871 test_deleting_empty_playback(); | 1022 test_deleting_empty_playback(); |
872 test_serializing_empty_picture(); | 1023 test_serializing_empty_picture(); |
873 #else | 1024 #else |
874 test_bad_bitmap(); | 1025 test_bad_bitmap(); |
875 #endif | 1026 #endif |
876 test_peephole(); | 1027 test_peephole(); |
877 test_gatherpixelrefs(reporter); | 1028 test_gatherpixelrefs(reporter); |
| 1029 test_gatherpixelrefsandrects(reporter); |
878 test_bitmap_with_encoded_data(reporter); | 1030 test_bitmap_with_encoded_data(reporter); |
879 test_clone_empty(reporter); | 1031 test_clone_empty(reporter); |
880 test_clip_bound_opt(reporter); | 1032 test_clip_bound_opt(reporter); |
881 test_clip_expansion(reporter); | 1033 test_clip_expansion(reporter); |
882 test_hierarchical(reporter); | 1034 test_hierarchical(reporter); |
883 } | 1035 } |
OLD | NEW |