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

Unified Diff: src/core/SkClipStack.cpp

Issue 54543008: Revert "Avoid re-rendering stencil clip for every draw with reducable clip stack" (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 7 years, 1 month 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/SkClipStack.h ('k') | src/gpu/GrClipMaskCache.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkClipStack.cpp
diff --git a/src/core/SkClipStack.cpp b/src/core/SkClipStack.cpp
index 9e3f7c6b308071c16397e1cd6ece7d2abefc9a64..2c0961ab83c8254654078782903364666e260209 100644
--- a/src/core/SkClipStack.cpp
+++ b/src/core/SkClipStack.cpp
@@ -452,6 +452,7 @@ void SkClipStack::restoreTo(int saveCount) {
if (element->fSaveCount <= saveCount) {
break;
}
+ this->purgeClip(element);
element->~Element();
fDeque.pop_back();
}
@@ -539,6 +540,7 @@ void SkClipStack::clipDevRect(const SkRect& rect, SkRegion::Op op, bool doAA) {
return;
case Element::kRect_Type:
if (element->rectRectIntersectAllowed(rect, doAA)) {
+ this->purgeClip(element);
if (!element->fRect.intersect(rect)) {
element->setEmpty();
return;
@@ -552,6 +554,7 @@ void SkClipStack::clipDevRect(const SkRect& rect, SkRegion::Op op, bool doAA) {
break;
case Element::kPath_Type:
if (!SkRect::Intersects(element->fPath.getBounds(), rect)) {
+ this->purgeClip(element);
element->setEmpty();
return;
}
@@ -564,6 +567,10 @@ void SkClipStack::clipDevRect(const SkRect& rect, SkRegion::Op op, bool doAA) {
}
new (fDeque.push_back()) Element(fSaveCount, rect, op, doAA);
((Element*) fDeque.back())->updateBoundAndGenID(element);
+
+ if (element && element->fSaveCount == fSaveCount) {
+ this->purgeClip(element);
+ }
}
void SkClipStack::clipDevPath(const SkPath& path, SkRegion::Op op, bool doAA) {
@@ -582,12 +589,14 @@ void SkClipStack::clipDevPath(const SkPath& path, SkRegion::Op op, bool doAA) {
return;
case Element::kRect_Type:
if (!SkRect::Intersects(element->fRect, pathBounds)) {
+ this->purgeClip(element);
element->setEmpty();
return;
}
break;
case Element::kPath_Type:
if (!SkRect::Intersects(element->fPath.getBounds(), pathBounds)) {
+ this->purgeClip(element);
element->setEmpty();
return;
}
@@ -600,6 +609,10 @@ void SkClipStack::clipDevPath(const SkPath& path, SkRegion::Op op, bool doAA) {
}
new (fDeque.push_back()) Element(fSaveCount, path, op, doAA);
((Element*) fDeque.back())->updateBoundAndGenID(element);
+
+ if (element && element->fSaveCount == fSaveCount) {
+ this->purgeClip(element);
+ }
}
void SkClipStack::clipEmpty() {
@@ -613,17 +626,27 @@ void SkClipStack::clipEmpty() {
return;
case Element::kRect_Type:
case Element::kPath_Type:
+ this->purgeClip(element);
element->setEmpty();
return;
}
}
new (fDeque.push_back()) Element(fSaveCount);
+ if (element && element->fSaveCount == fSaveCount) {
+ this->purgeClip(element);
+ }
((Element*)fDeque.back())->fGenID = kEmptyGenID;
}
bool SkClipStack::isWideOpen() const {
- return this->getTopmostGenID() == kWideOpenGenID;
+ if (0 == fDeque.count()) {
+ return true;
+ }
+
+ const Element* back = (const Element*) fDeque.back();
+ return kWideOpenGenID == back->fGenID ||
+ (kInsideOut_BoundsType == back->fFiniteBoundType && back->fFiniteBound.isEmpty());
}
///////////////////////////////////////////////////////////////////////////////
@@ -717,20 +740,45 @@ void SkClipStack::getConservativeBounds(int offsetX,
}
}
+void SkClipStack::addPurgeClipCallback(PFPurgeClipCB callback, void* data) const {
+ ClipCallbackData temp = { callback, data };
+ fCallbackData.append(1, &temp);
+}
+
+void SkClipStack::removePurgeClipCallback(PFPurgeClipCB callback, void* data) const {
+ ClipCallbackData temp = { callback, data };
+ int index = fCallbackData.find(temp);
+ if (index >= 0) {
+ fCallbackData.removeShuffle(index);
+ }
+}
+
+// The clip state represented by 'element' will never be used again. Purge it.
+void SkClipStack::purgeClip(Element* element) {
+ SkASSERT(NULL != element);
+ if (element->fGenID >= 0 && element->fGenID < kFirstUnreservedGenID) {
+ return;
+ }
+
+ for (int i = 0; i < fCallbackData.count(); ++i) {
+ (*fCallbackData[i].fCallback)(element->fGenID, fCallbackData[i].fData);
+ }
+
+ // Invalidate element's gen ID so handlers can detect already handled records
+ element->fGenID = kInvalidGenID;
+}
+
int32_t SkClipStack::GetNextGenID() {
// TODO: handle overflow.
return sk_atomic_inc(&gGenID);
}
int32_t SkClipStack::getTopmostGenID() const {
- if (fDeque.empty()) {
- return kWideOpenGenID;
- }
- const Element* back = static_cast<const Element*>(fDeque.back());
- if (kInsideOut_BoundsType == back->fFiniteBoundType && back->fFiniteBound.isEmpty()) {
- return kWideOpenGenID;
+ if (fDeque.empty()) {
+ return kInvalidGenID;
}
- return back->getGenID();
+ Element* element = (Element*)fDeque.back();
+ return element->fGenID;
}
« no previous file with comments | « include/core/SkClipStack.h ('k') | src/gpu/GrClipMaskCache.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698