Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
RegionOp.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2016 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
9
20
21using namespace skia_private;
22
24
25namespace {
26
27GrGeometryProcessor* make_gp(SkArenaAlloc* arena,
28 const SkMatrix& viewMatrix,
29 bool wideColor) {
30 using namespace GrDefaultGeoProcFactory;
31 Color::Type colorType = wideColor ? Color::kPremulWideColorAttribute_Type
32 : Color::kPremulGrColorAttribute_Type;
33 return GrDefaultGeoProcFactory::Make(arena, colorType, Coverage::kSolid_Type,
34 LocalCoords::kUsePosition_Type, viewMatrix);
35}
36
37class RegionOpImpl final : public GrMeshDrawOp {
38private:
40
41public:
43
44 static GrOp::Owner Make(GrRecordingContext* context,
45 GrPaint&& paint,
46 const SkMatrix& viewMatrix,
47 const SkRegion& region,
48 GrAAType aaType,
49 const GrUserStencilSettings* stencilSettings = nullptr) {
50 return Helper::FactoryHelper<RegionOpImpl>(context, std::move(paint), viewMatrix, region,
51 aaType, stencilSettings);
52 }
53
54 RegionOpImpl(GrProcessorSet* processorSet, const SkPMColor4f& color,
55 const SkMatrix& viewMatrix, const SkRegion& region, GrAAType aaType,
56 const GrUserStencilSettings* stencilSettings)
57 : INHERITED(ClassID())
58 , fHelper(processorSet, aaType, stencilSettings)
59 , fViewMatrix(viewMatrix) {
60 RegionInfo& info = fRegions.push_back();
61 info.fColor = color;
62 info.fRegion = region;
63
64 SkRect bounds = SkRect::Make(region.getBounds());
65 this->setTransformedBounds(bounds, viewMatrix, HasAABloat::kNo, IsHairline::kNo);
66 }
67
68 const char* name() const override { return "GrRegionOp"; }
69
70 void visitProxies(const GrVisitProxyFunc& func) const override {
71 if (fProgramInfo) {
72 fProgramInfo->visitFPProxies(func);
73 } else {
74 fHelper.visitProxies(func);
75 }
76 }
77
78 FixedFunctionFlags fixedFunctionFlags() const override { return fHelper.fixedFunctionFlags(); }
79
80 GrProcessorSet::Analysis finalize(const GrCaps& caps, const GrAppliedClip* clip,
81 GrClampType clampType) override {
82 return fHelper.finalizeProcessors(caps, clip, clampType, GrProcessorAnalysisCoverage::kNone,
83 &fRegions[0].fColor, &fWideColor);
84 }
85
86private:
87 GrProgramInfo* programInfo() override { return fProgramInfo; }
88
89 void onCreateProgramInfo(const GrCaps* caps,
90 SkArenaAlloc* arena,
91 const GrSurfaceProxyView& writeView,
92 bool usesMSAASurface,
93 GrAppliedClip&& appliedClip,
94 const GrDstProxyView& dstProxyView,
95 GrXferBarrierFlags renderPassXferBarriers,
96 GrLoadOp colorLoadOp) override {
97 GrGeometryProcessor* gp = make_gp(arena, fViewMatrix, fWideColor);
98 if (!gp) {
99 SkDebugf("Couldn't create GrGeometryProcessor\n");
100 return;
101 }
102
103 fProgramInfo = fHelper.createProgramInfoWithStencil(caps, arena, writeView, usesMSAASurface,
104 std::move(appliedClip), dstProxyView,
106 renderPassXferBarriers, colorLoadOp);
107 }
108
109 void onPrepareDraws(GrMeshDrawTarget* target) override {
110 if (!fProgramInfo) {
111 this->createProgramInfo(target);
112 if (!fProgramInfo) {
113 return;
114 }
115 }
116
117 int numRegions = fRegions.size();
118 int numRects = 0;
119 for (int i = 0; i < numRegions; i++) {
120 numRects += fRegions[i].fRegion.computeRegionComplexity();
121 }
122
123 if (!numRects) {
124 return;
125 }
126
127 QuadHelper helper(target, fProgramInfo->geomProc().vertexStride(), numRects);
128
129 VertexWriter vertices{helper.vertices()};
130 if (!vertices) {
131 SkDebugf("Could not allocate vertices\n");
132 return;
133 }
134
135 for (int i = 0; i < numRegions; i++) {
136 VertexColor color(fRegions[i].fColor, fWideColor);
137 SkRegion::Iterator iter(fRegions[i].fRegion);
138 while (!iter.done()) {
139 SkRect rect = SkRect::Make(iter.rect());
140 vertices.writeQuad(VertexWriter::TriStripFromRect(rect), color);
141 iter.next();
142 }
143 }
144
145 fMesh = helper.mesh();
146 }
147
148 void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override {
149 if (!fProgramInfo || !fMesh) {
150 return;
151 }
152
153 flushState->bindPipelineAndScissorClip(*fProgramInfo, chainBounds);
154 flushState->bindTextures(fProgramInfo->geomProc(), nullptr, fProgramInfo->pipeline());
155 flushState->drawMesh(*fMesh);
156 }
157
158 CombineResult onCombineIfPossible(GrOp* t, SkArenaAlloc*, const GrCaps& caps) override {
159 auto that = t->cast<RegionOpImpl>();
160 if (!fHelper.isCompatible(that->fHelper, caps, this->bounds(), that->bounds())) {
161 return CombineResult::kCannotCombine;
162 }
163
164 if (fViewMatrix != that->fViewMatrix) {
165 return CombineResult::kCannotCombine;
166 }
167
168 fRegions.push_back_n(that->fRegions.size(), that->fRegions.begin());
169 fWideColor |= that->fWideColor;
170 return CombineResult::kMerged;
171 }
172
173#if defined(GR_TEST_UTILS)
174 SkString onDumpInfo() const override {
175 SkString str = SkStringPrintf("# combined: %d\n", fRegions.size());
176 for (int i = 0; i < fRegions.size(); ++i) {
177 const RegionInfo& info = fRegions[i];
178 str.appendf("%d: Color: 0x%08x, Region with %d rects\n", i, info.fColor.toBytes_RGBA(),
179 info.fRegion.computeRegionComplexity());
180 }
181 str += fHelper.dumpInfo();
182 return str;
183 }
184#endif
185
186 struct RegionInfo {
189 };
190
191 Helper fHelper;
194 bool fWideColor;
195
196 GrSimpleMesh* fMesh = nullptr;
197 GrProgramInfo* fProgramInfo = nullptr;
198
199 using INHERITED = GrMeshDrawOp;
200};
201
202} // anonymous namespace
203
205 GrPaint&& paint,
206 const SkMatrix& viewMatrix,
207 const SkRegion& region,
208 GrAAType aaType,
209 const GrUserStencilSettings* stencilSettings) {
210 if (aaType != GrAAType::kNone && aaType != GrAAType::kMSAA) {
211 return nullptr;
212 }
213 return RegionOpImpl::Make(context, std::move(paint), viewMatrix, region, aaType,
214 stencilSettings);
215}
216
217} // namespace skgpu::ganesh::RegionOp
218
219#if defined(GR_TEST_UTILS)
220
222
223GR_DRAW_OP_TEST_DEFINE(RegionOp) {
224 SkRegion region;
225 int n = random->nextULessThan(200);
226 for (int i = 0; i < n; ++i) {
228 center.fX = random->nextULessThan(1000);
229 center.fY = random->nextULessThan(1000);
230 int w = random->nextRangeU(10, 1000);
231 int h = random->nextRangeU(10, 1000);
232 SkIRect rect = {center.fX - w / 2, center.fY - h / 2, center.fX + w / 2, center.fY + h / 2};
233 SkRegion::Op op;
234 if (i == 0) {
236 } else {
237 // Pick an other than replace.
239 op = (SkRegion::Op)random->nextULessThan(SkRegion::kLastOp);
240 }
241 region.op(rect, op);
242 }
243 SkMatrix viewMatrix = GrTest::TestMatrix(random);
244 GrAAType aaType = GrAAType::kNone;
245 if (numSamples > 1 && random->nextBool()) {
246 aaType = GrAAType::kMSAA;
247 }
248 return skgpu::ganesh::RegionOp::RegionOpImpl::Make(context,
249 std::move(paint),
250 viewMatrix,
251 region,
252 aaType,
253 GrGetRandomStencil(random, context));
254}
255
256#endif // defined(GR_TEST_UTILS)
SkMatrix fViewMatrix
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
#define DEFINE_OP_CLASS_ID
Definition GrOp.h:64
GrClampType
std::function< void(GrSurfaceProxy *, skgpu::Mipmapped)> GrVisitProxyFunc
GrAAType
GrLoadOp
GrXferBarrierFlags
SkColor4f color
SkRegion fRegion
Definition RegionOp.cpp:188
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static SkColorType colorType(AImageDecoder *decoder, const AImageDecoderHeaderInfo *headerInfo)
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
Definition SkPath.cpp:3824
#define INHERITED(method,...)
SK_API SkString static SkString SkStringPrintf()
Definition SkString.h:287
static SkScalar center(float pos0, float pos1)
void drawMesh(const GrSimpleMesh &mesh)
void bindPipelineAndScissorClip(const GrProgramInfo &programInfo, const SkRect &drawBounds)
void bindTextures(const GrGeometryProcessor &geomProc, const GrSurfaceProxy &singleGeomProcTexture, const GrPipeline &pipeline)
Definition GrOp.h:70
std::unique_ptr< GrOp > Owner
Definition GrOp.h:72
const T & cast() const
Definition GrOp.h:148
const GrPipeline & pipeline() const
const GrGeometryProcessor & geomProc() const
void visitFPProxies(const GrVisitProxyFunc &func) const
GrProcessorSet::Analysis finalizeProcessors(const GrCaps &caps, const GrAppliedClip *clip, GrClampType clampType, GrProcessorAnalysisCoverage geometryCoverage, GrProcessorAnalysisColor *geometryColor)
void visitProxies(const GrVisitProxyFunc &func) const
GrDrawOp::FixedFunctionFlags fixedFunctionFlags() const
bool isCompatible(const GrSimpleMeshDrawOpHelperWithStencil &that, const GrCaps &, const SkRect &thisBounds, const SkRect &thatBounds, bool ignoreAAType=false) const
GrProgramInfo * createProgramInfoWithStencil(const GrCaps *, SkArenaAlloc *, const GrSurfaceProxyView &writeView, bool usesMSAASurface, GrAppliedClip &&, const GrDstProxyView &, GrGeometryProcessor *, GrPrimitiveType, GrXferBarrierFlags renderPassXferBarriers, GrLoadOp colorLoadOp)
const SkIRect & rect() const
Definition SkRegion.h:501
bool done() const
Definition SkRegion.h:488
@ kLastOp
last operator
Definition SkRegion.h:373
@ kReplace_Op
replace target with operand
Definition SkRegion.h:372
const SkIRect & getBounds() const
Definition SkRegion.h:165
bool op(const SkIRect &rect, Op op)
Definition SkRegion.h:384
void void void appendf(const char format[],...) SK_PRINTF_LIKE(2
Definition SkString.cpp:550
const Paint & paint
uint32_t * target
const char * name
Definition fuchsia.cc:50
GrGeometryProcessor * Make(SkArenaAlloc *, const Color &, const Coverage &, const LocalCoords &, const SkMatrix &viewMatrix)
ClipOpAndAA opAA SkRegion region
Definition SkRecords.h:238
void Helper(uword arg)
GrOp::Owner Make(GrRecordingContext *context, GrPaint &&paint, const SkMatrix &viewMatrix, const SkRegion &region, GrAAType aaType, const GrUserStencilSettings *stencilSettings)
Definition RegionOp.cpp:204
SkScalar w
SkScalar h
int32_t fX
x-axis value
static SkRect Make(const SkISize &size)
Definition SkRect.h:669
static TriStrip< float > TriStripFromRect(const SkRect &r)