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