• 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 
drawData(const void * data,size_t length)413 void SkPictureRecord::drawData(const void* data, size_t length) {
414     addDraw(DRAW_DATA);
415     addInt(length);
416     fWriter.writePad(data, length);
417 }
418 
419 ///////////////////////////////////////////////////////////////////////////////
420 
reset()421 void SkPictureRecord::reset() {
422     fPathHeap->safeUnref();
423     fPathHeap = NULL;
424 
425     fBitmaps.reset();
426     fMatrices.reset();
427     fPaints.reset();
428     fPictureRefs.unrefAll();
429     fRegions.reset();
430     fShapes.safeUnrefAll();
431     fWriter.reset();
432     fHeap.reset();
433 
434     fRestoreOffsetStack.setCount(1);
435     fRestoreOffsetStack.top() = 0;
436 
437     fRCRecorder.reset();
438     fTFRecorder.reset();
439 }
440 
addBitmap(const SkBitmap & bitmap)441 void SkPictureRecord::addBitmap(const SkBitmap& bitmap) {
442     addInt(find(fBitmaps, bitmap));
443 }
444 
addMatrix(const SkMatrix & matrix)445 void SkPictureRecord::addMatrix(const SkMatrix& matrix) {
446     addMatrixPtr(&matrix);
447 }
448 
addMatrixPtr(const SkMatrix * matrix)449 void SkPictureRecord::addMatrixPtr(const SkMatrix* matrix) {
450     addInt(find(fMatrices, matrix));
451 }
452 
addPaint(const SkPaint & paint)453 void SkPictureRecord::addPaint(const SkPaint& paint) {
454     addPaintPtr(&paint);
455 }
456 
addPaintPtr(const SkPaint * paint)457 void SkPictureRecord::addPaintPtr(const SkPaint* paint) {
458     addInt(find(fPaints, paint));
459 }
460 
addPath(const SkPath & path)461 void SkPictureRecord::addPath(const SkPath& path) {
462     if (NULL == fPathHeap) {
463         fPathHeap = SkNEW(SkPathHeap);
464     }
465     addInt(fPathHeap->append(path));
466 }
467 
addPicture(SkPicture & picture)468 void SkPictureRecord::addPicture(SkPicture& picture) {
469     int index = fPictureRefs.find(&picture);
470     if (index < 0) {    // not found
471         index = fPictureRefs.count();
472         *fPictureRefs.append() = &picture;
473         picture.ref();
474     }
475     // follow the convention of recording a 1-based index
476     addInt(index + 1);
477 }
478 
addPoint(const SkPoint & point)479 void SkPictureRecord::addPoint(const SkPoint& point) {
480 #ifdef SK_DEBUG_SIZE
481     size_t start = fWriter.size();
482 #endif
483     fWriter.writePoint(point);
484 #ifdef SK_DEBUG_SIZE
485     fPointBytes += fWriter.size() - start;
486     fPointWrites++;
487 #endif
488 }
489 
addPoints(const SkPoint pts[],int count)490 void SkPictureRecord::addPoints(const SkPoint pts[], int count) {
491     fWriter.writeMul4(pts, count * sizeof(SkPoint));
492 #ifdef SK_DEBUG_SIZE
493     fPointBytes += count * sizeof(SkPoint);
494     fPointWrites++;
495 #endif
496 }
497 
addRect(const SkRect & rect)498 void SkPictureRecord::addRect(const SkRect& rect) {
499 #ifdef SK_DEBUG_SIZE
500     size_t start = fWriter.size();
501 #endif
502     fWriter.writeRect(rect);
503 #ifdef SK_DEBUG_SIZE
504     fRectBytes += fWriter.size() - start;
505     fRectWrites++;
506 #endif
507 }
508 
addRectPtr(const SkRect * rect)509 void SkPictureRecord::addRectPtr(const SkRect* rect) {
510     if (fWriter.writeBool(rect != NULL)) {
511         fWriter.writeRect(*rect);
512     }
513 }
514 
addIRectPtr(const SkIRect * rect)515 void SkPictureRecord::addIRectPtr(const SkIRect* rect) {
516     if (fWriter.writeBool(rect != NULL)) {
517         *(SkIRect*)fWriter.reserve(sizeof(SkIRect)) = *rect;
518     }
519 }
520 
addRegion(const SkRegion & region)521 void SkPictureRecord::addRegion(const SkRegion& region) {
522     addInt(find(fRegions, region));
523 }
524 
addText(const void * text,size_t byteLength)525 void SkPictureRecord::addText(const void* text, size_t byteLength) {
526 #ifdef SK_DEBUG_SIZE
527     size_t start = fWriter.size();
528 #endif
529     addInt(byteLength);
530     fWriter.writePad(text, byteLength);
531 #ifdef SK_DEBUG_SIZE
532     fTextBytes += fWriter.size() - start;
533     fTextWrites++;
534 #endif
535 }
536 
537 ///////////////////////////////////////////////////////////////////////////////
538 
find(SkTDArray<const SkFlatBitmap * > & bitmaps,const SkBitmap & bitmap)539 int SkPictureRecord::find(SkTDArray<const SkFlatBitmap* >& bitmaps, const SkBitmap& bitmap) {
540     SkFlatBitmap* flat = SkFlatBitmap::Flatten(&fHeap, bitmap, fBitmapIndex,
541                                                &fRCRecorder);
542     int index = SkTSearch<SkFlatData>((const SkFlatData**) bitmaps.begin(),
543         bitmaps.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare);
544     if (index >= 0) {
545         (void)fHeap.unalloc(flat);
546         return bitmaps[index]->index();
547     }
548     index = ~index;
549     *bitmaps.insert(index) = flat;
550     return fBitmapIndex++;
551 }
552 
find(SkTDArray<const SkFlatMatrix * > & matrices,const SkMatrix * matrix)553 int SkPictureRecord::find(SkTDArray<const SkFlatMatrix* >& matrices, const SkMatrix* matrix) {
554     if (matrix == NULL)
555         return 0;
556     SkFlatMatrix* flat = SkFlatMatrix::Flatten(&fHeap, *matrix, fMatrixIndex);
557     int index = SkTSearch<SkFlatData>((const SkFlatData**) matrices.begin(),
558         matrices.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare);
559     if (index >= 0) {
560         (void)fHeap.unalloc(flat);
561         return matrices[index]->index();
562     }
563     index = ~index;
564     *matrices.insert(index) = flat;
565     return fMatrixIndex++;
566 }
567 
find(SkTDArray<const SkFlatPaint * > & paints,const SkPaint * paint)568 int SkPictureRecord::find(SkTDArray<const SkFlatPaint* >& paints, const SkPaint* paint) {
569     if (paint == NULL) {
570         return 0;
571     }
572 
573     SkFlatPaint* flat = SkFlatPaint::Flatten(&fHeap, *paint, fPaintIndex,
574                                              &fRCRecorder, &fTFRecorder);
575     int index = SkTSearch<SkFlatData>((const SkFlatData**) paints.begin(),
576         paints.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare);
577     if (index >= 0) {
578         (void)fHeap.unalloc(flat);
579         return paints[index]->index();
580     }
581 
582     index = ~index;
583     *paints.insert(index) = flat;
584     return fPaintIndex++;
585 }
586 
find(SkTDArray<const SkFlatRegion * > & regions,const SkRegion & region)587 int SkPictureRecord::find(SkTDArray<const SkFlatRegion* >& regions, const SkRegion& region) {
588     SkFlatRegion* flat = SkFlatRegion::Flatten(&fHeap, region, fRegionIndex);
589     int index = SkTSearch<SkFlatData>((const SkFlatData**) regions.begin(),
590         regions.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare);
591     if (index >= 0) {
592         (void)fHeap.unalloc(flat);
593         return regions[index]->index();
594     }
595     index = ~index;
596     *regions.insert(index) = flat;
597     return fRegionIndex++;
598 }
599 
600 #ifdef SK_DEBUG_DUMP
dumpMatrices()601 void SkPictureRecord::dumpMatrices() {
602     int count = fMatrices.count();
603     SkMatrix defaultMatrix;
604     defaultMatrix.reset();
605     for (int index = 0; index < count; index++) {
606         const SkFlatMatrix* flatMatrix = fMatrices[index];
607         flatMatrix->dump();
608     }
609 }
610 
dumpPaints()611 void SkPictureRecord::dumpPaints() {
612     int count = fPaints.count();
613     for (int index = 0; index < count; index++)
614         fPaints[index]->dump();
615 }
616 #endif
617 
618 #ifdef SK_DEBUG_SIZE
size() const619 size_t SkPictureRecord::size() const {
620     size_t result = 0;
621     size_t sizeData;
622     bitmaps(&sizeData);
623     result += sizeData;
624     matrices(&sizeData);
625     result += sizeData;
626     paints(&sizeData);
627     result += sizeData;
628     paths(&sizeData);
629     result += sizeData;
630     pictures(&sizeData);
631     result += sizeData;
632     regions(&sizeData);
633     result += sizeData;
634     result += streamlen();
635     return result;
636 }
637 
bitmaps(size_t * size) const638 int SkPictureRecord::bitmaps(size_t* size) const {
639     size_t result = 0;
640     int count = fBitmaps.count();
641     for (int index = 0; index < count; index++)
642         result += sizeof(fBitmaps[index]) + fBitmaps[index]->size();
643     *size = result;
644     return count;
645 }
646 
matrices(size_t * size) const647 int SkPictureRecord::matrices(size_t* size) const {
648     int count = fMatrices.count();
649     *size = sizeof(fMatrices[0]) * count;
650     return count;
651 }
652 
paints(size_t * size) const653 int SkPictureRecord::paints(size_t* size) const {
654     size_t result = 0;
655     int count = fPaints.count();
656     for (int index = 0; index < count; index++)
657         result += sizeof(fPaints[index]) + fPaints[index]->size();
658     *size = result;
659     return count;
660 }
661 
paths(size_t * size) const662 int SkPictureRecord::paths(size_t* size) const {
663     size_t result = 0;
664     int count = fPaths.count();
665     for (int index = 0; index < count; index++)
666         result += sizeof(fPaths[index]) + fPaths[index]->size();
667     *size = result;
668     return count;
669 }
670 
regions(size_t * size) const671 int SkPictureRecord::regions(size_t* size) const {
672     size_t result = 0;
673     int count = fRegions.count();
674     for (int index = 0; index < count; index++)
675         result += sizeof(fRegions[index]) + fRegions[index]->size();
676     *size = result;
677     return count;
678 }
679 
streamlen() const680 size_t SkPictureRecord::streamlen() const {
681     return fWriter.size();
682 }
683 #endif
684 
685 #ifdef SK_DEBUG_VALIDATE
validate() const686 void SkPictureRecord::validate() const {
687     validateBitmaps();
688     validateMatrices();
689     validatePaints();
690     validatePaths();
691     validatePictures();
692     validateRegions();
693 }
694 
validateBitmaps() const695 void SkPictureRecord::validateBitmaps() const {
696     int count = fBitmaps.count();
697     SkASSERT((unsigned) count < 0x1000);
698     for (int index = 0; index < count; index++) {
699         const SkFlatBitmap* bitPtr = fBitmaps[index];
700         SkASSERT(bitPtr);
701         bitPtr->validate();
702     }
703 }
704 
validateMatrices() const705 void SkPictureRecord::validateMatrices() const {
706     int count = fMatrices.count();
707     SkASSERT((unsigned) count < 0x1000);
708     for (int index = 0; index < count; index++) {
709         const SkFlatMatrix* matrix = fMatrices[index];
710         SkASSERT(matrix);
711         matrix->validate();
712     }
713 }
714 
validatePaints() const715 void SkPictureRecord::validatePaints() const {
716     int count = fPaints.count();
717     SkASSERT((unsigned) count < 0x1000);
718     for (int index = 0; index < count; index++) {
719         const SkFlatPaint* paint = fPaints[index];
720         SkASSERT(paint);
721 //            paint->validate();
722     }
723 }
724 
validatePaths() const725 void SkPictureRecord::validatePaths() const {
726     int count = fPaths.count();
727     SkASSERT((unsigned) count < 0x1000);
728     for (int index = 0; index < count; index++) {
729         const SkFlatPath* path = fPaths[index];
730         SkASSERT(path);
731         path->validate();
732     }
733 }
734 
validateRegions() const735 void SkPictureRecord::validateRegions() const {
736     int count = fRegions.count();
737     SkASSERT((unsigned) count < 0x1000);
738     for (int index = 0; index < count; index++) {
739         const SkFlatRegion* region = fRegions[index];
740         SkASSERT(region);
741         region->validate();
742     }
743 }
744 #endif
745 
746