Home | History | Annotate | Download | only in batches
      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 GrDrawPathBatch_DEFINED
      9 #define GrDrawPathBatch_DEFINED
     10 
     11 #include "GrBatchFlushState.h"
     12 #include "GrDrawBatch.h"
     13 #include "GrGpu.h"
     14 #include "GrPath.h"
     15 #include "GrPathRendering.h"
     16 #include "GrPathProcessor.h"
     17 
     18 #include "SkTLList.h"
     19 
     20 class GrDrawPathBatchBase : public GrDrawBatch {
     21 public:
     22     void computePipelineOptimizations(GrInitInvariantOutput* color,
     23                                       GrInitInvariantOutput* coverage,
     24                                       GrBatchToXPOverrides* overrides) const override {
     25         color->setKnownFourComponents(fColor);
     26         coverage->setKnownSingleComponent(0xff);
     27     }
     28 
     29     GrPathRendering::FillType fillType() const { return fFillType; }
     30 
     31     void setStencilSettings(const GrStencilSettings& stencil) { fStencilSettings = stencil; }
     32 
     33 protected:
     34     GrDrawPathBatchBase(uint32_t classID, const SkMatrix& viewMatrix, GrColor initialColor,
     35                         GrPathRendering::FillType fill)
     36         : INHERITED(classID)
     37         , fViewMatrix(viewMatrix)
     38         , fColor(initialColor)
     39         , fFillType(fill) {}
     40 
     41     const GrStencilSettings& stencilSettings() const { return fStencilSettings; }
     42     const GrXPOverridesForBatch& overrides() const { return fOverrides; }
     43     const SkMatrix& viewMatrix() const { return fViewMatrix; }
     44     GrColor color() const { return fColor; }
     45 
     46 private:
     47     void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
     48         overrides.getOverrideColorIfSet(&fColor);
     49         fOverrides = overrides;
     50     }
     51 
     52     SkMatrix                                                fViewMatrix;
     53     GrColor                                                 fColor;
     54     GrPathRendering::FillType                               fFillType;
     55     GrStencilSettings                                       fStencilSettings;
     56     GrXPOverridesForBatch                                   fOverrides;
     57 
     58     typedef GrDrawBatch INHERITED;
     59 };
     60 
     61 class GrDrawPathBatch final : public GrDrawPathBatchBase {
     62 public:
     63     DEFINE_BATCH_CLASS_ID
     64 
     65     // This can't return a more abstract type because we install the stencil settings late :(
     66     static GrDrawPathBatchBase* Create(const SkMatrix& viewMatrix, GrColor color,
     67                                        GrPathRendering::FillType fill, const GrPath* path) {
     68         return new GrDrawPathBatch(viewMatrix, color, fill, path);
     69     }
     70 
     71     const char* name() const override { return "DrawPath"; }
     72 
     73     SkString dumpInfo() const override;
     74 
     75 private:
     76     GrDrawPathBatch(const SkMatrix& viewMatrix, GrColor color, GrPathRendering::FillType fill,
     77                     const GrPath* path)
     78         : INHERITED(ClassID(), viewMatrix, color, fill)
     79         , fPath(path) {
     80         fBounds = path->getBounds();
     81         viewMatrix.mapRect(&fBounds);
     82     }
     83 
     84     bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { return false; }
     85 
     86     void onPrepare(GrBatchFlushState*) override {}
     87 
     88     void onDraw(GrBatchFlushState* state) override;
     89 
     90     GrPendingIOResource<const GrPath, kRead_GrIOType> fPath;
     91 
     92     typedef GrDrawPathBatchBase INHERITED;
     93 };
     94 
     95 // Template this if we decide to support index types other than 16bit
     96 class GrDrawPathRangeBatch final : public GrDrawPathBatchBase {
     97 public:
     98     typedef GrPathRendering::PathTransformType TransformType;
     99 
    100     DEFINE_BATCH_CLASS_ID
    101 
    102     struct InstanceData : public SkNoncopyable {
    103     public:
    104         static InstanceData* Alloc(TransformType transformType, int reserveCnt) {
    105             int transformSize = GrPathRendering::PathTransformSize(transformType);
    106             uint8_t* ptr = (uint8_t*)sk_malloc_throw(Align32(sizeof(InstanceData)) +
    107                                                      Align32(reserveCnt * sizeof(uint16_t)) +
    108                                                      reserveCnt * transformSize * sizeof(float));
    109             InstanceData* instanceData = (InstanceData*)ptr;
    110             instanceData->fIndices = (uint16_t*)&ptr[Align32(sizeof(InstanceData))];
    111             instanceData->fTransformValues = (float*)&ptr[Align32(sizeof(InstanceData)) +
    112                                                           Align32(reserveCnt * sizeof(uint16_t))];
    113             instanceData->fTransformType = transformType;
    114             instanceData->fInstanceCount = 0;
    115             instanceData->fRefCnt = 1;
    116             SkDEBUGCODE(instanceData->fReserveCnt = reserveCnt;)
    117             return instanceData;
    118         }
    119 
    120         // Overload this method if we start using other transform types.
    121         void append(uint16_t index, float x, float y) {
    122             SkASSERT(GrPathRendering::kTranslate_PathTransformType == fTransformType);
    123             SkASSERT(fInstanceCount < fReserveCnt);
    124             fIndices[fInstanceCount] = index;
    125             fTransformValues[2 * fInstanceCount] = x;
    126             fTransformValues[2 * fInstanceCount + 1] = y;
    127             ++fInstanceCount;
    128         }
    129 
    130         TransformType transformType() const { return fTransformType; }
    131         int count() const { return fInstanceCount; }
    132 
    133         const uint16_t* indices() const { return fIndices; }
    134         uint16_t* indices() { return fIndices; }
    135 
    136         const float* transformValues() const { return fTransformValues; }
    137         float* transformValues() { return fTransformValues; }
    138 
    139         void ref() const { ++fRefCnt; }
    140 
    141         void unref() const {
    142             if (0 == --fRefCnt) {
    143                 sk_free(const_cast<InstanceData*>(this));
    144             }
    145         }
    146 
    147     private:
    148         static int Align32(int sizeInBytes) { return (sizeInBytes + 3) & ~3; }
    149 
    150         InstanceData() {}
    151         ~InstanceData() {}
    152 
    153         uint16_t*       fIndices;
    154         float*          fTransformValues;
    155         TransformType   fTransformType;
    156         int             fInstanceCount;
    157         mutable int     fRefCnt;
    158         SkDEBUGCODE(int fReserveCnt;)
    159     };
    160 
    161     // This can't return a more abstract type because we install the stencil settings late :(
    162     static GrDrawPathBatchBase* Create(const SkMatrix& viewMatrix, SkScalar scale, SkScalar x,
    163                                        SkScalar y, GrColor color, GrPathRendering::FillType fill,
    164                                        GrPathRange* range, const InstanceData* instanceData,
    165                                        const SkRect& bounds) {
    166         return new GrDrawPathRangeBatch(viewMatrix, scale, x, y, color, fill, range, instanceData,
    167                                         bounds);
    168     }
    169 
    170     const char* name() const override { return "DrawPathRange"; }
    171 
    172     SkString dumpInfo() const override;
    173 
    174 private:
    175     GrDrawPathRangeBatch(const SkMatrix& viewMatrix, SkScalar scale, SkScalar x, SkScalar y,
    176                          GrColor color, GrPathRendering::FillType fill, GrPathRange* range,
    177                          const InstanceData* instanceData, const SkRect& bounds);
    178 
    179     TransformType transformType() const { return fDraws.head()->fInstanceData->transformType(); }
    180 
    181     bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override;
    182 
    183     void onPrepare(GrBatchFlushState*) override {}
    184 
    185     void onDraw(GrBatchFlushState* state) override;
    186 
    187     struct Draw {
    188         void set(const InstanceData* instanceData, SkScalar x, SkScalar y) {
    189             fInstanceData.reset(SkRef(instanceData));
    190             fX = x;
    191             fY = y;
    192         }
    193 
    194         SkAutoTUnref<const InstanceData>    fInstanceData;
    195         SkScalar                            fX, fY;
    196     };
    197 
    198     typedef GrPendingIOResource<const GrPathRange, kRead_GrIOType> PendingPathRange;
    199     typedef SkTLList<Draw, 4> DrawList;
    200 
    201     PendingPathRange    fPathRange;
    202     DrawList            fDraws;
    203     int                 fTotalPathCount;
    204     SkScalar            fScale;
    205 
    206     typedef GrDrawPathBatchBase INHERITED;
    207 };
    208 
    209 #endif
    210