Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(142)

Side by Side Diff: tests/PictureTest.cpp

Issue 869463002: remove (unused) GatherPixelRefs (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/utils/SkPictureUtils.cpp ('k') | tools/PictureRenderer.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "SkBBoxHierarchy.h" 8 #include "SkBBoxHierarchy.h"
9 #include "SkBlurImageFilter.h" 9 #include "SkBlurImageFilter.h"
10 #include "SkCanvas.h" 10 #include "SkCanvas.h"
(...skipping 20 matching lines...) Expand all
31 31
32 #if SK_SUPPORT_GPU 32 #if SK_SUPPORT_GPU
33 #include "SkSurface.h" 33 #include "SkSurface.h"
34 #include "GrContextFactory.h" 34 #include "GrContextFactory.h"
35 #endif 35 #endif
36 #include "Test.h" 36 #include "Test.h"
37 37
38 #include "SkLumaColorFilter.h" 38 #include "SkLumaColorFilter.h"
39 #include "SkColorFilterImageFilter.h" 39 #include "SkColorFilterImageFilter.h"
40 40
41 static const int gColorScale = 30;
42 static const int gColorOffset = 60;
43
44 static void make_bm(SkBitmap* bm, int w, int h, SkColor color, bool immutable) { 41 static void make_bm(SkBitmap* bm, int w, int h, SkColor color, bool immutable) {
45 bm->allocN32Pixels(w, h); 42 bm->allocN32Pixels(w, h);
46 bm->eraseColor(color); 43 bm->eraseColor(color);
47 if (immutable) { 44 if (immutable) {
48 bm->setImmutable(); 45 bm->setImmutable();
49 } 46 }
50 } 47 }
51 48
52 static void make_checkerboard(SkBitmap* bm, int w, int h, bool immutable) {
53 SkASSERT(w % 2 == 0);
54 SkASSERT(h % 2 == 0);
55 bm->allocPixels(SkImageInfo::Make(w, h, kAlpha_8_SkColorType,
56 kPremul_SkAlphaType));
57 SkAutoLockPixels lock(*bm);
58 for (int y = 0; y < h; y += 2) {
59 uint8_t* s = bm->getAddr8(0, y);
60 for (int x = 0; x < w; x += 2) {
61 *s++ = 0xFF;
62 *s++ = 0x00;
63 }
64 s = bm->getAddr8(0, y + 1);
65 for (int x = 0; x < w; x += 2) {
66 *s++ = 0x00;
67 *s++ = 0xFF;
68 }
69 }
70 if (immutable) {
71 bm->setImmutable();
72 }
73 }
74
75 static void init_paint(SkPaint* paint, const SkBitmap &bm) {
76 SkShader* shader = SkShader::CreateBitmapShader(bm,
77 SkShader::kClamp_TileMode,
78 SkShader::kClamp_TileMode);
79 paint->setShader(shader)->unref();
80 }
81
robertphillips 2015/01/22 15:37:05 Remove this?
reed1 2015/01/22 17:02:40 Will do in followup CL
82 typedef void (*DrawBitmapProc)(SkCanvas*, const SkBitmap&, 49 typedef void (*DrawBitmapProc)(SkCanvas*, const SkBitmap&,
83 const SkBitmap&, const SkPoint&, 50 const SkBitmap&, const SkPoint&,
84 SkTDArray<SkPixelRef*>* usedPixRefs); 51 SkTDArray<SkPixelRef*>* usedPixRefs);
85 52
86 static void drawpaint_proc(SkCanvas* canvas, const SkBitmap& bm,
87 const SkBitmap& altBM, const SkPoint& pos,
88 SkTDArray<SkPixelRef*>* usedPixRefs) {
89 SkPaint paint;
90 init_paint(&paint, bm);
91
92 canvas->drawPaint(paint);
93 *usedPixRefs->append() = bm.pixelRef();
94 }
95
96 static void drawpoints_proc(SkCanvas* canvas, const SkBitmap& bm,
97 const SkBitmap& altBM, const SkPoint& pos,
98 SkTDArray<SkPixelRef*>* usedPixRefs) {
99 SkPaint paint;
100 init_paint(&paint, bm);
101
102 // draw a rect
103 SkPoint points[5] = {
104 { pos.fX, pos.fY },
105 { pos.fX + bm.width() - 1, pos.fY },
106 { pos.fX + bm.width() - 1, pos.fY + bm.height() - 1 },
107 { pos.fX, pos.fY + bm.height() - 1 },
108 { pos.fX, pos.fY },
109 };
110
111 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 5, points, paint);
112 *usedPixRefs->append() = bm.pixelRef();
113 }
114
115 static void drawrect_proc(SkCanvas* canvas, const SkBitmap& bm,
116 const SkBitmap& altBM, const SkPoint& pos,
117 SkTDArray<SkPixelRef*>* usedPixRefs) {
118 SkPaint paint;
119 init_paint(&paint, bm);
120
121 SkRect r = { 0, 0, SkIntToScalar(bm.width()), SkIntToScalar(bm.height()) };
122 r.offset(pos.fX, pos.fY);
123
124 canvas->drawRect(r, paint);
125 *usedPixRefs->append() = bm.pixelRef();
126 }
127
128 static void drawoval_proc(SkCanvas* canvas, const SkBitmap& bm,
129 const SkBitmap& altBM, const SkPoint& pos,
130 SkTDArray<SkPixelRef*>* usedPixRefs) {
131 SkPaint paint;
132 init_paint(&paint, bm);
133
134 SkRect r = { 0, 0, SkIntToScalar(bm.width()), SkIntToScalar(bm.height()) };
135 r.offset(pos.fX, pos.fY);
136
137 canvas->drawOval(r, paint);
138 *usedPixRefs->append() = bm.pixelRef();
139 }
140
141 static void drawrrect_proc(SkCanvas* canvas, const SkBitmap& bm,
142 const SkBitmap& altBM, const SkPoint& pos,
143 SkTDArray<SkPixelRef*>* usedPixRefs) {
144 SkPaint paint;
145 init_paint(&paint, bm);
146
147 SkRect r = { 0, 0, SkIntToScalar(bm.width()), SkIntToScalar(bm.height()) };
148 r.offset(pos.fX, pos.fY);
149
150 SkRRect rr;
151 rr.setRectXY(r, SkIntToScalar(bm.width())/4, SkIntToScalar(bm.height())/4);
152 canvas->drawRRect(rr, paint);
153 *usedPixRefs->append() = bm.pixelRef();
154 }
155
156 static void drawpath_proc(SkCanvas* canvas, const SkBitmap& bm,
157 const SkBitmap& altBM, const SkPoint& pos,
158 SkTDArray<SkPixelRef*>* usedPixRefs) {
159 SkPaint paint;
160 init_paint(&paint, bm);
161
162 SkPath path;
163 path.lineTo(bm.width()/2.0f, SkIntToScalar(bm.height()));
164 path.lineTo(SkIntToScalar(bm.width()), 0);
165 path.close();
166 path.offset(pos.fX, pos.fY);
167
168 canvas->drawPath(path, paint);
169 *usedPixRefs->append() = bm.pixelRef();
170 }
171
172 static void drawbitmap_proc(SkCanvas* canvas, const SkBitmap& bm,
173 const SkBitmap& altBM, const SkPoint& pos,
174 SkTDArray<SkPixelRef*>* usedPixRefs) {
175 canvas->drawBitmap(bm, pos.fX, pos.fY, NULL);
176 *usedPixRefs->append() = bm.pixelRef();
177 }
178
179 static void drawbitmap_withshader_proc(SkCanvas* canvas, const SkBitmap& bm,
180 const SkBitmap& altBM, const SkPoint& pos ,
181 SkTDArray<SkPixelRef*>* usedPixRefs) {
182 SkPaint paint;
183 init_paint(&paint, bm);
184
185 // The bitmap in the paint is ignored unless we're drawing an A8 bitmap
186 canvas->drawBitmap(altBM, pos.fX, pos.fY, &paint);
187 *usedPixRefs->append() = bm.pixelRef();
188 *usedPixRefs->append() = altBM.pixelRef();
189 }
190
191 static void drawsprite_proc(SkCanvas* canvas, const SkBitmap& bm,
192 const SkBitmap& altBM, const SkPoint& pos,
193 SkTDArray<SkPixelRef*>* usedPixRefs) {
194 const SkMatrix& ctm = canvas->getTotalMatrix();
195
196 SkPoint p(pos);
197 ctm.mapPoints(&p, 1);
198
199 canvas->drawSprite(bm, (int)p.fX, (int)p.fY, NULL);
200 *usedPixRefs->append() = bm.pixelRef();
201 }
202
robertphillips 2015/01/22 15:37:05 Remove this too
reed1 2015/01/22 17:02:40 Will do in followup CL
203 #if 0 53 #if 0
204 // Although specifiable, this case doesn't seem to make sense (i.e., the 54 // Although specifiable, this case doesn't seem to make sense (i.e., the
205 // bitmap in the shader is never used). 55 // bitmap in the shader is never used).
206 static void drawsprite_withshader_proc(SkCanvas* canvas, const SkBitmap& bm, 56 static void drawsprite_withshader_proc(SkCanvas* canvas, const SkBitmap& bm,
207 const SkBitmap& altBM, const SkPoint& pos , 57 const SkBitmap& altBM, const SkPoint& pos ,
208 SkTDArray<SkPixelRef*>* usedPixRefs) { 58 SkTDArray<SkPixelRef*>* usedPixRefs) {
209 SkPaint paint; 59 SkPaint paint;
210 init_paint(&paint, bm); 60 init_paint(&paint, bm);
211 61
212 const SkMatrix& ctm = canvas->getTotalMatrix(); 62 const SkMatrix& ctm = canvas->getTotalMatrix();
213 63
214 SkPoint p(pos); 64 SkPoint p(pos);
215 ctm.mapPoints(&p, 1); 65 ctm.mapPoints(&p, 1);
216 66
217 canvas->drawSprite(altBM, (int)p.fX, (int)p.fY, &paint); 67 canvas->drawSprite(altBM, (int)p.fX, (int)p.fY, &paint);
218 *usedPixRefs->append() = bm.pixelRef(); 68 *usedPixRefs->append() = bm.pixelRef();
219 *usedPixRefs->append() = altBM.pixelRef(); 69 *usedPixRefs->append() = altBM.pixelRef();
220 } 70 }
221 #endif 71 #endif
222 72
223 static void drawbitmaprect_proc(SkCanvas* canvas, const SkBitmap& bm,
224 const SkBitmap& altBM, const SkPoint& pos,
225 SkTDArray<SkPixelRef*>* usedPixRefs) {
226 SkRect r = { 0, 0, SkIntToScalar(bm.width()), SkIntToScalar(bm.height()) };
227
228 r.offset(pos.fX, pos.fY);
229 canvas->drawBitmapRectToRect(bm, NULL, r, NULL);
230 *usedPixRefs->append() = bm.pixelRef();
231 }
232
233 static void drawbitmaprect_withshader_proc(SkCanvas* canvas,
234 const SkBitmap& bm,
235 const SkBitmap& altBM,
236 const SkPoint& pos,
237 SkTDArray<SkPixelRef*>* usedPixRefs) {
238 SkPaint paint;
239 init_paint(&paint, bm);
240
241 SkRect r = { 0, 0, SkIntToScalar(bm.width()), SkIntToScalar(bm.height()) };
242 r.offset(pos.fX, pos.fY);
243
244 // The bitmap in the paint is ignored unless we're drawing an A8 bitmap
245 canvas->drawBitmapRectToRect(altBM, NULL, r, &paint);
246 *usedPixRefs->append() = bm.pixelRef();
247 *usedPixRefs->append() = altBM.pixelRef();
248 }
249
250 static void drawtext_proc(SkCanvas* canvas, const SkBitmap& bm,
251 const SkBitmap& altBM, const SkPoint& pos,
252 SkTDArray<SkPixelRef*>* usedPixRefs) {
253 SkPaint paint;
254 init_paint(&paint, bm);
255 paint.setTextSize(SkIntToScalar(1.5*bm.width()));
256
257 canvas->drawText("0", 1, pos.fX, pos.fY+bm.width(), paint);
258 *usedPixRefs->append() = bm.pixelRef();
259 }
260
261 static void drawpostext_proc(SkCanvas* canvas, const SkBitmap& bm,
262 const SkBitmap& altBM, const SkPoint& pos,
263 SkTDArray<SkPixelRef*>* usedPixRefs) {
264 SkPaint paint;
265 init_paint(&paint, bm);
266 paint.setTextSize(SkIntToScalar(1.5*bm.width()));
267
268 SkPoint point = { pos.fX, pos.fY + bm.height() };
269 canvas->drawPosText("O", 1, &point, paint);
270 *usedPixRefs->append() = bm.pixelRef();
271 }
272
273 static void drawtextonpath_proc(SkCanvas* canvas, const SkBitmap& bm,
274 const SkBitmap& altBM, const SkPoint& pos,
275 SkTDArray<SkPixelRef*>* usedPixRefs) {
276 SkPaint paint;
277
278 init_paint(&paint, bm);
279 paint.setTextSize(SkIntToScalar(1.5*bm.width()));
280
281 SkPath path;
282 path.lineTo(SkIntToScalar(bm.width()), 0);
283 path.offset(pos.fX, pos.fY+bm.height());
284
285 canvas->drawTextOnPath("O", 1, path, NULL, paint);
286 *usedPixRefs->append() = bm.pixelRef();
287 }
288
289 static void drawverts_proc(SkCanvas* canvas, const SkBitmap& bm,
290 const SkBitmap& altBM, const SkPoint& pos,
291 SkTDArray<SkPixelRef*>* usedPixRefs) {
292 SkPaint paint;
293 init_paint(&paint, bm);
294
295 SkPoint verts[4] = {
296 { pos.fX, pos.fY },
297 { pos.fX + bm.width(), pos.fY },
298 { pos.fX + bm.width(), pos.fY + bm.height() },
299 { pos.fX, pos.fY + bm.height() }
300 };
301 SkPoint texs[4] = { { 0, 0 },
302 { SkIntToScalar(bm.width()), 0 },
303 { SkIntToScalar(bm.width()), SkIntToScalar(bm.height()) },
304 { 0, SkIntToScalar(bm.height()) } };
305 uint16_t indices[6] = { 0, 1, 2, 0, 2, 3 };
306
307 canvas->drawVertices(SkCanvas::kTriangles_VertexMode, 4, verts, texs, NULL, NULL,
308 indices, 6, paint);
309 *usedPixRefs->append() = bm.pixelRef();
310 }
311
312 // Return a picture with the bitmaps drawn at the specified positions.
313 static SkPicture* record_bitmaps(const SkBitmap bm[],
314 const SkPoint pos[],
315 SkTDArray<SkPixelRef*> analytic[],
316 int count,
317 DrawBitmapProc proc) {
318 SkPictureRecorder recorder;
319 SkCanvas* canvas = recorder.beginRecording(1000, 1000);
320 for (int i = 0; i < count; ++i) {
321 analytic[i].rewind();
322 canvas->save();
323 SkRect clipRect = SkRect::MakeXYWH(pos[i].fX, pos[i].fY,
324 SkIntToScalar(bm[i].width()),
325 SkIntToScalar(bm[i].height()));
326 canvas->clipRect(clipRect, SkRegion::kIntersect_Op);
327 proc(canvas, bm[i], bm[count+i], pos[i], &analytic[i]);
328 canvas->restore();
329 }
330 return recorder.endRecording();
331 }
332
333 static void rand_rect(SkRect* rect, SkRandom& rand, SkScalar W, SkScalar H) {
334 rect->fLeft = rand.nextRangeScalar(-W, 2*W);
335 rect->fTop = rand.nextRangeScalar(-H, 2*H);
336 rect->fRight = rect->fLeft + rand.nextRangeScalar(0, W);
337 rect->fBottom = rect->fTop + rand.nextRangeScalar(0, H);
338
339 // we integralize rect to make our tests more predictable, since Gather is
340 // a little sloppy.
341 SkIRect ir;
342 rect->round(&ir);
343 rect->set(ir);
344 }
345
346 static void draw(SkPicture* pic, int width, int height, SkBitmap* result) {
347 make_bm(result, width, height, SK_ColorBLACK, false);
348
349 SkCanvas canvas(*result);
350 canvas.drawPicture(pic);
351 }
352
353 template <typename T> int find_index(const T* array, T elem, int count) {
354 for (int i = 0; i < count; ++i) {
355 if (array[i] == elem) {
356 return i;
357 }
358 }
359 return -1;
360 }
361
362 // Return true if 'ref' is found in array[]
363 static bool find(SkPixelRef const * const * array, SkPixelRef const * ref, int c ount) {
364 return find_index<const SkPixelRef*>(array, ref, count) >= 0;
365 }
366
367 // Look at each pixel that is inside 'subset', and if its color appears in
368 // colors[], find the corresponding value in refs[] and append that ref into
369 // array, skipping duplicates of the same value.
370 // Note that gathering pixelRefs from rendered colors suffers from the problem
371 // that multiple simultaneous textures (e.g., A8 for alpha and 8888 for color)
372 // isn't easy to reconstruct.
373 static void gather_from_image(const SkBitmap& bm, SkPixelRef* const refs[],
374 int count, SkTDArray<SkPixelRef*>* array,
375 const SkRect& subset) {
376 SkIRect ir;
377 subset.roundOut(&ir);
378
379 if (!ir.intersect(0, 0, bm.width()-1, bm.height()-1)) {
380 return;
381 }
382
383 // Since we only want to return unique values in array, when we scan we just
384 // set a bit for each index'd color found. In practice we only have a few
385 // distinct colors, so we just use an int's bits as our array. Hence the
386 // assert that count <= number-of-bits-in-our-int.
387 SkASSERT((unsigned)count <= 32);
388 uint32_t bitarray = 0;
389
390 SkAutoLockPixels alp(bm);
391
392 for (int y = ir.fTop; y < ir.fBottom; ++y) {
393 for (int x = ir.fLeft; x < ir.fRight; ++x) {
394 SkPMColor pmc = *bm.getAddr32(x, y);
395 // the only good case where the color is not found would be if
396 // the color is transparent, meaning no bitmap was drawn in that
397 // pixel.
398 if (pmc) {
399 uint32_t index = SkGetPackedR32(pmc);
400 SkASSERT(SkGetPackedG32(pmc) == index);
401 SkASSERT(SkGetPackedB32(pmc) == index);
402 if (0 == index) {
403 continue; // background color
404 }
405 SkASSERT(0 == (index - gColorOffset) % gColorScale);
406 index = (index - gColorOffset) / gColorScale;
407 SkASSERT(static_cast<int>(index) < count);
408 bitarray |= 1 << index;
409 }
410 }
411 }
412
413 for (int i = 0; i < count; ++i) {
414 if (bitarray & (1 << i)) {
415 *array->append() = refs[i];
416 }
417 }
418 }
419
420 static void gather_from_analytic(const SkPoint pos[], SkScalar w, SkScalar h,
421 const SkTDArray<SkPixelRef*> analytic[],
422 int count,
423 SkTDArray<SkPixelRef*>* result,
424 const SkRect& subset) {
425 for (int i = 0; i < count; ++i) {
426 SkRect rect = SkRect::MakeXYWH(pos[i].fX, pos[i].fY, w, h);
427
428 if (SkRect::Intersects(subset, rect)) {
429 result->append(analytic[i].count(), analytic[i].begin());
430 }
431 }
432 }
433
434
435 static const struct {
436 const DrawBitmapProc proc;
437 const char* const desc;
438 } gProcs[] = {
439 {drawpaint_proc, "drawpaint"},
440 {drawpoints_proc, "drawpoints"},
441 {drawrect_proc, "drawrect"},
442 {drawoval_proc, "drawoval"},
443 {drawrrect_proc, "drawrrect"},
444 {drawpath_proc, "drawpath"},
445 {drawbitmap_proc, "drawbitmap"},
446 {drawbitmap_withshader_proc, "drawbitmap_withshader"},
447 {drawsprite_proc, "drawsprite"},
448 #if 0
449 {drawsprite_withshader_proc, "drawsprite_withshader"},
450 #endif
451 {drawbitmaprect_proc, "drawbitmaprect"},
452 {drawbitmaprect_withshader_proc, "drawbitmaprect_withshader"},
453 {drawtext_proc, "drawtext"},
454 {drawpostext_proc, "drawpostext"},
455 {drawtextonpath_proc, "drawtextonpath"},
456 {drawverts_proc, "drawverts"},
457 };
458
459 static void create_textures(SkBitmap* bm, SkPixelRef** refs, int num, int w, int h) {
460 // Our convention is that the color components contain an encoding of
461 // the index of their corresponding bitmap/pixelref. (0,0,0,0) is
462 // reserved for the background
463 for (int i = 0; i < num; ++i) {
464 make_bm(&bm[i], w, h,
465 SkColorSetARGB(0xFF,
466 gColorScale*i+gColorOffset,
467 gColorScale*i+gColorOffset,
468 gColorScale*i+gColorOffset),
469 true);
470 refs[i] = bm[i].pixelRef();
471 }
472
473 // The A8 alternate bitmaps are all BW checkerboards
474 for (int i = 0; i < num; ++i) {
475 make_checkerboard(&bm[num+i], w, h, true);
476 refs[num+i] = bm[num+i].pixelRef();
477 }
478 }
479
480 static void test_gatherpixelrefs(skiatest::Reporter* reporter) {
481 const int IW = 32;
482 const int IH = IW;
483 const SkScalar W = SkIntToScalar(IW);
484 const SkScalar H = W;
485
486 static const int N = 4;
487 SkBitmap bm[2*N];
488 SkPixelRef* refs[2*N];
489 SkTDArray<SkPixelRef*> analytic[N];
490
491 const SkPoint pos[N] = {
492 { 0, 0 }, { W, 0 }, { 0, H }, { W, H }
493 };
494
495 create_textures(bm, refs, N, IW, IH);
496
497 SkRandom rand;
498 for (size_t k = 0; k < SK_ARRAY_COUNT(gProcs); ++k) {
499 SkAutoTUnref<SkPicture> pic(
500 record_bitmaps(bm, pos, analytic, N, gProcs[k].proc));
501
502 REPORTER_ASSERT(reporter, pic->willPlayBackBitmaps() || N == 0);
503 // quick check for a small piece of each quadrant, which should just
504 // contain 1 or 2 bitmaps.
505 for (size_t i = 0; i < SK_ARRAY_COUNT(pos); ++i) {
506 SkRect r;
507 r.set(2, 2, W - 2, H - 2);
508 r.offset(pos[i].fX, pos[i].fY);
509 SkAutoDataUnref data(SkPictureUtils::GatherPixelRefs(pic, r));
510 if (!data) {
511 ERRORF(reporter, "SkPictureUtils::GatherPixelRefs returned "
512 "NULL for %s.", gProcs[k].desc);
513 continue;
514 }
515 SkPixelRef** gatheredRefs = (SkPixelRef**)data->data();
516 int count = static_cast<int>(data->size() / sizeof(SkPixelRef*));
517 REPORTER_ASSERT(reporter, 1 == count || 2 == count);
518 if (1 == count) {
519 REPORTER_ASSERT(reporter, gatheredRefs[0] == refs[i]);
520 } else if (2 == count) {
521 REPORTER_ASSERT(reporter,
522 (gatheredRefs[0] == refs[i] && gatheredRefs[1] == refs[i+N]) ||
523 (gatheredRefs[1] == refs[i] && gatheredRefs[0] == refs[i+N]) );
524 }
525 }
526
527 SkBitmap image;
528 draw(pic, 2*IW, 2*IH, &image);
529
530 // Test a bunch of random (mostly) rects, and compare the gather results
531 // with a deduced list of refs by looking at the colors drawn.
532 for (int j = 0; j < 100; ++j) {
533 SkRect r;
534 rand_rect(&r, rand, 2*W, 2*H);
535
536 SkTDArray<SkPixelRef*> fromImage;
537 gather_from_image(image, refs, N, &fromImage, r);
538
539 SkTDArray<SkPixelRef*> fromAnalytic;
540 gather_from_analytic(pos, W, H, analytic, N, &fromAnalytic, r);
541
542 SkData* data = SkPictureUtils::GatherPixelRefs(pic, r);
543 size_t dataSize = data ? data->size() : 0;
544 int gatherCount = static_cast<int>(dataSize / sizeof(SkPixelRef*));
545 SkASSERT(gatherCount * sizeof(SkPixelRef*) == dataSize);
546 SkPixelRef** gatherRefs = data ? (SkPixelRef**)(data->data()) : NULL ;
547 SkAutoDataUnref adu(data);
548
549 // Everything that we saw drawn should appear in the analytic list
550 // but the analytic list may contain some pixelRefs that were not
551 // seen in the image (e.g., A8 textures used as masks)
552 for (int i = 0; i < fromImage.count(); ++i) {
553 if (-1 == fromAnalytic.find(fromImage[i])) {
554 ERRORF(reporter, "PixelRef missing %d %s",
555 i, gProcs[k].desc);
556 }
557 }
558
559 /*
560 * GatherPixelRefs is conservative, so it can return more bitmaps
561 * than are strictly required. Thus our check here is only that
562 * Gather didn't miss any that we actually needed. Even that isn't
563 * a strict requirement on Gather, which is meant to be quick and
564 * only mostly-correct, but at the moment this test should work.
565 */
566 for (int i = 0; i < fromAnalytic.count(); ++i) {
567 bool found = find(gatherRefs, fromAnalytic[i], gatherCount);
568 if (!found) {
569 ERRORF(reporter, "PixelRef missing %d %s",
570 i, gProcs[k].desc);
571 }
572 #if 0
573 // enable this block of code to debug failures, as it will rerun
574 // the case that failed.
575 if (!found) {
576 SkData* data = SkPictureUtils::GatherPixelRefs(pic, r);
577 size_t dataSize = data ? data->size() : 0;
578 }
579 #endif
580 }
581 }
582 }
583 }
584
585 /* Hit a few SkPicture::Analysis cases not handled elsewhere. */ 73 /* Hit a few SkPicture::Analysis cases not handled elsewhere. */
586 static void test_analysis(skiatest::Reporter* reporter) { 74 static void test_analysis(skiatest::Reporter* reporter) {
587 SkPictureRecorder recorder; 75 SkPictureRecorder recorder;
588 76
589 SkCanvas* canvas = recorder.beginRecording(100, 100); 77 SkCanvas* canvas = recorder.beginRecording(100, 100);
590 { 78 {
591 canvas->drawRect(SkRect::MakeWH(10, 10), SkPaint ()); 79 canvas->drawRect(SkRect::MakeWH(10, 10), SkPaint ());
592 } 80 }
593 SkAutoTUnref<SkPicture> picture(recorder.endRecording()); 81 SkAutoTUnref<SkPicture> picture(recorder.endRecording());
594 REPORTER_ASSERT(reporter, !picture->willPlayBackBitmaps()); 82 REPORTER_ASSERT(reporter, !picture->willPlayBackBitmaps());
(...skipping 13 matching lines...) Expand all
608 REPORTER_ASSERT(reporter, 96 REPORTER_ASSERT(reporter,
609 shader->asABitmap(NULL, NULL, NULL) == SkShader::kDefaul t_BitmapType); 97 shader->asABitmap(NULL, NULL, NULL) == SkShader::kDefaul t_BitmapType);
610 98
611 canvas->drawRect(SkRect::MakeWH(10, 10), paint); 99 canvas->drawRect(SkRect::MakeWH(10, 10), paint);
612 } 100 }
613 picture.reset(recorder.endRecording()); 101 picture.reset(recorder.endRecording());
614 REPORTER_ASSERT(reporter, picture->willPlayBackBitmaps()); 102 REPORTER_ASSERT(reporter, picture->willPlayBackBitmaps());
615 } 103 }
616 104
617 105
618 static void test_gatherpixelrefsandrects(skiatest::Reporter* reporter) {
619 const int IW = 32;
620 const int IH = IW;
621 const SkScalar W = SkIntToScalar(IW);
622 const SkScalar H = W;
623
624 static const int N = 4;
625 SkBitmap bm[2*N];
626 SkPixelRef* refs[2*N];
627 SkTDArray<SkPixelRef*> analytic[N];
628
629 const SkPoint pos[N] = {
630 { 0, 0 }, { W, 0 }, { 0, H }, { W, H }
631 };
632
633 create_textures(bm, refs, N, IW, IH);
634
635 SkRandom rand;
636 for (size_t k = 0; k < SK_ARRAY_COUNT(gProcs); ++k) {
637 SkAutoTUnref<SkPicture> pic(
638 record_bitmaps(bm, pos, analytic, N, gProcs[k].proc));
639
640 REPORTER_ASSERT(reporter, pic->willPlayBackBitmaps() || N == 0);
641
642 SkAutoTUnref<SkPictureUtils::SkPixelRefContainer> prCont(
643 new SkPictureUtils::SkPixelRefsAndRectsList);
644
645 SkPictureUtils::GatherPixelRefsAndRects(pic, prCont);
646
647 // quick check for a small piece of each quadrant, which should just
648 // contain 1 or 2 bitmaps.
649 for (size_t i = 0; i < SK_ARRAY_COUNT(pos); ++i) {
650 SkRect r;
651 r.set(2, 2, W - 2, H - 2);
652 r.offset(pos[i].fX, pos[i].fY);
653
654 SkTDArray<SkPixelRef*> gatheredRefs;
655 prCont->query(r, &gatheredRefs);
656
657 int count = gatheredRefs.count();
658 REPORTER_ASSERT(reporter, 1 == count || 2 == count);
659 if (1 == count) {
660 REPORTER_ASSERT(reporter, gatheredRefs[0] == refs[i]);
661 } else if (2 == count) {
662 REPORTER_ASSERT(reporter,
663 (gatheredRefs[0] == refs[i] && gatheredRefs[1] == refs[i+N]) ||
664 (gatheredRefs[1] == refs[i] && gatheredRefs[0] == refs[i+N]) );
665 }
666 }
667
668 SkBitmap image;
669 draw(pic, 2*IW, 2*IH, &image);
670
671 // Test a bunch of random (mostly) rects, and compare the gather results
672 // with the analytic results and the pixel refs seen in a rendering.
673 for (int j = 0; j < 100; ++j) {
674 SkRect r;
675 rand_rect(&r, rand, 2*W, 2*H);
676
677 SkTDArray<SkPixelRef*> fromImage;
678 gather_from_image(image, refs, N, &fromImage, r);
679
680 SkTDArray<SkPixelRef*> fromAnalytic;
681 gather_from_analytic(pos, W, H, analytic, N, &fromAnalytic, r);
682
683 SkTDArray<SkPixelRef*> gatheredRefs;
684 prCont->query(r, &gatheredRefs);
685
686 // Everything that we saw drawn should appear in the analytic list
687 // but the analytic list may contain some pixelRefs that were not
688 // seen in the image (e.g., A8 textures used as masks)
689 for (int i = 0; i < fromImage.count(); ++i) {
690 REPORTER_ASSERT(reporter, -1 != fromAnalytic.find(fromImage[i])) ;
691 }
692
693 // Everything in the analytic list should appear in the gathered
694 // list.
695 for (int i = 0; i < fromAnalytic.count(); ++i) {
696 REPORTER_ASSERT(reporter, -1 != gatheredRefs.find(fromAnalytic[i ]));
697 }
698 }
699 }
700 }
701
702 #ifdef SK_DEBUG 106 #ifdef SK_DEBUG
703 // Ensure that deleting an empty SkPicture does not assert. Asserts only fire 107 // Ensure that deleting an empty SkPicture does not assert. Asserts only fire
704 // in debug mode, so only run in debug mode. 108 // in debug mode, so only run in debug mode.
705 static void test_deleting_empty_picture() { 109 static void test_deleting_empty_picture() {
706 SkPictureRecorder recorder; 110 SkPictureRecorder recorder;
707 // Creates an SkPictureRecord 111 // Creates an SkPictureRecord
708 recorder.beginRecording(0, 0); 112 recorder.beginRecording(0, 0);
709 // Turns that into an SkPicture 113 // Turns that into an SkPicture
710 SkAutoTUnref<SkPicture> picture(recorder.endRecording()); 114 SkAutoTUnref<SkPicture> picture(recorder.endRecording());
711 // Ceates a new SkPictureRecord 115 // Ceates a new SkPictureRecord
(...skipping 1050 matching lines...) Expand 10 before | Expand all | Expand 10 after
1762 #else 1166 #else
1763 test_bad_bitmap(); 1167 test_bad_bitmap();
1764 #endif 1168 #endif
1765 test_unbalanced_save_restores(reporter); 1169 test_unbalanced_save_restores(reporter);
1766 test_peephole(); 1170 test_peephole();
1767 #if SK_SUPPORT_GPU 1171 #if SK_SUPPORT_GPU
1768 test_gpu_veto(reporter); 1172 test_gpu_veto(reporter);
1769 #endif 1173 #endif
1770 test_has_text(reporter); 1174 test_has_text(reporter);
1771 test_analysis(reporter); 1175 test_analysis(reporter);
1772 test_gatherpixelrefs(reporter);
1773 test_gatherpixelrefsandrects(reporter);
1774 test_bitmap_with_encoded_data(reporter); 1176 test_bitmap_with_encoded_data(reporter);
1775 test_clip_bound_opt(reporter); 1177 test_clip_bound_opt(reporter);
1776 test_clip_expansion(reporter); 1178 test_clip_expansion(reporter);
1777 test_hierarchical(reporter); 1179 test_hierarchical(reporter);
1778 test_gen_id(reporter); 1180 test_gen_id(reporter);
1779 test_savelayer_extraction(reporter); 1181 test_savelayer_extraction(reporter);
1780 test_bytes_used(reporter); 1182 test_bytes_used(reporter);
1781 } 1183 }
1782 1184
1783 static void draw_bitmaps(const SkBitmap bitmap, SkCanvas* canvas) { 1185 static void draw_bitmaps(const SkBitmap bitmap, SkCanvas* canvas) {
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
1927 1329
1928 // The picture shares the immutable pixels but copies the mutable ones. 1330 // The picture shares the immutable pixels but copies the mutable ones.
1929 REPORTER_ASSERT(r, mut.pixelRef()->unique()); 1331 REPORTER_ASSERT(r, mut.pixelRef()->unique());
1930 REPORTER_ASSERT(r, !immut.pixelRef()->unique()); 1332 REPORTER_ASSERT(r, !immut.pixelRef()->unique());
1931 1333
1932 // When the picture goes away, it's just our bitmaps holding the refs. 1334 // When the picture goes away, it's just our bitmaps holding the refs.
1933 pic.reset(NULL); 1335 pic.reset(NULL);
1934 REPORTER_ASSERT(r, mut.pixelRef()->unique()); 1336 REPORTER_ASSERT(r, mut.pixelRef()->unique());
1935 REPORTER_ASSERT(r, immut.pixelRef()->unique()); 1337 REPORTER_ASSERT(r, immut.pixelRef()->unique());
1936 } 1338 }
OLDNEW
« no previous file with comments | « src/utils/SkPictureUtils.cpp ('k') | tools/PictureRenderer.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698