Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(242)

Unified Diff: src/gpu/GrBatchFlushState.h

Issue 1286043004: Make GrVertexBatch objects hold their own draws during GrDrawTarget flush (Closed) Base URL: https://skia.googlesource.com/skia.git@m
Patch Set: forward decl Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/gpu/GrBatchAtlas.cpp ('k') | src/gpu/GrBatchFlushState.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
« no previous file with comments | « src/gpu/GrBatchAtlas.cpp ('k') | src/gpu/GrBatchFlushState.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698