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

Unified Diff: src/core/SkClipStack.cpp

Issue 163683002: Store SkRRects in SkClipStack (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: fix unhandled enum value warning in unit test Created 6 years, 10 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 | « src/core/SkCanvas.cpp ('k') | src/gpu/GrClipMaskManager.cpp » ('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 c66a219b629bbe7c467eafa946e2487fe067afbe..17eb6f931d31f04d344c27ecc0228fe7a100ce0a 100644
--- a/src/core/SkClipStack.cpp
+++ b/src/core/SkClipStack.cpp
@@ -16,17 +16,89 @@
static const int32_t kFirstUnreservedGenID = 3;
int32_t SkClipStack::gGenID = kFirstUnreservedGenID;
+bool SkClipStack::Element::operator== (const Element& element) const {
+ if (this == &element) {
+ return true;
+ }
+ if (fOp != element.fOp ||
+ fType != element.fType ||
+ fDoAA != element.fDoAA ||
+ fSaveCount != element.fSaveCount) {
+ return false;
+ }
+ switch (fType) {
+ case kPath_Type:
+ return fPath == element.fPath;
+ case kRRect_Type:
+ return fRRect == element.fRRect;
+ case kRect_Type:
+ return fRect == element.fRect;
+ case kEmpty_Type:
+ return true;
+ default:
+ SkDEBUGFAIL("Unexpected type.");
+ return false;
+ }
+}
+
void SkClipStack::Element::invertShapeFillType() {
switch (fType) {
case kRect_Type:
fPath.reset();
fPath.addRect(fRect);
- fPath.setFillType(SkPath::kInverseWinding_FillType);
+ fPath.setFillType(SkPath::kInverseEvenOdd_FillType);
+ fType = kPath_Type;
+ break;
+ case kRRect_Type:
+ fPath.reset();
+ fPath.addRRect(fRRect);
+ fPath.setFillType(SkPath::kInverseEvenOdd_FillType);
fType = kPath_Type;
break;
case kPath_Type:
fPath.toggleInverseFillType();
+ break;
case kEmpty_Type:
+ // Should this set to an empty, inverse filled path?
+ break;
+ }
+}
+
+void SkClipStack::Element::initPath(int saveCount, const SkPath& path, SkRegion::Op op,
+ bool doAA) {
+ if (!path.isInverseFillType()) {
+ if (SkPath::kNone_PathAsRect != path.asRect()) {
+ this->initRect(saveCount, path.getBounds(), op, doAA);
+ return;
+ }
+ SkRect ovalRect;
+ if (path.isOval(&ovalRect)) {
+ SkRRect rrect;
+ rrect.setOval(ovalRect);
+ this->initRRect(saveCount, rrect, op, doAA);
+ return;
+ }
+ }
+ fPath = path;
+ fType = kPath_Type;
+ this->initCommon(saveCount, op, doAA);
+}
+
+void SkClipStack::Element::asPath(SkPath* path) const {
+ switch (fType) {
+ case kEmpty_Type:
+ path->reset();
+ break;
+ case kRect_Type:
+ path->reset();
+ path->addRect(fRect);
+ break;
+ case kRRect_Type:
+ path->reset();
+ path->addRRect(fRRect);
+ break;
+ case kPath_Type:
+ *path = fPath;
break;
}
}
@@ -100,10 +172,10 @@ void SkClipStack::Element::combineBoundsDiff(FillCombo combination, const SkRect
// is erased, so the only pixels that can remain set
// occur w/in the intersection of the two finite bounds
if (!fFiniteBound.intersect(prevFinite)) {
- fFiniteBound.setEmpty();
- fGenID = kEmptyGenID;
+ this->setEmpty();
+ } else {
+ fFiniteBoundType = kNormal_BoundsType;
}
- fFiniteBoundType = kNormal_BoundsType;
break;
case kPrev_Cur_FillCombo:
// The most conservative result bound is that of the
@@ -205,8 +277,7 @@ void SkClipStack::Element::combineBoundsIntersection(int combination, const SkRe
break;
case kPrev_Cur_FillCombo:
if (!fFiniteBound.intersect(prevFinite)) {
- fFiniteBound.setEmpty();
- fGenID = kEmptyGenID;
+ this->setEmpty();
}
break;
default:
@@ -228,10 +299,10 @@ void SkClipStack::Element::combineBoundsRevDiff(int combination, const SkRect& p
break;
case kInvPrev_Cur_FillCombo:
if (!fFiniteBound.intersect(prevFinite)) {
- fFiniteBound.setEmpty();
- fGenID = kEmptyGenID;
+ this->setEmpty();
+ } else {
+ fFiniteBoundType = kNormal_BoundsType;
}
- fFiniteBoundType = kNormal_BoundsType;
break;
case kPrev_InvCur_FillCombo:
fFiniteBound.join(prevFinite);
@@ -258,27 +329,34 @@ void SkClipStack::Element::updateBoundAndGenID(const Element* prior) {
// First, optimistically update the current Element's bound information
// with the current clip's bound
fIsIntersectionOfRects = false;
- if (kRect_Type == fType) {
- fFiniteBound = fRect;
- fFiniteBoundType = kNormal_BoundsType;
-
- if (SkRegion::kReplace_Op == fOp ||
- (SkRegion::kIntersect_Op == fOp && NULL == prior) ||
- (SkRegion::kIntersect_Op == fOp && prior->fIsIntersectionOfRects &&
- prior->rectRectIntersectAllowed(fRect, fDoAA))) {
- fIsIntersectionOfRects = true;
- }
-
- } else {
- SkASSERT(kPath_Type == fType);
-
- fFiniteBound = fPath.getBounds();
+ switch (fType) {
+ case kRect_Type:
+ fFiniteBound = fRect;
+ fFiniteBoundType = kNormal_BoundsType;
- if (fPath.isInverseFillType()) {
- fFiniteBoundType = kInsideOut_BoundsType;
- } else {
+ if (SkRegion::kReplace_Op == fOp ||
+ (SkRegion::kIntersect_Op == fOp && NULL == prior) ||
+ (SkRegion::kIntersect_Op == fOp && prior->fIsIntersectionOfRects &&
+ prior->rectRectIntersectAllowed(fRect, fDoAA))) {
+ fIsIntersectionOfRects = true;
+ }
+ break;
+ case kRRect_Type:
+ fFiniteBound = fRRect.getBounds();
fFiniteBoundType = kNormal_BoundsType;
- }
+ break;
+ case kPath_Type:
+ fFiniteBound = fPath.getBounds();
+
+ if (fPath.isInverseFillType()) {
+ fFiniteBoundType = kInsideOut_BoundsType;
+ } else {
+ fFiniteBoundType = kNormal_BoundsType;
+ }
+ break;
+ case kEmpty_Type:
+ SkDEBUGFAIL("We shouldn't get here with an empty element.");
+ break;
}
if (!fDoAA) {
@@ -344,7 +422,7 @@ void SkClipStack::Element::updateBoundAndGenID(const Element* prior) {
// so nothing to do
break;
default:
- SkDebugf("SkRegion::Op error/n");
+ SkDebugf("SkRegion::Op error\n");
SkASSERT(0);
break;
}
@@ -528,97 +606,69 @@ bool SkClipStack::quickContains(const SkRect& rect) const {
return true;
}
-void SkClipStack::clipDevRect(const SkRect& rect, SkRegion::Op op, bool doAA) {
-
+void SkClipStack::pushElement(const Element& element) {
// Use reverse iterator instead of back because Rect path may need previous
SkDeque::Iter iter(fDeque, SkDeque::Iter::kBack_IterStart);
- Element* element = (Element*) iter.prev();
+ Element* prior = (Element*) iter.prev();
- if (NULL != element) {
- if (element->canBeIntersectedInPlace(fSaveCount, op)) {
- switch (element->fType) {
+ if (NULL != prior) {
+ if (prior->canBeIntersectedInPlace(fSaveCount, element.getOp())) {
+ switch (prior->fType) {
case Element::kEmpty_Type:
- element->checkEmpty();
+ SkDEBUGCODE(prior->checkEmpty();)
return;
case Element::kRect_Type:
- if (element->rectRectIntersectAllowed(rect, doAA)) {
- if (!element->fRect.intersect(rect)) {
- element->setEmpty();
+ if (Element::kRect_Type == element.getType()) {
+ if (prior->rectRectIntersectAllowed(element.getRect(), element.isAA())) {
+ if (!prior->fRect.intersect(element.getRect())) {
+ prior->setEmpty();
+ return;
+ }
+
+ prior->fDoAA = element.isAA();
+ Element* priorPrior = (Element*) iter.prev();
+ prior->updateBoundAndGenID(priorPrior);
return;
}
-
- element->fDoAA = doAA;
- Element* prev = (Element*) iter.prev();
- element->updateBoundAndGenID(prev);
- return;
+ break;
}
- break;
- case Element::kPath_Type:
- if (!SkRect::Intersects(element->fPath.getBounds(), rect)) {
- element->setEmpty();
+ // fallthrough
+ default:
+ if (!SkRect::Intersects(prior->getBounds(), element.getBounds())) {
+ prior->setEmpty();
return;
}
break;
}
- } else if (SkRegion::kReplace_Op == op) {
+ } else if (SkRegion::kReplace_Op == element.getOp()) {
this->restoreTo(fSaveCount - 1);
- element = (Element*) fDeque.back();
+ prior = (Element*) fDeque.back();
}
}
- new (fDeque.push_back()) Element(fSaveCount, rect, op, doAA);
- ((Element*) fDeque.back())->updateBoundAndGenID(element);
+ Element* newElement = SkNEW_PLACEMENT_ARGS(fDeque.push_back(), Element, (element));
+ newElement->updateBoundAndGenID(prior);
}
-void SkClipStack::clipDevPath(const SkPath& path, SkRegion::Op op, bool doAA) {
- SkRect alt;
- if (path.isRect(&alt) && !path.isInverseFillType()) {
- return this->clipDevRect(alt, op, doAA);
- }
+void SkClipStack::clipDevRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) {
+ Element element(fSaveCount, rrect, op, doAA);
+ this->pushElement(element);
+}
- Element* element = (Element*)fDeque.back();
- if (NULL != element) {
- if (element->canBeIntersectedInPlace(fSaveCount, op)) {
- const SkRect& pathBounds = path.getBounds();
- switch (element->fType) {
- case Element::kEmpty_Type:
- element->checkEmpty();
- return;
- case Element::kRect_Type:
- if (!SkRect::Intersects(element->fRect, pathBounds)) {
- element->setEmpty();
- return;
- }
- break;
- case Element::kPath_Type:
- if (!SkRect::Intersects(element->fPath.getBounds(), pathBounds)) {
- element->setEmpty();
- return;
- }
- break;
- }
- } else if (SkRegion::kReplace_Op == op) {
- this->restoreTo(fSaveCount - 1);
- element = (Element*) fDeque.back();
- }
- }
- new (fDeque.push_back()) Element(fSaveCount, path, op, doAA);
- ((Element*) fDeque.back())->updateBoundAndGenID(element);
+void SkClipStack::clipDevRect(const SkRect& rect, SkRegion::Op op, bool doAA) {
+ Element element(fSaveCount, rect, op, doAA);
+ this->pushElement(element);
}
-void SkClipStack::clipEmpty() {
+void SkClipStack::clipDevPath(const SkPath& path, SkRegion::Op op, bool doAA) {
+ Element element(fSaveCount, path, op, doAA);
+ this->pushElement(element);
+}
+void SkClipStack::clipEmpty() {
Element* element = (Element*) fDeque.back();
if (element && element->canBeIntersectedInPlace(fSaveCount, SkRegion::kIntersect_Op)) {
- switch (element->fType) {
- case Element::kEmpty_Type:
- element->checkEmpty();
- return;
- case Element::kRect_Type:
- case Element::kPath_Type:
- element->setEmpty();
- return;
- }
+ element->setEmpty();
}
new (fDeque.push_back()) Element(fSaveCount);
« no previous file with comments | « src/core/SkCanvas.cpp ('k') | src/gpu/GrClipMaskManager.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698