• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2014 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 #ifndef GrProcessorAnalysis_DEFINED
9 #define GrProcessorAnalysis_DEFINED
10 
11 #include "include/private/SkColorData.h"
12 
13 #include <memory>
14 
15 class GrCaps;
16 class GrDrawOp;
17 class GrFragmentProcessor;
18 
19 class GrProcessorAnalysisColor {
20 public:
21     enum class Opaque {
22         kNo,
23         kYes,
24     };
25 
26     constexpr GrProcessorAnalysisColor(Opaque opaque = Opaque::kNo)
27             : fFlags(opaque == Opaque::kYes ? kIsOpaque_Flag : 0)
28             , fColor(SK_PMColor4fTRANSPARENT) {}
29 
GrProcessorAnalysisColor(const SkPMColor4f & color)30     GrProcessorAnalysisColor(const SkPMColor4f& color) { this->setToConstant(color); }
31 
setToConstant(const SkPMColor4f & color)32     void setToConstant(const SkPMColor4f& color) {
33         fColor = color;
34         if (color.isOpaque()) {
35             fFlags = kColorIsKnown_Flag | kIsOpaque_Flag;
36         } else {
37             fFlags = kColorIsKnown_Flag;
38         }
39     }
40 
setToUnknown()41     void setToUnknown() { fFlags = 0; }
42 
setToUnknownOpaque()43     void setToUnknownOpaque() { fFlags = kIsOpaque_Flag; }
44 
isUnknown()45     bool isUnknown() const { return SkToBool(fFlags == 0); }
46 
isOpaque()47     bool isOpaque() const { return SkToBool(kIsOpaque_Flag & fFlags); }
48 
49     bool isConstant(SkPMColor4f* color = nullptr) const {
50         if (kColorIsKnown_Flag & fFlags) {
51             if (color) {
52                 *color = fColor;
53             }
54             return true;
55         }
56         return false;
57     }
58 
59     bool operator==(const GrProcessorAnalysisColor& that) const {
60         if (fFlags != that.fFlags) {
61             return false;
62         }
63         return (kColorIsKnown_Flag & fFlags) ? fColor == that.fColor : true;
64     }
65 
66     /** The returned value reflects the common properties of the two inputs. */
Combine(const GrProcessorAnalysisColor & a,const GrProcessorAnalysisColor & b)67     static GrProcessorAnalysisColor Combine(const GrProcessorAnalysisColor& a,
68                                             const GrProcessorAnalysisColor& b) {
69         GrProcessorAnalysisColor result;
70         uint32_t commonFlags = a.fFlags & b.fFlags;
71         if ((kColorIsKnown_Flag & commonFlags) && a.fColor == b.fColor) {
72             result.fColor = a.fColor;
73             result.fFlags = a.fFlags;
74         } else if (kIsOpaque_Flag & commonFlags) {
75             result.fFlags = kIsOpaque_Flag;
76         }
77         return result;
78     }
79 
80 private:
81     enum Flags {
82         kColorIsKnown_Flag = 0x1,
83         kIsOpaque_Flag = 0x2,
84     };
85     uint32_t fFlags;
86     SkPMColor4f fColor;
87 };
88 
89 enum class GrProcessorAnalysisCoverage { kNone, kSingleChannel, kLCD };
90 
91 /**
92  * GrColorFragmentProcessorAnalysis gathers invariant data from a set of color fragment processors.
93  * It is used to recognize optimizations that can simplify the generated shader or make blending
94  * more effecient.
95  */
96 class GrColorFragmentProcessorAnalysis {
97 public:
98     GrColorFragmentProcessorAnalysis() = delete;
99 
100     GrColorFragmentProcessorAnalysis(const GrProcessorAnalysisColor& input,
101                                      std::unique_ptr<GrFragmentProcessor> const fps[],
102                                      int count);
103 
isOpaque()104     bool isOpaque() const { return fIsOpaque; }
105 
106     /**
107      * Are all the fragment processors compatible with conflating coverage with color prior to the
108      * the first fragment processor. This result assumes that processors that should be eliminated
109      * as indicated by initialProcessorsToEliminate() are in fact eliminated.
110      */
allProcessorsCompatibleWithCoverageAsAlpha()111     bool allProcessorsCompatibleWithCoverageAsAlpha() const {
112         return fCompatibleWithCoverageAsAlpha;
113     }
114 
115     /**
116      * Do any of the fragment processors require local coords. This result assumes that
117      * processors that should be eliminated as indicated by initialProcessorsToEliminate() are in
118      * fact eliminated.
119      */
usesLocalCoords()120     bool usesLocalCoords() const { return fUsesLocalCoords; }
121 
122     /**
123      * Do any of the fragment processors read back the destination color?
124      */
willReadDstColor()125     bool willReadDstColor() const { return fWillReadDstColor; }
126 
127     /**
128      * Will we require a destination-surface texture?
129      */
130     bool requiresDstTexture(const GrCaps& caps) const;
131 
132     /**
133      * If we detected that the result after the first N processors is a known color then we
134      * eliminate those N processors and replace the GrDrawOp's color input to the GrPipeline with
135      * the known output of the Nth processor, so that the Nth+1 fragment processor (or the XP if
136      * there are only N processors) sees its expected input. If this returns 0 then there are no
137      * processors to eliminate.
138      */
initialProcessorsToEliminate(SkPMColor4f * newPipelineInputColor)139     int initialProcessorsToEliminate(SkPMColor4f* newPipelineInputColor) const {
140         if (fProcessorsToEliminate > 0) {
141             *newPipelineInputColor = fLastKnownOutputColor;
142         }
143         return fProcessorsToEliminate;
144     }
145 
146     /**
147      * Provides known information about the last processor's output color.
148      */
outputColor()149     GrProcessorAnalysisColor outputColor() const {
150         if (fOutputColorKnown) {
151             return fLastKnownOutputColor;
152         }
153         return fIsOpaque ? GrProcessorAnalysisColor::Opaque::kYes
154                          : GrProcessorAnalysisColor::Opaque::kNo;
155     }
156 
157 private:
158     bool fIsOpaque;
159     bool fCompatibleWithCoverageAsAlpha;
160     bool fUsesLocalCoords;
161     bool fWillReadDstColor;
162     bool fOutputColorKnown;
163     int fProcessorsToEliminate;
164     SkPMColor4f fLastKnownOutputColor;
165 };
166 
167 #endif
168