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