Home | History | Annotate | Download | only in gpu
      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