1 #include "SkPictureRecord.h"
2 #include "SkShape.h"
3 #include "SkTSearch.h"
4
5 #define MIN_WRITER_SIZE 16384
6 #define HEAP_BLOCK_SIZE 4096
7
SkPictureRecord(uint32_t flags)8 SkPictureRecord::SkPictureRecord(uint32_t flags) :
9 fHeap(HEAP_BLOCK_SIZE), fWriter(MIN_WRITER_SIZE), fRecordFlags(flags) {
10 fBitmapIndex = fMatrixIndex = fPaintIndex = fRegionIndex = 1;
11 #ifdef SK_DEBUG_SIZE
12 fPointBytes = fRectBytes = fTextBytes = 0;
13 fPointWrites = fRectWrites = fTextWrites = 0;
14 #endif
15
16 fRestoreOffsetStack.setReserve(32);
17 fRestoreOffsetStack.push(0);
18
19 fPathHeap = NULL; // lazy allocate
20 }
21
~SkPictureRecord()22 SkPictureRecord::~SkPictureRecord() {
23 reset();
24 }
25
26 ///////////////////////////////////////////////////////////////////////////////
27
save(SaveFlags flags)28 int SkPictureRecord::save(SaveFlags flags) {
29 addDraw(SAVE);
30 addInt(flags);
31
32 fRestoreOffsetStack.push(0);
33
34 validate();
35 return this->INHERITED::save(flags);
36 }
37
saveLayer(const SkRect * bounds,const SkPaint * paint,SaveFlags flags)38 int SkPictureRecord::saveLayer(const SkRect* bounds, const SkPaint* paint,
39 SaveFlags flags) {
40 addDraw(SAVE_LAYER);
41 addRectPtr(bounds);
42 addPaintPtr(paint);
43 addInt(flags);
44
45 fRestoreOffsetStack.push(0);
46
47 validate();
48 /* Don't actually call saveLayer, because that will try to allocate an
49 offscreen device (potentially very big) which we don't actually need
50 at this time (and may not be able to afford since during record our
51 clip starts out the size of the picture, which is often much larger
52 than the size of the actual device we'll use during playback).
53 */
54 return this->INHERITED::save(flags);
55 }
56
restore()57 void SkPictureRecord::restore() {
58 // check for underflow
59 if (fRestoreOffsetStack.count() == 0) {
60 return;
61 }
62
63 // patch up the clip offsets
64 uint32_t restoreOffset = (uint32_t)fWriter.size();
65 uint32_t offset = fRestoreOffsetStack.top();
66 while (offset) {
67 uint32_t* peek = fWriter.peek32(offset);
68 offset = *peek;
69 *peek = restoreOffset;
70 }
71 fRestoreOffsetStack.pop();
72
73 addDraw(RESTORE);
74 validate();
75 return this->INHERITED::restore();
76 }
77
translate(SkScalar dx,SkScalar dy)78 bool SkPictureRecord::translate(SkScalar dx, SkScalar dy) {
79 addDraw(TRANSLATE);
80 addScalar(dx);
81 addScalar(dy);
82 validate();
83 return this->INHERITED::translate(dx, dy);
84 }
85
scale(SkScalar sx,SkScalar sy)86 bool SkPictureRecord::scale(SkScalar sx, SkScalar sy) {
87 addDraw(SCALE);
88 addScalar(sx);
89 addScalar(sy);
90 validate();
91 return this->INHERITED::scale(sx, sy);
92 }
93
rotate(SkScalar degrees)94 bool SkPictureRecord::rotate(SkScalar degrees) {
95 addDraw(ROTATE);
96 addScalar(degrees);
97 validate();
98 return this->INHERITED::rotate(degrees);
99 }
100
skew(SkScalar sx,SkScalar sy)101 bool SkPictureRecord::skew(SkScalar sx, SkScalar sy) {
102 addDraw(SKEW);
103 addScalar(sx);
104 addScalar(sy);
105 validate();
106 return this->INHERITED::skew(sx, sy);
107 }
108
concat(const SkMatrix & matrix)109 bool SkPictureRecord::concat(const SkMatrix& matrix) {
110 validate();
111 addDraw(CONCAT);
112 addMatrix(matrix);
113 validate();
114 return this->INHERITED::concat(matrix);
115 }
116
setMatrix(const SkMatrix & matrix)117 void SkPictureRecord::setMatrix(const SkMatrix& matrix) {
118 validate();
119 addDraw(SET_MATRIX);
120 addMatrix(matrix);
121 validate();
122 this->INHERITED::setMatrix(matrix);
123 }
124
clipRect(const SkRect & rect,SkRegion::Op op)125 bool SkPictureRecord::clipRect(const SkRect& rect, SkRegion::Op op) {
126 addDraw(CLIP_RECT);
127 addRect(rect);
128 addInt(op);
129
130 size_t offset = fWriter.size();
131 addInt(fRestoreOffsetStack.top());
132 fRestoreOffsetStack.top() = offset;
133
134 validate();
135 return this->INHERITED::clipRect(rect, op);
136 }
137
clipPath(const SkPath & path,SkRegion::Op op)138 bool SkPictureRecord::clipPath(const SkPath& path, SkRegion::Op op) {
139 addDraw(CLIP_PATH);
140 addPath(path);
141 addInt(op);
142
143 size_t offset = fWriter.size();
144 addInt(fRestoreOffsetStack.top());
145 fRestoreOffsetStack.top() = offset;
146
147 validate();
148
149 if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) {
150 return this->INHERITED::clipRect(path.getBounds(), op);
151 } else {
152 return this->INHERITED::clipPath(path, op);
153 }
154 }
155
clipRegion(const SkRegion & region,SkRegion::Op op)156 bool SkPictureRecord::clipRegion(const SkRegion& region, SkRegion::Op op) {
157 addDraw(CLIP_REGION);
158 addRegion(region);
159 addInt(op);
160
161 size_t offset = fWriter.size();
162 addInt(fRestoreOffsetStack.top());
163 fRestoreOffsetStack.top() = offset;
164
165 validate();
166 return this->INHERITED::clipRegion(region, op);
167 }
168
drawPaint(const SkPaint & paint)169 void SkPictureRecord::drawPaint(const SkPaint& paint) {
170 addDraw(DRAW_PAINT);
171 addPaint(paint);
172 validate();
173 }
174
drawPoints(PointMode mode,size_t count,const SkPoint pts[],const SkPaint & paint)175 void SkPictureRecord::drawPoints(PointMode mode, size_t count, const SkPoint pts[],
176 const SkPaint& paint) {
177 addDraw(DRAW_POINTS);
178 addPaint(paint);
179 addInt(mode);
180 addInt(count);
181 fWriter.writeMul4(pts, count * sizeof(SkPoint));
182 validate();
183 }
184
drawRect(const SkRect & rect,const SkPaint & paint)185 void SkPictureRecord::drawRect(const SkRect& rect, const SkPaint& paint) {
186 addDraw(DRAW_RECT);
187 addPaint(paint);
188 addRect(rect);
189 validate();
190 }
191
drawPath(const SkPath & path,const SkPaint & paint)192 void SkPictureRecord::drawPath(const SkPath& path, const SkPaint& paint) {
193 addDraw(DRAW_PATH);
194 addPaint(paint);
195 addPath(path);
196 validate();
197 }
198
drawBitmap(const SkBitmap & bitmap,SkScalar left,SkScalar top,const SkPaint * paint=NULL)199 void SkPictureRecord::drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
200 const SkPaint* paint = NULL) {
201 addDraw(DRAW_BITMAP);
202 addPaintPtr(paint);
203 addBitmap(bitmap);
204 addScalar(left);
205 addScalar(top);
206 validate();
207 }
208
drawBitmapRect(const SkBitmap & bitmap,const SkIRect * src,const SkRect & dst,const SkPaint * paint)209 void SkPictureRecord::drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
210 const SkRect& dst, const SkPaint* paint) {
211 addDraw(DRAW_BITMAP_RECT);
212 addPaintPtr(paint);
213 addBitmap(bitmap);
214 addIRectPtr(src); // may be null
215 addRect(dst);
216 validate();
217 }
218
drawBitmapMatrix(const SkBitmap & bitmap,const SkMatrix & matrix,const SkPaint * paint)219 void SkPictureRecord::drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& matrix,
220 const SkPaint* paint) {
221 addDraw(DRAW_BITMAP_MATRIX);
222 addPaintPtr(paint);
223 addBitmap(bitmap);
224 addMatrix(matrix);
225 validate();
226 }
227
drawSprite(const SkBitmap & bitmap,int left,int top,const SkPaint * paint=NULL)228 void SkPictureRecord::drawSprite(const SkBitmap& bitmap, int left, int top,
229 const SkPaint* paint = NULL) {
230 addDraw(DRAW_SPRITE);
231 addPaintPtr(paint);
232 addBitmap(bitmap);
233 addInt(left);
234 addInt(top);
235 validate();
236 }
237
addFontMetricsTopBottom(const SkPaint & paint,SkScalar baselineY)238 void SkPictureRecord::addFontMetricsTopBottom(const SkPaint& paint,
239 SkScalar baselineY) {
240 SkPaint::FontMetrics metrics;
241 paint.getFontMetrics(&metrics);
242 SkRect bounds;
243 // construct a rect so we can see any adjustments from the paint.
244 // we use 0,1 for left,right, just so the rect isn't empty
245 bounds.set(0, metrics.fTop + baselineY,
246 SK_Scalar1, metrics.fBottom + baselineY);
247 (void)paint.computeFastBounds(bounds, &bounds);
248 // now record the top and bottom
249 addScalar(bounds.fTop);
250 addScalar(bounds.fBottom);
251 }
252
drawText(const void * text,size_t byteLength,SkScalar x,SkScalar y,const SkPaint & paint)253 void SkPictureRecord::drawText(const void* text, size_t byteLength, SkScalar x,
254 SkScalar y, const SkPaint& paint) {
255 bool fast = paint.canComputeFastBounds();
256
257 addDraw(fast ? DRAW_TEXT_TOP_BOTTOM : DRAW_TEXT);
258 addPaint(paint);
259 addText(text, byteLength);
260 addScalar(x);
261 addScalar(y);
262 if (fast) {
263 addFontMetricsTopBottom(paint, y);
264 }
265 validate();
266 }
267
drawPosText(const void * text,size_t byteLength,const SkPoint pos[],const SkPaint & paint)268 void SkPictureRecord::drawPosText(const void* text, size_t byteLength,
269 const SkPoint pos[], const SkPaint& paint) {
270 size_t points = paint.countText(text, byteLength);
271 if (0 == points)
272 return;
273
274 bool canUseDrawH = true;
275 // check if the caller really should have used drawPosTextH()
276 {
277 const SkScalar firstY = pos[0].fY;
278 for (size_t index = 1; index < points; index++) {
279 if (pos[index].fY != firstY) {
280 canUseDrawH = false;
281 break;
282 }
283 }
284 }
285
286 bool fast = canUseDrawH && paint.canComputeFastBounds();
287
288 if (fast) {
289 addDraw(DRAW_POS_TEXT_H_TOP_BOTTOM);
290 } else {
291 addDraw(canUseDrawH ? DRAW_POS_TEXT_H : DRAW_POS_TEXT);
292 }
293 addPaint(paint);
294 addText(text, byteLength);
295 addInt(points);
296
297 #ifdef SK_DEBUG_SIZE
298 size_t start = fWriter.size();
299 #endif
300 if (canUseDrawH) {
301 if (fast) {
302 addFontMetricsTopBottom(paint, pos[0].fY);
303 }
304 addScalar(pos[0].fY);
305 SkScalar* xptr = (SkScalar*)fWriter.reserve(points * sizeof(SkScalar));
306 for (size_t index = 0; index < points; index++)
307 *xptr++ = pos[index].fX;
308 }
309 else {
310 fWriter.writeMul4(pos, points * sizeof(SkPoint));
311 }
312 #ifdef SK_DEBUG_SIZE
313 fPointBytes += fWriter.size() - start;
314 fPointWrites += points;
315 #endif
316 validate();
317 }
318
drawPosTextH(const void * text,size_t byteLength,const SkScalar xpos[],SkScalar constY,const SkPaint & paint)319 void SkPictureRecord::drawPosTextH(const void* text, size_t byteLength,
320 const SkScalar xpos[], SkScalar constY,
321 const SkPaint& paint) {
322 size_t points = paint.countText(text, byteLength);
323 if (0 == points)
324 return;
325
326 bool fast = paint.canComputeFastBounds();
327
328 addDraw(fast ? DRAW_POS_TEXT_H_TOP_BOTTOM : DRAW_POS_TEXT_H);
329 addPaint(paint);
330 addText(text, byteLength);
331 addInt(points);
332
333 #ifdef SK_DEBUG_SIZE
334 size_t start = fWriter.size();
335 #endif
336 if (fast) {
337 addFontMetricsTopBottom(paint, constY);
338 }
339 addScalar(constY);
340 fWriter.writeMul4(xpos, points * sizeof(SkScalar));
341 #ifdef SK_DEBUG_SIZE
342 fPointBytes += fWriter.size() - start;
343 fPointWrites += points;
344 #endif
345 validate();
346 }
347
drawTextOnPath(const void * text,size_t byteLength,const SkPath & path,const SkMatrix * matrix,const SkPaint & paint)348 void SkPictureRecord::drawTextOnPath(const void* text, size_t byteLength,
349 const SkPath& path, const SkMatrix* matrix,
350 const SkPaint& paint) {
351 addDraw(DRAW_TEXT_ON_PATH);
352 addPaint(paint);
353 addText(text, byteLength);
354 addPath(path);
355 addMatrixPtr(matrix);
356 validate();
357 }
358
drawPicture(SkPicture & picture)359 void SkPictureRecord::drawPicture(SkPicture& picture) {
360 addDraw(DRAW_PICTURE);
361 addPicture(picture);
362 validate();
363 }
364
drawShape(SkShape * shape)365 void SkPictureRecord::drawShape(SkShape* shape) {
366 addDraw(DRAW_SHAPE);
367
368 int index = fShapes.find(shape);
369 if (index < 0) { // not found
370 index = fShapes.count();
371 *fShapes.append() = shape;
372 shape->ref();
373 }
374 // follow the convention of recording a 1-based index
375 addInt(index + 1);
376 validate();
377 }
378
drawVertices(VertexMode vmode,int vertexCount,const SkPoint vertices[],const SkPoint texs[],const SkColor colors[],SkXfermode *,const uint16_t indices[],int indexCount,const SkPaint & paint)379 void SkPictureRecord::drawVertices(VertexMode vmode, int vertexCount,
380 const SkPoint vertices[], const SkPoint texs[],
381 const SkColor colors[], SkXfermode*,
382 const uint16_t indices[], int indexCount,
383 const SkPaint& paint) {
384 uint32_t flags = 0;
385 if (texs) {
386 flags |= DRAW_VERTICES_HAS_TEXS;
387 }
388 if (colors) {
389 flags |= DRAW_VERTICES_HAS_COLORS;
390 }
391 if (indexCount > 0) {
392 flags |= DRAW_VERTICES_HAS_INDICES;
393 }
394
395 addDraw(DRAW_VERTICES);
396 addPaint(paint);
397 addInt(flags);
398 addInt(vmode);
399 addInt(vertexCount);
400 addPoints(vertices, vertexCount);
401 if (flags & DRAW_VERTICES_HAS_TEXS) {
402 addPoints(texs, vertexCount);
403 }
404 if (flags & DRAW_VERTICES_HAS_COLORS) {
405 fWriter.writeMul4(colors, vertexCount * sizeof(SkColor));
406 }
407 if (flags & DRAW_VERTICES_HAS_INDICES) {
408 addInt(indexCount);
409 fWriter.writePad(indices, indexCount * sizeof(uint16_t));
410 }
411 }
412
413 ///////////////////////////////////////////////////////////////////////////////
414
reset()415 void SkPictureRecord::reset() {
416 fPathHeap->safeUnref();
417 fPathHeap = NULL;
418
419 fBitmaps.reset();
420 fMatrices.reset();
421 fPaints.reset();
422 fPictureRefs.unrefAll();
423 fRegions.reset();
424 fShapes.safeUnrefAll();
425 fWriter.reset();
426 fHeap.reset();
427
428 fRestoreOffsetStack.setCount(1);
429 fRestoreOffsetStack.top() = 0;
430
431 fRCRecorder.reset();
432 fTFRecorder.reset();
433 }
434
addBitmap(const SkBitmap & bitmap)435 void SkPictureRecord::addBitmap(const SkBitmap& bitmap) {
436 addInt(find(fBitmaps, bitmap));
437 }
438
addMatrix(const SkMatrix & matrix)439 void SkPictureRecord::addMatrix(const SkMatrix& matrix) {
440 addMatrixPtr(&matrix);
441 }
442
addMatrixPtr(const SkMatrix * matrix)443 void SkPictureRecord::addMatrixPtr(const SkMatrix* matrix) {
444 addInt(find(fMatrices, matrix));
445 }
446
addPaint(const SkPaint & paint)447 void SkPictureRecord::addPaint(const SkPaint& paint) {
448 addPaintPtr(&paint);
449 }
450
addPaintPtr(const SkPaint * paint)451 void SkPictureRecord::addPaintPtr(const SkPaint* paint) {
452 addInt(find(fPaints, paint));
453 }
454
addPath(const SkPath & path)455 void SkPictureRecord::addPath(const SkPath& path) {
456 if (NULL == fPathHeap) {
457 fPathHeap = SkNEW(SkPathHeap);
458 }
459 addInt(fPathHeap->append(path));
460 }
461
addPicture(SkPicture & picture)462 void SkPictureRecord::addPicture(SkPicture& picture) {
463 int index = fPictureRefs.find(&picture);
464 if (index < 0) { // not found
465 index = fPictureRefs.count();
466 *fPictureRefs.append() = &picture;
467 picture.ref();
468 }
469 // follow the convention of recording a 1-based index
470 addInt(index + 1);
471 }
472
addPoint(const SkPoint & point)473 void SkPictureRecord::addPoint(const SkPoint& point) {
474 #ifdef SK_DEBUG_SIZE
475 size_t start = fWriter.size();
476 #endif
477 fWriter.writePoint(point);
478 #ifdef SK_DEBUG_SIZE
479 fPointBytes += fWriter.size() - start;
480 fPointWrites++;
481 #endif
482 }
483
addPoints(const SkPoint pts[],int count)484 void SkPictureRecord::addPoints(const SkPoint pts[], int count) {
485 fWriter.writeMul4(pts, count * sizeof(SkPoint));
486 #ifdef SK_DEBUG_SIZE
487 fPointBytes += count * sizeof(SkPoint);
488 fPointWrites++;
489 #endif
490 }
491
addRect(const SkRect & rect)492 void SkPictureRecord::addRect(const SkRect& rect) {
493 #ifdef SK_DEBUG_SIZE
494 size_t start = fWriter.size();
495 #endif
496 fWriter.writeRect(rect);
497 #ifdef SK_DEBUG_SIZE
498 fRectBytes += fWriter.size() - start;
499 fRectWrites++;
500 #endif
501 }
502
addRectPtr(const SkRect * rect)503 void SkPictureRecord::addRectPtr(const SkRect* rect) {
504 if (fWriter.writeBool(rect != NULL)) {
505 fWriter.writeRect(*rect);
506 }
507 }
508
addIRectPtr(const SkIRect * rect)509 void SkPictureRecord::addIRectPtr(const SkIRect* rect) {
510 if (fWriter.writeBool(rect != NULL)) {
511 *(SkIRect*)fWriter.reserve(sizeof(SkIRect)) = *rect;
512 }
513 }
514
addRegion(const SkRegion & region)515 void SkPictureRecord::addRegion(const SkRegion& region) {
516 addInt(find(fRegions, region));
517 }
518
addText(const void * text,size_t byteLength)519 void SkPictureRecord::addText(const void* text, size_t byteLength) {
520 #ifdef SK_DEBUG_SIZE
521 size_t start = fWriter.size();
522 #endif
523 addInt(byteLength);
524 fWriter.writePad(text, byteLength);
525 #ifdef SK_DEBUG_SIZE
526 fTextBytes += fWriter.size() - start;
527 fTextWrites++;
528 #endif
529 }
530
531 ///////////////////////////////////////////////////////////////////////////////
532
find(SkTDArray<const SkFlatBitmap * > & bitmaps,const SkBitmap & bitmap)533 int SkPictureRecord::find(SkTDArray<const SkFlatBitmap* >& bitmaps, const SkBitmap& bitmap) {
534 SkFlatBitmap* flat = SkFlatBitmap::Flatten(&fHeap, bitmap, fBitmapIndex,
535 &fRCRecorder);
536 int index = SkTSearch<SkFlatData>((const SkFlatData**) bitmaps.begin(),
537 bitmaps.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare);
538 if (index >= 0) {
539 (void)fHeap.unalloc(flat);
540 return bitmaps[index]->index();
541 }
542 index = ~index;
543 *bitmaps.insert(index) = flat;
544 return fBitmapIndex++;
545 }
546
find(SkTDArray<const SkFlatMatrix * > & matrices,const SkMatrix * matrix)547 int SkPictureRecord::find(SkTDArray<const SkFlatMatrix* >& matrices, const SkMatrix* matrix) {
548 if (matrix == NULL)
549 return 0;
550 SkFlatMatrix* flat = SkFlatMatrix::Flatten(&fHeap, *matrix, fMatrixIndex);
551 int index = SkTSearch<SkFlatData>((const SkFlatData**) matrices.begin(),
552 matrices.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare);
553 if (index >= 0) {
554 (void)fHeap.unalloc(flat);
555 return matrices[index]->index();
556 }
557 index = ~index;
558 *matrices.insert(index) = flat;
559 return fMatrixIndex++;
560 }
561
find(SkTDArray<const SkFlatPaint * > & paints,const SkPaint * paint)562 int SkPictureRecord::find(SkTDArray<const SkFlatPaint* >& paints, const SkPaint* paint) {
563 if (paint == NULL) {
564 return 0;
565 }
566
567 SkFlatPaint* flat = SkFlatPaint::Flatten(&fHeap, *paint, fPaintIndex,
568 &fRCRecorder, &fTFRecorder);
569 int index = SkTSearch<SkFlatData>((const SkFlatData**) paints.begin(),
570 paints.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare);
571 if (index >= 0) {
572 (void)fHeap.unalloc(flat);
573 return paints[index]->index();
574 }
575
576 index = ~index;
577 *paints.insert(index) = flat;
578 return fPaintIndex++;
579 }
580
find(SkTDArray<const SkFlatRegion * > & regions,const SkRegion & region)581 int SkPictureRecord::find(SkTDArray<const SkFlatRegion* >& regions, const SkRegion& region) {
582 SkFlatRegion* flat = SkFlatRegion::Flatten(&fHeap, region, fRegionIndex);
583 int index = SkTSearch<SkFlatData>((const SkFlatData**) regions.begin(),
584 regions.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare);
585 if (index >= 0) {
586 (void)fHeap.unalloc(flat);
587 return regions[index]->index();
588 }
589 index = ~index;
590 *regions.insert(index) = flat;
591 return fRegionIndex++;
592 }
593
594 #ifdef SK_DEBUG_DUMP
dumpMatrices()595 void SkPictureRecord::dumpMatrices() {
596 int count = fMatrices.count();
597 SkMatrix defaultMatrix;
598 defaultMatrix.reset();
599 for (int index = 0; index < count; index++) {
600 const SkFlatMatrix* flatMatrix = fMatrices[index];
601 flatMatrix->dump();
602 }
603 }
604
dumpPaints()605 void SkPictureRecord::dumpPaints() {
606 int count = fPaints.count();
607 for (int index = 0; index < count; index++)
608 fPaints[index]->dump();
609 }
610 #endif
611
612 #ifdef SK_DEBUG_SIZE
size() const613 size_t SkPictureRecord::size() const {
614 size_t result = 0;
615 size_t sizeData;
616 bitmaps(&sizeData);
617 result += sizeData;
618 matrices(&sizeData);
619 result += sizeData;
620 paints(&sizeData);
621 result += sizeData;
622 paths(&sizeData);
623 result += sizeData;
624 pictures(&sizeData);
625 result += sizeData;
626 regions(&sizeData);
627 result += sizeData;
628 result += streamlen();
629 return result;
630 }
631
bitmaps(size_t * size) const632 int SkPictureRecord::bitmaps(size_t* size) const {
633 size_t result = 0;
634 int count = fBitmaps.count();
635 for (int index = 0; index < count; index++)
636 result += sizeof(fBitmaps[index]) + fBitmaps[index]->size();
637 *size = result;
638 return count;
639 }
640
matrices(size_t * size) const641 int SkPictureRecord::matrices(size_t* size) const {
642 int count = fMatrices.count();
643 *size = sizeof(fMatrices[0]) * count;
644 return count;
645 }
646
paints(size_t * size) const647 int SkPictureRecord::paints(size_t* size) const {
648 size_t result = 0;
649 int count = fPaints.count();
650 for (int index = 0; index < count; index++)
651 result += sizeof(fPaints[index]) + fPaints[index]->size();
652 *size = result;
653 return count;
654 }
655
paths(size_t * size) const656 int SkPictureRecord::paths(size_t* size) const {
657 size_t result = 0;
658 int count = fPaths.count();
659 for (int index = 0; index < count; index++)
660 result += sizeof(fPaths[index]) + fPaths[index]->size();
661 *size = result;
662 return count;
663 }
664
regions(size_t * size) const665 int SkPictureRecord::regions(size_t* size) const {
666 size_t result = 0;
667 int count = fRegions.count();
668 for (int index = 0; index < count; index++)
669 result += sizeof(fRegions[index]) + fRegions[index]->size();
670 *size = result;
671 return count;
672 }
673
streamlen() const674 size_t SkPictureRecord::streamlen() const {
675 return fWriter.size();
676 }
677 #endif
678
679 #ifdef SK_DEBUG_VALIDATE
validate() const680 void SkPictureRecord::validate() const {
681 validateBitmaps();
682 validateMatrices();
683 validatePaints();
684 validatePaths();
685 validatePictures();
686 validateRegions();
687 }
688
validateBitmaps() const689 void SkPictureRecord::validateBitmaps() const {
690 int count = fBitmaps.count();
691 SkASSERT((unsigned) count < 0x1000);
692 for (int index = 0; index < count; index++) {
693 const SkFlatBitmap* bitPtr = fBitmaps[index];
694 SkASSERT(bitPtr);
695 bitPtr->validate();
696 }
697 }
698
validateMatrices() const699 void SkPictureRecord::validateMatrices() const {
700 int count = fMatrices.count();
701 SkASSERT((unsigned) count < 0x1000);
702 for (int index = 0; index < count; index++) {
703 const SkFlatMatrix* matrix = fMatrices[index];
704 SkASSERT(matrix);
705 matrix->validate();
706 }
707 }
708
validatePaints() const709 void SkPictureRecord::validatePaints() const {
710 int count = fPaints.count();
711 SkASSERT((unsigned) count < 0x1000);
712 for (int index = 0; index < count; index++) {
713 const SkFlatPaint* paint = fPaints[index];
714 SkASSERT(paint);
715 // paint->validate();
716 }
717 }
718
validatePaths() const719 void SkPictureRecord::validatePaths() const {
720 int count = fPaths.count();
721 SkASSERT((unsigned) count < 0x1000);
722 for (int index = 0; index < count; index++) {
723 const SkFlatPath* path = fPaths[index];
724 SkASSERT(path);
725 path->validate();
726 }
727 }
728
validateRegions() const729 void SkPictureRecord::validateRegions() const {
730 int count = fRegions.count();
731 SkASSERT((unsigned) count < 0x1000);
732 for (int index = 0; index < count; index++) {
733 const SkFlatRegion* region = fRegions[index];
734 SkASSERT(region);
735 region->validate();
736 }
737 }
738 #endif
739
740