GrOpList.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /*
  2. * Copyright 2016 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. #include "src/gpu/GrOpList.h"
  8. #include "include/gpu/GrContext.h"
  9. #include "src/gpu/GrDeferredProxyUploader.h"
  10. #include "src/gpu/GrMemoryPool.h"
  11. #include "src/gpu/GrRenderTargetPriv.h"
  12. #include "src/gpu/GrStencilAttachment.h"
  13. #include "src/gpu/GrSurfaceProxy.h"
  14. #include "src/gpu/GrTextureProxyPriv.h"
  15. #include <atomic>
  16. uint32_t GrOpList::CreateUniqueID() {
  17. static std::atomic<uint32_t> nextID{1};
  18. uint32_t id;
  19. do {
  20. id = nextID++;
  21. } while (id == SK_InvalidUniqueID);
  22. return id;
  23. }
  24. GrOpList::GrOpList(sk_sp<GrOpMemoryPool> opMemoryPool,
  25. sk_sp<GrSurfaceProxy> surfaceProxy,
  26. GrAuditTrail* auditTrail)
  27. : fOpMemoryPool(std::move(opMemoryPool))
  28. , fAuditTrail(auditTrail)
  29. , fUniqueID(CreateUniqueID())
  30. , fFlags(0) {
  31. SkASSERT(fOpMemoryPool);
  32. fTarget = std::move(surfaceProxy);
  33. fTarget->setLastOpList(this);
  34. }
  35. GrOpList::~GrOpList() {
  36. if (fTarget && this == fTarget->getLastOpList()) {
  37. // Ensure the target proxy doesn't keep hold of a dangling back pointer.
  38. fTarget->setLastOpList(nullptr);
  39. }
  40. }
  41. void GrOpList::endFlush() {
  42. if (fTarget && this == fTarget->getLastOpList()) {
  43. fTarget->setLastOpList(nullptr);
  44. }
  45. fTarget.reset();
  46. fDeferredProxies.reset();
  47. fAuditTrail = nullptr;
  48. }
  49. #ifdef SK_DEBUG
  50. bool GrOpList::deferredProxiesAreInstantiated() const {
  51. for (int i = 0; i < fDeferredProxies.count(); ++i) {
  52. if (!fDeferredProxies[i]->isInstantiated()) {
  53. return false;
  54. }
  55. }
  56. return true;
  57. }
  58. #endif
  59. void GrOpList::prepare(GrOpFlushState* flushState) {
  60. for (int i = 0; i < fDeferredProxies.count(); ++i) {
  61. fDeferredProxies[i]->texPriv().scheduleUpload(flushState);
  62. }
  63. this->onPrepare(flushState);
  64. }
  65. // Add a GrOpList-based dependency
  66. void GrOpList::addDependency(GrOpList* dependedOn) {
  67. SkASSERT(!dependedOn->dependsOn(this)); // loops are bad
  68. if (this->dependsOn(dependedOn)) {
  69. return; // don't add duplicate dependencies
  70. }
  71. fDependencies.push_back(dependedOn);
  72. dependedOn->addDependent(this);
  73. SkDEBUGCODE(this->validate());
  74. }
  75. // Convert from a GrSurface-based dependency to a GrOpList one
  76. void GrOpList::addDependency(GrSurfaceProxy* dependedOn, const GrCaps& caps) {
  77. if (dependedOn->getLastOpList()) {
  78. // If it is still receiving dependencies, this GrOpList shouldn't be closed
  79. SkASSERT(!this->isClosed());
  80. GrOpList* opList = dependedOn->getLastOpList();
  81. if (opList == this) {
  82. // self-read - presumably for dst reads. We can't make it closed in the self-read case.
  83. } else {
  84. this->addDependency(opList);
  85. // We are closing 'opList' here bc the current contents of it are what 'this' opList
  86. // depends on. We need a break in 'opList' so that the usage of that state has a
  87. // chance to execute.
  88. opList->makeClosed(caps);
  89. }
  90. }
  91. if (GrTextureProxy* textureProxy = dependedOn->asTextureProxy()) {
  92. if (textureProxy->texPriv().isDeferred()) {
  93. fDeferredProxies.push_back(textureProxy);
  94. }
  95. }
  96. }
  97. bool GrOpList::dependsOn(const GrOpList* dependedOn) const {
  98. for (int i = 0; i < fDependencies.count(); ++i) {
  99. if (fDependencies[i] == dependedOn) {
  100. return true;
  101. }
  102. }
  103. return false;
  104. }
  105. void GrOpList::addDependent(GrOpList* dependent) {
  106. fDependents.push_back(dependent);
  107. }
  108. #ifdef SK_DEBUG
  109. bool GrOpList::isDependedent(const GrOpList* dependent) const {
  110. for (int i = 0; i < fDependents.count(); ++i) {
  111. if (fDependents[i] == dependent) {
  112. return true;
  113. }
  114. }
  115. return false;
  116. }
  117. void GrOpList::validate() const {
  118. // TODO: check for loops and duplicates
  119. for (int i = 0; i < fDependencies.count(); ++i) {
  120. SkASSERT(fDependencies[i]->isDependedent(this));
  121. }
  122. }
  123. #endif
  124. void GrOpList::closeThoseWhoDependOnMe(const GrCaps& caps) {
  125. for (int i = 0; i < fDependents.count(); ++i) {
  126. if (!fDependents[i]->isClosed()) {
  127. fDependents[i]->makeClosed(caps);
  128. }
  129. }
  130. }
  131. bool GrOpList::isInstantiated() const {
  132. if (!fTarget->isInstantiated()) {
  133. return false;
  134. }
  135. int minStencilSampleCount = (fTarget->asRenderTargetProxy())
  136. ? fTarget->asRenderTargetProxy()->numStencilSamples()
  137. : 0;
  138. if (minStencilSampleCount) {
  139. GrRenderTarget* rt = fTarget->peekRenderTarget();
  140. SkASSERT(rt);
  141. GrStencilAttachment* stencil = rt->renderTargetPriv().getStencilAttachment();
  142. if (!stencil) {
  143. return false;
  144. }
  145. SkASSERT(stencil->numSamples() >= minStencilSampleCount);
  146. }
  147. GrSurface* surface = fTarget->peekSurface();
  148. if (surface->wasDestroyed()) {
  149. return false;
  150. }
  151. return true;
  152. }
  153. #ifdef SK_DEBUG
  154. static const char* op_to_name(GrLoadOp op) {
  155. return GrLoadOp::kLoad == op ? "load" : GrLoadOp::kClear == op ? "clear" : "discard";
  156. }
  157. void GrOpList::dump(bool printDependencies) const {
  158. SkDebugf("--------------------------------------------------------------\n");
  159. SkDebugf("opListID: %d - proxyID: %d - surfaceID: %d\n", fUniqueID,
  160. fTarget ? fTarget->uniqueID().asUInt() : -1,
  161. fTarget && fTarget->peekSurface()
  162. ? fTarget->peekSurface()->uniqueID().asUInt()
  163. : -1);
  164. SkDebugf("ColorLoadOp: %s %x StencilLoadOp: %s\n",
  165. op_to_name(fColorLoadOp),
  166. GrLoadOp::kClear == fColorLoadOp ? fLoadClearColor.toBytes_RGBA() : 0x0,
  167. op_to_name(fStencilLoadOp));
  168. if (printDependencies) {
  169. SkDebugf("I rely On (%d): ", fDependencies.count());
  170. for (int i = 0; i < fDependencies.count(); ++i) {
  171. SkDebugf("%d, ", fDependencies[i]->fUniqueID);
  172. }
  173. SkDebugf("\n");
  174. SkDebugf("(%d) Rely On Me: ", fDependents.count());
  175. for (int i = 0; i < fDependents.count(); ++i) {
  176. SkDebugf("%d, ", fDependents[i]->fUniqueID);
  177. }
  178. SkDebugf("\n");
  179. }
  180. }
  181. #endif