GrOpFlushState.cpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /*
  2. * Copyright 2015 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/GrOpFlushState.h"
  8. #include "include/gpu/GrTexture.h"
  9. #include "src/core/SkConvertPixels.h"
  10. #include "src/gpu/GrContextPriv.h"
  11. #include "src/gpu/GrDrawOpAtlas.h"
  12. #include "src/gpu/GrGpu.h"
  13. #include "src/gpu/GrResourceProvider.h"
  14. //////////////////////////////////////////////////////////////////////////////
  15. GrOpFlushState::GrOpFlushState(GrGpu* gpu, GrResourceProvider* resourceProvider,
  16. GrTokenTracker* tokenTracker,
  17. sk_sp<GrBufferAllocPool::CpuBufferCache> cpuBufferCache)
  18. : fVertexPool(gpu, cpuBufferCache)
  19. , fIndexPool(gpu, std::move(cpuBufferCache))
  20. , fGpu(gpu)
  21. , fResourceProvider(resourceProvider)
  22. , fTokenTracker(tokenTracker)
  23. , fDeinstantiateProxyTracker() {}
  24. const GrCaps& GrOpFlushState::caps() const {
  25. return *fGpu->caps();
  26. }
  27. GrGpuRTCommandBuffer* GrOpFlushState::rtCommandBuffer() {
  28. return fCommandBuffer->asRTCommandBuffer();
  29. }
  30. void GrOpFlushState::executeDrawsAndUploadsForMeshDrawOp(
  31. const GrOp* op, const SkRect& chainBounds, GrProcessorSet&& processorSet,
  32. GrPipeline::InputFlags pipelineFlags, const GrUserStencilSettings* stencilSettings) {
  33. SkASSERT(this->rtCommandBuffer());
  34. GrPipeline::InitArgs pipelineArgs;
  35. pipelineArgs.fInputFlags = pipelineFlags;
  36. pipelineArgs.fDstProxy = this->dstProxy();
  37. pipelineArgs.fCaps = &this->caps();
  38. pipelineArgs.fUserStencil = stencilSettings;
  39. pipelineArgs.fOutputSwizzle = this->drawOpArgs().fOutputSwizzle;
  40. GrPipeline pipeline(pipelineArgs, std::move(processorSet), this->detachAppliedClip());
  41. while (fCurrDraw != fDraws.end() && fCurrDraw->fOp == op) {
  42. GrDeferredUploadToken drawToken = fTokenTracker->nextTokenToFlush();
  43. while (fCurrUpload != fInlineUploads.end() &&
  44. fCurrUpload->fUploadBeforeToken == drawToken) {
  45. this->rtCommandBuffer()->inlineUpload(this, fCurrUpload->fUpload);
  46. ++fCurrUpload;
  47. }
  48. this->rtCommandBuffer()->draw(
  49. *fCurrDraw->fGeometryProcessor, pipeline, fCurrDraw->fFixedDynamicState,
  50. fCurrDraw->fDynamicStateArrays, fCurrDraw->fMeshes, fCurrDraw->fMeshCnt,
  51. chainBounds);
  52. fTokenTracker->flushToken();
  53. ++fCurrDraw;
  54. }
  55. }
  56. void GrOpFlushState::preExecuteDraws() {
  57. fVertexPool.unmap();
  58. fIndexPool.unmap();
  59. for (auto& upload : fASAPUploads) {
  60. this->doUpload(upload);
  61. }
  62. // Setup execution iterators.
  63. fCurrDraw = fDraws.begin();
  64. fCurrUpload = fInlineUploads.begin();
  65. }
  66. void GrOpFlushState::reset() {
  67. SkASSERT(fCurrDraw == fDraws.end());
  68. SkASSERT(fCurrUpload == fInlineUploads.end());
  69. fVertexPool.reset();
  70. fIndexPool.reset();
  71. fArena.reset();
  72. fASAPUploads.reset();
  73. fInlineUploads.reset();
  74. fDraws.reset();
  75. fBaseDrawToken = GrDeferredUploadToken::AlreadyFlushedToken();
  76. }
  77. void GrOpFlushState::doUpload(GrDeferredTextureUploadFn& upload) {
  78. GrDeferredTextureUploadWritePixelsFn wp = [this](GrTextureProxy* dstProxy, int left, int top,
  79. int width, int height,
  80. GrColorType srcColorType, const void* buffer,
  81. size_t rowBytes) {
  82. GrSurface* dstSurface = dstProxy->peekSurface();
  83. if (!fGpu->caps()->surfaceSupportsWritePixels(dstSurface) &&
  84. fGpu->caps()->supportedWritePixelsColorType(dstSurface->config(), srcColorType) != srcColorType) {
  85. return false;
  86. }
  87. size_t tightRB = width * GrColorTypeToSkColorType(srcColorType);
  88. std::unique_ptr<char[]> tmpPixels;
  89. if (!fGpu->caps()->writePixelsRowBytesSupport() && rowBytes > tightRB) {
  90. tmpPixels.reset(new char[tightRB * height]);
  91. SkRectMemcpy(tmpPixels.get(), tightRB, buffer, rowBytes, tightRB, height);
  92. buffer = tmpPixels.get();
  93. rowBytes = tightRB;
  94. }
  95. return this->fGpu->writePixels(dstSurface, left, top, width, height, srcColorType, buffer,
  96. rowBytes);
  97. };
  98. upload(wp);
  99. }
  100. GrDeferredUploadToken GrOpFlushState::addInlineUpload(GrDeferredTextureUploadFn&& upload) {
  101. return fInlineUploads.append(&fArena, std::move(upload), fTokenTracker->nextDrawToken())
  102. .fUploadBeforeToken;
  103. }
  104. GrDeferredUploadToken GrOpFlushState::addASAPUpload(GrDeferredTextureUploadFn&& upload) {
  105. fASAPUploads.append(&fArena, std::move(upload));
  106. return fTokenTracker->nextTokenToFlush();
  107. }
  108. void GrOpFlushState::recordDraw(
  109. sk_sp<const GrGeometryProcessor> gp, const GrMesh meshes[], int meshCnt,
  110. const GrPipeline::FixedDynamicState* fixedDynamicState,
  111. const GrPipeline::DynamicStateArrays* dynamicStateArrays) {
  112. SkASSERT(fOpArgs);
  113. SkASSERT(fOpArgs->fOp);
  114. bool firstDraw = fDraws.begin() == fDraws.end();
  115. auto& draw = fDraws.append(&fArena);
  116. GrDeferredUploadToken token = fTokenTracker->issueDrawToken();
  117. if (fixedDynamicState && fixedDynamicState->fPrimitiveProcessorTextures) {
  118. for (int i = 0; i < gp->numTextureSamplers(); ++i) {
  119. fixedDynamicState->fPrimitiveProcessorTextures[i]->ref();
  120. }
  121. }
  122. if (dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures) {
  123. int n = gp->numTextureSamplers() * meshCnt;
  124. for (int i = 0; i < n; ++i) {
  125. dynamicStateArrays->fPrimitiveProcessorTextures[i]->ref();
  126. }
  127. }
  128. draw.fGeometryProcessor = std::move(gp);
  129. draw.fFixedDynamicState = fixedDynamicState;
  130. draw.fDynamicStateArrays = dynamicStateArrays;
  131. draw.fMeshes = meshes;
  132. draw.fMeshCnt = meshCnt;
  133. draw.fOp = fOpArgs->fOp;
  134. if (firstDraw) {
  135. fBaseDrawToken = token;
  136. }
  137. }
  138. void* GrOpFlushState::makeVertexSpace(size_t vertexSize, int vertexCount,
  139. sk_sp<const GrBuffer>* buffer, int* startVertex) {
  140. return fVertexPool.makeSpace(vertexSize, vertexCount, buffer, startVertex);
  141. }
  142. uint16_t* GrOpFlushState::makeIndexSpace(int indexCount, sk_sp<const GrBuffer>* buffer,
  143. int* startIndex) {
  144. return reinterpret_cast<uint16_t*>(fIndexPool.makeSpace(indexCount, buffer, startIndex));
  145. }
  146. void* GrOpFlushState::makeVertexSpaceAtLeast(size_t vertexSize, int minVertexCount,
  147. int fallbackVertexCount, sk_sp<const GrBuffer>* buffer,
  148. int* startVertex, int* actualVertexCount) {
  149. return fVertexPool.makeSpaceAtLeast(vertexSize, minVertexCount, fallbackVertexCount, buffer,
  150. startVertex, actualVertexCount);
  151. }
  152. uint16_t* GrOpFlushState::makeIndexSpaceAtLeast(int minIndexCount, int fallbackIndexCount,
  153. sk_sp<const GrBuffer>* buffer, int* startIndex,
  154. int* actualIndexCount) {
  155. return reinterpret_cast<uint16_t*>(fIndexPool.makeSpaceAtLeast(
  156. minIndexCount, fallbackIndexCount, buffer, startIndex, actualIndexCount));
  157. }
  158. void GrOpFlushState::putBackIndices(int indexCount) {
  159. fIndexPool.putBack(indexCount * sizeof(uint16_t));
  160. }
  161. void GrOpFlushState::putBackVertices(int vertices, size_t vertexStride) {
  162. fVertexPool.putBack(vertices * vertexStride);
  163. }
  164. GrAppliedClip GrOpFlushState::detachAppliedClip() {
  165. return fOpArgs->fAppliedClip ? std::move(*fOpArgs->fAppliedClip) : GrAppliedClip();
  166. }
  167. GrStrikeCache* GrOpFlushState::glyphCache() const {
  168. return fGpu->getContext()->priv().getGrStrikeCache();
  169. }
  170. GrAtlasManager* GrOpFlushState::atlasManager() const {
  171. return fGpu->getContext()->priv().getAtlasManager();
  172. }
  173. //////////////////////////////////////////////////////////////////////////////
  174. GrOpFlushState::Draw::~Draw() {
  175. if (fFixedDynamicState && fFixedDynamicState->fPrimitiveProcessorTextures) {
  176. for (int i = 0; i < fGeometryProcessor->numTextureSamplers(); ++i) {
  177. fFixedDynamicState->fPrimitiveProcessorTextures[i]->unref();
  178. }
  179. }
  180. if (fDynamicStateArrays && fDynamicStateArrays->fPrimitiveProcessorTextures) {
  181. int n = fGeometryProcessor->numTextureSamplers() * fMeshCnt;
  182. const auto* textures = fDynamicStateArrays->fPrimitiveProcessorTextures;
  183. for (int i = 0; i < n; ++i) {
  184. textures[i]->unref();
  185. }
  186. }
  187. }