Home | History | Annotate | Download | only in instanced
      1 /*
      2  * Copyright 2017 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 gr_instanced_InstancedOp_DEFINED
      9 #define gr_instanced_InstancedOp_DEFINED
     10 
     11 
     12 #include "../private/GrInstancedPipelineInfo.h"
     13 #include "GrMemoryPool.h"
     14 #include "ops/GrDrawOp.h"
     15 #include "instanced/InstancedRenderingTypes.h"
     16 
     17 #include "SkTInternalLList.h"
     18 
     19 namespace gr_instanced {
     20 
     21 class InstancedRendering;
     22 class OpAllocator;
     23 
     24 class InstancedOp : public GrDrawOp {
     25 public:
     26     SK_DECLARE_INTERNAL_LLIST_INTERFACE(InstancedOp);
     27 
     28     ~InstancedOp() override;
     29     const char* name() const override { return "InstancedOp"; }
     30 
     31     SkString dumpInfo() const override {
     32         SkString string;
     33         string.printf(
     34                 "AA: %d, ShapeTypes: 0x%02x, IShapeTypes: 0x%02x, Persp %d, "
     35                 "NonSquare: %d, PLoad: %0.2f, Tracked: %d, NumDraws: %d, "
     36                 "GeomChanges: %d\n",
     37                 (unsigned)fInfo.fAAType,
     38                 fInfo.fShapeTypes,
     39                 fInfo.fInnerShapeTypes,
     40                 fInfo.fHasPerspective,
     41                 fInfo.fNonSquare,
     42                 fPixelLoad,
     43                 fIsTracked,
     44                 fNumDraws,
     45                 fNumChangesInGeometry);
     46         string.append(INHERITED::dumpInfo());
     47         return string;
     48     }
     49 
     50     struct Draw {
     51         Instance     fInstance;
     52         IndexRange   fGeometry;
     53         Draw*        fNext;
     54     };
     55 
     56     Draw& getSingleDraw() const { SkASSERT(fHeadDraw && !fHeadDraw->fNext); return *fHeadDraw; }
     57     Instance& getSingleInstance() const { return this->getSingleDraw().fInstance; }
     58 
     59     void appendRRectParams(const SkRRect&);
     60     void appendParamsTexel(const SkScalar* vals, int count);
     61     void appendParamsTexel(SkScalar x, SkScalar y, SkScalar z, SkScalar w);
     62     void appendParamsTexel(SkScalar x, SkScalar y, SkScalar z);
     63     FixedFunctionFlags fixedFunctionFlags() const override {
     64         return GrAATypeIsHW(fInfo.aaType()) ? FixedFunctionFlags::kUsesHWAA
     65                                             : FixedFunctionFlags::kNone;
     66     }
     67     RequiresDstTexture finalize(const GrCaps&, const GrAppliedClip*) override;
     68 
     69     // Registers the op with the InstancedRendering list of tracked ops.
     70     void wasRecorded(GrRenderTargetOpList*) override;
     71 
     72 protected:
     73     InstancedOp(uint32_t classID, GrPaint&&, OpAllocator*);
     74 
     75     bool fIsTracked : 1;
     76     bool fRequiresBarrierOnOverlap : 1;
     77     bool fAllowsSRGBInputs : 1;
     78     bool fDisableSRGBOutputConversion : 1;
     79     int fNumDraws;
     80     int fNumChangesInGeometry;
     81     Draw* fHeadDraw;
     82     Draw* fTailDraw;
     83     OpAllocator* fAllocator;
     84     InstancedRendering* fInstancedRendering;
     85     OpInfo fInfo;
     86     SkScalar fPixelLoad;
     87     GrProcessorSet fProcessors;
     88     SkSTArray<5, ParamsTexel, true> fParams;
     89 
     90 private:
     91     bool onCombineIfPossible(GrOp* other, const GrCaps& caps) override;
     92     void onPrepare(GrOpFlushState*) override {}
     93     void onExecute(GrOpFlushState*) override;
     94 
     95     typedef GrDrawOp INHERITED;
     96 
     97     friend class InstancedRendering;
     98     friend class OpAllocator;
     99 };
    100 
    101 class OpAllocator : public SkNoncopyable {
    102 public:
    103     virtual ~OpAllocator();
    104 
    105     /**
    106      * These methods make a new record internally for an instanced draw, and return an op that is
    107      * effectively just an index to that record. The returned op is not self-contained, but
    108      * rather relies on this class to handle the rendering. The client must call beginFlush() on
    109      * this class before attempting to flush ops returned by it. It is invalid to record new
    110      * draws between beginFlush() and endFlush().
    111      */
    112     std::unique_ptr<GrDrawOp> SK_WARN_UNUSED_RESULT recordRect(const SkRect&, const SkMatrix&,
    113                                                                GrPaint&&, GrAA,
    114                                                                const GrInstancedPipelineInfo&);
    115 
    116     std::unique_ptr<GrDrawOp> SK_WARN_UNUSED_RESULT recordRect(const SkRect&, const SkMatrix&,
    117                                                                GrPaint&&, const SkRect& localRect,
    118                                                                GrAA,
    119                                                                const GrInstancedPipelineInfo&);
    120 
    121     std::unique_ptr<GrDrawOp> SK_WARN_UNUSED_RESULT recordRect(const SkRect&, const SkMatrix&,
    122                                                                GrPaint&&,
    123                                                                const SkMatrix& localMatrix, GrAA,
    124                                                                const GrInstancedPipelineInfo&);
    125 
    126     std::unique_ptr<GrDrawOp> SK_WARN_UNUSED_RESULT recordOval(const SkRect&, const SkMatrix&,
    127                                                                GrPaint&&, GrAA,
    128                                                                const GrInstancedPipelineInfo&);
    129 
    130     std::unique_ptr<GrDrawOp> SK_WARN_UNUSED_RESULT recordRRect(const SkRRect&, const SkMatrix&,
    131                                                                 GrPaint&&, GrAA,
    132                                                                 const GrInstancedPipelineInfo&);
    133 
    134     std::unique_ptr<GrDrawOp> SK_WARN_UNUSED_RESULT recordDRRect(const SkRRect& outer,
    135                                                                  const SkRRect& inner,
    136                                                                  const SkMatrix&, GrPaint&&, GrAA,
    137                                                                  const GrInstancedPipelineInfo&);
    138 
    139     InstancedOp::Draw* allocateDraw() { return fDrawPool.allocate(); }
    140     void releaseDraw(InstancedOp::Draw* draw) { fDrawPool.release(draw); }
    141 
    142 protected:
    143     OpAllocator(const GrCaps*);
    144 
    145 private:
    146     bool selectAntialiasMode(const SkMatrix& viewMatrix, GrAA aa, const GrInstancedPipelineInfo&,
    147                              GrAAType*);
    148     virtual std::unique_ptr<InstancedOp> makeOp(GrPaint&&) = 0;
    149 
    150     std::unique_ptr<InstancedOp> SK_WARN_UNUSED_RESULT recordShape(
    151                                                           ShapeType, const SkRect& bounds,
    152                                                           const SkMatrix& viewMatrix, GrPaint&&,
    153                                                           const SkRect& localRect, GrAA aa,
    154                                                           const GrInstancedPipelineInfo&);
    155 
    156     GrObjectMemoryPool<InstancedOp::Draw> fDrawPool;
    157     sk_sp<const GrCaps>                   fCaps;
    158 };
    159 
    160 }
    161 
    162 #endif
    163