• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2017 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 #include "src/gpu/ops/GrSimpleMeshDrawOpHelper.h"
9 
10 #include "src/gpu/GrAppliedClip.h"
11 #include "src/gpu/GrProcessorSet.h"
12 #include "src/gpu/GrProgramInfo.h"
13 #include "src/gpu/GrUserStencilSettings.h"
14 #include "src/gpu/SkGr.h"
15 #include "src/gpu/geometry/GrRect.h"
16 
GrSimpleMeshDrawOpHelper(GrProcessorSet * processorSet,GrAAType aaType,InputFlags inputFlags)17 GrSimpleMeshDrawOpHelper::GrSimpleMeshDrawOpHelper(GrProcessorSet* processorSet,
18                                                    GrAAType aaType,
19                                                    InputFlags inputFlags)
20         : fProcessors(processorSet)
21         , fPipelineFlags((GrPipeline::InputFlags)inputFlags)
22         , fAAType((int)aaType)
23         , fUsesLocalCoords(false)
24         , fCompatibleWithCoverageAsAlpha(false) {
25     SkDEBUGCODE(fDidAnalysis = false);
26     SkDEBUGCODE(fMadePipeline = false);
27 }
28 
~GrSimpleMeshDrawOpHelper()29 GrSimpleMeshDrawOpHelper::~GrSimpleMeshDrawOpHelper() {
30     if (fProcessors) {
31         fProcessors->~GrProcessorSet();
32     }
33 }
34 
fixedFunctionFlags() const35 GrDrawOp::FixedFunctionFlags GrSimpleMeshDrawOpHelper::fixedFunctionFlags() const {
36     return GrAATypeIsHW(this->aaType()) ? GrDrawOp::FixedFunctionFlags::kUsesHWAA
37                                         : GrDrawOp::FixedFunctionFlags::kNone;
38 }
39 
isCompatible(const GrSimpleMeshDrawOpHelper & that,const GrCaps & caps,const SkRect & thisBounds,const SkRect & thatBounds,bool ignoreAAType) const40 bool GrSimpleMeshDrawOpHelper::isCompatible(const GrSimpleMeshDrawOpHelper& that,
41                                             const GrCaps& caps, const SkRect& thisBounds,
42                                             const SkRect& thatBounds, bool ignoreAAType) const {
43     if (SkToBool(fProcessors) != SkToBool(that.fProcessors)) {
44         return false;
45     }
46     if (fProcessors) {
47         if (*fProcessors != *that.fProcessors) {
48             return false;
49         }
50     }
51 
52 #ifdef SK_DEBUG
53     if (ignoreAAType) {
54         // If we're ignoring AA it should be bc we already know they are the same or that
55         // the are different but are compatible (i.e., one is AA and the other is None)
56         SkASSERT(fAAType == that.fAAType ||
57                  GrMeshDrawOp::CanUpgradeAAOnMerge(this->aaType(), that.aaType()));
58     }
59 #endif
60 
61     bool result = fPipelineFlags == that.fPipelineFlags &&
62                   (ignoreAAType || fAAType == that.fAAType);
63     SkASSERT(!result || fCompatibleWithCoverageAsAlpha == that.fCompatibleWithCoverageAsAlpha);
64     SkASSERT(!result || fUsesLocalCoords == that.fUsesLocalCoords);
65     return result;
66 }
67 
finalizeProcessors(const GrCaps & caps,const GrAppliedClip * clip,GrClampType clampType,GrProcessorAnalysisCoverage geometryCoverage,SkPMColor4f * geometryColor,bool * wideColor)68 GrProcessorSet::Analysis GrSimpleMeshDrawOpHelper::finalizeProcessors(
69         const GrCaps& caps, const GrAppliedClip* clip, GrClampType clampType,
70         GrProcessorAnalysisCoverage geometryCoverage, SkPMColor4f* geometryColor, bool* wideColor) {
71     GrProcessorAnalysisColor color = *geometryColor;
72     auto result = this->finalizeProcessors(caps, clip, clampType, geometryCoverage, &color);
73     color.isConstant(geometryColor);
74     if (wideColor) {
75         *wideColor = !geometryColor->fitsInBytes();
76     }
77     return result;
78 }
79 
finalizeProcessors(const GrCaps & caps,const GrAppliedClip * clip,const GrUserStencilSettings * userStencil,GrClampType clampType,GrProcessorAnalysisCoverage geometryCoverage,GrProcessorAnalysisColor * geometryColor)80 GrProcessorSet::Analysis GrSimpleMeshDrawOpHelper::finalizeProcessors(
81         const GrCaps& caps, const GrAppliedClip* clip, const GrUserStencilSettings* userStencil,
82         GrClampType clampType, GrProcessorAnalysisCoverage geometryCoverage,
83         GrProcessorAnalysisColor* geometryColor) {
84     SkDEBUGCODE(fDidAnalysis = true);
85     GrProcessorSet::Analysis analysis;
86     if (fProcessors) {
87         GrProcessorAnalysisCoverage coverage = geometryCoverage;
88         if (GrProcessorAnalysisCoverage::kNone == coverage) {
89             coverage = (clip && clip->hasCoverageFragmentProcessor())
90                                ? GrProcessorAnalysisCoverage::kSingleChannel
91                                : GrProcessorAnalysisCoverage::kNone;
92         }
93         SkPMColor4f overrideColor;
94         analysis = fProcessors->finalize(*geometryColor, coverage, clip, userStencil, caps,
95                                          clampType, &overrideColor);
96         if (analysis.inputColorIsOverridden()) {
97             *geometryColor = overrideColor;
98         }
99     } else {
100         analysis = GrProcessorSet::EmptySetAnalysis();
101     }
102     fUsesLocalCoords = analysis.usesLocalCoords();
103     fCompatibleWithCoverageAsAlpha = analysis.isCompatibleWithCoverageAsAlpha();
104     return analysis;
105 }
106 
CreatePipeline(const GrCaps * caps,SkArenaAlloc * arena,GrSwizzle writeViewSwizzle,GrAppliedClip && appliedClip,const GrDstProxyView & dstProxyView,GrProcessorSet && processorSet,GrPipeline::InputFlags pipelineFlags)107 const GrPipeline* GrSimpleMeshDrawOpHelper::CreatePipeline(
108                                                 const GrCaps* caps,
109                                                 SkArenaAlloc* arena,
110                                                 GrSwizzle writeViewSwizzle,
111                                                 GrAppliedClip&& appliedClip,
112                                                 const GrDstProxyView& dstProxyView,
113                                                 GrProcessorSet&& processorSet,
114                                                 GrPipeline::InputFlags pipelineFlags) {
115     GrPipeline::InitArgs pipelineArgs;
116 
117     pipelineArgs.fInputFlags = pipelineFlags;
118     pipelineArgs.fCaps = caps;
119     pipelineArgs.fDstProxyView = dstProxyView;
120     pipelineArgs.fWriteSwizzle = writeViewSwizzle;
121 
122     return arena->make<GrPipeline>(pipelineArgs,
123                                    std::move(processorSet),
124                                    std::move(appliedClip));
125 }
126 
CreatePipeline(GrOpFlushState * flushState,GrProcessorSet && processorSet,GrPipeline::InputFlags pipelineFlags)127 const GrPipeline* GrSimpleMeshDrawOpHelper::CreatePipeline(
128                                                 GrOpFlushState* flushState,
129                                                 GrProcessorSet&& processorSet,
130                                                 GrPipeline::InputFlags pipelineFlags) {
131     return CreatePipeline(&flushState->caps(),
132                           flushState->allocator(),
133                           flushState->writeView().swizzle(),
134                           flushState->detachAppliedClip(),
135                           flushState->dstProxyView(),
136                           std::move(processorSet),
137                           pipelineFlags);
138 }
139 
createPipeline(GrOpFlushState * flushState)140 const GrPipeline* GrSimpleMeshDrawOpHelper::createPipeline(GrOpFlushState* flushState) {
141     return CreatePipeline(&flushState->caps(),
142                           flushState->allocator(),
143                           flushState->writeView().swizzle(),
144                           flushState->detachAppliedClip(),
145                           flushState->dstProxyView(),
146                           this->detachProcessorSet(),
147                           this->pipelineFlags());
148 }
149 
createPipeline(const GrCaps * caps,SkArenaAlloc * arena,GrSwizzle writeViewSwizzle,GrAppliedClip && appliedClip,const GrDstProxyView & dstProxyView)150 const GrPipeline* GrSimpleMeshDrawOpHelper::createPipeline(
151         const GrCaps* caps,
152         SkArenaAlloc* arena,
153         GrSwizzle writeViewSwizzle,
154         GrAppliedClip&& appliedClip,
155         const GrDstProxyView& dstProxyView) {
156     return GrSimpleMeshDrawOpHelper::CreatePipeline(caps,
157                                                     arena,
158                                                     writeViewSwizzle,
159                                                     std::move(appliedClip),
160                                                     dstProxyView,
161                                                     this->detachProcessorSet(),
162                                                     this->pipelineFlags());
163 }
164 
CreateProgramInfo(const GrCaps * caps,SkArenaAlloc * arena,const GrSurfaceProxyView & writeView,bool usesMSAASurface,GrAppliedClip && appliedClip,const GrDstProxyView & dstProxyView,GrGeometryProcessor * geometryProcessor,GrProcessorSet && processorSet,GrPrimitiveType primitiveType,GrXferBarrierFlags renderPassXferBarriers,GrLoadOp colorLoadOp,GrPipeline::InputFlags pipelineFlags,const GrUserStencilSettings * stencilSettings)165 GrProgramInfo* GrSimpleMeshDrawOpHelper::CreateProgramInfo(
166             const GrCaps* caps,
167             SkArenaAlloc* arena,
168             const GrSurfaceProxyView& writeView,
169             bool usesMSAASurface,
170             GrAppliedClip&& appliedClip,
171             const GrDstProxyView& dstProxyView,
172             GrGeometryProcessor* geometryProcessor,
173             GrProcessorSet&& processorSet,
174             GrPrimitiveType primitiveType,
175             GrXferBarrierFlags renderPassXferBarriers,
176             GrLoadOp colorLoadOp,
177             GrPipeline::InputFlags pipelineFlags,
178             const GrUserStencilSettings* stencilSettings) {
179     auto pipeline = CreatePipeline(caps,
180                                    arena,
181                                    writeView.swizzle(),
182                                    std::move(appliedClip),
183                                    dstProxyView,
184                                    std::move(processorSet),
185                                    pipelineFlags);
186 
187     return CreateProgramInfo(caps, arena, pipeline, writeView, usesMSAASurface, geometryProcessor,
188                              primitiveType, renderPassXferBarriers, colorLoadOp, stencilSettings);
189 }
190 
CreateProgramInfo(const GrCaps * caps,SkArenaAlloc * arena,const GrPipeline * pipeline,const GrSurfaceProxyView & writeView,bool usesMSAASurface,GrGeometryProcessor * geometryProcessor,GrPrimitiveType primitiveType,GrXferBarrierFlags xferBarrierFlags,GrLoadOp colorLoadOp,const GrUserStencilSettings * stencilSettings)191 GrProgramInfo* GrSimpleMeshDrawOpHelper::CreateProgramInfo(const GrCaps* caps,
192                                                            SkArenaAlloc* arena,
193                                                            const GrPipeline* pipeline,
194                                                            const GrSurfaceProxyView& writeView,
195                                                            bool usesMSAASurface,
196                                                            GrGeometryProcessor* geometryProcessor,
197                                                            GrPrimitiveType primitiveType,
198                                                            GrXferBarrierFlags xferBarrierFlags,
199                                                            GrLoadOp colorLoadOp,
200                                                            const GrUserStencilSettings* stencilSettings) {
201     auto tmp = arena->make<GrProgramInfo>(*caps,
202                                           writeView,
203                                           usesMSAASurface,
204                                           pipeline,
205                                           stencilSettings,
206                                           geometryProcessor,
207                                           primitiveType,
208                                           0,
209                                           xferBarrierFlags,
210                                           colorLoadOp);
211     return tmp;
212 }
213 
createProgramInfo(const GrCaps * caps,SkArenaAlloc * arena,const GrSurfaceProxyView & writeView,bool usesMSAASurface,GrAppliedClip && appliedClip,const GrDstProxyView & dstProxyView,GrGeometryProcessor * gp,GrPrimitiveType primType,GrXferBarrierFlags renderPassXferBarriers,GrLoadOp colorLoadOp)214 GrProgramInfo* GrSimpleMeshDrawOpHelper::createProgramInfo(
215                                             const GrCaps* caps,
216                                             SkArenaAlloc* arena,
217                                             const GrSurfaceProxyView& writeView,
218                                             bool usesMSAASurface,
219                                             GrAppliedClip&& appliedClip,
220                                             const GrDstProxyView& dstProxyView,
221                                             GrGeometryProcessor* gp,
222                                             GrPrimitiveType primType,
223                                             GrXferBarrierFlags renderPassXferBarriers,
224                                             GrLoadOp colorLoadOp) {
225     return CreateProgramInfo(caps,
226                              arena,
227                              writeView,
228                              usesMSAASurface,
229                              std::move(appliedClip),
230                              dstProxyView,
231                              gp,
232                              this->detachProcessorSet(),
233                              primType,
234                              renderPassXferBarriers,
235                              colorLoadOp,
236                              this->pipelineFlags());
237 }
238 
239 #if GR_TEST_UTILS
dump_pipeline_flags(GrPipeline::InputFlags flags,SkString * result)240 static void dump_pipeline_flags(GrPipeline::InputFlags flags, SkString* result) {
241     if (GrPipeline::InputFlags::kNone != flags) {
242         if (flags & GrPipeline::InputFlags::kSnapVerticesToPixelCenters) {
243             result->append("Snap vertices to pixel center.\n");
244         }
245         if (flags & GrPipeline::InputFlags::kWireframe) {
246             result->append("Wireframe enabled.\n");
247         }
248         if (flags & GrPipeline::InputFlags::kConservativeRaster) {
249             result->append("Conservative raster enabled.\n");
250         }
251         return;
252     }
253     result->append("No pipeline flags\n");
254 }
255 
dumpInfo() const256 SkString GrSimpleMeshDrawOpHelper::dumpInfo() const {
257     const GrProcessorSet& processors = fProcessors ? *fProcessors : GrProcessorSet::EmptySet();
258     SkString result = processors.dumpProcessors();
259     result.append("AA Type: ");
260     switch (this->aaType()) {
261         case GrAAType::kNone:
262             result.append(" none\n");
263             break;
264         case GrAAType::kCoverage:
265             result.append(" coverage\n");
266             break;
267         case GrAAType::kMSAA:
268             result.append(" msaa\n");
269             break;
270     }
271     dump_pipeline_flags(fPipelineFlags, &result);
272     return result;
273 }
274 #endif
275