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