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 GrProcOptInfo_DEFINED
9 #define GrProcOptInfo_DEFINED
10 
11 #include "GrColor.h"
12 #include "GrInvariantOutput.h"
13 
14 class GrDrawBatch;
15 class GrFragmentProcessor;
16 class GrPrimitiveProcessor;
17 class GrProcessor;
18 
19 /**
20  * GrProcOptInfo gathers invariant data from a set of processor stages.It is used to recognize
21  * optimizations related to eliminating stages and vertex attributes that aren't necessary for a
22  * draw.
23  */
24 class GrProcOptInfo {
25 public:
GrProcOptInfo()26     GrProcOptInfo()
27         : fInOut(0, static_cast<GrColorComponentFlags>(0), false)
28         , fFirstEffectiveProcessorIndex(0)
29         , fInputColorIsUsed(true)
30         , fInputColor(0)
31         , fReadsFragPosition(false) {}
32 
33     void calcWithInitialValues(const GrFragmentProcessor* const *, int cnt, GrColor startColor,
34                                GrColorComponentFlags, bool areCoverageStages, bool isLCD = false);
35     void initUsingInvariantOutput(GrInitInvariantOutput invOutput);
36     void completeCalculations(const GrFragmentProcessor * const processors[], int cnt);
37 
isSolidWhite()38     bool isSolidWhite() const { return fInOut.isSolidWhite(); }
isOpaque()39     bool isOpaque() const { return fInOut.isOpaque(); }
isSingleComponent()40     bool isSingleComponent() const { return fInOut.isSingleComponent(); }
allStagesMultiplyInput()41     bool allStagesMultiplyInput() const { return fInOut.allStagesMulInput(); }
42 
43     // TODO: Once texture pixel configs quaries are updated, we no longer need this function.
44     // For now this function will correctly tell us if we are using LCD text or not and should only
45     // be called when looking at the coverage output.
isFourChannelOutput()46     bool isFourChannelOutput() const { return !fInOut.isSingleComponent() &&
47                                                fInOut.isLCDCoverage(); }
48 
color()49     GrColor color() const { return fInOut.color(); }
50 
validFlags()51     GrColorComponentFlags validFlags() const {
52         return fInOut.validFlags();
53     }
54 
55     /**
56      * Returns the index of the first effective color processor. If an intermediate processor
57      * doesn't read its input or has a known output, then we can ignore all earlier processors
58      * since they will not affect the final output. Thus the first effective processors index is
59      * the index to the first processor that will have an effect on the final output.
60      *
61      * If processors before the firstEffectiveProcessorIndex() are removed, corresponding values
62      * from inputColorIsUsed(), inputColorToEffectiveProcessor(), removeVertexAttribs(), and
63      * readsDst() must be used when setting up the draw to ensure correct drawing.
64      */
firstEffectiveProcessorIndex()65     int firstEffectiveProcessorIndex() const { return fFirstEffectiveProcessorIndex; }
66 
67     /**
68      * True if the first effective processor reads its input, false otherwise.
69      */
inputColorIsUsed()70     bool inputColorIsUsed() const { return fInputColorIsUsed; }
71 
72     /**
73      * If input color is used and per-vertex colors are not used, this is the input color to the
74      * first effective processor.
75      */
inputColorToFirstEffectiveProccesor()76     GrColor inputColorToFirstEffectiveProccesor() const { return fInputColor; }
77 
78     /**
79      * Returns true if any of the processor preserved by GrProcOptInfo read the frag position.
80      */
readsFragPosition()81     bool readsFragPosition() const { return fReadsFragPosition; }
82 
83 private:
84     void internalCalc(const GrFragmentProcessor* const[], int cnt, bool initWillReadFragPosition);
85 
86     GrInvariantOutput fInOut;
87     int fFirstEffectiveProcessorIndex;
88     bool fInputColorIsUsed;
89     GrColor fInputColor;
90     bool fReadsFragPosition;
91 };
92 
93 #endif
94