From 641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4d Mon Sep 17 00:00:00 2001 From: "robertphillips@google.com" Date: Tue, 31 Jul 2012 19:15:58 +0000 Subject: [PATCH] Replace GrClip with SkClipStack http://codereview.appspot.com/6449070/ git-svn-id: http://skia.googlecode.com/svn/trunk@4865 2bbb7eff-a529-9590-31e7-b0007b416f81 --- include/core/SkClipStack.h | 4 ++- include/gpu/GrClip.h | 10 +++--- include/gpu/GrContext.h | 2 +- include/gpu/SkGpuDevice.h | 5 +-- src/core/SkClipStack.cpp | 8 +++++ src/gpu/GrClip.cpp | 34 +++++------------- src/gpu/GrClipMaskManager.cpp | 45 ++++++++++++----------- src/gpu/GrClipMaskManager.h | 21 +++++------ src/gpu/GrInOrderDrawBuffer.cpp | 80 ++++++++++++++++++++++------------------- src/gpu/GrInOrderDrawBuffer.h | 3 +- src/gpu/GrStencilBuffer.h | 2 +- src/gpu/GrTextContext.cpp | 27 +++++--------- src/gpu/SkGpuDevice.cpp | 77 ++++++++++++++------------------------- tests/ClipCacheTest.cpp | 32 +++++------------ 14 files changed, 150 insertions(+), 200 deletions(-) diff --git a/include/core/SkClipStack.h b/include/core/SkClipStack.h index c0fadb1..4c79c2f 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 cf646a1..4e6211a 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 2f05458..d6ac363 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 f576ae4..539372a 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 d2c2035..e9a02ec 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 e8ea9a6..4fbac8a 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 71743a0..ff47306 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 3ba26d3..d22838e 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 d5d03cd..9f24c4e 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 9dfb18e..4bdaa6e 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 fStates; GrSTAllocator fClears; - GrSTAllocator fClips; + GrSTAllocator fClips; GrSTAllocator fClipOrigins; GrDrawTarget* fAutoFlushTarget; diff --git a/src/gpu/GrStencilBuffer.h b/src/gpu/GrStencilBuffer.h index 506e5ce..77843a3 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 576a5bd..23b16dd 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 ec8f26c..8860d6e 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 0a72be4..a02f0d3 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); -- 2.7.4