1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/*
2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2014 Google Inc.
3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *
4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be
5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file.
6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifndef GrProcessorAnalysis_DEFINED
9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define GrProcessorAnalysis_DEFINED
10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrColor.h"
12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass GrDrawOp;
14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass GrFragmentProcessor;
15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass GrPrimitiveProcessor;
16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass GrProcessorAnalysisColor {
18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    enum class Opaque {
20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kNo,
21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kYes,
22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    constexpr GrProcessorAnalysisColor(Opaque opaque = Opaque::kNo)
25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            : fFlags(opaque == Opaque::kYes ? kIsOpaque_Flag : 0), fColor(0) {}
26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrProcessorAnalysisColor(GrColor color) { this->setToConstant(color); }
28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void setToConstant(GrColor color) {
30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fColor = color;
31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (GrColorIsOpaque(color)) {
32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fFlags = kColorIsKnown_Flag | kIsOpaque_Flag;
33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        } else {
34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fFlags = kColorIsKnown_Flag;
35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void setToUnknown() { fFlags = 0; }
39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void setToUnknownOpaque() { fFlags = kIsOpaque_Flag; }
41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool isOpaque() const { return SkToBool(kIsOpaque_Flag & fFlags); }
43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool isConstant(GrColor* color = nullptr) const {
45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (kColorIsKnown_Flag & fFlags) {
46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (color) {
47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                *color = fColor;
48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return true;
50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return false;
52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool operator==(const GrProcessorAnalysisColor& that) const {
55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fFlags != that.fFlags) {
56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return false;
57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return (kColorIsKnown_Flag & fFlags) ? fColor == that.fColor : true;
59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /** The returned value reflects the common properties of the two inputs. */
62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static GrProcessorAnalysisColor Combine(const GrProcessorAnalysisColor& a,
63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                            const GrProcessorAnalysisColor& b) {
64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        GrProcessorAnalysisColor result;
65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        uint32_t commonFlags = a.fFlags & b.fFlags;
66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if ((kColorIsKnown_Flag & commonFlags) && a.fColor == b.fColor) {
67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            result.fColor = a.fColor;
68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            result.fFlags = a.fFlags;
69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        } else if (kIsOpaque_Flag & commonFlags) {
70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            result.fFlags = kIsOpaque_Flag;
71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return result;
73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    enum Flags {
77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kColorIsKnown_Flag = 0x1,
78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kIsOpaque_Flag = 0x2,
79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    uint32_t fFlags;
81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrColor fColor;
82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotenum class GrProcessorAnalysisCoverage { kNone, kSingleChannel, kLCD };
85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/**
87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * GrColorFragmentProcessorAnalysis gathers invariant data from a set of color fragment processor.
88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * It is used to recognize optimizations that can simplify the generated shader or make blending
89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * more effecient.
90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass GrColorFragmentProcessorAnalysis {
92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrColorFragmentProcessorAnalysis() = delete;
94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrColorFragmentProcessorAnalysis(const GrProcessorAnalysisColor& input,
96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                     const GrFragmentProcessor* const* processors,
97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                     int cnt);
98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool isOpaque() const { return fIsOpaque; }
100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /**
102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * Are all the fragment processors compatible with conflating coverage with color prior to the
103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * the first fragment processor. This result assumes that processors that should be eliminated
104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * as indicated by initialProcessorsToEliminate() are in fact eliminated.
105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     */
106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool allProcessorsCompatibleWithCoverageAsAlpha() const {
107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return fCompatibleWithCoverageAsAlpha;
108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /**
111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * Do any of the fragment processors require local coords. This result assumes that
112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * processors that should be eliminated as indicated by initialProcessorsToEliminate() are in
113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * fact eliminated.
114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     */
115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool usesLocalCoords() const { return fUsesLocalCoords; }
116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /**
118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * If we detected that the result after the first N processors is a known color then we
119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * eliminate those N processors and replace the GrDrawOp's color input to the GrPipeline with
120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * the known output of the Nth processor, so that the Nth+1 fragment processor (or the XP if
121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * there are only N processors) sees its expected input. If this returns 0 then there are no
122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * processors to eliminate.
123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     */
124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int initialProcessorsToEliminate(GrColor* newPipelineInputColor) const {
125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fProcessorsToEliminate > 0) {
126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            *newPipelineInputColor = fLastKnownOutputColor.toGrColor();
127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return fProcessorsToEliminate;
129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int initialProcessorsToEliminate(GrColor4f* newPipelineInputColor) const {
132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fProcessorsToEliminate > 0) {
133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            *newPipelineInputColor = fLastKnownOutputColor;
134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return fProcessorsToEliminate;
136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /**
139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * Provides known information about the last processor's output color.
140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     */
141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrProcessorAnalysisColor outputColor() const {
142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fKnowOutputColor) {
143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return fLastKnownOutputColor.toGrColor();
144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return fIsOpaque ? GrProcessorAnalysisColor::Opaque::kYes
146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                         : GrProcessorAnalysisColor::Opaque::kNo;
147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fIsOpaque;
151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fCompatibleWithCoverageAsAlpha;
152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fUsesLocalCoords;
153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fKnowOutputColor;
154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int fProcessorsToEliminate;
155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrColor4f fLastKnownOutputColor;
156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
159