• Home
  • History
  • Annotate
  • 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 "GrProcessorSet.h"
9 #include "GrAppliedClip.h"
10 #include "GrCaps.h"
11 #include "GrPipelineAnalysis.h"
12 
GrProcessorSet(GrPaint && paint)13 GrProcessorSet::GrProcessorSet(GrPaint&& paint) {
14     fXPFactory = paint.fXPFactory;
15     fFlags = 0;
16     if (paint.numColorFragmentProcessors() <= kMaxColorProcessors) {
17         fColorFragmentProcessorCnt = paint.numColorFragmentProcessors();
18         fFragmentProcessors.reset(paint.numTotalFragmentProcessors());
19         int i = 0;
20         for (auto& fp : paint.fColorFragmentProcessors) {
21             fFragmentProcessors[i++] = fp.release();
22         }
23         for (auto& fp : paint.fCoverageFragmentProcessors) {
24             fFragmentProcessors[i++] = fp.release();
25         }
26         if (paint.usesDistanceVectorField()) {
27             fFlags |= kUseDistanceVectorField_Flag;
28         }
29     } else {
30         SkDebugf("Insane number of color fragment processors in paint. Dropping all processors.");
31         fColorFragmentProcessorCnt = 0;
32     }
33     if (paint.getDisableOutputConversionToSRGB()) {
34         fFlags |= kDisableOutputConversionToSRGB_Flag;
35     }
36     if (paint.getAllowSRGBInputs()) {
37         fFlags |= kAllowSRGBInputs_Flag;
38     }
39 }
40 
~GrProcessorSet()41 GrProcessorSet::~GrProcessorSet() {
42     for (int i = fFragmentProcessorOffset; i < fFragmentProcessors.count(); ++i) {
43         if (this->isPendingExecution()) {
44             fFragmentProcessors[i]->completedExecution();
45         } else {
46             fFragmentProcessors[i]->unref();
47         }
48     }
49 }
50 
makePendingExecution()51 void GrProcessorSet::makePendingExecution() {
52     SkASSERT(!(kPendingExecution_Flag & fFlags));
53     fFlags |= kPendingExecution_Flag;
54     for (int i = fFragmentProcessorOffset; i < fFragmentProcessors.count(); ++i) {
55         fFragmentProcessors[i]->addPendingExecution();
56         fFragmentProcessors[i]->unref();
57     }
58 }
59 
operator ==(const GrProcessorSet & that) const60 bool GrProcessorSet::operator==(const GrProcessorSet& that) const {
61     int fpCount = this->numFragmentProcessors();
62     if (((fFlags ^ that.fFlags) & ~kPendingExecution_Flag) ||
63         fpCount != that.numFragmentProcessors() ||
64         fColorFragmentProcessorCnt != that.fColorFragmentProcessorCnt) {
65         return false;
66     }
67 
68     for (int i = 0; i < fpCount; ++i) {
69         int a = i + fFragmentProcessorOffset;
70         int b = i + that.fFragmentProcessorOffset;
71         if (!fFragmentProcessors[a]->isEqual(*that.fFragmentProcessors[b])) {
72             return false;
73         }
74     }
75     if (fXPFactory != that.fXPFactory) {
76         return false;
77     }
78     return true;
79 }
80 
81 //////////////////////////////////////////////////////////////////////////////
82 
internalInit(const GrPipelineAnalysisColor & colorInput,const GrPipelineAnalysisCoverage coverageInput,const GrProcessorSet & processors,const GrFragmentProcessor * clipFP,const GrCaps & caps)83 void GrProcessorSet::FragmentProcessorAnalysis::internalInit(
84         const GrPipelineAnalysisColor& colorInput,
85         const GrPipelineAnalysisCoverage coverageInput,
86         const GrProcessorSet& processors,
87         const GrFragmentProcessor* clipFP,
88         const GrCaps& caps) {
89     GrColorFragmentProcessorAnalysis colorInfo(colorInput);
90     fCompatibleWithCoverageAsAlpha = GrPipelineAnalysisCoverage::kLCD != coverageInput;
91     fValidInputColor = colorInput.isConstant(&fInputColor);
92 
93     const GrFragmentProcessor* const* fps =
94             processors.fFragmentProcessors.get() + processors.fFragmentProcessorOffset;
95     colorInfo.analyzeProcessors(fps, processors.fColorFragmentProcessorCnt);
96     fCompatibleWithCoverageAsAlpha &= colorInfo.allProcessorsCompatibleWithCoverageAsAlpha();
97     fps += processors.fColorFragmentProcessorCnt;
98     int n = processors.numCoverageFragmentProcessors();
99     bool hasCoverageFP = n > 0;
100     fUsesLocalCoords = colorInfo.usesLocalCoords();
101     for (int i = 0; i < n; ++i) {
102         if (!fps[i]->compatibleWithCoverageAsAlpha()) {
103             fCompatibleWithCoverageAsAlpha = false;
104             // Other than tests that exercise atypical behavior we expect all coverage FPs to be
105             // compatible with the coverage-as-alpha optimization.
106             GrCapsDebugf(&caps, "Coverage FP is not compatible with coverage as alpha.\n");
107         }
108         fUsesLocalCoords |= fps[i]->usesLocalCoords();
109     }
110 
111     if (clipFP) {
112         fCompatibleWithCoverageAsAlpha &= clipFP->compatibleWithCoverageAsAlpha();
113         fUsesLocalCoords |= clipFP->usesLocalCoords();
114         hasCoverageFP = true;
115     }
116     fInitialColorProcessorsToEliminate = colorInfo.initialProcessorsToEliminate(&fInputColor);
117     fValidInputColor |= SkToBool(fInitialColorProcessorsToEliminate);
118 
119     GrPipelineAnalysisColor outputColor = colorInfo.outputColor();
120     if (outputColor.isConstant(&fKnownOutputColor)) {
121         fOutputColorType = static_cast<unsigned>(outputColor.isOpaque() ? ColorType::kOpaqueConstant
122                                                                         : ColorType::kConstant);
123     } else if (outputColor.isOpaque()) {
124         fOutputColorType = static_cast<unsigned>(ColorType::kOpaque);
125     } else {
126         fOutputColorType = static_cast<unsigned>(ColorType::kUnknown);
127     }
128 
129     if (GrPipelineAnalysisCoverage::kLCD == coverageInput) {
130         fOutputCoverageType = static_cast<unsigned>(GrPipelineAnalysisCoverage::kLCD);
131     } else if (hasCoverageFP || GrPipelineAnalysisCoverage::kSingleChannel == coverageInput) {
132         fOutputCoverageType = static_cast<unsigned>(GrPipelineAnalysisCoverage::kSingleChannel);
133     } else {
134         fOutputCoverageType = static_cast<unsigned>(GrPipelineAnalysisCoverage::kNone);
135     }
136 }
137 
init(const GrPipelineAnalysisColor & colorInput,const GrPipelineAnalysisCoverage coverageInput,const GrProcessorSet & processors,const GrAppliedClip * appliedClip,const GrCaps & caps)138 void GrProcessorSet::FragmentProcessorAnalysis::init(const GrPipelineAnalysisColor& colorInput,
139                                                      const GrPipelineAnalysisCoverage coverageInput,
140                                                      const GrProcessorSet& processors,
141                                                      const GrAppliedClip* appliedClip,
142                                                      const GrCaps& caps) {
143     const GrFragmentProcessor* clipFP =
144             appliedClip ? appliedClip->clipCoverageFragmentProcessor() : nullptr;
145     this->internalInit(colorInput, coverageInput, processors, clipFP, caps);
146     fIsInitializedWithProcessorSet = true;
147 }
148 
FragmentProcessorAnalysis(const GrPipelineAnalysisColor & colorInput,const GrPipelineAnalysisCoverage coverageInput,const GrCaps & caps)149 GrProcessorSet::FragmentProcessorAnalysis::FragmentProcessorAnalysis(
150         const GrPipelineAnalysisColor& colorInput,
151         const GrPipelineAnalysisCoverage coverageInput,
152         const GrCaps& caps)
153         : FragmentProcessorAnalysis() {
154     this->internalInit(colorInput, coverageInput, GrProcessorSet(GrPaint()), nullptr, caps);
155 }
156 
analyzeAndEliminateFragmentProcessors(FragmentProcessorAnalysis * analysis,const GrPipelineAnalysisColor & colorInput,const GrPipelineAnalysisCoverage coverageInput,const GrAppliedClip * clip,const GrCaps & caps)157 void GrProcessorSet::analyzeAndEliminateFragmentProcessors(
158         FragmentProcessorAnalysis* analysis,
159         const GrPipelineAnalysisColor& colorInput,
160         const GrPipelineAnalysisCoverage coverageInput,
161         const GrAppliedClip* clip,
162         const GrCaps& caps) {
163     analysis->init(colorInput, coverageInput, *this, clip, caps);
164     if (analysis->fInitialColorProcessorsToEliminate > 0) {
165         for (unsigned i = 0; i < analysis->fInitialColorProcessorsToEliminate; ++i) {
166             if (this->isPendingExecution()) {
167                 fFragmentProcessors[i + fFragmentProcessorOffset]->completedExecution();
168             } else {
169                 fFragmentProcessors[i + fFragmentProcessorOffset]->unref();
170             }
171             fFragmentProcessors[i + fFragmentProcessorOffset] = nullptr;
172         }
173         fFragmentProcessorOffset += analysis->fInitialColorProcessorsToEliminate;
174         fColorFragmentProcessorCnt -= analysis->fInitialColorProcessorsToEliminate;
175         SkASSERT(fFragmentProcessorOffset + fColorFragmentProcessorCnt <=
176                  fFragmentProcessors.count());
177         analysis->fInitialColorProcessorsToEliminate = 0;
178     }
179 }
180