Batch consecutive draw rects.
Review URL: http://codereview.appspot.com/4178057/
git-svn-id: http://skia.googlecode.com/svn/trunk@800 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/include/GrAllocPool.h b/gpu/include/GrAllocPool.h
index 46359e5..251c0b4 100644
--- a/gpu/include/GrAllocPool.h
+++ b/gpu/include/GrAllocPool.h
@@ -33,7 +33,7 @@
/**
* Returns a block of memory bytes size big. This address must not be
* passed to realloc/free/delete or any other function that assumes the
- * address was allocated by malloc or new (becuase it hasn't).
+ * address was allocated by malloc or new (because it hasn't).
*/
void* alloc(size_t bytes);
diff --git a/gpu/include/GrContext.h b/gpu/include/GrContext.h
index 6b9c3f3..973198b 100644
--- a/gpu/include/GrContext.h
+++ b/gpu/include/GrContext.h
@@ -445,25 +445,33 @@
GrFontCache* getFontCache() { return fFontCache; }
GrDrawTarget* getTextTarget(const GrPaint& paint);
void flushText();
-
- const GrIndexBuffer* quadIndexBuffer() const;
- int maxQuadsInIndexBuffer() const;
+ const GrIndexBuffer* getQuadIndexBuffer() const;
private:
+ // used to keep track of when we need to flush the draw buffer
+ enum DrawCategory {
+ kBuffered_DrawCategory, // last draw was inserted in draw buffer
+ kUnbuffered_DrawCategory, // last draw was not inserted in the draw buffer
+ kText_DrawCategory // text context was last to draw
+ };
+ DrawCategory fLastDrawCategory;
+
GrGpu* fGpu;
GrTextureCache* fTextureCache;
GrFontCache* fFontCache;
- GrVertexBufferAllocPool* fTextVBAllocPool;
- GrIndexBufferAllocPool* fTextIBAllocPool;
- GrInOrderDrawBuffer* fTextDrawBuffer;
+ GrVertexBufferAllocPool* fDrawBufferVBAllocPool;
+ GrIndexBufferAllocPool* fDrawBufferIBAllocPool;
+ GrInOrderDrawBuffer* fDrawBuffer;
GrContext(GrGpu* gpu);
+ void flushDrawBuffer();
static void SetPaint(const GrPaint& paint, GrDrawTarget* target);
bool finalizeTextureKey(GrTextureKey*, const GrSamplerState&) const;
- void prepareToDraw(const GrPaint& paint);
+
+ GrDrawTarget* prepareToDraw(const GrPaint& paint, DrawCategory drawType);
void drawClipIntoStencil();
};
diff --git a/gpu/include/GrContext_impl.h b/gpu/include/GrContext_impl.h
index b54e927..8af38e6 100644
--- a/gpu/include/GrContext_impl.h
+++ b/gpu/include/GrContext_impl.h
@@ -30,7 +30,7 @@
GrDrawTarget::AutoReleaseGeometry geo;
- this->prepareToDraw(paint);
+ GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
if (NULL != paint.getTexture()) {
if (NULL != texCoordSrc) {
@@ -47,7 +47,7 @@
int vertexCount = posSrc.count();
int indexCount = (NULL != idxSrc) ? idxSrc->count() : 0;
- if (!geo.set(fGpu, layout, vertexCount, indexCount)) {
+ if (!geo.set(target, layout, vertexCount, indexCount)) {
GrPrintf("Failed to get space for vertices!");
return;
}
@@ -77,9 +77,9 @@
}
if (NULL == idxSrc) {
- fGpu->drawNonIndexed(primitiveType, 0, vertexCount);
+ target->drawNonIndexed(primitiveType, 0, vertexCount);
} else {
- fGpu->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount);
+ target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount);
}
}
diff --git a/gpu/include/GrDrawTarget.h b/gpu/include/GrDrawTarget.h
index 88782f1..91af9ce 100644
--- a/gpu/include/GrDrawTarget.h
+++ b/gpu/include/GrDrawTarget.h
@@ -18,7 +18,6 @@
#ifndef GrDrawTarget_DEFINED
#define GrDrawTarget_DEFINED
-#include "GrScalar.h"
#include "GrMatrix.h"
#include "GrColor.h"
#include "GrRefCnt.h"
@@ -347,7 +346,11 @@
void disableState(uint32_t stateBits);
bool isDitherState() const {
- return fCurrDrawState.fFlagBits & kDither_StateBit;
+ return 0 != (fCurrDrawState.fFlagBits & kDither_StateBit);
+ }
+
+ bool isClipState() const {
+ return 0 != (fCurrDrawState.fFlagBits & kClip_StateBit);
}
/**
@@ -435,6 +438,16 @@
GrAssert(texCoordIdx < kMaxTexCoords);
return 1 << (stage + (texCoordIdx * kNumStages));
}
+
+ /**
+ * Determines if blend is effectively disabled.
+ *
+ * @return true if blend can be disabled without changing the rendering
+ * result given the current state including the vertex layout specified
+ * with the vertex source.
+ */
+ bool canDisableBlend() const;
+
private:
static const int TEX_COORD_BIT_CNT = kNumStages*kMaxTexCoords;
public:
@@ -655,6 +668,45 @@
int startVertex,
int vertexCount) = 0;
+ /**
+ * Helper function for drawing rects. This does not use the current index
+ * and vertex sources. After returning, the vertex and index sources may
+ * have changed. They should be reestablished before the next drawIndexed
+ * or drawNonIndexed. This cannot be called between reserving and releasing
+ * geometry. The GrDrawTarget subclass may be able to perform additional
+ * optimizations if drawRect is used rather than drawIndexed or
+ * drawNonIndexed.
+ * @param rect the rect to draw
+ * @param matrix optional matrix applied to rect (before viewMatrix)
+ * @param stageEnableMask bitmask indicating which stages are enabled.
+ * Bit i indicates whether stage i is enabled.
+ * @param srcRects specifies rects for stages enabled by stageEnableMask.
+ * if stageEnableMask bit i is 1, srcRects is not NULL,
+ * and srcRects[i] is not NULL, then srcRects[i] will be
+ * used as coordinates for stage i. Otherwise, if stage i
+ * is enabled then rect is used as the coordinates.
+ * @param srcMatrices optional matrices applied to srcRects. If
+ * srcRect[i] is non-NULL and srcMatrices[i] is
+ * non-NULL then srcRect[i] will be transformed by
+ * srcMatrix[i]. srcMatrices can be NULL when no
+ * srcMatrices are desired.
+ */
+ virtual void drawRect(const GrRect& rect,
+ const GrMatrix* matrix,
+ int stageEnableMask,
+ const GrRect* srcRects[],
+ const GrMatrix* srcMatrices[]);
+
+ /**
+ * Helper for drawRect when the caller doesn't need separate src rects or
+ * matrices.
+ */
+ void drawSimpleRect(const GrRect& rect,
+ const GrMatrix* matrix,
+ int stageEnableMask) {
+ drawRect(rect, matrix, stageEnableMask, NULL, NULL);
+ }
+
///////////////////////////////////////////////////////////////////////////
class AutoStateRestore : ::GrNoncopyable {
@@ -869,6 +921,65 @@
static int VertexSizeAndOffsetsByStage(GrVertexLayout vertexLayout,
int texCoordOffsetsByStage[kNumStages],
int *colorOffset);
+
+ /**
+ * Accessing positions, texture coords, or colors, of a vertex within an
+ * array is a hassle involving casts and simple math. These helpers exist
+ * to keep GrDrawTarget clients' code a bit nicer looking.
+ */
+
+ /**
+ * Gets a pointer to a GrPoint of a vertex's position or texture
+ * coordinate.
+ * @param vertices the vetex array
+ * @param vertexIndex the index of the vertex in the array
+ * @param vertexSize the size of each vertex in the array
+ * @param offset the offset in bytes of the vertex component.
+ * Defaults to zero (corresponding to vertex position)
+ * @return pointer to the vertex component as a GrPoint
+ */
+ static GrPoint* GetVertexPoint(void* vertices,
+ int vertexIndex,
+ int vertexSize,
+ int offset = 0) {
+ intptr_t start = GrTCast<intptr_t>(vertices);
+ return GrTCast<GrPoint*>(start + offset +
+ vertexIndex * vertexSize);
+ }
+ static const GrPoint* GetVertexPoint(const void* vertices,
+ int vertexIndex,
+ int vertexSize,
+ int offset = 0) {
+ intptr_t start = GrTCast<intptr_t>(vertices);
+ return GrTCast<const GrPoint*>(start + offset +
+ vertexIndex * vertexSize);
+ }
+
+ /**
+ * Gets a pointer to a GrColor inside a vertex within a vertex array.
+ * @param vertices the vetex array
+ * @param vertexIndex the index of the vertex in the array
+ * @param vertexSize the size of each vertex in the array
+ * @param offset the offset in bytes of the vertex color
+ * @return pointer to the vertex component as a GrColor
+ */
+ static GrColor* GetVertexColor(void* vertices,
+ int vertexIndex,
+ int vertexSize,
+ int offset) {
+ intptr_t start = GrTCast<intptr_t>(vertices);
+ return GrTCast<GrColor*>(start + offset +
+ vertexIndex * vertexSize);
+ }
+ static const GrColor* GetVertexColor(const void* vertices,
+ int vertexIndex,
+ int vertexSize,
+ int offset) {
+ const intptr_t start = GrTCast<intptr_t>(vertices);
+ return GrTCast<const GrColor*>(start + offset +
+ vertexIndex * vertexSize);
+ }
+
protected:
// Helpers for GrDrawTarget subclasses that won't have private access to
@@ -885,7 +996,8 @@
virtual void releaseGeometryHelper() = 0;
- virtual void clipWillChange(const GrClip& clip) = 0;
+ // subclass overrides to be notified when clip is set.
+ virtual void clipWillBeSet(const GrClip& clip) = 0;
virtual void setVertexSourceToArrayHelper(const void* vertexArray,
int vertexCount) = 0;
@@ -893,6 +1005,18 @@
virtual void setIndexSourceToArrayHelper(const void* indexArray,
int indexCount) = 0;
+ // Helpers for drawRect, protected so subclasses that override drawRect
+ // can use them.
+ static GrVertexLayout GetRectVertexLayout(int stageEnableMask,
+ const GrRect* srcRects[]);
+
+ static void SetRectVertices(const GrRect& rect,
+ const GrMatrix* matrix,
+ const GrRect* srcRects[],
+ const GrMatrix* srcMatrices[],
+ GrVertexLayout layout,
+ void* vertices);
+
enum GeometrySrcType {
kReserved_GeometrySrcType, // src was set using reserveAndLockGeometry
kArray_GeometrySrcType, // src was set using set*SourceToArray
diff --git a/gpu/include/GrGeometryBuffer.h b/gpu/include/GrGeometryBuffer.h
index fc3e358..af6eed5 100644
--- a/gpu/include/GrGeometryBuffer.h
+++ b/gpu/include/GrGeometryBuffer.h
@@ -31,7 +31,7 @@
*
* @return the size of the buffer in bytes
*/
- size_t size() { return fSizeInBytes; }
+ size_t size() const { return fSizeInBytes; }
/**
*Retrieves whether the buffer was created with the dynamic flag
@@ -107,9 +107,9 @@
fDynamic(dynamic) {}
private:
- size_t fSizeInBytes;
+ size_t fSizeInBytes;
bool fDynamic;
-
+
typedef GrRefCnt INHERITED;
};
diff --git a/gpu/include/GrGpu.h b/gpu/include/GrGpu.h
index 9fb7b9c..a132e9f 100644
--- a/gpu/include/GrGpu.h
+++ b/gpu/include/GrGpu.h
@@ -21,9 +21,7 @@
#include "GrRect.h"
#include "GrRefCnt.h"
#include "GrDrawTarget.h"
-#include "GrGpuVertex.h"
#include "GrTexture.h"
-#include "GrMemory.h"
class GrVertexBufferAllocPool;
class GrIndexBufferAllocPool;
@@ -295,29 +293,20 @@
int vertexCount);
/**
- * Determines if blend is effectively disabled.
- *
- * @return true if blend can be disabled without changing the rendering
- * result given the current state including the vertex layout specified
- * with the vertex source.
- */
- bool canDisableBlend() const;
-
- /**
* Returns an index buffer that can be used to render quads.
- * Indices are 0, 1, 2, 0, 2, 3, etc.
+ * Six indices per quad: 0, 1, 2, 0, 2, 3, etc.
+ * The max number of quads can be queried using GrIndexBuffer::maxQuads().
* Draw with kTriangles_PrimitiveType
+ * @ return the quad index buffer
*/
- const GrIndexBuffer* quadIndexBuffer() const;
- /**
- * Gets the number of quads that can be rendered using quadIndexBuffer.
- */
- int maxQuadsInIndexBuffer() const;
+ const GrIndexBuffer* getQuadIndexBuffer() const;
/**
- * Returns a vertex buffer with four position-only vertices [(0,0), (1,0), (1,1), (0,1)]
+ * Returns a vertex buffer with four position-only vertices [(0,0), (1,0),
+ * (1,1), (0,1)].
+ * @ return unit square vertex buffer
*/
- const GrVertexBuffer* unitSquareVertexBuffer() const;
+ const GrVertexBuffer* getUnitSquareVertexBuffer() const;
/**
* Ensures that the current render target is actually set in the
@@ -356,7 +345,10 @@
GrRenderTarget* fStencilClipTarget;
} fClipState;
- virtual void clipWillChange(const GrClip& clip);
+ // GrDrawTarget override
+ virtual void clipWillBeSet(const GrClip& newClip);
+
+ // prepares clip flushes gpu state before a draw
bool setupClipAndFlushState(PrimitiveType type);
struct BoundsState {
diff --git a/gpu/include/GrInOrderDrawBuffer.h b/gpu/include/GrInOrderDrawBuffer.h
index 463ea2d..0dba8e3 100644
--- a/gpu/include/GrInOrderDrawBuffer.h
+++ b/gpu/include/GrInOrderDrawBuffer.h
@@ -41,31 +41,65 @@
class GrInOrderDrawBuffer : public GrDrawTarget {
public:
+ /**
+ * Creates a GrInOrderDrawBuffer
+ *
+ * @param vertexPool pool where vertices for queued draws will be saved when
+ * the vertex source is either reserved or array.
+ * @param indexPool pool where indices for queued draws will be saved when
+ * the index source is either reserved or array.
+ */
GrInOrderDrawBuffer(GrVertexBufferAllocPool* vertexPool,
GrIndexBufferAllocPool* indexPool);
virtual ~GrInOrderDrawBuffer();
+ /**
+ * Copies the draw state and clip from target to this draw buffer.
+ *
+ * @param target the target whose clip and state should be copied.
+ */
void initializeDrawStateAndClip(const GrDrawTarget& target);
+ /**
+ * Provides the buffer with an index buffer that can be used for quad rendering.
+ * The buffer may be able to batch consecutive drawRects if this is provided.
+ * @param indexBuffer index buffer with quad indices.
+ */
+ void setQuadIndexBuffer(const GrIndexBuffer* indexBuffer);
+
+ /**
+ * Empties the draw buffer of any queued up draws.
+ */
+ void reset();
+
+ /**
+ * plays the queued up draws to another target. Does not empty this buffer so
+ * that it can be played back multiple times.
+ * @param target the target to receive the playback
+ */
+ void playback(GrDrawTarget* target);
+
+ // overrides from GrDrawTarget
virtual void drawIndexed(PrimitiveType primitiveType,
int startVertex,
int startIndex,
int vertexCount,
int indexCount);
-
virtual void drawNonIndexed(PrimitiveType primitiveType,
int startVertex,
int vertexCount);
+ virtual void drawRect(const GrRect& rect,
+ const GrMatrix* matrix = NULL,
+ int stageEnableMask = 0,
+ const GrRect* srcRects[] = NULL,
+ const GrMatrix* srcMatrices[] = NULL);
+
virtual bool geometryHints(GrVertexLayout vertexLayout,
int* vertexCount,
int* indexCount) const;
- void reset();
-
- void playback(GrDrawTarget* target);
-
private:
struct Draw {
@@ -85,7 +119,7 @@
void** vertices,
void** indices);
virtual void releaseGeometryHelper();
- virtual void clipWillChange(const GrClip& clip);
+ virtual void clipWillBeSet(const GrClip& newClip);
virtual void setVertexSourceToArrayHelper(const void* vertexArray,
int vertexCount);
@@ -93,9 +127,11 @@
virtual void setIndexSourceToArrayHelper(const void* indexArray,
int indexCount);
+ bool needsNewState() const;
+ bool needsNewClip() const;
- bool grabState();
- bool grabClip();
+ void pushState();
+ void pushClip();
GrTAllocator<Draw> fDraws;
// HACK: We currently do not hold refs on RTs in the saved draw states.
@@ -106,7 +142,12 @@
GrTAllocator<SavedDrawState> fStates;
GrTAllocator<GrClip> fClips;
- bool fClipChanged;
+ bool fClipSet;
+
+ GrVertexLayout fLastRectVertexLayout;
+ const GrIndexBuffer* fQuadIndexBuffer;
+ int fMaxQuads;
+ int fCurrQuad;
GrVertexBufferAllocPool& fVertexPool;
const GrVertexBuffer* fCurrPoolVertexBuffer;
@@ -134,6 +175,7 @@
STATES_BLOCK_SIZE];
int8_t fClipsStorage[sizeof(GrClip) *
CLIPS_BLOCK_SIZE];
+ typedef GrDrawTarget INHERITED;
};
#endif
diff --git a/gpu/include/GrIndexBuffer.h b/gpu/include/GrIndexBuffer.h
index 85ff749..09d1977 100644
--- a/gpu/include/GrIndexBuffer.h
+++ b/gpu/include/GrIndexBuffer.h
@@ -21,6 +21,13 @@
#include "GrGeometryBuffer.h"
class GrIndexBuffer : public GrGeometryBuffer {
+public:
+ /**
+ * Retrieves the maximum number of quads that could be rendered
+ * from the index buffer (using kTriangles_PrimitiveType).
+ * @return the maximum number of quads using full size of index buffer.
+ */
+ int maxQuads() const { return size() / (sizeof(uint16_t) * 6); }
protected:
GrIndexBuffer(size_t sizeInBytes, bool dynamic) :
INHERITED(sizeInBytes, dynamic) {}
diff --git a/gpu/include/GrRect.h b/gpu/include/GrRect.h
index 5192ebd..e98913a 100644
--- a/gpu/include/GrRect.h
+++ b/gpu/include/GrRect.h
@@ -131,7 +131,7 @@
* Initialize a rectangle to a point.
* @param pt the point used to initialize the rectanglee.
*/
- GrRect(GrPoint pt) {
+ explicit GrRect(const GrPoint& pt) {
setToPoint(pt);
}
@@ -187,6 +187,11 @@
bool isInverted() const {
return (fLeft > fRight) || (fTop > fBottom);
}
+
+ bool contains(const GrPoint& point) const {
+ return point.fX >= fLeft && point.fX < fRight &&
+ point.fY >= fTop && point.fY < fBottom;
+ }
/**
* Initialize a rectangle to a point.
diff --git a/gpu/include/GrTextContext.h b/gpu/include/GrTextContext.h
index 727358e..3dc9c7a 100644
--- a/gpu/include/GrTextContext.h
+++ b/gpu/include/GrTextContext.h
@@ -19,8 +19,10 @@
#define GrTextContext_DEFINED
#include "GrGlyph.h"
-#include "GrGpuVertex.h"
+#include "GrPaint.h"
+struct GrGpuTextVertex;
+class GrMatrix;
class GrContext;
class GrTextStrike;
class GrFontScaler;
diff --git a/gpu/include/GrTypes.h b/gpu/include/GrTypes.h
index 9553678..8311239 100644
--- a/gpu/include/GrTypes.h
+++ b/gpu/include/GrTypes.h
@@ -141,14 +141,14 @@
///////////////////////////////////////////////////////////////////////////////
/**
- * Use to cast a pointer to a different type, and maintaining strict-aliasing
+ * Use to cast a ptr to a different type, and maintain strict-aliasing
*/
-template <typename Dst> Dst GrTCast(const void* ptr) {
+template <typename Dst, typename Src> Dst GrTCast(Src src) {
union {
- const void* src;
+ Src src;
Dst dst;
} data;
- data.src = ptr;
+ data.src = src;
return data.dst;
}