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: computePipelineOptimizations(GrInitInvariantOutput * color,GrInitInvariantOutput * coverage,GrBatchToXPOverrides * overrides)22 void computePipelineOptimizations(GrInitInvariantOutput* color, 23 GrInitInvariantOutput* coverage, 24 GrBatchToXPOverrides* overrides) const override { 25 color->setKnownFourComponents(fColor); 26 coverage->setKnownSingleComponent(0xff); 27 } 28 fillType()29 GrPathRendering::FillType fillType() const { return fFillType; } 30 setStencilSettings(const GrStencilSettings & stencil)31 void setStencilSettings(const GrStencilSettings& stencil) { fStencilSettings = stencil; } 32 33 protected: GrDrawPathBatchBase(uint32_t classID,const SkMatrix & viewMatrix,GrColor initialColor,GrPathRendering::FillType fill)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 stencilSettings()41 const GrStencilSettings& stencilSettings() const { return fStencilSettings; } overrides()42 const GrXPOverridesForBatch& overrides() const { return fOverrides; } viewMatrix()43 const SkMatrix& viewMatrix() const { return fViewMatrix; } color()44 GrColor color() const { return fColor; } 45 46 private: initBatchTracker(const GrXPOverridesForBatch & overrides)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 :( Create(const SkMatrix & viewMatrix,GrColor color,GrPathRendering::FillType fill,const GrPath * path)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 name()71 const char* name() const override { return "DrawPath"; } 72 73 SkString dumpInfo() const override; 74 75 private: GrDrawPathBatch(const SkMatrix & viewMatrix,GrColor color,GrPathRendering::FillType fill,const GrPath * path)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 onCombineIfPossible(GrBatch * t,const GrCaps & caps)84 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { return false; } 85 onPrepare(GrBatchFlushState *)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: AllocInstanceData104 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. appendInstanceData121 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 transformTypeInstanceData130 TransformType transformType() const { return fTransformType; } countInstanceData131 int count() const { return fInstanceCount; } 132 indicesInstanceData133 const uint16_t* indices() const { return fIndices; } indicesInstanceData134 uint16_t* indices() { return fIndices; } 135 transformValuesInstanceData136 const float* transformValues() const { return fTransformValues; } transformValuesInstanceData137 float* transformValues() { return fTransformValues; } 138 refInstanceData139 void ref() const { ++fRefCnt; } 140 unrefInstanceData141 void unref() const { 142 if (0 == --fRefCnt) { 143 sk_free(const_cast<InstanceData*>(this)); 144 } 145 } 146 147 private: Align32InstanceData148 static int Align32(int sizeInBytes) { return (sizeInBytes + 3) & ~3; } 149 InstanceDataInstanceData150 InstanceData() {} ~InstanceDataInstanceData151 ~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 :( Create(const SkMatrix & viewMatrix,SkScalar scale,SkScalar x,SkScalar y,GrColor color,GrPathRendering::FillType fill,GrPathRange * range,const InstanceData * instanceData,const SkRect & bounds)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 name()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 transformType()179 TransformType transformType() const { return fDraws.head()->fInstanceData->transformType(); } 180 181 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override; 182 onPrepare(GrBatchFlushState *)183 void onPrepare(GrBatchFlushState*) override {} 184 185 void onDraw(GrBatchFlushState* state) override; 186 187 struct Draw { setDraw188 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