diff options
author | robertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-10-31 21:44:25 +0000 |
---|---|---|
committer | robertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-10-31 21:44:25 +0000 |
commit | 56ce48ade325f6f49acb0da31d6252806e4ed7ef (patch) | |
tree | e804f1b07497ae7bc57e6b52bf27100364cca1f0 | |
parent | fc7ceefd1a6d90e659960336ecea8742f4d4d146 (diff) |
Add can-ignore-rect hint to clear call
https://codereview.chromium.org/53823003/
git-svn-id: http://skia.googlecode.com/svn/trunk@12064 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | include/gpu/GrContext.h | 4 | ||||
-rw-r--r-- | src/effects/SkBitmapAlphaThresholdShader.cpp | 2 | ||||
-rw-r--r-- | src/effects/SkGpuBlurUtils.cpp | 8 | ||||
-rw-r--r-- | src/effects/SkMorphologyImageFilter.cpp | 2 | ||||
-rw-r--r-- | src/gpu/GrClipMaskManager.cpp | 2 | ||||
-rw-r--r-- | src/gpu/GrContext.cpp | 6 | ||||
-rw-r--r-- | src/gpu/GrDrawTarget.h | 4 | ||||
-rw-r--r-- | src/gpu/GrGpu.cpp | 3 | ||||
-rw-r--r-- | src/gpu/GrGpu.h | 6 | ||||
-rw-r--r-- | src/gpu/GrInOrderDrawBuffer.cpp | 5 | ||||
-rw-r--r-- | src/gpu/GrInOrderDrawBuffer.h | 2 | ||||
-rw-r--r-- | src/gpu/SkGpuDevice.cpp | 4 | ||||
-rw-r--r-- | src/gpu/gl/GrGLCaps.cpp | 7 | ||||
-rw-r--r-- | src/gpu/gl/GrGLCaps.h | 3 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL.cpp | 6 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL.h | 2 |
16 files changed, 48 insertions, 18 deletions
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h index 2b306c0158..f0aba38ccb 100644 --- a/include/gpu/GrContext.h +++ b/include/gpu/GrContext.h @@ -379,10 +379,12 @@ public: * Clear the entire or rect of the render target, ignoring any clips. * @param rect the rect to clear or the whole thing if rect is NULL. * @param color the color to clear to. + * @param canIgnoreRect allows partial clears to be converted to whole + * clears on platforms for which that is cheap * @param target if non-NULL, the render target to clear otherwise clear * the current render target */ - void clear(const SkIRect* rect, GrColor color, + void clear(const SkIRect* rect, GrColor color, bool canIgnoreRect, GrRenderTarget* target = NULL); /** diff --git a/src/effects/SkBitmapAlphaThresholdShader.cpp b/src/effects/SkBitmapAlphaThresholdShader.cpp index 226b3173e1..05d7ba30d3 100644 --- a/src/effects/SkBitmapAlphaThresholdShader.cpp +++ b/src/effects/SkBitmapAlphaThresholdShader.cpp @@ -241,7 +241,7 @@ GrEffectRef* BATShader::asNewEffect(GrContext* context, const SkPaint& paint) co grPaint.setBlendFunc(kOne_GrBlendCoeff, kZero_GrBlendCoeff); SkRegion::Iterator iter(fRegion); context->setRenderTarget(maskTexture->asRenderTarget()); - context->clear(NULL, 0x0); + context->clear(NULL, 0x0, true); // offset to ensure border is zero on top/left SkMatrix matrix; diff --git a/src/effects/SkGpuBlurUtils.cpp b/src/effects/SkGpuBlurUtils.cpp index fce5b6bc30..6188c49540 100644 --- a/src/effects/SkGpuBlurUtils.cpp +++ b/src/effects/SkGpuBlurUtils.cpp @@ -197,7 +197,7 @@ GrTexture* GaussianBlur(GrContext* context, // X convolution from reading garbage. clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop, radiusX, srcIRect.height()); - context->clear(&clearRect, 0x0); + context->clear(&clearRect, 0x0, false); } context->setRenderTarget(dstTexture->asRenderTarget()); SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); @@ -214,7 +214,7 @@ GrTexture* GaussianBlur(GrContext* context, // convolution from reading garbage. clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, srcIRect.width(), radiusY); - context->clear(&clearRect, 0x0); + context->clear(&clearRect, 0x0, false); } context->setRenderTarget(dstTexture->asRenderTarget()); @@ -231,10 +231,10 @@ GrTexture* GaussianBlur(GrContext* context, // upsampling. clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, srcIRect.width() + 1, 1); - context->clear(&clearRect, 0x0); + context->clear(&clearRect, 0x0, false); clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop, 1, srcIRect.height()); - context->clear(&clearRect, 0x0); + context->clear(&clearRect, 0x0, false); SkMatrix matrix; matrix.setIDiv(srcTexture->width(), srcTexture->height()); context->setRenderTarget(dstTexture->asRenderTarget()); diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp index 152ec560bd..9665dcb162 100644 --- a/src/effects/SkMorphologyImageFilter.cpp +++ b/src/effects/SkMorphologyImageFilter.cpp @@ -538,7 +538,7 @@ bool apply_morphology(const SkBitmap& input, dstRect.width(), radius.fHeight); context->clear(&clearRect, GrMorphologyEffect::kErode_MorphologyType == morphType ? SK_ColorWHITE : - SK_ColorTRANSPARENT); + SK_ColorTRANSPARENT, false); src.reset(ast.detach()); srcRect = dstRect; } diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp index e2597dfad8..0f915666fb 100644 --- a/src/gpu/GrClipMaskManager.cpp +++ b/src/gpu/GrClipMaskManager.cpp @@ -461,6 +461,7 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t clipStackGenID, // clear the part that we care about. fGpu->clear(&maskSpaceIBounds, kAllIn_InitialState == initialState ? 0xffffffff : 0x00000000, + true, result->asRenderTarget()); // When we use the stencil in the below loop it is important to have this clip installed. @@ -505,6 +506,7 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t clipStackGenID, // clear the temp target and set blend to replace fGpu->clear(&maskSpaceElementIBounds, invert ? 0xffffffff : 0x00000000, + true, dst->asRenderTarget()); setup_boolean_blendcoeffs(drawState, SkRegion::kReplace_Op); diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 967738ac34..cf3b86af53 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -645,10 +645,12 @@ bool GrContext::supportsIndex8PixelConfig(const GrTextureParams* params, void GrContext::clear(const SkIRect* rect, const GrColor color, + bool canIgnoreRect, GrRenderTarget* target) { AutoRestoreEffects are; AutoCheckFlush acf(this); - this->prepareToDraw(NULL, BUFFERED_DRAW, &are, &acf)->clear(rect, color, target); + this->prepareToDraw(NULL, BUFFERED_DRAW, &are, &acf)->clear(rect, color, + canIgnoreRect, target); } void GrContext::drawPaint(const GrPaint& origPaint) { @@ -833,7 +835,7 @@ void GrContext::drawRect(const GrPaint& paint, // Will it blend? GrColor clearColor; if (paint.isOpaqueAndConstantColor(&clearColor)) { - target->clear(NULL, clearColor); + target->clear(NULL, clearColor, true); return; } } diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h index 6a1cc02133..266dc0712b 100644 --- a/src/gpu/GrDrawTarget.h +++ b/src/gpu/GrDrawTarget.h @@ -405,10 +405,12 @@ public: /** * Clear the current render target if one isn't passed in. Ignores the * clip and all other draw state (blend mode, stages, etc). Clears the - * whole thing if rect is NULL, otherwise just the rect. + * whole thing if rect is NULL, otherwise just the rect. If canIgnoreRect + * is set then the entire render target can be optionally cleared. */ virtual void clear(const SkIRect* rect, GrColor color, + bool canIgnoreRect, GrRenderTarget* renderTarget = NULL) = 0; /** diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp index cd217f4dc2..af7037a7c2 100644 --- a/src/gpu/GrGpu.cpp +++ b/src/gpu/GrGpu.cpp @@ -205,6 +205,7 @@ GrPath* GrGpu::createPath(const SkPath& path, const SkStrokeRec& stroke) { void GrGpu::clear(const SkIRect* rect, GrColor color, + bool canIgnoreRect, GrRenderTarget* renderTarget) { GrDrawState::AutoRenderTargetRestore art; if (NULL != renderTarget) { @@ -215,7 +216,7 @@ void GrGpu::clear(const SkIRect* rect, return; } this->handleDirtyContext(); - this->onClear(rect, color); + this->onClear(rect, color, canIgnoreRect); } void GrGpu::forceRenderTargetFlush() { diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h index c0a4b8f2dc..f9028b95fb 100644 --- a/src/gpu/GrGpu.h +++ b/src/gpu/GrGpu.h @@ -265,6 +265,7 @@ public: // GrDrawTarget overrides virtual void clear(const SkIRect* rect, GrColor color, + bool canIgnoreRect, GrRenderTarget* renderTarget = NULL) SK_OVERRIDE; virtual void purgeResources() SK_OVERRIDE { @@ -426,8 +427,9 @@ private: virtual GrPath* onCreatePath(const SkPath& path, const SkStrokeRec&) = 0; // overridden by backend-specific derived class to perform the clear and - // clearRect. NULL rect means clear whole target. - virtual void onClear(const SkIRect* rect, GrColor color) = 0; + // clearRect. NULL rect means clear whole target. If canIgnoreRect is + // true, it is okay to perform a full clear instead of a partial clear + virtual void onClear(const SkIRect* rect, GrColor color, bool canIgnoreRect) = 0; // overridden by backend-specific derived class to perform the draw call. virtual void onGpuDraw(const DrawInfo&) = 0; diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp index a299512538..ccbfe59b98 100644 --- a/src/gpu/GrInOrderDrawBuffer.cpp +++ b/src/gpu/GrInOrderDrawBuffer.cpp @@ -419,7 +419,8 @@ void GrInOrderDrawBuffer::onDrawPath(const GrPath* path, } } -void GrInOrderDrawBuffer::clear(const SkIRect* rect, GrColor color, GrRenderTarget* renderTarget) { +void GrInOrderDrawBuffer::clear(const SkIRect* rect, GrColor color, + bool canIgnoreRect, GrRenderTarget* renderTarget) { SkIRect r; if (NULL == renderTarget) { renderTarget = this->drawState()->getRenderTarget(); @@ -435,6 +436,7 @@ void GrInOrderDrawBuffer::clear(const SkIRect* rect, GrColor color, GrRenderTarg Clear* clr = this->recordClear(); clr->fColor = color; clr->fRect = *rect; + clr->fCanIgnoreRect = canIgnoreRect; clr->fRenderTarget = renderTarget; renderTarget->ref(); } @@ -540,6 +542,7 @@ void GrInOrderDrawBuffer::flush() { case kClear_Cmd: fDstGpu->clear(&fClears[currClear].fRect, fClears[currClear].fColor, + fClears[currClear].fCanIgnoreRect, fClears[currClear].fRenderTarget); ++currClear; break; diff --git a/src/gpu/GrInOrderDrawBuffer.h b/src/gpu/GrInOrderDrawBuffer.h index 275d7e06fa..6b680b2d55 100644 --- a/src/gpu/GrInOrderDrawBuffer.h +++ b/src/gpu/GrInOrderDrawBuffer.h @@ -71,6 +71,7 @@ public: int* indexCount) const SK_OVERRIDE; virtual void clear(const SkIRect* rect, GrColor color, + bool canIgnoreRect, GrRenderTarget* renderTarget = NULL) SK_OVERRIDE; virtual void initCopySurfaceDstDesc(const GrSurface* src, GrTextureDesc* desc) SK_OVERRIDE; @@ -117,6 +118,7 @@ private: SkIRect fRect; GrColor fColor; + bool fCanIgnoreRect; GrRenderTarget* fRenderTarget; }; diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index f47a91bf50..4041c411fc 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -548,7 +548,7 @@ SkBitmap::Config SkGpuDevice::config() const { void SkGpuDevice::clear(SkColor color) { SkIRect rect = SkIRect::MakeWH(this->width(), this->height()); - fContext->clear(&rect, SkColor2GrColor(color), fRenderTarget); + fContext->clear(&rect, SkColor2GrColor(color), true, fRenderTarget); fNeedClear = false; } @@ -822,7 +822,7 @@ bool create_mask_GPU(GrContext* context, GrContext::AutoRenderTarget art(context, maskTexture->asRenderTarget()); GrContext::AutoClip ac(context, clipRect); - context->clear(NULL, 0x0); + context->clear(NULL, 0x0, true); GrPaint tempPaint; if (doAA) { diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp index 8e6c3e2d23..60c0dfaf10 100644 --- a/src/gpu/gl/GrGLCaps.cpp +++ b/src/gpu/gl/GrGLCaps.cpp @@ -48,6 +48,7 @@ void GrGLCaps::reset() { fIsCoreProfile = false; fFixedFunctionSupport = false; fDiscardFBSupport = false; + fFullClearIsFree = false; } GrGLCaps::GrGLCaps(const GrGLCaps& caps) : GrDrawTargetCaps() { @@ -84,6 +85,7 @@ GrGLCaps& GrGLCaps::operator = (const GrGLCaps& caps) { fIsCoreProfile = caps.fIsCoreProfile; fFixedFunctionSupport = caps.fFixedFunctionSupport; fDiscardFBSupport = caps.fDiscardFBSupport; + fFullClearIsFree = caps.fFullClearIsFree; return *this; } @@ -224,6 +226,10 @@ void GrGLCaps::init(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) { fDiscardFBSupport = ctxInfo.hasExtension("GL_EXT_discard_framebuffer"); + if (kARM_GrGLVendor == ctxInfo.vendor() || kImagination_GrGLVendor == ctxInfo.vendor()) { + fFullClearIsFree = true; + } + if (kDesktop_GrGLBinding == binding) { fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_vertex_array_object"); @@ -648,4 +654,5 @@ void GrGLCaps::print() const { GrPrintf("Use non-VBO for dynamic data: %s\n", (fUseNonVBOVertexAndIndexDynamicData ? "YES" : "NO")); GrPrintf("Discard FrameBuffer support: %s\n", (fDiscardFBSupport ? "YES" : "NO")); + GrPrintf("Full screen clear is free: %s\n", (fFullClearIsFree ? "YES" : "NO")); } diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h index 81391ecc6b..c126a76774 100644 --- a/src/gpu/gl/GrGLCaps.h +++ b/src/gpu/gl/GrGLCaps.h @@ -248,6 +248,8 @@ public: /// Is there support for discarding the frame buffer bool discardFBSupport() const { return fDiscardFBSupport; } + bool fullClearIsFree() const { return fFullClearIsFree; } + private: /** * Maintains a bit per GrPixelConfig. It is used to avoid redundantly @@ -329,6 +331,7 @@ private: bool fIsCoreProfile : 1; bool fFixedFunctionSupport : 1; bool fDiscardFBSupport : 1; + bool fFullClearIsFree : 1; typedef GrDrawTargetCaps INHERITED; }; diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp index adbfc35bef..92e496c3ee 100644 --- a/src/gpu/gl/GrGpuGL.cpp +++ b/src/gpu/gl/GrGpuGL.cpp @@ -1255,12 +1255,16 @@ void GrGpuGL::flushScissor() { } } -void GrGpuGL::onClear(const SkIRect* rect, GrColor color) { +void GrGpuGL::onClear(const SkIRect* rect, GrColor color, bool canIgnoreRect) { const GrDrawState& drawState = this->getDrawState(); const GrRenderTarget* rt = drawState.getRenderTarget(); // parent class should never let us get here with no RT SkASSERT(NULL != rt); + if (canIgnoreRect && this->glCaps().fullClearIsFree()) { + rect = NULL; + } + SkIRect clippedRect; if (NULL != rect) { // flushScissor expects rect to be clipped to the target. diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h index 677e48cb0f..7c97080e5f 100644 --- a/src/gpu/gl/GrGpuGL.h +++ b/src/gpu/gl/GrGpuGL.h @@ -135,7 +135,7 @@ private: GrStencilBuffer* sb, GrRenderTarget* rt) SK_OVERRIDE; - virtual void onClear(const SkIRect* rect, GrColor color) SK_OVERRIDE; + virtual void onClear(const SkIRect* rect, GrColor color, bool canIgnoreRect) SK_OVERRIDE; virtual void onForceRenderTargetFlush() SK_OVERRIDE; |