aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/core/SkClipStack.h4
-rw-r--r--include/gpu/GrClip.h10
-rw-r--r--include/gpu/GrContext.h2
-rw-r--r--include/gpu/SkGpuDevice.h5
-rw-r--r--src/core/SkClipStack.cpp8
-rw-r--r--src/gpu/GrClip.cpp34
-rw-r--r--src/gpu/GrClipMaskManager.cpp45
-rw-r--r--src/gpu/GrClipMaskManager.h21
-rw-r--r--src/gpu/GrInOrderDrawBuffer.cpp80
-rw-r--r--src/gpu/GrInOrderDrawBuffer.h3
-rw-r--r--src/gpu/GrStencilBuffer.h2
-rw-r--r--src/gpu/GrTextContext.cpp27
-rw-r--r--src/gpu/SkGpuDevice.cpp77
-rw-r--r--tests/ClipCacheTest.cpp32
14 files changed, 150 insertions, 200 deletions
diff --git a/include/core/SkClipStack.h b/include/core/SkClipStack.h
index c0fadb1ab1..4c79c2f824 100644
--- a/include/core/SkClipStack.h
+++ b/include/core/SkClipStack.h
@@ -25,6 +25,7 @@ public:
SkClipStack();
SkClipStack(const SkClipStack& b);
explicit SkClipStack(const SkRect& r);
+ explicit SkClipStack(const SkIRect& r);
~SkClipStack();
SkClipStack& operator=(const SkClipStack& b);
@@ -182,7 +183,8 @@ public:
* the translation (+offsetX, +offsetY) is applied before the clamp to the
* maximum rectangle: [0,maxWidth) x [0,maxHeight).
* isIntersectionOfRects is an optional parameter that is true when
- * 'bounds' is the result of an intersection of rects.
+ * 'devBounds' is the result of an intersection of rects. In this case
+ * 'devBounds' is the exact answer/clip.
*/
void getConservativeBounds(int offsetX,
int offsetY,
diff --git a/include/gpu/GrClip.h b/include/gpu/GrClip.h
index cf646a1282..4e6211a179 100644
--- a/include/gpu/GrClip.h
+++ b/include/gpu/GrClip.h
@@ -11,14 +11,16 @@
#ifndef GrClip_DEFINED
#define GrClip_DEFINED
-#include "GrClipIterator.h"
#include "GrRect.h"
+#include "SkClipStack.h"
+
+class GrSurface;
+
+#include "GrClipIterator.h"
#include "SkPath.h"
#include "SkTArray.h"
-class GrSurface;
-
class GrClip {
public:
GrClip();
@@ -212,7 +214,7 @@ private:
*/
class GrClipData : public SkNoncopyable {
public:
- const GrClip* fClipStack;
+ const SkClipStack* fClipStack;
SkIPoint fOrigin;
GrClipData()
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h
index 2f05458c44..d6ac363edb 100644
--- a/include/gpu/GrContext.h
+++ b/include/gpu/GrContext.h
@@ -710,7 +710,7 @@ public:
GrContext* fContext;
const GrClipData* fOldClip;
- GrClip fNewClipStack;
+ SkClipStack fNewClipStack;
GrClipData fNewClipData;
};
diff --git a/include/gpu/SkGpuDevice.h b/include/gpu/SkGpuDevice.h
index f576ae499b..539372a68f 100644
--- a/include/gpu/SkGpuDevice.h
+++ b/include/gpu/SkGpuDevice.h
@@ -130,10 +130,7 @@ private:
GrSkDrawProcs* fDrawProcs;
- // the clip stack - on loan to us from SkCanvas so it can be NULL.
- const SkClipStack* fClipStack;
- GrClip fGrClip;
- GrClipData fClipData;
+ GrClipData fClipData;
// state for our offscreen render-target
TexCache fCache;
diff --git a/src/core/SkClipStack.cpp b/src/core/SkClipStack.cpp
index d2c2035bef..e9a02ecbb5 100644
--- a/src/core/SkClipStack.cpp
+++ b/src/core/SkClipStack.cpp
@@ -381,6 +381,14 @@ SkClipStack::SkClipStack(const SkRect& r) : fDeque(sizeof(Rec)) {
}
}
+SkClipStack::SkClipStack(const SkIRect& r) : fDeque(sizeof(Rec)) {
+ if (!r.isEmpty()) {
+ SkRect temp;
+ temp.set(r);
+ this->clipDevRect(temp, SkRegion::kReplace_Op, false);
+ }
+}
+
SkClipStack::~SkClipStack() {
reset();
}
diff --git a/src/gpu/GrClip.cpp b/src/gpu/GrClip.cpp
index e8ea9a6399..4fbac8a714 100644
--- a/src/gpu/GrClip.cpp
+++ b/src/gpu/GrClip.cpp
@@ -6,8 +6,6 @@
* found in the LICENSE file.
*/
-
-
#include "GrClip.h"
#include "GrSurface.h"
#include "GrRect.h"
@@ -254,31 +252,15 @@ void GrClip::Iter::reset(const GrClip& stack, IterStart startLoc) {
void GrClipData::getConservativeBounds(const GrSurface* surface,
GrIRect* devResult,
bool* isIntersectionOfRects) const {
+ GrRect devBounds;
- // Until we switch to using the SkClipStack directly we need to take
- // this belt and suspenders approach here. When the clip stack
- // reduces to a single clip, GrClip uses that rect as the conservative
- // bounds rather than SkClipStack's bounds and the reduced rect
- // was never trimmed to the render target's bounds.
- SkRect temp = SkRect::MakeLTRB(0, 0,
- SkIntToScalar(surface->width()),
- SkIntToScalar(surface->height()));
-
- // convervativeBounds starts off in canvas coordinates here
- GrRect conservativeBounds = fClipStack->getConservativeBounds();
-
- // but is translated into device coordinates here
- conservativeBounds.offset(SkIntToScalar(-fOrigin.fX),
- SkIntToScalar(-fOrigin.fY));
+ fClipStack->getConservativeBounds(-fOrigin.fX,
+ -fOrigin.fY,
+ surface->width(),
+ surface->height(),
+ &devBounds,
+ isIntersectionOfRects);
- if (!conservativeBounds.intersect(temp)) {
- conservativeBounds.setEmpty();
- }
-
- conservativeBounds.roundOut(devResult);
-
- if (NULL != isIntersectionOfRects) {
- *isIntersectionOfRects = fClipStack->isRect();
- }
+ devBounds.roundOut(devResult);
}
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp
index 71743a03e9..ff473069df 100644
--- a/src/gpu/GrClipMaskManager.cpp
+++ b/src/gpu/GrClipMaskManager.cpp
@@ -83,12 +83,12 @@ GrPathFill get_path_fill(const SkPath& path) {
/**
* Does any individual clip in 'clipIn' use anti-aliasing?
*/
-bool requires_AA(const GrClip& clipIn) {
+bool requires_AA(const SkClipStack& clipIn) {
- GrClip::Iter iter;
- iter.reset(clipIn, GrClip::Iter::kBottom_IterStart);
+ SkClipStack::Iter iter;
+ iter.reset(clipIn, SkClipStack::Iter::kBottom_IterStart);
- const GrClip::Iter::Clip* clip = NULL;
+ const SkClipStack::Iter::Clip* clip = NULL;
for (clip = iter.skipToTopmost(SkRegion::kReplace_Op);
NULL != clip;
clip = iter.next()) {
@@ -108,15 +108,15 @@ bool requires_AA(const GrClip& clipIn) {
* will be used on any element. If so, it returns true to indicate that the
* entire clip should be rendered in SW and then uploaded en masse to the gpu.
*/
-bool GrClipMaskManager::useSWOnlyPath(const GrClip& clipIn) {
+bool GrClipMaskManager::useSWOnlyPath(const SkClipStack& clipIn) {
// TODO: generalize this function so that when
// a clip gets complex enough it can just be done in SW regardless
// of whether it would invoke the GrSoftwarePathRenderer.
bool useSW = false;
- GrClip::Iter iter(clipIn, GrClip::Iter::kBottom_IterStart);
- const GrClip::Iter::Clip* clip = NULL;
+ SkClipStack::Iter iter(clipIn, SkClipStack::Iter::kBottom_IterStart);
+ const SkClipStack::Iter::Clip* clip = NULL;
for (clip = iter.skipToTopmost(SkRegion::kReplace_Op);
NULL != clip;
@@ -169,7 +169,6 @@ bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn) {
}
bool requiresAA = requires_AA(*clipDataIn->fClipStack);
- GrAssert(requiresAA == clipDataIn->fClipStack->requiresAA());
#if GR_SW_CLIP
// If MSAA is enabled we can do everything in the stencil buffer.
@@ -281,8 +280,8 @@ bool contains(const SkRect& canvContainer,
// determines how many elements at the head of the clip can be skipped and
// whether the initial clear should be to the inside- or outside-the-clip value,
// and what op should be used to draw the first element that isn't skipped.
-const GrClip::Iter::Clip* process_initial_clip_elements(
- GrClip::Iter* iter,
+const SkClipStack::Iter::Clip* process_initial_clip_elements(
+ SkClipStack::Iter* iter,
const GrIRect& devBounds,
bool* clearToInside,
SkRegion::Op* firstOp,
@@ -298,7 +297,7 @@ const GrClip::Iter::Clip* process_initial_clip_elements(
bool done = false;
*clearToInside = true;
- const GrClip::Iter::Clip* clip = NULL;
+ const SkClipStack::Iter::Clip* clip = NULL;
for (clip = iter->skipToTopmost(SkRegion::kReplace_Op);
NULL != clip && !done;
@@ -469,7 +468,7 @@ void device_to_canvas(SkRect* rect, const SkIPoint& origin) {
////////////////////////////////////////////////////////////////////////////////
bool GrClipMaskManager::drawClipShape(GrTexture* target,
- const GrClip::Iter::Clip* clip,
+ const SkClipStack::Iter::Clip* clip,
const GrIRect& resultBounds) {
GrDrawState* drawState = fGpu->drawState();
GrAssert(NULL != drawState);
@@ -535,7 +534,7 @@ void GrClipMaskManager::getTemp(const GrIRect& bounds,
}
-void GrClipMaskManager::setupCache(const GrClip& clipIn,
+void GrClipMaskManager::setupCache(const SkClipStack& clipIn,
const GrIRect& bounds) {
// Since we are setting up the cache we know the last lookup was a miss
// Free up the currently cached mask so it can be reused
@@ -628,9 +627,9 @@ bool GrClipMaskManager::createAlphaClipMask(const GrClipData& clipDataIn,
bool clearToInside;
SkRegion::Op firstOp = SkRegion::kReplace_Op; // suppress warning
- GrClip::Iter iter(*clipDataIn.fClipStack,
- GrClip::Iter::kBottom_IterStart);
- const GrClip::Iter::Clip* clip = process_initial_clip_elements(&iter,
+ SkClipStack::Iter iter(*clipDataIn.fClipStack,
+ SkClipStack::Iter::kBottom_IterStart);
+ const SkClipStack::Iter::Clip* clip = process_initial_clip_elements(&iter,
*devResultBounds,
&clearToInside,
&firstOp,
@@ -749,7 +748,7 @@ bool GrClipMaskManager::createStencilClipMask(const GrClipData& clipDataIn,
// The origin of 'newClipData' is (0, 0) so it is okay to place
// a device-coordinate bound in 'newClipStack'
- GrClip newClipStack(devClipBounds);
+ SkClipStack newClipStack(devClipBounds);
GrClipData newClipData;
newClipData.fClipStack = &newClipStack;
@@ -782,9 +781,9 @@ bool GrClipMaskManager::createStencilClipMask(const GrClipData& clipDataIn,
bool clearToInside;
SkRegion::Op firstOp = SkRegion::kReplace_Op; // suppress warning
- GrClip::Iter iter(*oldClipData->fClipStack,
- GrClip::Iter::kBottom_IterStart);
- const GrClip::Iter::Clip* clip = process_initial_clip_elements(&iter,
+ SkClipStack::Iter iter(*oldClipData->fClipStack,
+ SkClipStack::Iter::kBottom_IterStart);
+ const SkClipStack::Iter::Clip* clip = process_initial_clip_elements(&iter,
devRTRect,
&clearToInside,
&firstOp,
@@ -1155,9 +1154,9 @@ bool GrClipMaskManager::createSoftwareClipMask(const GrClipData& clipDataIn,
bool clearToInside;
SkRegion::Op firstOp = SkRegion::kReplace_Op; // suppress warning
- GrClip::Iter iter(*clipDataIn.fClipStack,
- GrClip::Iter::kBottom_IterStart);
- const GrClip::Iter::Clip* clip = process_initial_clip_elements(&iter,
+ SkClipStack::Iter iter(*clipDataIn.fClipStack,
+ SkClipStack::Iter::kBottom_IterStart);
+ const SkClipStack::Iter::Clip* clip = process_initial_clip_elements(&iter,
*devResultBounds,
&clearToInside,
&firstOp,
diff --git a/src/gpu/GrClipMaskManager.h b/src/gpu/GrClipMaskManager.h
index 3ba26d3818..d22838e6e7 100644
--- a/src/gpu/GrClipMaskManager.h
+++ b/src/gpu/GrClipMaskManager.h
@@ -16,6 +16,7 @@
#include "GrStencil.h"
#include "GrTexture.h"
+#include "SkClipStack.h"
#include "SkDeque.h"
#include "SkPath.h"
#include "SkRefCnt.h"
@@ -44,7 +45,7 @@ public:
}
}
- bool canReuse(const GrClip& clip, int width, int height) {
+ bool canReuse(const SkClipStack& clip, int width, int height) {
if (fStack.empty()) {
GrAssert(false);
@@ -93,11 +94,11 @@ public:
}
}
- void getLastClip(GrClip* clip) const {
+ void getLastClip(SkClipStack* clip) const {
if (fStack.empty()) {
GrAssert(false);
- clip->setEmpty();
+ clip->reset();
return;
}
@@ -130,7 +131,7 @@ public:
return back->fLastMask.texture();
}
- void acquireMask(const GrClip& clip,
+ void acquireMask(const SkClipStack& clip,
const GrTextureDesc& desc,
const GrIRect& bound) {
@@ -216,7 +217,7 @@ private:
}
void acquireMask(GrContext* context,
- const GrClip& clip,
+ const SkClipStack& clip,
const GrTextureDesc& desc,
const GrIRect& bound) {
@@ -228,7 +229,7 @@ private:
}
void reset () {
- fLastClip.setEmpty();
+ fLastClip.reset();
GrTextureDesc desc;
@@ -236,7 +237,7 @@ private:
fLastBound.setEmpty();
}
- GrClip fLastClip;
+ SkClipStack fLastClip;
// The mask's width & height values are used in setupDrawStateAAClip to
// correctly scale the uvs for geometry drawn with this mask
GrAutoScratchTexture fLastMask;
@@ -339,10 +340,10 @@ private:
GrTexture** result,
GrIRect *devResultBounds);
- bool useSWOnlyPath(const GrClip& clipIn);
+ bool useSWOnlyPath(const SkClipStack& clipIn);
bool drawClipShape(GrTexture* target,
- const GrClip::Iter::Clip* clip,
+ const SkClipStack::Iter::Clip* clip,
const GrIRect& resultBounds);
void drawTexture(GrTexture* target,
@@ -350,7 +351,7 @@ private:
void getTemp(const GrIRect& bounds, GrAutoScratchTexture* temp);
- void setupCache(const GrClip& clip,
+ void setupCache(const SkClipStack& clip,
const GrIRect& bounds);
/**
diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp
index d5d03cd5cf..9f24c4e7a3 100644
--- a/src/gpu/GrInOrderDrawBuffer.cpp
+++ b/src/gpu/GrInOrderDrawBuffer.cpp
@@ -125,44 +125,52 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
// the rect.
bool disabledClip = false;
- if (drawState->isClipState() && fClip->fClipStack->isRect()) {
-
- GrClip::Iter iter(*fClip->fClipStack, GrClip::Iter::kBottom_IterStart);
- const GrClip::Iter::Clip* clip = iter.next();
- GrAssert(NULL != clip && NULL != clip->fRect);
-
- GrRect clipRect = *clip->fRect;
- // If the clip rect touches the edge of the viewport, extended it
- // out (close) to infinity to avoid bogus intersections.
- // We might consider a more exact clip to viewport if this
- // conservative test fails.
- const GrRenderTarget* target = drawState->getRenderTarget();
- if (0 >= clipRect.fLeft) {
- clipRect.fLeft = GR_ScalarMin;
- }
- if (target->width() <= clipRect.fRight) {
- clipRect.fRight = GR_ScalarMax;
- }
- if (0 >= clipRect.top()) {
- clipRect.fTop = GR_ScalarMin;
- }
- if (target->height() <= clipRect.fBottom) {
- clipRect.fBottom = GR_ScalarMax;
- }
- int stride = VertexSize(layout);
- bool insideClip = true;
- for (int v = 0; v < 4; ++v) {
- const GrPoint& p = *GetVertexPoint(geo.vertices(), v, stride);
- if (!clipRect.contains(p)) {
- insideClip = false;
- break;
+ if (drawState->isClipState()) {
+
+ GrRect devClipRect;
+ bool isIntersectionOfRects = false;
+
+ fClip->fClipStack->getConservativeBounds(-fClip->fOrigin.fX,
+ -fClip->fOrigin.fY,
+ drawState->getRenderTarget()->width(),
+ drawState->getRenderTarget()->height(),
+ &devClipRect,
+ &isIntersectionOfRects);
+
+ if (isIntersectionOfRects) {
+ // If the clip rect touches the edge of the viewport, extended it
+ // out (close) to infinity to avoid bogus intersections.
+ // We might consider a more exact clip to viewport if this
+ // conservative test fails.
+ const GrRenderTarget* target = drawState->getRenderTarget();
+ if (0 >= devClipRect.fLeft) {
+ devClipRect.fLeft = GR_ScalarMin;
+ }
+ if (target->width() <= devClipRect.fRight) {
+ devClipRect.fRight = GR_ScalarMax;
+ }
+ if (0 >= devClipRect.top()) {
+ devClipRect.fTop = GR_ScalarMin;
+ }
+ if (target->height() <= devClipRect.fBottom) {
+ devClipRect.fBottom = GR_ScalarMax;
+ }
+ int stride = VertexSize(layout);
+ bool insideClip = true;
+ for (int v = 0; v < 4; ++v) {
+ const GrPoint& p = *GetVertexPoint(geo.vertices(), v, stride);
+ if (!devClipRect.contains(p)) {
+ insideClip = false;
+ break;
+ }
+ }
+ if (insideClip) {
+ drawState->disableState(GrDrawState::kClip_StateBit);
+ disabledClip = true;
}
- }
- if (insideClip) {
- drawState->disableState(GrDrawState::kClip_StateBit);
- disabledClip = true;
}
}
+
if (!this->needsNewClip() &&
!this->needsNewState() &&
fCurrQuad > 0 &&
@@ -833,7 +841,7 @@ void GrInOrderDrawBuffer::recordClip() {
}
void GrInOrderDrawBuffer::recordDefaultClip() {
- fClips.push_back() = GrClip();
+ fClips.push_back() = SkClipStack();
fClipOrigins.push_back() = SkIPoint::Make(0, 0);
fCmds.push_back(kSetClip_Cmd);
}
diff --git a/src/gpu/GrInOrderDrawBuffer.h b/src/gpu/GrInOrderDrawBuffer.h
index 9dfb18e91c..4bdaa6ecdc 100644
--- a/src/gpu/GrInOrderDrawBuffer.h
+++ b/src/gpu/GrInOrderDrawBuffer.h
@@ -17,6 +17,7 @@
#include "GrPath.h"
#include "GrClip.h"
+#include "SkClipStack.h"
#include "SkTemplates.h"
class GrGpu;
@@ -232,7 +233,7 @@ private:
GrSTAllocator<kStatePreallocCnt, GrDrawState> fStates;
GrSTAllocator<kClearPreallocCnt, Clear> fClears;
- GrSTAllocator<kClipPreallocCnt, GrClip> fClips;
+ GrSTAllocator<kClipPreallocCnt, SkClipStack> fClips;
GrSTAllocator<kClipPreallocCnt, SkIPoint> fClipOrigins;
GrDrawTarget* fAutoFlushTarget;
diff --git a/src/gpu/GrStencilBuffer.h b/src/gpu/GrStencilBuffer.h
index 506e5ce102..77843a3baf 100644
--- a/src/gpu/GrStencilBuffer.h
+++ b/src/gpu/GrStencilBuffer.h
@@ -98,7 +98,7 @@ private:
int fBits;
int fSampleCnt;
- GrClip fLastClipStack;
+ SkClipStack fLastClipStack;
GrClipData fLastClipData;
int fLastClipWidth;
int fLastClipHeight;
diff --git a/src/gpu/GrTextContext.cpp b/src/gpu/GrTextContext.cpp
index 576a5bdeae..23b16dd3ae 100644
--- a/src/gpu/GrTextContext.cpp
+++ b/src/gpu/GrTextContext.cpp
@@ -70,20 +70,6 @@ void GrTextContext::flushGlyphs() {
fDrawTarget = NULL;
}
-namespace {
-
-// 'rect' enters in canvas coordinates and leaves in device coordinates
-void canvas_to_device(SkRect* rect, const SkIPoint& origin) {
- GrAssert(NULL != rect);
-
- rect->fLeft -= SkIntToScalar(origin.fX);
- rect->fTop -= SkIntToScalar(origin.fY);
- rect->fRight -= SkIntToScalar(origin.fX);
- rect->fBottom -= SkIntToScalar(origin.fY);
-}
-
-};
-
GrTextContext::GrTextContext(GrContext* context,
const GrPaint& paint,
const GrMatrix* extMatrix) : fPaint(paint) {
@@ -101,17 +87,22 @@ GrTextContext::GrTextContext(GrContext* context,
const GrClipData* clipData = context->getClip();
- GrRect conservativeBound = clipData->fClipStack->getConservativeBounds();
- canvas_to_device(&conservativeBound, clipData->fOrigin);
+ GrRect devConservativeBound;
+ clipData->fClipStack->getConservativeBounds(
+ -clipData->fOrigin.fX,
+ -clipData->fOrigin.fY,
+ context->getRenderTarget()->width(),
+ context->getRenderTarget()->height(),
+ &devConservativeBound);
if (!fExtMatrix.isIdentity()) {
GrMatrix inverse;
if (fExtMatrix.invert(&inverse)) {
- inverse.mapRect(&conservativeBound);
+ inverse.mapRect(&devConservativeBound);
}
}
- conservativeBound.roundOut(&fClipRect);
+ devConservativeBound.roundOut(&fClipRect);
// save the context's original matrix off and restore in destructor
// this must be done before getTextTarget.
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index ec8f26c5fb..8860d6e6a5 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -167,14 +167,12 @@ static SkBitmap make_bitmap(GrContext* context, GrRenderTarget* renderTarget) {
}
SkGpuDevice::SkGpuDevice(GrContext* context, GrTexture* texture)
-: SkDevice(make_bitmap(context, texture->asRenderTarget()))
-, fClipStack(NULL) {
+: SkDevice(make_bitmap(context, texture->asRenderTarget())) {
this->initFromRenderTarget(context, texture->asRenderTarget());
}
SkGpuDevice::SkGpuDevice(GrContext* context, GrRenderTarget* renderTarget)
-: SkDevice(make_bitmap(context, renderTarget))
-, fClipStack(NULL) {
+: SkDevice(make_bitmap(context, renderTarget)) {
this->initFromRenderTarget(context, renderTarget);
}
@@ -215,8 +213,8 @@ SkGpuDevice::SkGpuDevice(GrContext* context,
SkBitmap::Config config,
int width,
int height)
- : SkDevice(config, width, height, false /*isOpaque*/)
- , fClipStack(NULL) {
+ : SkDevice(config, width, height, false /*isOpaque*/) {
+
fNeedPrepareRenderTarget = false;
fDrawProcs = NULL;
@@ -351,23 +349,18 @@ void SkGpuDevice::onAttachToCanvas(SkCanvas* canvas) {
INHERITED::onAttachToCanvas(canvas);
// Canvas promises that this ptr is valid until onDetachFromCanvas is called
- fClipStack = canvas->getClipStack();
-
- fClipData.fClipStack = NULL;
+ fClipData.fClipStack = canvas->getClipStack();
}
void SkGpuDevice::onDetachFromCanvas() {
INHERITED::onDetachFromCanvas();
- fClipStack = NULL;
-
fClipData.fClipStack = NULL;
}
#ifdef SK_DEBUG
-static void check_bounds(const SkClipStack& clipStack,
+static void check_bounds(const GrClipData& clipData,
const SkRegion& clipRegion,
- const SkIPoint& origin,
int renderTargetWidth,
int renderTargetHeight) {
@@ -378,13 +371,13 @@ static void check_bounds(const SkClipStack& clipStack,
SkClipStack::BoundsType boundType;
SkRect canvTemp;
- clipStack.getBounds(&canvTemp, &boundType);
+ clipData.fClipStack->getBounds(&canvTemp, &boundType);
if (SkClipStack::kNormal_BoundsType == boundType) {
SkIRect devTemp;
canvTemp.roundOut(&devTemp);
- devTemp.offset(-origin.fX, -origin.fY);
+ devTemp.offset(-clipData.fOrigin.fX, -clipData.fOrigin.fY);
if (!devBound.intersect(devTemp)) {
devBound.setEmpty();
@@ -397,55 +390,37 @@ static void check_bounds(const SkClipStack& clipStack,
///////////////////////////////////////////////////////////////////////////////
-static void convert_matrixclip(GrContext* context, const SkMatrix& matrix,
- const SkClipStack& clipStack,
- GrClipData& clipData,
- const SkRegion& clipRegion,
- const SkIPoint& origin,
- int renderTargetWidth, int renderTargetHeight,
- GrClip* result) {
+static void set_matrix_and_clip(GrContext* context, const SkMatrix& matrix,
+ GrClipData& clipData,
+ const SkRegion& clipRegion,
+ const SkIPoint& origin,
+ int renderTargetWidth, int renderTargetHeight) {
context->setMatrix(matrix);
- SkGrClipIterator iter;
- iter.reset(clipStack);
+ clipData.fOrigin = origin;
#ifdef SK_DEBUG
- check_bounds(clipStack, clipRegion, origin,
+ check_bounds(clipData, clipRegion,
renderTargetWidth, renderTargetHeight);
#endif
- SkRect devClipBounds;
- bool isIntersectionOfRects = false;
- clipStack.getConservativeBounds(0, 0,
- renderTargetWidth,
- renderTargetHeight,
- &devClipBounds,
- &isIntersectionOfRects);
-
- result->setFromIterator(&iter, devClipBounds);
-
- GrAssert(result->isRect() == isIntersectionOfRects);
-
- clipData.fClipStack = result;
- clipData.fOrigin = origin;
context->setClip(&clipData);
}
// call this every draw call, to ensure that the context reflects our state,
// and not the state from some other canvas/device
void SkGpuDevice::prepareRenderTarget(const SkDraw& draw) {
- GrAssert(NULL != fClipStack);
+ GrAssert(NULL != fClipData.fClipStack);
if (fNeedPrepareRenderTarget ||
fContext->getRenderTarget() != fRenderTarget) {
fContext->setRenderTarget(fRenderTarget);
- SkASSERT(draw.fClipStack && draw.fClipStack == fClipStack);
+ SkASSERT(draw.fClipStack && draw.fClipStack == fClipData.fClipStack);
- convert_matrixclip(fContext, *draw.fMatrix,
- *fClipStack, fClipData, *draw.fClip, this->getOrigin(),
- fRenderTarget->width(), fRenderTarget->height(),
- &fGrClip);
+ set_matrix_and_clip(fContext, *draw.fMatrix,
+ fClipData, *draw.fClip, this->getOrigin(),
+ fRenderTarget->width(), fRenderTarget->height());
fNeedPrepareRenderTarget = false;
}
}
@@ -459,14 +434,14 @@ void SkGpuDevice::setMatrixClip(const SkMatrix& matrix, const SkRegion& clip,
void SkGpuDevice::gainFocus(const SkMatrix& matrix, const SkRegion& clip) {
- GrAssert(NULL != fClipStack);
+ GrAssert(NULL != fClipData.fClipStack);
fContext->setRenderTarget(fRenderTarget);
this->INHERITED::gainFocus(matrix, clip);
- convert_matrixclip(fContext, matrix, *fClipStack, fClipData, clip, this->getOrigin(),
- fRenderTarget->width(), fRenderTarget->height(), &fGrClip);
+ set_matrix_and_clip(fContext, matrix, fClipData, clip, this->getOrigin(),
+ fRenderTarget->width(), fRenderTarget->height());
DO_DEFERRED_CLEAR;
}
@@ -895,7 +870,7 @@ bool drawWithGPUMaskFilter(GrContext* context, const SkPath& path,
context->setRenderTarget(pathTexture->asRenderTarget());
- GrClip newClipStack(srcRect);
+ SkClipStack newClipStack(srcRect);
GrClipData newClipData;
newClipData.fClipStack = &newClipStack;
context->setClip(&newClipData);
@@ -1982,8 +1957,8 @@ SkGpuDevice::SkGpuDevice(GrContext* context,
GrTexture* texture,
TexCache cacheEntry,
bool needClear)
- : SkDevice(make_bitmap(context, texture->asRenderTarget()))
- , fClipStack(NULL) {
+ : SkDevice(make_bitmap(context, texture->asRenderTarget())) {
+
GrAssert(texture && texture->asRenderTarget());
GrAssert(NULL == cacheEntry.texture() || texture == cacheEntry.texture());
this->initFromRenderTarget(context, texture->asRenderTarget());
diff --git a/tests/ClipCacheTest.cpp b/tests/ClipCacheTest.cpp
index 0a72be4a8b..a02f0d3ec9 100644
--- a/tests/ClipCacheTest.cpp
+++ b/tests/ClipCacheTest.cpp
@@ -78,22 +78,9 @@ static void test_clip_bounds(skiatest::Reporter* reporter, GrContext* context) {
REPORTER_ASSERT(reporter, screen == devStackBounds);
REPORTER_ASSERT(reporter, isIntersectionOfRects);
- // convert the SkClipStack to a GrClip
- SkGrClipIterator iter;
- iter.reset(stack);
-
- GrClip clip;
- clip.setFromIterator(&iter, devStackBounds);
-
- const GrRect& canvGrClipBound = clip.getConservativeBounds();
-
- // make sure that GrClip is behaving itself
- REPORTER_ASSERT(reporter, clipRect == canvGrClipBound);
- REPORTER_ASSERT(reporter, clip.isRect());
-
- // wrap the GrClip in a GrClipData
+ // wrap the SkClipStack in a GrClipData
GrClipData clipData;
- clipData.fClipStack = &clip;
+ clipData.fClipStack = &stack;
SkIRect devGrClipDataBound;
clipData.getConservativeBounds(texture,
@@ -109,10 +96,10 @@ static void test_clip_bounds(skiatest::Reporter* reporter, GrContext* context) {
// verify that the top state of the stack matches the passed in state
static void check_state(skiatest::Reporter* reporter,
const GrClipMaskCache& cache,
- const GrClip& clip,
+ const SkClipStack& clip,
GrTexture* mask,
const GrIRect& bound) {
- GrClip cacheClip;
+ SkClipStack cacheClip;
cache.getLastClip(&cacheClip);
REPORTER_ASSERT(reporter, clip == cacheClip);
@@ -135,8 +122,8 @@ static void test_cache(skiatest::Reporter* reporter, GrContext* context) {
cache.setContext(context);
- GrClip emptyClip;
- emptyClip.setEmpty();
+ SkClipStack emptyClip;
+ emptyClip.reset();
GrIRect emptyBound;
emptyBound.setEmpty();
@@ -148,8 +135,7 @@ static void test_cache(skiatest::Reporter* reporter, GrContext* context) {
GrIRect bound1;
bound1.set(0, 0, 100, 100);
- GrClip clip1;
- clip1.setFromIRect(bound1);
+ SkClipStack clip1(bound1);
GrTextureDesc desc;
desc.fFlags = kRenderTarget_GrTextureFlagBit;
@@ -180,9 +166,7 @@ static void test_cache(skiatest::Reporter* reporter, GrContext* context) {
GrIRect bound2;
bound2.set(-10, -10, 10, 10);
- GrClip clip2;
- clip2.setEmpty();
- clip2.setFromIRect(bound2);
+ SkClipStack clip2(bound2);
cache.acquireMask(clip2, desc, bound2);