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