1
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9
10#ifndef GrPaint_DEFINED
11#define GrPaint_DEFINED
12
13#include "include/core/SkBlendMode.h"
14#include "include/core/SkRefCnt.h"
15#include "include/core/SkRegion.h"
16#include "src/core/SkTLazy.h"
17#include "src/gpu/GrColor.h"
18#include "src/gpu/GrFragmentProcessor.h"
19
20class GrTextureProxy;
21class GrXPFactory;
22
23/**
24 * The paint describes how color and coverage are computed at each pixel by GrContext draw
25 * functions and the how color is blended with the destination pixel.
26 *
27 * The paint allows installation of custom color and coverage stages. New types of stages are
28 * created by subclassing GrProcessor.
29 *
30 * The primitive color computation starts with the color specified by setColor(). This color is the
31 * input to the first color stage. Each color stage feeds its output to the next color stage.
32 *
33 * Fractional pixel coverage follows a similar flow. The GrGeometryProcessor (specified elsewhere)
34 * provides the initial coverage which is passed to the first coverage fragment processor, which
35 * feeds its output to next coverage fragment processor.
36 *
37 * setXPFactory is used to control blending between the output color and dest. It also implements
38 * the application of fractional coverage from the coverage pipeline.
39 */
40class GrPaint {
41public:
42 GrPaint() = default;
43 ~GrPaint() = default;
44
45 static GrPaint Clone(const GrPaint& src) { return GrPaint(src); }
46
47 /**
48 * The initial color of the drawn primitive. Defaults to solid white.
49 */
50 void setColor4f(const SkPMColor4f& color) { fColor = color; }
51 const SkPMColor4f& getColor4f() const { return fColor; }
52
53 void setXPFactory(const GrXPFactory* xpFactory) {
54 fXPFactory = xpFactory;
55 fTrivial &= !SkToBool(xpFactory);
56 }
57
58 void setPorterDuffXPFactory(SkBlendMode mode);
59
60 void setCoverageSetOpXPFactory(SkRegion::Op, bool invertCoverage = false);
61
62 /**
63 * Appends an additional color processor to the color computation.
64 */
65 void addColorFragmentProcessor(std::unique_ptr<GrFragmentProcessor> fp) {
66 SkASSERT(fp);
67 fColorFragmentProcessors.push_back(std::move(fp));
68 fTrivial = false;
69 }
70
71 /**
72 * Appends an additional coverage processor to the coverage computation.
73 */
74 void addCoverageFragmentProcessor(std::unique_ptr<GrFragmentProcessor> fp) {
75 SkASSERT(fp);
76 fCoverageFragmentProcessors.push_back(std::move(fp));
77 fTrivial = false;
78 }
79
80 int numColorFragmentProcessors() const { return fColorFragmentProcessors.count(); }
81 int numCoverageFragmentProcessors() const { return fCoverageFragmentProcessors.count(); }
82 int numTotalFragmentProcessors() const { return this->numColorFragmentProcessors() +
83 this->numCoverageFragmentProcessors(); }
84
85 const GrXPFactory* getXPFactory() const { return fXPFactory; }
86
87 GrFragmentProcessor* getColorFragmentProcessor(int i) const {
88 return fColorFragmentProcessors[i].get();
89 }
90 GrFragmentProcessor* getCoverageFragmentProcessor(int i) const {
91 return fCoverageFragmentProcessors[i].get();
92 }
93
94 /**
95 * Returns true if the paint's output color will be constant after blending. If the result is
96 * true, constantColor will be updated to contain the constant color. Note that we can conflate
97 * coverage and color, so the actual values written to pixels with partial coverage may still
98 * not seem constant, even if this function returns true.
99 */
100 bool isConstantBlendedColor(SkPMColor4f* constantColor) const;
101
102 /**
103 * A trivial paint is one that uses src-over and has no fragment processors.
104 * It may have variable sRGB settings.
105 **/
106 bool isTrivial() const { return fTrivial; }
107
108 friend void assert_alive(GrPaint& p) {
109 SkASSERT(p.fAlive);
110 }
111
112private:
113 // Since paint copying is expensive if there are fragment processors, we require going through
114 // the Clone() method.
115 GrPaint(const GrPaint&);
116 GrPaint& operator=(const GrPaint&) = delete;
117
118 friend class GrProcessorSet;
119
120 const GrXPFactory* fXPFactory = nullptr;
121 SkSTArray<4, std::unique_ptr<GrFragmentProcessor>> fColorFragmentProcessors;
122 SkSTArray<2, std::unique_ptr<GrFragmentProcessor>> fCoverageFragmentProcessors;
123 bool fTrivial = true;
124 SkPMColor4f fColor = SK_PMColor4fWHITE;
125 SkDEBUGCODE(bool fAlive = true;) // Set false after moved from.
126};
127
128#endif
129