diff options
author | Brian Salomon <bsalomon@google.com> | 2017-10-31 14:42:10 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-10-31 19:01:06 +0000 |
commit | 29b60c9020ce4376df3d31db15d1aa316d640711 (patch) | |
tree | 86748ea86ae5d10f62d1714e0423487ed4e43a4a /src/gpu/GrDeferredUpload.h | |
parent | f78b55cb94f4ac89b76a26d5a56d6380aa8fea6b (diff) |
Make deferred upload handling and draw recording be virtual interfaces implemented by GrOpFlushState.
The motivation for this is to allow other clients of GrDrawOpAtlas. Making GrMeshDrawOp::Target also be an abstract interface is somewhat incidental to this goal.
Bug: skia:
Change-Id: I0987adfa8a269aa2ca94147e933a2827d734c1cc
Reviewed-on: https://skia-review.googlesource.com/65121
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
Diffstat (limited to 'src/gpu/GrDeferredUpload.h')
-rw-r--r-- | src/gpu/GrDeferredUpload.h | 78 |
1 files changed, 73 insertions, 5 deletions
diff --git a/src/gpu/GrDeferredUpload.h b/src/gpu/GrDeferredUpload.h index 4110e55297..821e523627 100644 --- a/src/gpu/GrDeferredUpload.h +++ b/src/gpu/GrDeferredUpload.h @@ -14,6 +14,24 @@ class GrTextureProxy; /** + * A word about deferred uploads and tokens: Ops should usually schedule their uploads to occur at + * the beginning 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 draw and therefore the draw + * would read the new (wrong) texture data. When this read-before-write data hazard exists they + * should schedule an inline upload. + * + * Ops, in conjunction with helpers such as GrDrawOpAtlas, use upload tokens 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 thereof) can be tagged with the most recent reading draw's token. + * The deferred uploads target provides a facility for testing whether the draw corresponding to the + * token has been flushed. If it has not been flushed then the op must perform an inline upload + * instead so that the upload occurs after the draw depending on the old contents and before the + * draw depending on the updated contents. When scheduling an inline upload the op provides the + * token of the draw that the upload must occur before. + */ + +/** * GrDeferredUploadToken is used to sequence the uploads relative to each other and to draws. */ class GrDeferredUploadToken { @@ -22,19 +40,44 @@ public: GrDeferredUploadToken(const GrDeferredUploadToken&) = default; GrDeferredUploadToken& operator=(const GrDeferredUploadToken&) = default; + bool operator==(const GrDeferredUploadToken& that) const { return fSequenceNumber == that.fSequenceNumber; } bool operator!=(const GrDeferredUploadToken& that) const { return !(*this == that); } - bool inInterval(const GrDeferredUploadToken& start, const GrDeferredUploadToken& finish) { - return fSequenceNumber >= start.fSequenceNumber && - fSequenceNumber <= finish.fSequenceNumber; + bool operator<(const GrDeferredUploadToken that) const { + return fSequenceNumber < that.fSequenceNumber; + } + bool operator<=(const GrDeferredUploadToken that) const { + return fSequenceNumber <= that.fSequenceNumber; + } + bool operator>(const GrDeferredUploadToken that) const { + return fSequenceNumber > that.fSequenceNumber; + } + bool operator>=(const GrDeferredUploadToken that) const { + return fSequenceNumber >= that.fSequenceNumber; + } + + GrDeferredUploadToken& operator++() { + ++fSequenceNumber; + return *this; + } + GrDeferredUploadToken operator++(int) { + auto old = fSequenceNumber; + ++fSequenceNumber; + return GrDeferredUploadToken(old); + } + + GrDeferredUploadToken next() const { return GrDeferredUploadToken(fSequenceNumber + 1); } + + /** Is this token in the [start, end] inclusive interval? */ + bool inInterval(const GrDeferredUploadToken& start, const GrDeferredUploadToken& end) { + return *this >= start && *this <= end; } private: - GrDeferredUploadToken(); + GrDeferredUploadToken() = delete; explicit GrDeferredUploadToken(uint64_t sequenceNumber) : fSequenceNumber(sequenceNumber) {} - friend class GrOpFlushState; uint64_t fSequenceNumber; }; @@ -53,4 +96,29 @@ using GrDeferredTextureUploadWritePixelsFn = */ using GrDeferredTextureUploadFn = std::function<void(GrDeferredTextureUploadWritePixelsFn&)>; +/** + * An interface for scheduling deferred uploads. It provides sequence tokens and accepts asap and + * deferred inline uploads. + */ +class GrDeferredUploadTarget { +public: + virtual ~GrDeferredUploadTarget() {} + + /** Returns the token of the draw that this upload will occur before. */ + virtual GrDeferredUploadToken addInlineUpload(GrDeferredTextureUploadFn&&) = 0; + + /** 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. */ + virtual GrDeferredUploadToken addASAPUpload(GrDeferredTextureUploadFn&& upload) = 0; + + /** Gets the token one beyond the last token that has been flushed. */ + virtual GrDeferredUploadToken nextTokenToFlush() const = 0; + + /** Gets the next draw token that will be issued by this target. This can be used by an op + to record that the next draw it issues will use a resource (e.g. texture) while preparing + that draw. */ + virtual GrDeferredUploadToken nextDrawToken() const = 0; +}; + #endif |