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