1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrProcOptInfo_DEFINED
#define GrProcOptInfo_DEFINED
#include "GrColor.h"
#include "GrPipelineInput.h"
class GrDrawOp;
class GrFragmentProcessor;
class GrPrimitiveProcessor;
/**
* GrProcOptInfo gathers invariant data from a set of processor stages.It is used to recognize
* optimizations related to eliminating stages and vertex attributes that aren't necessary for a
* draw.
*/
class GrProcOptInfo {
public:
GrProcOptInfo() { this->reset(0, kNone_GrColorComponentFlags); }
GrProcOptInfo(GrColor color, GrColorComponentFlags colorFlags) {
this->reset(color, colorFlags);
}
void resetToLCDCoverage(GrColor color, GrColorComponentFlags colorFlags) {
this->internalReset(color, colorFlags, true);
}
void reset(GrColor color, GrColorComponentFlags colorFlags) {
this->internalReset(color, colorFlags, false);
}
void reset(const GrPipelineInput& input) {
this->internalReset(input.fColor, input.fValidFlags, input.fIsLCDCoverage);
}
/**
* Runs through a series of processors and updates calculated values. This can be called
* repeatedly for cases when the sequence of processors is not in a contiguous array.
*/
void analyzeProcessors(const GrFragmentProcessor* const* processors, int cnt);
bool isSolidWhite() const {
return fProcessorsVisitedWithKnownOutput == fTotalProcessorsVisited &&
fLastKnownOutputColor == GrColor4f::OpaqueWhite();
}
bool isOpaque() const { return fIsOpaque; }
bool allProcessorsModulateByPremul() const { return fAllProcessorsModulatePremul; }
bool isLCDCoverage() const { return fIsLCDCoverage; }
/**
* If we detected that the result after the first N processors is a known color then we
* eliminate those N processors and replace the GrDrawOp's color input to the GrPipeline with
* the known output of the Nth processor, so that the Nth+1 fragment processor (or the XP if
* there are only N processors) sees its expected input. If this returns 0 then there are no
* processors to eliminate.
*/
int initialProcessorsToEliminate(GrColor* newPipelineInputColor) const {
if (fProcessorsVisitedWithKnownOutput > 0) {
*newPipelineInputColor = fLastKnownOutputColor.toGrColor();
}
return SkTMax(0, fProcessorsVisitedWithKnownOutput);
}
int initialProcessorsToEliminate(GrColor4f* newPipelineInputColor) const {
if (fProcessorsVisitedWithKnownOutput > 0) {
*newPipelineInputColor = fLastKnownOutputColor;
}
return SkTMax(0, fProcessorsVisitedWithKnownOutput);
}
bool hasKnownOutputColor(GrColor* knownOutputColor = nullptr) const {
if (fProcessorsVisitedWithKnownOutput != fTotalProcessorsVisited) {
return false;
}
if (knownOutputColor) {
*knownOutputColor = fLastKnownOutputColor.toGrColor();
}
return true;
}
private:
void internalReset(GrColor color, GrColorComponentFlags colorFlags, bool isLCDCoverage) {
fTotalProcessorsVisited = 0;
fIsLCDCoverage = isLCDCoverage;
fIsOpaque = (kA_GrColorComponentFlag & colorFlags) && GrColorIsOpaque(color);
fAllProcessorsModulatePremul = true;
if (kRGBA_GrColorComponentFlags == colorFlags) {
fProcessorsVisitedWithKnownOutput = 0;
fLastKnownOutputColor = GrColor4f::FromGrColor(color);
} else {
// -1 so that we know that even without adding processors that the color is not known.
fProcessorsVisitedWithKnownOutput = -1;
}
}
int fTotalProcessorsVisited;
int fProcessorsVisitedWithKnownOutput;
bool fIsLCDCoverage;
bool fIsOpaque;
bool fAllProcessorsModulatePremul;
GrColor4f fLastKnownOutputColor;
};
#endif
|