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 "GrOpFlushState.h" 13 #include "GrPath.h" 14 #include "GrPathProcessor.h" 15 #include "GrPathRendering.h" 16 #include "GrProcessorSet.h" 17 #include "GrStencilSettings.h" 18 19 #include "SkTLList.h" 20 21 class GrPaint; 22 23 class GrDrawPathOpBase : public GrDrawOp { 24 protected: 25 GrDrawPathOpBase(uint32_t classID, const SkMatrix& viewMatrix, GrPaint&&, 26 GrPathRendering::FillType, GrAAType); 27 fixedFunctionFlags()28 FixedFunctionFlags fixedFunctionFlags() const override { 29 if (GrAATypeIsHW(fAAType)) { 30 return FixedFunctionFlags::kUsesHWAA | FixedFunctionFlags::kUsesStencil; 31 } 32 return FixedFunctionFlags::kUsesStencil; 33 } finalize(const GrCaps & caps,const GrAppliedClip * clip,GrPixelConfigIsClamped dstIsClamped)34 RequiresDstTexture finalize(const GrCaps& caps, const GrAppliedClip* clip, 35 GrPixelConfigIsClamped dstIsClamped) override { 36 return this->doProcessorAnalysis(caps, clip, dstIsClamped).requiresDstTexture() 37 ? RequiresDstTexture::kYes : RequiresDstTexture::kNo; 38 } 39 visitProxies(const VisitProxyFunc & func)40 void visitProxies(const VisitProxyFunc& func) const override { 41 fProcessorSet.visitProxies(func); 42 } 43 44 protected: viewMatrix()45 const SkMatrix& viewMatrix() const { return fViewMatrix; } color()46 GrColor color() const { return fInputColor; } fillType()47 GrPathRendering::FillType fillType() const { return fFillType; } processors()48 const GrProcessorSet& processors() const { return fProcessorSet; } detachProcessors()49 GrProcessorSet detachProcessors() { return std::move(fProcessorSet); } pipelineSRGBFlags()50 uint32_t pipelineSRGBFlags() const { return fPipelineSRGBFlags; } 51 inline GrPipeline::InitArgs pipelineInitArgs(const GrOpFlushState&); doProcessorAnalysis(const GrCaps & caps,const GrAppliedClip * clip,GrPixelConfigIsClamped dstIsClamped)52 const GrProcessorSet::Analysis& doProcessorAnalysis(const GrCaps& caps, 53 const GrAppliedClip* clip, 54 GrPixelConfigIsClamped dstIsClamped) { 55 bool isMixedSamples = GrAAType::kMixedSamples == fAAType; 56 fAnalysis = fProcessorSet.finalize(fInputColor, GrProcessorAnalysisCoverage::kNone, clip, 57 isMixedSamples, caps, dstIsClamped, &fInputColor); 58 return fAnalysis; 59 } processorAnalysis()60 const GrProcessorSet::Analysis& processorAnalysis() const { 61 SkASSERT(fAnalysis.isInitialized()); 62 return fAnalysis; 63 } 64 65 private: onPrepare(GrOpFlushState *)66 void onPrepare(GrOpFlushState*) final {} 67 68 SkMatrix fViewMatrix; 69 GrColor fInputColor; 70 GrProcessorSet::Analysis fAnalysis; 71 GrPathRendering::FillType fFillType; 72 GrAAType fAAType; 73 uint32_t fPipelineSRGBFlags; 74 GrProcessorSet fProcessorSet; 75 76 typedef GrDrawOp INHERITED; 77 }; 78 79 class GrDrawPathOp final : public GrDrawPathOpBase { 80 public: 81 DEFINE_OP_CLASS_ID 82 Make(const SkMatrix & viewMatrix,GrPaint && paint,GrAAType aaType,GrPath * path)83 static std::unique_ptr<GrDrawOp> Make(const SkMatrix& viewMatrix, GrPaint&& paint, 84 GrAAType aaType, GrPath* path) { 85 return std::unique_ptr<GrDrawOp>( 86 new GrDrawPathOp(viewMatrix, std::move(paint), aaType, path)); 87 } 88 name()89 const char* name() const override { return "DrawPath"; } 90 91 SkString dumpInfo() const override; 92 93 private: GrDrawPathOp(const SkMatrix & viewMatrix,GrPaint && paint,GrAAType aaType,const GrPath * path)94 GrDrawPathOp(const SkMatrix& viewMatrix, GrPaint&& paint, GrAAType aaType, const GrPath* path) 95 : GrDrawPathOpBase(ClassID(), viewMatrix, std::move(paint), path->getFillType(), aaType) 96 , fPath(path) { 97 this->setTransformedBounds(path->getBounds(), viewMatrix, HasAABloat::kNo, IsZeroArea::kNo); 98 } 99 onCombineIfPossible(GrOp * t,const GrCaps & caps)100 bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override { return false; } 101 102 void onExecute(GrOpFlushState* state) override; 103 104 GrPendingIOResource<const GrPath, kRead_GrIOType> fPath; 105 106 typedef GrDrawPathOpBase INHERITED; 107 }; 108 109 // Template this if we decide to support index types other than 16bit 110 class GrDrawPathRangeOp final : public GrDrawPathOpBase { 111 public: 112 typedef GrPathRendering::PathTransformType TransformType; 113 114 DEFINE_OP_CLASS_ID 115 116 struct InstanceData : private ::SkNoncopyable { 117 public: AllocInstanceData118 static InstanceData* Alloc(TransformType transformType, int reserveCnt) { 119 int transformSize = GrPathRendering::PathTransformSize(transformType); 120 uint8_t* ptr = (uint8_t*)sk_malloc_throw(Align32(sizeof(InstanceData)) + 121 Align32(reserveCnt * sizeof(uint16_t)) + 122 reserveCnt * transformSize * sizeof(float)); 123 InstanceData* instanceData = (InstanceData*)ptr; 124 instanceData->fIndices = (uint16_t*)&ptr[Align32(sizeof(InstanceData))]; 125 instanceData->fTransformValues = (float*)&ptr[Align32(sizeof(InstanceData)) + 126 Align32(reserveCnt * sizeof(uint16_t))]; 127 instanceData->fTransformType = transformType; 128 instanceData->fInstanceCount = 0; 129 instanceData->fRefCnt = 1; 130 SkDEBUGCODE(instanceData->fReserveCnt = reserveCnt); 131 return instanceData; 132 } 133 134 // Overload this method if we start using other transform types. appendInstanceData135 void append(uint16_t index, float x, float y) { 136 SkASSERT(GrPathRendering::kTranslate_PathTransformType == fTransformType); 137 SkASSERT(fInstanceCount < fReserveCnt); 138 fIndices[fInstanceCount] = index; 139 fTransformValues[2 * fInstanceCount] = x; 140 fTransformValues[2 * fInstanceCount + 1] = y; 141 ++fInstanceCount; 142 } 143 transformTypeInstanceData144 TransformType transformType() const { return fTransformType; } countInstanceData145 int count() const { return fInstanceCount; } 146 indicesInstanceData147 const uint16_t* indices() const { return fIndices; } indicesInstanceData148 uint16_t* indices() { return fIndices; } 149 transformValuesInstanceData150 const float* transformValues() const { return fTransformValues; } transformValuesInstanceData151 float* transformValues() { return fTransformValues; } 152 refInstanceData153 void ref() const { ++fRefCnt; } 154 unrefInstanceData155 void unref() const { 156 if (0 == --fRefCnt) { 157 sk_free(const_cast<InstanceData*>(this)); 158 } 159 } 160 161 private: Align32InstanceData162 static int Align32(int sizeInBytes) { return (sizeInBytes + 3) & ~3; } 163 InstanceDataInstanceData164 InstanceData() {} ~InstanceDataInstanceData165 ~InstanceData() {} 166 167 uint16_t* fIndices; 168 float* fTransformValues; 169 TransformType fTransformType; 170 int fInstanceCount; 171 mutable int fRefCnt; 172 SkDEBUGCODE(int fReserveCnt;) 173 }; 174 Make(const SkMatrix & viewMatrix,SkScalar scale,SkScalar x,SkScalar y,GrPaint && paint,GrPathRendering::FillType fill,GrAAType aaType,GrPathRange * range,const InstanceData * instanceData,const SkRect & bounds)175 static std::unique_ptr<GrDrawOp> Make(const SkMatrix& viewMatrix, SkScalar scale, SkScalar x, 176 SkScalar y, GrPaint&& paint, 177 GrPathRendering::FillType fill, GrAAType aaType, 178 GrPathRange* range, const InstanceData* instanceData, 179 const SkRect& bounds) { 180 return std::unique_ptr<GrDrawOp>(new GrDrawPathRangeOp(viewMatrix, scale, x, y, 181 std::move(paint), fill, aaType, 182 range, instanceData, bounds)); 183 } 184 name()185 const char* name() const override { return "DrawPathRange"; } 186 187 SkString dumpInfo() const override; 188 189 private: 190 GrDrawPathRangeOp(const SkMatrix& viewMatrix, SkScalar scale, SkScalar x, SkScalar y, 191 GrPaint&& paint, GrPathRendering::FillType fill, GrAAType aaType, 192 GrPathRange* range, const InstanceData* instanceData, const SkRect& bounds); 193 transformType()194 TransformType transformType() const { return fDraws.head()->fInstanceData->transformType(); } 195 196 bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override; 197 198 void onExecute(GrOpFlushState* state) override; 199 200 struct Draw { setDraw201 void set(const InstanceData* instanceData, SkScalar x, SkScalar y) { 202 fInstanceData.reset(SkRef(instanceData)); 203 fX = x; 204 fY = y; 205 } 206 207 sk_sp<const InstanceData> fInstanceData; 208 SkScalar fX, fY; 209 }; 210 211 typedef GrPendingIOResource<const GrPathRange, kRead_GrIOType> PendingPathRange; 212 typedef SkTLList<Draw, 4> DrawList; 213 214 PendingPathRange fPathRange; 215 DrawList fDraws; 216 int fTotalPathCount; 217 SkScalar fScale; 218 219 typedef GrDrawPathOpBase INHERITED; 220 }; 221 222 #endif 223