• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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