aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrDeferredUpload.h
diff options
context:
space:
mode:
authorGravatar Brian Salomon <bsalomon@google.com>2017-10-31 14:42:10 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-10-31 19:01:06 +0000
commit29b60c9020ce4376df3d31db15d1aa316d640711 (patch)
tree86748ea86ae5d10f62d1714e0423487ed4e43a4a /src/gpu/GrDeferredUpload.h
parentf78b55cb94f4ac89b76a26d5a56d6380aa8fea6b (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.h78
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