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, 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