From 586d5d640b19860dfbbd903a5188da1bbbe87336 Mon Sep 17 00:00:00 2001 From: joshualitt Date: Wed, 25 Feb 2015 11:21:21 -0800 Subject: [PATCH] I'd really like to land this before the branch so speedy reviews are appreciated. BUG=skia: Review URL: https://codereview.chromium.org/936943002 --- gm/texdata.cpp | 7 ++- include/core/SkMaskFilter.h | 3 + include/core/SkRect.h | 10 +++ include/gpu/GrClip.h | 41 ++++++++++--- include/gpu/GrContext.h | 91 ++++++---------------------- src/core/SkImageFilter.cpp | 9 ++- src/core/SkMaskFilter.cpp | 2 + src/effects/SkAlphaThresholdFilter.cpp | 3 +- src/effects/SkBlurMaskFilter.cpp | 13 ++-- src/effects/SkDisplacementMapEffect.cpp | 3 +- src/effects/SkGpuBlurUtils.cpp | 42 +++++++------ src/effects/SkMorphologyImageFilter.cpp | 32 ++++++---- src/effects/SkXfermodeImageFilter.cpp | 2 +- src/gpu/GrBitmapTextContext.cpp | 20 +++--- src/gpu/GrBitmapTextContext.h | 6 +- src/gpu/GrClip.cpp | 11 +++- src/gpu/GrClipMaskManager.cpp | 62 ++++++++++++------- src/gpu/GrContext.cpp | 78 ++++++++++++++---------- src/gpu/GrDistanceFieldTextContext.cpp | 20 +++--- src/gpu/GrDistanceFieldTextContext.h | 6 +- src/gpu/GrPipelineBuilder.cpp | 6 +- src/gpu/GrPipelineBuilder.h | 2 +- src/gpu/GrStencilAndCoverTextContext.cpp | 11 ++-- src/gpu/GrStencilAndCoverTextContext.h | 8 +-- src/gpu/GrTextContext.cpp | 22 ++++--- src/gpu/GrTextContext.h | 17 +++--- src/gpu/SkGpuDevice.cpp | 77 ++++++++++++----------- src/gpu/SkGpuDevice.h | 2 +- src/gpu/SkGr.cpp | 11 ++-- src/gpu/effects/GrConfigConversionEffect.cpp | 20 ++++-- tests/ClipCacheTest.cpp | 10 +-- tests/GLProgramsTest.cpp | 2 +- 32 files changed, 359 insertions(+), 290 deletions(-) diff --git a/gm/texdata.cpp b/gm/texdata.cpp index e0aa233..927bea5 100644 --- a/gm/texdata.cpp +++ b/gm/texdata.cpp @@ -91,7 +91,8 @@ protected: } SkAutoTUnref au(texture); - GrContext::AutoClip acs(ctx, SkRect::MakeWH(2*S, 2*S)); + // setup new clip + GrClip clip(SkRect::MakeWH(2*S, 2*S)); GrPaint paint; paint.setPorterDuffXPFactory(SkXfermode::kSrcOver_Mode); @@ -109,7 +110,7 @@ protected: tm.postIDiv(2*S, 2*S); paint.addColorTextureProcessor(texture, tm); - ctx->drawRect(target, paint, vm, SkRect::MakeWH(2*S, 2*S)); + ctx->drawRect(target, clip, paint, vm, SkRect::MakeWH(2*S, 2*S)); // now update the lower right of the texture in first pass // or upper right in second pass @@ -123,7 +124,7 @@ protected: texture->writePixels(S, (i ? 0 : S), S, S, texture->config(), gTextureData.get(), 4 * stride); - ctx->drawRect(target, paint, vm, SkRect::MakeWH(2*S, 2*S)); + ctx->drawRect(target, clip, paint, vm, SkRect::MakeWH(2*S, 2*S)); } } else { this->drawGpuOnlyMessage(canvas); diff --git a/include/core/SkMaskFilter.h b/include/core/SkMaskFilter.h index 1167407..c94faf6 100644 --- a/include/core/SkMaskFilter.h +++ b/include/core/SkMaskFilter.h @@ -15,6 +15,7 @@ #include "SkMask.h" #include "SkPaint.h" +class GrClip; class GrContext; class GrPaint; class GrRenderTarget; @@ -100,6 +101,7 @@ public: virtual bool directFilterMaskGPU(GrContext* context, GrRenderTarget* rt, GrPaint* grp, + const GrClip&, const SkMatrix& viewMatrix, const SkStrokeRec& strokeRec, const SkPath& path) const; @@ -110,6 +112,7 @@ public: virtual bool directFilterRRectMaskGPU(GrContext* context, GrRenderTarget* rt, GrPaint* grp, + const GrClip&, const SkMatrix& viewMatrix, const SkStrokeRec& strokeRec, const SkRRect& rrect) const; diff --git a/include/core/SkRect.h b/include/core/SkRect.h index 69c2dc9..8d68c97 100644 --- a/include/core/SkRect.h +++ b/include/core/SkRect.h @@ -784,6 +784,16 @@ public: } /** + * Returns true if the specified rectangle r is inside or equal to this rectangle. + */ + bool contains(const SkIRect& r) const { + // todo: can we eliminate the this->isEmpty check? + return !r.isEmpty() && !this->isEmpty() && + fLeft <= SkIntToScalar(r.fLeft) && fTop <= SkIntToScalar(r.fTop) && + fRight >= SkIntToScalar(r.fRight) && fBottom >= SkIntToScalar(r.fBottom); + } + + /** * Set the dst rectangle by rounding this rectangle's coordinates to their * nearest integer values using SkScalarRoundToInt. */ diff --git a/include/gpu/GrClip.h b/include/gpu/GrClip.h index 76cb46e..e8f42a2 100644 --- a/include/gpu/GrClip.h +++ b/include/gpu/GrClip.h @@ -15,7 +15,7 @@ struct SkIRect; /** * GrClip encapsulates the information required to construct the clip - * masks. 'A GrClip is either wide open, just an IRect, just a Rect(TODO), or a full clipstack. + * masks. 'A GrClip is either wide open, just an IRect, just a Rect, or a full clipstack. * If the clip is a clipstack than the origin is used to translate the stack with * respect to device coordinates. This allows us to use a clip stack that is * specified for a root device with a layer device that is restricted to a subset @@ -28,18 +28,23 @@ public: GrClip() : fClipType(kWideOpen_ClipType) { fOrigin.setZero(); } + GrClip(const SkIRect& rect) : fClipType(kIRect_ClipType) { fOrigin.setZero(); fClip.fIRect = rect; } + + GrClip(const SkRect& rect) : fClipType(kRect_ClipType) { + fOrigin.setZero(); + fClip.fRect = rect; + } + ~GrClip() { this->reset(); } const GrClip& operator=(const GrClip& other) { this->reset(); fClipType = other.fClipType; switch (other.fClipType) { - default: - SkFAIL("Incomplete Switch\n"); case kWideOpen_ClipType: fOrigin.setZero(); break; @@ -51,6 +56,10 @@ public: fClip.fIRect = other.irect(); fOrigin.setZero(); break; + case kRect_ClipType: + fClip.fRect = other.rect(); + fOrigin.setZero(); + break; } return *this; } @@ -61,9 +70,6 @@ public: } switch (fClipType) { - default: - SkFAIL("Incomplete Switch\n"); - return false; case kWideOpen_ClipType: return true; case kClipStack_ClipType: @@ -80,6 +86,9 @@ public: case kIRect_ClipType: return this->irect() == other.irect(); break; + case kRect_ClipType: + return this->rect() == other.rect(); + break; } } @@ -113,6 +122,11 @@ public: return fClip.fIRect; } + const SkRect& rect() const { + SkASSERT(kRect_ClipType == fClipType); + return fClip.fRect; + } + void reset() { if (kClipStack_ClipType == fClipType) { fClip.fStack->unref(); @@ -132,13 +146,15 @@ public: bool isWideOpen(const SkRect& rect) const { return (kWideOpen_ClipType == fClipType) || (kClipStack_ClipType == fClipType && this->clipStack()->isWideOpen()) || - (kIRect_ClipType == fClipType && this->irect().contains(rect)); + (kIRect_ClipType == fClipType && this->irect().contains(rect)) || + (kRect_ClipType == fClipType && this->rect().contains(rect)); } bool isWideOpen(const SkIRect& rect) const { return (kWideOpen_ClipType == fClipType) || (kClipStack_ClipType == fClipType && this->clipStack()->isWideOpen()) || - (kIRect_ClipType == fClipType && this->irect().contains(rect)); + (kIRect_ClipType == fClipType && this->irect().contains(rect)) || + (kRect_ClipType == fClipType && this->rect().contains(rect)); } bool isWideOpen() const { @@ -146,6 +162,13 @@ public: (kClipStack_ClipType == fClipType && this->clipStack()->isWideOpen()); } + bool quickContains(const SkRect& rect) const { + return (kWideOpen_ClipType == fClipType) || + (kClipStack_ClipType == fClipType && this->clipStack()->quickContains(rect)) || + (kIRect_ClipType == fClipType && this->irect().contains(rect)) || + (kRect_ClipType == fClipType && this->rect().contains(rect)); + } + void getConservativeBounds(const GrSurface* surface, SkIRect* devResult, bool* isIntersectionOfRects = NULL) const { @@ -163,6 +186,7 @@ public: kClipStack_ClipType, kWideOpen_ClipType, kIRect_ClipType, + kRect_ClipType, }; ClipType clipType() const { return fClipType; } @@ -170,6 +194,7 @@ public: private: union Clip { const SkClipStack* fStack; + SkRect fRect; SkIRect fIRect; } fClip; diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h index 2433b89..6a225c2 100644 --- a/include/gpu/GrContext.h +++ b/include/gpu/GrContext.h @@ -362,20 +362,6 @@ public: GrRenderTarget* wrapBackendRenderTarget(const GrBackendRenderTargetDesc& desc); /////////////////////////////////////////////////////////////////////////// - // Clip state - /** - * Gets the current clip. - * @return the current clip. - */ - const GrClip* getClip() const { return fClip; } - - /** - * Sets the clip. - * @param clipData the clip to set. - */ - void setClip(const GrClip* clipData) { fClip = clipData; } - - /////////////////////////////////////////////////////////////////////////// // Draws /** @@ -391,7 +377,7 @@ public: /** * Draw everywhere (respecting the clip) with the paint. */ - void drawPaint(GrRenderTarget*, const GrPaint&, const SkMatrix& viewMatrix); + void drawPaint(GrRenderTarget*, const GrClip&, const GrPaint&, const SkMatrix& viewMatrix); /** * Draw the rect using a paint. @@ -406,6 +392,7 @@ public: * The rects coords are used to access the paint (through texture matrix) */ void drawRect(GrRenderTarget*, + const GrClip&, const GrPaint& paint, const SkMatrix& viewMatrix, const SkRect&, @@ -422,6 +409,7 @@ public: * to rectToDraw */ void drawNonAARectToRect(GrRenderTarget*, + const GrClip&, const GrPaint& paint, const SkMatrix& viewMatrix, const SkRect& rectToDraw, @@ -432,11 +420,12 @@ public: * Draws a non-AA rect with paint and a localMatrix */ void drawNonAARectWithLocalMatrix(GrRenderTarget* rt, + const GrClip& clip, const GrPaint& paint, const SkMatrix& viewMatrix, const SkRect& rect, const SkMatrix& localMatrix) { - this->drawNonAARectToRect(rt, paint, viewMatrix, rect, rect, &localMatrix); + this->drawNonAARectToRect(rt, clip, paint, viewMatrix, rect, rect, &localMatrix); } /** @@ -449,6 +438,7 @@ public: * the dash information (intervals, count, phase). */ void drawRRect(GrRenderTarget*, + const GrClip&, const GrPaint&, const SkMatrix& viewMatrix, const SkRRect& rrect, @@ -465,6 +455,7 @@ public: * @param inner the inner roundrect */ void drawDRRect(GrRenderTarget*, + const GrClip&, const GrPaint&, const SkMatrix& viewMatrix, const SkRRect& outer, @@ -481,6 +472,7 @@ public: * the dash information (intervals, count, phase). */ void drawPath(GrRenderTarget*, + const GrClip&, const GrPaint&, const SkMatrix& viewMatrix, const SkPath&, @@ -504,6 +496,7 @@ public: * number of indices. */ void drawVertices(GrRenderTarget*, + const GrClip&, const GrPaint& paint, const SkMatrix& viewMatrix, GrPrimitiveType primitiveType, @@ -524,6 +517,7 @@ public: * the dash information (intervals, count, phase). */ void drawOval(GrRenderTarget*, + const GrClip&, const GrPaint& paint, const SkMatrix& viewMatrix, const SkRect& oval, @@ -666,59 +660,6 @@ public: #endif /////////////////////////////////////////////////////////////////////////// - // Helpers - - class AutoClip : public ::SkNoncopyable { - public: - // This enum exists to require a caller of the constructor to acknowledge that the clip will - // initially be wide open. It also could be extended if there are other desirable initial - // clip states. - enum InitialClip { - kWideOpen_InitialClip, - }; - - AutoClip(GrContext* context, InitialClip SkDEBUGCODE(initialState)) - : fContext(context) { - SkASSERT(kWideOpen_InitialClip == initialState); - fNewClipData.setClipStack(&fNewClipStack); - - fOldClip = context->getClip(); - context->setClip(&fNewClipData); - } - - AutoClip(GrContext* context, const SkRect& newClipRect) - : fContext(context) - , fNewClipStack(newClipRect) { - fNewClipData.setClipStack(&fNewClipStack); - - fOldClip = fContext->getClip(); - fContext->setClip(&fNewClipData); - } - - ~AutoClip() { - if (fContext) { - fContext->setClip(fOldClip); - } - } - private: - GrContext* fContext; - const GrClip* fOldClip; - - SkClipStack fNewClipStack; - GrClip fNewClipData; - }; - - class AutoWideOpenIdentityDraw { - public: - AutoWideOpenIdentityDraw(GrContext* ctx) - : fAutoClip(ctx, AutoClip::kWideOpen_InitialClip) { - } - - private: - AutoClip fAutoClip; - }; - - /////////////////////////////////////////////////////////////////////////// // Functions intended for internal use only. GrGpu* getGpu() { return fGpu; } const GrGpu* getGpu() const { return fGpu; } @@ -761,7 +702,6 @@ public: private: GrGpu* fGpu; - const GrClip* fClip; GrResourceCache* fResourceCache; GrFontCache* fFontCache; @@ -802,11 +742,16 @@ private: void setupDrawBuffer(); class AutoCheckFlush; - // Sets the paint and returns the target to draw into. This function is overloaded to either - // take a GrDrawState, GrPaint, and AutoCheckFlush, or JUST an AutoCheckFlush - GrDrawTarget* prepareToDraw(GrPipelineBuilder*, GrRenderTarget* rt, const GrPaint* paint, + // Sets the paint and returns the target to draw into. + GrDrawTarget* prepareToDraw(GrPipelineBuilder*, + GrRenderTarget* rt, + const GrClip&, + const GrPaint* paint, const AutoCheckFlush*); + // A simpler version of the above which just returns the draw target. Clip is *NOT* set + GrDrawTarget* prepareToDraw(); + void internalDrawPath(GrDrawTarget*, GrPipelineBuilder*, const SkMatrix& viewMatrix, diff --git a/src/core/SkImageFilter.cpp b/src/core/SkImageFilter.cpp index 99a1d13..94b90d6 100644 --- a/src/core/SkImageFilter.cpp +++ b/src/core/SkImageFilter.cpp @@ -257,7 +257,9 @@ bool SkImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Cont return false; } - GrContext::AutoClip acs(context, dstRect); + // setup new clip + GrClip clip(dstRect); + GrFragmentProcessor* fp; offset->fX = bounds.left(); offset->fY = bounds.top(); @@ -268,7 +270,8 @@ bool SkImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Cont SkASSERT(fp); GrPaint paint; paint.addColorProcessor(fp)->unref(); - context->drawNonAARectToRect(dst->asRenderTarget(), paint, SkMatrix::I(), dstRect, srcRect); + context->drawNonAARectToRect(dst->asRenderTarget(), clip, paint, SkMatrix::I(), dstRect, + srcRect); WrapTexture(dst, bounds.width(), bounds.height(), result); return true; @@ -382,7 +385,7 @@ bool SkImageFilter::getInputResultGPU(SkImageFilter::Proxy* proxy, // matrix with no clip and that the matrix, clip, and render target set before this function was // called are restored before we return to the caller. GrContext* context = src.getTexture()->getContext(); - GrContext::AutoWideOpenIdentityDraw awoid(context); + if (this->canFilterImageGPU()) { return this->filterImageGPU(proxy, src, ctx, result, offset); } else { diff --git a/src/core/SkMaskFilter.cpp b/src/core/SkMaskFilter.cpp index 3b13186..54a22fc 100644 --- a/src/core/SkMaskFilter.cpp +++ b/src/core/SkMaskFilter.cpp @@ -318,6 +318,7 @@ bool SkMaskFilter::canFilterMaskGPU(const SkRect& devBounds, bool SkMaskFilter::directFilterMaskGPU(GrContext* context, GrRenderTarget* rt, GrPaint* grp, + const GrClip&, const SkMatrix& viewMatrix, const SkStrokeRec& strokeRec, const SkPath& path) const { @@ -328,6 +329,7 @@ bool SkMaskFilter::canFilterMaskGPU(const SkRect& devBounds, bool SkMaskFilter::directFilterRRectMaskGPU(GrContext* context, GrRenderTarget* rt, GrPaint* grp, + const GrClip&, const SkMatrix& viewMatrix, const SkStrokeRec& strokeRec, const SkRRect& rrect) const { diff --git a/src/effects/SkAlphaThresholdFilter.cpp b/src/effects/SkAlphaThresholdFilter.cpp index f78c9c0..09dc742 100644 --- a/src/effects/SkAlphaThresholdFilter.cpp +++ b/src/effects/SkAlphaThresholdFilter.cpp @@ -292,7 +292,8 @@ bool SkAlphaThresholdFilterImpl::asFragmentProcessor(GrFragmentProcessor** fp, while (!iter.done()) { SkRect rect = SkRect::Make(iter.rect()); - context->drawRect(maskTexture->asRenderTarget(), grPaint, in_matrix, rect); + context->drawRect(maskTexture->asRenderTarget(), GrClip::WideOpen(), grPaint, + in_matrix, rect); iter.next(); } } diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp index ae4f756..d7c874c 100644 --- a/src/effects/SkBlurMaskFilter.cpp +++ b/src/effects/SkBlurMaskFilter.cpp @@ -50,12 +50,14 @@ public: virtual bool directFilterMaskGPU(GrContext* context, GrRenderTarget* rt, GrPaint* grp, + const GrClip&, const SkMatrix& viewMatrix, const SkStrokeRec& strokeRec, const SkPath& path) const SK_OVERRIDE; virtual bool directFilterRRectMaskGPU(GrContext* context, GrRenderTarget* rt, GrPaint* grp, + const GrClip&, const SkMatrix& viewMatrix, const SkStrokeRec& strokeRec, const SkRRect& rrect) const SK_OVERRIDE; @@ -830,6 +832,7 @@ GrFragmentProcessor* GrRectBlurEffect::TestCreate(SkRandom* random, bool SkBlurMaskFilterImpl::directFilterMaskGPU(GrContext* context, GrRenderTarget* rt, GrPaint* grp, + const GrClip& clip, const SkMatrix& viewMatrix, const SkStrokeRec& strokeRec, const SkPath& path) const { @@ -863,7 +866,7 @@ bool SkBlurMaskFilterImpl::directFilterMaskGPU(GrContext* context, if (!viewMatrix.invert(&inverse)) { return false; } - context->drawNonAARectWithLocalMatrix(rt, *grp, SkMatrix::I(), rect, inverse); + context->drawNonAARectWithLocalMatrix(rt, clip, *grp, SkMatrix::I(), rect, inverse); return true; } @@ -1120,6 +1123,7 @@ GrGLFragmentProcessor* GrRRectBlurEffect::createGLInstance() const { bool SkBlurMaskFilterImpl::directFilterRRectMaskGPU(GrContext* context, GrRenderTarget* rt, GrPaint* grp, + const GrClip& clip, const SkMatrix& viewMatrix, const SkStrokeRec& strokeRec, const SkRRect& rrect) const { @@ -1148,7 +1152,7 @@ bool SkBlurMaskFilterImpl::directFilterRRectMaskGPU(GrContext* context, if (!viewMatrix.invert(&inverse)) { return false; } - context->drawNonAARectWithLocalMatrix(rt, *grp, SkMatrix::I(), proxy_rect, inverse); + context->drawNonAARectWithLocalMatrix(rt, clip, *grp, SkMatrix::I(), proxy_rect, inverse); return true; } @@ -1200,8 +1204,6 @@ bool SkBlurMaskFilterImpl::filterMaskGPU(GrTexture* src, GrContext* context = src->getContext(); - GrContext::AutoWideOpenIdentityDraw awo(context); - SkScalar xformedSigma = this->computeXformedSigma(ctm); SkASSERT(xformedSigma > 0); @@ -1232,7 +1234,8 @@ bool SkBlurMaskFilterImpl::filterMaskGPU(GrTexture* src, // = 0 * src + (1 - src) * dst paint.setCoverageSetOpXPFactory(SkRegion::kDifference_Op); } - context->drawRect((*result)->asRenderTarget(), paint, SkMatrix::I(), clipRect); + context->drawRect((*result)->asRenderTarget(), GrClip::WideOpen(), paint, SkMatrix::I(), + clipRect); } return true; diff --git a/src/effects/SkDisplacementMapEffect.cpp b/src/effects/SkDisplacementMapEffect.cpp index 0463fb0..25339e6 100644 --- a/src/effects/SkDisplacementMapEffect.cpp +++ b/src/effects/SkDisplacementMapEffect.cpp @@ -449,7 +449,8 @@ bool SkDisplacementMapEffect::filterImageGPU(Proxy* proxy, const SkBitmap& src, SkMatrix matrix; matrix.setTranslate(-SkIntToScalar(colorBounds.x()), -SkIntToScalar(colorBounds.y())); - context->drawRect(dst->asRenderTarget(), paint, matrix, SkRect::Make(colorBounds)); + context->drawRect(dst->asRenderTarget(), GrClip::WideOpen(), paint, matrix, + SkRect::Make(colorBounds)); offset->fX = bounds.left(); offset->fY = bounds.top(); WrapTexture(dst, bounds.width(), bounds.height(), result); diff --git a/src/effects/SkGpuBlurUtils.cpp b/src/effects/SkGpuBlurUtils.cpp index 77e2258..832e48a 100644 --- a/src/effects/SkGpuBlurUtils.cpp +++ b/src/effects/SkGpuBlurUtils.cpp @@ -45,6 +45,7 @@ static float adjust_sigma(float sigma, int maxTextureSize, int *scaleFactor, int static void convolve_gaussian_1d(GrContext* context, GrRenderTarget* rt, + const GrClip& clip, const SkRect& srcRect, const SkRect& dstRect, GrTexture* texture, @@ -57,11 +58,12 @@ static void convolve_gaussian_1d(GrContext* context, SkAutoTUnref conv(GrConvolutionEffect::CreateGaussian( texture, direction, radius, sigma, useBounds, bounds)); paint.addColorProcessor(conv); - context->drawNonAARectToRect(rt, paint, SkMatrix::I(), dstRect, srcRect); + context->drawNonAARectToRect(rt, clip, paint, SkMatrix::I(), dstRect, srcRect); } static void convolve_gaussian_2d(GrContext* context, GrRenderTarget* rt, + const GrClip& clip, const SkRect& srcRect, const SkRect& dstRect, GrTexture* texture, @@ -79,11 +81,12 @@ static void convolve_gaussian_2d(GrContext* context, useBounds ? GrTextureDomain::kClamp_Mode : GrTextureDomain::kIgnore_Mode, true, sigmaX, sigmaY)); paint.addColorProcessor(conv); - context->drawNonAARectToRect(rt, paint, SkMatrix::I(), dstRect, srcRect); + context->drawNonAARectToRect(rt, clip, paint, SkMatrix::I(), dstRect, srcRect); } static void convolve_gaussian(GrContext* context, GrRenderTarget* rt, + const GrClip& clip, const SkRect& srcRect, const SkRect& dstRect, GrTexture* texture, @@ -93,7 +96,7 @@ static void convolve_gaussian(GrContext* context, bool cropToSrcRect) { float bounds[2] = { 0.0f, 1.0f }; if (!cropToSrcRect) { - convolve_gaussian_1d(context, rt, srcRect, dstRect, texture, + convolve_gaussian_1d(context, rt, clip, srcRect, dstRect, texture, direction, radius, sigma, false, bounds); return; } @@ -125,15 +128,15 @@ static void convolve_gaussian(GrContext* context, } if (radius >= size * SK_ScalarHalf) { // Blur radius covers srcRect; use bounds over entire draw - convolve_gaussian_1d(context, rt, srcRect, dstRect, texture, + convolve_gaussian_1d(context, rt, clip, srcRect, dstRect, texture, direction, radius, sigma, true, bounds); } else { // Draw upper and lower margins with bounds; middle without. - convolve_gaussian_1d(context, rt, lowerSrcRect, lowerDstRect, texture, + convolve_gaussian_1d(context, rt, clip, lowerSrcRect, lowerDstRect, texture, direction, radius, sigma, true, bounds); - convolve_gaussian_1d(context, rt, upperSrcRect, upperDstRect, texture, + convolve_gaussian_1d(context, rt, clip, upperSrcRect, upperDstRect, texture, direction, radius, sigma, true, bounds); - convolve_gaussian_1d(context, rt, middleSrcRect, middleDstRect, texture, + convolve_gaussian_1d(context, rt, clip, middleSrcRect, middleDstRect, texture, direction, radius, sigma, false, bounds); } } @@ -160,7 +163,8 @@ GrTexture* GaussianBlur(GrContext* context, scale_rect(&srcRect, static_cast(scaleFactorX), static_cast(scaleFactorY)); - GrContext::AutoClip acs(context, SkRect::MakeWH(srcRect.width(), srcRect.height())); + // setup new clip + GrClip clip(SkRect::MakeWH(srcRect.width(), srcRect.height())); SkASSERT(kBGRA_8888_GrPixelConfig == srcTexture->config() || kRGBA_8888_GrPixelConfig == srcTexture->config() || @@ -213,8 +217,8 @@ GrTexture* GaussianBlur(GrContext* context, } scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f, i < scaleFactorY ? 0.5f : 1.0f); - context->drawNonAARectToRect(dstTexture->asRenderTarget(), paint, SkMatrix::I(), dstRect, - srcRect); + context->drawNonAARectToRect(dstTexture->asRenderTarget(), clip, paint, SkMatrix::I(), + dstRect, srcRect); srcRect = dstRect; srcTexture = dstTexture; SkTSwap(dstTexture, tempTexture); @@ -229,8 +233,8 @@ GrTexture* GaussianBlur(GrContext* context, // We shouldn't be scaling because this is a small size blur SkASSERT((scaleFactorX == scaleFactorY) == 1); SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); - convolve_gaussian_2d(context, dstTexture->asRenderTarget(), srcRect, dstRect, srcTexture, - radiusX, radiusY, sigmaX, sigmaY, cropToRect, srcIRect); + convolve_gaussian_2d(context, dstTexture->asRenderTarget(), clip, srcRect, dstRect, + srcTexture, radiusX, radiusY, sigmaX, sigmaY, cropToRect, srcIRect); srcTexture = dstTexture; srcRect = dstRect; SkTSwap(dstTexture, tempTexture); @@ -245,8 +249,9 @@ GrTexture* GaussianBlur(GrContext* context, context->clear(&clearRect, 0x0, false, srcTexture->asRenderTarget()); } SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); - convolve_gaussian(context, dstTexture->asRenderTarget(), srcRect, dstRect, srcTexture, - Gr1DKernelEffect::kX_Direction, radiusX, sigmaX, cropToRect); + convolve_gaussian(context, dstTexture->asRenderTarget(), clip, srcRect, dstRect, + srcTexture, Gr1DKernelEffect::kX_Direction, radiusX, sigmaX, + cropToRect); srcTexture = dstTexture; srcRect = dstRect; SkTSwap(dstTexture, tempTexture); @@ -262,8 +267,9 @@ GrTexture* GaussianBlur(GrContext* context, } SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); - convolve_gaussian(context, dstTexture->asRenderTarget(), srcRect, dstRect, srcTexture, - Gr1DKernelEffect::kY_Direction, radiusY, sigmaY, cropToRect); + convolve_gaussian(context, dstTexture->asRenderTarget(), clip, srcRect, + dstRect, srcTexture, Gr1DKernelEffect::kY_Direction, radiusY, sigmaY, + cropToRect); srcTexture = dstTexture; srcRect = dstRect; SkTSwap(dstTexture, tempTexture); @@ -289,8 +295,8 @@ GrTexture* GaussianBlur(GrContext* context, SkRect dstRect(srcRect); scale_rect(&dstRect, (float) scaleFactorX, (float) scaleFactorY); - context->drawNonAARectToRect(dstTexture->asRenderTarget(), paint, SkMatrix::I(), dstRect, - srcRect); + context->drawNonAARectToRect(dstTexture->asRenderTarget(), clip, paint, + SkMatrix::I(), dstRect, srcRect); srcRect = dstRect; srcTexture = dstTexture; SkTSwap(dstTexture, tempTexture); diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp index 8c46aae..d2ec036 100644 --- a/src/effects/SkMorphologyImageFilter.cpp +++ b/src/effects/SkMorphologyImageFilter.cpp @@ -563,6 +563,7 @@ namespace { void apply_morphology_rect(GrContext* context, GrRenderTarget* rt, + const GrClip& clip, GrTexture* texture, const SkIRect& srcRect, const SkIRect& dstRect, @@ -576,12 +577,13 @@ void apply_morphology_rect(GrContext* context, radius, morphType, bounds))->unref(); - context->drawNonAARectToRect(rt, paint, SkMatrix::I(), SkRect::Make(dstRect), + context->drawNonAARectToRect(rt, clip, paint, SkMatrix::I(), SkRect::Make(dstRect), SkRect::Make(srcRect)); } void apply_morphology_rect_no_bounds(GrContext* context, GrRenderTarget* rt, + const GrClip& clip, GrTexture* texture, const SkIRect& srcRect, const SkIRect& dstRect, @@ -593,12 +595,13 @@ void apply_morphology_rect_no_bounds(GrContext* context, direction, radius, morphType))->unref(); - context->drawNonAARectToRect(rt, paint, SkMatrix::I(), SkRect::Make(dstRect), + context->drawNonAARectToRect(rt, clip, paint, SkMatrix::I(), SkRect::Make(dstRect), SkRect::Make(srcRect)); } void apply_morphology_pass(GrContext* context, GrRenderTarget* rt, + const GrClip& clip, GrTexture* texture, const SkIRect& srcRect, const SkIRect& dstRect, @@ -630,16 +633,16 @@ void apply_morphology_pass(GrContext* context, } if (middleSrcRect.fLeft - middleSrcRect.fRight >= 0) { // radius covers srcRect; use bounds over entire draw - apply_morphology_rect(context, rt, texture, srcRect, dstRect, radius, + apply_morphology_rect(context, rt, clip, texture, srcRect, dstRect, radius, morphType, bounds, direction); } else { // Draw upper and lower margins with bounds; middle without. - apply_morphology_rect(context, rt,texture, lowerSrcRect, lowerDstRect, radius, + apply_morphology_rect(context, rt, clip, texture, lowerSrcRect, lowerDstRect, radius, morphType, bounds, direction); - apply_morphology_rect(context, rt, texture, upperSrcRect, upperDstRect, radius, + apply_morphology_rect(context, rt, clip, texture, upperSrcRect, upperDstRect, radius, morphType, bounds, direction); - apply_morphology_rect_no_bounds(context, rt, texture, middleSrcRect, middleDstRect, radius, - morphType, direction); + apply_morphology_rect_no_bounds(context, rt, clip, texture, middleSrcRect, middleDstRect, + radius, morphType, direction); } } @@ -652,8 +655,9 @@ bool apply_morphology(const SkBitmap& input, SkASSERT(srcTexture); GrContext* context = srcTexture->getContext(); - GrContext::AutoClip acs(context, SkRect::MakeWH(SkIntToScalar(srcTexture->width()), - SkIntToScalar(srcTexture->height()))); + // setup new clip + GrClip clip(SkRect::MakeWH(SkIntToScalar(srcTexture->width()), + SkIntToScalar(srcTexture->height()))); SkIRect dstRect = SkIRect::MakeWH(rect.width(), rect.height()); GrSurfaceDesc desc; @@ -668,8 +672,9 @@ bool apply_morphology(const SkBitmap& input, if (NULL == texture) { return false; } - apply_morphology_pass(context, texture->asRenderTarget(), srcTexture, srcRect, dstRect, - radius.fWidth, morphType, Gr1DKernelEffect::kX_Direction); + apply_morphology_pass(context, texture->asRenderTarget(), clip, srcTexture, + srcRect, dstRect, radius.fWidth, morphType, + Gr1DKernelEffect::kX_Direction); SkIRect clearRect = SkIRect::MakeXYWH(dstRect.fLeft, dstRect.fBottom, dstRect.width(), radius.fHeight); GrColor clearColor = GrMorphologyEffect::kErode_MorphologyType == morphType ? @@ -684,8 +689,9 @@ bool apply_morphology(const SkBitmap& input, if (NULL == texture) { return false; } - apply_morphology_pass(context, texture->asRenderTarget(), srcTexture, srcRect, dstRect, - radius.fHeight, morphType, Gr1DKernelEffect::kY_Direction); + apply_morphology_pass(context, texture->asRenderTarget(), clip, srcTexture, + srcRect, dstRect, radius.fHeight, morphType, + Gr1DKernelEffect::kY_Direction); srcTexture.reset(texture); } SkImageFilter::WrapTexture(srcTexture, rect.width(), rect.height(), dst); diff --git a/src/effects/SkXfermodeImageFilter.cpp b/src/effects/SkXfermodeImageFilter.cpp index ce6e790..2ba5ec5 100644 --- a/src/effects/SkXfermodeImageFilter.cpp +++ b/src/effects/SkXfermodeImageFilter.cpp @@ -172,7 +172,7 @@ bool SkXfermodeImageFilter::filterImageGPU(Proxy* proxy, GrPaint paint; paint.addColorTextureProcessor(foregroundTex, foregroundMatrix); paint.addColorProcessor(xferProcessor)->unref(); - context->drawRect(dst->asRenderTarget(), paint, SkMatrix::I(), srcRect); + context->drawRect(dst->asRenderTarget(), GrClip::WideOpen(), paint, SkMatrix::I(), srcRect); offset->fX = backgroundOffset.fX; offset->fY = backgroundOffset.fY; diff --git a/src/gpu/GrBitmapTextContext.cpp b/src/gpu/GrBitmapTextContext.cpp index 2345ac1..d06df1c 100755 --- a/src/gpu/GrBitmapTextContext.cpp +++ b/src/gpu/GrBitmapTextContext.cpp @@ -70,9 +70,9 @@ bool GrBitmapTextContext::canDraw(const SkPaint& paint, const SkMatrix& viewMatr return !SkDraw::ShouldDrawTextAsPaths(paint, viewMatrix); } -inline void GrBitmapTextContext::init(GrRenderTarget* rt, const GrPaint& paint, - const SkPaint& skPaint) { - GrTextContext::init(rt, paint, skPaint); +inline void GrBitmapTextContext::init(GrRenderTarget* rt, const GrClip& clip, + const GrPaint& paint, const SkPaint& skPaint) { + GrTextContext::init(rt, clip, paint, skPaint); fStrike = NULL; @@ -84,8 +84,8 @@ inline void GrBitmapTextContext::init(GrRenderTarget* rt, const GrPaint& paint, fTotalVertexCount = 0; } -void GrBitmapTextContext::onDrawText(GrRenderTarget* rt, const GrPaint& paint, - const SkPaint& skPaint, +void GrBitmapTextContext::onDrawText(GrRenderTarget* rt, const GrClip& clip, + const GrPaint& paint, const SkPaint& skPaint, const SkMatrix& viewMatrix, const char text[], size_t byteLength, SkScalar x, SkScalar y) { @@ -96,7 +96,7 @@ void GrBitmapTextContext::onDrawText(GrRenderTarget* rt, const GrPaint& paint, return; } - this->init(rt, paint, skPaint); + this->init(rt, clip, paint, skPaint); SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); @@ -184,8 +184,8 @@ void GrBitmapTextContext::onDrawText(GrRenderTarget* rt, const GrPaint& paint, this->finish(); } -void GrBitmapTextContext::onDrawPosText(GrRenderTarget* rt, const GrPaint& paint, - const SkPaint& skPaint, +void GrBitmapTextContext::onDrawPosText(GrRenderTarget* rt, const GrClip& clip, + const GrPaint& paint, const SkPaint& skPaint, const SkMatrix& viewMatrix, const char text[], size_t byteLength, const SkScalar pos[], int scalarsPerPosition, @@ -198,7 +198,7 @@ void GrBitmapTextContext::onDrawPosText(GrRenderTarget* rt, const GrPaint& paint return; } - this->init(rt, paint, skPaint); + this->init(rt, clip, paint, skPaint); SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); @@ -455,7 +455,7 @@ void GrBitmapTextContext::appendGlyph(GrGlyph::PackedID packed, SkPath tmpPath(*glyph->fPath); tmpPath.transform(translate); GrStrokeInfo strokeInfo(SkStrokeRec::kFill_InitStyle); - fContext->drawPath(fRenderTarget, fPaint, SkMatrix::I(), tmpPath, strokeInfo); + fContext->drawPath(fRenderTarget, fClip, fPaint, SkMatrix::I(), tmpPath, strokeInfo); // remove this glyph from the vertices we need to allocate fTotalVertexCount -= kVerticesPerGlyph; diff --git a/src/gpu/GrBitmapTextContext.h b/src/gpu/GrBitmapTextContext.h index c38bd07..2c50873 100644 --- a/src/gpu/GrBitmapTextContext.h +++ b/src/gpu/GrBitmapTextContext.h @@ -40,16 +40,16 @@ private: bool canDraw(const SkPaint& paint, const SkMatrix& viewMatrix) SK_OVERRIDE; - virtual void onDrawText(GrRenderTarget*, const GrPaint&, const SkPaint&, + virtual void onDrawText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&, const SkMatrix& viewMatrix, const char text[], size_t byteLength, SkScalar x, SkScalar y) SK_OVERRIDE; - virtual void onDrawPosText(GrRenderTarget*, const GrPaint&, const SkPaint&, + virtual void onDrawPosText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&, const SkMatrix& viewMatrix, const char text[], size_t byteLength, const SkScalar pos[], int scalarsPerPosition, const SkPoint& offset) SK_OVERRIDE; - void init(GrRenderTarget*, const GrPaint&, const SkPaint&); + void init(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&); void appendGlyph(GrGlyph::PackedID, SkFixed left, SkFixed top, GrFontScaler*); bool uploadGlyph(GrGlyph*, GrFontScaler*); void flush(); // automatically called by destructor diff --git a/src/gpu/GrClip.cpp b/src/gpu/GrClip.cpp index 1dc6edc..63d8f51 100644 --- a/src/gpu/GrClip.cpp +++ b/src/gpu/GrClip.cpp @@ -21,8 +21,6 @@ void GrClip::getConservativeBounds(int width, int height, SkIRect* devResult, bool* isIntersectionOfRects) const { switch (fClipType) { - default: - SkFAIL("incomplete switch\n"); case kWideOpen_ClipType: { devResult->setLTRB(0, 0, width, height); if (isIntersectionOfRects) { @@ -35,6 +33,15 @@ void GrClip::getConservativeBounds(int width, int height, SkIRect* devResult, *isIntersectionOfRects = true; } } break; + case kRect_ClipType: { + devResult->setLTRB(SkScalarCeilToInt(this->rect().fLeft), + SkScalarCeilToInt(this->rect().fTop), + SkScalarCeilToInt(this->rect().fRight), + SkScalarCeilToInt(this->rect().fBottom)); + if (isIntersectionOfRects) { + *isIntersectionOfRects = true; + } + } break; case kClipStack_ClipType: { SkRect devBounds; this->clipStack()->getConservativeBounds(-this->origin().fX, diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp index b28b75c..99c74e3 100644 --- a/src/gpu/GrClipMaskManager.cpp +++ b/src/gpu/GrClipMaskManager.cpp @@ -231,29 +231,47 @@ bool GrClipMaskManager::setupClipping(GrPipelineBuilder* pipelineBuilder, bool ignoreClip = clip.isWideOpen(clipSpaceRTIBounds); if (!ignoreClip) { // The clip mask manager always draws with a single IRect so we special case that logic here - if (GrClip::kIRect_ClipType == clip.clipType()) { - initialState = GrReducedClip::kAllIn_InitialState; - clipSpaceIBounds = clip.irect(); - SkNEW_INSERT_AT_LLIST_HEAD(&elements, - Element, - (SkRect::Make(clipSpaceIBounds), - SkRegion::kIntersect_Op, false)); - } else { - clipSpaceRTIBounds.offset(clip.origin()); - GrReducedClip::ReduceClipStack(*clip.clipStack(), - clipSpaceRTIBounds, - &elements, - &genID, - &initialState, - &clipSpaceIBounds, - &requiresAA); - if (elements.isEmpty()) { - if (GrReducedClip::kAllIn_InitialState == initialState) { - ignoreClip = clipSpaceIBounds == clipSpaceRTIBounds; - } else { - return false; + // Image filters just use a rect, so we also special case that logic + switch (clip.clipType()) { + case GrClip::kWideOpen_ClipType: + // we should have handled this case above + SkASSERT(false); + case GrClip::kIRect_ClipType: { + initialState = GrReducedClip::kAllIn_InitialState; + clipSpaceIBounds = clip.irect(); + SkNEW_INSERT_AT_LLIST_HEAD(&elements, + Element, + (SkRect::Make(clipSpaceIBounds), + SkRegion::kIntersect_Op, false)); + } break; + case GrClip::kRect_ClipType: { + initialState = GrReducedClip::kAllIn_InitialState; + clipSpaceIBounds.setLTRB(SkScalarCeilToInt(clip.rect().fLeft), + SkScalarCeilToInt(clip.rect().fTop), + SkScalarCeilToInt(clip.rect().fRight), + SkScalarCeilToInt(clip.rect().fBottom)); + SkNEW_INSERT_AT_LLIST_HEAD(&elements, + Element, + (SkRect::Make(clipSpaceIBounds), + SkRegion::kIntersect_Op, false)); + } break; + case GrClip::kClipStack_ClipType: { + clipSpaceRTIBounds.offset(clip.origin()); + GrReducedClip::ReduceClipStack(*clip.clipStack(), + clipSpaceRTIBounds, + &elements, + &genID, + &initialState, + &clipSpaceIBounds, + &requiresAA); + if (elements.isEmpty()) { + if (GrReducedClip::kAllIn_InitialState == initialState) { + ignoreClip = clipSpaceIBounds == clipSpaceRTIBounds; + } else { + return false; + } } - } + } break; } } diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 0395e1b..b574614 100755 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -86,7 +86,6 @@ GrContext* GrContext::Create(GrBackend backend, GrBackendContext backendContext, GrContext::GrContext(const Options& opts) : fOptions(opts) { fGpu = NULL; - fClip = NULL; fPathRendererChain = NULL; fSoftwarePathRenderer = NULL; fResourceCache = NULL; @@ -363,7 +362,7 @@ void GrContext::clear(const SkIRect* rect, AutoCheckFlush acf(this); GR_CREATE_TRACE_MARKER_CONTEXT("GrContext::clear", this); - GrDrawTarget* target = this->prepareToDraw(NULL, renderTarget, NULL, &acf); + GrDrawTarget* target = this->prepareToDraw(); if (NULL == target) { return; } @@ -371,6 +370,7 @@ void GrContext::clear(const SkIRect* rect, } void GrContext::drawPaint(GrRenderTarget* rt, + const GrClip& clip, const GrPaint& origPaint, const SkMatrix& viewMatrix) { // set rect to be big enough to fill the space, but not super-huge, so we @@ -398,7 +398,7 @@ void GrContext::drawPaint(GrRenderTarget* rt, return; } inverse.mapRect(&r); - this->drawRect(rt, *paint, viewMatrix, r); + this->drawRect(rt, clip, *paint, viewMatrix, r); } else { SkMatrix localMatrix; if (!viewMatrix.invert(&localMatrix)) { @@ -408,7 +408,7 @@ void GrContext::drawPaint(GrRenderTarget* rt, AutoCheckFlush acf(this); GrPipelineBuilder pipelineBuilder; - GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, paint, &acf); + GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, paint, &acf); if (NULL == target) { return; } @@ -502,6 +502,7 @@ static inline bool rect_contains_inclusive(const SkRect& rect, const SkPoint& po } void GrContext::drawRect(GrRenderTarget* rt, + const GrClip& clip, const GrPaint& paint, const SkMatrix& viewMatrix, const SkRect& rect, @@ -509,13 +510,13 @@ void GrContext::drawRect(GrRenderTarget* rt, if (strokeInfo && strokeInfo->isDashed()) { SkPath path; path.addRect(rect); - this->drawPath(rt, paint, viewMatrix, path, *strokeInfo); + this->drawPath(rt, clip, paint, viewMatrix, path, *strokeInfo); return; } AutoCheckFlush acf(this); GrPipelineBuilder pipelineBuilder; - GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, &paint, &acf); + GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf); if (NULL == target) { return; } @@ -529,13 +530,13 @@ void GrContext::drawRect(GrRenderTarget* rt, SkRect rtRect; pipelineBuilder.getRenderTarget()->getBoundsRect(&rtRect); SkRect clipSpaceRTRect = rtRect; - bool checkClip = fClip && GrClip::kWideOpen_ClipType != fClip->clipType(); + bool checkClip = GrClip::kWideOpen_ClipType != clip.clipType(); if (checkClip) { - clipSpaceRTRect.offset(SkIntToScalar(this->getClip()->origin().fX), - SkIntToScalar(this->getClip()->origin().fY)); + clipSpaceRTRect.offset(SkIntToScalar(clip.origin().fX), + SkIntToScalar(clip.origin().fY)); } // Does the clip contain the entire RT? - if (!checkClip || fClip->clipStack()->quickContains(clipSpaceRTRect)) { + if (!checkClip || clip.quickContains(clipSpaceRTRect)) { SkMatrix invM; if (!viewMatrix.invert(&invM)) { return; @@ -634,6 +635,7 @@ void GrContext::drawRect(GrRenderTarget* rt, } void GrContext::drawNonAARectToRect(GrRenderTarget* rt, + const GrClip& clip, const GrPaint& paint, const SkMatrix& viewMatrix, const SkRect& rectToDraw, @@ -641,7 +643,7 @@ void GrContext::drawNonAARectToRect(GrRenderTarget* rt, const SkMatrix* localMatrix) { AutoCheckFlush acf(this); GrPipelineBuilder pipelineBuilder; - GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, &paint, &acf); + GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf); if (NULL == target) { return; } @@ -681,6 +683,7 @@ static const GrGeometryProcessor* set_vertex_attributes(const SkPoint* texCoords } void GrContext::drawVertices(GrRenderTarget* rt, + const GrClip& clip, const GrPaint& paint, const SkMatrix& viewMatrix, GrPrimitiveType primitiveType, @@ -694,7 +697,7 @@ void GrContext::drawVertices(GrRenderTarget* rt, GrPipelineBuilder pipelineBuilder; GrDrawTarget::AutoReleaseGeometry geo; // must be inside AutoCheckFlush scope - GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, &paint, &acf); + GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf); if (NULL == target) { return; } @@ -743,6 +746,7 @@ void GrContext::drawVertices(GrRenderTarget* rt, /////////////////////////////////////////////////////////////////////////////// void GrContext::drawRRect(GrRenderTarget*rt, + const GrClip& clip, const GrPaint& paint, const SkMatrix& viewMatrix, const SkRRect& rrect, @@ -754,13 +758,13 @@ void GrContext::drawRRect(GrRenderTarget*rt, if (strokeInfo.isDashed()) { SkPath path; path.addRRect(rrect); - this->drawPath(rt, paint, viewMatrix, path, strokeInfo); + this->drawPath(rt, clip, paint, viewMatrix, path, strokeInfo); return; } AutoCheckFlush acf(this); GrPipelineBuilder pipelineBuilder; - GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, &paint, &acf); + GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf); if (NULL == target) { return; } @@ -787,6 +791,7 @@ void GrContext::drawRRect(GrRenderTarget*rt, /////////////////////////////////////////////////////////////////////////////// void GrContext::drawDRRect(GrRenderTarget* rt, + const GrClip& clip, const GrPaint& paint, const SkMatrix& viewMatrix, const SkRRect& outer, @@ -797,7 +802,7 @@ void GrContext::drawDRRect(GrRenderTarget* rt, AutoCheckFlush acf(this); GrPipelineBuilder pipelineBuilder; - GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, &paint, &acf); + GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf); GR_CREATE_TRACE_MARKER("GrContext::drawDRRect", target); @@ -822,7 +827,8 @@ void GrContext::drawDRRect(GrRenderTarget* rt, /////////////////////////////////////////////////////////////////////////////// -void GrContext::drawOval(GrRenderTarget*rt, +void GrContext::drawOval(GrRenderTarget* rt, + const GrClip& clip, const GrPaint& paint, const SkMatrix& viewMatrix, const SkRect& oval, @@ -834,13 +840,13 @@ void GrContext::drawOval(GrRenderTarget*rt, if (strokeInfo.isDashed()) { SkPath path; path.addOval(oval); - this->drawPath(rt, paint, viewMatrix, path, strokeInfo); + this->drawPath(rt, clip, paint, viewMatrix, path, strokeInfo); return; } AutoCheckFlush acf(this); GrPipelineBuilder pipelineBuilder; - GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, &paint, &acf); + GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf); if (NULL == target) { return; } @@ -918,6 +924,7 @@ static bool is_nested_rects(GrDrawTarget* target, } void GrContext::drawPath(GrRenderTarget* rt, + const GrClip& clip, const GrPaint& paint, const SkMatrix& viewMatrix, const SkPath& path, @@ -925,7 +932,7 @@ void GrContext::drawPath(GrRenderTarget* rt, if (path.isEmpty()) { if (path.isInverseFillType()) { - this->drawPaint(rt, paint, viewMatrix); + this->drawPaint(rt, clip, paint, viewMatrix); } return; } @@ -936,7 +943,7 @@ void GrContext::drawPath(GrRenderTarget* rt, if (path.isLine(pts)) { AutoCheckFlush acf(this); GrPipelineBuilder pipelineBuilder; - GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, &paint, &acf); + GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf); if (NULL == target) { return; } @@ -953,11 +960,11 @@ void GrContext::drawPath(GrRenderTarget* rt, GrStrokeInfo newStrokeInfo(strokeInfo, false); SkStrokeRec* stroke = newStrokeInfo.getStrokeRecPtr(); if (SkDashPath::FilterDashPath(effectPath.init(), path, stroke, NULL, info)) { - this->drawPath(rt, paint, viewMatrix, *effectPath.get(), newStrokeInfo); + this->drawPath(rt, clip, paint, viewMatrix, *effectPath.get(), newStrokeInfo); return; } - this->drawPath(rt, paint, viewMatrix, path, newStrokeInfo); + this->drawPath(rt, clip, paint, viewMatrix, path, newStrokeInfo); return; } @@ -968,7 +975,7 @@ void GrContext::drawPath(GrRenderTarget* rt, // OK. AutoCheckFlush acf(this); GrPipelineBuilder pipelineBuilder; - GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, &paint, &acf); + GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf); if (NULL == target) { return; } @@ -1197,7 +1204,10 @@ bool GrContext::writeSurfacePixels(GrSurface* surface, // drawing a rect to the render target. // The bracket ensures we pop the stack if we wind up flushing below. { - GrDrawTarget* drawTarget = this->prepareToDraw(NULL, NULL, NULL, NULL); + GrDrawTarget* drawTarget = this->prepareToDraw(); + if (!drawTarget) { + return false; + } GrDrawTarget::AutoGeometryPush agp(drawTarget); GrPipelineBuilder pipelineBuilder; @@ -1383,7 +1393,7 @@ void GrContext::discardRenderTarget(GrRenderTarget* renderTarget) { SkASSERT(renderTarget); ASSERT_OWNED_RESOURCE(renderTarget); AutoCheckFlush acf(this); - GrDrawTarget* target = this->prepareToDraw(NULL, NULL, NULL, NULL); + GrDrawTarget* target = this->prepareToDraw(); if (NULL == target) { return; } @@ -1401,7 +1411,7 @@ void GrContext::copySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRe // Since we're going to the draw target and not GPU, no need to check kNoFlush // here. - GrDrawTarget* target = this->prepareToDraw(NULL, NULL, NULL, NULL); + GrDrawTarget* target = this->prepareToDraw(); if (NULL == target) { return; } @@ -1420,16 +1430,22 @@ void GrContext::flushSurfaceWrites(GrSurface* surface) { GrDrawTarget* GrContext::prepareToDraw(GrPipelineBuilder* pipelineBuilder, GrRenderTarget* rt, + const GrClip& clip, const GrPaint* paint, const AutoCheckFlush* acf) { if (NULL == fGpu) { return NULL; } - if (pipelineBuilder) { - ASSERT_OWNED_RESOURCE(rt); - SkASSERT(rt && paint && acf); - pipelineBuilder->setFromPaint(*paint, rt, fClip); + ASSERT_OWNED_RESOURCE(rt); + SkASSERT(rt && paint && acf); + pipelineBuilder->setFromPaint(*paint, rt, clip); + return fDrawBuffer; +} + +GrDrawTarget* GrContext::prepareToDraw() { + if (NULL == fGpu) { + return NULL; } return fDrawBuffer; } @@ -1513,7 +1529,7 @@ void GrContext::setupDrawBuffer() { } GrDrawTarget* GrContext::getTextTarget() { - return this->prepareToDraw(NULL, NULL, NULL, NULL); + return this->prepareToDraw(); } const GrIndexBuffer* GrContext::getQuadIndexBuffer() const { diff --git a/src/gpu/GrDistanceFieldTextContext.cpp b/src/gpu/GrDistanceFieldTextContext.cpp index d2b34e6..47d408f 100755 --- a/src/gpu/GrDistanceFieldTextContext.cpp +++ b/src/gpu/GrDistanceFieldTextContext.cpp @@ -112,9 +112,9 @@ bool GrDistanceFieldTextContext::canDraw(const SkPaint& paint, const SkMatrix& v return true; } -inline void GrDistanceFieldTextContext::init(GrRenderTarget* rt, const GrPaint& paint, - const SkPaint& skPaint) { - GrTextContext::init(rt, paint, skPaint); +inline void GrDistanceFieldTextContext::init(GrRenderTarget* rt, const GrClip& clip, + const GrPaint& paint, const SkPaint& skPaint) { + GrTextContext::init(rt, clip, paint, skPaint); fStrike = NULL; @@ -207,7 +207,8 @@ static void setup_gamma_texture(GrContext* context, const SkGlyphCache* cache, } } -void GrDistanceFieldTextContext::onDrawText(GrRenderTarget* rt, const GrPaint& paint, +void GrDistanceFieldTextContext::onDrawText(GrRenderTarget* rt, const GrClip& clip, + const GrPaint& paint, const SkPaint& skPaint, const SkMatrix& viewMatrix, const char text[], size_t byteLength, SkScalar x, SkScalar y) { @@ -268,11 +269,12 @@ void GrDistanceFieldTextContext::onDrawText(GrRenderTarget* rt, const GrPaint& p y -= alignY; SkPoint offset = SkPoint::Make(x, y); - this->drawPosText(rt, paint, skPaint, viewMatrix, text, byteLength, positions.begin(), 2, + this->drawPosText(rt, clip, paint, skPaint, viewMatrix, text, byteLength, positions.begin(), 2, offset); } -void GrDistanceFieldTextContext::onDrawPosText(GrRenderTarget* rt, const GrPaint& paint, +void GrDistanceFieldTextContext::onDrawPosText(GrRenderTarget* rt, const GrClip& clip, + const GrPaint& paint, const SkPaint& skPaint, const SkMatrix& viewMatrix, const char text[], size_t byteLength, const SkScalar pos[], int scalarsPerPosition, @@ -287,7 +289,7 @@ void GrDistanceFieldTextContext::onDrawPosText(GrRenderTarget* rt, const GrPaint } fViewMatrix = viewMatrix; - this->init(rt, paint, skPaint); + this->init(rt, clip, paint, skPaint); SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); @@ -362,7 +364,7 @@ void GrDistanceFieldTextContext::onDrawPosText(GrRenderTarget* rt, const GrPaint this->finish(); if (fallbackTxt.count() > 0) { - fFallbackTextContext->drawPosText(rt, paint, skPaint, viewMatrix, fallbackTxt.begin(), + fFallbackTextContext->drawPosText(rt, clip, paint, skPaint, viewMatrix, fallbackTxt.begin(), fallbackTxt.count(), fallbackPos.begin(), scalarsPerPosition, offset); } @@ -571,7 +573,7 @@ bool GrDistanceFieldTextContext::appendGlyph(GrGlyph::PackedID packed, tmpPath.transform(ctm); GrStrokeInfo strokeInfo(SkStrokeRec::kFill_InitStyle); - fContext->drawPath(fRenderTarget, fPaint, fViewMatrix, tmpPath, strokeInfo); + fContext->drawPath(fRenderTarget, fClip, fPaint, fViewMatrix, tmpPath, strokeInfo); // remove this glyph from the vertices we need to allocate fTotalVertexCount -= kVerticesPerGlyph; diff --git a/src/gpu/GrDistanceFieldTextContext.h b/src/gpu/GrDistanceFieldTextContext.h index ecba340..129c6e9 100644 --- a/src/gpu/GrDistanceFieldTextContext.h +++ b/src/gpu/GrDistanceFieldTextContext.h @@ -52,17 +52,17 @@ private: bool canDraw(const SkPaint& paint, const SkMatrix& viewMatrix) SK_OVERRIDE; - virtual void onDrawText(GrRenderTarget*, const GrPaint&, const SkPaint&, + virtual void onDrawText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&, const SkMatrix& viewMatrix, const char text[], size_t byteLength, SkScalar x, SkScalar y) SK_OVERRIDE; - virtual void onDrawPosText(GrRenderTarget*, const GrPaint&, const SkPaint&, + virtual void onDrawPosText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&, const SkMatrix& viewMatrix, const char text[], size_t byteLength, const SkScalar pos[], int scalarsPerPosition, const SkPoint& offset) SK_OVERRIDE; - void init(GrRenderTarget*, const GrPaint&, const SkPaint&); + void init(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&); bool appendGlyph(GrGlyph::PackedID, SkScalar left, SkScalar top, GrFontScaler*); bool uploadGlyph(GrGlyph*, GrFontScaler*); void setupCoverageEffect(const SkColor& filteredColor); diff --git a/src/gpu/GrPipelineBuilder.cpp b/src/gpu/GrPipelineBuilder.cpp index faa20b1..89bf15f 100644 --- a/src/gpu/GrPipelineBuilder.cpp +++ b/src/gpu/GrPipelineBuilder.cpp @@ -47,7 +47,7 @@ GrPipelineBuilder& GrPipelineBuilder::operator=(const GrPipelineBuilder& that) { return *this; } -void GrPipelineBuilder::setFromPaint(const GrPaint& paint, GrRenderTarget* rt, const GrClip* clip) { +void GrPipelineBuilder::setFromPaint(const GrPaint& paint, GrRenderTarget* rt, const GrClip& clip) { SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numFragmentStages()); fColorStages.reset(); @@ -70,9 +70,7 @@ void GrPipelineBuilder::setFromPaint(const GrPaint& paint, GrRenderTarget* rt, c fStencilSettings.setDisabled(); fFlagBits = 0; - if (clip) { - fClip = *clip; - } + fClip = clip; this->setState(GrPipelineBuilder::kDither_StateBit, paint.isDither()); this->setState(GrPipelineBuilder::kHWAntialias_StateBit, paint.isAntiAlias()); diff --git a/src/gpu/GrPipelineBuilder.h b/src/gpu/GrPipelineBuilder.h index 54b06db..96807d5 100644 --- a/src/gpu/GrPipelineBuilder.h +++ b/src/gpu/GrPipelineBuilder.h @@ -45,7 +45,7 @@ public: * no GrPaint equivalents are set to default values with the exception of vertex attribute state * which is unmodified by this function and clipping which will be enabled. */ - void setFromPaint(const GrPaint&, GrRenderTarget*, const GrClip*); + void setFromPaint(const GrPaint&, GrRenderTarget*, const GrClip&); /// @} diff --git a/src/gpu/GrStencilAndCoverTextContext.cpp b/src/gpu/GrStencilAndCoverTextContext.cpp index 6dbfe9f..4b121da 100644 --- a/src/gpu/GrStencilAndCoverTextContext.cpp +++ b/src/gpu/GrStencilAndCoverTextContext.cpp @@ -65,6 +65,7 @@ bool GrStencilAndCoverTextContext::canDraw(const SkPaint& paint, const SkMatrix& } void GrStencilAndCoverTextContext::onDrawText(GrRenderTarget* rt, + const GrClip& clip, const GrPaint& paint, const SkPaint& skPaint, const SkMatrix& viewMatrix, @@ -92,7 +93,7 @@ void GrStencilAndCoverTextContext::onDrawText(GrRenderTarget* rt, // will turn off the use of device-space glyphs when perspective transforms // are in use. - this->init(rt, paint, skPaint, byteLength, kMaxAccuracy_RenderMode, viewMatrix); + this->init(rt, clip, paint, skPaint, byteLength, kMaxAccuracy_RenderMode, viewMatrix); // Transform our starting point. if (fUsingDeviceSpaceGlyphs) { @@ -155,6 +156,7 @@ void GrStencilAndCoverTextContext::onDrawText(GrRenderTarget* rt, } void GrStencilAndCoverTextContext::onDrawPosText(GrRenderTarget* rt, + const GrClip& clip, const GrPaint& paint, const SkPaint& skPaint, const SkMatrix& viewMatrix, @@ -179,7 +181,7 @@ void GrStencilAndCoverTextContext::onDrawPosText(GrRenderTarget* rt, // transform is not part of SkPaint::measureText API, and thus we use the // same glyphs as what were measured. - this->init(rt, paint, skPaint, byteLength, kMaxPerformance_RenderMode, viewMatrix); + this->init(rt, clip, paint, skPaint, byteLength, kMaxPerformance_RenderMode, viewMatrix); SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); @@ -232,12 +234,13 @@ static GrPathRange* get_gr_glyphs(GrContext* ctx, } void GrStencilAndCoverTextContext::init(GrRenderTarget* rt, + const GrClip& clip, const GrPaint& paint, const SkPaint& skPaint, size_t textByteLength, RenderMode renderMode, const SkMatrix& viewMatrix) { - GrTextContext::init(rt, paint, skPaint); + GrTextContext::init(rt, clip, paint, skPaint); fContextInitialMatrix = viewMatrix; fViewMatrix = viewMatrix; @@ -442,7 +445,7 @@ void GrStencilAndCoverTextContext::flush() { inverse.mapPoints(&fGlyphPositions[fFallbackGlyphsIdx], fallbackGlyphCount); } - fFallbackTextContext->drawPosText(fRenderTarget, paintFallback, skPaintFallback, + fFallbackTextContext->drawPosText(fRenderTarget, fClip, paintFallback, skPaintFallback, fViewMatrix, (char*)&fGlyphIndices[fFallbackGlyphsIdx], 2 * fallbackGlyphCount, get_xy_scalar_array(&fGlyphPositions[fFallbackGlyphsIdx]), diff --git a/src/gpu/GrStencilAndCoverTextContext.h b/src/gpu/GrStencilAndCoverTextContext.h index 3b4cd9b..3753795 100644 --- a/src/gpu/GrStencilAndCoverTextContext.h +++ b/src/gpu/GrStencilAndCoverTextContext.h @@ -71,18 +71,18 @@ private: bool canDraw(const SkPaint& paint, const SkMatrix& viewMatrix) SK_OVERRIDE; - virtual void onDrawText(GrRenderTarget*, const GrPaint&, const SkPaint&, + virtual void onDrawText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&, const SkMatrix& viewMatrix, const char text[], size_t byteLength, SkScalar x, SkScalar y) SK_OVERRIDE; - virtual void onDrawPosText(GrRenderTarget*, const GrPaint&, const SkPaint&, + virtual void onDrawPosText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&, const SkMatrix& viewMatrix, const char text[], size_t byteLength, const SkScalar pos[], int scalarsPerPosition, const SkPoint& offset) SK_OVERRIDE; - void init(GrRenderTarget*, const GrPaint&, const SkPaint&, size_t textByteLength, RenderMode, - const SkMatrix& viewMatrix); + void init(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&, + size_t textByteLength, RenderMode, const SkMatrix& viewMatrix); bool mapToFallbackContext(SkMatrix* inverse); void appendGlyph(const SkGlyph&, const SkPoint&); void flush(); diff --git a/src/gpu/GrTextContext.cpp b/src/gpu/GrTextContext.cpp index 895e977..cef99c6 100644 --- a/src/gpu/GrTextContext.cpp +++ b/src/gpu/GrTextContext.cpp @@ -7,10 +7,11 @@ #include "GrTextContext.h" #include "GrContext.h" +#include "GrDrawTarget.h" +#include "GrFontScaler.h" #include "SkAutoKern.h" #include "SkGlyphCache.h" -#include "GrFontScaler.h" GrTextContext::GrTextContext(GrContext* context, const SkDeviceProperties& properties) : fFallbackTextContext(NULL), @@ -21,12 +22,13 @@ GrTextContext::~GrTextContext() { SkDELETE(fFallbackTextContext); } -void GrTextContext::init(GrRenderTarget* rt, const GrPaint& grPaint, const SkPaint& skPaint) { - fClip = fContext->getClip(); +void GrTextContext::init(GrRenderTarget* rt, const GrClip& clip, const GrPaint& grPaint, + const SkPaint& skPaint) { + fClip = clip; fRenderTarget.reset(SkRef(rt)); - fClip->getConservativeBounds(fRenderTarget->width(), fRenderTarget->height(), &fClipRect); + fClip.getConservativeBounds(fRenderTarget->width(), fRenderTarget->height(), &fClipRect); fDrawTarget = fContext->getTextTarget(); @@ -34,15 +36,15 @@ void GrTextContext::init(GrRenderTarget* rt, const GrPaint& grPaint, const SkPai fSkPaint = skPaint; } -bool GrTextContext::drawText(GrRenderTarget* rt, const GrPaint& paint, const SkPaint& skPaint, - const SkMatrix& viewMatrix, +bool GrTextContext::drawText(GrRenderTarget* rt, const GrClip& clip, const GrPaint& paint, + const SkPaint& skPaint, const SkMatrix& viewMatrix, const char text[], size_t byteLength, SkScalar x, SkScalar y) { GrTextContext* textContext = this; do { if (textContext->canDraw(skPaint, viewMatrix)) { - textContext->onDrawText(rt, paint, skPaint, viewMatrix, text, byteLength, x, y); + textContext->onDrawText(rt, clip, paint, skPaint, viewMatrix, text, byteLength, x, y); return true; } textContext = textContext->fFallbackTextContext; @@ -51,8 +53,8 @@ bool GrTextContext::drawText(GrRenderTarget* rt, const GrPaint& paint, const SkP return false; } -bool GrTextContext::drawPosText(GrRenderTarget* rt, const GrPaint& paint, const SkPaint& skPaint, - const SkMatrix& viewMatrix, +bool GrTextContext::drawPosText(GrRenderTarget* rt, const GrClip& clip, const GrPaint& paint, + const SkPaint& skPaint, const SkMatrix& viewMatrix, const char text[], size_t byteLength, const SkScalar pos[], int scalarsPerPosition, const SkPoint& offset) { @@ -60,7 +62,7 @@ bool GrTextContext::drawPosText(GrRenderTarget* rt, const GrPaint& paint, const GrTextContext* textContext = this; do { if (textContext->canDraw(skPaint, viewMatrix)) { - textContext->onDrawPosText(rt, paint, skPaint, viewMatrix, text, byteLength, pos, + textContext->onDrawPosText(rt, clip, paint, skPaint, viewMatrix, text, byteLength, pos, scalarsPerPosition, offset); return true; } diff --git a/src/gpu/GrTextContext.h b/src/gpu/GrTextContext.h index 581ff64..d333c63 100644 --- a/src/gpu/GrTextContext.h +++ b/src/gpu/GrTextContext.h @@ -15,6 +15,7 @@ #include "SkPostConfig.h" +class GrClip; class GrContext; class GrDrawTarget; class GrFontScaler; @@ -26,9 +27,11 @@ class GrTextContext { public: virtual ~GrTextContext(); - bool drawText(GrRenderTarget* rt, const GrPaint&, const SkPaint&, const SkMatrix& viewMatrix, - const char text[], size_t byteLength, SkScalar x, SkScalar y); - bool drawPosText(GrRenderTarget* rt, const GrPaint&, const SkPaint&, const SkMatrix& viewMatrix, + bool drawText(GrRenderTarget* rt, const GrClip&, const GrPaint&, const SkPaint&, + const SkMatrix& viewMatrix, const char text[], size_t byteLength, SkScalar x, + SkScalar y); + bool drawPosText(GrRenderTarget* rt, const GrClip&, const GrPaint&, const SkPaint&, + const SkMatrix& viewMatrix, const char text[], size_t byteLength, const SkScalar pos[], int scalarsPerPosition, const SkPoint& offset); @@ -39,7 +42,7 @@ protected: SkDeviceProperties fDeviceProperties; SkAutoTUnref fRenderTarget; - const GrClip* fClip; + GrClip fClip; GrDrawTarget* fDrawTarget; SkIRect fClipRect; GrPaint fPaint; @@ -49,16 +52,16 @@ protected: virtual bool canDraw(const SkPaint& paint, const SkMatrix& viewMatrix) = 0; - virtual void onDrawText(GrRenderTarget*, const GrPaint&, const SkPaint&, + virtual void onDrawText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&, const SkMatrix& viewMatrix, const char text[], size_t byteLength, SkScalar x, SkScalar y) = 0; - virtual void onDrawPosText(GrRenderTarget*, const GrPaint&, const SkPaint&, + virtual void onDrawPosText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&, const SkMatrix& viewMatrix, const char text[], size_t byteLength, const SkScalar pos[], int scalarsPerPosition, const SkPoint& offset) = 0; - void init(GrRenderTarget*, const GrPaint&, const SkPaint&); + void init(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&); void finish() { fDrawTarget = NULL; } static GrFontScaler* GetGrFontScaler(SkGlyphCache* cache); diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index d384cd1..edbb82e 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -220,10 +220,6 @@ SkGpuDevice::~SkGpuDevice() { delete fTextContext; - if (fContext->getClip() == &fClipData) { - fContext->setClip(NULL); - } - fRenderTarget->unref(); fContext->unref(); } @@ -281,7 +277,7 @@ void SkGpuDevice::onAttachToCanvas(SkCanvas* canvas) { void SkGpuDevice::onDetachFromCanvas() { INHERITED::onDetachFromCanvas(); - fClipData.reset(); + fClip.reset(); fClipStack.reset(NULL); } @@ -292,9 +288,7 @@ void SkGpuDevice::prepareDraw(const SkDraw& draw) { SkASSERT(draw.fClipStack && draw.fClipStack == fClipStack); - fClipData.setClipStack(fClipStack, &this->getOrigin()); - - fContext->setClip(&fClipData); + fClip.setClipStack(fClipStack, &this->getOrigin()); DO_DEFERRED_CLEAR(); } @@ -366,7 +360,7 @@ void SkGpuDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) { GrPaint grPaint; SkPaint2GrPaintShader(this->context(), fRenderTarget, paint, *draw.fMatrix, true, &grPaint); - fContext->drawPaint(fRenderTarget, grPaint, *draw.fMatrix); + fContext->drawPaint(fRenderTarget, fClip, grPaint, *draw.fMatrix); } // must be in SkCanvas::PointMode order @@ -394,7 +388,7 @@ void SkGpuDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, path.setIsVolatile(true); path.moveTo(pts[0]); path.lineTo(pts[1]); - fContext->drawPath(fRenderTarget, grPaint, *draw.fMatrix, path, strokeInfo); + fContext->drawPath(fRenderTarget, fClip, grPaint, *draw.fMatrix, path, strokeInfo); return; } @@ -409,6 +403,7 @@ void SkGpuDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, SkPaint2GrPaintShader(this->context(), fRenderTarget, paint, *draw.fMatrix, true, &grPaint); fContext->drawVertices(fRenderTarget, + fClip, grPaint, *draw.fMatrix, gPointMode2PrimtiveType[mode], @@ -479,7 +474,7 @@ void SkGpuDevice::drawRect(const SkDraw& draw, const SkRect& rect, GrPaint grPaint; SkPaint2GrPaintShader(this->context(), fRenderTarget, paint, *draw.fMatrix, true, &grPaint); - fContext->drawRect(fRenderTarget, grPaint, *draw.fMatrix, rect, &strokeInfo); + fContext->drawRect(fRenderTarget, fClip, grPaint, *draw.fMatrix, rect, &strokeInfo); } /////////////////////////////////////////////////////////////////////////////// @@ -514,6 +509,7 @@ void SkGpuDevice::drawRRect(const SkDraw& draw, const SkRRect& rect, if (paint.getMaskFilter()->directFilterRRectMaskGPU(fContext, fRenderTarget, &grPaint, + fClip, *draw.fMatrix, strokeInfo.getStrokeRec(), devRRect)) { @@ -546,7 +542,7 @@ void SkGpuDevice::drawRRect(const SkDraw& draw, const SkRRect& rect, return; } - fContext->drawRRect(fRenderTarget, grPaint, *draw.fMatrix, rect, strokeInfo); + fContext->drawRRect(fRenderTarget, fClip, grPaint, *draw.fMatrix, rect, strokeInfo); } void SkGpuDevice::drawDRRect(const SkDraw& draw, const SkRRect& outer, @@ -561,7 +557,7 @@ void SkGpuDevice::drawDRRect(const SkDraw& draw, const SkRRect& outer, SkPaint2GrPaintShader(this->context(), fRenderTarget, paint, *draw.fMatrix, true, &grPaint); if (NULL == paint.getMaskFilter() && NULL == paint.getPathEffect()) { - fContext->drawDRRect(fRenderTarget, grPaint, *draw.fMatrix, outer, inner); + fContext->drawDRRect(fRenderTarget, fClip, grPaint, *draw.fMatrix, outer, inner); return; } } @@ -608,7 +604,7 @@ void SkGpuDevice::drawOval(const SkDraw& draw, const SkRect& oval, GrPaint grPaint; SkPaint2GrPaintShader(this->context(), fRenderTarget, paint, *draw.fMatrix, true, &grPaint); - fContext->drawOval(fRenderTarget, grPaint, *draw.fMatrix, oval, strokeInfo); + fContext->drawOval(fRenderTarget, fClip, grPaint, *draw.fMatrix, oval, strokeInfo); } #include "SkMaskFilter.h" @@ -623,6 +619,7 @@ namespace { // Return true if the mask was successfully drawn. bool draw_mask(GrContext* context, GrRenderTarget* rt, + const GrClip& clip, const SkMatrix& viewMatrix, const SkRect& maskRect, GrPaint* grp, @@ -638,12 +635,13 @@ bool draw_mask(GrContext* context, if (!viewMatrix.invert(&inverse)) { return false; } - context->drawNonAARectWithLocalMatrix(rt, *grp, SkMatrix::I(), maskRect, inverse); + context->drawNonAARectWithLocalMatrix(rt, clip, *grp, SkMatrix::I(), maskRect, inverse); return true; } bool draw_with_mask_filter(GrContext* context, GrRenderTarget* rt, + const GrClip& clipData, const SkMatrix& viewMatrix, const SkPath& devPath, SkMaskFilter* filter, @@ -685,7 +683,7 @@ bool draw_with_mask_filter(GrContext* context, SkRect maskRect = SkRect::Make(dstM.fBounds); - return draw_mask(context, rt, viewMatrix, maskRect, grp, texture); + return draw_mask(context, rt, clipData, viewMatrix, maskRect, grp, texture); } // Create a mask of 'devPath' and place the result in 'mask'. @@ -717,18 +715,19 @@ GrTexture* create_mask_GPU(GrContext* context, SkRect clipRect = SkRect::MakeWH(maskRect.width(), maskRect.height()); - GrContext::AutoClip ac(context, clipRect); - context->clear(NULL, 0x0, true, mask->asRenderTarget()); GrPaint tempPaint; tempPaint.setAntiAlias(doAA); tempPaint.setCoverageSetOpXPFactory(SkRegion::kReplace_Op); + // setup new clip + GrClip clip(clipRect); + // Draw the mask into maskTexture with the path's top-left at the origin using tempPaint. SkMatrix translate; translate.setTranslate(-maskRect.fLeft, -maskRect.fTop); - context->drawPath(mask->asRenderTarget(), tempPaint, translate, devPath, strokeInfo); + context->drawPath(mask->asRenderTarget(), clip, tempPaint, translate, devPath, strokeInfo); return mask; } @@ -833,6 +832,7 @@ void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath, if (paint.getMaskFilter()->directFilterMaskGPU(fContext, fRenderTarget, &grPaint, + fClip, viewMatrix, stroke, *devPathPtr)) { @@ -855,7 +855,12 @@ void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath, if (paint.getMaskFilter()->filterMaskGPU(mask, viewMatrix, maskRect, &filtered, true)) { // filterMaskGPU gives us ownership of a ref to the result SkAutoTUnref atu(filtered); - if (draw_mask(fContext, fRenderTarget, viewMatrix, maskRect, &grPaint, + if (draw_mask(fContext, + fRenderTarget, + fClip, + viewMatrix, + maskRect, + &grPaint, filtered)) { // This path is completely drawn return; @@ -868,12 +873,12 @@ void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath, // GPU path fails SkPaint::Style style = stroke.isHairlineStyle() ? SkPaint::kStroke_Style : SkPaint::kFill_Style; - draw_with_mask_filter(fContext, fRenderTarget, viewMatrix, *devPathPtr, + draw_with_mask_filter(fContext, fRenderTarget, fClip, viewMatrix, *devPathPtr, paint.getMaskFilter(), *draw.fClip, &grPaint, style); return; } - fContext->drawPath(fRenderTarget, grPaint, viewMatrix, *pathPtr, strokeInfo); + fContext->drawPath(fRenderTarget, fClip, grPaint, viewMatrix, *pathPtr, strokeInfo); } static const int kBmpSmallTileSize = 1 << 10; @@ -906,12 +911,12 @@ static int determine_tile_size(const SkBitmap& bitmap, const SkIRect& src, int m // pixels from the bitmap are necessary. static void determine_clipped_src_rect(const GrContext* context, const GrRenderTarget* rt, + const GrClip& clip, const SkMatrix& viewMatrix, const SkBitmap& bitmap, const SkRect* srcRectPtr, SkIRect* clippedSrcIRect) { - const GrClip* clip = context->getClip(); - clip->getConservativeBounds(rt, clippedSrcIRect, NULL); + clip.getConservativeBounds(rt, clippedSrcIRect, NULL); SkMatrix inv; if (!viewMatrix.invert(&inv)) { clippedSrcIRect->setEmpty(); @@ -948,8 +953,8 @@ bool SkGpuDevice::shouldTileBitmap(const SkBitmap& bitmap, // if it's larger than the max tile size, then we have no choice but tiling. if (bitmap.width() > maxTileSize || bitmap.height() > maxTileSize) { - determine_clipped_src_rect(fContext, fRenderTarget, viewMatrix, bitmap, srcRectPtr, - clippedSrcRect); + determine_clipped_src_rect(fContext, fRenderTarget, fClip, viewMatrix, bitmap, + srcRectPtr, clippedSrcRect); *tileSize = determine_tile_size(bitmap, *clippedSrcRect, maxTileSize); return true; } @@ -978,7 +983,7 @@ bool SkGpuDevice::shouldTileBitmap(const SkBitmap& bitmap, } // Figure out how much of the src we will need based on the src rect and clipping. - determine_clipped_src_rect(fContext, fRenderTarget, viewMatrix, bitmap, srcRectPtr, + determine_clipped_src_rect(fContext, fRenderTarget, fClip, viewMatrix, bitmap, srcRectPtr, clippedSrcRect); *tileSize = kBmpSmallTileSize; // already know whole bitmap fits in one max sized tile. size_t usedTileBytes = get_tile_count(*clippedSrcRect, kBmpSmallTileSize) * @@ -1452,7 +1457,8 @@ void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap, SkColor2GrColor(paint.getColor()); SkPaint2GrPaintNoShader(this->context(), fRenderTarget, paint, paintColor, false, &grPaint); - fContext->drawNonAARectToRect(fRenderTarget, grPaint, viewMatrix, dstRect, paintRect); + fContext->drawNonAARectToRect(fRenderTarget, fClip, grPaint, viewMatrix, dstRect, + paintRect); } bool SkGpuDevice::filterTexture(GrContext* context, GrTexture* texture, @@ -1466,8 +1472,6 @@ bool SkGpuDevice::filterTexture(GrContext* context, GrTexture* texture, SkDeviceImageFilterProxy proxy(this, SkSurfaceProps(0, getLeakyProperties().pixelGeometry())); if (filter->canFilterImageGPU()) { - // Set the clip wide open and the matrix to identity. - GrContext::AutoWideOpenIdentityDraw awo(context); return filter->filterImageGPU(&proxy, wrap_texture(texture), ctx, result, offset); } else { return false; @@ -1523,6 +1527,7 @@ void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap, SkColor2GrColorJustAlpha(paint.getColor()), false, &grPaint); fContext->drawNonAARectToRect(fRenderTarget, + fClip, grPaint, SkMatrix::I(), SkRect::MakeXYWH(SkIntToScalar(left), @@ -1645,7 +1650,8 @@ void SkGpuDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device, SkRect srcRect = SkRect::MakeWH(SK_Scalar1 * w / devTex->width(), SK_Scalar1 * h / devTex->height()); - fContext->drawNonAARectToRect(fRenderTarget, grPaint, SkMatrix::I(), dstRect, srcRect); + fContext->drawNonAARectToRect(fRenderTarget, fClip, grPaint, SkMatrix::I(), dstRect, + srcRect); } bool SkGpuDevice::canHandleImageFilter(const SkImageFilter* filter) { @@ -1779,6 +1785,7 @@ void SkGpuDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode, colors = convertedColors.get(); } fContext->drawVertices(fRenderTarget, + fClip, grPaint, *draw.fMatrix, primType, @@ -1803,8 +1810,8 @@ void SkGpuDevice::drawText(const SkDraw& draw, const void* text, SkDEBUGCODE(this->validate();) - if (!fTextContext->drawText(fRenderTarget, grPaint, paint, *draw.fMatrix, (const char *)text, - byteLength, x, y)) { + if (!fTextContext->drawText(fRenderTarget, fClip, grPaint, paint, *draw.fMatrix, + (const char *)text, byteLength, x, y)) { // this will just call our drawPath() draw.drawText_asPaths((const char*)text, byteLength, x, y, paint); } @@ -1821,8 +1828,8 @@ void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text, size_t byteL SkDEBUGCODE(this->validate();) - if (!fTextContext->drawPosText(fRenderTarget, grPaint, paint, *draw.fMatrix, (const char *)text, - byteLength, pos, scalarsPerPos, offset)) { + if (!fTextContext->drawPosText(fRenderTarget, fClip, grPaint, paint, *draw.fMatrix, + (const char *)text, byteLength, pos, scalarsPerPos, offset)) { // this will just call our drawPath() draw.drawPosText_asPaths((const char*)text, byteLength, pos, scalarsPerPos, offset, paint); } diff --git a/src/gpu/SkGpuDevice.h b/src/gpu/SkGpuDevice.h index a6cc4ef..8dafcfc 100644 --- a/src/gpu/SkGpuDevice.h +++ b/src/gpu/SkGpuDevice.h @@ -137,7 +137,7 @@ private: GrSkDrawProcs* fDrawProcs; SkAutoTUnref fClipStack; SkIPoint fClipOrigin; - GrClip fClipData; + GrClip fClip; GrTextContext* fTextContext; SkSurfaceProps fSurfaceProps; GrRenderTarget* fRenderTarget; diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp index d069fe0..b0814af 100644 --- a/src/gpu/SkGr.cpp +++ b/src/gpu/SkGr.cpp @@ -243,9 +243,8 @@ GrTexture* stretch_texture_to_next_pot(GrTexture* inputTexture, Stretch stretch, SkRect rect = SkRect::MakeWH(SkIntToScalar(rtDesc.fWidth), SkIntToScalar(rtDesc.fHeight)); SkRect localRect = SkRect::MakeWH(1.f, 1.f); - GrContext::AutoClip ac(context, GrContext::AutoClip::kWideOpen_InitialClip); - context->drawNonAARectToRect(stretched->asRenderTarget(), paint, SkMatrix::I(), rect, - localRect); + context->drawNonAARectToRect(stretched->asRenderTarget(), GrClip::WideOpen(), paint, + SkMatrix::I(), rect, localRect); return stretched; } @@ -392,8 +391,8 @@ static GrTexture* load_yuv_texture(GrContext* ctx, const GrUniqueKey& optionalKe paint.addColorProcessor(yuvToRgbProcessor); SkRect r = SkRect::MakeWH(SkIntToScalar(yuvInfo.fSize[0].fWidth), SkIntToScalar(yuvInfo.fSize[0].fHeight)); - GrContext::AutoClip ac(ctx, GrContext::AutoClip::kWideOpen_InitialClip); - ctx->drawRect(renderTarget, paint, SkMatrix::I(), r); + + ctx->drawRect(renderTarget, GrClip::WideOpen(), paint, SkMatrix::I(), r); return result; } @@ -706,8 +705,6 @@ void SkPaint2GrPaintShader(GrContext* context, GrRenderTarget* rt, const SkPaint // asFragmentProcessor(). Since these calls get passed back to the client, we don't really // want them messing around with the context. { - GrContext::AutoClip ac(context, GrContext::AutoClip::kWideOpen_InitialClip); - // Allow the shader to modify paintColor and also create an effect to be installed as // the first color effect on the GrPaint. GrFragmentProcessor* fp = NULL; diff --git a/src/gpu/effects/GrConfigConversionEffect.cpp b/src/gpu/effects/GrConfigConversionEffect.cpp index 46dde19..fedc470 100644 --- a/src/gpu/effects/GrConfigConversionEffect.cpp +++ b/src/gpu/effects/GrConfigConversionEffect.cpp @@ -205,8 +205,6 @@ void GrConfigConversionEffect::TestForPreservingPMConversions(GrContext* context {kDivByAlpha_RoundUp_PMConversion, kMulByAlpha_RoundDown_PMConversion}, }; - GrContext::AutoWideOpenIdentityDraw awoid(context); - bool failed = true; for (size_t i = 0; i < SK_ARRAY_COUNT(kConversionRules) && failed; ++i) { @@ -231,19 +229,31 @@ void GrConfigConversionEffect::TestForPreservingPMConversions(GrContext* context GrPaint paint1; paint1.addColorProcessor(pmToUPM1); - context->drawNonAARectToRect(readTex->asRenderTarget(), paint1, SkMatrix::I(), kDstRect, + context->drawNonAARectToRect(readTex->asRenderTarget(), + GrClip::WideOpen(), + paint1, + SkMatrix::I(), + kDstRect, kSrcRect); readTex->readPixels(0, 0, 256, 256, kRGBA_8888_GrPixelConfig, firstRead); GrPaint paint2; paint2.addColorProcessor(upmToPM); - context->drawNonAARectToRect(tempTex->asRenderTarget(), paint2, SkMatrix::I(), kDstRect, + context->drawNonAARectToRect(tempTex->asRenderTarget(), + GrClip::WideOpen(), + paint2, + SkMatrix::I(), + kDstRect, kSrcRect); GrPaint paint3; paint3.addColorProcessor(pmToUPM2); - context->drawNonAARectToRect(readTex->asRenderTarget(), paint3, SkMatrix::I(), kDstRect, + context->drawNonAARectToRect(readTex->asRenderTarget(), + GrClip::WideOpen(), + paint3, + SkMatrix::I(), + kDstRect, kSrcRect); readTex->readPixels(0, 0, 256, 256, kRGBA_8888_GrPixelConfig, secondRead); diff --git a/tests/ClipCacheTest.cpp b/tests/ClipCacheTest.cpp index 0e5fe1e..3d3fa95 100644 --- a/tests/ClipCacheTest.cpp +++ b/tests/ClipCacheTest.cpp @@ -84,17 +84,17 @@ static void test_clip_bounds(skiatest::Reporter* reporter, GrContext* context) { REPORTER_ASSERT(reporter, screen == devStackBounds); REPORTER_ASSERT(reporter, isIntersectionOfRects); - // wrap the SkClipStack in a GrClipData + // wrap the SkClipStack in a GrClip GrClip clipData; clipData.setClipStack(&stack); - SkIRect devGrClipDataBound; + SkIRect devGrClipBound; clipData.getConservativeBounds(texture, - &devGrClipDataBound, + &devGrClipBound, &isIntersectionOfRects); - // make sure that GrClipData is behaving itself - REPORTER_ASSERT(reporter, intScreen == devGrClipDataBound); + // make sure that GrClip is behaving itself + REPORTER_ASSERT(reporter, intScreen == devGrClipBound); REPORTER_ASSERT(reporter, isIntersectionOfRects); } diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp index d96c56c..897e261 100644 --- a/tests/GLProgramsTest.cpp +++ b/tests/GLProgramsTest.cpp @@ -247,7 +247,7 @@ bool GrDrawTarget::programUnitTest(int maxStages) { SkClipStack stack; stack.clipDevRect(screen, SkRegion::kReplace_Op, false); - // wrap the SkClipStack in a GrClipData + // wrap the SkClipStack in a GrClip GrClip clip; clip.setClipStack(&stack); -- 2.7.4