 Chromium Code Reviews
 Chromium Code Reviews Issue 869463002:
  remove (unused) GatherPixelRefs  (Closed) 
  Base URL: https://skia.googlesource.com/skia.git@master
    
  
    Issue 869463002:
  remove (unused) GatherPixelRefs  (Closed) 
  Base URL: https://skia.googlesource.com/skia.git@master| 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 "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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } | 
| OLD | NEW |