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

Unified Diff: src/gpu/GrBatchFlushState.h

Issue 1835283002: Simplify GrDrawBatch uploads and token uage. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: rebase Created 4 years, 9 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
index be9d790597671b242b3aba2f5df94f883bbc9575..0b2e2bd239450eb1584a69142b391a8c531cd43f 100644
--- a/src/gpu/GrBatchFlushState.h
+++ b/src/gpu/GrBatchFlushState.h
@@ -13,34 +13,6 @@
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:
@@ -48,32 +20,37 @@ public:
~GrBatchFlushState() { this->reset(); }
- void advanceToken() { ++fCurrentToken; }
-
- void advanceLastFlushedToken() { ++fLastFlushedToken; }
-
- /** Inserts an upload to be executred after all batches in the flush prepared their draws
+ /** Inserts an upload to be executed 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));
+ void addASAPUpload(GrDrawBatch::DeferredUploadFn&& upload) {
+ fAsapUploads.emplace_back(std::move(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; }
+ bool hasDrawBeenFlushed(GrBatchDrawToken token) const {
+ return token.fSequenceNumber <= fLastFlushedToken.fSequenceNumber;
+ }
+
+ /** Issue a token to an operation that is being enqueued. */
+ GrBatchDrawToken issueDrawToken() {
+ return GrBatchDrawToken(++fLastIssuedToken.fSequenceNumber);
+ }
- /** The current token advances once for every contiguous set of uninterrupted draws prepared
- by a batch. */
- GrBatchToken currentToken() const { return fCurrentToken; }
+ /** Call every time a draw that was issued a token is flushed */
+ void flushToken() { ++fLastFlushedToken.fSequenceNumber; }
- /** The last token flushed to all the way to the backend API. */
- GrBatchToken lastFlushedToken() const { return fLastFlushedToken; }
+ /** Gets the next draw token that will be issued. */
+ GrBatchDrawToken nextDrawToken() const {
+ return GrBatchDrawToken(fLastIssuedToken.fSequenceNumber + 1);
+ }
- /** 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; }
+ /** The last token flushed to all the way to the backend API. */
+ GrBatchDrawToken nextTokenToFlush() const {
+ return GrBatchDrawToken(fLastFlushedToken.fSequenceNumber + 1);
+ }
void* makeVertexSpace(size_t vertexSize, int vertexCount,
const GrBuffer** buffer, int* startVertex);
@@ -85,18 +62,28 @@ public:
fVertexPool.unmap();
fIndexPool.unmap();
int uploadCount = fAsapUploads.count();
+
for (int i = 0; i < uploadCount; i++) {
- fAsapUploads[i]->upload(&fUploader);
+ this->doUpload(fAsapUploads[i]);
}
fAsapUploads.reset();
}
+ void doUpload(GrDrawBatch::DeferredUploadFn& upload) {
+ GrDrawBatch::WritePixelsFn wp = [this] (GrSurface* surface,
+ int left, int top, int width, int height,
+ GrPixelConfig config, const void* buffer,
+ size_t rowBytes) -> bool {
+ return this->fGpu->writePixels(surface, left, top, width, height, config, buffer,
+ rowBytes);
+ };
+ upload(wp);
+ }
+
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; }
void reset() {
@@ -105,22 +92,44 @@ public:
}
private:
- GrGpu* fGpu;
- GrBatchUploader::TextureUploader fUploader;
- GrResourceProvider* fResourceProvider;
+ GrGpu* fGpu;
+
+ GrResourceProvider* fResourceProvider;
- GrVertexBufferAllocPool fVertexPool;
- GrIndexBufferAllocPool fIndexPool;
+ GrVertexBufferAllocPool fVertexPool;
+ GrIndexBufferAllocPool fIndexPool;
- SkTArray<SkAutoTUnref<GrBatchUploader>, true> fAsapUploads;
+ SkSTArray<4, GrDrawBatch::DeferredUploadFn> fAsapUploads;
- GrBatchToken fCurrentToken;
+ GrBatchDrawToken fLastIssuedToken;
- GrBatchToken fLastFlushedToken;
+ GrBatchDrawToken fLastFlushedToken;
};
/**
+ * A word about uploads and tokens: Batches should usually schedule their uploads to occur at the
+ * begining of a frame whenever possible. These are called ASAP uploads. Of course, this requires
+ * that there are no draws that have yet to be flushed that rely on the old texture contents. In
+ * that case the ASAP upload would happen prior to the previous draw causing the draw to read the
+ * new (wrong) texture data. In that case they should schedule an inline upload.
+ *
+ * Batches, in conjunction with helpers such as GrBatchAtlas, can use the token system to know
+ * what the most recent draw was that referenced a resource (or portion of a resource). Each draw
+ * is assigned a token. A resource (or portion) can be tagged with the most recent draw's
+ * token. The target provides a facility for testing whether the draw corresponding to the token
+ * has been flushed. If it has not been flushed then the batch must perform an inline upload
+ * instead. When scheduling an inline upload the batch provides the token of the draw that the
+ * upload must occur before. The upload will then occur between the draw that requires the new
+ * data but after the token that requires the old data.
+ *
+ * TODO: Currently the token/upload interface is spread over GrDrawBatch, GrVertexBatch,
+ * GrDrawBatch::Target, and GrVertexBatch::Target. However, the interface at the GrDrawBatch
+ * level is not complete and isn't useful. We should push it down to GrVertexBatch until it
+ * is required at the GrDrawBatch level.
+ */
+
+/**
* GrDrawBatch instances use this object to allocate space for their geometry and to issue the draws
* that render their batch.
*/
@@ -128,19 +137,28 @@ 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));
- }
+ /** Returns the token of the draw that this upload will occur before. */
+ GrBatchDrawToken addInlineUpload(DeferredUploadFn&& upload) {
+ fBatch->fInlineUploads.emplace_back(std::move(upload), fState->nextDrawToken());
+ return fBatch->fInlineUploads.back().fUploadBeforeToken;
+ }
+
+ /** Returns the token of the draw that this upload will occur before. Since ASAP uploads
+ are done first during a flush, this will be the first token since the most recent
+ flush. */
+ GrBatchDrawToken addAsapUpload(DeferredUploadFn&& upload) {
+ fState->addASAPUpload(std::move(upload));
+ return fState->nextTokenToFlush();
}
- bool hasTokenBeenFlushed(GrBatchToken token) const {
- return fState->hasTokenBeenFlushed(token);
+ bool hasDrawBeenFlushed(GrBatchDrawToken token) const {
+ return fState->hasDrawBeenFlushed(token);
}
- GrBatchToken currentToken() const { return fState->currentToken(); }
- GrBatchToken asapToken() const { return fState->asapToken(); }
+
+ /** Gets the next draw token that will be issued by this target. This can be used by a batch
+ to record that the next draw it issues will use a resource (e.g. texture) while preparing
+ that draw. */
+ GrBatchDrawToken nextDrawToken() const { return fState->nextDrawToken(); }
const GrCaps& caps() const { return fState->caps(); }
@@ -161,15 +179,7 @@ class GrVertexBatch::Target : public GrDrawBatch::Target {
public:
Target(GrBatchFlushState* state, GrVertexBatch* batch) : INHERITED(state, batch) {}
- void initDraw(const GrPrimitiveProcessor* primProc) {
- GrVertexBatch::DrawArray* draws = this->vertexBatch()->fDrawArrays.addToTail();
- draws->fPrimitiveProcessor.reset(primProc);
- this->state()->advanceToken();
- }
-
- void draw(const GrMesh& mesh) {
- this->vertexBatch()->fDrawArrays.tail()->fDraws.push_back(mesh);
- }
+ void draw(const GrGeometryProcessor* gp, const GrMesh& mesh);
void* makeVertexSpace(size_t vertexSize, int vertexCount,
const GrBuffer** buffer, int* startVertex) {
« 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