diff options
author | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-03-13 12:40:53 +0000 |
---|---|---|
committer | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-03-13 12:40:53 +0000 |
commit | e3d7095c2374a423815e662020459832f389a40f (patch) | |
tree | 5206775dff89e8040547cf7edd651883b13efadf | |
parent | 470f07f9a988e8524049346f9ff724a8d21cad63 (diff) |
Change interface on GrDrawTarget to reserve vtx/idx space at same time
Review URL: https://codereview.appspot.com/5796066/
git-svn-id: http://skia.googlecode.com/svn/trunk@3371 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | src/gpu/GrDrawTarget.cpp | 45 | ||||
-rw-r--r-- | src/gpu/GrDrawTarget.h | 119 | ||||
-rw-r--r-- | src/gpu/GrTextContext.cpp | 11 |
3 files changed, 98 insertions, 77 deletions
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp index d68aa3957d..d180bcca9c 100644 --- a/src/gpu/GrDrawTarget.cpp +++ b/src/gpu/GrDrawTarget.cpp @@ -568,6 +568,30 @@ bool GrDrawTarget::reserveIndexSpace(int indexCount, } +bool GrDrawTarget::reserveVertexAndIndexSpace(GrVertexLayout vertexLayout, + int vertexCount, + int indexCount, + void** vertices, + void** indices) { + if (vertexCount) { + if (!this->reserveVertexSpace(vertexLayout, vertexCount, vertices)) { + if (indexCount) { + this->resetIndexSource(); + } + return false; + } + } + if (indexCount) { + if (!this->reserveIndexSpace(indexCount, indices)) { + if (vertexCount) { + this->resetVertexSource(); + } + return false; + } + } + return true; +} + bool GrDrawTarget::geometryHints(GrVertexLayout vertexLayout, int32_t* vertexCount, int32_t* indexCount) const { @@ -1168,19 +1192,14 @@ bool GrDrawTarget::AutoReleaseGeometry::set(GrDrawTarget* 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(); - } + success = target->reserveVertexAndIndexSpace(vertexLayout, + vertexCount, + indexCount, + &fVertices, + &fIndices); + if (!success) { + fTarget = NULL; + this->reset(); } } GrAssert(success == (NULL != fTarget)); diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h index 6962a18859..cc0e8758f8 100644 --- a/src/gpu/GrDrawTarget.h +++ b/src/gpu/GrDrawTarget.h @@ -260,21 +260,30 @@ public: GR_STATIC_ASSERT(kHighVertexLayoutBit < ((uint64_t)1 << 8*sizeof(GrVertexLayout))); /** - * There are three methods for specifying geometry (vertices and optionally - * indices) to the draw target. When indexed drawing the indices and vertices - * can use a different method. Once geometry is specified it can be used for - * multiple drawIndexed and drawNonIndexed calls. + * There are three types of "sources" of geometry (vertices and indices) for + * draw calls made on the target. When performing an indexed draw, the + * indices and vertices can use different source types. Once a source is + * specified it can be used for multiple drawIndexed and drawNonIndexed + * calls. However, the time at which the geometry data is no longer editable + * depends on the source type. * * 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 + * already specified geometry that it isn't finished with. So there are push + * and pop methods. This allows the client to push the sources, draw + * something using alternate sources, and then pop to restore the original + * sources. + * + * Aside from pushes and pops, a source remains valid until another source + * is set or resetVertexSource / resetIndexSource is called. Drawing from + * a reset source is an error. + * + * The three types of sources are: * - * 1. Provide a cpu array (set*SourceToArray). This is useful when the - * caller's client has already provided vertex data in a format - * the time compatible with a GrVertexLayout. The array must contain the - * data at set*SourceToArray is called. The source stays in effect for - * drawIndexed & drawNonIndexed calls until set*SourceToArray is called - * again or one of the other two paths is chosen. + * 1. A cpu array (set*SourceToArray). This is useful when the caller + * already provided vertex data in a format compatible with a + * GrVertexLayout. The data in the array is consumed at the time that + * set*SourceToArray is called and subsequent edits to the array will not + * be reflected in draws. * * 2. Reserve. This is most useful when the caller has data it must * transform before drawing and is not long-lived. The caller requests @@ -282,70 +291,53 @@ public: * 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 + * or pushGeometrySource. At this point the data is frozen and the ptrs * are no longer valid. * + * Where the space is allocated and how it is uploaded to the GPU is + * subclass-dependent. + * * 3. Vertex and Index Buffers. This is most useful for geometry that will - * 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. + * is long-lived. When the data in the buffer is consumed depends on the + * GrDrawTarget subclass. For deferred subclasses the caller has to + * guarantee that the data is still available in the buffers at playback. + * (TODO: Make this more automatic as we have done for read/write pixels) */ /** - * Reserves space for vertices. Draw target will use reserved vertices at - * at the next draw. + * Reserves space for vertices and/or indices. Zero can be specifed as + * either the vertex or index count if the caller desires to only reserve + * space for only indices or only vertices. If zero is specifed for + * vertexCount then the vertex source will be unmodified and likewise for + * indexCount. * - * If succeeds: - * if vertexCount > 0, *vertices will be the array - * of vertices to be filled by caller. The next draw will read - * these vertices. + * If the function returns true then the reserve suceeded and the vertices + * and indices pointers will point to the space created. * - * If a client does not already have a vertex buffer then this is the - * 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. + * If the target cannot make space for the request then this function will + * return false. If vertexCount was non-zero then upon failure the vertex + * source is reset and likewise for indexCount. * - * 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. + * The pointers to the space allocated for vertices and indices remain valid + * until a drawIndexed, drawNonIndexed, or push/popGeomtrySource is called. + * At that point logically a snapshot of the data is made and the pointers + * are invalid. * * @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. - * - * @return true if succeeded in allocating space for the vertices and false - * if not. - */ - 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 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 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. */ + virtual bool reserveVertexAndIndexSpace(GrVertexLayout vertexLayout, + int vertexCount, + int indexCount, + void** vertices, + void** indices); - 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 @@ -994,7 +986,14 @@ protected: // and index sources have been released (including those held by // pushGeometrySource()) void releaseGeometry(); + private: + // helpers for reserving vertex and index space. + bool reserveVertexSpace(GrVertexLayout vertexLayout, + int vertexCount, + void** vertices); + bool reserveIndexSpace(int indexCount, void** indices); + // called by drawIndexed and drawNonIndexed. Use a negative indexCount to // indicate non-indexed drawing. bool checkDraw(GrPrimitiveType type, int startVertex, diff --git a/src/gpu/GrTextContext.cpp b/src/gpu/GrTextContext.cpp index c22b203d9d..62c894e275 100644 --- a/src/gpu/GrTextContext.cpp +++ b/src/gpu/GrTextContext.cpp @@ -255,8 +255,8 @@ HAS_ATLAS: // a number of verts to reserve and whether to perform a flush. fMaxVertices = kMinRequestedVerts; bool flush = fDrawTarget->geometryHints(fVertexLayout, - &fMaxVertices, - NULL); + &fMaxVertices, + NULL); if (flush) { this->flushGlyphs(); fContext->flushText(); @@ -275,9 +275,12 @@ HAS_ATLAS: // don't exceed the limit of the index buffer fMaxVertices = maxQuadVertices; } - bool success = fDrawTarget->reserveVertexSpace(fVertexLayout, + bool success = fDrawTarget->reserveVertexAndIndexSpace( + fVertexLayout, fMaxVertices, - GrTCast<void**>(&fVertices)); + 0, + GrTCast<void**>(&fVertices), + NULL); GrAlwaysAssert(success); } |