Use SkTLazy to hold path in SkClipStack::Element

R=reed@google.com, robertphillips@google.com

Author: bsalomon@google.com

Review URL: https://codereview.chromium.org/178583002

git-svn-id: http://skia.googlecode.com/svn/trunk@13610 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
commit-bot@chromium.org 2014-02-27 17:39:46 +00:00
parent 939560b87a
commit 6f954b956f
3 changed files with 56 additions and 18 deletions

View File

@ -14,6 +14,7 @@
#include "SkRRect.h"
#include "SkRegion.h"
#include "SkTDArray.h"
#include "SkTLazy.h"
// Because a single save/restore state can have multiple clips, this class
@ -53,6 +54,8 @@ public:
this->setEmpty();
}
Element(const Element&);
Element(const SkRect& rect, SkRegion::Op op, bool doAA) {
this->initRect(0, rect, op, doAA);
}
@ -72,7 +75,7 @@ public:
Type getType() const { return fType; }
//!< Call if getType() is kPath to get the path.
const SkPath& getPath() const { SkASSERT(kPath_Type == fType); return fPath; }
const SkPath& getPath() const { SkASSERT(kPath_Type == fType); return *fPath.get(); }
//!< Call if getType() is kRRect to get the round-rect.
const SkRRect& getRRect() const { SkASSERT(kRRect_Type == fType); return fRRect; }
@ -117,7 +120,7 @@ public:
case kRRect_Type:
return fRRect.getBounds();
case kPath_Type:
return fPath.getBounds();
return fPath.get()->getBounds();
case kEmpty_Type:
return kEmpty;
default:
@ -137,7 +140,7 @@ public:
case kRRect_Type:
return fRRect.contains(rect);
case kPath_Type:
return fPath.conservativelyContainsRect(rect);
return fPath.get()->conservativelyContainsRect(rect);
case kEmpty_Type:
return false;
default:
@ -150,13 +153,13 @@ public:
* Is the clip shape inverse filled.
*/
bool isInverseFilled() const {
return kPath_Type == fType && fPath.isInverseFillType();
return kPath_Type == fType && fPath.get()->isInverseFillType();
}
private:
friend class SkClipStack;
SkPath fPath;
SkTLazy<SkPath> fPath;
SkRRect fRRect;
int fSaveCount; // save count of stack when this element was added.
SkRegion::Op fOp;

View File

@ -74,6 +74,16 @@ public:
return fPtr;
}
/**
* Destroy the lazy object (if it was created via init() or set())
*/
void reset() {
if (this->isValid()) {
fPtr->~T();
fPtr = NULL;
}
}
/**
* Returns true if a valid object has been initialized in the SkTLazy,
* false otherwise.

View File

@ -16,6 +16,31 @@
static const int32_t kFirstUnreservedGenID = 3;
int32_t SkClipStack::gGenID = kFirstUnreservedGenID;
SkClipStack::Element::Element(const Element& that) {
switch (that.getType()) {
case kEmpty_Type:
fPath.reset();
break;
case kRect_Type: // Rect uses rrect
case kRRect_Type:
fPath.reset();
fRRect = that.fRRect;
break;
case kPath_Type:
fPath.set(that.getPath());
break;
}
fSaveCount = that.fSaveCount;
fOp = that.fOp;
fType = that.fType;
fDoAA = that.fDoAA;
fFiniteBoundType = that.fFiniteBoundType;
fFiniteBound = that.fFiniteBound;
fIsIntersectionOfRects = that.fIsIntersectionOfRects;
fGenID = that.fGenID;
}
bool SkClipStack::Element::operator== (const Element& element) const {
if (this == &element) {
return true;
@ -28,7 +53,7 @@ bool SkClipStack::Element::operator== (const Element& element) const {
}
switch (fType) {
case kPath_Type:
return fPath == element.fPath;
return this->getPath() == element.getPath();
case kRRect_Type:
return fRRect == element.fRRect;
case kRect_Type:
@ -44,19 +69,19 @@ bool SkClipStack::Element::operator== (const Element& element) const {
void SkClipStack::Element::invertShapeFillType() {
switch (fType) {
case kRect_Type:
fPath.reset();
fPath.addRect(this->getRect());
fPath.setFillType(SkPath::kInverseEvenOdd_FillType);
fPath.init();
fPath.get()->addRect(this->getRect());
fPath.get()->setFillType(SkPath::kInverseEvenOdd_FillType);
fType = kPath_Type;
break;
case kRRect_Type:
fPath.reset();
fPath.addRRect(fRRect);
fPath.setFillType(SkPath::kInverseEvenOdd_FillType);
fPath.init();
fPath.get()->addRRect(fRRect);
fPath.get()->setFillType(SkPath::kInverseEvenOdd_FillType);
fType = kPath_Type;
break;
case kPath_Type:
fPath.toggleInverseFillType();
fPath.get()->toggleInverseFillType();
break;
case kEmpty_Type:
// Should this set to an empty, inverse filled path?
@ -79,7 +104,7 @@ void SkClipStack::Element::initPath(int saveCount, const SkPath& path, SkRegion:
return;
}
}
fPath = path;
fPath.set(path);
fType = kPath_Type;
this->initCommon(saveCount, op, doAA);
}
@ -98,7 +123,7 @@ void SkClipStack::Element::asPath(SkPath* path) const {
path->addRRect(fRRect);
break;
case kPath_Type:
*path = fPath;
*path = *fPath.get();
break;
}
}
@ -119,7 +144,7 @@ void SkClipStack::Element::checkEmpty() const {
SkASSERT(kNormal_BoundsType == fFiniteBoundType);
SkASSERT(!fIsIntersectionOfRects);
SkASSERT(kEmptyGenID == fGenID);
SkASSERT(fPath.isEmpty());
SkASSERT(!fPath.isValid());
}
bool SkClipStack::Element::canBeIntersectedInPlace(int saveCount, SkRegion::Op op) const {
@ -357,9 +382,9 @@ void SkClipStack::Element::updateBoundAndGenID(const Element* prior) {
fFiniteBoundType = kNormal_BoundsType;
break;
case kPath_Type:
fFiniteBound = fPath.getBounds();
fFiniteBound = fPath.get()->getBounds();
if (fPath.isInverseFillType()) {
if (fPath.get()->isInverseFillType()) {
fFiniteBoundType = kInsideOut_BoundsType;
} else {
fFiniteBoundType = kNormal_BoundsType;