LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/gpu - GrOpFlushState.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 68 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 38 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : #ifndef GrOpFlushState_DEFINED
       9             : #define GrOpFlushState_DEFINED
      10             : 
      11             : #include "GrBufferAllocPool.h"
      12             : #include "GrGpu.h"
      13             : #include "ops/GrMeshDrawOp.h"
      14             : 
      15             : class GrGpuCommandBuffer;
      16             : class GrResourceProvider;
      17             : 
      18             : /** Tracks the state across all the GrOps (really just the GrDrawOps) in a GrOpList flush. */
      19             : class GrOpFlushState {
      20             : public:
      21             :     GrOpFlushState(GrGpu*, GrResourceProvider*);
      22             : 
      23           0 :     ~GrOpFlushState() { this->reset(); }
      24             : 
      25             :     /** Inserts an upload to be executed after all ops in the flush prepared their draws but before
      26             :         the draws are executed to the backend 3D API. */
      27           0 :     void addASAPUpload(GrDrawOp::DeferredUploadFn&& upload) {
      28           0 :         fAsapUploads.emplace_back(std::move(upload));
      29           0 :     }
      30             : 
      31           0 :     const GrCaps& caps() const { return *fGpu->caps(); }
      32           0 :     GrResourceProvider* resourceProvider() const { return fResourceProvider; }
      33             : 
      34             :     /** Has the token been flushed to the backend 3D API. */
      35           0 :     bool hasDrawBeenFlushed(GrDrawOpUploadToken token) const {
      36           0 :         return token.fSequenceNumber <= fLastFlushedToken.fSequenceNumber;
      37             :     }
      38             : 
      39             :     /** Issue a token to an operation that is being enqueued. */
      40           0 :     GrDrawOpUploadToken issueDrawToken() {
      41           0 :         return GrDrawOpUploadToken(++fLastIssuedToken.fSequenceNumber);
      42             :     }
      43             : 
      44             :     /** Call every time a draw that was issued a token is flushed */
      45           0 :     void flushToken() { ++fLastFlushedToken.fSequenceNumber; }
      46             : 
      47             :     /** Gets the next draw token that will be issued. */
      48           0 :     GrDrawOpUploadToken nextDrawToken() const {
      49           0 :         return GrDrawOpUploadToken(fLastIssuedToken.fSequenceNumber + 1);
      50             :     }
      51             : 
      52             :     /** The last token flushed to all the way to the backend API. */
      53           0 :     GrDrawOpUploadToken nextTokenToFlush() const {
      54           0 :         return GrDrawOpUploadToken(fLastFlushedToken.fSequenceNumber + 1);
      55             :     }
      56             : 
      57             :     void* makeVertexSpace(size_t vertexSize, int vertexCount,
      58             :                           const GrBuffer** buffer, int* startVertex);
      59             :     uint16_t* makeIndexSpace(int indexCount, const GrBuffer** buffer, int* startIndex);
      60             : 
      61             :     /** This is called after each op has a chance to prepare its draws and before the draws are
      62             :         issued. */
      63           0 :     void preIssueDraws() {
      64           0 :         fVertexPool.unmap();
      65           0 :         fIndexPool.unmap();
      66           0 :         int uploadCount = fAsapUploads.count();
      67             : 
      68           0 :         for (int i = 0; i < uploadCount; i++) {
      69           0 :             this->doUpload(fAsapUploads[i]);
      70             :         }
      71           0 :         fAsapUploads.reset();
      72           0 :     }
      73             : 
      74           0 :     void doUpload(GrDrawOp::DeferredUploadFn& upload) {
      75             :         GrDrawOp::WritePixelsFn wp = [this] (GrSurface* surface,
      76             :                 int left, int top, int width, int height,
      77             :                 GrPixelConfig config, const void* buffer,
      78           0 :                 size_t rowBytes) -> bool {
      79           0 :             return this->fGpu->writePixels(surface, left, top, width, height, config, buffer,
      80           0 :                                            rowBytes);
      81           0 :         };
      82           0 :         upload(wp);
      83           0 :     }
      84             : 
      85           0 :     void putBackIndices(size_t indices) { fIndexPool.putBack(indices * sizeof(uint16_t)); }
      86             : 
      87           0 :     void putBackVertexSpace(size_t sizeInBytes) { fVertexPool.putBack(sizeInBytes); }
      88             : 
      89           0 :     GrGpuCommandBuffer* commandBuffer() { return fCommandBuffer; }
      90           0 :     void setCommandBuffer(GrGpuCommandBuffer* buffer) { fCommandBuffer = buffer; }
      91             : 
      92           0 :     GrGpu* gpu() { return fGpu; }
      93             : 
      94           0 :     void reset() {
      95           0 :         fVertexPool.reset();
      96           0 :         fIndexPool.reset();
      97           0 :     }
      98             : 
      99             :     /** Additional data required on a per-op basis when executing GrDrawOps. */
     100           0 :     struct DrawOpArgs {
     101             :         GrRenderTarget* fRenderTarget;
     102             :         const GrAppliedClip* fAppliedClip;
     103             :         GrXferProcessor::DstTexture fDstTexture;
     104             :     };
     105             : 
     106           0 :     void setDrawOpArgs(DrawOpArgs* opArgs) { fOpArgs = opArgs; }
     107             : 
     108           0 :     const DrawOpArgs& drawOpArgs() const {
     109           0 :         SkASSERT(fOpArgs);
     110           0 :         return *fOpArgs;
     111             :     }
     112             : 
     113             : private:
     114             :     GrGpu*                                      fGpu;
     115             :     GrResourceProvider*                         fResourceProvider;
     116             :     GrGpuCommandBuffer*                         fCommandBuffer;
     117             :     GrVertexBufferAllocPool                     fVertexPool;
     118             :     GrIndexBufferAllocPool                      fIndexPool;
     119             :     SkSTArray<4, GrDrawOp::DeferredUploadFn>    fAsapUploads;
     120             :     GrDrawOpUploadToken                         fLastIssuedToken;
     121             :     GrDrawOpUploadToken                         fLastFlushedToken;
     122             :     DrawOpArgs*                                 fOpArgs;
     123             : };
     124             : 
     125             : /**
     126             :  * A word about uploads and tokens: Ops should usually schedule their uploads to occur at the
     127             :  * begining of a frame whenever possible. These are called ASAP uploads. Of course, this requires
     128             :  * that there are no draws that have yet to be flushed that rely on the old texture contents. In
     129             :  * that case the ASAP upload would happen prior to the previous draw causing the draw to read the
     130             :  * new (wrong) texture data. In that case they should schedule an inline upload.
     131             :  *
     132             :  * Ops, in conjunction with helpers such as GrDrawOpAtlas, can use the token system to know
     133             :  * what the most recent draw was that referenced a resource (or portion of a resource). Each draw
     134             :  * is assigned a token. A resource (or portion) can be tagged with the most recent draw's
     135             :  * token. The target provides a facility for testing whether the draw corresponding to the token
     136             :  * has been flushed. If it has not been flushed then the op must perform an inline upload instead.
     137             :  * When scheduling an inline upload the op provides the token of the draw that the upload must occur
     138             :  * before. The upload will then occur between the draw that requires the new data but after the
     139             :  * token that requires the old data.
     140             :  *
     141             :  * TODO: Currently the token/upload interface is spread over GrDrawOp, GrMeshDrawOp,
     142             :  * GrDrawOp::Target, and GrMeshDrawOp::Target. However, the interface at the GrDrawOp level is not
     143             :  * complete and isn't useful. We should push it down to GrMeshDrawOp until it is required at the
     144             :  * GrDrawOp level.
     145             :  */
     146             : 
     147             : /**
     148             :  * GrDrawOp instances use this object to allocate space for their geometry and to issue the draws
     149             :  * that render their op.
     150             :  */
     151             : class GrDrawOp::Target {
     152             : public:
     153           0 :     Target(GrOpFlushState* state, GrDrawOp* op) : fState(state), fOp(op) {}
     154             : 
     155             :     /** Returns the token of the draw that this upload will occur before. */
     156           0 :     GrDrawOpUploadToken addInlineUpload(DeferredUploadFn&& upload) {
     157           0 :         fOp->fInlineUploads.emplace_back(std::move(upload), fState->nextDrawToken());
     158           0 :         return fOp->fInlineUploads.back().fUploadBeforeToken;
     159             :     }
     160             : 
     161             :     /** Returns the token of the draw that this upload will occur before. Since ASAP uploads
     162             :         are done first during a flush, this will be the first token since the most recent
     163             :         flush. */
     164           0 :     GrDrawOpUploadToken addAsapUpload(DeferredUploadFn&& upload) {
     165           0 :         fState->addASAPUpload(std::move(upload));
     166           0 :         return fState->nextTokenToFlush();
     167             :     }
     168             : 
     169           0 :     bool hasDrawBeenFlushed(GrDrawOpUploadToken token) const {
     170           0 :         return fState->hasDrawBeenFlushed(token);
     171             :     }
     172             : 
     173             :     /** Gets the next draw token that will be issued by this target. This can be used by an op
     174             :         to record that the next draw it issues will use a resource (e.g. texture) while preparing
     175             :         that draw. */
     176           0 :     GrDrawOpUploadToken nextDrawToken() const { return fState->nextDrawToken(); }
     177             : 
     178           0 :     const GrCaps& caps() const { return fState->caps(); }
     179             : 
     180           0 :     GrResourceProvider* resourceProvider() const { return fState->resourceProvider(); }
     181             : 
     182             : protected:
     183           0 :     GrDrawOp* op() { return fOp; }
     184           0 :     GrOpFlushState* state() { return fState; }
     185             : 
     186             : private:
     187             :     GrOpFlushState* fState;
     188             :     GrDrawOp* fOp;
     189             : };
     190             : 
     191             : /** Extension of GrDrawOp::Target for use by GrMeshDrawOp. Adds the ability to create vertex
     192             :     draws. */
     193             : class GrMeshDrawOp::Target : public GrDrawOp::Target {
     194             : public:
     195           0 :     Target(GrOpFlushState* state, GrMeshDrawOp* op) : INHERITED(state, op) {}
     196             : 
     197             :     void draw(const GrGeometryProcessor* gp, const GrPipeline* pipeline, const GrMesh& mesh);
     198             : 
     199           0 :     void* makeVertexSpace(size_t vertexSize, int vertexCount,
     200             :                           const GrBuffer** buffer, int* startVertex) {
     201           0 :         return this->state()->makeVertexSpace(vertexSize, vertexCount, buffer, startVertex);
     202             :     }
     203             : 
     204           0 :     uint16_t* makeIndexSpace(int indexCount, const GrBuffer** buffer, int* startIndex) {
     205           0 :         return this->state()->makeIndexSpace(indexCount, buffer, startIndex);
     206             :     }
     207             : 
     208             :     /** Helpers for ops which over-allocate and then return data to the pool. */
     209           0 :     void putBackIndices(int indices) { this->state()->putBackIndices(indices); }
     210           0 :     void putBackVertices(int vertices, size_t vertexStride) {
     211           0 :         this->state()->putBackVertexSpace(vertices * vertexStride);
     212           0 :     }
     213             : 
     214             : private:
     215           0 :     GrMeshDrawOp* meshDrawOp() { return static_cast<GrMeshDrawOp*>(this->op()); }
     216             :     typedef GrDrawOp::Target INHERITED;
     217             : };
     218             : 
     219             : #endif

Generated by: LCOV version 1.13