• 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(args.fSRGBFlags)
18         , fAAType((int)aaType)
19         , fRequiresDstTexture(false)
20         , fUsesLocalCoords(false)
21         , fCompatibleWithAlphaAsCoveage(false) {
22     SkDEBUGCODE(fDidAnalysis = false);
23     SkDEBUGCODE(fMadePipeline = false);
24     if (GrAATypeIsHW(aaType)) {
25         fPipelineFlags |= GrPipeline::kHWAntialias_Flag;
26     }
27     if (flags & Flags::kSnapVerticesToPixelCenters) {
28         fPipelineFlags |= GrPipeline::kSnapVerticesToPixelCenters_Flag;
29     }
30 }
31 
~GrSimpleMeshDrawOpHelper()32 GrSimpleMeshDrawOpHelper::~GrSimpleMeshDrawOpHelper() {
33     if (fProcessors) {
34         fProcessors->~GrProcessorSet();
35     }
36 }
37 
fixedFunctionFlags() const38 GrDrawOp::FixedFunctionFlags GrSimpleMeshDrawOpHelper::fixedFunctionFlags() const {
39     return GrAATypeIsHW((this->aaType())) ? GrDrawOp::FixedFunctionFlags::kUsesHWAA
40                                           : GrDrawOp::FixedFunctionFlags::kNone;
41 }
42 
isCompatible(const GrSimpleMeshDrawOpHelper & that,const GrCaps & caps,const SkRect & thisBounds,const SkRect & thatBounds) const43 bool GrSimpleMeshDrawOpHelper::isCompatible(const GrSimpleMeshDrawOpHelper& that,
44                                             const GrCaps& caps, const SkRect& thisBounds,
45                                             const SkRect& thatBounds) const {
46     if (SkToBool(fProcessors) != SkToBool(that.fProcessors)) {
47         return false;
48     }
49     if (fProcessors) {
50         if (*fProcessors != *that.fProcessors) {
51             return false;
52         }
53         if (fRequiresDstTexture ||
54             (fProcessors->xferProcessor() && fProcessors->xferProcessor()->xferBarrierType(caps))) {
55             if (GrRectsTouchOrOverlap(thisBounds, thatBounds)) {
56                 return false;
57             }
58         }
59     }
60     bool result = fPipelineFlags == that.fPipelineFlags && fAAType == that.fAAType;
61     SkASSERT(!result || fCompatibleWithAlphaAsCoveage == that.fCompatibleWithAlphaAsCoveage);
62     SkASSERT(!result || fUsesLocalCoords == that.fUsesLocalCoords);
63     return result;
64 }
65 
xpRequiresDstTexture(const GrCaps & caps,const GrAppliedClip * clip,GrPixelConfigIsClamped dstIsClamped,GrProcessorAnalysisCoverage geometryCoverage,GrProcessorAnalysisColor * geometryColor)66 GrDrawOp::RequiresDstTexture GrSimpleMeshDrawOpHelper::xpRequiresDstTexture(
67         const GrCaps& caps, const GrAppliedClip* clip, GrPixelConfigIsClamped dstIsClamped,
68         GrProcessorAnalysisCoverage geometryCoverage, GrProcessorAnalysisColor* geometryColor) {
69     SkDEBUGCODE(fDidAnalysis = true);
70     GrProcessorSet::Analysis analysis;
71     if (fProcessors) {
72         GrProcessorAnalysisCoverage coverage = geometryCoverage;
73         if (GrProcessorAnalysisCoverage::kNone == coverage) {
74             coverage = clip->numClipCoverageFragmentProcessors()
75                                ? GrProcessorAnalysisCoverage::kSingleChannel
76                                : GrProcessorAnalysisCoverage::kNone;
77         }
78         bool isMixedSamples = this->aaType() == GrAAType::kMixedSamples;
79         GrColor overrideColor;
80         analysis = fProcessors->finalize(*geometryColor, coverage, clip, isMixedSamples, caps,
81                                          dstIsClamped, &overrideColor);
82         if (analysis.inputColorIsOverridden()) {
83             *geometryColor = overrideColor;
84         }
85     } else {
86         analysis = GrProcessorSet::EmptySetAnalysis();
87     }
88     fRequiresDstTexture = analysis.requiresDstTexture();
89     fUsesLocalCoords = analysis.usesLocalCoords();
90     fCompatibleWithAlphaAsCoveage = analysis.isCompatibleWithCoverageAsAlpha();
91     return analysis.requiresDstTexture() ? GrDrawOp::RequiresDstTexture::kYes
92                                          : GrDrawOp::RequiresDstTexture::kNo;
93 }
94 
xpRequiresDstTexture(const GrCaps & caps,const GrAppliedClip * clip,GrPixelConfigIsClamped dstIsClamped,GrProcessorAnalysisCoverage geometryCoverage,GrColor * geometryColor)95 GrDrawOp::RequiresDstTexture GrSimpleMeshDrawOpHelper::xpRequiresDstTexture(
96         const GrCaps& caps, const GrAppliedClip* clip, GrPixelConfigIsClamped dstIsClamped,
97         GrProcessorAnalysisCoverage geometryCoverage, GrColor* geometryColor) {
98     GrProcessorAnalysisColor color = *geometryColor;
99     auto result = this->xpRequiresDstTexture(caps, clip, dstIsClamped, geometryCoverage, &color);
100     color.isConstant(geometryColor);
101     return result;
102 }
103 
dumpInfo() const104 SkString GrSimpleMeshDrawOpHelper::dumpInfo() const {
105     const GrProcessorSet& processors = fProcessors ? *fProcessors : GrProcessorSet::EmptySet();
106     SkString result = processors.dumpProcessors();
107     result.append("AA Type: ");
108     switch (this->aaType()) {
109         case GrAAType::kNone:
110             result.append(" none\n");
111             break;
112         case GrAAType::kCoverage:
113             result.append(" coverage\n");
114             break;
115         case GrAAType::kMSAA:
116             result.append(" msaa\n");
117             break;
118         case GrAAType::kMixedSamples:
119             result.append(" mixed samples\n");
120             break;
121     }
122     result.append(GrPipeline::DumpFlags(fPipelineFlags));
123     return result;
124 }
125 
pipelineInitArgs(GrMeshDrawOp::Target * target) const126 GrPipeline::InitArgs GrSimpleMeshDrawOpHelper::pipelineInitArgs(
127         GrMeshDrawOp::Target* target) const {
128     GrPipeline::InitArgs args;
129     args.fFlags = this->pipelineFlags();
130     args.fProxy = target->proxy();
131     args.fDstProxy = target->dstProxy();
132     args.fCaps = &target->caps();
133     args.fResourceProvider = target->resourceProvider();
134     return args;
135 }
136 
internalMakePipeline(GrMeshDrawOp::Target * target,const GrPipeline::InitArgs & args)137 GrPipeline* GrSimpleMeshDrawOpHelper::internalMakePipeline(GrMeshDrawOp::Target* target,
138                                                            const GrPipeline::InitArgs& args) {
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     if (fProcessors) {
144         return target->allocPipeline(args, std::move(*fProcessors), target->detachAppliedClip());
145     } else {
146         return target->allocPipeline(args, GrProcessorSet::MakeEmptySet(),
147                                      target->detachAppliedClip());
148     }
149 }
150 
GrSimpleMeshDrawOpHelperWithStencil(const MakeArgs & args,GrAAType aaType,const GrUserStencilSettings * stencilSettings,Flags flags)151 GrSimpleMeshDrawOpHelperWithStencil::GrSimpleMeshDrawOpHelperWithStencil(
152         const MakeArgs& args, GrAAType aaType, const GrUserStencilSettings* stencilSettings,
153         Flags flags)
154         : INHERITED(args, aaType, flags)
155         , fStencilSettings(stencilSettings ? stencilSettings : &GrUserStencilSettings::kUnused) {}
156 
fixedFunctionFlags() const157 GrDrawOp::FixedFunctionFlags GrSimpleMeshDrawOpHelperWithStencil::fixedFunctionFlags() const {
158     GrDrawOp::FixedFunctionFlags flags = INHERITED::fixedFunctionFlags();
159     if (fStencilSettings != &GrUserStencilSettings::kUnused) {
160         flags |= GrDrawOp::FixedFunctionFlags::kUsesStencil;
161     }
162     return flags;
163 }
164 
isCompatible(const GrSimpleMeshDrawOpHelperWithStencil & that,const GrCaps & caps,const SkRect & thisBounds,const SkRect & thatBounds) const165 bool GrSimpleMeshDrawOpHelperWithStencil::isCompatible(
166         const GrSimpleMeshDrawOpHelperWithStencil& that, const GrCaps& caps,
167         const SkRect& thisBounds, const SkRect& thatBounds) const {
168     return INHERITED::isCompatible(that, caps, thisBounds, thatBounds) &&
169            fStencilSettings == that.fStencilSettings;
170 }
171 
makePipeline(GrMeshDrawOp::Target * target)172 const GrPipeline* GrSimpleMeshDrawOpHelperWithStencil::makePipeline(
173         GrMeshDrawOp::Target* target) {
174     auto args = INHERITED::pipelineInitArgs(target);
175     args.fUserStencil = fStencilSettings;
176     return this->internalMakePipeline(target, args);
177 }
178 
dumpInfo() const179 SkString GrSimpleMeshDrawOpHelperWithStencil::dumpInfo() const {
180     SkString result = INHERITED::dumpInfo();
181     result.appendf("Stencil settings: %s\n", (fStencilSettings ? "yes" : "no"));
182     return result;
183 }
184