GrDeferredUpload.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /*
  2. * Copyright 2017 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #ifndef GrDeferredUpload_DEFINED
  8. #define GrDeferredUpload_DEFINED
  9. #include <functional>
  10. #include "include/gpu/GrTypes.h"
  11. #include "include/private/GrTypesPriv.h"
  12. class GrTextureProxy;
  13. /**
  14. * A word about deferred uploads and tokens: Ops should usually schedule their uploads to occur at
  15. * the beginning of a frame whenever possible. These are called ASAP uploads. Of course, this
  16. * requires that there are no draws that have yet to be flushed that rely on the old texture
  17. * contents. In that case the ASAP upload would happen prior to the draw and therefore the draw
  18. * would read the new (wrong) texture data. When this read-before-write data hazard exists they
  19. * should schedule an inline upload.
  20. *
  21. * Ops, in conjunction with helpers such as GrDrawOpAtlas, use upload tokens to know what the most
  22. * recent draw was that referenced a resource (or portion of a resource). Each draw is assigned a
  23. * token. A resource (or portion thereof) can be tagged with the most recent reading draw's token.
  24. * The deferred uploads target provides a facility for testing whether the draw corresponding to the
  25. * token has been flushed. If it has not been flushed then the op must perform an inline upload
  26. * instead so that the upload occurs after the draw depending on the old contents and before the
  27. * draw depending on the updated contents. When scheduling an inline upload the op provides the
  28. * token of the draw that the upload must occur before.
  29. */
  30. /**
  31. * GrDeferredUploadToken is used to sequence the uploads relative to each other and to draws.
  32. */
  33. class GrDeferredUploadToken {
  34. public:
  35. static GrDeferredUploadToken AlreadyFlushedToken() { return GrDeferredUploadToken(0); }
  36. GrDeferredUploadToken(const GrDeferredUploadToken&) = default;
  37. GrDeferredUploadToken& operator=(const GrDeferredUploadToken&) = default;
  38. bool operator==(const GrDeferredUploadToken& that) const {
  39. return fSequenceNumber == that.fSequenceNumber;
  40. }
  41. bool operator!=(const GrDeferredUploadToken& that) const { return !(*this == that); }
  42. bool operator<(const GrDeferredUploadToken that) const {
  43. return fSequenceNumber < that.fSequenceNumber;
  44. }
  45. bool operator<=(const GrDeferredUploadToken that) const {
  46. return fSequenceNumber <= that.fSequenceNumber;
  47. }
  48. bool operator>(const GrDeferredUploadToken that) const {
  49. return fSequenceNumber > that.fSequenceNumber;
  50. }
  51. bool operator>=(const GrDeferredUploadToken that) const {
  52. return fSequenceNumber >= that.fSequenceNumber;
  53. }
  54. GrDeferredUploadToken& operator++() {
  55. ++fSequenceNumber;
  56. return *this;
  57. }
  58. GrDeferredUploadToken operator++(int) {
  59. auto old = fSequenceNumber;
  60. ++fSequenceNumber;
  61. return GrDeferredUploadToken(old);
  62. }
  63. GrDeferredUploadToken next() const { return GrDeferredUploadToken(fSequenceNumber + 1); }
  64. /** Is this token in the [start, end] inclusive interval? */
  65. bool inInterval(const GrDeferredUploadToken& start, const GrDeferredUploadToken& end) {
  66. return *this >= start && *this <= end;
  67. }
  68. private:
  69. GrDeferredUploadToken() = delete;
  70. explicit GrDeferredUploadToken(uint64_t sequenceNumber) : fSequenceNumber(sequenceNumber) {}
  71. uint64_t fSequenceNumber;
  72. };
  73. /*
  74. * The GrTokenTracker encapsulates the incrementing and distribution of tokens.
  75. */
  76. class GrTokenTracker {
  77. public:
  78. /** Gets the token one beyond the last token that has been flushed. */
  79. GrDeferredUploadToken nextTokenToFlush() const { return fLastFlushedToken.next(); }
  80. /** Gets the next draw token that will be issued by this target. This can be used by an op
  81. to record that the next draw it issues will use a resource (e.g. texture) while preparing
  82. that draw. */
  83. GrDeferredUploadToken nextDrawToken() const { return fLastIssuedToken.next(); }
  84. private:
  85. // Only these three classes get to increment the token counters
  86. friend class SkInternalAtlasTextContext;
  87. friend class GrOpFlushState;
  88. friend class TestingUploadTarget;
  89. /** Issues the next token for a draw. */
  90. GrDeferredUploadToken issueDrawToken() { return ++fLastIssuedToken; }
  91. /** Advances the last flushed token by one. */
  92. GrDeferredUploadToken flushToken() { return ++fLastFlushedToken; }
  93. GrDeferredUploadToken fLastIssuedToken = GrDeferredUploadToken::AlreadyFlushedToken();
  94. GrDeferredUploadToken fLastFlushedToken = GrDeferredUploadToken::AlreadyFlushedToken();
  95. };
  96. /**
  97. * Passed to a deferred upload when it is executed, this method allows the deferred upload to
  98. * actually write its pixel data into a texture.
  99. */
  100. using GrDeferredTextureUploadWritePixelsFn =
  101. std::function<bool(GrTextureProxy*, int left, int top, int width, int height,
  102. GrColorType colorType, const void* buffer, size_t rowBytes)>;
  103. /**
  104. * A deferred texture upload is simply a std::function that takes a
  105. * GrDeferredTextureUploadWritePixelsFn as a parameter. It is called when it should perform its
  106. * upload as the draw/upload sequence is executed.
  107. */
  108. using GrDeferredTextureUploadFn = std::function<void(GrDeferredTextureUploadWritePixelsFn&)>;
  109. /**
  110. * An interface for scheduling deferred uploads. It accepts asap and deferred inline uploads.
  111. */
  112. class GrDeferredUploadTarget {
  113. public:
  114. virtual ~GrDeferredUploadTarget() {}
  115. virtual const GrTokenTracker* tokenTracker() = 0;
  116. /** Returns the token of the draw that this upload will occur before. */
  117. virtual GrDeferredUploadToken addInlineUpload(GrDeferredTextureUploadFn&&) = 0;
  118. /** Returns the token of the draw that this upload will occur before. Since ASAP uploads
  119. are done first during a flush, this will be the first token since the most recent
  120. flush. */
  121. virtual GrDeferredUploadToken addASAPUpload(GrDeferredTextureUploadFn&& upload) = 0;
  122. };
  123. #endif