blob: 9d0fe5575e730fd0b2bbe0d4bc85c071fc29ccee [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"
egdaniel378092f2014-12-03 10:40:13 -080014#include "GrXferProcessor.h"
egdaniel95131432014-12-09 11:15:43 -080015#include "effects/GrPorterDuffXferProcessor.h"
wangyix58d890b2015-08-12 09:40:47 -070016#include "GrFragmentProcessor.h"
bsalomon@google.com27847de2011-02-22 20:59:41 +000017
egdanielb197b8f2015-02-17 07:34:43 -080018#include "SkRegion.h"
Scroggo97c88c22011-05-11 14:05:25 +000019#include "SkXfermode.h"
20
bsalomon@google.com27847de2011-02-22 20:59:41 +000021/**
bsalomon@google.comc7448ce2012-10-05 19:04:13 +000022 * The paint describes how color and coverage are computed at each pixel by GrContext draw
23 * functions and the how color is blended with the destination pixel.
24 *
25 * The paint allows installation of custom color and coverage stages. New types of stages are
joshualittb0a8a372014-09-23 09:50:21 -070026 * created by subclassing GrProcessor.
bsalomon@google.comc7448ce2012-10-05 19:04:13 +000027 *
28 * The primitive color computation starts with the color specified by setColor(). This color is the
bsalomon37f9a262015-02-02 13:00:10 -080029 * 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 +000030 *
31 * Fractional pixel coverage follows a similar flow. The coverage is initially the value specified
32 * by setCoverage(). This is input to the first coverage stage. Coverage stages are chained
33 * together in the same manner as color stages. The output of the last stage is modulated by any
34 * fractional coverage produced by anti-aliasing. This last step produces the final coverage, C.
35 *
bsalomon37f9a262015-02-02 13:00:10 -080036 * setXPFactory is used to control blending between the output color and dest. It also implements
37 * the application of fractional coverage from the coverage pipeline.
bsalomon@google.com27847de2011-02-22 20:59:41 +000038 */
39class GrPaint {
40public:
joshualitt2fdeda02015-01-22 07:11:44 -080041 GrPaint();
bsalomon@google.com27847de2011-02-22 20:59:41 +000042
bsalomon@google.comc7448ce2012-10-05 19:04:13 +000043 GrPaint(const GrPaint& paint) { *this = paint; }
bsalomon@google.com27847de2011-02-22 20:59:41 +000044
bsalomonac856c92015-08-27 06:30:17 -070045 ~GrPaint() { this->resetFragmentProcessors(); }
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 */
50 void setColor(GrColor color) { fColor = color; }
51 GrColor getColor() const { return fColor; }
52
53 /**
bsalomon@google.comc7448ce2012-10-05 19:04:13 +000054 * Should primitives be anti-aliased or not. Defaults to false.
55 */
56 void setAntiAlias(bool aa) { fAntiAlias = aa; }
57 bool isAntiAlias() const { return fAntiAlias; }
58
egdaniel378092f2014-12-03 10:40:13 -080059 const GrXPFactory* setXPFactory(const GrXPFactory* xpFactory) {
60 fXPFactory.reset(SkRef(xpFactory));
61 return xpFactory;
62 }
63
egdaniel95131432014-12-09 11:15:43 -080064 void setPorterDuffXPFactory(SkXfermode::Mode mode) {
65 fXPFactory.reset(GrPorterDuffXPFactory::Create(mode));
66 }
67
egdanielb197b8f2015-02-17 07:34:43 -080068 void setCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage = false);
egdaniel95131432014-12-09 11:15:43 -080069
bsalomon@google.comc7448ce2012-10-05 19:04:13 +000070 /**
joshualittb0a8a372014-09-23 09:50:21 -070071 * Appends an additional color processor to the color computation.
bsalomon@google.comc7448ce2012-10-05 19:04:13 +000072 */
bsalomonac856c92015-08-27 06:30:17 -070073 const GrFragmentProcessor* addColorFragmentProcessor(const GrFragmentProcessor* fp) {
joshualittb0a8a372014-09-23 09:50:21 -070074 SkASSERT(fp);
bsalomonac856c92015-08-27 06:30:17 -070075 fColorFragmentProcessors.push_back(SkRef(fp));
joshualittb0a8a372014-09-23 09:50:21 -070076 return fp;
tomhudson@google.comf13f5882012-06-25 17:27:28 +000077 }
78
bsalomon@google.comc7448ce2012-10-05 19:04:13 +000079 /**
joshualittb0a8a372014-09-23 09:50:21 -070080 * Appends an additional coverage processor to the coverage computation.
bsalomon@google.comc7448ce2012-10-05 19:04:13 +000081 */
bsalomonac856c92015-08-27 06:30:17 -070082 const GrFragmentProcessor* addCoverageFragmentProcessor(const GrFragmentProcessor* fp) {
joshualittb0a8a372014-09-23 09:50:21 -070083 SkASSERT(fp);
bsalomonac856c92015-08-27 06:30:17 -070084 fCoverageFragmentProcessors.push_back(SkRef(fp));
joshualittb0a8a372014-09-23 09:50:21 -070085 return fp;
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000086 }
87
commit-bot@chromium.org42dacab2013-07-13 17:24:24 +000088 /**
89 * Helpers for adding color or coverage effects that sample a texture. The matrix is applied
90 * to the src space position to compute texture coordinates.
91 */
joshualittb0a8a372014-09-23 09:50:21 -070092 void addColorTextureProcessor(GrTexture*, const SkMatrix&);
93 void addCoverageTextureProcessor(GrTexture*, const SkMatrix&);
94 void addColorTextureProcessor(GrTexture*, const SkMatrix&, const GrTextureParams&);
95 void addCoverageTextureProcessor(GrTexture*, const SkMatrix&, const GrTextureParams&);
tomhudson@google.comf13f5882012-06-25 17:27:28 +000096
bsalomonac856c92015-08-27 06:30:17 -070097 int numColorFragmentProcessors() const { return fColorFragmentProcessors.count(); }
98 int numCoverageFragmentProcessors() const { return fCoverageFragmentProcessors.count(); }
99 int numTotalFragmentProcessors() const { return this->numColorFragmentProcessors() +
100 this->numCoverageFragmentProcessors(); }
bsalomon@google.come3d32162012-07-20 13:37:06 +0000101
joshualitt2fdeda02015-01-22 07:11:44 -0800102 const GrXPFactory* getXPFactory() const {
103 if (!fXPFactory) {
104 fXPFactory.reset(GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode));
105 }
106 return fXPFactory.get();
107 }
egdaniel378092f2014-12-03 10:40:13 -0800108
bsalomonac856c92015-08-27 06:30:17 -0700109 const GrFragmentProcessor* getColorFragmentProcessor(int i) const {
110 return fColorFragmentProcessors[i];
111 }
112 const GrFragmentProcessor* getCoverageFragmentProcessor(int i) const {
113 return fCoverageFragmentProcessors[i];
114 }
bsalomon@google.come3d32162012-07-20 13:37:06 +0000115
bsalomon@google.com27c9b6d2011-09-12 14:30:27 +0000116 GrPaint& operator=(const GrPaint& paint) {
bsalomon@google.com27847de2011-02-22 20:59:41 +0000117 fAntiAlias = paint.fAntiAlias;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000118
119 fColor = paint.fColor;
bsalomonac856c92015-08-27 06:30:17 -0700120 this->resetFragmentProcessors();
121 fColorFragmentProcessors = paint.fColorFragmentProcessors;
122 fCoverageFragmentProcessors = paint.fCoverageFragmentProcessors;
123 for (int i = 0; i < fColorFragmentProcessors.count(); ++i) {
124 fColorFragmentProcessors[i]->ref();
125 }
126 for (int i = 0; i < fCoverageFragmentProcessors.count(); ++i) {
127 fCoverageFragmentProcessors[i]->ref();
128 }
commit-bot@chromium.org42dacab2013-07-13 17:24:24 +0000129
egdaniel378092f2014-12-03 10:40:13 -0800130 fXPFactory.reset(SkRef(paint.getXPFactory()));
131
bsalomon@google.com27c9b6d2011-09-12 14:30:27 +0000132 return *this;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000133 }
134
bsalomon@google.comc7448ce2012-10-05 19:04:13 +0000135 /**
cdalton1fa45722015-06-02 10:43:39 -0700136 * Returns true if the paint's output color will be constant after blending. If the result is
137 * true, constantColor will be updated to contain the constant color. Note that we can conflate
138 * coverage and color, so the actual values written to pixels with partial coverage may still
139 * not seem constant, even if this function returns true.
commit-bot@chromium.org24ab3b02013-08-14 21:56:37 +0000140 */
cdalton1fa45722015-06-02 10:43:39 -0700141 bool isConstantBlendedColor(GrColor* constantColor) const;
commit-bot@chromium.org24ab3b02013-08-14 21:56:37 +0000142
joshualitt5531d512014-12-17 15:50:11 -0800143private:
bsalomonac856c92015-08-27 06:30:17 -0700144 void resetFragmentProcessors() {
145 for (int i = 0; i < fColorFragmentProcessors.count(); ++i) {
146 fColorFragmentProcessors[i]->unref();
147 }
148 for (int i = 0; i < fCoverageFragmentProcessors.count(); ++i) {
149 fCoverageFragmentProcessors[i]->unref();
150 }
151 fColorFragmentProcessors.reset();
152 fCoverageFragmentProcessors.reset();
153 }
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000154
bsalomonac856c92015-08-27 06:30:17 -0700155 mutable SkAutoTUnref<const GrXPFactory> fXPFactory;
156 SkSTArray<4, const GrFragmentProcessor*, true> fColorFragmentProcessors;
157 SkSTArray<2, const GrFragmentProcessor*, true> fCoverageFragmentProcessors;
bsalomon@google.comc7448ce2012-10-05 19:04:13 +0000158
bsalomonac856c92015-08-27 06:30:17 -0700159 bool fAntiAlias;
bsalomonac856c92015-08-27 06:30:17 -0700160
161 GrColor fColor;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000162};
163
164#endif