| 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 |