Make Gr clear take a rect for a partial-clear
Review URL: http://codereview.appspot.com/4442093/
git-svn-id: http://skia.googlecode.com/svn/trunk@1203 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/include/GrContext.h b/gpu/include/GrContext.h
index 3112112..214fc05 100644
--- a/gpu/include/GrContext.h
+++ b/gpu/include/GrContext.h
@@ -282,9 +282,11 @@
// Draws
/**
- * Clear the entire render target, ignoring any clips
+ * 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.
*/
- void clear(GrColor color);
+ void clear(const GrIRect* rect, GrColor color);
/**
* Draw everywhere (respecting the clip) with the paint.
diff --git a/gpu/include/GrDrawTarget.h b/gpu/include/GrDrawTarget.h
index cb36d3c..c971e71 100644
--- a/gpu/include/GrDrawTarget.h
+++ b/gpu/include/GrDrawTarget.h
@@ -731,10 +731,11 @@
}
/**
- * Clear the entire render target. Ignores the clip an all other draw state
- * (blend mode, stages, etc).
+ * Clear the render target. Ignores the clip and all other draw state
+ * (blend mode, stages, etc). Clears the whole thing if rect is NULL,
+ * otherwise just the rect.
*/
- virtual void clear(GrColor color) = 0;
+ virtual void clear(const GrIRect* rect, GrColor color) = 0;
///////////////////////////////////////////////////////////////////////////
diff --git a/gpu/include/GrGpu.h b/gpu/include/GrGpu.h
index 19f3746..590712b 100644
--- a/gpu/include/GrGpu.h
+++ b/gpu/include/GrGpu.h
@@ -263,7 +263,7 @@
virtual void drawNonIndexed(GrPrimitiveType type,
int startVertex,
int vertexCount);
- virtual void clear(GrColor color);
+ virtual void clear(const GrIRect* rect, GrColor color);
/**
* Installs a path renderer that will be used to draw paths that are
@@ -444,8 +444,9 @@
virtual GrIndexBuffer* onCreateIndexBuffer(uint32_t size,
bool dynamic) = 0;
- // overridden by API-specific derivated class to perform the clear.
- virtual void onClear(GrColor color) = 0;
+ // overridden by API-specific derivated class to perform the clear and
+ // clearRect. NULL rect means clear whole target.
+ virtual void onClear(const GrIRect* rect, GrColor color) = 0;
// overridden by API-specific derived class to perform the draw call.
virtual void onDrawIndexed(GrPrimitiveType type,
diff --git a/gpu/include/GrInOrderDrawBuffer.h b/gpu/include/GrInOrderDrawBuffer.h
index 03a2f2d..b26cd72 100644
--- a/gpu/include/GrInOrderDrawBuffer.h
+++ b/gpu/include/GrInOrderDrawBuffer.h
@@ -100,7 +100,7 @@
int* vertexCount,
int* indexCount) const;
- virtual void clear(GrColor color);
+ virtual void clear(const GrIRect* rect, GrColor color);
private:
@@ -119,6 +119,7 @@
struct Clear {
int fBeforeDrawIdx;
+ GrIRect fRect;
GrColor fColor;
};
diff --git a/gpu/include/GrRect.h b/gpu/include/GrRect.h
index a9ff6ec..b85574a 100644
--- a/gpu/include/GrRect.h
+++ b/gpu/include/GrRect.h
@@ -76,19 +76,22 @@
/**
* Sets this rect to the intersection with a clip rect. If there is no
- * intersection then this rect will be made empty.
+ * intersection then this rect will be made empty and the function will
+ * return false.
*/
- void intersectWith(const GrIRect& clipRect) {
+ bool intersectWith(const GrIRect& clipRect) {
if (fRight < clipRect.fLeft ||
fLeft > clipRect.fRight ||
fBottom < clipRect.fTop ||
fTop > clipRect.fBottom) {
this->setEmpty();
+ return false;
} else {
fLeft = GrMax(fLeft, clipRect.fLeft);
fRight = GrMin(fRight, clipRect.fRight);
fTop = GrMax(fTop, clipRect.fTop);
fBottom = GrMin(fBottom, clipRect.fBottom);
+ return true;
}
}
diff --git a/gpu/src/GrContext.cpp b/gpu/src/GrContext.cpp
index 0584e4b..d3904e0 100644
--- a/gpu/src/GrContext.cpp
+++ b/gpu/src/GrContext.cpp
@@ -391,11 +391,9 @@
////////////////////////////////////////////////////////////////////////////////
-void GrContext::clear(GrColor color) {
- // gpu flush call is immediate, must flush.
- // (could in theory skip draws to current render target.)
+void GrContext::clear(const GrIRect* rect, const GrColor color) {
this->flush();
- fGpu->clear(color);
+ fGpu->clear(rect, color);
}
void GrContext::drawPaint(const GrPaint& paint) {
@@ -462,7 +460,7 @@
// clip gets applied in second pass
target->disableState(GrDrawTarget::kClip_StateBit);
- target->clear(0x0);
+ target->clear(NULL, 0x0);
return true;
}
diff --git a/gpu/src/GrGpu.cpp b/gpu/src/GrGpu.cpp
index c05a04a..cb78204 100644
--- a/gpu/src/GrGpu.cpp
+++ b/gpu/src/GrGpu.cpp
@@ -173,9 +173,9 @@
return this->onCreateIndexBuffer(size, dynamic);
}
-void GrGpu::clear(GrColor color) {
+void GrGpu::clear(const GrIRect* rect, GrColor color) {
this->handleDirtyContext();
- this->onClear(color);
+ this->onClear(rect, color);
}
void GrGpu::forceRenderTargetFlush() {
diff --git a/gpu/src/GrGpuGL.cpp b/gpu/src/GrGpuGL.cpp
index 4bdf10e..352ad3f 100644
--- a/gpu/src/GrGpuGL.cpp
+++ b/gpu/src/GrGpuGL.cpp
@@ -1166,15 +1166,25 @@
}
}
-void GrGpuGL::onClear(GrColor color) {
+void GrGpuGL::onClear(const GrIRect* rect, GrColor color) {
if (NULL == fCurrDrawState.fRenderTarget) {
return;
}
- flushRenderTarget();
- if (fHWBounds.fScissorEnabled) {
- GR_GL(Disable(GR_GL_SCISSOR_TEST));
- fHWBounds.fScissorEnabled = false;
+ GrIRect r;
+ if (NULL != rect) {
+ // flushScissor expects rect to be clipped to the target.
+ r = *rect;
+ GrIRect rtRect(0, 0,
+ fCurrDrawState.fRenderTarget->width(),
+ fCurrDrawState.fRenderTarget->height());
+ if (r.intersectWith(rtRect)) {
+ rect = &r;
+ } else {
+ return;
+ }
}
+ this->flushRenderTarget();
+ this->flushScissor(rect);
GR_GL(ColorMask(GR_GL_TRUE,GR_GL_TRUE,GR_GL_TRUE,GR_GL_TRUE));
fHWDrawState.fFlagBits &= ~kNoColorWrites_StateBit;
GR_GL(ClearColor(GrColorUnpackR(color)/255.f,
diff --git a/gpu/src/GrGpuGL.h b/gpu/src/GrGpuGL.h
index 918ab80..bfa7351 100644
--- a/gpu/src/GrGpuGL.h
+++ b/gpu/src/GrGpuGL.h
@@ -27,10 +27,11 @@
class GrGpuGL : public GrGpu {
public:
- GrGpuGL();
virtual ~GrGpuGL();
protected:
+ GrGpuGL();
+
struct {
size_t fVertexOffset;
GrVertexLayout fVertexLayout;
@@ -87,7 +88,7 @@
int width, int height);
virtual GrRenderTarget* onCreateRenderTargetFrom3DApiState();
- virtual void onClear(GrColor color);
+ virtual void onClear(const GrIRect* rect, GrColor color);
virtual void onForceRenderTargetFlush();
@@ -140,6 +141,7 @@
static bool BlendCoefReferencesConstant(GrBlendCoeff coeff);
private:
+
// notify callbacks to update state tracking when related
// objects are bound to GL or deleted outside of the class
void notifyVertexBufferBind(const GrGLVertexBuffer* buffer);
diff --git a/gpu/src/GrInOrderDrawBuffer.cpp b/gpu/src/GrInOrderDrawBuffer.cpp
index 7b769fe..2ea12e1 100644
--- a/gpu/src/GrInOrderDrawBuffer.cpp
+++ b/gpu/src/GrInOrderDrawBuffer.cpp
@@ -150,7 +150,12 @@
GrAssert(0 == lastDraw.fIndexCount % 6);
GrAssert(0 == lastDraw.fStartIndex);
- appendToPreviousDraw = lastDraw.fVertexBuffer == fCurrPoolVertexBuffer &&
+ bool clearSinceLastDraw =
+ fClears.count() &&
+ fClears.back().fBeforeDrawIdx == fDraws.count();
+
+ appendToPreviousDraw = !clearSinceLastDraw &&
+ lastDraw.fVertexBuffer == fCurrPoolVertexBuffer &&
(fCurrQuad * 4 + lastDraw.fStartVertex) == fCurrPoolStartVertex;
if (appendToPreviousDraw) {
lastDraw.fVertexCount += 4;
@@ -288,14 +293,21 @@
draw.fIndexBuffer = NULL;
}
-void GrInOrderDrawBuffer::clear(GrColor color) {
+void GrInOrderDrawBuffer::clear(const GrIRect* rect, GrColor color) {
+ GrIRect r;
+ if (NULL == rect) {
+ // We could do something smart and remove previous draws and clears to
+ // the current render target. If we get that smart we have to make sure
+ // those draws aren't read before this clear (render-to-texture).
+ r.setLTRB(0, 0,
+ this->getRenderTarget()->width(),
+ this->getRenderTarget()->height());
+ rect = &r;
+ }
Clear& clr = fClears.push_back();
clr.fColor = color;
clr.fBeforeDrawIdx = fDraws.count();
-
- // We could do something smart and remove previous draws and clears to the
- // current render target. If we get that smart we have to make sure those
- // draws aren't read before this clear (render-to-texture).
+ clr.fRect = *rect;
}
void GrInOrderDrawBuffer::reset() {
@@ -354,7 +366,7 @@
for (int i = 0; i < numDraws; ++i) {
while (currClear < fClears.count() &&
i == fClears[currClear].fBeforeDrawIdx) {
- target->clear(fClears[currClear].fColor);
+ target->clear(&fClears[currClear].fRect, fClears[currClear].fColor);
++currClear;
}
@@ -388,7 +400,7 @@
}
while (currClear < fClears.count()) {
GrAssert(fDraws.count() == fClears[currClear].fBeforeDrawIdx);
- target->clear(fClears[currClear].fColor);
+ target->clear(&fClears[currClear].fRect, fClears[currClear].fColor);
++currClear;
}
}