Home | History | Annotate | Download | only in ops
      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 GrMeshDrawOp_DEFINED
      9 #define GrMeshDrawOp_DEFINED
     10 
     11 #include "GrAppliedClip.h"
     12 #include "GrDrawOp.h"
     13 #include "GrGeometryProcessor.h"
     14 #include "GrMesh.h"
     15 #include <type_traits>
     16 
     17 class GrAtlasManager;
     18 class GrCaps;
     19 class GrStrikeCache;
     20 class GrOpFlushState;
     21 
     22 /**
     23  * Base class for mesh-drawing GrDrawOps.
     24  */
     25 class GrMeshDrawOp : public GrDrawOp {
     26 public:
     27     /** Abstract interface that represents a destination for a GrMeshDrawOp. */
     28     class Target;
     29 
     30 protected:
     31     GrMeshDrawOp(uint32_t classID);
     32 
     33     /** Helper for rendering repeating meshes using a patterned index buffer. This class creates the
     34         space for the vertices and flushes the draws to the GrMeshDrawOp::Target. */
     35     class PatternHelper {
     36     public:
     37         PatternHelper(Target*, GrPrimitiveType, size_t vertexStride,
     38                       sk_sp<const GrBuffer> indexBuffer, int verticesPerRepetition,
     39                       int indicesPerRepetition, int repeatCount);
     40 
     41         /** Called to issue draws to the GrMeshDrawOp::Target.*/
     42         void recordDraw(Target*, sk_sp<const GrGeometryProcessor>) const;
     43         void recordDraw(Target*, sk_sp<const GrGeometryProcessor>,
     44                         const GrPipeline::FixedDynamicState*) const;
     45 
     46         void* vertices() const { return fVertices; }
     47 
     48     protected:
     49         PatternHelper() = default;
     50         void init(Target*, GrPrimitiveType, size_t vertexStride, sk_sp<const GrBuffer> indexBuffer,
     51                   int verticesPerRepetition, int indicesPerRepetition, int repeatCount);
     52 
     53     private:
     54         void* fVertices = nullptr;
     55         GrMesh* fMesh = nullptr;
     56     };
     57 
     58     static const int kVerticesPerQuad = 4;
     59     static const int kIndicesPerQuad = 6;
     60 
     61     /** A specialization of InstanceHelper for quad rendering. */
     62     class QuadHelper : private PatternHelper {
     63     public:
     64         QuadHelper() = delete;
     65         QuadHelper(Target* target, size_t vertexStride, int quadsToDraw);
     66 
     67         using PatternHelper::recordDraw;
     68         using PatternHelper::vertices;
     69 
     70     private:
     71         typedef PatternHelper INHERITED;
     72     };
     73 
     74 private:
     75     void onPrepare(GrOpFlushState* state) final;
     76     virtual void onPrepareDraws(Target*) = 0;
     77     typedef GrDrawOp INHERITED;
     78 };
     79 
     80 class GrMeshDrawOp::Target {
     81 public:
     82     virtual ~Target() {}
     83 
     84     /** Adds a draw of a mesh. */
     85     virtual void recordDraw(
     86             sk_sp<const GrGeometryProcessor>, const GrMesh[], int meshCnt,
     87             const GrPipeline::FixedDynamicState*, const GrPipeline::DynamicStateArrays*) = 0;
     88 
     89     /**
     90      * Helper for drawing GrMesh(es) with zero primProc textures and no dynamic state besides the
     91      * scissor clip.
     92      */
     93     void recordDraw(sk_sp<const GrGeometryProcessor> gp, const GrMesh meshes[], int meshCnt = 1) {
     94         static constexpr int kZeroPrimProcTextures = 0;
     95         auto fixedDynamicState = this->makeFixedDynamicState(kZeroPrimProcTextures);
     96         this->recordDraw(std::move(gp), meshes, meshCnt, fixedDynamicState, nullptr);
     97     }
     98 
     99     /**
    100      * Makes space for vertex data. The returned pointer is the location where vertex data
    101      * should be written. On return the buffer that will hold the data as well as an offset into
    102      * the buffer (in 'vertexSize' units) where the data will be placed.
    103      */
    104     virtual void* makeVertexSpace(size_t vertexSize, int vertexCount, sk_sp<const GrBuffer>*,
    105                                   int* startVertex) = 0;
    106 
    107     /**
    108      * Makes space for index data. The returned pointer is the location where index data
    109      * should be written. On return the buffer that will hold the data as well as an offset into
    110      * the buffer (in uint16_t units) where the data will be placed.
    111      */
    112     virtual uint16_t* makeIndexSpace(int indexCount, sk_sp<const GrBuffer>*, int* startIndex) = 0;
    113 
    114     /**
    115      * This is similar to makeVertexSpace. It allows the caller to use up to 'actualVertexCount'
    116      * vertices in the returned pointer, which may exceed 'minVertexCount'.
    117      * 'fallbackVertexCount' is the maximum number of vertices that should be allocated if a new
    118      * buffer is allocated on behalf of this request.
    119      */
    120     virtual void* makeVertexSpaceAtLeast(size_t vertexSize, int minVertexCount,
    121                                          int fallbackVertexCount, sk_sp<const GrBuffer>*,
    122                                          int* startVertex, int* actualVertexCount) = 0;
    123 
    124     /**
    125      * This is similar to makeIndexSpace. It allows the caller to use up to 'actualIndexCount'
    126      * indices in the returned pointer, which may exceed 'minIndexCount'.
    127      * 'fallbackIndexCount' is the maximum number of indices that should be allocated if a new
    128      * buffer is allocated on behalf of this request.
    129      */
    130     virtual uint16_t* makeIndexSpaceAtLeast(int minIndexCount, int fallbackIndexCount,
    131                                             sk_sp<const GrBuffer>*, int* startIndex,
    132                                             int* actualIndexCount) = 0;
    133 
    134     /** Helpers for ops which over-allocate and then return excess data to the pool. */
    135     virtual void putBackIndices(int indices) = 0;
    136     virtual void putBackVertices(int vertices, size_t vertexStride) = 0;
    137 
    138     GrMesh* allocMesh(GrPrimitiveType primitiveType) {
    139         return this->allocator()->make<GrMesh>(primitiveType);
    140     }
    141 
    142     GrMesh* allocMeshes(int n) { return this->allocator()->makeArray<GrMesh>(n); }
    143 
    144     GrPipeline::DynamicStateArrays* allocDynamicStateArrays(int numMeshes,
    145                                                             int numPrimitiveProcessorTextures,
    146                                                             bool allocScissors);
    147 
    148     GrPipeline::FixedDynamicState* makeFixedDynamicState(int numPrimitiveProcessorTextures);
    149 
    150     virtual GrRenderTargetProxy* proxy() const = 0;
    151 
    152     virtual const GrAppliedClip* appliedClip() = 0;
    153     virtual GrAppliedClip detachAppliedClip() = 0;
    154 
    155     virtual const GrXferProcessor::DstProxy& dstProxy() const = 0;
    156 
    157     virtual GrResourceProvider* resourceProvider() const = 0;
    158     uint32_t contextUniqueID() const { return this->resourceProvider()->contextUniqueID(); }
    159 
    160     virtual GrStrikeCache* glyphCache() const = 0;
    161     virtual GrAtlasManager* atlasManager() const = 0;
    162 
    163     virtual const GrCaps& caps() const = 0;
    164 
    165     virtual GrDeferredUploadTarget* deferredUploadTarget() = 0;
    166 
    167 private:
    168     virtual SkArenaAlloc* allocator() = 0;
    169 };
    170 
    171 #endif
    172