Initialize fClip in SkBounder, in case doIRect() is called before it is used

inside a canvas (which calls setClip).

Export a global empty region. Used by SkBounder's constructor.



git-svn-id: http://skia.googlecode.com/svn/trunk@985 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
reed@google.com 2011-03-23 13:51:55 +00:00
parent a9ecdadfbc
commit 0a0a236c3b
4 changed files with 48 additions and 43 deletions

View File

@ -36,6 +36,8 @@ class SkRegion;
*/
class SkBounder : public SkRefCnt {
public:
SkBounder();
/* Call to perform a clip test before calling onIRect.
Returns the result from onIRect.
*/

View File

@ -365,7 +365,13 @@ public:
* of bytes actually read.
*/
uint32_t unflatten(const void* buffer);
/**
* Returns a reference to a global empty region. Just a convenience for
* callers that need a const empty region.
*/
static const SkRegion& GetEmptyRegion();
SkDEBUGCODE(void dump() const;)
SkDEBUGCODE(void validate() const;)
SkDEBUGCODE(static void UnitTest();)

View File

@ -2364,8 +2364,8 @@ void SkDraw::drawVertices(SkCanvas::VertexMode vmode, int count,
}
}
////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
#ifdef SK_DEBUG
@ -2386,7 +2386,12 @@ void SkDraw::validate() const {
#endif
//////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
SkBounder::SkBounder() {
// initialize up front. This gets reset by SkCanvas before each draw call.
fClip = &SkRegion::GetEmptyRegion();
}
bool SkBounder::doIRect(const SkIRect& r) {
SkIRect rr;

View File

@ -85,36 +85,29 @@ bool SkRegion::ComputeRunBounds(const SkRegion::RunType runs[], int count, SkIRe
//////////////////////////////////////////////////////////////////////////
SkRegion::SkRegion()
{
SkRegion::SkRegion() {
fBounds.set(0, 0, 0, 0);
fRunHead = SkRegion_gEmptyRunHeadPtr;
}
SkRegion::SkRegion(const SkRegion& src)
{
SkRegion::SkRegion(const SkRegion& src) {
fRunHead = SkRegion_gEmptyRunHeadPtr; // just need a value that won't trigger sk_free(fRunHead)
this->setRegion(src);
}
SkRegion::SkRegion(const SkIRect& rect)
{
SkRegion::SkRegion(const SkIRect& rect) {
fRunHead = SkRegion_gEmptyRunHeadPtr; // just need a value that won't trigger sk_free(fRunHead)
this->setRect(rect);
}
SkRegion::~SkRegion()
{
SkRegion::~SkRegion() {
this->freeRuns();
}
void SkRegion::freeRuns()
{
if (fRunHead->isComplex())
{
void SkRegion::freeRuns() {
if (fRunHead->isComplex()) {
SkASSERT(fRunHead->fRefCnt >= 1);
if (sk_atomic_dec(&fRunHead->fRefCnt) == 1)
{
if (sk_atomic_dec(&fRunHead->fRefCnt) == 1) {
//SkASSERT(gRgnAllocCounter > 0);
//SkDEBUGCODE(sk_atomic_dec(&gRgnAllocCounter));
//SkDEBUGF(("************** gRgnAllocCounter::free %d\n", gRgnAllocCounter));
@ -123,76 +116,68 @@ void SkRegion::freeRuns()
}
}
void SkRegion::allocateRuns(int count)
{
void SkRegion::allocateRuns(int count) {
fRunHead = RunHead::Alloc(count);
}
SkRegion& SkRegion::operator=(const SkRegion& src)
{
SkRegion& SkRegion::operator=(const SkRegion& src) {
(void)this->setRegion(src);
return *this;
}
void SkRegion::swap(SkRegion& other)
{
void SkRegion::swap(SkRegion& other) {
SkTSwap<SkIRect>(fBounds, other.fBounds);
SkTSwap<RunHead*>(fRunHead, other.fRunHead);
}
bool SkRegion::setEmpty()
{
bool SkRegion::setEmpty() {
this->freeRuns();
fBounds.set(0, 0, 0, 0);
fRunHead = SkRegion_gEmptyRunHeadPtr;
return false;
}
bool SkRegion::setRect(int32_t left, int32_t top, int32_t right, int32_t bottom)
{
if (left >= right || top >= bottom)
bool SkRegion::setRect(int32_t left, int32_t top,
int32_t right, int32_t bottom) {
if (left >= right || top >= bottom) {
return this->setEmpty();
}
this->freeRuns();
fBounds.set(left, top, right, bottom);
fRunHead = SkRegion_gRectRunHeadPtr;
return true;
}
bool SkRegion::setRect(const SkIRect& r)
{
bool SkRegion::setRect(const SkIRect& r) {
return this->setRect(r.fLeft, r.fTop, r.fRight, r.fBottom);
}
bool SkRegion::setRegion(const SkRegion& src)
{
if (this != &src)
{
bool SkRegion::setRegion(const SkRegion& src) {
if (this != &src) {
this->freeRuns();
fBounds = src.fBounds;
fRunHead = src.fRunHead;
if (fRunHead->isComplex())
if (fRunHead->isComplex()) {
sk_atomic_inc(&fRunHead->fRefCnt);
}
}
return fRunHead != SkRegion_gEmptyRunHeadPtr;
}
bool SkRegion::op(const SkIRect& rect, const SkRegion& rgn, Op op)
{
bool SkRegion::op(const SkIRect& rect, const SkRegion& rgn, Op op) {
SkRegion tmp(rect);
return this->op(tmp, rgn, op);
}
bool SkRegion::op(const SkRegion& rgn, const SkIRect& rect, Op op)
{
bool SkRegion::op(const SkRegion& rgn, const SkIRect& rect, Op op) {
SkRegion tmp(rect);
return this->op(rgn, tmp, op);
}
//////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
#ifdef ANDROID
char* SkRegion::toString()
@ -1082,7 +1067,14 @@ uint32_t SkRegion::unflatten(const void* storage) {
return buffer.pos();
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
const SkRegion& SkRegion::GetEmptyRegion() {
static SkRegion gEmpty;
return gEmpty;
}
///////////////////////////////////////////////////////////////////////////////
#ifdef SK_DEBUG