blob: 4175b5ea48f52c097ac42b3f8ff3b8bd3991f3b5 [file] [log] [blame]
Brian Salomonc0b642c2017-03-27 13:09:36 -04001/*
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
Brian Salomona811b122017-03-30 08:21:32 -04008#ifndef GrProcessorAnalysis_DEFINED
9#define GrProcessorAnalysis_DEFINED
Brian Salomonc0b642c2017-03-27 13:09:36 -040010
11#include "GrColor.h"
12
13class GrDrawOp;
14class GrFragmentProcessor;
15class GrPrimitiveProcessor;
16
Brian Salomona811b122017-03-30 08:21:32 -040017class GrProcessorAnalysisColor {
Brian Salomonc0b642c2017-03-27 13:09:36 -040018public:
19 enum class Opaque {
20 kNo,
21 kYes,
22 };
23
Brian Salomon82ddc942017-07-14 12:00:13 -040024 constexpr GrProcessorAnalysisColor(Opaque opaque = Opaque::kNo)
25 : fFlags(opaque == Opaque::kYes ? kIsOpaque_Flag : 0), fColor(0) {}
Brian Salomonc0b642c2017-03-27 13:09:36 -040026
Brian Salomona811b122017-03-30 08:21:32 -040027 GrProcessorAnalysisColor(GrColor color) { this->setToConstant(color); }
Brian Salomonc0b642c2017-03-27 13:09:36 -040028
29 void setToConstant(GrColor color) {
30 fColor = color;
31 if (GrColorIsOpaque(color)) {
32 fFlags = kColorIsKnown_Flag | kIsOpaque_Flag;
33 } else {
34 fFlags = kColorIsKnown_Flag;
35 }
36 }
37
38 void setToUnknown() { fFlags = 0; }
39
40 void setToUnknownOpaque() { fFlags = kIsOpaque_Flag; }
41
42 bool isOpaque() const { return SkToBool(kIsOpaque_Flag & fFlags); }
43
Brian Salomon31853842017-03-28 16:32:05 -040044 bool isConstant(GrColor* color = nullptr) const {
Brian Salomonc0b642c2017-03-27 13:09:36 -040045 if (kColorIsKnown_Flag & fFlags) {
Brian Salomon31853842017-03-28 16:32:05 -040046 if (color) {
47 *color = fColor;
48 }
Brian Salomonc0b642c2017-03-27 13:09:36 -040049 return true;
50 }
51 return false;
52 }
53
Brian Salomona811b122017-03-30 08:21:32 -040054 bool operator==(const GrProcessorAnalysisColor& that) const {
Brian Salomon1c6025c2017-03-29 14:25:04 -040055 if (fFlags != that.fFlags) {
56 return false;
57 }
58 return (kColorIsKnown_Flag & fFlags) ? fColor == that.fColor : true;
59 }
60
Brian Salomon13071c52017-03-29 21:28:20 -040061 /** The returned value reflects the common properties of the two inputs. */
Brian Salomona811b122017-03-30 08:21:32 -040062 static GrProcessorAnalysisColor Combine(const GrProcessorAnalysisColor& a,
63 const GrProcessorAnalysisColor& b) {
64 GrProcessorAnalysisColor result;
Brian Salomon13071c52017-03-29 21:28:20 -040065 uint32_t commonFlags = a.fFlags & b.fFlags;
66 if ((kColorIsKnown_Flag & commonFlags) && a.fColor == b.fColor) {
67 result.fColor = a.fColor;
68 result.fFlags = a.fFlags;
69 } else if (kIsOpaque_Flag & commonFlags) {
70 result.fFlags = kIsOpaque_Flag;
71 }
72 return result;
73 }
74
Brian Salomonc0b642c2017-03-27 13:09:36 -040075private:
76 enum Flags {
77 kColorIsKnown_Flag = 0x1,
78 kIsOpaque_Flag = 0x2,
79 };
80 uint32_t fFlags;
81 GrColor fColor;
82};
83
Brian Salomona811b122017-03-30 08:21:32 -040084enum class GrProcessorAnalysisCoverage { kNone, kSingleChannel, kLCD };
Brian Salomonc0b642c2017-03-27 13:09:36 -040085
86/**
87 * GrColorFragmentProcessorAnalysis gathers invariant data from a set of color fragment processor.
88 * It is used to recognize optimizations that can simplify the generated shader or make blending
89 * more effecient.
90 */
91class GrColorFragmentProcessorAnalysis {
92public:
Brian Salomon650ced02017-07-20 16:46:46 -040093 GrColorFragmentProcessorAnalysis() = delete;
Brian Salomonc0b642c2017-03-27 13:09:36 -040094
Brian Salomon650ced02017-07-20 16:46:46 -040095 GrColorFragmentProcessorAnalysis(const GrProcessorAnalysisColor& input,
96 const GrFragmentProcessor* const* processors,
97 int cnt);
Brian Salomonc0b642c2017-03-27 13:09:36 -040098
99 bool isOpaque() const { return fIsOpaque; }
100
101 /**
102 * Are all the fragment processors compatible with conflating coverage with color prior to the
Brian Salomon28207df2017-06-05 12:25:13 -0400103 * the first fragment processor. This result assumes that processors that should be eliminated
104 * as indicated by initialProcessorsToEliminate() are in fact eliminated.
Brian Salomonc0b642c2017-03-27 13:09:36 -0400105 */
106 bool allProcessorsCompatibleWithCoverageAsAlpha() const {
Brian Salomon650ced02017-07-20 16:46:46 -0400107 return fCompatibleWithCoverageAsAlpha;
Brian Salomonc0b642c2017-03-27 13:09:36 -0400108 }
109
110 /**
Brian Salomon28207df2017-06-05 12:25:13 -0400111 * Do any of the fragment processors require local coords. This result assumes that
112 * processors that should be eliminated as indicated by initialProcessorsToEliminate() are in
113 * fact eliminated.
Brian Salomonc0b642c2017-03-27 13:09:36 -0400114 */
115 bool usesLocalCoords() const { return fUsesLocalCoords; }
116
117 /**
118 * If we detected that the result after the first N processors is a known color then we
119 * eliminate those N processors and replace the GrDrawOp's color input to the GrPipeline with
120 * the known output of the Nth processor, so that the Nth+1 fragment processor (or the XP if
121 * there are only N processors) sees its expected input. If this returns 0 then there are no
122 * processors to eliminate.
123 */
124 int initialProcessorsToEliminate(GrColor* newPipelineInputColor) const {
Brian Salomon650ced02017-07-20 16:46:46 -0400125 if (fProcessorsToEliminate > 0) {
Brian Salomonc0b642c2017-03-27 13:09:36 -0400126 *newPipelineInputColor = fLastKnownOutputColor.toGrColor();
127 }
Brian Salomon650ced02017-07-20 16:46:46 -0400128 return fProcessorsToEliminate;
Brian Salomonc0b642c2017-03-27 13:09:36 -0400129 }
130
131 int initialProcessorsToEliminate(GrColor4f* newPipelineInputColor) const {
Brian Salomon650ced02017-07-20 16:46:46 -0400132 if (fProcessorsToEliminate > 0) {
Brian Salomonc0b642c2017-03-27 13:09:36 -0400133 *newPipelineInputColor = fLastKnownOutputColor;
134 }
Brian Salomon650ced02017-07-20 16:46:46 -0400135 return fProcessorsToEliminate;
Brian Salomonc0b642c2017-03-27 13:09:36 -0400136 }
137
Brian Salomon650ced02017-07-20 16:46:46 -0400138 /**
139 * Provides known information about the last processor's output color.
140 */
Brian Salomona811b122017-03-30 08:21:32 -0400141 GrProcessorAnalysisColor outputColor() const {
Brian Salomon650ced02017-07-20 16:46:46 -0400142 if (fKnowOutputColor) {
143 return fLastKnownOutputColor.toGrColor();
Brian Salomonc0b642c2017-03-27 13:09:36 -0400144 }
Brian Salomon650ced02017-07-20 16:46:46 -0400145 return fIsOpaque ? GrProcessorAnalysisColor::Opaque::kYes
146 : GrProcessorAnalysisColor::Opaque::kNo;
Brian Salomonc0b642c2017-03-27 13:09:36 -0400147 }
148
149private:
Brian Salomon650ced02017-07-20 16:46:46 -0400150 bool fIsOpaque;
151 bool fCompatibleWithCoverageAsAlpha;
152 bool fUsesLocalCoords;
153 bool fKnowOutputColor;
154 int fProcessorsToEliminate;
Brian Salomonc0b642c2017-03-27 13:09:36 -0400155 GrColor4f fLastKnownOutputColor;
156};
157
158#endif