| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 #include "SkPictureRecord.h" | 8 #include "SkPictureRecord.h" |
| 9 #include "SkTSearch.h" | 9 #include "SkTSearch.h" |
| 10 #include "SkPixelRef.h" | 10 #include "SkPixelRef.h" |
| (...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 495 SkDebugf("Collapse [%d out of %d] %g%spn", gCollapseCount, gCollapseCalls, | 495 SkDebugf("Collapse [%d out of %d] %g%spn", gCollapseCount, gCollapseCalls, |
| 496 (double)gCollapseCount / gCollapseCalls, "%"); | 496 (double)gCollapseCount / gCollapseCalls, "%"); |
| 497 #endif | 497 #endif |
| 498 | 498 |
| 499 writer->rewindToOffset(saveOffset); | 499 writer->rewindToOffset(saveOffset); |
| 500 return true; | 500 return true; |
| 501 } | 501 } |
| 502 | 502 |
| 503 typedef bool (*PictureRecordOptProc)(SkWriter32* writer, int32_t offset, | 503 typedef bool (*PictureRecordOptProc)(SkWriter32* writer, int32_t offset, |
| 504 SkPaintDictionary* paintDict); | 504 SkPaintDictionary* paintDict); |
| 505 enum PictureRecordOptType { |
| 506 kRewind_OptType, // Optimization rewinds the command stream |
| 507 kCollapseSaveLayer_OptType, // Optimization eliminates a save/restore pair |
| 508 }; |
| 505 | 509 |
| 510 struct PictureRecordOpt { |
| 511 PictureRecordOptProc fProc; |
| 512 PictureRecordOptType fType; |
| 513 }; |
| 506 /* | 514 /* |
| 507 * A list of the optimizations that are tried upon seeing a restore | 515 * A list of the optimizations that are tried upon seeing a restore |
| 508 * TODO: add a real API for such optimizations | 516 * TODO: add a real API for such optimizations |
| 509 * Add the ability to fire optimizations on any op (not just RESTORE) | 517 * Add the ability to fire optimizations on any op (not just RESTORE) |
| 510 */ | 518 */ |
| 511 static const PictureRecordOptProc gPictureRecordOpts[] = { | 519 static const PictureRecordOpt gPictureRecordOpts[] = { |
| 512 collapse_save_clip_restore, | 520 { collapse_save_clip_restore, kRewind_OptType }, |
| 513 #ifndef SK_IGNORE_PICTURE_RECORD_SAVE_LAYER_OPT | 521 { remove_save_layer1, kCollapseSaveLayer_OptType }, |
| 514 remove_save_layer1, | 522 { remove_save_layer2, kCollapseSaveLayer_OptType } |
| 515 remove_save_layer2, | |
| 516 #endif | |
| 517 }; | 523 }; |
| 518 | 524 |
| 525 // This is called after an optimization has been applied to the command stream |
| 526 // in order to adjust the contents and state of the bounding box hierarchy and |
| 527 // state tree to reflect the optimization. |
| 528 static void apply_optimization_to_bbh(PictureRecordOptType opt, SkPictureStateTr
ee* stateTree, |
| 529 SkBBoxHierarchy* boundingHierarchy) { |
| 530 switch (opt) { |
| 531 case kCollapseSaveLayer_OptType: |
| 532 stateTree->saveCollapsed(); |
| 533 break; |
| 534 case kRewind_OptType: |
| 535 if (NULL != boundingHierarchy) { |
| 536 boundingHierarchy->rewindInserts(); |
| 537 } |
| 538 // Note: No need to touch the state tree for this to work correctly. |
| 539 // Unused branches do not burden the playback, and pruning the tree |
| 540 // would be O(N^2), so it is best to leave it alone. |
| 541 break; |
| 542 default: |
| 543 SkASSERT(0); |
| 544 } |
| 545 } |
| 546 |
| 519 void SkPictureRecord::restore() { | 547 void SkPictureRecord::restore() { |
| 520 // FIXME: SkDeferredCanvas needs to be refactored to respect | 548 // FIXME: SkDeferredCanvas needs to be refactored to respect |
| 521 // save/restore balancing so that the following test can be | 549 // save/restore balancing so that the following test can be |
| 522 // turned on permanently. | 550 // turned on permanently. |
| 523 #if 0 | 551 #if 0 |
| 524 SkASSERT(fRestoreOffsetStack.count() > 1); | 552 SkASSERT(fRestoreOffsetStack.count() > 1); |
| 525 #endif | 553 #endif |
| 526 | 554 |
| 527 // check for underflow | 555 // check for underflow |
| 528 if (fRestoreOffsetStack.count() == 0) { | 556 if (fRestoreOffsetStack.count() == 0) { |
| 529 return; | 557 return; |
| 530 } | 558 } |
| 531 | 559 |
| 532 if (fRestoreOffsetStack.count() == fFirstSavedLayerIndex) { | 560 if (fRestoreOffsetStack.count() == fFirstSavedLayerIndex) { |
| 533 fFirstSavedLayerIndex = kNoSavedLayerIndex; | 561 fFirstSavedLayerIndex = kNoSavedLayerIndex; |
| 534 } | 562 } |
| 535 | 563 |
| 536 uint32_t initialOffset, size; | 564 uint32_t initialOffset, size; |
| 537 size_t opt; | 565 size_t opt; |
| 538 for (opt = 0; opt < SK_ARRAY_COUNT(gPictureRecordOpts); ++opt) { | 566 for (opt = 0; opt < SK_ARRAY_COUNT(gPictureRecordOpts); ++opt) { |
| 539 if ((*gPictureRecordOpts[opt])(&fWriter, fRestoreOffsetStack.top(), &fPa
ints)) { | 567 if ((*gPictureRecordOpts[opt].fProc)(&fWriter, fRestoreOffsetStack.top()
, &fPaints)) { |
| 540 // Some optimization fired so don't add the RESTORE | 568 // Some optimization fired so don't add the RESTORE |
| 541 size = 0; | 569 size = 0; |
| 542 initialOffset = fWriter.size(); | 570 initialOffset = fWriter.size(); |
| 571 apply_optimization_to_bbh(gPictureRecordOpts[opt].fType, |
| 572 fStateTree, fBoundingHierarchy); |
| 543 break; | 573 break; |
| 544 } | 574 } |
| 545 } | 575 } |
| 546 | 576 |
| 547 if (SK_ARRAY_COUNT(gPictureRecordOpts) == opt) { | 577 if (SK_ARRAY_COUNT(gPictureRecordOpts) == opt) { |
| 548 // No optimization fired so add the RESTORE | 578 // No optimization fired so add the RESTORE |
| 549 fillRestoreOffsetPlaceholdersForCurrentStackLevel((uint32_t)fWriter.size
()); | 579 fillRestoreOffsetPlaceholdersForCurrentStackLevel((uint32_t)fWriter.size
()); |
| 550 size = 1 * kUInt32Size; // RESTORE consists solely of 1 op code | 580 size = 1 * kUInt32Size; // RESTORE consists solely of 1 op code |
| 551 initialOffset = this->addDraw(RESTORE, &size); | 581 initialOffset = this->addDraw(RESTORE, &size); |
| 552 } | 582 } |
| (...skipping 862 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1415 void SkPictureRecord::validateRegions() const { | 1445 void SkPictureRecord::validateRegions() const { |
| 1416 int count = fRegions.count(); | 1446 int count = fRegions.count(); |
| 1417 SkASSERT((unsigned) count < 0x1000); | 1447 SkASSERT((unsigned) count < 0x1000); |
| 1418 for (int index = 0; index < count; index++) { | 1448 for (int index = 0; index < count; index++) { |
| 1419 const SkFlatData* region = fRegions[index]; | 1449 const SkFlatData* region = fRegions[index]; |
| 1420 SkASSERT(region); | 1450 SkASSERT(region); |
| 1421 // region->validate(); | 1451 // region->validate(); |
| 1422 } | 1452 } |
| 1423 } | 1453 } |
| 1424 #endif | 1454 #endif |
| OLD | NEW |