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