Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(293)

Side by Side Diff: src/core/SkCanvas.cpp

Issue 993863002: Make the canvas draw looper internal layer not part of SkCanvas save count Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: another approach Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « include/core/SkDrawLooper.h ('k') | tests/DrawLooperTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2008 The Android Open Source Project 2 * Copyright 2008 The Android Open Source Project
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 "SkCanvas.h" 8 #include "SkCanvas.h"
9 #include "SkCanvasPriv.h" 9 #include "SkCanvasPriv.h"
10 #include "SkBitmapDevice.h" 10 #include "SkBitmapDevice.h"
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 DeviceCM* fLayer; 191 DeviceCM* fLayer;
192 /* If there are any layers in the stack, this points to the top-most 192 /* If there are any layers in the stack, this points to the top-most
193 one that is at or below this level in the stack (so we know what 193 one that is at or below this level in the stack (so we know what
194 bitmap/device to draw into from this level. This value is NOT 194 bitmap/device to draw into from this level. This value is NOT
195 reference counted, since the real owner is either our fLayer field, 195 reference counted, since the real owner is either our fLayer field,
196 or a previous one in a lower level.) 196 or a previous one in a lower level.)
197 */ 197 */
198 DeviceCM* fTopLayer; 198 DeviceCM* fTopLayer;
199 SkRasterClip fRasterClip; 199 SkRasterClip fRasterClip;
200 SkMatrix fMatrix; 200 SkMatrix fMatrix;
201 int fDeferredSaveCount; 201 int fSaveCount; // The count of SkCanvas::save() calls when thi s rec was created.
202 202
203 MCRec(bool conservativeRasterClip) : fRasterClip(conservativeRasterClip) { 203 MCRec(bool conservativeRasterClip, int saveCount)
204 : fRasterClip(conservativeRasterClip)
205 , fSaveCount(saveCount) {
204 fFilter = NULL; 206 fFilter = NULL;
205 fLayer = NULL; 207 fLayer = NULL;
206 fTopLayer = NULL; 208 fTopLayer = NULL;
207 fMatrix.reset(); 209 fMatrix.reset();
208 fDeferredSaveCount = 0;
209 210
210 // don't bother initializing fNext 211 // don't bother initializing fNext
211 inc_rec(); 212 inc_rec();
212 } 213 }
213 MCRec(const MCRec& prev) : fRasterClip(prev.fRasterClip), fMatrix(prev.fMatr ix) { 214 MCRec(const MCRec& prev, int saveCount)
215 : fRasterClip(prev.fRasterClip), fMatrix(prev.fMatrix)
216 , fSaveCount(saveCount) {
214 fFilter = SkSafeRef(prev.fFilter); 217 fFilter = SkSafeRef(prev.fFilter);
215 fLayer = NULL; 218 fLayer = NULL;
216 fTopLayer = prev.fTopLayer; 219 fTopLayer = prev.fTopLayer;
217 fDeferredSaveCount = 0;
218 220
219 // don't bother initializing fNext 221 // don't bother initializing fNext
220 inc_rec(); 222 inc_rec();
221 } 223 }
222 ~MCRec() { 224 ~MCRec() {
223 SkSafeUnref(fFilter); 225 SkSafeUnref(fFilter);
224 SkDELETE(fLayer); 226 SkDELETE(fLayer);
225 dec_rec(); 227 dec_rec();
226 } 228 }
227 }; 229 };
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 fConservativeRasterClip = SkToBool(flags & kConservativeRasterClip_InitFlag) ; 431 fConservativeRasterClip = SkToBool(flags & kConservativeRasterClip_InitFlag) ;
430 fCachedLocalClipBounds.setEmpty(); 432 fCachedLocalClipBounds.setEmpty();
431 fCachedLocalClipBoundsDirty = true; 433 fCachedLocalClipBoundsDirty = true;
432 fAllowSoftClip = true; 434 fAllowSoftClip = true;
433 fAllowSimplifyClip = false; 435 fAllowSimplifyClip = false;
434 fDeviceCMDirty = true; 436 fDeviceCMDirty = true;
435 fSaveCount = 1; 437 fSaveCount = 1;
436 fMetaData = NULL; 438 fMetaData = NULL;
437 439
438 fMCRec = (MCRec*)fMCStack.push_back(); 440 fMCRec = (MCRec*)fMCStack.push_back();
439 new (fMCRec) MCRec(fConservativeRasterClip); 441 new (fMCRec) MCRec(fConservativeRasterClip, fSaveCount);
440 442
441 fMCRec->fLayer = SkNEW_ARGS(DeviceCM, (NULL, NULL, NULL, fConservativeRaster Clip)); 443 fMCRec->fLayer = SkNEW_ARGS(DeviceCM, (NULL, NULL, NULL, fConservativeRaster Clip));
442 fMCRec->fTopLayer = fMCRec->fLayer; 444 fMCRec->fTopLayer = fMCRec->fLayer;
443 445
444 fSurfaceBase = NULL; 446 fSurfaceBase = NULL;
445 447
446 fClipStack.reset(SkNEW(SkClipStack)); 448 fClipStack.reset(SkNEW(SkClipStack));
447 449
448 if (device) { 450 if (device) {
449 device->initForRootLayer(fProps.pixelGeometry()); 451 device->initForRootLayer(fProps.pixelGeometry());
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 { 540 {
539 inc_canvas(); 541 inc_canvas();
540 542
541 SkAutoTUnref<SkBaseDevice> device(SkNEW_ARGS(SkBitmapDevice, (bitmap))); 543 SkAutoTUnref<SkBaseDevice> device(SkNEW_ARGS(SkBitmapDevice, (bitmap)));
542 this->init(device, kDefault_InitFlags); 544 this->init(device, kDefault_InitFlags);
543 } 545 }
544 546
545 SkCanvas::~SkCanvas() { 547 SkCanvas::~SkCanvas() {
546 // free up the contents of our deque 548 // free up the contents of our deque
547 this->restoreToCount(1); // restore everything but the last 549 this->restoreToCount(1); // restore everything but the last
548
549 this->internalRestore(); // restore the last, since we're going away 550 this->internalRestore(); // restore the last, since we're going away
550 551
551 SkDELETE(fMetaData); 552 SkDELETE(fMetaData);
552 553
553 dec_canvas(); 554 dec_canvas();
554 } 555 }
555 556
556 SkDrawFilter* SkCanvas::getDrawFilter() const { 557 SkDrawFilter* SkCanvas::getDrawFilter() const {
557 return fMCRec->fFilter; 558 return fMCRec->fFilter;
558 } 559 }
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
745 layer->updateMC(totalMatrix, clip, *fClipStack, &clip); 746 layer->updateMC(totalMatrix, clip, *fClipStack, &clip);
746 } while ((layer = layer->fNext) != NULL); 747 } while ((layer = layer->fNext) != NULL);
747 } 748 }
748 fDeviceCMDirty = false; 749 fDeviceCMDirty = false;
749 } 750 }
750 } 751 }
751 752
752 /////////////////////////////////////////////////////////////////////////////// 753 ///////////////////////////////////////////////////////////////////////////////
753 754
754 void SkCanvas::checkForDeferredSave() { 755 void SkCanvas::checkForDeferredSave() {
755 if (fMCRec->fDeferredSaveCount > 0) { 756 if (fMCRec->fSaveCount < fSaveCount) {
756 fMCRec->fDeferredSaveCount -= 1;
757 this->doSave(); 757 this->doSave();
758 } 758 }
759 } 759 }
760 760
761 int SkCanvas::getSaveCount() const { 761 int SkCanvas::getSaveCount() const {
762 #ifdef SK_DEBUG
763 int count = 0;
764 SkDeque::Iter iter(fMCStack, SkDeque::Iter::kFront_IterStart);
765 for (;;) {
766 const MCRec* rec = (const MCRec*)iter.next();
767 if (!rec) {
768 break;
769 }
770 count += 1 + rec->fDeferredSaveCount;
771 }
772 SkASSERT(count == fSaveCount);
773 #endif
774 return fSaveCount; 762 return fSaveCount;
775 } 763 }
776 764
777 int SkCanvas::save() { 765 int SkCanvas::save() {
778 fSaveCount += 1; 766 fSaveCount += 1;
779 fMCRec->fDeferredSaveCount += 1;
780 return this->getSaveCount() - 1; // return our prev value 767 return this->getSaveCount() - 1; // return our prev value
781 } 768 }
782 769
783 void SkCanvas::doSave() { 770 void SkCanvas::doSave() {
784 this->willSave(); 771 this->willSave();
785 this->internalSave(); 772 this->internalSave();
786 } 773 }
787 774
788 void SkCanvas::restore() { 775 void SkCanvas::restore() {
789 if (fMCRec->fDeferredSaveCount > 0) { 776 int deferredSaveCount = fSaveCount - fMCRec->fSaveCount;
790 SkASSERT(fSaveCount > 1); 777 SkASSERT(deferredSaveCount >= 0);
791 fSaveCount -= 1; 778 if (deferredSaveCount == 0) {
792 fMCRec->fDeferredSaveCount -= 1; 779 // Check if the client tried to restore() too many times.
793 } else {
794 // check for underflow
795 if (fMCStack.count() > 1) { 780 if (fMCStack.count() > 1) {
796 this->willRestore(); 781 this->willRestore();
797 SkASSERT(fSaveCount > 1); 782 this->internalRestore();
798 fSaveCount -= 1; 783 fSaveCount -= 1;
799 this->internalRestore();
800 this->didRestore(); 784 this->didRestore();
801 } 785 }
786 } else {
787 // The topmost save was deferred.
788 fSaveCount -= 1;
802 } 789 }
790
791 // Note: we can not detect the case where errorneous SkCanvas::restore()
792 // is called within the SkDrawLooper callback.
803 } 793 }
804 794
805 void SkCanvas::restoreToCount(int count) { 795 void SkCanvas::restoreToCount(int count) {
806 // sanity check 796 // sanity check
807 if (count < 1) { 797 if (count < 1) {
808 count = 1; 798 count = 1;
809 } 799 }
810 800
811 int n = this->getSaveCount() - count; 801 int n = this->getSaveCount() - count;
812 for (int i = 0; i < n; ++i) { 802 for (int i = 0; i < n; ++i) {
813 this->restore(); 803 this->restore();
814 } 804 }
815 } 805 }
816 806
817 void SkCanvas::internalSave() { 807 void SkCanvas::internalSave() {
818 MCRec* newTop = (MCRec*)fMCStack.push_back(); 808 MCRec* newTop = (MCRec*)fMCStack.push_back();
819 new (newTop) MCRec(*fMCRec); // balanced in restore() 809 new (newTop) MCRec(*fMCRec, fSaveCount); // balanced in restore()
820 fMCRec = newTop; 810 fMCRec = newTop;
821
822 fClipStack->save(); 811 fClipStack->save();
823 } 812 }
824 813
825 static bool bounds_affects_clip(SkCanvas::SaveFlags flags) { 814 static bool bounds_affects_clip(SkCanvas::SaveFlags flags) {
826 #ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG 815 #ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
827 return (flags & SkCanvas::kClipToLayer_SaveFlag) != 0; 816 return (flags & SkCanvas::kClipToLayer_SaveFlag) != 0;
828 #else 817 #else
829 return true; 818 return true;
830 #endif 819 #endif
831 } 820 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
872 *intersection = ir; 861 *intersection = ir;
873 } 862 }
874 return true; 863 return true;
875 } 864 }
876 865
877 int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint) { 866 int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint) {
878 if (gIgnoreSaveLayerBounds) { 867 if (gIgnoreSaveLayerBounds) {
879 bounds = NULL; 868 bounds = NULL;
880 } 869 }
881 SaveLayerStrategy strategy = this->willSaveLayer(bounds, paint, kARGB_ClipLa yer_SaveFlag); 870 SaveLayerStrategy strategy = this->willSaveLayer(bounds, paint, kARGB_ClipLa yer_SaveFlag);
882 fSaveCount += 1; 871 fSaveCount++;
883 this->internalSaveLayer(bounds, paint, kARGB_ClipLayer_SaveFlag, strategy); 872 this->internalSaveLayer(bounds, paint, kARGB_ClipLayer_SaveFlag, strategy);
884 return this->getSaveCount() - 1; 873 return this->getSaveCount() - 1;
885 } 874 }
886 875
887 int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags fl ags) { 876 int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags fl ags) {
888 if (gIgnoreSaveLayerBounds) { 877 if (gIgnoreSaveLayerBounds) {
889 bounds = NULL; 878 bounds = NULL;
890 } 879 }
891 SaveLayerStrategy strategy = this->willSaveLayer(bounds, paint, flags); 880 SaveLayerStrategy strategy = this->willSaveLayer(bounds, paint, flags);
892 fSaveCount += 1; 881 fSaveCount++;
893 this->internalSaveLayer(bounds, paint, flags, strategy); 882 this->internalSaveLayer(bounds, paint, flags, strategy);
894 return this->getSaveCount() - 1; 883 return this->getSaveCount() - 1;
895 } 884 }
896 885
897 void SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, Sav eFlags flags, 886 void SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, Sav eFlags flags,
898 SaveLayerStrategy strategy) { 887 SaveLayerStrategy strategy) {
899 #ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG 888 #ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
900 flags |= kClipToLayer_SaveFlag; 889 flags |= kClipToLayer_SaveFlag;
901 #endif 890 #endif
902 891
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
970 return this->saveLayer(bounds, NULL, flags); 959 return this->saveLayer(bounds, NULL, flags);
971 } else { 960 } else {
972 SkPaint tmpPaint; 961 SkPaint tmpPaint;
973 tmpPaint.setAlpha(alpha); 962 tmpPaint.setAlpha(alpha);
974 return this->saveLayer(bounds, &tmpPaint, flags); 963 return this->saveLayer(bounds, &tmpPaint, flags);
975 } 964 }
976 } 965 }
977 966
978 void SkCanvas::internalRestore() { 967 void SkCanvas::internalRestore() {
979 SkASSERT(fMCStack.count() != 0); 968 SkASSERT(fMCStack.count() != 0);
969 SkASSERT(fMCRec->fSaveCount == fSaveCount);
980 970
981 fDeviceCMDirty = true; 971 fDeviceCMDirty = true;
982 fCachedLocalClipBoundsDirty = true; 972 fCachedLocalClipBoundsDirty = true;
983 973
984 fClipStack->restore(); 974 fClipStack->restore();
985 975
986 // reserve our layer (if any) 976 // reserve our layer (if any)
987 DeviceCM* layer = fMCRec->fLayer; // may be null 977 DeviceCM* layer = fMCRec->fLayer; // may be null
988 // now detach it from fMCRec so we can pop(). Gets freed after its drawn 978 // now detach it from fMCRec so we can pop(). Gets freed after its drawn
989 fMCRec->fLayer = NULL; 979 fMCRec->fLayer = NULL;
(...skipping 10 matching lines...) Expand all
1000 if (layer) { 990 if (layer) {
1001 if (layer->fNext) { 991 if (layer->fNext) {
1002 const SkIPoint& origin = layer->fDevice->getOrigin(); 992 const SkIPoint& origin = layer->fDevice->getOrigin();
1003 this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), 993 this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(),
1004 layer->fPaint); 994 layer->fPaint);
1005 // reset this, since internalDrawDevice will have set it to true 995 // reset this, since internalDrawDevice will have set it to true
1006 fDeviceCMDirty = true; 996 fDeviceCMDirty = true;
1007 } 997 }
1008 SkDELETE(layer); 998 SkDELETE(layer);
1009 } 999 }
1000 SkASSERT(fMCStack.count() == 0 || fMCRec->fSaveCount <= fSaveCount);
1010 } 1001 }
1011 1002
1012 SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* p rops) { 1003 SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* p rops) {
1013 if (NULL == props) { 1004 if (NULL == props) {
1014 props = &fProps; 1005 props = &fProps;
1015 } 1006 }
1016 return this->onNewSurface(info, *props); 1007 return this->onNewSurface(info, *props);
1017 } 1008 }
1018 1009
1019 SkSurface* SkCanvas::onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props) { 1010 SkSurface* SkCanvas::onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props) {
(...skipping 1500 matching lines...) Expand 10 before | Expand all | Expand 10 after
2520 } 2511 }
2521 2512
2522 if (matrix) { 2513 if (matrix) {
2523 canvas->concat(*matrix); 2514 canvas->concat(*matrix);
2524 } 2515 }
2525 } 2516 }
2526 2517
2527 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { 2518 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() {
2528 fCanvas->restoreToCount(fSaveCount); 2519 fCanvas->restoreToCount(fSaveCount);
2529 } 2520 }
OLDNEW
« no previous file with comments | « include/core/SkDrawLooper.h ('k') | tests/DrawLooperTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698