• 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 "GrSimpleMeshDrawOpHelper.h"
9 #include "GrAppliedClip.h"
10 #include "GrProcessorSet.h"
11 #include "GrRect.h"
12 #include "GrUserStencilSettings.h"
13 
GrSimpleMeshDrawOpHelper(const MakeArgs & args,GrAAType aaType,Flags flags)14 GrSimpleMeshDrawOpHelper::GrSimpleMeshDrawOpHelper(const MakeArgs& args, GrAAType aaType,
15                                                    Flags flags)
16         : fProcessors(args.fProcessorSet)
17         , fPipelineFlags(0)
18         , fAAType((int)aaType)
19         , fUsesLocalCoords(false)
20         , fCompatibleWithAlphaAsCoveage(false) {
21     SkDEBUGCODE(fDidAnalysis = false);
22     SkDEBUGCODE(fMadePipeline = false);
23     if (GrAATypeIsHW(aaType)) {
24         fPipelineFlags |= GrPipeline::kHWAntialias_Flag;
25     }
26     if (flags & Flags::kSnapVerticesToPixelCenters) {
27         fPipelineFlags |= GrPipeline::kSnapVerticesToPixelCenters_Flag;
28     }
29 }
30 
~GrSimpleMeshDrawOpHelper()31 GrSimpleMeshDrawOpHelper::~GrSimpleMeshDrawOpHelper() {
32     if (fProcessors) {
33         fProcessors->~GrProcessorSet();
34     }
35 }
36 
fixedFunctionFlags() const37 GrDrawOp::FixedFunctionFlags GrSimpleMeshDrawOpHelper::fixedFunctionFlags() const {
38     return GrAATypeIsHW((this->aaType())) ? GrDrawOp::FixedFunctionFlags::kUsesHWAA
39                                           : GrDrawOp::FixedFunctionFlags::kNone;
40 }
41 
none_as_coverage_aa_compatible(GrAAType aa1,GrAAType aa2)42 static bool none_as_coverage_aa_compatible(GrAAType aa1, GrAAType aa2) {
43     return (aa1 == GrAAType::kNone && aa2 == GrAAType::kCoverage) ||
44            (aa1 == GrAAType::kCoverage && aa2 == GrAAType::kNone);
45 }
46 
isCompatible(const GrSimpleMeshDrawOpHelper & that,const GrCaps & caps,const SkRect & thisBounds,const SkRect & thatBounds,bool noneAsCoverageAA) const47 bool GrSimpleMeshDrawOpHelper::isCompatible(const GrSimpleMeshDrawOpHelper& that,
48                                             const GrCaps& caps, const SkRect& thisBounds,
49                                             const SkRect& thatBounds, bool noneAsCoverageAA) const {
50     if (SkToBool(fProcessors) != SkToBool(that.fProcessors)) {
51         return false;
52     }
53     if (fProcessors) {
54         if (*fProcessors != *that.fProcessors) {
55             return false;
56         }
57     }
58     bool result = fPipelineFlags == that.fPipelineFlags && (fAAType == that.fAAType ||
59             (noneAsCoverageAA && none_as_coverage_aa_compatible(this->aaType(), that.aaType())));
60     SkASSERT(!result || fCompatibleWithAlphaAsCoveage == that.fCompatibleWithAlphaAsCoveage);
61     SkASSERT(!result || fUsesLocalCoords == that.fUsesLocalCoords);
62     return result;
63 }
64 
finalizeProcessors(const GrCaps & caps,const GrAppliedClip * clip,GrProcessorAnalysisCoverage geometryCoverage,GrProcessorAnalysisColor * geometryColor)65 GrProcessorSet::Analysis GrSimpleMeshDrawOpHelper::finalizeProcessors(
66         const GrCaps& caps, const GrAppliedClip* clip, GrProcessorAnalysisCoverage geometryCoverage,
67         GrProcessorAnalysisColor* geometryColor) {
68     SkDEBUGCODE(fDidAnalysis = true);
69     GrProcessorSet::Analysis analysis;
70     if (fProcessors) {
71         GrProcessorAnalysisCoverage coverage = geometryCoverage;
72         if (GrProcessorAnalysisCoverage::kNone == coverage) {
73             coverage = clip->numClipCoverageFragmentProcessors()
74                                ? GrProcessorAnalysisCoverage::kSingleChannel
75                                : GrProcessorAnalysisCoverage::kNone;
76         }
77         bool isMixedSamples = this->aaType() == GrAAType::kMixedSamples;
78         SkPMColor4f overrideColor;
79         analysis = fProcessors->finalize(*geometryColor, coverage, clip, isMixedSamples, caps,
80                                          &overrideColor);
81         if (analysis.inputColorIsOverridden()) {
82             *geometryColor = overrideColor;
83         }
84     } else {
85         analysis = GrProcessorSet::EmptySetAnalysis();
86     }
87     fUsesLocalCoords = analysis.usesLocalCoords();
88     fCompatibleWithAlphaAsCoveage = analysis.isCompatibleWithCoverageAsAlpha();
89     return analysis;
90 }
91 
finalizeProcessors(const GrCaps & caps,const GrAppliedClip * clip,GrProcessorAnalysisCoverage geometryCoverage,SkPMColor4f * geometryColor)92 GrProcessorSet::Analysis GrSimpleMeshDrawOpHelper::finalizeProcessors(
93         const GrCaps& caps, const GrAppliedClip* clip, GrProcessorAnalysisCoverage geometryCoverage,
94         SkPMColor4f* geometryColor) {
95     GrProcessorAnalysisColor color = *geometryColor;
96     auto result = this->finalizeProcessors(caps, clip, geometryCoverage, &color);
97     color.isConstant(geometryColor);
98     return result;
99 }
100 
101 #ifdef SK_DEBUG
dumpInfo() const102 SkString GrSimpleMeshDrawOpHelper::dumpInfo() const {
103     const GrProcessorSet& processors = fProcessors ? *fProcessors : GrProcessorSet::EmptySet();
104     SkString result = processors.dumpProcessors();
105     result.append("AA Type: ");
106     switch (this->aaType()) {
107         case GrAAType::kNone:
108             result.append(" none\n");
109             break;
110         case GrAAType::kCoverage:
111             result.append(" coverage\n");
112             break;
113         case GrAAType::kMSAA:
114             result.append(" msaa\n");
115             break;
116         case GrAAType::kMixedSamples:
117             result.append(" mixed samples\n");
118             break;
119     }
120     result.append(GrPipeline::DumpFlags(fPipelineFlags));
121     return result;
122 }
123 #endif
124 
pipelineInitArgs(GrMeshDrawOp::Target * target) const125 GrPipeline::InitArgs GrSimpleMeshDrawOpHelper::pipelineInitArgs(
126         GrMeshDrawOp::Target* target) const {
127     GrPipeline::InitArgs args;
128     args.fFlags = this->pipelineFlags();
129     args.fDstProxy = target->dstProxy();
130     args.fCaps = &target->caps();
131     args.fResourceProvider = target->resourceProvider();
132     return args;
133 }
134 
internalMakePipeline(GrMeshDrawOp::Target * target,const GrPipeline::InitArgs & args,int numPrimitiveProcessorProxies)135 auto GrSimpleMeshDrawOpHelper::internalMakePipeline(GrMeshDrawOp::Target* target,
136                                                     const GrPipeline::InitArgs& args,
137                                                     int numPrimitiveProcessorProxies)
138         -> PipelineAndFixedDynamicState {
139     // A caller really should only call this once as the processor set and applied clip get
140     // moved into the GrPipeline.
141     SkASSERT(!fMadePipeline);
142     SkDEBUGCODE(fMadePipeline = true);
143     auto clip = target->detachAppliedClip();
144     GrPipeline::FixedDynamicState* fixedDynamicState = nullptr;
145     if (clip.scissorState().enabled() || numPrimitiveProcessorProxies) {
146         fixedDynamicState = target->allocFixedDynamicState(clip.scissorState().rect());
147         if (numPrimitiveProcessorProxies) {
148             fixedDynamicState->fPrimitiveProcessorTextures =
149                     target->allocPrimitiveProcessorTextureArray(numPrimitiveProcessorProxies);
150         }
151     }
152     if (fProcessors) {
153         return {target->allocPipeline(args, std::move(*fProcessors), std::move(clip)),
154                 fixedDynamicState};
155     } else {
156         return {target->allocPipeline(args, GrProcessorSet::MakeEmptySet(), std::move(clip)),
157                 fixedDynamicState};
158     }
159 }
160 
GrSimpleMeshDrawOpHelperWithStencil(const MakeArgs & args,GrAAType aaType,const GrUserStencilSettings * stencilSettings,Flags flags)161 GrSimpleMeshDrawOpHelperWithStencil::GrSimpleMeshDrawOpHelperWithStencil(
162         const MakeArgs& args, GrAAType aaType, const GrUserStencilSettings* stencilSettings,
163         Flags flags)
164         : INHERITED(args, aaType, flags)
165         , fStencilSettings(stencilSettings ? stencilSettings : &GrUserStencilSettings::kUnused) {}
166 
fixedFunctionFlags() const167 GrDrawOp::FixedFunctionFlags GrSimpleMeshDrawOpHelperWithStencil::fixedFunctionFlags() const {
168     GrDrawOp::FixedFunctionFlags flags = INHERITED::fixedFunctionFlags();
169     if (fStencilSettings != &GrUserStencilSettings::kUnused) {
170         flags |= GrDrawOp::FixedFunctionFlags::kUsesStencil;
171     }
172     return flags;
173 }
174 
isCompatible(const GrSimpleMeshDrawOpHelperWithStencil & that,const GrCaps & caps,const SkRect & thisBounds,const SkRect & thatBounds,bool noneAsCoverageAA) const175 bool GrSimpleMeshDrawOpHelperWithStencil::isCompatible(
176         const GrSimpleMeshDrawOpHelperWithStencil& that, const GrCaps& caps,
177         const SkRect& thisBounds, const SkRect& thatBounds, bool noneAsCoverageAA) const {
178     return INHERITED::isCompatible(that, caps, thisBounds, thatBounds, noneAsCoverageAA) &&
179            fStencilSettings == that.fStencilSettings;
180 }
181 
makePipeline(GrMeshDrawOp::Target * target,int numPrimitiveProcessorTextures)182 auto GrSimpleMeshDrawOpHelperWithStencil::makePipeline(GrMeshDrawOp::Target* target,
183                                                        int numPrimitiveProcessorTextures)
184         -> PipelineAndFixedDynamicState {
185     auto args = INHERITED::pipelineInitArgs(target);
186     args.fUserStencil = fStencilSettings;
187     return this->internalMakePipeline(target, args, numPrimitiveProcessorTextures);
188 }
189 
190 #ifdef SK_DEBUG
dumpInfo() const191 SkString GrSimpleMeshDrawOpHelperWithStencil::dumpInfo() const {
192     SkString result = INHERITED::dumpInfo();
193     result.appendf("Stencil settings: %s\n", (fStencilSettings ? "yes" : "no"));
194     return result;
195 }
196 #endif
197