123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- /*
- * Copyright 2017 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
- #ifndef GrDeferredUpload_DEFINED
- #define GrDeferredUpload_DEFINED
- #include <functional>
- #include "include/gpu/GrTypes.h"
- #include "include/private/GrTypesPriv.h"
- 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 {
- public:
- static GrDeferredUploadToken AlreadyFlushedToken() { return GrDeferredUploadToken(0); }
- 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 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() = delete;
- explicit GrDeferredUploadToken(uint64_t sequenceNumber) : fSequenceNumber(sequenceNumber) {}
- uint64_t fSequenceNumber;
- };
- /*
- * The GrTokenTracker encapsulates the incrementing and distribution of tokens.
- */
- class GrTokenTracker {
- public:
- /** Gets the token one beyond the last token that has been flushed. */
- GrDeferredUploadToken nextTokenToFlush() const { return fLastFlushedToken.next(); }
- /** 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. */
- GrDeferredUploadToken nextDrawToken() const { return fLastIssuedToken.next(); }
- private:
- // Only these three classes get to increment the token counters
- friend class SkInternalAtlasTextContext;
- friend class GrOpFlushState;
- friend class TestingUploadTarget;
- /** Issues the next token for a draw. */
- GrDeferredUploadToken issueDrawToken() { return ++fLastIssuedToken; }
- /** Advances the last flushed token by one. */
- GrDeferredUploadToken flushToken() { return ++fLastFlushedToken; }
- GrDeferredUploadToken fLastIssuedToken = GrDeferredUploadToken::AlreadyFlushedToken();
- GrDeferredUploadToken fLastFlushedToken = GrDeferredUploadToken::AlreadyFlushedToken();
- };
- /**
- * Passed to a deferred upload when it is executed, this method allows the deferred upload to
- * actually write its pixel data into a texture.
- */
- using GrDeferredTextureUploadWritePixelsFn =
- std::function<bool(GrTextureProxy*, int left, int top, int width, int height,
- GrColorType colorType, const void* buffer, size_t rowBytes)>;
- /**
- * A deferred texture upload is simply a std::function that takes a
- * GrDeferredTextureUploadWritePixelsFn as a parameter. It is called when it should perform its
- * upload as the draw/upload sequence is executed.
- */
- using GrDeferredTextureUploadFn = std::function<void(GrDeferredTextureUploadWritePixelsFn&)>;
- /**
- * An interface for scheduling deferred uploads. It accepts asap and deferred inline uploads.
- */
- class GrDeferredUploadTarget {
- public:
- virtual ~GrDeferredUploadTarget() {}
- virtual const GrTokenTracker* tokenTracker() = 0;
- /** 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;
- };
- #endif
|