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 GrDrawPathOp_DEFINED 9 #define GrDrawPathOp_DEFINED 10 11 #include "GrDrawOp.h" 12 #include "GrGpu.h" 13 #include "GrOpFlushState.h" 14 #include "GrPath.h" 15 #include "GrPathProcessor.h" 16 #include "GrPathRendering.h" 17 #include "GrProcessorSet.h" 18 #include "GrStencilSettings.h" 19 20 #include "SkTLList.h" 21 22 class GrPaint; 23 24 class GrDrawPathOpBase : public GrDrawOp { 25 protected: 26 GrDrawPathOpBase(uint32_t classID, const SkMatrix& viewMatrix, GrPaint&& paint, 27 GrPathRendering::FillType fill, GrAA aa); fixedFunctionFlags()28 FixedFunctionFlags fixedFunctionFlags() const override { 29 return FixedFunctionFlags::kUsesHWAA | FixedFunctionFlags::kUsesStencil; 30 } xpRequiresDstTexture(const GrCaps & caps,const GrAppliedClip * clip)31 bool xpRequiresDstTexture(const GrCaps& caps, const GrAppliedClip* clip) override { 32 return GrXPFactory::WillNeedDstTexture(fProcessorSet.xpFactory(), caps, 33 this->doFragmentProcessorAnalysis(caps, clip)); 34 } 35 wasRecorded()36 void wasRecorded() override { fProcessorSet.makePendingExecution(); } 37 38 protected: viewMatrix()39 const SkMatrix& viewMatrix() const { return fViewMatrix; } color()40 GrColor color() const { return fAnalysis.inputColor(); } fillType()41 GrPathRendering::FillType fillType() const { return fFillType; } processors()42 const GrProcessorSet& processors() const { return fProcessorSet; } 43 GrPipelineOptimizations initPipeline(const GrOpFlushState&, GrPipeline*); doFragmentProcessorAnalysis(const GrCaps & caps,const GrAppliedClip * clip)44 const GrProcessorSet::FragmentProcessorAnalysis& doFragmentProcessorAnalysis( 45 const GrCaps& caps, const GrAppliedClip* clip) { 46 fProcessorSet.analyzeAndEliminateFragmentProcessors( 47 &fAnalysis, fAnalysis.inputColor(), GrPipelineAnalysisCoverage::kNone, clip, caps); 48 return fAnalysis; 49 } fragmentProcessorAnalysis()50 const GrProcessorSet::FragmentProcessorAnalysis& fragmentProcessorAnalysis() const { 51 SkASSERT(fAnalysis.isInitializedWithProcessorSet()); 52 return fAnalysis; 53 } 54 55 private: onPrepare(GrOpFlushState *)56 void onPrepare(GrOpFlushState*) final {} 57 58 SkMatrix fViewMatrix; 59 GrProcessorSet fProcessorSet; 60 GrProcessorSet::FragmentProcessorAnalysis fAnalysis; 61 GrPathRendering::FillType fFillType; 62 GrAA fAA; 63 64 typedef GrDrawOp INHERITED; 65 }; 66 67 class GrDrawPathOp final : public GrDrawPathOpBase { 68 public: 69 DEFINE_OP_CLASS_ID 70 Make(const SkMatrix & viewMatrix,GrPaint && paint,GrAA aa,GrPath * path)71 static std::unique_ptr<GrDrawOp> Make(const SkMatrix& viewMatrix, GrPaint&& paint, GrAA aa, 72 GrPath* path) { 73 return std::unique_ptr<GrDrawOp>(new GrDrawPathOp(viewMatrix, std::move(paint), aa, path)); 74 } 75 name()76 const char* name() const override { return "DrawPath"; } 77 78 SkString dumpInfo() const override; 79 80 private: GrDrawPathOp(const SkMatrix & viewMatrix,GrPaint && paint,GrAA aa,const GrPath * path)81 GrDrawPathOp(const SkMatrix& viewMatrix, GrPaint&& paint, GrAA aa, const GrPath* path) 82 : GrDrawPathOpBase(ClassID(), viewMatrix, std::move(paint), path->getFillType(), aa) 83 , fPath(path) { 84 this->setTransformedBounds(path->getBounds(), viewMatrix, HasAABloat::kNo, IsZeroArea::kNo); 85 } 86 onCombineIfPossible(GrOp * t,const GrCaps & caps)87 bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override { return false; } 88 89 void onExecute(GrOpFlushState* state) override; 90 91 GrPendingIOResource<const GrPath, kRead_GrIOType> fPath; 92 93 typedef GrDrawPathOpBase INHERITED; 94 }; 95 96 // Template this if we decide to support index types other than 16bit 97 class GrDrawPathRangeOp final : public GrDrawPathOpBase { 98 public: 99 typedef GrPathRendering::PathTransformType TransformType; 100 101 DEFINE_OP_CLASS_ID 102 103 struct InstanceData : private ::SkNoncopyable { 104 public: AllocInstanceData105 static InstanceData* Alloc(TransformType transformType, int reserveCnt) { 106 int transformSize = GrPathRendering::PathTransformSize(transformType); 107 uint8_t* ptr = (uint8_t*)sk_malloc_throw(Align32(sizeof(InstanceData)) + 108 Align32(reserveCnt * sizeof(uint16_t)) + 109 reserveCnt * transformSize * sizeof(float)); 110 InstanceData* instanceData = (InstanceData*)ptr; 111 instanceData->fIndices = (uint16_t*)&ptr[Align32(sizeof(InstanceData))]; 112 instanceData->fTransformValues = (float*)&ptr[Align32(sizeof(InstanceData)) + 113 Align32(reserveCnt * sizeof(uint16_t))]; 114 instanceData->fTransformType = transformType; 115 instanceData->fInstanceCount = 0; 116 instanceData->fRefCnt = 1; 117 SkDEBUGCODE(instanceData->fReserveCnt = reserveCnt); 118 return instanceData; 119 } 120 121 // Overload this method if we start using other transform types. appendInstanceData122 void append(uint16_t index, float x, float y) { 123 SkASSERT(GrPathRendering::kTranslate_PathTransformType == fTransformType); 124 SkASSERT(fInstanceCount < fReserveCnt); 125 fIndices[fInstanceCount] = index; 126 fTransformValues[2 * fInstanceCount] = x; 127 fTransformValues[2 * fInstanceCount + 1] = y; 128 ++fInstanceCount; 129 } 130 transformTypeInstanceData131 TransformType transformType() const { return fTransformType; } countInstanceData132 int count() const { return fInstanceCount; } 133 indicesInstanceData134 const uint16_t* indices() const { return fIndices; } indicesInstanceData135 uint16_t* indices() { return fIndices; } 136 transformValuesInstanceData137 const float* transformValues() const { return fTransformValues; } transformValuesInstanceData138 float* transformValues() { return fTransformValues; } 139 refInstanceData140 void ref() const { ++fRefCnt; } 141 unrefInstanceData142 void unref() const { 143 if (0 == --fRefCnt) { 144 sk_free(const_cast<InstanceData*>(this)); 145 } 146 } 147 148 private: Align32InstanceData149 static int Align32(int sizeInBytes) { return (sizeInBytes + 3) & ~3; } 150 InstanceDataInstanceData151 InstanceData() {} ~InstanceDataInstanceData152 ~InstanceData() {} 153 154 uint16_t* fIndices; 155 float* fTransformValues; 156 TransformType fTransformType; 157 int fInstanceCount; 158 mutable int fRefCnt; 159 SkDEBUGCODE(int fReserveCnt;) 160 }; 161 Make(const SkMatrix & viewMatrix,SkScalar scale,SkScalar x,SkScalar y,GrPaint && paint,GrPathRendering::FillType fill,GrAA aa,GrPathRange * range,const InstanceData * instanceData,const SkRect & bounds)162 static std::unique_ptr<GrDrawOp> Make(const SkMatrix& viewMatrix, SkScalar scale, SkScalar x, 163 SkScalar y, GrPaint&& paint, 164 GrPathRendering::FillType fill, GrAA aa, 165 GrPathRange* range, const InstanceData* instanceData, 166 const SkRect& bounds) { 167 return std::unique_ptr<GrDrawOp>(new GrDrawPathRangeOp( 168 viewMatrix, scale, x, y, std::move(paint), fill, aa, range, instanceData, bounds)); 169 } 170 name()171 const char* name() const override { return "DrawPathRange"; } 172 173 SkString dumpInfo() const override; 174 175 private: 176 GrDrawPathRangeOp(const SkMatrix& viewMatrix, SkScalar scale, SkScalar x, SkScalar y, 177 GrPaint&& paint, GrPathRendering::FillType fill, GrAA aa, GrPathRange* range, 178 const InstanceData* instanceData, const SkRect& bounds); 179 transformType()180 TransformType transformType() const { return fDraws.head()->fInstanceData->transformType(); } 181 182 bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override; 183 184 void onExecute(GrOpFlushState* state) override; 185 186 struct Draw { setDraw187 void set(const InstanceData* instanceData, SkScalar x, SkScalar y) { 188 fInstanceData.reset(SkRef(instanceData)); 189 fX = x; 190 fY = y; 191 } 192 193 sk_sp<const InstanceData> fInstanceData; 194 SkScalar fX, fY; 195 }; 196 197 typedef GrPendingIOResource<const GrPathRange, kRead_GrIOType> PendingPathRange; 198 typedef SkTLList<Draw, 4> DrawList; 199 200 PendingPathRange fPathRange; 201 DrawList fDraws; 202 int fTotalPathCount; 203 SkScalar fScale; 204 205 typedef GrDrawPathOpBase INHERITED; 206 }; 207 208 #endif 209