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