blob: 6fe561ab33dc3caa4b273aae4c43e51cb380a039 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
bsalomon@google.com27847de2011-02-22 20:59:41 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * 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.
bsalomon@google.com27847de2011-02-22 20:59:41 +00007 */
8
epoger@google.comec3ed6a2011-07-28 14:26:00 +00009
bsalomon@google.com27847de2011-02-22 20:59:41 +000010#ifndef GrPaint_DEFINED
11#define GrPaint_DEFINED
12
bsalomon@google.com27847de2011-02-22 20:59:41 +000013#include "GrColor.h"
brianosman54f30c12016-07-18 10:53:52 -070014#include "GrColorSpaceXform.h"
wangyix58d890b2015-08-12 09:40:47 -070015#include "GrFragmentProcessor.h"
reed374772b2016-10-05 17:33:02 -070016#include "SkBlendMode.h"
bungeman06ca8ec2016-06-09 08:01:03 -070017#include "SkRefCnt.h"
egdanielb197b8f2015-02-17 07:34:43 -080018#include "SkRegion.h"
Brian Salomon82f44312017-01-11 13:42:54 -050019#include "SkTLazy.h"
Scroggo97c88c22011-05-11 14:05:25 +000020
Robert Phillips901f29a2017-01-24 16:24:41 -050021class GrTextureProxy;
Brian Salomon94cce4c2017-02-21 16:32:20 -050022class GrXPFactory;
Robert Phillips901f29a2017-01-24 16:24:41 -050023
bsalomon@google.com27847de2011-02-22 20:59:41 +000024/**
bsalomon@google.comc7448ce2012-10-05 19:04:13 +000025 * The paint describes how color and coverage are computed at each pixel by GrContext draw
26 * functions and the how color is blended with the destination pixel.
27 *
28 * The paint allows installation of custom color and coverage stages. New types of stages are
joshualittb0a8a372014-09-23 09:50:21 -070029 * created by subclassing GrProcessor.
bsalomon@google.comc7448ce2012-10-05 19:04:13 +000030 *
31 * The primitive color computation starts with the color specified by setColor(). This color is the
bsalomon37f9a262015-02-02 13:00:10 -080032 * input to the first color stage. Each color stage feeds its output to the next color stage.
bsalomon@google.comc7448ce2012-10-05 19:04:13 +000033 *
Brian Salomon0e8fc8b2016-12-09 15:10:07 -050034 * Fractional pixel coverage follows a similar flow. The GrGeometryProcessor (specified elsewhere)
35 * provides the initial coverage which is passed to the first coverage fragment processor, which
36 * feeds its output to next coverage fragment processor.
bsalomon@google.comc7448ce2012-10-05 19:04:13 +000037 *
bsalomon37f9a262015-02-02 13:00:10 -080038 * setXPFactory is used to control blending between the output color and dest. It also implements
39 * the application of fractional coverage from the coverage pipeline.
bsalomon@google.com27847de2011-02-22 20:59:41 +000040 */
41class GrPaint {
42public:
Brian Salomon82f44312017-01-11 13:42:54 -050043 GrPaint() = default;
44 explicit GrPaint(const GrPaint&) = default;
45 ~GrPaint() = default;
Scroggo97c88c22011-05-11 14:05:25 +000046
bsalomon@google.comc7448ce2012-10-05 19:04:13 +000047 /**
bsalomon@google.comc7448ce2012-10-05 19:04:13 +000048 * The initial color of the drawn primitive. Defaults to solid white.
49 */
brianosmana4535a32016-06-24 12:50:19 -070050 void setColor4f(const GrColor4f& color) { fColor = color; }
51 const GrColor4f& getColor4f() const { return fColor; }
52
53 /**
54 * Legacy getter, until all code handles 4f directly.
55 */
56 GrColor getColor() const { return fColor.toGrColor(); }
bsalomon@google.comc7448ce2012-10-05 19:04:13 +000057
58 /**
brianosman64d094d2016-03-25 06:01:59 -070059 * Should shader output conversion from linear to sRGB be disabled.
60 * Only relevant if the destination is sRGB. Defaults to false.
61 */
62 void setDisableOutputConversionToSRGB(bool srgb) { fDisableOutputConversionToSRGB = srgb; }
63 bool getDisableOutputConversionToSRGB() const { return fDisableOutputConversionToSRGB; }
64
brianosman898235c2016-04-06 07:38:23 -070065 /**
66 * Should sRGB inputs be allowed to perform sRGB to linear conversion. With this flag
67 * set to false, sRGB textures will be treated as linear (including filtering).
68 */
69 void setAllowSRGBInputs(bool allowSRGBInputs) { fAllowSRGBInputs = allowSRGBInputs; }
70 bool getAllowSRGBInputs() const { return fAllowSRGBInputs; }
71
brianosmanb461d342016-04-13 13:10:14 -070072 /**
dvonbeck9b03e7b2016-08-01 11:01:56 -070073 * Does one of the fragment processors need a field of distance vectors to the nearest edge?
74 */
75 bool usesDistanceVectorField() const { return fUsesDistanceVectorField; }
76
77 /**
brianosman0e3c5542016-04-13 13:56:21 -070078 * Should rendering be gamma-correct, end-to-end. Causes sRGB render targets to behave
79 * as such (with linear blending), and sRGB inputs to be filtered and decoded correctly.
brianosmanb461d342016-04-13 13:10:14 -070080 */
81 void setGammaCorrect(bool gammaCorrect) {
Brian Salomon6d4b65e2017-05-03 17:06:09 -040082 this->setDisableOutputConversionToSRGB(!gammaCorrect);
83 this->setAllowSRGBInputs(gammaCorrect);
brianosmanb461d342016-04-13 13:10:14 -070084 }
85
Brian Salomon6d4b65e2017-05-03 17:06:09 -040086 void setXPFactory(const GrXPFactory* xpFactory) {
87 fXPFactory = xpFactory;
88 fTrivial &= !SkToBool(xpFactory);
89 }
egdaniel378092f2014-12-03 10:40:13 -080090
Brian Salomon94cce4c2017-02-21 16:32:20 -050091 void setPorterDuffXPFactory(SkBlendMode mode);
egdaniel95131432014-12-09 11:15:43 -080092
reed73603f32016-09-20 08:42:38 -070093 void setCoverageSetOpXPFactory(SkRegion::Op, bool invertCoverage = false);
egdaniel95131432014-12-09 11:15:43 -080094
bsalomon@google.comc7448ce2012-10-05 19:04:13 +000095 /**
joshualittb0a8a372014-09-23 09:50:21 -070096 * Appends an additional color processor to the color computation.
bsalomon@google.comc7448ce2012-10-05 19:04:13 +000097 */
bungeman06ca8ec2016-06-09 08:01:03 -070098 void addColorFragmentProcessor(sk_sp<GrFragmentProcessor> fp) {
joshualittb0a8a372014-09-23 09:50:21 -070099 SkASSERT(fp);
dvonbeck9b03e7b2016-08-01 11:01:56 -0700100 fUsesDistanceVectorField |= fp->usesDistanceVectorField();
bungeman06ca8ec2016-06-09 08:01:03 -0700101 fColorFragmentProcessors.push_back(std::move(fp));
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400102 fTrivial = false;
tomhudson@google.comf13f5882012-06-25 17:27:28 +0000103 }
104
bsalomon@google.comc7448ce2012-10-05 19:04:13 +0000105 /**
joshualittb0a8a372014-09-23 09:50:21 -0700106 * Appends an additional coverage processor to the coverage computation.
bsalomon@google.comc7448ce2012-10-05 19:04:13 +0000107 */
bungeman06ca8ec2016-06-09 08:01:03 -0700108 void addCoverageFragmentProcessor(sk_sp<GrFragmentProcessor> fp) {
joshualittb0a8a372014-09-23 09:50:21 -0700109 SkASSERT(fp);
dvonbeck9b03e7b2016-08-01 11:01:56 -0700110 fUsesDistanceVectorField |= fp->usesDistanceVectorField();
bungeman06ca8ec2016-06-09 08:01:03 -0700111 fCoverageFragmentProcessors.push_back(std::move(fp));
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400112 fTrivial = false;
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000113 }
114
commit-bot@chromium.org42dacab2013-07-13 17:24:24 +0000115 /**
116 * Helpers for adding color or coverage effects that sample a texture. The matrix is applied
117 * to the src space position to compute texture coordinates.
118 */
Robert Phillips296b1cc2017-03-15 10:42:12 -0400119 void addColorTextureProcessor(GrResourceProvider*, sk_sp<GrTextureProxy>,
120 sk_sp<GrColorSpaceXform>, const SkMatrix&);
121 void addColorTextureProcessor(GrResourceProvider*, sk_sp<GrTextureProxy>,
122 sk_sp<GrColorSpaceXform>, const SkMatrix&,
123 const GrSamplerParams&);
Robert Phillips901f29a2017-01-24 16:24:41 -0500124
Robert Phillips296b1cc2017-03-15 10:42:12 -0400125 void addCoverageTextureProcessor(GrResourceProvider*, sk_sp<GrTextureProxy>, const SkMatrix&);
126 void addCoverageTextureProcessor(GrResourceProvider*, sk_sp<GrTextureProxy>,
Robert Phillips901f29a2017-01-24 16:24:41 -0500127 const SkMatrix&, const GrSamplerParams&);
128
bsalomonac856c92015-08-27 06:30:17 -0700129 int numColorFragmentProcessors() const { return fColorFragmentProcessors.count(); }
130 int numCoverageFragmentProcessors() const { return fCoverageFragmentProcessors.count(); }
131 int numTotalFragmentProcessors() const { return this->numColorFragmentProcessors() +
132 this->numCoverageFragmentProcessors(); }
bsalomon@google.come3d32162012-07-20 13:37:06 +0000133
Brian Salomona1633922017-01-09 11:46:10 -0500134 const GrXPFactory* getXPFactory() const { return fXPFactory; }
egdaniel378092f2014-12-03 10:40:13 -0800135
bungeman06ca8ec2016-06-09 08:01:03 -0700136 GrFragmentProcessor* getColorFragmentProcessor(int i) const {
137 return fColorFragmentProcessors[i].get();
bsalomonac856c92015-08-27 06:30:17 -0700138 }
bungeman06ca8ec2016-06-09 08:01:03 -0700139 GrFragmentProcessor* getCoverageFragmentProcessor(int i) const {
140 return fCoverageFragmentProcessors[i].get();
bsalomonac856c92015-08-27 06:30:17 -0700141 }
bsalomon@google.come3d32162012-07-20 13:37:06 +0000142
bsalomon@google.comc7448ce2012-10-05 19:04:13 +0000143 /**
cdalton1fa45722015-06-02 10:43:39 -0700144 * Returns true if the paint's output color will be constant after blending. If the result is
145 * true, constantColor will be updated to contain the constant color. Note that we can conflate
146 * coverage and color, so the actual values written to pixels with partial coverage may still
147 * not seem constant, even if this function returns true.
commit-bot@chromium.org24ab3b02013-08-14 21:56:37 +0000148 */
Brian Salomon94cce4c2017-02-21 16:32:20 -0500149 bool isConstantBlendedColor(GrColor* constantColor) const;
commit-bot@chromium.org24ab3b02013-08-14 21:56:37 +0000150
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400151 /**
152 * A trivial paint is one that uses src-over and has no fragment processors.
153 * It may have variable sRGB settings.
154 **/
155 bool isTrivial() const { return fTrivial; }
156
joshualitt5531d512014-12-17 15:50:11 -0800157private:
Brian Salomon82f44312017-01-11 13:42:54 -0500158 template <bool> class MoveOrImpl;
159
160public:
161 /**
162 * A temporary instance of this class can be used to select between moving an existing paint or
163 * a temporary copy of an existing paint into a call site. MoveOrClone(paint, false) is a rvalue
164 * reference to paint while MoveOrClone(paint, true) is a rvalue reference to a copy of paint.
165 */
166 using MoveOrClone = MoveOrImpl<true>;
167
168 /**
169 * A temporary instance of this class can be used to select between moving an existing or a
170 * newly default constructed paint into a call site. MoveOrNew(paint, false) is a rvalue
171 * reference to paint while MoveOrNew(paint, true) is a rvalue reference to a default paint.
172 */
173 using MoveOrNew = MoveOrImpl<false>;
174
175private:
176 GrPaint& operator=(const GrPaint&) = delete;
177
Brian Salomon92ce5942017-01-18 11:01:10 -0500178 friend class GrProcessorSet;
Brian Salomon82f44312017-01-11 13:42:54 -0500179
Brian Salomon82f44312017-01-11 13:42:54 -0500180 const GrXPFactory* fXPFactory = nullptr;
bungeman06ca8ec2016-06-09 08:01:03 -0700181 SkSTArray<4, sk_sp<GrFragmentProcessor>> fColorFragmentProcessors;
182 SkSTArray<2, sk_sp<GrFragmentProcessor>> fCoverageFragmentProcessors;
Brian Salomon82f44312017-01-11 13:42:54 -0500183 bool fDisableOutputConversionToSRGB = false;
184 bool fAllowSRGBInputs = false;
185 bool fUsesDistanceVectorField = false;
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400186 bool fTrivial = true;
Brian Salomon82f44312017-01-11 13:42:54 -0500187 GrColor4f fColor = GrColor4f::OpaqueWhite();
188};
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000189
Brian Salomon82f44312017-01-11 13:42:54 -0500190/** This is the implementation of MoveOrCopy and MoveOrNew. */
191template <bool COPY_IF_NEW>
192class GrPaint::MoveOrImpl {
193public:
194 MoveOrImpl(GrPaint& paint, bool newPaint) {
195 if (newPaint) {
196 if (COPY_IF_NEW) {
197 fStorage.init(paint);
198 } else {
199 fStorage.init();
200 };
201 fPaint = fStorage.get();
202 } else {
203 fPaint = &paint;
204 }
205 }
bsalomon@google.comc7448ce2012-10-05 19:04:13 +0000206
Brian Salomond4652ca2017-01-13 12:11:36 -0500207 operator GrPaint&&() && { return std::move(*fPaint); }
208 GrPaint& paint() { return *fPaint; }
Brian Salomon82f44312017-01-11 13:42:54 -0500209
210private:
211 SkTLazy<GrPaint> fStorage;
212 GrPaint* fPaint;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000213};
214
215#endif