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