aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar robertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-10-31 21:44:25 +0000
committerGravatar robertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-10-31 21:44:25 +0000
commit56ce48ade325f6f49acb0da31d6252806e4ed7ef (patch)
treee804f1b07497ae7bc57e6b52bf27100364cca1f0
parentfc7ceefd1a6d90e659960336ecea8742f4d4d146 (diff)
Add can-ignore-rect hint to clear call
-rw-r--r--include/gpu/GrContext.h4
-rw-r--r--src/effects/SkBitmapAlphaThresholdShader.cpp2
-rw-r--r--src/effects/SkGpuBlurUtils.cpp8
-rw-r--r--src/effects/SkMorphologyImageFilter.cpp2
-rw-r--r--src/gpu/GrClipMaskManager.cpp2
-rw-r--r--src/gpu/GrContext.cpp6
-rw-r--r--src/gpu/GrDrawTarget.h4
-rw-r--r--src/gpu/GrGpu.cpp3
-rw-r--r--src/gpu/GrGpu.h6
-rw-r--r--src/gpu/GrInOrderDrawBuffer.cpp5
-rw-r--r--src/gpu/GrInOrderDrawBuffer.h2
-rw-r--r--src/gpu/SkGpuDevice.cpp4
-rw-r--r--src/gpu/gl/GrGLCaps.cpp7
-rw-r--r--src/gpu/gl/GrGLCaps.h3
-rw-r--r--src/gpu/gl/GrGpuGL.cpp6
-rw-r--r--src/gpu/gl/GrGpuGL.h2
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;