Index: src/gpu/GrBatchFlushState.h |
diff --git a/src/gpu/GrBatchFlushState.h b/src/gpu/GrBatchFlushState.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..5e68e282858e8fe4d49225b5f858955362212232 |
--- /dev/null |
+++ b/src/gpu/GrBatchFlushState.h |
@@ -0,0 +1,189 @@ |
+/* |
+ * Copyright 2015 Google Inc. |
+ * |
+ * Use of this source code is governed by a BSD-style license that can be |
+ * found in the LICENSE file. |
+ */ |
+ |
+#ifndef GrBatchBuffer_DEFINED |
+#define GrBatchBuffer_DEFINED |
+ |
+#include "GrBufferAllocPool.h" |
+#include "batches/GrVertexBatch.h" |
+ |
+class GrResourceProvider; |
+ |
+/** Simple class that performs the upload on behalf of a GrBatchUploader. */ |
+class GrBatchUploader::TextureUploader { |
+public: |
+ TextureUploader(GrGpu* gpu) : fGpu(gpu) { SkASSERT(gpu); } |
+ |
+ /** |
+ * Updates the pixels in a rectangle of a texture. |
+ * |
+ * @param left left edge of the rectangle to write (inclusive) |
+ * @param top top edge of the rectangle to write (inclusive) |
+ * @param width width of rectangle to write in pixels. |
+ * @param height height of rectangle to write in pixels. |
+ * @param config the pixel config of the source buffer |
+ * @param buffer memory to read pixels from |
+ * @param rowBytes number of bytes between consecutive rows. Zero |
+ * means rows are tightly packed. |
+ */ |
+ bool writeTexturePixels(GrTexture* texture, |
+ int left, int top, int width, int height, |
+ GrPixelConfig config, const void* buffer, |
+ size_t rowBytes) { |
+ return fGpu->writePixels(texture, left, top, width, height, config, buffer, rowBytes); |
+ } |
+ |
+private: |
+ GrGpu* fGpu; |
+}; |
+ |
+/** Tracks the state across all the GrBatches in a GrDrawTarget flush. */ |
+class GrBatchFlushState { |
+public: |
+ GrBatchFlushState(GrGpu*, GrResourceProvider*, GrBatchToken lastFlushedToken); |
+ |
+ ~GrBatchFlushState() { SkASSERT(fLastFlushedToken == fCurrentToken); } |
+ |
+ void advanceToken() { ++fCurrentToken; } |
+ |
+ void advanceLastFlushedToken() { ++fLastFlushedToken; } |
+ |
+ /** Inserts an upload to be executred after all batches in the flush prepared their draws |
+ but before the draws are executed to the backend 3D API. */ |
+ void addASAPUpload(GrBatchUploader* upload) { |
+ fAsapUploads.push_back().reset(SkRef(upload)); |
+ } |
+ |
+ const GrCaps& caps() const { return *fGpu->caps(); } |
+ GrResourceProvider* resourceProvider() const { return fResourceProvider; } |
+ |
+ /** Has the token been flushed to the backend 3D API. */ |
+ bool hasTokenBeenFlushed(GrBatchToken token) const { return fLastFlushedToken >= token; } |
+ |
+ /** The current token advances once for every contiguous set of uninterrupted draws prepared |
+ by a batch. */ |
+ GrBatchToken currentToken() const { return fCurrentToken; } |
+ |
+ /** The last token flushed to all the way to the backend API. */ |
+ GrBatchToken lastFlushedToken() const { return fLastFlushedToken; } |
+ |
+ /** This is a magic token that can be used to indicate that an upload should occur before |
+ any draws for any batch in the current flush execute. */ |
+ GrBatchToken asapToken() const { return fLastFlushedToken + 1; } |
+ |
+ void* makeVertexSpace(size_t vertexSize, int vertexCount, |
+ const GrVertexBuffer** buffer, int* startVertex); |
+ uint16_t* makeIndexSpace(int indexCount, const GrIndexBuffer** buffer, int* startIndex); |
+ |
+ /** This is called after each batch has a chance to prepare its draws and before the draws |
+ are issued. */ |
+ void preIssueDraws() { |
+ fVertexPool.unmap(); |
+ fIndexPool.unmap(); |
+ int uploadCount = fAsapUploads.count(); |
+ for (int i = 0; i < uploadCount; i++) { |
+ fAsapUploads[i]->upload(&fUploader); |
+ } |
+ fAsapUploads.reset(); |
+ } |
+ |
+ void putBackIndices(size_t indices) { fIndexPool.putBack(indices * sizeof(uint16_t)); } |
+ |
+ void putBackVertexSpace(size_t sizeInBytes) { fVertexPool.putBack(sizeInBytes); } |
+ |
+ GrBatchUploader::TextureUploader* uploader() { return &fUploader; } |
+ |
+ GrGpu* gpu() { return fGpu; } |
+ |
+private: |
+ GrGpu* fGpu; |
+ GrBatchUploader::TextureUploader fUploader; |
+ |
+ GrResourceProvider* fResourceProvider; |
+ |
+ GrVertexBufferAllocPool fVertexPool; |
+ GrIndexBufferAllocPool fIndexPool; |
+ |
+ SkTArray<SkAutoTUnref<GrBatchUploader>, true> fAsapUploads; |
+ |
+ GrBatchToken fCurrentToken; |
+ |
+ GrBatchToken fLastFlushedToken; |
+}; |
+ |
+/** |
+ * GrDrawBatch instances use this object to allocate space for their geometry and to issue the draws |
+ * that render their batch. |
+ */ |
+class GrDrawBatch::Target { |
+public: |
+ Target(GrBatchFlushState* state, GrDrawBatch* batch) : fState(state), fBatch(batch) {} |
+ |
+ void upload(GrBatchUploader* upload) { |
+ if (this->asapToken() == upload->lastUploadToken()) { |
+ fState->addASAPUpload(upload); |
+ } else { |
+ fBatch->fInlineUploads.push_back().reset(SkRef(upload)); |
+ } |
+ } |
+ |
+ bool hasTokenBeenFlushed(GrBatchToken token) const { |
+ return fState->hasTokenBeenFlushed(token); |
+ } |
+ GrBatchToken currentToken() const { return fState->currentToken(); } |
+ GrBatchToken asapToken() const { return fState->asapToken(); } |
+ |
+ const GrCaps& caps() const { return fState->caps(); } |
+ |
+ GrResourceProvider* resourceProvider() const { return fState->resourceProvider(); } |
+ |
+protected: |
+ GrDrawBatch* batch() { return fBatch; } |
+ GrBatchFlushState* state() { return fState; } |
+ |
+private: |
+ GrBatchFlushState* fState; |
+ GrDrawBatch* fBatch; |
+}; |
+ |
+/** Extension of GrDrawBatch::Target for use by GrVertexBatch. Adds the ability to create vertex |
+ draws. */ |
+class GrVertexBatch::Target : public GrDrawBatch::Target { |
+public: |
+ Target(GrBatchFlushState* state, GrVertexBatch* batch) : INHERITED(state, batch) {} |
+ |
+ void initDraw(const GrPrimitiveProcessor* primProc, const GrPipeline* pipeline) { |
+ GrVertexBatch::DrawArray* draws = this->vertexBatch()->fDrawArrays.addToTail(); |
+ draws->fPrimitiveProcessor.reset(primProc); |
+ this->state()->advanceToken(); |
+ } |
+ |
+ void draw(const GrVertices& vertices) { |
+ this->vertexBatch()->fDrawArrays.tail()->fDraws.push_back(vertices); |
+ } |
+ |
+ void* makeVertexSpace(size_t vertexSize, int vertexCount, |
+ const GrVertexBuffer** buffer, int* startVertex) { |
+ return this->state()->makeVertexSpace(vertexSize, vertexCount, buffer, startVertex); |
+ } |
+ |
+ uint16_t* makeIndexSpace(int indexCount, const GrIndexBuffer** buffer, int* startIndex) { |
+ return this->state()->makeIndexSpace(indexCount, buffer, startIndex); |
+ } |
+ |
+ /** Helpers for batches which over-allocate and then return data to the pool. */ |
+ void putBackIndices(int indices) { this->state()->putBackIndices(indices); } |
+ void putBackVertices(int vertices, size_t vertexStride) { |
+ this->state()->putBackVertexSpace(vertices * vertexStride); |
+ } |
+ |
+private: |
+ GrVertexBatch* vertexBatch() { return static_cast<GrVertexBatch*>(this->batch()); } |
+ typedef GrDrawBatch::Target INHERITED; |
+}; |
+ |
+#endif |