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