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

Unified 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, 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « include/core/SkDrawLooper.h ('k') | tests/DrawLooperTest.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkCanvas.cpp
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 8426f090ec5949653ab516ffca3f7d33a317c338..8fe572010b5872dad067848cc3e155c1a3b0d53d 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -198,23 +198,25 @@ public:
DeviceCM* fTopLayer;
SkRasterClip fRasterClip;
SkMatrix fMatrix;
- int fDeferredSaveCount;
+ int fSaveCount; // The count of SkCanvas::save() calls when this rec was created.
- MCRec(bool conservativeRasterClip) : fRasterClip(conservativeRasterClip) {
+ MCRec(bool conservativeRasterClip, int saveCount)
+ : fRasterClip(conservativeRasterClip)
+ , fSaveCount(saveCount) {
fFilter = NULL;
fLayer = NULL;
fTopLayer = NULL;
fMatrix.reset();
- fDeferredSaveCount = 0;
// don't bother initializing fNext
inc_rec();
}
- MCRec(const MCRec& prev) : fRasterClip(prev.fRasterClip), fMatrix(prev.fMatrix) {
+ MCRec(const MCRec& prev, int saveCount)
+ : fRasterClip(prev.fRasterClip), fMatrix(prev.fMatrix)
+ , fSaveCount(saveCount) {
fFilter = SkSafeRef(prev.fFilter);
fLayer = NULL;
fTopLayer = prev.fTopLayer;
- fDeferredSaveCount = 0;
// don't bother initializing fNext
inc_rec();
@@ -436,7 +438,7 @@ SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) {
fMetaData = NULL;
fMCRec = (MCRec*)fMCStack.push_back();
- new (fMCRec) MCRec(fConservativeRasterClip);
+ new (fMCRec) MCRec(fConservativeRasterClip, fSaveCount);
fMCRec->fLayer = SkNEW_ARGS(DeviceCM, (NULL, NULL, NULL, fConservativeRasterClip));
fMCRec->fTopLayer = fMCRec->fLayer;
@@ -545,7 +547,6 @@ SkCanvas::SkCanvas(const SkBitmap& bitmap)
SkCanvas::~SkCanvas() {
// free up the contents of our deque
this->restoreToCount(1); // restore everything but the last
-
this->internalRestore(); // restore the last, since we're going away
SkDELETE(fMetaData);
@@ -752,31 +753,17 @@ void SkCanvas::updateDeviceCMCache() {
///////////////////////////////////////////////////////////////////////////////
void SkCanvas::checkForDeferredSave() {
- if (fMCRec->fDeferredSaveCount > 0) {
- fMCRec->fDeferredSaveCount -= 1;
+ if (fMCRec->fSaveCount < fSaveCount) {
this->doSave();
}
}
int SkCanvas::getSaveCount() const {
-#ifdef SK_DEBUG
- int count = 0;
- SkDeque::Iter iter(fMCStack, SkDeque::Iter::kFront_IterStart);
- for (;;) {
- const MCRec* rec = (const MCRec*)iter.next();
- if (!rec) {
- break;
- }
- count += 1 + rec->fDeferredSaveCount;
- }
- SkASSERT(count == fSaveCount);
-#endif
return fSaveCount;
}
int SkCanvas::save() {
fSaveCount += 1;
- fMCRec->fDeferredSaveCount += 1;
return this->getSaveCount() - 1; // return our prev value
}
@@ -786,20 +773,23 @@ void SkCanvas::doSave() {
}
void SkCanvas::restore() {
- if (fMCRec->fDeferredSaveCount > 0) {
- SkASSERT(fSaveCount > 1);
- fSaveCount -= 1;
- fMCRec->fDeferredSaveCount -= 1;
- } else {
- // check for underflow
+ int deferredSaveCount = fSaveCount - fMCRec->fSaveCount;
+ SkASSERT(deferredSaveCount >= 0);
+ if (deferredSaveCount == 0) {
+ // Check if the client tried to restore() too many times.
if (fMCStack.count() > 1) {
this->willRestore();
- SkASSERT(fSaveCount > 1);
- fSaveCount -= 1;
this->internalRestore();
+ fSaveCount -= 1;
this->didRestore();
}
+ } else {
+ // The topmost save was deferred.
+ fSaveCount -= 1;
}
+
+ // Note: we can not detect the case where errorneous SkCanvas::restore()
+ // is called within the SkDrawLooper callback.
}
void SkCanvas::restoreToCount(int count) {
@@ -816,9 +806,8 @@ void SkCanvas::restoreToCount(int count) {
void SkCanvas::internalSave() {
MCRec* newTop = (MCRec*)fMCStack.push_back();
- new (newTop) MCRec(*fMCRec); // balanced in restore()
+ new (newTop) MCRec(*fMCRec, fSaveCount); // balanced in restore()
fMCRec = newTop;
-
fClipStack->save();
}
@@ -879,7 +868,7 @@ int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint) {
bounds = NULL;
}
SaveLayerStrategy strategy = this->willSaveLayer(bounds, paint, kARGB_ClipLayer_SaveFlag);
- fSaveCount += 1;
+ fSaveCount++;
this->internalSaveLayer(bounds, paint, kARGB_ClipLayer_SaveFlag, strategy);
return this->getSaveCount() - 1;
}
@@ -889,7 +878,7 @@ int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags fl
bounds = NULL;
}
SaveLayerStrategy strategy = this->willSaveLayer(bounds, paint, flags);
- fSaveCount += 1;
+ fSaveCount++;
this->internalSaveLayer(bounds, paint, flags, strategy);
return this->getSaveCount() - 1;
}
@@ -977,6 +966,7 @@ int SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha,
void SkCanvas::internalRestore() {
SkASSERT(fMCStack.count() != 0);
+ SkASSERT(fMCRec->fSaveCount == fSaveCount);
fDeviceCMDirty = true;
fCachedLocalClipBoundsDirty = true;
@@ -1007,6 +997,7 @@ void SkCanvas::internalRestore() {
}
SkDELETE(layer);
}
+ SkASSERT(fMCStack.count() == 0 || fMCRec->fSaveCount <= fSaveCount);
}
SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* props) {
« 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