///////////////////////////////////////////////////////////////////////////
GrDrawTarget();
+ virtual ~GrDrawTarget();
/**
* Sets the current clip to the region specified by clip. All draws will be
GR_STATIC_ASSERT(kHighVertexLayoutBit < ((uint64_t)1 << 8*sizeof(GrVertexLayout)));
/**
- * There are three paths for specifying geometry (vertices and optionally
+ * There are three methods for specifying geometry (vertices and optionally
* indices) to the draw target. When indexed drawing the indices and vertices
- * can be each use a different path.
+ * can use a different method. Once geometry is specified it can be used for
+ * multiple drawIndexed and drawNonIndexed calls.
+ *
+ * Sometimes it is necessary to perform a draw while upstack code has
+ * already specified geometry that it isn't finished with. There are push
+ * pop methods
*
* 1. Provide a cpu array (set*SourceToArray). This is useful when the
* caller's client has already provided vertex data in a format
* drawIndexed & drawNonIndexed calls until set*SourceToArray is called
* again or one of the other two paths is chosen.
*
- * 2. Reserve and Lock. This is most useful when the caller has data it must
- * transform before drawing and will not likely render it again. The
- * caller requests that the draw target make room for some amount of
- * vertex and/or index data. The target provides ptrs to hold the data
- * data. The caller can write the data into the pts up until the first
- * drawIndexed or drawNonIndexed call. At this point the data is frozen
- * and the ptrs are no longer guaranteed to be valid. All subsequent
- * drawIndexed & drawNonIndexed calls will use this data until
- * releaseReserved geometry is called. This must be called before another
- * source is set.
+ * 2. Reserve. This is most useful when the caller has data it must
+ * transform before drawing and is not long-lived. The caller requests
+ * that the draw target make room for some amount of vertex and/or index
+ * data. The target provides ptrs to hold the vertex and/or index data.
+ *
+ * The data is writable up until the next drawIndexed, drawNonIndexed,
+ * or pushGeometrySource At this point the data is frozen and the ptrs
+ * are no longer valid.
*
* 3. Vertex and Index Buffers. This is most useful for geometry that will
- * be rendered multiple times. SetVertexSourceToBuffer &
- * SetIndexSourceToBuffer are used to set the buffer and subsequent
- * drawIndexed and drawNonIndexed calls use this source until another
- * source is set.
+ * is long-lived. SetVertexSourceToBuffer and SetIndexSourceToBuffer are
+ * used to set the buffer and subsequent drawIndexed and drawNonIndexed
+ * calls use this source until another source is set.
*/
/**
- * Reserves space for vertices and/or indices. Draw target will use
- * reserved vertices / indices at next draw.
+ * Reserves space for vertices. Draw target will use reserved vertices at
+ * at the next draw.
*
* If succeeds:
- * if vertexCount is nonzero, *vertices will be the array
+ * if vertexCount > 0, *vertices will be the array
* of vertices to be filled by caller. The next draw will read
* these vertices.
*
- * if indexCount is nonzero, *indices will be the array of indices
- * to be filled by caller. The next indexed draw will read from
- * these indices.
- *
* If a client does not already have a vertex buffer then this is the
- * preferred way to allocate vertex/index array. It allows the subclass of
+ * preferred way to allocate vertex data. It allows the subclass of
* GrDrawTarget to decide whether to put data in buffers, to group vertex
* data that uses the same state (e.g. for deferred rendering), etc.
*
- * Following the first draw after reserveAndLockGeometry the ptrs returned
- * by releaseReservedGeometry are no longer valid and the geometry data
- * cannot be further modified. The contents that were put in the reserved
- * space can be drawn by multiple draws, however.
+ * After the next draw or pushGeometrySource the vertices ptr is no longer
+ * valid and the geometry data cannot be further modified. The contents
+ * that were put in the reserved space can be drawn by multiple draws,
+ * however.
*
- * reserveAndLockGeometry must be matched with a releaseReservedGeometry
- * call after all draws that reference the reserved geometry data have
- * been called.
- *
- * AutoGeometryRelease can be used to automatically call the release.
- *
- * @param vertexCount the number of vertices to reserve space for. Can be 0.
- * @param indexCount the number of indices to reserve space for. Can be 0.
* @param vertexLayout the format of vertices (ignored if vertexCount == 0).
+ * @param vertexCount the number of vertices to reserve space for. Can be 0.
* @param vertices will point to reserved vertex space if vertexCount is
* non-zero. Illegal to pass NULL if vertexCount > 0.
- * @param indices will point to reserved index space if indexCount is
- * non-zero. Illegal to pass NULL if indexCount > 0.
*
* @return true if succeeded in allocating space for the vertices and false
* if not.
*/
- bool reserveAndLockGeometry(GrVertexLayout vertexLayout,
- uint32_t vertexCount,
- uint32_t indexCount,
- void** vertices,
- void** indices);
+ bool reserveVertexSpace(GrVertexLayout vertexLayout,
+ int vertexCount,
+ void** vertices);
+ /**
+ * Reserves space for indices. Draw target will use the reserved indices at
+ * the next indexed draw.
+ *
+ * If succeeds:
+ * if indexCount > 0, *indices will be the array
+ * of indices to be filled by caller. The next draw will read
+ * these indices.
+ *
+ * If a client does not already have a index buffer then this is the
+ * preferred way to allocate index data. It allows the subclass of
+ * GrDrawTarget to decide whether to put data in buffers, to group index
+ * data that uses the same state (e.g. for deferred rendering), etc.
+ *
+ * After the next indexed draw or pushGeometrySource the indices ptr is no
+ * longer valid and the geometry data cannot be further modified. The
+ * contents that were put in the reserved space can be drawn by multiple
+ * draws, however.
+ *
+ * @param indexCount the number of indices to reserve space for. Can be 0.
+ * @param indices will point to reserved index space if indexCount is
+ * non-zero. Illegal to pass NULL if indexCount > 0.
+ */
+
+ bool reserveIndexSpace(int indexCount, void** indices);
/**
* Provides hints to caller about the number of vertices and indices
* that can be allocated cheaply. This can be useful if caller is reserving
int* indexCount) const;
/**
- * Releases reserved vertex/index data from reserveAndLockGeometry().
- */
- void releaseReservedGeometry();
-
- /**
* Sets source of vertex data for the next draw. Array must contain
* the vertex data when this is called.
*
* before indexed draw call.
*/
void setIndexSourceToBuffer(const GrIndexBuffer* buffer);
+
+ /**
+ * Resets vertex source. Drawing from reset vertices is illegal. Set vertex
+ * source to reserved, array, or buffer before next draw. May be able to free
+ * up temporary storage allocated by setVertexSourceToArray or
+ * reserveVertexSpace.
+ */
+ void resetVertexSource();
+
+ /**
+ * Resets index source. Indexed Drawing from reset indices is illegal. Set
+ * index source to reserved, array, or buffer before next indexed draw. May
+ * be able to free up temporary storage allocated by setIndexSourceToArray
+ * or reserveIndexSpace.
+ */
+ void resetIndexSource();
/**
+ * Pushes and resets the vertex/index sources. Any reserved vertex / index
+ * data is finalized (i.e. cannot be updated after the matching pop but can
+ * be drawn from). Must be balanced by a pop.
+ */
+ void pushGeometrySource();
+
+ /**
+ * Pops the vertex / index sources from the matching push.
+ */
+ void popGeometrySource();
+
+ /**
* Draws indexed geometry using the current state and current vertex / index
* sources.
*
* is effectively trimmed to the last completely
* specified primitive.
*/
- virtual void drawIndexed(GrPrimitiveType type,
- int startVertex,
- int startIndex,
- int vertexCount,
- int indexCount) = 0;
+ void drawIndexed(GrPrimitiveType type,
+ int startVertex,
+ int startIndex,
+ int vertexCount,
+ int indexCount);
/**
* Draws non-indexed geometry using the current state and current vertex
* to index 0
* @param vertexCount one greater than the max index.
*/
- virtual void drawNonIndexed(GrPrimitiveType type,
- int startVertex,
- int vertexCount) = 0;
+ void drawNonIndexed(GrPrimitiveType type,
+ int startVertex,
+ int vertexCount);
/**
* Helper function for drawing rects. This does not use the current index
*/
virtual int getMaxEdges() const { return 6; }
- ///////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////
class AutoStateRestore : ::GrNoncopyable {
public:
SavedDrawState fDrawState;
};
- ///////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////
class AutoViewMatrixRestore : ::GrNoncopyable {
public:
GrMatrix fMatrix;
};
- ///////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////
/**
* Sets the view matrix to I and preconcats all stage matrices enabled in
int fStageMask;
};
- ///////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////
class AutoReleaseGeometry : ::GrNoncopyable {
public:
AutoReleaseGeometry(GrDrawTarget* target,
GrVertexLayout vertexLayout,
- uint32_t vertexCount,
- uint32_t indexCount) {
- fTarget = NULL;
- this->set(target, vertexLayout, vertexCount, indexCount);
- }
-
- AutoReleaseGeometry() {
- fTarget = NULL;
- }
-
- ~AutoReleaseGeometry() {
- if (NULL != fTarget) {
- fTarget->releaseReservedGeometry();
- }
- }
-
+ int vertexCount,
+ int indexCount);
+ AutoReleaseGeometry();
+ ~AutoReleaseGeometry();
bool set(GrDrawTarget* target,
GrVertexLayout vertexLayout,
- uint32_t vertexCount,
- uint32_t indexCount) {
- if (NULL != fTarget) {
- fTarget->releaseReservedGeometry();
- }
- fTarget = target;
- if (NULL != fTarget) {
- if (!fTarget->reserveAndLockGeometry(vertexLayout,
- vertexCount,
- indexCount,
- &fVertices,
- &fIndices)) {
- fTarget = NULL;
- }
- }
- return NULL != fTarget;
- }
-
+ int vertexCount,
+ int indexCount);
bool succeeded() const { return NULL != fTarget; }
void* vertices() const { return fVertices; }
void* indices() const { return fIndices; }
-
GrPoint* positions() const {
return static_cast<GrPoint*>(fVertices);
}
private:
+ void reset();
+
GrDrawTarget* fTarget;
void* fVertices;
void* fIndices;
};
- ///////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////
class AutoClipRestore : ::GrNoncopyable {
public:
GrDrawTarget* fTarget;
GrClip fClip;
};
+
+ ////////////////////////////////////////////////////////////////////////////
+
+ class AutoGeometryPush : ::GrNoncopyable {
+ public:
+ AutoGeometryPush(GrDrawTarget* target) {
+ GrAssert(NULL != target);
+ fTarget = target;
+ target->pushGeometrySource();
+ }
+ ~AutoGeometryPush() {
+ fTarget->popGeometrySource();
+ }
+ private:
+ GrDrawTarget* fTarget;
+ };
////////////////////////////////////////////////////////////////////////////
// Helpers for picking apart vertex layouts
static void VertexLayoutUnitTest();
protected:
+
+ enum GeometrySrcType {
+ kNone_GeometrySrcType, //<! src has not been specified
+ kReserved_GeometrySrcType, //<! src was set using reserve*Space
+ kArray_GeometrySrcType, //<! src was set using set*SourceToArray
+ kBuffer_GeometrySrcType //<! src was set using set*SourceToBuffer
+ };
+
+ struct GeometrySrcState {
+ GeometrySrcType fVertexSrc;
+ union {
+ // valid if src type is buffer
+ const GrVertexBuffer* fVertexBuffer;
+ // valid if src type is reserved or array
+ int fVertexCount;
+ };
+
+ GeometrySrcType fIndexSrc;
+ union {
+ // valid if src type is buffer
+ const GrIndexBuffer* fIndexBuffer;
+ // valid if src type is reserved or array
+ int fIndexCount;
+ };
+
+ GrVertexLayout fVertexLayout;
+ };
+
// given a vertex layout and a draw state, will a stage be used?
static bool StageWillBeUsed(int stage, GrVertexLayout layout,
const DrState& state) {
}
bool isStageEnabled(int stage) const {
- return StageWillBeUsed(stage, fGeometrySrc.fVertexLayout, fCurrDrawState);
+ return StageWillBeUsed(stage, this->getGeomSrc().fVertexLayout,
+ fCurrDrawState);
}
// Helpers for GrDrawTarget subclasses that won't have private access to
static const DrState& accessSavedDrawState(const SavedDrawState& sds)
{ return sds.fState; }
- // implemented by subclass
- virtual bool onAcquireGeometry(GrVertexLayout vertexLayout,
- void** vertices,
- void** indices) = 0;
-
- virtual void onReleaseGeometry() = 0;
-
- // subclass overrides to be notified when clip is set.
- virtual void clipWillBeSet(const GrClip& clip) = 0;
-
+ // implemented by subclass to allocate space for reserved geom
+ virtual bool onReserveVertexSpace(GrVertexLayout vertexLayout,
+ int vertexCount,
+ void** vertices) = 0;
+ virtual bool onReserveIndexSpace(int indexCount, void** indices) = 0;
+ // implemented by subclass to handle release of reserved geom space
+ virtual void releaseReservedVertexSpace() = 0;
+ virtual void releaseReservedIndexSpace() = 0;
+ // subclass must consume array contents when set
virtual void onSetVertexSourceToArray(const void* vertexArray,
int vertexCount) = 0;
-
virtual void onSetIndexSourceToArray(const void* indexArray,
int indexCount) = 0;
+ // subclass is notified that geom source will be set away from an array
+ virtual void releaseVertexArray() = 0;
+ virtual void releaseIndexArray() = 0;
+ // subclass overrides to be notified just before geo src state
+ // is pushed/popped.
+ virtual void geometrySourceWillPush() = 0;
+ virtual void geometrySourceWillPop(const GeometrySrcState& restoredState) = 0;
+ // subclass called to perform drawing
+ virtual void onDrawIndexed(GrPrimitiveType type,
+ int startVertex,
+ int startIndex,
+ int vertexCount,
+ int indexCount) = 0;
+ virtual void onDrawNonIndexed(GrPrimitiveType type,
+ int startVertex,
+ int vertexCount) = 0;
+ // subclass overrides to be notified when clip is set.
+ virtual void clipWillBeSet(const GrClip& clip) = 0;
+
// Helpers for drawRect, protected so subclasses that override drawRect
// can use them.
GrVertexLayout layout,
void* vertices);
- enum GeometrySrcType {
- kReserved_GeometrySrcType, // src was set using reserveAndLockGeometry
- kArray_GeometrySrcType, // src was set using set*SourceToArray
- kBuffer_GeometrySrcType // src was set using set*SourceToBuffer
- };
-
- struct ReservedGeometry {
- bool fLocked;
- uint32_t fVertexCount;
- uint32_t fIndexCount;
- } fReservedGeometry;
-
- struct GeometrySrc {
- GeometrySrcType fVertexSrc;
- const GrVertexBuffer* fVertexBuffer; // valid if src type is buffer
- GeometrySrcType fIndexSrc;
- const GrIndexBuffer* fIndexBuffer; // valid if src type is buffer
- GrVertexLayout fVertexLayout;
- } fGeometrySrc;
+ // accessor for derived classes
+ const GeometrySrcState& getGeomSrc() const {
+ return fGeoSrcStateStack.back();
+ }
GrClip fClip;
DrState fCurrDrawState;
- // Not meant for external use. Only setVertexSourceToBuffer and
- // setIndexSourceToBuffer will work since GrDrawTarget subclasses don't
- // support nested reserveAndLockGeometry (and cpu arrays internally use the
- // same path).
- class AutoGeometrySrcRestore {
- public:
- AutoGeometrySrcRestore(GrDrawTarget* target) {
- fTarget = target;
- fGeometrySrc = fTarget->fGeometrySrc;
- }
- ~AutoGeometrySrcRestore() {
- fTarget->fGeometrySrc = fGeometrySrc;
- }
- private:
- GrDrawTarget *fTarget;
- GeometrySrc fGeometrySrc;
-
- AutoGeometrySrcRestore();
- AutoGeometrySrcRestore(const AutoGeometrySrcRestore&);
- AutoGeometrySrcRestore& operator =(AutoGeometrySrcRestore&);
+private:
+ // called when setting a new vert/idx source to unref prev vb/ib
+ void releasePreviousVertexSource();
+ void releasePreviousIndexSource();
+
+ enum {
+ kPreallocGeoSrcStateStackCnt = 4,
};
+ GrAlignedSTStorage<kPreallocGeoSrcStateStackCnt,
+ GeometrySrcState>
+ fGeoSrcStateStackStorage;
+ GrTArray<GeometrySrcState, true> fGeoSrcStateStack;
+
};
#endif
*/
int maxRenderTargetSize() const { return fMaxRenderTargetSize; }
- // GrDrawTarget overrides
- virtual void drawIndexed(GrPrimitiveType type,
- int startVertex,
- int startIndex,
- int vertexCount,
- int indexCount);
-
- virtual void drawNonIndexed(GrPrimitiveType type,
- int startVertex,
- int vertexCount);
virtual void clear(const GrIRect* rect, GrColor color);
/**
GrGpuStats fStats;
- const GrVertexBuffer* fCurrPoolVertexBuffer;
- int fCurrPoolStartVertex;
-
- const GrIndexBuffer* fCurrPoolIndexBuffer;
- int fCurrPoolStartIndex;
+ struct GeometryPoolState {
+ const GrVertexBuffer* fPoolVertexBuffer;
+ int fPoolStartVertex;
+
+ const GrIndexBuffer* fPoolIndexBuffer;
+ int fPoolStartIndex;
+ };
+ const GeometryPoolState& getGeomPoolState() {
+ return fGeomPoolStateStack.back();
+ }
// GrDrawTarget overrides
- virtual bool onAcquireGeometry(GrVertexLayout vertexLayout,
- void** vertices,
- void** indices);
- virtual void onReleaseGeometry();
-
+ virtual bool onReserveVertexSpace(GrVertexLayout vertexLayout,
+ int vertexCount,
+ void** vertices);
+ virtual bool onReserveIndexSpace(int indexCount, void** indices);
+ virtual void releaseReservedVertexSpace();
+ virtual void releaseReservedIndexSpace();
virtual void onSetVertexSourceToArray(const void* vertexArray,
int vertexCount);
-
virtual void onSetIndexSourceToArray(const void* indexArray,
int indexCount);
+ virtual void releaseVertexArray();
+ virtual void releaseIndexArray();
+ virtual void geometrySourceWillPush();
+ virtual void geometrySourceWillPop(const GeometrySrcState& restoredState);
+
// Helpers for setting up geometry state
void finalizeReservedVertices();
void finalizeReservedIndices();
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,
- uint32_t startVertex,
- uint32_t startIndex,
- uint32_t vertexCount,
- uint32_t indexCount) = 0;
-
- virtual void onDrawNonIndexed(GrPrimitiveType type,
+ virtual void onGpuDrawIndexed(GrPrimitiveType type,
+ uint32_t startVertex,
+ uint32_t startIndex,
uint32_t vertexCount,
- uint32_t numVertices) = 0;
+ uint32_t indexCount) = 0;
+
+ virtual void onGpuDrawNonIndexed(GrPrimitiveType type,
+ uint32_t vertexCount,
+ uint32_t numVertices) = 0;
// overridden by API-specific derived class to perform flush
virtual void onForceRenderTargetFlush() = 0;
GrVertexBufferAllocPool* fVertexPool;
GrIndexBufferAllocPool* fIndexPool;
-
+
+ // counts number of uses of vertex/index pool in the geometry stack
+ int fVertexPoolUseCnt;
+ int fIndexPoolUseCnt;
+
+ enum {
+ kPreallocGeomPoolStateStackCnt = 4,
+ };
+ GrAlignedSTStorage<kPreallocGeomPoolStateStackCnt,
+ GeometryPoolState> fGeoSrcStateStackStorage;
+ GrTArray<GeometryPoolState, true> fGeomPoolStateStack;
+
mutable GrIndexBuffer* fQuadIndexBuffer; // mutable so it can be
// created on-demand
bool fContextIsDirty;
- // when in an internal draw these indicate whether the pools are in use
- // by one of the outer draws. If false then it is safe to reset the
- // pool.
- bool fVertexPoolInUse;
- bool fIndexPoolInUse;
-
GrResource* fResourceHead;
+ // GrDrawTarget overrides
+ virtual void onDrawIndexed(GrPrimitiveType type,
+ int startVertex,
+ int startIndex,
+ int vertexCount,
+ int indexCount);
+ virtual void onDrawNonIndexed(GrPrimitiveType type,
+ int startVertex,
+ int vertexCount);
+
// readies the pools to provide vertex/index data.
void prepareVertexPool();
void prepareIndexPool();
}
}
- // used to save and restore state when the GrGpu needs
- // to make its geometry pools available internally
- class AutoInternalDrawGeomRestore {
- public:
- AutoInternalDrawGeomRestore(GrGpu* gpu) : fAgsr(gpu) {
- fGpu = gpu;
-
- fVertexPoolWasInUse = gpu->fVertexPoolInUse;
- fIndexPoolWasInUse = gpu->fIndexPoolInUse;
-
- gpu->fVertexPoolInUse = fVertexPoolWasInUse ||
- (kBuffer_GeometrySrcType !=
- gpu->fGeometrySrc.fVertexSrc);
- gpu->fIndexPoolInUse = fIndexPoolWasInUse ||
- (kBuffer_GeometrySrcType !=
- gpu->fGeometrySrc.fIndexSrc);;
-
- fSavedPoolVertexBuffer = gpu->fCurrPoolVertexBuffer;
- fSavedPoolStartVertex = gpu->fCurrPoolStartVertex;
- fSavedPoolIndexBuffer = gpu->fCurrPoolIndexBuffer;
- fSavedPoolStartIndex = gpu->fCurrPoolStartIndex;
-
- fSavedReservedGeometry = gpu->fReservedGeometry;
- gpu->fReservedGeometry.fLocked = false;
- }
- ~AutoInternalDrawGeomRestore() {
- fGpu->fCurrPoolVertexBuffer = fSavedPoolVertexBuffer;
- fGpu->fCurrPoolStartVertex = fSavedPoolStartVertex;
- fGpu->fCurrPoolIndexBuffer = fSavedPoolIndexBuffer;
- fGpu->fCurrPoolStartIndex = fSavedPoolStartIndex;
- fGpu->fVertexPoolInUse = fVertexPoolWasInUse;
- fGpu->fIndexPoolInUse = fIndexPoolWasInUse;
- fGpu->fReservedGeometry = fSavedReservedGeometry;
- }
- private:
- AutoGeometrySrcRestore fAgsr;
- GrGpu* fGpu;
- const GrVertexBuffer* fSavedPoolVertexBuffer;
- int fSavedPoolStartVertex;
- const GrIndexBuffer* fSavedPoolIndexBuffer;
- int fSavedPoolStartIndex;
- bool fVertexPoolWasInUse;
- bool fIndexPoolWasInUse;
- ReservedGeometry fSavedReservedGeometry;
- };
-
typedef GrDrawTarget INHERITED;
};
void playback(GrDrawTarget* target);
// overrides from GrDrawTarget
- virtual void drawIndexed(GrPrimitiveType primitiveType,
- int startVertex,
- int startIndex,
- int vertexCount,
- int indexCount);
- virtual void drawNonIndexed(GrPrimitiveType primitiveType,
- int startVertex,
- int vertexCount);
-
virtual void drawRect(const GrRect& rect,
const GrMatrix* matrix = NULL,
int stageEnableMask = 0,
GrColor fColor;
};
- virtual bool onAcquireGeometry(GrVertexLayout vertexLayout,
- void** vertices,
- void** indices);
- virtual void onReleaseGeometry();
- virtual void clipWillBeSet(const GrClip& newClip);
-
+ // overrides from GrDrawTarget
+ virtual void onDrawIndexed(GrPrimitiveType primitiveType,
+ int startVertex,
+ int startIndex,
+ int vertexCount,
+ int indexCount);
+ virtual void onDrawNonIndexed(GrPrimitiveType primitiveType,
+ int startVertex,
+ int vertexCount);
+ virtual bool onReserveVertexSpace(GrVertexLayout layout,
+ int vertexCount,
+ void** vertices);
+ virtual bool onReserveIndexSpace(int indexCount, void** indices);
+ virtual void releaseReservedVertexSpace();
+ virtual void releaseReservedIndexSpace();
virtual void onSetVertexSourceToArray(const void* vertexArray,
- int vertexCount);
-
+ int vertexCount);
virtual void onSetIndexSourceToArray(const void* indexArray,
int indexCount);
+ virtual void releaseVertexArray();
+ virtual void releaseIndexArray();
+ virtual void geometrySourceWillPush();
+ virtual void geometrySourceWillPop(const GeometrySrcState& restoredState);
+ virtual void clipWillBeSet(const GrClip& newClip);
bool needsNewState() const;
bool needsNewClip() const;
int fCurrQuad;
GrVertexBufferAllocPool& fVertexPool;
- const GrVertexBuffer* fCurrPoolVertexBuffer;
- int fCurrPoolStartVertex;
GrIndexBufferAllocPool& fIndexPool;
- const GrIndexBuffer* fCurrPoolIndexBuffer;
- int fCurrPoolStartIndex;
-
- // caller may conservatively over reserve vertices / indices.
- // we release unused space back to allocator if possible
- size_t fReservedVertexBytes;
- size_t fReservedIndexBytes;
- size_t fUsedReservedVertexBytes;
- size_t fUsedReservedIndexBytes;
+ struct GeometryPoolState {
+ const GrVertexBuffer* fPoolVertexBuffer;
+ int fPoolStartVertex;
+ const GrIndexBuffer* fPoolIndexBuffer;
+ int fPoolStartIndex;
+ // caller may conservatively over reserve vertices / indices.
+ // we release unused space back to allocator if possible
+ // can only do this if there isn't an intervening pushGeometrySource()
+ size_t fUsedPoolVertexBytes;
+ size_t fUsedPoolIndexBytes;
+ };
+ GrTArray<GeometryPoolState> fGeoPoolStateStack;
+
enum {
- kDrawPreallocCnt = 8,
- kStatePreallocCnt = 8,
- kClipPreallocCnt = 8,
- kClearPreallocCnt = 4,
+ kDrawPreallocCnt = 8,
+ kStatePreallocCnt = 8,
+ kClipPreallocCnt = 8,
+ kClearPreallocCnt = 4,
+ kGeoPoolStatePreAllocCnt = 4,
};
GrAlignedSTStorage<kDrawPreallocCnt, Draw> fDrawStorage;
GrAlignedSTStorage<kStatePreallocCnt, SavedDrawState> fStateStorage;
GrAlignedSTStorage<kClipPreallocCnt, GrClip> fClipStorage;
GrAlignedSTStorage<kClearPreallocCnt, Clear> fClearStorage;
+ GrAlignedSTStorage<kGeoPoolStatePreAllocCnt,
+ GeometryPoolState> fGeoStackStorage;
typedef GrDrawTarget INHERITED;
};
#if GR_DEBUG
#define VALIDATE validate
#else
- #define VALIDATE()
+ static void VALIDATE(bool x = false) {}
#endif
+// page size
#define GrBufferAllocPool_MIN_BLOCK_SIZE ((size_t)1 << 12)
GrBufferAllocPool::GrBufferAllocPool(GrGpu* gpu,
fBufferPtr = NULL;
fMinBlockSize = GrMax(GrBufferAllocPool_MIN_BLOCK_SIZE, blockSize);
+ fBytesInUse = 0;
+
fPreallocBuffersInUse = 0;
fFirstPreallocBuffer = 0;
for (int i = 0; i < preallocBufferCnt; ++i) {
void GrBufferAllocPool::reset() {
VALIDATE();
+ fBytesInUse = 0;
if (fBlocks.count()) {
GrGeometryBuffer* buffer = fBlocks.back().fBuffer;
if (buffer->isLocked()) {
}
#if GR_DEBUG
-void GrBufferAllocPool::validate() const {
+void GrBufferAllocPool::validate(bool unusedBlockAllowed) const {
if (NULL != fBufferPtr) {
GrAssert(!fBlocks.empty());
if (fBlocks.back().fBuffer->isLocked()) {
} else {
GrAssert(fBlocks.empty() || !fBlocks.back().fBuffer->isLocked());
}
+ size_t bytesInUse = 0;
for (int i = 0; i < fBlocks.count() - 1; ++i) {
GrAssert(!fBlocks[i].fBuffer->isLocked());
}
+ for (int i = 0; i < fBlocks.count(); ++i) {
+ size_t bytes = fBlocks[i].fBuffer->size() - fBlocks[i].fBytesFree;
+ bytesInUse += bytes;
+ GrAssert(bytes || unusedBlockAllowed);
+ }
+
+ GrAssert(bytesInUse == fBytesInUse);
+ if (unusedBlockAllowed) {
+ GrAssert((fBytesInUse && !fBlocks.empty()) ||
+ (!fBytesInUse && (fBlocks.count() < 2)));
+ } else {
+ GrAssert((0 == fBytesInUse) == fBlocks.empty());
+ }
}
#endif
*offset = usedBytes;
*buffer = back.fBuffer;
back.fBytesFree -= size + pad;
+ fBytesInUse += size;
return (void*)(reinterpret_cast<intptr_t>(fBufferPtr) + usedBytes);
}
}
+ // We could honor the space request using updateSubData on the current VB
+ // (if there is room). But we don't currently use draw calls to GL that
+ // allow the driver to know that previously issued draws won't read from
+ // the part of the buffer we update.
+
if (!createBlock(size)) {
return NULL;
}
- VALIDATE();
GrAssert(NULL != fBufferPtr);
*offset = 0;
BufferBlock& back = fBlocks.back();
*buffer = back.fBuffer;
back.fBytesFree -= size;
+ fBytesInUse += size;
+ VALIDATE();
return fBufferPtr;
}
void GrBufferAllocPool::putBack(size_t bytes) {
VALIDATE();
- if (NULL != fBufferPtr) {
- BufferBlock& back = fBlocks.back();
- size_t bytesUsed = back.fBuffer->size() - back.fBytesFree;
+
+ while (bytes) {
+ // caller shouldnt try to put back more than they've taken
+ GrAssert(!fBlocks.empty());
+ BufferBlock& block = fBlocks.back();
+ size_t bytesUsed = block.fBuffer->size() - block.fBytesFree;
if (bytes >= bytesUsed) {
- destroyBlock();
bytes -= bytesUsed;
+ fBytesInUse -= bytesUsed;
+ destroyBlock();
} else {
- back.fBytesFree += bytes;
- return;
+ block.fBytesFree += bytes;
+ fBytesInUse -= bytes;
+ bytes = 0;
+ break;
}
}
VALIDATE();
- GrAssert(NULL == fBufferPtr);
- // we don't partially roll-back buffers because our VB semantics say locking
- // a VB discards its previous content.
- // We could honor it by being sure we use updateSubData and not lock
- // we will roll-back fully released buffers, though.
- while (!fBlocks.empty() &&
- bytes >= fBlocks.back().fBuffer->size()) {
- bytes -= fBlocks.back().fBuffer->size();
- destroyBlock();
- }
- VALIDATE();
}
bool GrBufferAllocPool::createBlock(size_t requestSize) {
fBufferPtr = fCpuData.realloc(size);
}
- VALIDATE();
+ VALIDATE(true);
return true;
}
void destroyBlock();
void flushCpuData(GrGeometryBuffer* buffer, size_t flushSize);
#if GR_DEBUG
- void validate() const;
+ void validate(bool unusedBlockAllowed = false) const;
#endif
+
+ size_t fBytesInUse;
GrGpu* fGpu;
bool fGpuIsReffed;
#include "GrDrawTarget.h"
#include "GrGpuVertex.h"
#include "GrTexture.h"
+#include "GrVertexBuffer.h"
+#include "GrIndexBuffer.h"
namespace {
////////////////////////////////////////////////////////////////////////////////
-GrDrawTarget::GrDrawTarget() {
+#define DEBUG_INVAL_BUFFER 0xdeadcafe
+#define DEBUG_INVAL_START_IDX -1
+
+GrDrawTarget::GrDrawTarget()
+: fGeoSrcStateStack(&fGeoSrcStateStackStorage) {
#if GR_DEBUG
VertexLayoutUnitTest();
#endif
- fReservedGeometry.fLocked = false;
+ GeometrySrcState& geoSrc = fGeoSrcStateStack.push_back();
#if GR_DEBUG
- fReservedGeometry.fVertexCount = ~0;
- fReservedGeometry.fIndexCount = ~0;
+ geoSrc.fVertexCount = DEBUG_INVAL_START_IDX;
+ geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
+ geoSrc.fIndexCount = DEBUG_INVAL_START_IDX;
+ geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
#endif
- fGeometrySrc.fVertexSrc = kReserved_GeometrySrcType;
- fGeometrySrc.fIndexSrc = kReserved_GeometrySrcType;
+ geoSrc.fVertexSrc = kNone_GeometrySrcType;
+ geoSrc.fIndexSrc = kNone_GeometrySrcType;
+}
+
+GrDrawTarget::~GrDrawTarget() {
+ int popCnt = fGeoSrcStateStack.count() - 1;
+ while (popCnt) {
+ this->popGeometrySource();
+ --popCnt;
+ }
+ this->releasePreviousVertexSource();
+ this->releasePreviousIndexSource();
}
void GrDrawTarget::setClip(const GrClip& clip) {
fCurrDrawState = srcTarget.fCurrDrawState;
}
+bool GrDrawTarget::reserveVertexSpace(GrVertexLayout vertexLayout,
+ int vertexCount,
+ void** vertices) {
+ GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+ bool acquired = false;
+ if (vertexCount > 0) {
+ GrAssert(NULL != vertices);
+ this->releasePreviousVertexSource();
+ geoSrc.fVertexSrc = kNone_GeometrySrcType;
-bool GrDrawTarget::reserveAndLockGeometry(GrVertexLayout vertexLayout,
- uint32_t vertexCount,
- uint32_t indexCount,
- void** vertices,
- void** indices) {
- GrAssert(!fReservedGeometry.fLocked);
- fReservedGeometry.fVertexCount = vertexCount;
- fReservedGeometry.fIndexCount = indexCount;
-
- fReservedGeometry.fLocked = this->onAcquireGeometry(vertexLayout,
- vertices,
- indices);
- if (fReservedGeometry.fLocked) {
- if (vertexCount) {
- fGeometrySrc.fVertexSrc = kReserved_GeometrySrcType;
- fGeometrySrc.fVertexLayout = vertexLayout;
- } else if (NULL != vertices) {
- *vertices = NULL;
- }
- if (indexCount) {
- fGeometrySrc.fIndexSrc = kReserved_GeometrySrcType;
- } else if (NULL != indices) {
- *indices = NULL;
- }
+ acquired = this->onReserveVertexSpace(vertexLayout,
+ vertexCount,
+ vertices);
+ }
+ if (acquired) {
+ geoSrc.fVertexSrc = kReserved_GeometrySrcType;
+ geoSrc.fVertexCount = vertexCount;
+ geoSrc.fVertexLayout = vertexLayout;
+ } else if (NULL != vertices) {
+ *vertices = NULL;
+ }
+ return acquired;
+}
+
+bool GrDrawTarget::reserveIndexSpace(int indexCount,
+ void** indices) {
+ GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+ bool acquired = false;
+ if (indexCount > 0) {
+ GrAssert(NULL != indices);
+ this->releasePreviousIndexSource();
+ geoSrc.fIndexSrc = kNone_GeometrySrcType;
+
+ acquired = this->onReserveIndexSpace(indexCount, indices);
}
- return fReservedGeometry.fLocked;
+ if (acquired) {
+ geoSrc.fIndexSrc = kReserved_GeometrySrcType;
+ geoSrc.fIndexCount = indexCount;
+ } else if (NULL != indices) {
+ *indices = NULL;
+ }
+ return acquired;
+
}
bool GrDrawTarget::geometryHints(GrVertexLayout vertexLayout,
int32_t* vertexCount,
int32_t* indexCount) const {
- GrAssert(!fReservedGeometry.fLocked);
if (NULL != vertexCount) {
*vertexCount = -1;
}
return false;
}
-void GrDrawTarget::releaseReservedGeometry() {
- GrAssert(fReservedGeometry.fLocked);
- this->onReleaseGeometry();
- fReservedGeometry.fLocked = false;
+void GrDrawTarget::releasePreviousVertexSource() {
+ GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+ switch (geoSrc.fVertexSrc) {
+ case kNone_GeometrySrcType:
+ break;
+ case kArray_GeometrySrcType:
+ this->releaseVertexArray();
+ break;
+ case kReserved_GeometrySrcType:
+ this->releaseReservedVertexSpace();
+ break;
+ case kBuffer_GeometrySrcType:
+ geoSrc.fVertexBuffer->unref();
+#if GR_DEBUG
+ geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
+#endif
+ break;
+ default:
+ GrCrash("Unknown Vertex Source Type.");
+ break;
+ }
+}
+
+void GrDrawTarget::releasePreviousIndexSource() {
+ GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+ switch (geoSrc.fIndexSrc) {
+ case kNone_GeometrySrcType: // these two don't require
+ break;
+ case kArray_GeometrySrcType:
+ this->releaseIndexArray();
+ break;
+ case kReserved_GeometrySrcType:
+ this->releaseReservedIndexSpace();
+ break;
+ case kBuffer_GeometrySrcType:
+ geoSrc.fIndexBuffer->unref();
+#if GR_DEBUG
+ geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
+#endif
+ break;
+ default:
+ GrCrash("Unknown Index Source Type.");
+ break;
+ }
}
void GrDrawTarget::setVertexSourceToArray(GrVertexLayout vertexLayout,
const void* vertexArray,
int vertexCount) {
- fGeometrySrc.fVertexSrc = kArray_GeometrySrcType;
- fGeometrySrc.fVertexLayout = vertexLayout;
+ this->releasePreviousVertexSource();
+ GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+ geoSrc.fVertexSrc = kArray_GeometrySrcType;
+ geoSrc.fVertexLayout = vertexLayout;
+ geoSrc.fVertexCount = vertexCount;
this->onSetVertexSourceToArray(vertexArray, vertexCount);
}
void GrDrawTarget::setIndexSourceToArray(const void* indexArray,
int indexCount) {
- fGeometrySrc.fIndexSrc = kArray_GeometrySrcType;
+ this->releasePreviousIndexSource();
+ GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+ geoSrc.fIndexSrc = kArray_GeometrySrcType;
+ geoSrc.fIndexCount = indexCount;
this->onSetIndexSourceToArray(indexArray, indexCount);
}
void GrDrawTarget::setVertexSourceToBuffer(GrVertexLayout vertexLayout,
const GrVertexBuffer* buffer) {
- fGeometrySrc.fVertexSrc = kBuffer_GeometrySrcType;
- fGeometrySrc.fVertexBuffer = buffer;
- fGeometrySrc.fVertexLayout = vertexLayout;
+ this->releasePreviousVertexSource();
+ GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+ geoSrc.fVertexSrc = kBuffer_GeometrySrcType;
+ geoSrc.fVertexBuffer = buffer;
+ buffer->ref();
+ geoSrc.fVertexLayout = vertexLayout;
}
void GrDrawTarget::setIndexSourceToBuffer(const GrIndexBuffer* buffer) {
- fGeometrySrc.fIndexSrc = kBuffer_GeometrySrcType;
- fGeometrySrc.fIndexBuffer = buffer;
+ this->releasePreviousIndexSource();
+ GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+ geoSrc.fIndexSrc = kBuffer_GeometrySrcType;
+ geoSrc.fIndexBuffer = buffer;
+ buffer->ref();
}
-///////////////////////////////////////////////////////////////////////////////
+void GrDrawTarget::resetVertexSource() {
+ this->releasePreviousVertexSource();
+ GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+ geoSrc.fVertexSrc = kNone_GeometrySrcType;
+}
+
+void GrDrawTarget::resetIndexSource() {
+ this->releasePreviousIndexSource();
+ GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+ geoSrc.fIndexSrc = kNone_GeometrySrcType;
+}
+
+void GrDrawTarget::pushGeometrySource() {
+ this->geometrySourceWillPush();
+ GeometrySrcState& newState = fGeoSrcStateStack.push_back();
+ newState.fIndexSrc = kNone_GeometrySrcType;
+ newState.fVertexSrc = kNone_GeometrySrcType;
+#if GR_DEBUG
+ newState.fVertexCount = ~0;
+ newState.fVertexBuffer = (GrVertexBuffer*)~0;
+ newState.fIndexCount = ~0;
+ newState.fIndexBuffer = (GrIndexBuffer*)~0;
+#endif
+}
+
+void GrDrawTarget::popGeometrySource() {
+ const GeometrySrcState& geoSrc = this->getGeomSrc();
+ // if popping last element then pops are unbalanced with pushes
+ GrAssert(fGeoSrcStateStack.count() > 1);
+
+ this->geometrySourceWillPop(fGeoSrcStateStack.fromBack(1));
+ this->releasePreviousVertexSource();
+ this->releasePreviousIndexSource();
+ fGeoSrcStateStack.pop_back();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void GrDrawTarget::drawIndexed(GrPrimitiveType type, int startVertex,
+ int startIndex, int vertexCount,
+ int indexCount) {
+#if GR_DEBUG
+ GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+ int maxVertex = startVertex + vertexCount;
+ int maxValidVertex;
+ switch (geoSrc.fVertexSrc) {
+ case kNone_GeometrySrcType:
+ GrCrash("Attempting to draw indexed geom without vertex src.");
+ case kReserved_GeometrySrcType: // fallthrough
+ case kArray_GeometrySrcType:
+ maxValidVertex = geoSrc.fVertexCount;
+ break;
+ case kBuffer_GeometrySrcType:
+ maxValidVertex = geoSrc.fVertexBuffer->size() /
+ VertexSize(geoSrc.fVertexLayout);
+ break;
+ }
+ if (maxVertex > maxValidVertex) {
+ GrCrash("Indexed drawing outside valid vertex range.");
+ }
+ int maxIndex = startIndex + indexCount;
+ int maxValidIndex;
+ switch (geoSrc.fIndexSrc) {
+ case kNone_GeometrySrcType:
+ GrCrash("Attempting to draw indexed geom without index src.");
+ case kReserved_GeometrySrcType: // fallthrough
+ case kArray_GeometrySrcType:
+ maxValidIndex = geoSrc.fIndexCount;
+ break;
+ case kBuffer_GeometrySrcType:
+ maxValidIndex = geoSrc.fIndexBuffer->size() / sizeof(uint16_t);
+ break;
+ }
+ if (maxIndex > maxValidIndex) {
+ GrCrash("Indexed drawing outside valid index range.");
+ }
+#endif
+ this->onDrawIndexed(type, startVertex, startIndex,
+ vertexCount, indexCount);
+}
+
+
+void GrDrawTarget::drawNonIndexed(GrPrimitiveType type,
+ int startVertex,
+ int vertexCount) {
+#if GR_DEBUG
+ GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+ int maxVertex = startVertex + vertexCount;
+ int maxValidVertex;
+ switch (geoSrc.fVertexSrc) {
+ case kNone_GeometrySrcType:
+ GrCrash("Attempting to draw non-indexed geom without vertex src.");
+ case kReserved_GeometrySrcType: // fallthrough
+ case kArray_GeometrySrcType:
+ maxValidVertex = geoSrc.fVertexCount;
+ break;
+ case kBuffer_GeometrySrcType:
+ maxValidVertex = geoSrc.fVertexBuffer->size() /
+ VertexSize(geoSrc.fVertexLayout);
+ break;
+ }
+ if (maxVertex > maxValidVertex) {
+ GrCrash("Non-indexed drawing outside valid vertex range.");
+ }
+#endif
+ this->onDrawNonIndexed(type, startVertex, vertexCount);
+}
+
+////////////////////////////////////////////////////////////////////////////////
bool GrDrawTarget::canDisableBlend() const {
// If we compute a coverage value (using edge AA or a coverage stage) then
}
// If we have vertex color without alpha then we can't force blend off
- if ((fGeometrySrc.fVertexLayout & kColor_VertexLayoutBit) ||
+ if ((this->getGeomSrc().fVertexLayout & kColor_VertexLayoutBit) ||
0xff != GrColorUnpackA(fCurrDrawState.fColor)) {
return false;
}
}
-///////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
void GrDrawTarget::drawRect(const GrRect& rect,
const GrMatrix* matrix,
StageBitfield stageEnableBitfield,
}
}
-///////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
GrDrawTarget::AutoStateRestore::AutoStateRestore() {
fDrawTarget = NULL;
}
}
-///////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
GrDrawTarget::AutoDeviceCoordDraw::AutoDeviceCoordDraw(GrDrawTarget* target,
int stageMask) {
}
}
+////////////////////////////////////////////////////////////////////////////////
+
+GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry(
+ GrDrawTarget* target,
+ GrVertexLayout vertexLayout,
+ int vertexCount,
+ int indexCount) {
+ fTarget = NULL;
+ this->set(target, vertexLayout, vertexCount, indexCount);
+}
+
+GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry() {
+ fTarget = NULL;
+}
+
+GrDrawTarget::AutoReleaseGeometry::~AutoReleaseGeometry() {
+ this->reset();
+}
+
+bool GrDrawTarget::AutoReleaseGeometry::set(GrDrawTarget* target,
+ GrVertexLayout vertexLayout,
+ int vertexCount,
+ int indexCount) {
+ this->reset();
+ fTarget = target;
+ bool success = true;
+ if (NULL != fTarget) {
+ fTarget = target;
+ if (vertexCount > 0) {
+ success = target->reserveVertexSpace(vertexLayout,
+ vertexCount,
+ &fVertices);
+ if (!success) {
+ this->reset();
+ }
+ }
+ if (success && indexCount > 0) {
+ success = target->reserveIndexSpace(indexCount, &fIndices);
+ if (!success) {
+ this->reset();
+ }
+ }
+ }
+ GrAssert(success == (NULL != fTarget));
+ return success;
+}
+
+void GrDrawTarget::AutoReleaseGeometry::reset() {
+ if (NULL != fTarget) {
+ if (NULL != fVertices) {
+ fTarget->resetVertexSource();
+ }
+ if (NULL != fIndices) {
+ fTarget->resetIndexSource();
+ }
+ fTarget = NULL;
+ }
+}
+
extern void gr_run_unittests();
+#define DEBUG_INVAL_BUFFER 0xdeadcafe
+#define DEBUG_INVAL_START_IDX -1
+
GrGpu::GrGpu()
: f8bitPaletteSupport(false)
- , fCurrPoolVertexBuffer(NULL)
- , fCurrPoolStartVertex(0)
- , fCurrPoolIndexBuffer(NULL)
- , fCurrPoolStartIndex(0)
, fContext(NULL)
, fVertexPool(NULL)
, fIndexPool(NULL)
+ , fVertexPoolUseCnt(0)
+ , fIndexPoolUseCnt(0)
+ , fGeomPoolStateStack(&fGeoSrcStateStackStorage)
, fQuadIndexBuffer(NULL)
, fUnitSquareVertexBuffer(NULL)
, fDefaultPathRenderer(NULL)
, fClientPathRenderer(NULL)
, fContextIsDirty(true)
- , fVertexPoolInUse(false)
- , fIndexPoolInUse(false)
, fResourceHead(NULL) {
#if GR_DEBUG
//gr_run_unittests();
#endif
+
+ fGeomPoolStateStack.push_back();
+#if GR_DEBUG
+ GeometryPoolState& poolState = fGeomPoolStateStack.back();
+ poolState.fPoolVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
+ poolState.fPoolStartVertex = DEBUG_INVAL_START_IDX;
+ poolState.fPoolIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
+ poolState.fPoolStartIndex = DEBUG_INVAL_START_IDX;
+#endif
resetStats();
}
fClip.setFromRect(bounds);
AutoStateRestore asr(this);
- AutoInternalDrawGeomRestore aidgr(this);
+ AutoGeometryPush agp(this);
this->setViewMatrix(GrMatrix::I());
this->clearStencilClip(clipRect);
////////////////////////////////////////////////////////////////////////////////
-void GrGpu::drawIndexed(GrPrimitiveType type,
- int startVertex,
- int startIndex,
- int vertexCount,
- int indexCount) {
- GrAssert(kReserved_GeometrySrcType != fGeometrySrc.fVertexSrc ||
- fReservedGeometry.fLocked);
- GrAssert(kReserved_GeometrySrcType != fGeometrySrc.fIndexSrc ||
- fReservedGeometry.fLocked);
+void GrGpu::geometrySourceWillPush() {
+ const GeometrySrcState& geoSrc = this->getGeomSrc();
+ if (kArray_GeometrySrcType == geoSrc.fVertexSrc ||
+ kReserved_GeometrySrcType == geoSrc.fVertexSrc) {
+ this->finalizeReservedVertices();
+ }
+ if (kArray_GeometrySrcType == geoSrc.fIndexSrc ||
+ kReserved_GeometrySrcType == geoSrc.fIndexSrc) {
+ this->finalizeReservedIndices();
+ }
+ GeometryPoolState& newState = fGeomPoolStateStack.push_back();
+#if GR_DEBUG
+ newState.fPoolVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
+ newState.fPoolStartVertex = DEBUG_INVAL_START_IDX;
+ newState.fPoolIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
+ newState.fPoolStartIndex = DEBUG_INVAL_START_IDX;
+#endif
+}
+
+void GrGpu::geometrySourceWillPop(const GeometrySrcState& restoredState) {
+ // if popping last entry then pops are unbalanced with pushes
+ GrAssert(fGeomPoolStateStack.count() > 1);
+ fGeomPoolStateStack.pop_back();
+}
+
+void GrGpu::onDrawIndexed(GrPrimitiveType type,
+ int startVertex,
+ int startIndex,
+ int vertexCount,
+ int indexCount) {
this->handleDirtyContext();
int sIndex = startIndex;
setupGeometry(&sVertex, &sIndex, vertexCount, indexCount);
- this->onDrawIndexed(type, sVertex, sIndex,
- vertexCount, indexCount);
+ this->onGpuDrawIndexed(type, sVertex, sIndex,
+ vertexCount, indexCount);
}
-void GrGpu::drawNonIndexed(GrPrimitiveType type,
+void GrGpu::onDrawNonIndexed(GrPrimitiveType type,
int startVertex,
int vertexCount) {
- GrAssert(kReserved_GeometrySrcType != fGeometrySrc.fVertexSrc ||
- fReservedGeometry.fLocked);
-
this->handleDirtyContext();
if (!this->setupClipAndFlushState(type)) {
int sVertex = startVertex;
setupGeometry(&sVertex, NULL, vertexCount, 0);
- this->onDrawNonIndexed(type, sVertex, vertexCount);
+ this->onGpuDrawNonIndexed(type, sVertex, vertexCount);
}
void GrGpu::finalizeReservedVertices() {
void GrGpu::prepareVertexPool() {
if (NULL == fVertexPool) {
+ GrAssert(0 == fVertexPoolUseCnt);
fVertexPool = new GrVertexBufferAllocPool(this, true,
VERTEX_POOL_VB_SIZE,
VERTEX_POOL_VB_COUNT);
fVertexPool->releaseGpuRef();
- } else if (!fVertexPoolInUse) {
+ } else if (!fVertexPoolUseCnt) {
// the client doesn't have valid data in the pool
fVertexPool->reset();
}
void GrGpu::prepareIndexPool() {
if (NULL == fIndexPool) {
+ GrAssert(0 == fIndexPoolUseCnt);
fIndexPool = new GrIndexBufferAllocPool(this, true, 0, 1);
fIndexPool->releaseGpuRef();
- } else if (!fIndexPoolInUse) {
+ } else if (!fIndexPoolUseCnt) {
// the client doesn't have valid data in the pool
fIndexPool->reset();
}
}
-bool GrGpu::onAcquireGeometry(GrVertexLayout vertexLayout,
- void** vertices,
- void** indices) {
- GrAssert(!fReservedGeometry.fLocked);
- size_t reservedVertexSpace = 0;
+bool GrGpu::onReserveVertexSpace(GrVertexLayout vertexLayout,
+ int vertexCount,
+ void** vertices) {
+ GeometryPoolState& geomPoolState = fGeomPoolStateStack.back();
+
+ GrAssert(vertexCount > 0);
+ GrAssert(NULL != vertices);
+
+ this->prepareVertexPool();
+
+ *vertices = fVertexPool->makeSpace(vertexLayout,
+ vertexCount,
+ &geomPoolState.fPoolVertexBuffer,
+ &geomPoolState.fPoolStartVertex);
+ if (NULL == *vertices) {
+ return false;
+ }
+ ++fVertexPoolUseCnt;
+ return true;
+}
- if (fReservedGeometry.fVertexCount) {
- GrAssert(NULL != vertices);
+bool GrGpu::onReserveIndexSpace(int indexCount, void** indices) {
+ GeometryPoolState& geomPoolState = fGeomPoolStateStack.back();
+
+ GrAssert(indexCount > 0);
+ GrAssert(NULL != indices);
- this->prepareVertexPool();
+ this->prepareIndexPool();
- *vertices = fVertexPool->makeSpace(vertexLayout,
- fReservedGeometry.fVertexCount,
- &fCurrPoolVertexBuffer,
- &fCurrPoolStartVertex);
- if (NULL == *vertices) {
- return false;
- }
- reservedVertexSpace = VertexSize(vertexLayout) *
- fReservedGeometry.fVertexCount;
- }
- if (fReservedGeometry.fIndexCount) {
- GrAssert(NULL != indices);
-
- this->prepareIndexPool();
-
- *indices = fIndexPool->makeSpace(fReservedGeometry.fIndexCount,
- &fCurrPoolIndexBuffer,
- &fCurrPoolStartIndex);
- if (NULL == *indices) {
- fVertexPool->putBack(reservedVertexSpace);
- fCurrPoolVertexBuffer = NULL;
- return false;
- }
+ *indices = fIndexPool->makeSpace(indexCount,
+ &geomPoolState.fPoolIndexBuffer,
+ &geomPoolState.fPoolStartIndex);
+ if (NULL == *indices) {
+ return false;
}
+ ++fIndexPoolUseCnt;
return true;
}
-void GrGpu::onReleaseGeometry() {}
+void GrGpu::releaseReservedVertexSpace() {
+ const GeometrySrcState& geoSrc = this->getGeomSrc();
+ GrAssert(kReserved_GeometrySrcType == geoSrc.fVertexSrc);
+ size_t bytes = geoSrc.fVertexCount * VertexSize(geoSrc.fVertexLayout);
+ fVertexPool->putBack(bytes);
+ --fVertexPoolUseCnt;
+}
+
+void GrGpu::releaseReservedIndexSpace() {
+ const GeometrySrcState& geoSrc = this->getGeomSrc();
+ GrAssert(kReserved_GeometrySrcType == geoSrc.fIndexSrc);
+ size_t bytes = geoSrc.fIndexCount * sizeof(uint16_t);
+ fIndexPool->putBack(bytes);
+ --fIndexPoolUseCnt;
+}
void GrGpu::onSetVertexSourceToArray(const void* vertexArray, int vertexCount) {
- GrAssert(!fReservedGeometry.fLocked || !fReservedGeometry.fVertexCount);
this->prepareVertexPool();
+ GeometryPoolState& geomPoolState = fGeomPoolStateStack.back();
#if GR_DEBUG
bool success =
#endif
- fVertexPool->appendVertices(fGeometrySrc.fVertexLayout,
+ fVertexPool->appendVertices(this->getGeomSrc().fVertexLayout,
vertexCount,
vertexArray,
- &fCurrPoolVertexBuffer,
- &fCurrPoolStartVertex);
+ &geomPoolState.fPoolVertexBuffer,
+ &geomPoolState.fPoolStartVertex);
+ ++fVertexPoolUseCnt;
GR_DEBUGASSERT(success);
}
void GrGpu::onSetIndexSourceToArray(const void* indexArray, int indexCount) {
- GrAssert(!fReservedGeometry.fLocked || !fReservedGeometry.fIndexCount);
this->prepareIndexPool();
+ GeometryPoolState& geomPoolState = fGeomPoolStateStack.back();
#if GR_DEBUG
bool success =
#endif
fIndexPool->appendIndices(indexCount,
indexArray,
- &fCurrPoolIndexBuffer,
- &fCurrPoolStartIndex);
+ &geomPoolState.fPoolIndexBuffer,
+ &geomPoolState.fPoolStartIndex);
+ ++fIndexPoolUseCnt;
GR_DEBUGASSERT(success);
}
+void GrGpu::releaseVertexArray() {
+ // if vertex source was array, we stowed data in the pool
+ const GeometrySrcState& geoSrc = this->getGeomSrc();
+ GrAssert(kArray_GeometrySrcType == geoSrc.fVertexSrc);
+ size_t bytes = geoSrc.fVertexCount * VertexSize(geoSrc.fVertexLayout);
+ fVertexPool->putBack(bytes);
+ --fVertexPoolUseCnt;
+}
+
+void GrGpu::releaseIndexArray() {
+ // if index source was array, we stowed data in the pool
+ const GeometrySrcState& geoSrc = this->getGeomSrc();
+ GrAssert(kArray_GeometrySrcType == geoSrc.fIndexSrc);
+ size_t bytes = geoSrc.fIndexCount * sizeof(uint16_t);
+ fIndexPool->putBack(bytes);
+ --fIndexPoolUseCnt;
+}
+
////////////////////////////////////////////////////////////////////////////////
const GrGpuStats& GrGpu::getStats() const {
#endif
#endif
-void GrGpuGL::onDrawIndexed(GrPrimitiveType type,
- uint32_t startVertex,
- uint32_t startIndex,
- uint32_t vertexCount,
- uint32_t indexCount) {
+void GrGpuGL::onGpuDrawIndexed(GrPrimitiveType type,
+ uint32_t startVertex,
+ uint32_t startIndex,
+ uint32_t vertexCount,
+ uint32_t indexCount) {
GrAssert((size_t)type < GR_ARRAY_COUNT(gPrimitiveType2GLMode));
GrGLvoid* indices = (GrGLvoid*)(sizeof(uint16_t) * startIndex);
#endif
}
-void GrGpuGL::onDrawNonIndexed(GrPrimitiveType type,
- uint32_t startVertex,
- uint32_t vertexCount) {
+void GrGpuGL::onGpuDrawNonIndexed(GrPrimitiveType type,
+ uint32_t startVertex,
+ uint32_t vertexCount) {
GrAssert((size_t)type < GR_ARRAY_COUNT(gPrimitiveType2GLMode));
GrAssert(NULL != fHWGeometryState.fVertexBuffer);
}
void GrGpuGL::notifyIndexBufferBind(const GrGLIndexBuffer* buffer) {
- fGeometrySrc.fIndexBuffer = buffer;
+ fHWGeometryState.fIndexBuffer = buffer;
}
void GrGpuGL::notifyIndexBufferDelete(const GrGLIndexBuffer* buffer) {
GrAssert(NULL != extraVertexOffset);
+ const GeometryPoolState& geoPoolState = this->getGeomPoolState();
+
GrGLVertexBuffer* vbuf;
- switch (fGeometrySrc.fVertexSrc) {
+ switch (this->getGeomSrc().fVertexSrc) {
case kBuffer_GeometrySrcType:
*extraVertexOffset = 0;
- vbuf = (GrGLVertexBuffer*) fGeometrySrc.fVertexBuffer;
+ vbuf = (GrGLVertexBuffer*) this->getGeomSrc().fVertexBuffer;
break;
case kArray_GeometrySrcType:
case kReserved_GeometrySrcType:
- finalizeReservedVertices();
- *extraVertexOffset = fCurrPoolStartVertex;
- vbuf = (GrGLVertexBuffer*) fCurrPoolVertexBuffer;
+ this->finalizeReservedVertices();
+ *extraVertexOffset = geoPoolState.fPoolStartVertex;
+ vbuf = (GrGLVertexBuffer*) geoPoolState.fPoolVertexBuffer;
break;
default:
vbuf = NULL; // suppress warning
GrAssert(NULL != extraIndexOffset);
GrGLIndexBuffer* ibuf;
- switch (fGeometrySrc.fIndexSrc) {
+ switch (this->getGeomSrc().fIndexSrc) {
case kBuffer_GeometrySrcType:
*extraIndexOffset = 0;
- ibuf = (GrGLIndexBuffer*)fGeometrySrc.fIndexBuffer;
+ ibuf = (GrGLIndexBuffer*)this->getGeomSrc().fIndexBuffer;
break;
case kArray_GeometrySrcType:
case kReserved_GeometrySrcType:
- finalizeReservedIndices();
- *extraIndexOffset = fCurrPoolStartIndex;
- ibuf = (GrGLIndexBuffer*) fCurrPoolIndexBuffer;
+ this->finalizeReservedIndices();
+ *extraIndexOffset = geoPoolState.fPoolStartIndex;
+ ibuf = (GrGLIndexBuffer*) geoPoolState.fPoolIndexBuffer;
break;
default:
ibuf = NULL; // suppress warning
int left, int top, int width, int height,
GrPixelConfig, void* buffer);
- virtual void onDrawIndexed(GrPrimitiveType type,
- uint32_t startVertex,
- uint32_t startIndex,
- uint32_t vertexCount,
- uint32_t indexCount);
- virtual void onDrawNonIndexed(GrPrimitiveType type,
- uint32_t vertexCount,
- uint32_t numVertices);
+ virtual void onGpuDrawIndexed(GrPrimitiveType type,
+ uint32_t startVertex,
+ uint32_t startIndex,
+ uint32_t vertexCount,
+ uint32_t indexCount);
+ virtual void onGpuDrawNonIndexed(GrPrimitiveType type,
+ uint32_t vertexCount,
+ uint32_t numVertices);
virtual void flushScissor(const GrIRect* rect);
void clearStencil(uint32_t value, uint32_t mask);
virtual void clearStencilClip(const GrIRect& rect);
}
}
- uint32_t vertColor = (fGeometrySrc.fVertexLayout & kColor_VertexLayoutBit);
+ uint32_t vertColor = (this->getGeomSrc().fVertexLayout & kColor_VertexLayoutBit);
uint32_t prevVertColor = (fHWGeometryState.fVertexLayout &
kColor_VertexLayoutBit);
int newColorOffset;
int newTexCoordOffsets[kNumStages];
- GrGLsizei newStride = VertexSizeAndOffsetsByStage(fGeometrySrc.fVertexLayout,
+ GrGLsizei newStride = VertexSizeAndOffsetsByStage(this->getGeomSrc().fVertexLayout,
newTexCoordOffsets,
&newColorOffset);
int oldColorOffset;
setBuffers(indexed, &extraVertexOffset, &extraIndexOffset);
GrGLenum scalarType;
- if (fGeometrySrc.fVertexLayout & kTextFormat_VertexLayoutBit) {
+ if (this->getGeomSrc().fVertexLayout & kTextFormat_VertexLayoutBit) {
scalarType = GrGLTextType;
} else {
scalarType = GrGLType;
((GrGLTextType != GrGLType) &&
(kTextFormat_VertexLayoutBit &
(fHWGeometryState.fVertexLayout ^
- fGeometrySrc.fVertexLayout)));
+ this->getGeomSrc().fVertexLayout)));
if (posAndTexChange) {
GR_GL(VertexPointer(2, scalarType, newStride, (GrGLvoid*)vertexOffset));
GR_GL(DisableClientState(GR_GL_COLOR_ARRAY));
}
- fHWGeometryState.fVertexLayout = fGeometrySrc.fVertexLayout;
+ fHWGeometryState.fVertexLayout = this->getGeomSrc().fVertexLayout;
fHWGeometryState.fArrayPtrsDirty = false;
}
void GrGpuGLShaders::flushColor() {
const GrGLProgram::ProgramDesc& desc = fCurrentProgram.getDesc();
- if (fGeometrySrc.fVertexLayout & kColor_VertexLayoutBit) {
+ if (this->getGeomSrc().fVertexLayout & kColor_VertexLayoutBit) {
// color will be specified per-vertex as an attribute
// invalidate the const vertex attrib color
fHWDrawState.fColor = GrColor_ILLEGAL;
int newColorOffset;
int newTexCoordOffsets[kMaxTexCoords];
- GrGLsizei newStride = VertexSizeAndOffsetsByIdx(fGeometrySrc.fVertexLayout,
- newTexCoordOffsets,
- &newColorOffset);
+ GrGLsizei newStride = VertexSizeAndOffsetsByIdx(
+ this->getGeomSrc().fVertexLayout,
+ newTexCoordOffsets,
+ &newColorOffset);
int oldColorOffset;
int oldTexCoordOffsets[kMaxTexCoords];
- GrGLsizei oldStride = VertexSizeAndOffsetsByIdx(fHWGeometryState.fVertexLayout,
- oldTexCoordOffsets,
- &oldColorOffset);
+ GrGLsizei oldStride = VertexSizeAndOffsetsByIdx(
+ fHWGeometryState.fVertexLayout,
+ oldTexCoordOffsets,
+ &oldColorOffset);
bool indexed = NULL != startIndex;
int extraVertexOffset;
int extraIndexOffset;
- setBuffers(indexed, &extraVertexOffset, &extraIndexOffset);
+ this->setBuffers(indexed, &extraVertexOffset, &extraIndexOffset);
GrGLenum scalarType;
bool texCoordNorm;
- if (fGeometrySrc.fVertexLayout & kTextFormat_VertexLayoutBit) {
+ if (this->getGeomSrc().fVertexLayout & kTextFormat_VertexLayoutBit) {
scalarType = GrGLTextType;
texCoordNorm = GR_GL_TEXT_TEXTURE_NORMALIZED;
} else {
(((GrGLTextType != GrGLType) || GR_GL_TEXT_TEXTURE_NORMALIZED) &&
(kTextFormat_VertexLayoutBit &
(fHWGeometryState.fVertexLayout ^
- fGeometrySrc.fVertexLayout)));
+ this->getGeomSrc().fVertexLayout)));
if (posAndTexChange) {
int idx = GrGLProgram::PositionAttributeIdx();
GR_GL(DisableVertexAttribArray(GrGLProgram::ColorAttributeIdx()));
}
- fHWGeometryState.fVertexLayout = fGeometrySrc.fVertexLayout;
+ fHWGeometryState.fVertexLayout = this->getGeomSrc().fVertexLayout;
fHWGeometryState.fArrayPtrsDirty = false;
}
GrGLProgram::ProgramDesc& desc = fCurrentProgram.fProgramDesc;
// Must initialize all fields or cache will have false negatives!
- desc.fVertexLayout = fGeometrySrc.fVertexLayout;
+ desc.fVertexLayout = this->getGeomSrc().fVertexLayout;
desc.fEmitsPointSize = kPoints_PrimitiveType == type;
#include "GrGpu.h"
GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrVertexBufferAllocPool* vertexPool,
- GrIndexBufferAllocPool* indexPool) :
- fDraws(&fDrawStorage),
- fStates(&fStateStorage),
- fClears(&fClearStorage),
- fClips(&fClipStorage),
- fClipSet(true),
-
- fLastRectVertexLayout(0),
- fQuadIndexBuffer(NULL),
- fMaxQuads(0),
- fCurrQuad(0),
-
- fVertexPool(*vertexPool),
- fCurrPoolVertexBuffer(NULL),
- fCurrPoolStartVertex(0),
- fIndexPool(*indexPool),
- fCurrPoolIndexBuffer(NULL),
- fCurrPoolStartIndex(0),
- fReservedVertexBytes(0),
- fReservedIndexBytes(0),
- fUsedReservedVertexBytes(0),
- fUsedReservedIndexBytes(0) {
+ GrIndexBufferAllocPool* indexPool)
+ : fDraws(&fDrawStorage)
+ , fStates(&fStateStorage)
+ , fClears(&fClearStorage)
+ , fClips(&fClipStorage)
+ , fClipSet(true)
+
+ , fLastRectVertexLayout(0)
+ , fQuadIndexBuffer(NULL)
+ , fMaxQuads(0)
+ , fCurrQuad(0)
+
+ , fVertexPool(*vertexPool)
+ , fIndexPool(*indexPool)
+ , fGeoPoolStateStack(&fGeoStackStorage) {
+
GrAssert(NULL != vertexPool);
GrAssert(NULL != indexPool);
+
+ GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
+ poolState.fUsedPoolVertexBytes = 0;
+ poolState.fUsedPoolIndexBytes = 0;
+#if GR_DEBUG
+ poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
+ poolState.fPoolStartVertex = ~0;
+ poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
+ poolState.fPoolStartIndex = ~0;
+#endif
}
GrInOrderDrawBuffer::~GrInOrderDrawBuffer() {
GrAssert(0 == lastDraw.fIndexCount % 6);
GrAssert(0 == lastDraw.fStartIndex);
+ GeometryPoolState& poolState = fGeoPoolStateStack.back();
bool clearSinceLastDraw =
fClears.count() &&
fClears.back().fBeforeDrawIdx == fDraws.count();
- appendToPreviousDraw = !clearSinceLastDraw &&
- lastDraw.fVertexBuffer == fCurrPoolVertexBuffer &&
- (fCurrQuad * 4 + lastDraw.fStartVertex) == fCurrPoolStartVertex;
+ appendToPreviousDraw =
+ !clearSinceLastDraw &&
+ lastDraw.fVertexBuffer == poolState.fPoolVertexBuffer &&
+ (fCurrQuad * 4 + lastDraw.fStartVertex) == poolState.fPoolStartVertex;
+
if (appendToPreviousDraw) {
lastDraw.fVertexCount += 4;
lastDraw.fIndexCount += 6;
fCurrQuad += 1;
- GrAssert(0 == fUsedReservedVertexBytes);
- fUsedReservedVertexBytes = 4 * vsize;
+ // we reserved above, so we should be the first
+ // use of this vertex reserveation.
+ GrAssert(0 == poolState.fUsedPoolVertexBytes);
+ poolState.fUsedPoolVertexBytes = 4 * vsize;
}
}
if (!appendToPreviousDraw) {
}
}
-void GrInOrderDrawBuffer::drawIndexed(GrPrimitiveType primitiveType,
- int startVertex,
- int startIndex,
- int vertexCount,
- int indexCount) {
+void GrInOrderDrawBuffer::onDrawIndexed(GrPrimitiveType primitiveType,
+ int startVertex,
+ int startIndex,
+ int vertexCount,
+ int indexCount) {
if (!vertexCount || !indexCount) {
return;
fCurrQuad = 0;
+ GeometryPoolState& poolState = fGeoPoolStateStack.back();
+
Draw& draw = fDraws.push_back();
draw.fPrimitiveType = primitiveType;
draw.fStartVertex = startVertex;
this->pushState();
}
- draw.fVertexLayout = fGeometrySrc.fVertexLayout;
- switch (fGeometrySrc.fVertexSrc) {
+ draw.fVertexLayout = this->getGeomSrc().fVertexLayout;
+ switch (this->getGeomSrc().fVertexSrc) {
case kBuffer_GeometrySrcType:
- draw.fVertexBuffer = fGeometrySrc.fVertexBuffer;
+ draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer;
break;
- case kReserved_GeometrySrcType: {
+ case kReserved_GeometrySrcType: // fallthrough
+ case kArray_GeometrySrcType: {
size_t vertexBytes = (vertexCount + startVertex) *
- VertexSize(fGeometrySrc.fVertexLayout);
- fUsedReservedVertexBytes = GrMax(fUsedReservedVertexBytes, vertexBytes);
- } // fallthrough
- case kArray_GeometrySrcType:
- draw.fVertexBuffer = fCurrPoolVertexBuffer;
- draw.fStartVertex += fCurrPoolStartVertex;
+ VertexSize(this->getGeomSrc().fVertexLayout);
+ poolState.fUsedPoolVertexBytes =
+ GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
+ draw.fVertexBuffer = poolState.fPoolVertexBuffer;
+ draw.fStartVertex += poolState.fPoolStartVertex;
break;
+ }
default:
GrCrash("unknown geom src type");
}
draw.fVertexBuffer->ref();
- switch (fGeometrySrc.fIndexSrc) {
+ switch (this->getGeomSrc().fIndexSrc) {
case kBuffer_GeometrySrcType:
- draw.fIndexBuffer = fGeometrySrc.fIndexBuffer;
+ draw.fIndexBuffer = this->getGeomSrc().fIndexBuffer;
break;
- case kReserved_GeometrySrcType: {
+ case kReserved_GeometrySrcType: // fallthrough
+ case kArray_GeometrySrcType: {
size_t indexBytes = (indexCount + startIndex) * sizeof(uint16_t);
- fUsedReservedIndexBytes = GrMax(fUsedReservedIndexBytes, indexBytes);
- } // fallthrough
- case kArray_GeometrySrcType:
- draw.fIndexBuffer = fCurrPoolIndexBuffer;
- draw.fStartIndex += fCurrPoolStartVertex;
+ poolState.fUsedPoolIndexBytes =
+ GrMax(poolState.fUsedPoolIndexBytes, indexBytes);
+ draw.fIndexBuffer = poolState.fPoolIndexBuffer;
+ draw.fStartIndex += poolState.fPoolStartVertex;
break;
+ }
default:
GrCrash("unknown geom src type");
}
draw.fIndexBuffer->ref();
}
-void GrInOrderDrawBuffer::drawNonIndexed(GrPrimitiveType primitiveType,
- int startVertex,
- int vertexCount) {
+void GrInOrderDrawBuffer::onDrawNonIndexed(GrPrimitiveType primitiveType,
+ int startVertex,
+ int vertexCount) {
if (!vertexCount) {
return;
}
fCurrQuad = 0;
+ GeometryPoolState& poolState = fGeoPoolStateStack.back();
+
Draw& draw = fDraws.push_back();
draw.fPrimitiveType = primitiveType;
draw.fStartVertex = startVertex;
this->pushState();
}
- draw.fVertexLayout = fGeometrySrc.fVertexLayout;
- switch (fGeometrySrc.fVertexSrc) {
+ draw.fVertexLayout = this->getGeomSrc().fVertexLayout;
+ switch (this->getGeomSrc().fVertexSrc) {
case kBuffer_GeometrySrcType:
- draw.fVertexBuffer = fGeometrySrc.fVertexBuffer;
+ draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer;
break;
- case kReserved_GeometrySrcType: {
+ case kReserved_GeometrySrcType: // fallthrough
+ case kArray_GeometrySrcType: {
size_t vertexBytes = (vertexCount + startVertex) *
- VertexSize(fGeometrySrc.fVertexLayout);
- fUsedReservedVertexBytes = GrMax(fUsedReservedVertexBytes,
- vertexBytes);
- } // fallthrough
- case kArray_GeometrySrcType:
- draw.fVertexBuffer = fCurrPoolVertexBuffer;
- draw.fStartVertex += fCurrPoolStartVertex;
+ VertexSize(this->getGeomSrc().fVertexLayout);
+ poolState.fUsedPoolVertexBytes =
+ GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
+ draw.fVertexBuffer = poolState.fPoolVertexBuffer;
+ draw.fStartVertex += poolState.fPoolStartVertex;
break;
+ }
default:
GrCrash("unknown geom src type");
}
}
void GrInOrderDrawBuffer::reset() {
- GrAssert(!fReservedGeometry.fLocked);
+ GrAssert(1 == fGeoPoolStateStack.count());
+ this->resetVertexSource();
+ this->resetIndexSource();
uint32_t numStates = fStates.count();
for (uint32_t i = 0; i < numStates; ++i) {
const DrState& dstate = this->accessSavedDrawState(fStates[i]);
}
void GrInOrderDrawBuffer::playback(GrDrawTarget* target) {
- GrAssert(!fReservedGeometry.fLocked);
+ GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc);
+ GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc);
GrAssert(NULL != target);
GrAssert(target != this); // not considered and why?
GrDrawTarget::AutoStateRestore asr(target);
GrDrawTarget::AutoClipRestore acr(target);
- // important to not mess with reserve/lock geometry in the target with this
- // on the stack.
- GrDrawTarget::AutoGeometrySrcRestore agsr(target);
+ AutoGeometryPush agp(target);
int currState = ~0;
int currClip = ~0;
return flush;
}
-bool GrInOrderDrawBuffer::onAcquireGeometry(GrVertexLayout vertexLayout,
- void** vertices,
- void** indices) {
- GrAssert(!fReservedGeometry.fLocked);
- if (fReservedGeometry.fVertexCount) {
- GrAssert(NULL != vertices);
- GrAssert(0 == fReservedVertexBytes);
- GrAssert(0 == fUsedReservedVertexBytes);
-
- fReservedVertexBytes = VertexSize(vertexLayout) *
- fReservedGeometry.fVertexCount;
- *vertices = fVertexPool.makeSpace(vertexLayout,
- fReservedGeometry.fVertexCount,
- &fCurrPoolVertexBuffer,
- &fCurrPoolStartVertex);
- if (NULL == *vertices) {
- return false;
- }
- }
- if (fReservedGeometry.fIndexCount) {
- GrAssert(NULL != indices);
- GrAssert(0 == fReservedIndexBytes);
- GrAssert(0 == fUsedReservedIndexBytes);
-
- *indices = fIndexPool.makeSpace(fReservedGeometry.fIndexCount,
- &fCurrPoolIndexBuffer,
- &fCurrPoolStartIndex);
- if (NULL == *indices) {
- fVertexPool.putBack(fReservedVertexBytes);
- fReservedVertexBytes = 0;
- fCurrPoolVertexBuffer = NULL;
- return false;
- }
- }
- return true;
+bool GrInOrderDrawBuffer::onReserveVertexSpace(GrVertexLayout vertexLayout,
+ int vertexCount,
+ void** vertices) {
+ GeometryPoolState& poolState = fGeoPoolStateStack.back();
+ GrAssert(vertexCount > 0);
+ GrAssert(NULL != vertices);
+ GrAssert(0 == poolState.fUsedPoolVertexBytes);
+
+ *vertices = fVertexPool.makeSpace(vertexLayout,
+ vertexCount,
+ &poolState.fPoolVertexBuffer,
+ &poolState.fPoolStartVertex);
+ return NULL != *vertices;
+}
+
+bool GrInOrderDrawBuffer::onReserveIndexSpace(int indexCount, void** indices) {
+ GeometryPoolState& poolState = fGeoPoolStateStack.back();
+ GrAssert(indexCount > 0);
+ GrAssert(NULL != indices);
+ GrAssert(0 == poolState.fUsedPoolIndexBytes);
+
+ *indices = fIndexPool.makeSpace(indexCount,
+ &poolState.fPoolIndexBuffer,
+ &poolState.fPoolStartIndex);
+ return NULL != *indices;
}
-void GrInOrderDrawBuffer::onReleaseGeometry() {
- GrAssert(fUsedReservedVertexBytes <= fReservedVertexBytes);
- GrAssert(fUsedReservedIndexBytes <= fReservedIndexBytes);
-
- size_t vertexSlack = fReservedVertexBytes - fUsedReservedVertexBytes;
- fVertexPool.putBack(vertexSlack);
-
- size_t indexSlack = fReservedIndexBytes - fUsedReservedIndexBytes;
- fIndexPool.putBack(indexSlack);
+void GrInOrderDrawBuffer::releaseReservedVertexSpace() {
+ GeometryPoolState& poolState = fGeoPoolStateStack.back();
+ const GeometrySrcState& geoSrc = this->getGeomSrc();
+
+ GrAssert(kReserved_GeometrySrcType == geoSrc.fVertexSrc);
+
+ size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) *
+ geoSrc.fVertexCount;
+ fVertexPool.putBack(reservedVertexBytes -
+ poolState.fUsedPoolVertexBytes);
+ poolState.fUsedPoolVertexBytes = 0;
+ poolState.fPoolVertexBuffer = 0;
+}
- fReservedVertexBytes = 0;
- fReservedIndexBytes = 0;
- fUsedReservedVertexBytes = 0;
- fUsedReservedIndexBytes = 0;
- fCurrPoolVertexBuffer = 0;
- fCurrPoolStartVertex = 0;
+void GrInOrderDrawBuffer::releaseReservedIndexSpace() {
+ GeometryPoolState& poolState = fGeoPoolStateStack.back();
+ const GeometrySrcState& geoSrc = this->getGeomSrc();
+ GrAssert(kReserved_GeometrySrcType == geoSrc.fIndexSrc);
+
+ size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
+ fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
+ poolState.fUsedPoolIndexBytes = 0;
+ poolState.fPoolStartVertex = 0;
}
-
+
void GrInOrderDrawBuffer::onSetVertexSourceToArray(const void* vertexArray,
int vertexCount) {
- GrAssert(!fReservedGeometry.fLocked || !fReservedGeometry.fVertexCount);
+
+ GeometryPoolState& poolState = fGeoPoolStateStack.back();
+ GrAssert(0 == poolState.fUsedPoolVertexBytes);
#if GR_DEBUG
bool success =
#endif
- fVertexPool.appendVertices(fGeometrySrc.fVertexLayout,
+ fVertexPool.appendVertices(this->getGeomSrc().fVertexLayout,
vertexCount,
vertexArray,
- &fCurrPoolVertexBuffer,
- &fCurrPoolStartVertex);
+ &poolState.fPoolVertexBuffer,
+ &poolState.fPoolStartVertex);
GR_DEBUGASSERT(success);
}
void GrInOrderDrawBuffer::onSetIndexSourceToArray(const void* indexArray,
int indexCount) {
- GrAssert(!fReservedGeometry.fLocked || !fReservedGeometry.fIndexCount);
+ GeometryPoolState& poolState = fGeoPoolStateStack.back();
+ GrAssert(0 == poolState.fUsedPoolIndexBytes);
#if GR_DEBUG
bool success =
#endif
fIndexPool.appendIndices(indexCount,
indexArray,
- &fCurrPoolIndexBuffer,
- &fCurrPoolStartIndex);
+ &poolState.fPoolIndexBuffer,
+ &poolState.fPoolStartIndex);
GR_DEBUGASSERT(success);
}
+void GrInOrderDrawBuffer::geometrySourceWillPush() {
+ GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
+ poolState.fUsedPoolVertexBytes = 0;
+ poolState.fUsedPoolIndexBytes = 0;
+#if GR_DEBUG
+ poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
+ poolState.fPoolStartVertex = ~0;
+ poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
+ poolState.fPoolStartIndex = ~0;
+#endif
+}
+
+void GrInOrderDrawBuffer::releaseVertexArray() {
+ GeometryPoolState& poolState = fGeoPoolStateStack.back();
+ const GeometrySrcState& geoSrc = this->getGeomSrc();
+
+ size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) *
+ geoSrc.fVertexCount;
+ fVertexPool.putBack(reservedVertexBytes - poolState.fUsedPoolVertexBytes);
+
+ poolState.fUsedPoolVertexBytes = 0;
+}
+
+void GrInOrderDrawBuffer::releaseIndexArray() {
+ GeometryPoolState& poolState = fGeoPoolStateStack.back();
+ const GeometrySrcState& geoSrc = this->getGeomSrc();
+
+ size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
+ fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
+
+ poolState.fUsedPoolIndexBytes = 0;
+}
+
+void GrInOrderDrawBuffer::geometrySourceWillPop(
+ const GeometrySrcState& restoredState) {
+ GrAssert(fGeoPoolStateStack.count() > 1);
+ fGeoPoolStateStack.pop_back();
+ GeometryPoolState& poolState = fGeoPoolStateStack.back();
+ // we have to assume that any slack we had in our vertex/index data
+ // is now unreleasable because data may have been appended later in the
+ // pool.
+ if (kReserved_GeometrySrcType == restoredState.fVertexSrc ||
+ kArray_GeometrySrcType == restoredState.fVertexSrc) {
+ poolState.fUsedPoolVertexBytes =
+ VertexSize(restoredState.fVertexLayout) *
+ restoredState.fVertexCount;
+ }
+ if (kReserved_GeometrySrcType == restoredState.fIndexSrc ||
+ kArray_GeometrySrcType == restoredState.fIndexSrc) {
+ poolState.fUsedPoolVertexBytes = sizeof(uint16_t) *
+ restoredState.fIndexCount;
+ }
+}
+
bool GrInOrderDrawBuffer::needsNewState() const {
if (fStates.empty()) {
return true;
fDrawTarget->drawIndexed(kTriangles_PrimitiveType,
0, 0, fCurrVertex, nIndices);
- fDrawTarget->releaseReservedGeometry();
+ fDrawTarget->resetVertexSource();
fVertices = NULL;
fMaxVertices = 0;
fCurrVertex = 0;
// don't exceed the limit of the index buffer
fMaxVertices = maxQuadVertices;
}
- bool success = fDrawTarget->reserveAndLockGeometry(fVertexLayout,
- fMaxVertices, 0,
- GrTCast<void**>(&fVertices),
- NULL);
+ bool success = fDrawTarget->reserveVertexSpace(fVertexLayout,
+ fMaxVertices,
+ GrTCast<void**>(&fVertices));
GrAlwaysAssert(success);
}