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