| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkLayerInfo.h" | 8 #include "SkLayerInfo.h" |
| 9 #include "SkRecordDraw.h" | 9 #include "SkRecordDraw.h" |
| 10 #include "SkPatchUtils.h" | 10 #include "SkPatchUtils.h" |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 143 // non-drawing ("control") ops inside are exactly the union of the bounds of | 143 // non-drawing ("control") ops inside are exactly the union of the bounds of |
| 144 // the drawing ops inside that block. | 144 // the drawing ops inside that block. |
| 145 // | 145 // |
| 146 // To implement this, we keep a stack of active Save blocks. As we consume ops | 146 // To implement this, we keep a stack of active Save blocks. As we consume ops |
| 147 // inside the Save/Restore block, drawing ops are unioned with the bounds of | 147 // inside the Save/Restore block, drawing ops are unioned with the bounds of |
| 148 // the block, and control ops are stashed away for later. When we finish the | 148 // the block, and control ops are stashed away for later. When we finish the |
| 149 // block with a Restore, our bounds are complete, and we go back and fill them | 149 // block with a Restore, our bounds are complete, and we go back and fill them |
| 150 // in for all the control ops we stashed away. | 150 // in for all the control ops we stashed away. |
| 151 class FillBounds : SkNoncopyable { | 151 class FillBounds : SkNoncopyable { |
| 152 public: | 152 public: |
| 153 FillBounds(const SkRect& cullRect, const SkRecord& record) | 153 FillBounds(const SkRect& cullRect, const SkRecord& record, SkRect bounds[]) |
| 154 : fNumRecords(record.count()) | 154 : fNumRecords(record.count()) |
| 155 , fCullRect(cullRect) | 155 , fCullRect(cullRect) |
| 156 , fBounds(record.count()) | 156 , fBounds(bounds) { |
| 157 { | |
| 158 // Calculate bounds for all ops. This won't go quite in order, so we'll
need | |
| 159 // to store the bounds separately then feed them in to the BBH later in
order. | |
| 160 fCTM = &SkMatrix::I(); | 157 fCTM = &SkMatrix::I(); |
| 161 fCurrentClipBounds = fCullRect; | 158 fCurrentClipBounds = fCullRect; |
| 162 } | 159 } |
| 163 | 160 |
| 164 void setCurrentOp(int currentOp) { fCurrentOp = currentOp; } | 161 void cleanUp() { |
| 165 | |
| 166 void cleanUp(SkBBoxHierarchy* bbh) { | |
| 167 // If we have any lingering unpaired Saves, simulate restores to make | 162 // If we have any lingering unpaired Saves, simulate restores to make |
| 168 // sure all ops in those Save blocks have their bounds calculated. | 163 // sure all ops in those Save blocks have their bounds calculated. |
| 169 while (!fSaveStack.isEmpty()) { | 164 while (!fSaveStack.isEmpty()) { |
| 170 this->popSaveBlock(); | 165 this->popSaveBlock(); |
| 171 } | 166 } |
| 172 | 167 |
| 173 // Any control ops not part of any Save/Restore block draw everywhere. | 168 // Any control ops not part of any Save/Restore block draw everywhere. |
| 174 while (!fControlIndices.isEmpty()) { | 169 while (!fControlIndices.isEmpty()) { |
| 175 this->popControl(fCullRect); | 170 this->popControl(fCullRect); |
| 176 } | 171 } |
| 172 } |
| 177 | 173 |
| 178 // Finally feed all stored bounds into the BBH. They'll be returned in
this order. | 174 void setCurrentOp(int currentOp) { fCurrentOp = currentOp; } |
| 179 if (bbh) { | 175 |
| 180 bbh->insert(fBounds.get(), fNumRecords); | |
| 181 } | |
| 182 } | |
| 183 | 176 |
| 184 template <typename T> void operator()(const T& op) { | 177 template <typename T> void operator()(const T& op) { |
| 185 this->updateCTM(op); | 178 this->updateCTM(op); |
| 186 this->updateClipBounds(op); | 179 this->updateClipBounds(op); |
| 187 this->trackBounds(op); | 180 this->trackBounds(op); |
| 188 } | 181 } |
| 189 | 182 |
| 190 // In this file, SkRect are in local coordinates, Bounds are translated back
to identity space. | 183 // In this file, SkRect are in local coordinates, Bounds are translated back
to identity space. |
| 191 typedef SkRect Bounds; | 184 typedef SkRect Bounds; |
| 192 | 185 |
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 573 } | 566 } |
| 574 return true; | 567 return true; |
| 575 } | 568 } |
| 576 | 569 |
| 577 const int fNumRecords; | 570 const int fNumRecords; |
| 578 | 571 |
| 579 // We do not guarantee anything for operations outside of the cull rect | 572 // We do not guarantee anything for operations outside of the cull rect |
| 580 const SkRect fCullRect; | 573 const SkRect fCullRect; |
| 581 | 574 |
| 582 // Conservative identity-space bounds for each op in the SkRecord. | 575 // Conservative identity-space bounds for each op in the SkRecord. |
| 583 SkAutoTMalloc<Bounds> fBounds; | 576 Bounds* fBounds; |
| 584 | 577 |
| 585 // We walk fCurrentOp through the SkRecord, as we go using updateCTM() | 578 // We walk fCurrentOp through the SkRecord, as we go using updateCTM() |
| 586 // and updateClipBounds() to maintain the exact CTM (fCTM) and conservative | 579 // and updateClipBounds() to maintain the exact CTM (fCTM) and conservative |
| 587 // identity-space bounds of the current clip (fCurrentClipBounds). | 580 // identity-space bounds of the current clip (fCurrentClipBounds). |
| 588 int fCurrentOp; | 581 int fCurrentOp; |
| 589 const SkMatrix* fCTM; | 582 const SkMatrix* fCTM; |
| 590 Bounds fCurrentClipBounds; | 583 Bounds fCurrentClipBounds; |
| 591 | 584 |
| 592 // Used to track the bounds of Save/Restore blocks and the control ops insid
e them. | 585 // Used to track the bounds of Save/Restore blocks and the control ops insid
e them. |
| 593 SkTDArray<SaveBounds> fSaveStack; | 586 SkTDArray<SaveBounds> fSaveStack; |
| 594 SkTDArray<int> fControlIndices; | 587 SkTDArray<int> fControlIndices; |
| 595 }; | 588 }; |
| 596 | 589 |
| 597 // SkRecord visitor to gather saveLayer/restore information. | 590 // SkRecord visitor to gather saveLayer/restore information. |
| 598 class CollectLayers : SkNoncopyable { | 591 class CollectLayers : SkNoncopyable { |
| 599 public: | 592 public: |
| 600 CollectLayers(const SkRect& cullRect, const SkRecord& record, | 593 CollectLayers(const SkRect& cullRect, const SkRecord& record, SkRect bounds[
], |
| 601 const SkBigPicture::SnapshotArray* pictList, SkLayerInfo* acce
lData) | 594 const SkBigPicture::SnapshotArray* pictList, SkLayerInfo* acce
lData) |
| 602 : fSaveLayersInStack(0) | 595 : fSaveLayersInStack(0) |
| 603 , fAccelData(accelData) | 596 , fAccelData(accelData) |
| 604 , fPictList(pictList) | 597 , fPictList(pictList) |
| 605 , fFillBounds(cullRect, record) | 598 , fFillBounds(cullRect, record, bounds) |
| 606 {} | 599 {} |
| 607 | 600 |
| 608 void setCurrentOp(int currentOp) { fFillBounds.setCurrentOp(currentOp); } | 601 void cleanUp() { |
| 609 | |
| 610 void cleanUp(SkBBoxHierarchy* bbh) { | |
| 611 // fFillBounds must perform its cleanUp first so that all the bounding | 602 // fFillBounds must perform its cleanUp first so that all the bounding |
| 612 // boxes associated with unbalanced restores are updated (prior to | 603 // boxes associated with unbalanced restores are updated (prior to |
| 613 // fetching their bound in popSaveLayerInfo). | 604 // fetching their bound in popSaveLayerInfo). |
| 614 fFillBounds.cleanUp(bbh); | 605 fFillBounds.cleanUp(); |
| 615 | |
| 616 while (!fSaveLayerStack.isEmpty()) { | 606 while (!fSaveLayerStack.isEmpty()) { |
| 617 this->popSaveLayerInfo(); | 607 this->popSaveLayerInfo(); |
| 618 } | 608 } |
| 619 } | 609 } |
| 620 | 610 |
| 611 void setCurrentOp(int currentOp) { fFillBounds.setCurrentOp(currentOp); } |
| 612 |
| 613 |
| 621 template <typename T> void operator()(const T& op) { | 614 template <typename T> void operator()(const T& op) { |
| 622 fFillBounds(op); | 615 fFillBounds(op); |
| 623 this->trackSaveLayers(op); | 616 this->trackSaveLayers(op); |
| 624 } | 617 } |
| 625 | 618 |
| 626 private: | 619 private: |
| 627 struct SaveLayerInfo { | 620 struct SaveLayerInfo { |
| 628 SaveLayerInfo() { } | 621 SaveLayerInfo() { } |
| 629 SaveLayerInfo(int opIndex, bool isSaveLayer, const SkRect* bounds, const
SkPaint* paint) | 622 SaveLayerInfo(int opIndex, bool isSaveLayer, const SkRect* bounds, const
SkPaint* paint) |
| 630 : fStartIndex(opIndex) | 623 : fStartIndex(opIndex) |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 785 // The op code indices of all the currently active saveLayers | 778 // The op code indices of all the currently active saveLayers |
| 786 SkTDArray<int> fSaveLayerOpStack; | 779 SkTDArray<int> fSaveLayerOpStack; |
| 787 SkLayerInfo* fAccelData; | 780 SkLayerInfo* fAccelData; |
| 788 const SkBigPicture::SnapshotArray* fPictList; | 781 const SkBigPicture::SnapshotArray* fPictList; |
| 789 | 782 |
| 790 SkRecords::FillBounds fFillBounds; | 783 SkRecords::FillBounds fFillBounds; |
| 791 }; | 784 }; |
| 792 | 785 |
| 793 } // namespace SkRecords | 786 } // namespace SkRecords |
| 794 | 787 |
| 795 void SkRecordFillBounds(const SkRect& cullRect, const SkRecord& record, SkBBoxHi
erarchy* bbh) { | 788 void SkRecordFillBounds(const SkRect& cullRect, const SkRecord& record, SkRect b
ounds[]) { |
| 796 SkRecords::FillBounds visitor(cullRect, record); | 789 SkRecords::FillBounds visitor(cullRect, record, bounds); |
| 797 | |
| 798 for (int curOp = 0; curOp < record.count(); curOp++) { | 790 for (int curOp = 0; curOp < record.count(); curOp++) { |
| 799 visitor.setCurrentOp(curOp); | 791 visitor.setCurrentOp(curOp); |
| 800 record.visit<void>(curOp, visitor); | 792 record.visit<void>(curOp, visitor); |
| 801 } | 793 } |
| 802 | 794 visitor.cleanUp(); |
| 803 visitor.cleanUp(bbh); | |
| 804 } | 795 } |
| 805 | 796 |
| 806 void SkRecordComputeLayers(const SkRect& cullRect, const SkRecord& record, | 797 void SkRecordComputeLayers(const SkRect& cullRect, const SkRecord& record, SkRec
t bounds[], |
| 807 const SkBigPicture::SnapshotArray* pictList, SkBBoxHi
erarchy* bbh, | 798 const SkBigPicture::SnapshotArray* pictList, SkLayerI
nfo* data) { |
| 808 SkLayerInfo* data) { | 799 SkRecords::CollectLayers visitor(cullRect, record, bounds, pictList, data); |
| 809 SkRecords::CollectLayers visitor(cullRect, record, pictList, data); | |
| 810 | |
| 811 for (int curOp = 0; curOp < record.count(); curOp++) { | 800 for (int curOp = 0; curOp < record.count(); curOp++) { |
| 812 visitor.setCurrentOp(curOp); | 801 visitor.setCurrentOp(curOp); |
| 813 record.visit<void>(curOp, visitor); | 802 record.visit<void>(curOp, visitor); |
| 814 } | 803 } |
| 815 | 804 visitor.cleanUp(); |
| 816 visitor.cleanUp(bbh); | |
| 817 } | 805 } |
| 818 | 806 |
| OLD | NEW |