blob: 0085604caee91a7acd2d81724984f33831bfb700 [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"
egdaniel378092f2014-12-03 10:40:13 -080015#include "GrXferProcessor.h"
egdaniel95131432014-12-09 11:15:43 -080016#include "effects/GrPorterDuffXferProcessor.h"
wangyix58d890b2015-08-12 09:40:47 -070017#include "GrFragmentProcessor.h"
bsalomon@google.com27847de2011-02-22 20:59:41 +000018
bungeman06ca8ec2016-06-09 08:01:03 -070019#include "SkRefCnt.h"
egdanielb197b8f2015-02-17 07:34:43 -080020#include "SkRegion.h"
Scroggo97c88c22011-05-11 14:05:25 +000021#include "SkXfermode.h"
22
bsalomon@google.com27847de2011-02-22 20:59:41 +000023/**
bsalomon@google.comc7448ce2012-10-05 19:04:13 +000024 * 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
joshualittb0a8a372014-09-23 09:50:21 -070028 * created by subclassing GrProcessor.
bsalomon@google.comc7448ce2012-10-05 19:04:13 +000029 *
30 * The primitive color computation starts with the color specified by setColor(). This color is the
bsalomon37f9a262015-02-02 13:00:10 -080031 * 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 +000032 *
33 * Fractional pixel coverage follows a similar flow. The coverage is initially the value specified
34 * by setCoverage(). This is input to the first coverage stage. Coverage stages are chained
35 * together in the same manner as color stages. The output of the last stage is modulated by any
36 * fractional coverage produced by anti-aliasing. This last step produces the final coverage, C.
37 *
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:
joshualitt2fdeda02015-01-22 07:11:44 -080043 GrPaint();
bsalomon@google.com27847de2011-02-22 20:59:41 +000044
bsalomon@google.comc7448ce2012-10-05 19:04:13 +000045 GrPaint(const GrPaint& paint) { *this = paint; }
bsalomon@google.com27847de2011-02-22 20:59:41 +000046
bungeman06ca8ec2016-06-09 08:01:03 -070047 ~GrPaint() { }
Scroggo97c88c22011-05-11 14:05:25 +000048
bsalomon@google.comc7448ce2012-10-05 19:04:13 +000049 /**
bsalomon@google.comc7448ce2012-10-05 19:04:13 +000050 * The initial color of the drawn primitive. Defaults to solid white.
51 */
brianosmana4535a32016-06-24 12:50:19 -070052 void setColor4f(const GrColor4f& color) { fColor = color; }
53 const GrColor4f& getColor4f() const { return fColor; }
54
55 /**
56 * Legacy getter, until all code handles 4f directly.
57 */
58 GrColor getColor() const { return fColor.toGrColor(); }
bsalomon@google.comc7448ce2012-10-05 19:04:13 +000059
60 /**
bsalomon@google.comc7448ce2012-10-05 19:04:13 +000061 * Should primitives be anti-aliased or not. Defaults to false.
62 */
63 void setAntiAlias(bool aa) { fAntiAlias = aa; }
64 bool isAntiAlias() const { return fAntiAlias; }
65
brianosman64d094d2016-03-25 06:01:59 -070066 /**
67 * Should shader output conversion from linear to sRGB be disabled.
68 * Only relevant if the destination is sRGB. Defaults to false.
69 */
70 void setDisableOutputConversionToSRGB(bool srgb) { fDisableOutputConversionToSRGB = srgb; }
71 bool getDisableOutputConversionToSRGB() const { return fDisableOutputConversionToSRGB; }
72
brianosman898235c2016-04-06 07:38:23 -070073 /**
74 * Should sRGB inputs be allowed to perform sRGB to linear conversion. With this flag
75 * set to false, sRGB textures will be treated as linear (including filtering).
76 */
77 void setAllowSRGBInputs(bool allowSRGBInputs) { fAllowSRGBInputs = allowSRGBInputs; }
78 bool getAllowSRGBInputs() const { return fAllowSRGBInputs; }
79
brianosmanb461d342016-04-13 13:10:14 -070080 /**
dvonbeck9b03e7b2016-08-01 11:01:56 -070081 * Does one of the fragment processors need a field of distance vectors to the nearest edge?
82 */
83 bool usesDistanceVectorField() const { return fUsesDistanceVectorField; }
84
85 /**
brianosman0e3c5542016-04-13 13:56:21 -070086 * Should rendering be gamma-correct, end-to-end. Causes sRGB render targets to behave
87 * as such (with linear blending), and sRGB inputs to be filtered and decoded correctly.
brianosmanb461d342016-04-13 13:10:14 -070088 */
89 void setGammaCorrect(bool gammaCorrect) {
90 setDisableOutputConversionToSRGB(!gammaCorrect);
91 setAllowSRGBInputs(gammaCorrect);
92 }
93
bungeman06ca8ec2016-06-09 08:01:03 -070094 void setXPFactory(sk_sp<GrXPFactory> xpFactory) {
95 fXPFactory = std::move(xpFactory);
egdaniel378092f2014-12-03 10:40:13 -080096 }
97
egdaniel95131432014-12-09 11:15:43 -080098 void setPorterDuffXPFactory(SkXfermode::Mode mode) {
bungeman06ca8ec2016-06-09 08:01:03 -070099 fXPFactory = GrPorterDuffXPFactory::Make(mode);
egdaniel95131432014-12-09 11:15:43 -0800100 }
101
egdanielb197b8f2015-02-17 07:34:43 -0800102 void setCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage = false);
egdaniel95131432014-12-09 11:15:43 -0800103
bsalomon@google.comc7448ce2012-10-05 19:04:13 +0000104 /**
joshualittb0a8a372014-09-23 09:50:21 -0700105 * Appends an additional color processor to the color computation.
bsalomon@google.comc7448ce2012-10-05 19:04:13 +0000106 */
bungeman06ca8ec2016-06-09 08:01:03 -0700107 void addColorFragmentProcessor(sk_sp<GrFragmentProcessor> fp) {
joshualittb0a8a372014-09-23 09:50:21 -0700108 SkASSERT(fp);
dvonbeck9b03e7b2016-08-01 11:01:56 -0700109 fUsesDistanceVectorField |= fp->usesDistanceVectorField();
bungeman06ca8ec2016-06-09 08:01:03 -0700110 fColorFragmentProcessors.push_back(std::move(fp));
tomhudson@google.comf13f5882012-06-25 17:27:28 +0000111 }
112
bsalomon@google.comc7448ce2012-10-05 19:04:13 +0000113 /**
joshualittb0a8a372014-09-23 09:50:21 -0700114 * Appends an additional coverage processor to the coverage computation.
bsalomon@google.comc7448ce2012-10-05 19:04:13 +0000115 */
bungeman06ca8ec2016-06-09 08:01:03 -0700116 void addCoverageFragmentProcessor(sk_sp<GrFragmentProcessor> fp) {
joshualittb0a8a372014-09-23 09:50:21 -0700117 SkASSERT(fp);
dvonbeck9b03e7b2016-08-01 11:01:56 -0700118 fUsesDistanceVectorField |= fp->usesDistanceVectorField();
bungeman06ca8ec2016-06-09 08:01:03 -0700119 fCoverageFragmentProcessors.push_back(std::move(fp));
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000120 }
121
commit-bot@chromium.org42dacab2013-07-13 17:24:24 +0000122 /**
123 * Helpers for adding color or coverage effects that sample a texture. The matrix is applied
124 * to the src space position to compute texture coordinates.
125 */
brianosman54f30c12016-07-18 10:53:52 -0700126 void addColorTextureProcessor(GrTexture*, sk_sp<GrColorSpaceXform>, const SkMatrix&);
joshualittb0a8a372014-09-23 09:50:21 -0700127 void addCoverageTextureProcessor(GrTexture*, const SkMatrix&);
brianosman54f30c12016-07-18 10:53:52 -0700128 void addColorTextureProcessor(GrTexture*, sk_sp<GrColorSpaceXform>, const SkMatrix&,
129 const GrTextureParams&);
joshualittb0a8a372014-09-23 09:50:21 -0700130 void addCoverageTextureProcessor(GrTexture*, const SkMatrix&, const GrTextureParams&);
tomhudson@google.comf13f5882012-06-25 17:27:28 +0000131
bsalomonac856c92015-08-27 06:30:17 -0700132 int numColorFragmentProcessors() const { return fColorFragmentProcessors.count(); }
133 int numCoverageFragmentProcessors() const { return fCoverageFragmentProcessors.count(); }
134 int numTotalFragmentProcessors() const { return this->numColorFragmentProcessors() +
135 this->numCoverageFragmentProcessors(); }
bsalomon@google.come3d32162012-07-20 13:37:06 +0000136
bungeman06ca8ec2016-06-09 08:01:03 -0700137 GrXPFactory* getXPFactory() const {
138 return fXPFactory.get();
joshualitt2fdeda02015-01-22 07:11:44 -0800139 }
egdaniel378092f2014-12-03 10:40:13 -0800140
bungeman06ca8ec2016-06-09 08:01:03 -0700141 GrFragmentProcessor* getColorFragmentProcessor(int i) const {
142 return fColorFragmentProcessors[i].get();
bsalomonac856c92015-08-27 06:30:17 -0700143 }
bungeman06ca8ec2016-06-09 08:01:03 -0700144 GrFragmentProcessor* getCoverageFragmentProcessor(int i) const {
145 return fCoverageFragmentProcessors[i].get();
bsalomonac856c92015-08-27 06:30:17 -0700146 }
bsalomon@google.come3d32162012-07-20 13:37:06 +0000147
bsalomon@google.com27c9b6d2011-09-12 14:30:27 +0000148 GrPaint& operator=(const GrPaint& paint) {
bsalomon@google.com27847de2011-02-22 20:59:41 +0000149 fAntiAlias = paint.fAntiAlias;
brianosman64d094d2016-03-25 06:01:59 -0700150 fDisableOutputConversionToSRGB = paint.fDisableOutputConversionToSRGB;
brianosman898235c2016-04-06 07:38:23 -0700151 fAllowSRGBInputs = paint.fAllowSRGBInputs;
dvonbeck9b03e7b2016-08-01 11:01:56 -0700152 fUsesDistanceVectorField = paint.fUsesDistanceVectorField;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000153
154 fColor = paint.fColor;
bsalomonac856c92015-08-27 06:30:17 -0700155 fColorFragmentProcessors = paint.fColorFragmentProcessors;
156 fCoverageFragmentProcessors = paint.fCoverageFragmentProcessors;
commit-bot@chromium.org42dacab2013-07-13 17:24:24 +0000157
bungeman06ca8ec2016-06-09 08:01:03 -0700158 fXPFactory = paint.fXPFactory;
egdaniel378092f2014-12-03 10:40:13 -0800159
bsalomon@google.com27c9b6d2011-09-12 14:30:27 +0000160 return *this;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000161 }
162
bsalomon@google.comc7448ce2012-10-05 19:04:13 +0000163 /**
cdalton1fa45722015-06-02 10:43:39 -0700164 * Returns true if the paint's output color will be constant after blending. If the result is
165 * true, constantColor will be updated to contain the constant color. Note that we can conflate
166 * coverage and color, so the actual values written to pixels with partial coverage may still
167 * not seem constant, even if this function returns true.
commit-bot@chromium.org24ab3b02013-08-14 21:56:37 +0000168 */
bsalomon198ca422016-08-11 07:39:33 -0700169 bool isConstantBlendedColor(GrColor* constantColor) const {
170 GrColor paintColor = this->getColor();
171 if (!fXPFactory && fColorFragmentProcessors.empty()) {
172 if (!GrColorIsOpaque(paintColor)) {
173 return false;
174 }
175 *constantColor = paintColor;
176 return true;
177 }
178 return this->internalIsConstantBlendedColor(paintColor, constantColor);
179 }
commit-bot@chromium.org24ab3b02013-08-14 21:56:37 +0000180
joshualitt5531d512014-12-17 15:50:11 -0800181private:
bsalomon198ca422016-08-11 07:39:33 -0700182 bool internalIsConstantBlendedColor(GrColor paintColor, GrColor* constantColor) const;
183
bungeman06ca8ec2016-06-09 08:01:03 -0700184 mutable sk_sp<GrXPFactory> fXPFactory;
185 SkSTArray<4, sk_sp<GrFragmentProcessor>> fColorFragmentProcessors;
186 SkSTArray<2, sk_sp<GrFragmentProcessor>> fCoverageFragmentProcessors;
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000187
bungeman06ca8ec2016-06-09 08:01:03 -0700188 bool fAntiAlias;
189 bool fDisableOutputConversionToSRGB;
190 bool fAllowSRGBInputs;
dvonbeck9b03e7b2016-08-01 11:01:56 -0700191 bool fUsesDistanceVectorField;
bsalomon@google.comc7448ce2012-10-05 19:04:13 +0000192
brianosmana4535a32016-06-24 12:50:19 -0700193 GrColor4f fColor;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000194};
195
196#endif