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
clear(SkColor color)169 void SkPictureRecord::clear(SkColor color) {
170 addDraw(DRAW_CLEAR);
171 addInt(color);
172 validate();
173 }
174
drawPaint(const SkPaint & paint)175 void SkPictureRecord::drawPaint(const SkPaint& paint) {
176 addDraw(DRAW_PAINT);
177 addPaint(paint);
178 validate();
179 }
180
drawPoints(PointMode mode,size_t count,const SkPoint pts[],const SkPaint & paint)181 void SkPictureRecord::drawPoints(PointMode mode, size_t count, const SkPoint pts[],
182 const SkPaint& paint) {
183 addDraw(DRAW_POINTS);
184 addPaint(paint);
185 addInt(mode);
186 addInt(count);
187 fWriter.writeMul4(pts, count * sizeof(SkPoint));
188 validate();
189 }
190
drawRect(const SkRect & rect,const SkPaint & paint)191 void SkPictureRecord::drawRect(const SkRect& rect, const SkPaint& paint) {
192 addDraw(DRAW_RECT);
193 addPaint(paint);
194 addRect(rect);
195 validate();
196 }
197
drawPath(const SkPath & path,const SkPaint & paint)198 void SkPictureRecord::drawPath(const SkPath& path, const SkPaint& paint) {
199 addDraw(DRAW_PATH);
200 addPaint(paint);
201 addPath(path);
202 validate();
203 }
204
drawBitmap(const SkBitmap & bitmap,SkScalar left,SkScalar top,const SkPaint * paint=NULL)205 void SkPictureRecord::drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
206 const SkPaint* paint = NULL) {
207 addDraw(DRAW_BITMAP);
208 addPaintPtr(paint);
209 addBitmap(bitmap);
210 addScalar(left);
211 addScalar(top);
212 validate();
213 }
214
drawBitmapRect(const SkBitmap & bitmap,const SkIRect * src,const SkRect & dst,const SkPaint * paint)215 void SkPictureRecord::drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
216 const SkRect& dst, const SkPaint* paint) {
217 addDraw(DRAW_BITMAP_RECT);
218 addPaintPtr(paint);
219 addBitmap(bitmap);
220 addIRectPtr(src); // may be null
221 addRect(dst);
222 validate();
223 }
224
drawBitmapMatrix(const SkBitmap & bitmap,const SkMatrix & matrix,const SkPaint * paint)225 void SkPictureRecord::drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& matrix,
226 const SkPaint* paint) {
227 addDraw(DRAW_BITMAP_MATRIX);
228 addPaintPtr(paint);
229 addBitmap(bitmap);
230 addMatrix(matrix);
231 validate();
232 }
233
drawSprite(const SkBitmap & bitmap,int left,int top,const SkPaint * paint=NULL)234 void SkPictureRecord::drawSprite(const SkBitmap& bitmap, int left, int top,
235 const SkPaint* paint = NULL) {
236 addDraw(DRAW_SPRITE);
237 addPaintPtr(paint);
238 addBitmap(bitmap);
239 addInt(left);
240 addInt(top);
241 validate();
242 }
243
addFontMetricsTopBottom(const SkPaint & paint,SkScalar baselineY)244 void SkPictureRecord::addFontMetricsTopBottom(const SkPaint& paint,
245 SkScalar baselineY) {
246 SkPaint::FontMetrics metrics;
247 paint.getFontMetrics(&metrics);
248 SkRect bounds;
249 // construct a rect so we can see any adjustments from the paint.
250 // we use 0,1 for left,right, just so the rect isn't empty
251 bounds.set(0, metrics.fTop + baselineY,
252 SK_Scalar1, metrics.fBottom + baselineY);
253 (void)paint.computeFastBounds(bounds, &bounds);
254 // now record the top and bottom
255 addScalar(bounds.fTop);
256 addScalar(bounds.fBottom);
257 }
258
drawText(const void * text,size_t byteLength,SkScalar x,SkScalar y,const SkPaint & paint)259 void SkPictureRecord::drawText(const void* text, size_t byteLength, SkScalar x,
260 SkScalar y, const SkPaint& paint) {
261 bool fast = paint.canComputeFastBounds();
262
263 addDraw(fast ? DRAW_TEXT_TOP_BOTTOM : DRAW_TEXT);
264 addPaint(paint);
265 addText(text, byteLength);
266 addScalar(x);
267 addScalar(y);
268 if (fast) {
269 addFontMetricsTopBottom(paint, y);
270 }
271 validate();
272 }
273
drawPosText(const void * text,size_t byteLength,const SkPoint pos[],const SkPaint & paint)274 void SkPictureRecord::drawPosText(const void* text, size_t byteLength,
275 const SkPoint pos[], const SkPaint& paint) {
276 size_t points = paint.countText(text, byteLength);
277 if (0 == points)
278 return;
279
280 bool canUseDrawH = true;
281 // check if the caller really should have used drawPosTextH()
282 {
283 const SkScalar firstY = pos[0].fY;
284 for (size_t index = 1; index < points; index++) {
285 if (pos[index].fY != firstY) {
286 canUseDrawH = false;
287 break;
288 }
289 }
290 }
291
292 bool fast = canUseDrawH && paint.canComputeFastBounds();
293
294 if (fast) {
295 addDraw(DRAW_POS_TEXT_H_TOP_BOTTOM);
296 } else {
297 addDraw(canUseDrawH ? DRAW_POS_TEXT_H : DRAW_POS_TEXT);
298 }
299 addPaint(paint);
300 addText(text, byteLength);
301 addInt(points);
302
303 #ifdef SK_DEBUG_SIZE
304 size_t start = fWriter.size();
305 #endif
306 if (canUseDrawH) {
307 if (fast) {
308 addFontMetricsTopBottom(paint, pos[0].fY);
309 }
310 addScalar(pos[0].fY);
311 SkScalar* xptr = (SkScalar*)fWriter.reserve(points * sizeof(SkScalar));
312 for (size_t index = 0; index < points; index++)
313 *xptr++ = pos[index].fX;
314 }
315 else {
316 fWriter.writeMul4(pos, points * sizeof(SkPoint));
317 }
318 #ifdef SK_DEBUG_SIZE
319 fPointBytes += fWriter.size() - start;
320 fPointWrites += points;
321 #endif
322 validate();
323 }
324
drawPosTextH(const void * text,size_t byteLength,const SkScalar xpos[],SkScalar constY,const SkPaint & paint)325 void SkPictureRecord::drawPosTextH(const void* text, size_t byteLength,
326 const SkScalar xpos[], SkScalar constY,
327 const SkPaint& paint) {
328 size_t points = paint.countText(text, byteLength);
329 if (0 == points)
330 return;
331
332 bool fast = paint.canComputeFastBounds();
333
334 addDraw(fast ? DRAW_POS_TEXT_H_TOP_BOTTOM : DRAW_POS_TEXT_H);
335 addPaint(paint);
336 addText(text, byteLength);
337 addInt(points);
338
339 #ifdef SK_DEBUG_SIZE
340 size_t start = fWriter.size();
341 #endif
342 if (fast) {
343 addFontMetricsTopBottom(paint, constY);
344 }
345 addScalar(constY);
346 fWriter.writeMul4(xpos, points * sizeof(SkScalar));
347 #ifdef SK_DEBUG_SIZE
348 fPointBytes += fWriter.size() - start;
349 fPointWrites += points;
350 #endif
351 validate();
352 }
353
drawTextOnPath(const void * text,size_t byteLength,const SkPath & path,const SkMatrix * matrix,const SkPaint & paint)354 void SkPictureRecord::drawTextOnPath(const void* text, size_t byteLength,
355 const SkPath& path, const SkMatrix* matrix,
356 const SkPaint& paint) {
357 addDraw(DRAW_TEXT_ON_PATH);
358 addPaint(paint);
359 addText(text, byteLength);
360 addPath(path);
361 addMatrixPtr(matrix);
362 validate();
363 }
364
drawPicture(SkPicture & picture)365 void SkPictureRecord::drawPicture(SkPicture& picture) {
366 addDraw(DRAW_PICTURE);
367 addPicture(picture);
368 validate();
369 }
370
drawShape(SkShape * shape)371 void SkPictureRecord::drawShape(SkShape* shape) {
372 addDraw(DRAW_SHAPE);
373
374 int index = fShapes.find(shape);
375 if (index < 0) { // not found
376 index = fShapes.count();
377 *fShapes.append() = shape;
378 shape->ref();
379 }
380 // follow the convention of recording a 1-based index
381 addInt(index + 1);
382 validate();
383 }
384
drawVertices(VertexMode vmode,int vertexCount,const SkPoint vertices[],const SkPoint texs[],const SkColor colors[],SkXfermode *,const uint16_t indices[],int indexCount,const SkPaint & paint)385 void SkPictureRecord::drawVertices(VertexMode vmode, int vertexCount,
386 const SkPoint vertices[], const SkPoint texs[],
387 const SkColor colors[], SkXfermode*,
388 const uint16_t indices[], int indexCount,
389 const SkPaint& paint) {
390 uint32_t flags = 0;
391 if (texs) {
392 flags |= DRAW_VERTICES_HAS_TEXS;
393 }
394 if (colors) {
395 flags |= DRAW_VERTICES_HAS_COLORS;
396 }
397 if (indexCount > 0) {
398 flags |= DRAW_VERTICES_HAS_INDICES;
399 }
400
401 addDraw(DRAW_VERTICES);
402 addPaint(paint);
403 addInt(flags);
404 addInt(vmode);
405 addInt(vertexCount);
406 addPoints(vertices, vertexCount);
407 if (flags & DRAW_VERTICES_HAS_TEXS) {
408 addPoints(texs, vertexCount);
409 }
410 if (flags & DRAW_VERTICES_HAS_COLORS) {
411 fWriter.writeMul4(colors, vertexCount * sizeof(SkColor));
412 }
413 if (flags & DRAW_VERTICES_HAS_INDICES) {
414 addInt(indexCount);
415 fWriter.writePad(indices, indexCount * sizeof(uint16_t));
416 }
417 }
418
drawData(const void * data,size_t length)419 void SkPictureRecord::drawData(const void* data, size_t length) {
420 addDraw(DRAW_DATA);
421 addInt(length);
422 fWriter.writePad(data, length);
423 }
424
425 ///////////////////////////////////////////////////////////////////////////////
426
reset()427 void SkPictureRecord::reset() {
428 SkSafeUnref(fPathHeap);
429 fPathHeap = NULL;
430
431 fBitmaps.reset();
432 fMatrices.reset();
433 fPaints.reset();
434 fPictureRefs.unrefAll();
435 fRegions.reset();
436 fShapes.safeUnrefAll();
437 fWriter.reset();
438 fHeap.reset();
439
440 fRestoreOffsetStack.setCount(1);
441 fRestoreOffsetStack.top() = 0;
442
443 fRCSet.reset();
444 fTFSet.reset();
445 }
446
addBitmap(const SkBitmap & bitmap)447 void SkPictureRecord::addBitmap(const SkBitmap& bitmap) {
448 addInt(find(fBitmaps, bitmap));
449 }
450
addMatrix(const SkMatrix & matrix)451 void SkPictureRecord::addMatrix(const SkMatrix& matrix) {
452 addMatrixPtr(&matrix);
453 }
454
addMatrixPtr(const SkMatrix * matrix)455 void SkPictureRecord::addMatrixPtr(const SkMatrix* matrix) {
456 addInt(find(fMatrices, matrix));
457 }
458
addPaint(const SkPaint & paint)459 void SkPictureRecord::addPaint(const SkPaint& paint) {
460 addPaintPtr(&paint);
461 }
462
addPaintPtr(const SkPaint * paint)463 void SkPictureRecord::addPaintPtr(const SkPaint* paint) {
464 addInt(find(fPaints, paint));
465 }
466
addPath(const SkPath & path)467 void SkPictureRecord::addPath(const SkPath& path) {
468 if (NULL == fPathHeap) {
469 fPathHeap = SkNEW(SkPathHeap);
470 }
471 addInt(fPathHeap->append(path));
472 }
473
addPicture(SkPicture & picture)474 void SkPictureRecord::addPicture(SkPicture& picture) {
475 int index = fPictureRefs.find(&picture);
476 if (index < 0) { // not found
477 index = fPictureRefs.count();
478 *fPictureRefs.append() = &picture;
479 picture.ref();
480 }
481 // follow the convention of recording a 1-based index
482 addInt(index + 1);
483 }
484
addPoint(const SkPoint & point)485 void SkPictureRecord::addPoint(const SkPoint& point) {
486 #ifdef SK_DEBUG_SIZE
487 size_t start = fWriter.size();
488 #endif
489 fWriter.writePoint(point);
490 #ifdef SK_DEBUG_SIZE
491 fPointBytes += fWriter.size() - start;
492 fPointWrites++;
493 #endif
494 }
495
addPoints(const SkPoint pts[],int count)496 void SkPictureRecord::addPoints(const SkPoint pts[], int count) {
497 fWriter.writeMul4(pts, count * sizeof(SkPoint));
498 #ifdef SK_DEBUG_SIZE
499 fPointBytes += count * sizeof(SkPoint);
500 fPointWrites++;
501 #endif
502 }
503
addRect(const SkRect & rect)504 void SkPictureRecord::addRect(const SkRect& rect) {
505 #ifdef SK_DEBUG_SIZE
506 size_t start = fWriter.size();
507 #endif
508 fWriter.writeRect(rect);
509 #ifdef SK_DEBUG_SIZE
510 fRectBytes += fWriter.size() - start;
511 fRectWrites++;
512 #endif
513 }
514
addRectPtr(const SkRect * rect)515 void SkPictureRecord::addRectPtr(const SkRect* rect) {
516 if (fWriter.writeBool(rect != NULL)) {
517 fWriter.writeRect(*rect);
518 }
519 }
520
addIRectPtr(const SkIRect * rect)521 void SkPictureRecord::addIRectPtr(const SkIRect* rect) {
522 if (fWriter.writeBool(rect != NULL)) {
523 *(SkIRect*)fWriter.reserve(sizeof(SkIRect)) = *rect;
524 }
525 }
526
addRegion(const SkRegion & region)527 void SkPictureRecord::addRegion(const SkRegion& region) {
528 addInt(find(fRegions, region));
529 }
530
addText(const void * text,size_t byteLength)531 void SkPictureRecord::addText(const void* text, size_t byteLength) {
532 #ifdef SK_DEBUG_SIZE
533 size_t start = fWriter.size();
534 #endif
535 addInt(byteLength);
536 fWriter.writePad(text, byteLength);
537 #ifdef SK_DEBUG_SIZE
538 fTextBytes += fWriter.size() - start;
539 fTextWrites++;
540 #endif
541 }
542
543 ///////////////////////////////////////////////////////////////////////////////
544
find(SkTDArray<const SkFlatBitmap * > & bitmaps,const SkBitmap & bitmap)545 int SkPictureRecord::find(SkTDArray<const SkFlatBitmap* >& bitmaps, const SkBitmap& bitmap) {
546 SkFlatBitmap* flat = SkFlatBitmap::Flatten(&fHeap, bitmap, fBitmapIndex,
547 &fRCSet);
548 int index = SkTSearch<SkFlatData>((const SkFlatData**) bitmaps.begin(),
549 bitmaps.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare);
550 if (index >= 0) {
551 (void)fHeap.unalloc(flat);
552 return bitmaps[index]->index();
553 }
554 index = ~index;
555 *bitmaps.insert(index) = flat;
556 return fBitmapIndex++;
557 }
558
find(SkTDArray<const SkFlatMatrix * > & matrices,const SkMatrix * matrix)559 int SkPictureRecord::find(SkTDArray<const SkFlatMatrix* >& matrices, const SkMatrix* matrix) {
560 if (matrix == NULL)
561 return 0;
562 SkFlatMatrix* flat = SkFlatMatrix::Flatten(&fHeap, *matrix, fMatrixIndex);
563 int index = SkTSearch<SkFlatData>((const SkFlatData**) matrices.begin(),
564 matrices.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare);
565 if (index >= 0) {
566 (void)fHeap.unalloc(flat);
567 return matrices[index]->index();
568 }
569 index = ~index;
570 *matrices.insert(index) = flat;
571 return fMatrixIndex++;
572 }
573
find(SkTDArray<const SkFlatPaint * > & paints,const SkPaint * paint)574 int SkPictureRecord::find(SkTDArray<const SkFlatPaint* >& paints, const SkPaint* paint) {
575 if (paint == NULL) {
576 return 0;
577 }
578
579 SkFlatPaint* flat = SkFlatPaint::Flatten(&fHeap, *paint, fPaintIndex,
580 &fRCSet, &fTFSet);
581 int index = SkTSearch<SkFlatData>((const SkFlatData**) paints.begin(),
582 paints.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare);
583 if (index >= 0) {
584 (void)fHeap.unalloc(flat);
585 return paints[index]->index();
586 }
587
588 index = ~index;
589 *paints.insert(index) = flat;
590 return fPaintIndex++;
591 }
592
find(SkTDArray<const SkFlatRegion * > & regions,const SkRegion & region)593 int SkPictureRecord::find(SkTDArray<const SkFlatRegion* >& regions, const SkRegion& region) {
594 SkFlatRegion* flat = SkFlatRegion::Flatten(&fHeap, region, fRegionIndex);
595 int index = SkTSearch<SkFlatData>((const SkFlatData**) regions.begin(),
596 regions.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare);
597 if (index >= 0) {
598 (void)fHeap.unalloc(flat);
599 return regions[index]->index();
600 }
601 index = ~index;
602 *regions.insert(index) = flat;
603 return fRegionIndex++;
604 }
605
606 #ifdef SK_DEBUG_DUMP
dumpMatrices()607 void SkPictureRecord::dumpMatrices() {
608 int count = fMatrices.count();
609 SkMatrix defaultMatrix;
610 defaultMatrix.reset();
611 for (int index = 0; index < count; index++) {
612 const SkFlatMatrix* flatMatrix = fMatrices[index];
613 flatMatrix->dump();
614 }
615 }
616
dumpPaints()617 void SkPictureRecord::dumpPaints() {
618 int count = fPaints.count();
619 for (int index = 0; index < count; index++)
620 fPaints[index]->dump();
621 }
622 #endif
623
624 #ifdef SK_DEBUG_SIZE
size() const625 size_t SkPictureRecord::size() const {
626 size_t result = 0;
627 size_t sizeData;
628 bitmaps(&sizeData);
629 result += sizeData;
630 matrices(&sizeData);
631 result += sizeData;
632 paints(&sizeData);
633 result += sizeData;
634 paths(&sizeData);
635 result += sizeData;
636 pictures(&sizeData);
637 result += sizeData;
638 regions(&sizeData);
639 result += sizeData;
640 result += streamlen();
641 return result;
642 }
643
bitmaps(size_t * size) const644 int SkPictureRecord::bitmaps(size_t* size) const {
645 size_t result = 0;
646 int count = fBitmaps.count();
647 for (int index = 0; index < count; index++)
648 result += sizeof(fBitmaps[index]) + fBitmaps[index]->size();
649 *size = result;
650 return count;
651 }
652
matrices(size_t * size) const653 int SkPictureRecord::matrices(size_t* size) const {
654 int count = fMatrices.count();
655 *size = sizeof(fMatrices[0]) * count;
656 return count;
657 }
658
paints(size_t * size) const659 int SkPictureRecord::paints(size_t* size) const {
660 size_t result = 0;
661 int count = fPaints.count();
662 for (int index = 0; index < count; index++)
663 result += sizeof(fPaints[index]) + fPaints[index]->size();
664 *size = result;
665 return count;
666 }
667
paths(size_t * size) const668 int SkPictureRecord::paths(size_t* size) const {
669 size_t result = 0;
670 int count = fPaths.count();
671 for (int index = 0; index < count; index++)
672 result += sizeof(fPaths[index]) + fPaths[index]->size();
673 *size = result;
674 return count;
675 }
676
regions(size_t * size) const677 int SkPictureRecord::regions(size_t* size) const {
678 size_t result = 0;
679 int count = fRegions.count();
680 for (int index = 0; index < count; index++)
681 result += sizeof(fRegions[index]) + fRegions[index]->size();
682 *size = result;
683 return count;
684 }
685
streamlen() const686 size_t SkPictureRecord::streamlen() const {
687 return fWriter.size();
688 }
689 #endif
690
691 #ifdef SK_DEBUG_VALIDATE
validate() const692 void SkPictureRecord::validate() const {
693 validateBitmaps();
694 validateMatrices();
695 validatePaints();
696 validatePaths();
697 validatePictures();
698 validateRegions();
699 }
700
validateBitmaps() const701 void SkPictureRecord::validateBitmaps() const {
702 int count = fBitmaps.count();
703 SkASSERT((unsigned) count < 0x1000);
704 for (int index = 0; index < count; index++) {
705 const SkFlatBitmap* bitPtr = fBitmaps[index];
706 SkASSERT(bitPtr);
707 bitPtr->validate();
708 }
709 }
710
validateMatrices() const711 void SkPictureRecord::validateMatrices() const {
712 int count = fMatrices.count();
713 SkASSERT((unsigned) count < 0x1000);
714 for (int index = 0; index < count; index++) {
715 const SkFlatMatrix* matrix = fMatrices[index];
716 SkASSERT(matrix);
717 matrix->validate();
718 }
719 }
720
validatePaints() const721 void SkPictureRecord::validatePaints() const {
722 int count = fPaints.count();
723 SkASSERT((unsigned) count < 0x1000);
724 for (int index = 0; index < count; index++) {
725 const SkFlatPaint* paint = fPaints[index];
726 SkASSERT(paint);
727 // paint->validate();
728 }
729 }
730
validatePaths() const731 void SkPictureRecord::validatePaths() const {
732 int count = fPaths.count();
733 SkASSERT((unsigned) count < 0x1000);
734 for (int index = 0; index < count; index++) {
735 const SkFlatPath* path = fPaths[index];
736 SkASSERT(path);
737 path->validate();
738 }
739 }
740
validateRegions() const741 void SkPictureRecord::validateRegions() const {
742 int count = fRegions.count();
743 SkASSERT((unsigned) count < 0x1000);
744 for (int index = 0; index < count; index++) {
745 const SkFlatRegion* region = fRegions[index];
746 SkASSERT(region);
747 region->validate();
748 }
749 }
750 #endif
751
752