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 "GrDrawOp.h"
     12 #include "GrGeometryProcessor.h"
     13 #include "GrMesh.h"
     14 #include "GrPendingProgramElement.h"
     15 
     16 #include "SkTLList.h"
     17 
     18 class GrCaps;
     19 class GrOpFlushState;
     20 
     21 /**
     22  * Base class for mesh-drawing GrDrawOps.
     23  */
     24 class GrMeshDrawOp : public GrDrawOp {
     25 public:
     26     class Target;
     27 
     28     /**
     29      * Performs analysis of the fragment processors in GrProcessorSet and GrAppliedClip using the
     30      * initial color and coverage from this op's geometry processor.
     31      */
     32     void analyzeProcessors(GrProcessorSet::FragmentProcessorAnalysis* analysis,
     33                            const GrProcessorSet& processors,
     34                            const GrAppliedClip* appliedClip,
     35                            const GrCaps& caps) const {
     36         GrPipelineAnalysisColor inputColor;
     37         GrPipelineAnalysisCoverage inputCoverage;
     38         this->getFragmentProcessorAnalysisInputs(&inputColor, &inputCoverage);
     39         analysis->init(inputColor, inputCoverage, processors, appliedClip, caps);
     40     }
     41 
     42     void initPipeline(const GrPipeline::InitArgs& args) {
     43         this->applyPipelineOptimizations(fPipeline.init(args));
     44     }
     45 
     46     /**
     47      * Mesh draw ops use a legacy system in GrRenderTargetContext where the pipeline is created when
     48      * the op is recorded. These methods are unnecessary as this information is in the pipeline.
     49      */
     50     FixedFunctionFlags fixedFunctionFlags() const override {
     51         SkFAIL("This should never be called for mesh draw ops.");
     52         return FixedFunctionFlags::kNone;
     53     }
     54     bool xpRequiresDstTexture(const GrCaps&, const GrAppliedClip*) override {
     55         SkFAIL("Should never be called for mesh draw ops.");
     56         return false;
     57     }
     58 
     59 protected:
     60     GrMeshDrawOp(uint32_t classID);
     61 
     62     /** Helper for rendering instances using an instanced index index buffer. This class creates the
     63         space for the vertices and flushes the draws to the GrMeshDrawOp::Target. */
     64     class InstancedHelper {
     65     public:
     66         InstancedHelper() {}
     67         /** Returns the allocated storage for the vertices. The caller should populate the vertices
     68             before calling recordDraws(). */
     69         void* init(Target*, GrPrimitiveType, size_t vertexStride, const GrBuffer*,
     70                    int verticesPerInstance, int indicesPerInstance, int instancesToDraw);
     71 
     72         /** Call after init() to issue draws to the GrMeshDrawOp::Target.*/
     73         void recordDraw(Target*, const GrGeometryProcessor*);
     74 
     75     private:
     76         GrMesh fMesh;
     77     };
     78 
     79     static const int kVerticesPerQuad = 4;
     80     static const int kIndicesPerQuad = 6;
     81 
     82     /** A specialization of InstanceHelper for quad rendering. */
     83     class QuadHelper : private InstancedHelper {
     84     public:
     85         QuadHelper() : INHERITED() {}
     86         /** Finds the cached quad index buffer and reserves vertex space. Returns nullptr on failure
     87             and on success a pointer to the vertex data that the caller should populate before
     88             calling recordDraws(). */
     89         void* init(Target*, size_t vertexStride, int quadsToDraw);
     90 
     91         using InstancedHelper::recordDraw;
     92 
     93     private:
     94         typedef InstancedHelper INHERITED;
     95     };
     96 
     97     const GrPipeline* pipeline() const {
     98         SkASSERT(fPipeline.isInitialized());
     99         return &fPipeline;
    100     }
    101 
    102 private:
    103     /**
    104      * Provides information about the GrPrimitiveProccesor color and coverage outputs which become
    105      * inputs to the first color and coverage fragment processors.
    106      */
    107     virtual void getFragmentProcessorAnalysisInputs(GrPipelineAnalysisColor*,
    108                                                     GrPipelineAnalysisCoverage*) const = 0;
    109 
    110     /**
    111      * After GrPipeline analysis is complete this is called so that the op can use the analysis
    112      * results when constructing its GrPrimitiveProcessor.
    113      */
    114     virtual void applyPipelineOptimizations(const GrPipelineOptimizations&) = 0;
    115 
    116     void onPrepare(GrOpFlushState* state) final;
    117     void onExecute(GrOpFlushState* state) final;
    118 
    119     virtual void onPrepareDraws(Target*) const = 0;
    120 
    121     // A set of contiguous draws that share a draw token and primitive processor. The draws all use
    122     // the op's pipeline. The meshes for the draw are stored in the fMeshes array and each
    123     // Queued draw uses fMeshCnt meshes from the fMeshes array. The reason for coallescing meshes
    124     // that share a primitive processor into a QueuedDraw is that it allows the Gpu object to setup
    125     // the shared state once and then issue draws for each mesh.
    126     struct QueuedDraw {
    127         int fMeshCnt = 0;
    128         GrPendingProgramElement<const GrGeometryProcessor> fGeometryProcessor;
    129     };
    130 
    131     // All draws in all the GrMeshDrawOps have implicit tokens based on the order they are enqueued
    132     // globally across all ops. This is the offset of the first entry in fQueuedDraws.
    133     // fQueuedDraws[i]'s token is fBaseDrawToken + i.
    134     GrDrawOpUploadToken fBaseDrawToken;
    135     GrPipeline fPipeline;
    136     SkSTArray<4, GrMesh> fMeshes;
    137     SkSTArray<4, QueuedDraw, true> fQueuedDraws;
    138 
    139     typedef GrDrawOp INHERITED;
    140 };
    141 
    142 #endif
    143