blob: 0631adcdf6101765b24fb47c02082643d05da67f [file] [log] [blame]
bsalomonadd79ef2015-08-19 13:26:49 -07001/*
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
Brian Salomon82c263f2016-12-15 09:54:06 -05008#ifndef GrDrawPathOp_DEFINED
9#define GrDrawPathOp_DEFINED
bsalomonadd79ef2015-08-19 13:26:49 -070010
Brian Salomon9afd3712016-12-01 10:59:09 -050011#include "GrDrawOp.h"
bsalomonadd79ef2015-08-19 13:26:49 -070012#include "GrGpu.h"
Brian Salomon742e31d2016-12-07 17:06:19 -050013#include "GrOpFlushState.h"
bsalomonadd79ef2015-08-19 13:26:49 -070014#include "GrPath.h"
bsalomonadd79ef2015-08-19 13:26:49 -070015#include "GrPathProcessor.h"
Brian Salomon742e31d2016-12-07 17:06:19 -050016#include "GrPathRendering.h"
Brian Salomon54d212e2017-03-21 14:22:38 -040017#include "GrProcessorSet.h"
csmartdaltonc633abb2016-11-01 08:55:55 -070018#include "GrStencilSettings.h"
bsalomonadd79ef2015-08-19 13:26:49 -070019
bsalomon1fcc01c2015-09-09 09:48:06 -070020#include "SkTLList.h"
21
Brian Salomon54d212e2017-03-21 14:22:38 -040022class GrPaint;
23
Brian Salomon82c263f2016-12-15 09:54:06 -050024class GrDrawPathOpBase : public GrDrawOp {
bsalomon1fcc01c2015-09-09 09:48:06 -070025protected:
Brian Salomon54d212e2017-03-21 14:22:38 -040026 GrDrawPathOpBase(uint32_t classID, const SkMatrix& viewMatrix, GrPaint&& paint,
27 GrPathRendering::FillType fill, GrAA aa);
28 FixedFunctionFlags fixedFunctionFlags() const override {
29 return FixedFunctionFlags::kUsesHWAA | FixedFunctionFlags::kUsesStencil;
Brian Salomonc48af932017-03-16 19:51:42 +000030 }
Brian Salomon54d212e2017-03-21 14:22:38 -040031 bool xpRequiresDstTexture(const GrCaps& caps, const GrAppliedClip* clip) override {
Brian Salomona811b122017-03-30 08:21:32 -040032 return this->doProcessorAnalysis(caps, clip).requiresDstTexture();
Brian Salomon54d212e2017-03-21 14:22:38 -040033 }
34
35 void wasRecorded() override { fProcessorSet.makePendingExecution(); }
Brian Salomon92aee3d2016-12-21 09:20:25 -050036
37protected:
joshualittf2384692015-09-10 11:00:51 -070038 const SkMatrix& viewMatrix() const { return fViewMatrix; }
Brian Salomon54d212e2017-03-21 14:22:38 -040039 GrColor color() const { return fAnalysis.inputColor(); }
cdalton193d9cf2016-05-12 11:52:02 -070040 GrPathRendering::FillType fillType() const { return fFillType; }
Brian Salomon54d212e2017-03-21 14:22:38 -040041 const GrProcessorSet& processors() const { return fProcessorSet; }
Brian Salomone7d30482017-03-29 12:09:15 -040042 void initPipeline(const GrOpFlushState&, GrPipeline*);
Brian Salomona811b122017-03-30 08:21:32 -040043 const GrProcessorSet::Analysis& doProcessorAnalysis(const GrCaps& caps,
44 const GrAppliedClip* clip) {
Brian Salomonc0b642c2017-03-27 13:09:36 -040045 fProcessorSet.analyzeAndEliminateFragmentProcessors(
Brian Salomona811b122017-03-30 08:21:32 -040046 &fAnalysis, fAnalysis.inputColor(), GrProcessorAnalysisCoverage::kNone, clip, caps);
Brian Salomon54d212e2017-03-21 14:22:38 -040047 return fAnalysis;
48 }
Brian Salomona811b122017-03-30 08:21:32 -040049 const GrProcessorSet::Analysis& processorAnalysis() const {
Brian Salomon54d212e2017-03-21 14:22:38 -040050 SkASSERT(fAnalysis.isInitializedWithProcessorSet());
51 return fAnalysis;
52 }
joshualittf2384692015-09-10 11:00:51 -070053
bsalomon1fcc01c2015-09-09 09:48:06 -070054private:
Brian Salomon54d212e2017-03-21 14:22:38 -040055 void onPrepare(GrOpFlushState*) final {}
cdalton193d9cf2016-05-12 11:52:02 -070056
Brian Salomon82c263f2016-12-15 09:54:06 -050057 SkMatrix fViewMatrix;
Brian Salomon54d212e2017-03-21 14:22:38 -040058 GrProcessorSet fProcessorSet;
Brian Salomona811b122017-03-30 08:21:32 -040059 GrProcessorSet::Analysis fAnalysis;
Brian Salomon82c263f2016-12-15 09:54:06 -050060 GrPathRendering::FillType fFillType;
Brian Salomon54d212e2017-03-21 14:22:38 -040061 GrAA fAA;
bsalomon1fcc01c2015-09-09 09:48:06 -070062
Brian Salomon9afd3712016-12-01 10:59:09 -050063 typedef GrDrawOp INHERITED;
bsalomon1fcc01c2015-09-09 09:48:06 -070064};
65
Brian Salomon82c263f2016-12-15 09:54:06 -050066class GrDrawPathOp final : public GrDrawPathOpBase {
bsalomon1fcc01c2015-09-09 09:48:06 -070067public:
Brian Salomon25a88092016-12-01 09:36:50 -050068 DEFINE_OP_CLASS_ID
reed1b55a962015-09-17 20:16:13 -070069
Brian Salomon54d212e2017-03-21 14:22:38 -040070 static std::unique_ptr<GrDrawOp> Make(const SkMatrix& viewMatrix, GrPaint&& paint, GrAA aa,
71 GrPath* path) {
72 return std::unique_ptr<GrDrawOp>(new GrDrawPathOp(viewMatrix, std::move(paint), aa, path));
bsalomonadd79ef2015-08-19 13:26:49 -070073 }
74
75 const char* name() const override { return "DrawPath"; }
76
bsalomon1fcc01c2015-09-09 09:48:06 -070077 SkString dumpInfo() const override;
bsalomonadd79ef2015-08-19 13:26:49 -070078
79private:
Brian Salomon54d212e2017-03-21 14:22:38 -040080 GrDrawPathOp(const SkMatrix& viewMatrix, GrPaint&& paint, GrAA aa, const GrPath* path)
81 : GrDrawPathOpBase(ClassID(), viewMatrix, std::move(paint), path->getFillType(), aa)
82 , fPath(path) {
bsalomon88cf17d2016-07-08 06:40:56 -070083 this->setTransformedBounds(path->getBounds(), viewMatrix, HasAABloat::kNo, IsZeroArea::kNo);
bsalomonadd79ef2015-08-19 13:26:49 -070084 }
stephana1dc17212016-04-25 07:01:22 -070085
Brian Salomon25a88092016-12-01 09:36:50 -050086 bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override { return false; }
bsalomonadd79ef2015-08-19 13:26:49 -070087
Brian Salomon9e50f7b2017-03-06 12:02:34 -050088 void onExecute(GrOpFlushState* state) override;
bsalomon1fcc01c2015-09-09 09:48:06 -070089
90 GrPendingIOResource<const GrPath, kRead_GrIOType> fPath;
stephana1dc17212016-04-25 07:01:22 -070091
Brian Salomon82c263f2016-12-15 09:54:06 -050092 typedef GrDrawPathOpBase INHERITED;
bsalomon1fcc01c2015-09-09 09:48:06 -070093};
94
bsalomon1fcc01c2015-09-09 09:48:06 -070095// Template this if we decide to support index types other than 16bit
Brian Salomon82c263f2016-12-15 09:54:06 -050096class GrDrawPathRangeOp final : public GrDrawPathOpBase {
bsalomon1fcc01c2015-09-09 09:48:06 -070097public:
cdaltoncdd46822015-12-08 10:48:31 -080098 typedef GrPathRendering::PathTransformType TransformType;
99
Brian Salomon25a88092016-12-01 09:36:50 -0500100 DEFINE_OP_CLASS_ID
reed1b55a962015-09-17 20:16:13 -0700101
Brian Salomonf8334782017-01-03 09:42:58 -0500102 struct InstanceData : private ::SkNoncopyable {
cdaltoncdd46822015-12-08 10:48:31 -0800103 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;
Brian Salomon82c263f2016-12-15 09:54:06 -0500116 SkDEBUGCODE(instanceData->fReserveCnt = reserveCnt);
cdaltoncdd46822015-12-08 10:48:31 -0800117 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
Brian Salomon82c263f2016-12-15 09:54:06 -0500153 uint16_t* fIndices;
154 float* fTransformValues;
155 TransformType fTransformType;
156 int fInstanceCount;
157 mutable int fRefCnt;
cdaltoncdd46822015-12-08 10:48:31 -0800158 SkDEBUGCODE(int fReserveCnt;)
159 };
160
Brian Salomonf8334782017-01-03 09:42:58 -0500161 static std::unique_ptr<GrDrawOp> Make(const SkMatrix& viewMatrix, SkScalar scale, SkScalar x,
Brian Salomon54d212e2017-03-21 14:22:38 -0400162 SkScalar y, GrPaint&& paint,
163 GrPathRendering::FillType fill, GrAA aa,
Brian Salomonf8334782017-01-03 09:42:58 -0500164 GrPathRange* range, const InstanceData* instanceData,
165 const SkRect& bounds) {
Brian Salomon54d212e2017-03-21 14:22:38 -0400166 return std::unique_ptr<GrDrawOp>(new GrDrawPathRangeOp(
167 viewMatrix, scale, x, y, std::move(paint), fill, aa, range, instanceData, bounds));
bsalomon1fcc01c2015-09-09 09:48:06 -0700168 }
169
bsalomon1fcc01c2015-09-09 09:48:06 -0700170 const char* name() const override { return "DrawPathRange"; }
171
172 SkString dumpInfo() const override;
173
174private:
Brian Salomon82c263f2016-12-15 09:54:06 -0500175 GrDrawPathRangeOp(const SkMatrix& viewMatrix, SkScalar scale, SkScalar x, SkScalar y,
Brian Salomon54d212e2017-03-21 14:22:38 -0400176 GrPaint&& paint, GrPathRendering::FillType fill, GrAA aa, GrPathRange* range,
Brian Salomon82c263f2016-12-15 09:54:06 -0500177 const InstanceData* instanceData, const SkRect& bounds);
cdaltoncdd46822015-12-08 10:48:31 -0800178
179 TransformType transformType() const { return fDraws.head()->fInstanceData->transformType(); }
bsalomon1fcc01c2015-09-09 09:48:06 -0700180
Brian Salomon25a88092016-12-01 09:36:50 -0500181 bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override;
bsalomon1fcc01c2015-09-09 09:48:06 -0700182
Brian Salomon9e50f7b2017-03-06 12:02:34 -0500183 void onExecute(GrOpFlushState* state) override;
bsalomon1fcc01c2015-09-09 09:48:06 -0700184
cdaltoncdd46822015-12-08 10:48:31 -0800185 struct Draw {
186 void set(const InstanceData* instanceData, SkScalar x, SkScalar y) {
187 fInstanceData.reset(SkRef(instanceData));
188 fX = x;
189 fY = y;
190 }
191
Hal Canary144caf52016-11-07 17:57:18 -0500192 sk_sp<const InstanceData> fInstanceData;
Brian Salomon82c263f2016-12-15 09:54:06 -0500193 SkScalar fX, fY;
cdaltoncdd46822015-12-08 10:48:31 -0800194 };
195
cdalton8585dd22015-10-08 08:04:09 -0700196 typedef GrPendingIOResource<const GrPathRange, kRead_GrIOType> PendingPathRange;
cdaltoncdd46822015-12-08 10:48:31 -0800197 typedef SkTLList<Draw, 4> DrawList;
198
Brian Salomon82c263f2016-12-15 09:54:06 -0500199 PendingPathRange fPathRange;
200 DrawList fDraws;
201 int fTotalPathCount;
202 SkScalar fScale;
bsalomon1fcc01c2015-09-09 09:48:06 -0700203
Brian Salomon82c263f2016-12-15 09:54:06 -0500204 typedef GrDrawPathOpBase INHERITED;
bsalomonadd79ef2015-08-19 13:26:49 -0700205};
206
207#endif