• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
GrOpFlushState(GrGpu * gpu,GrResourceProvider * resourceProvider,GrTokenTracker * tokenTracker,sk_sp<GrBufferAllocPool::CpuBufferCache> cpuBufferCache)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 
caps() const27 const GrCaps& GrOpFlushState::caps() const {
28     return *fGpu->caps();
29 }
30 
rtCommandBuffer()31 GrGpuRTCommandBuffer* GrOpFlushState::rtCommandBuffer() {
32     return fCommandBuffer->asRTCommandBuffer();
33 }
34 
executeDrawsAndUploadsForMeshDrawOp(const GrOp * op,const SkRect & chainBounds,GrProcessorSet && processorSet,uint32_t pipelineFlags,const GrUserStencilSettings * stencilSettings)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 
preExecuteDraws()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 
reset()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 
doUpload(GrDeferredTextureUploadFn & upload)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 
addInlineUpload(GrDeferredTextureUploadFn && upload)103 GrDeferredUploadToken GrOpFlushState::addInlineUpload(GrDeferredTextureUploadFn&& upload) {
104     return fInlineUploads.append(&fArena, std::move(upload), fTokenTracker->nextDrawToken())
105             .fUploadBeforeToken;
106 }
107 
addASAPUpload(GrDeferredTextureUploadFn && upload)108 GrDeferredUploadToken GrOpFlushState::addASAPUpload(GrDeferredTextureUploadFn&& upload) {
109     fASAPUploads.append(&fArena, std::move(upload));
110     return fTokenTracker->nextTokenToFlush();
111 }
112 
recordDraw(sk_sp<const GrGeometryProcessor> gp,const GrMesh meshes[],int meshCnt,const GrPipeline::FixedDynamicState * fixedDynamicState,const GrPipeline::DynamicStateArrays * dynamicStateArrays)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 
makeVertexSpace(size_t vertexSize,int vertexCount,sk_sp<const GrBuffer> * buffer,int * startVertex)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 
makeIndexSpace(int indexCount,sk_sp<const GrBuffer> * buffer,int * startIndex)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 
makeVertexSpaceAtLeast(size_t vertexSize,int minVertexCount,int fallbackVertexCount,sk_sp<const GrBuffer> * buffer,int * startVertex,int * actualVertexCount)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 
makeIndexSpaceAtLeast(int minIndexCount,int fallbackIndexCount,sk_sp<const GrBuffer> * buffer,int * startIndex,int * actualIndexCount)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 
putBackIndices(int indexCount)168 void GrOpFlushState::putBackIndices(int indexCount) {
169     fIndexPool.putBack(indexCount * sizeof(uint16_t));
170 }
171 
putBackVertices(int vertices,size_t vertexStride)172 void GrOpFlushState::putBackVertices(int vertices, size_t vertexStride) {
173     fVertexPool.putBack(vertices * vertexStride);
174 }
175 
detachAppliedClip()176 GrAppliedClip GrOpFlushState::detachAppliedClip() {
177     return fOpArgs->fAppliedClip ? std::move(*fOpArgs->fAppliedClip) : GrAppliedClip();
178 }
179 
glyphCache() const180 GrStrikeCache* GrOpFlushState::glyphCache() const {
181     return fGpu->getContext()->priv().getGrStrikeCache();
182 }
183 
atlasManager() const184 GrAtlasManager* GrOpFlushState::atlasManager() const {
185     return fGpu->getContext()->priv().getAtlasManager();
186 }
187 
188 //////////////////////////////////////////////////////////////////////////////
189 
~Draw()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