blob: 0d8e7bef9a1ec083fdfd2e96014ecc6638d75821 [file] [log] [blame]
rileya@google.com1c6d64b2012-07-27 15:49:05 +00001/*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef SkGradientShaderPriv_DEFINED
9#define SkGradientShaderPriv_DEFINED
10
11#include "SkGradientShader.h"
Hal Canary95e3c052017-01-11 12:44:43 -050012
Herb Derby83e939b2017-02-07 14:25:11 -050013#include "SkArenaAlloc.h"
Hal Canary95e3c052017-01-11 12:44:43 -050014#include "SkAutoMalloc.h"
Florin Malitad4e9ec82017-10-25 18:00:26 -040015#include "SkMatrix.h"
Florin Malita4aed1382017-05-25 10:38:07 -040016#include "SkShaderBase.h"
Florin Malitad4e9ec82017-10-25 18:00:26 -040017#include "SkTDArray.h"
rileya@google.com1c6d64b2012-07-27 15:49:05 +000018
Florin Malitad4e9ec82017-10-25 18:00:26 -040019class SkColorSpace;
20class SkRasterPipeline;
21class SkReadBuffer;
22class SkWriteBuffer;
rileya@google.com1c6d64b2012-07-27 15:49:05 +000023
Florin Malita4aed1382017-05-25 10:38:07 -040024class SkGradientShaderBase : public SkShaderBase {
rileya@google.com1c6d64b2012-07-27 15:49:05 +000025public:
reed@google.com437d6eb2013-05-23 19:03:05 +000026 struct Descriptor {
27 Descriptor() {
28 sk_bzero(this, sizeof(*this));
29 fTileMode = SkShader::kClamp_TileMode;
30 }
skia.committer@gmail.com3e2345a2013-05-24 07:01:26 +000031
reedaddf2ed2014-08-11 08:28:24 -070032 const SkMatrix* fLocalMatrix;
brianosmane25d71c2016-09-28 11:27:28 -070033 const SkColor4f* fColors;
brianosmanb9c51372016-09-15 11:09:45 -070034 sk_sp<SkColorSpace> fColorSpace;
reed@google.com437d6eb2013-05-23 19:03:05 +000035 const SkScalar* fPos;
36 int fCount;
37 SkShader::TileMode fTileMode;
commit-bot@chromium.org6c5aea22014-04-22 16:25:15 +000038 uint32_t fGradFlags;
reed9fa60da2014-08-21 07:59:51 -070039
40 void flatten(SkWriteBuffer&) const;
41 };
42
43 class DescriptorScope : public Descriptor {
44 public:
45 DescriptorScope() {}
mtklein88fd0fb2014-12-01 06:56:38 -080046
reed9fa60da2014-08-21 07:59:51 -070047 bool unflatten(SkReadBuffer&);
48
49 // fColors and fPos always point into local memory, so they can be safely mutated
50 //
brianosmane25d71c2016-09-28 11:27:28 -070051 SkColor4f* mutableColors() { return const_cast<SkColor4f*>(fColors); }
reed9fa60da2014-08-21 07:59:51 -070052 SkScalar* mutablePos() { return const_cast<SkScalar*>(fPos); }
53
54 private:
55 enum {
56 kStorageCount = 16
57 };
brianosmane25d71c2016-09-28 11:27:28 -070058 SkColor4f fColorStorage[kStorageCount];
reed9fa60da2014-08-21 07:59:51 -070059 SkScalar fPosStorage[kStorageCount];
60 SkMatrix fLocalMatrixStorage;
61 SkAutoMalloc fDynamicStorage;
reed@google.com437d6eb2013-05-23 19:03:05 +000062 };
63
mtkleincc695fe2014-12-10 10:29:19 -080064 SkGradientShaderBase(const Descriptor& desc, const SkMatrix& ptsToUnit);
Brian Salomond3b65972017-03-22 12:05:03 -040065 ~SkGradientShaderBase() override;
rileya@google.com1c6d64b2012-07-27 15:49:05 +000066
mtklein36352bf2015-03-25 18:17:31 -070067 bool isOpaque() const override;
rileya@google.com1c6d64b2012-07-27 15:49:05 +000068
brianosmand4546092016-09-22 12:31:58 -070069 enum class GradientBitmapType : uint8_t {
70 kLegacy,
71 kSRGB,
72 kHalfFloat,
73 };
74
75 void getGradientTableBitmap(SkBitmap*, GradientBitmapType bitmapType) const;
rileya@google.com1c6d64b2012-07-27 15:49:05 +000076
commit-bot@chromium.org6c5aea22014-04-22 16:25:15 +000077 uint32_t getGradFlags() const { return fGradFlags; }
commit-bot@chromium.org53783b02014-04-17 21:09:49 +000078
Florin Malita0e36b3f2017-06-05 23:33:45 -040079 SkColor4f getXformedColor(size_t index, SkColorSpace*) const;
80
rileya@google.com1c6d64b2012-07-27 15:49:05 +000081protected:
fmalitabc590c02016-02-22 09:12:33 -080082 class GradientShaderBase4fContext;
83
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000084 SkGradientShaderBase(SkReadBuffer& );
mtklein36352bf2015-03-25 18:17:31 -070085 void flatten(SkWriteBuffer&) const override;
commit-bot@chromium.org0f10f7b2014-03-13 18:02:17 +000086 SK_TO_STRING_OVERRIDE()
rileya@google.com1c6d64b2012-07-27 15:49:05 +000087
Florin Malita5f379a82017-10-18 16:22:35 -040088 void commonAsAGradient(GradientInfo*) const;
skia.committer@gmail.comd3b28e82014-04-22 03:05:17 +000089
mtklein36352bf2015-03-25 18:17:31 -070090 bool onAsLuminanceColor(SkColor*) const override;
reed8367b8c2014-08-22 08:30:20 -070091
Florin Malita84d7cf92017-10-25 15:31:54 -040092 void initLinearBitmap(SkBitmap* bitmap, GradientBitmapType) const;
brianosmand4546092016-09-22 12:31:58 -070093
Mike Reed1d8c42e2017-08-29 14:58:19 -040094 bool onAppendStages(const StageRec&) const override;
Mike Kleina3771842017-05-04 19:38:48 -040095
Florin Malita50b20842017-07-29 19:08:28 -040096 virtual void appendGradientStages(SkArenaAlloc* alloc, SkRasterPipeline* tPipeline,
97 SkRasterPipeline* postPipeline) const = 0;
Mike Kleina3771842017-05-04 19:38:48 -040098
fmalita088e21b2016-10-05 09:28:42 -070099 template <typename T, typename... Args>
Herb Derby83e939b2017-02-07 14:25:11 -0500100 static Context* CheckedMakeContext(SkArenaAlloc* alloc, Args&&... args) {
101 auto* ctx = alloc->make<T>(std::forward<Args>(args)...);
fmalita088e21b2016-10-05 09:28:42 -0700102 if (!ctx->isValid()) {
fmalita088e21b2016-10-05 09:28:42 -0700103 return nullptr;
104 }
105 return ctx;
106 }
107
Mike Kleina3771842017-05-04 19:38:48 -0400108 const SkMatrix fPtsToUnit;
109 TileMode fTileMode;
Mike Kleina3771842017-05-04 19:38:48 -0400110 uint8_t fGradFlags;
Mike Kleina3771842017-05-04 19:38:48 -0400111
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000112private:
113 enum {
114 kColorStorageCount = 4, // more than this many colors, and we'll use sk_malloc for the space
115
Florin Malitacad3b8c2017-10-28 21:42:50 -0400116 kStorageSize = kColorStorageCount * (sizeof(SkColor) + sizeof(SkScalar) + sizeof(SkColor4f))
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000117 };
brianosmanb9c51372016-09-15 11:09:45 -0700118 SkColor fStorage[(kStorageSize + 3) >> 2];
reedf3182eb2015-11-17 08:12:19 -0800119public:
Florin Malitaed6ae562017-10-28 11:06:48 -0400120 SkScalar getPos(int i) const {
121 SkASSERT(i < fColorCount);
122 return fOrigPos ? fOrigPos[i] : SkIntToScalar(i) / (fColorCount - 1);
123 }
124
brianosmanb9c51372016-09-15 11:09:45 -0700125 SkColor* fOrigColors; // original colors, before modulation by paint in context.
126 SkColor4f* fOrigColors4f; // original colors, as linear floats
127 SkScalar* fOrigPos; // original positions
128 int fColorCount;
129 sk_sp<SkColorSpace> fColorSpace; // color space of gradient stops
reedf3182eb2015-11-17 08:12:19 -0800130
131 bool colorsAreOpaque() const { return fColorsAreOpaque; }
132
fmenozzicd9a1d02016-08-15 07:03:47 -0700133 TileMode getTileMode() const { return fTileMode; }
fmenozzicd9a1d02016-08-15 07:03:47 -0700134
reedf3182eb2015-11-17 08:12:19 -0800135private:
brianosmanb9c51372016-09-15 11:09:45 -0700136 bool fColorsAreOpaque;
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000137
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000138 void initCommon();
139
Florin Malita4aed1382017-05-25 10:38:07 -0400140 typedef SkShaderBase INHERITED;
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000141};
142
143///////////////////////////////////////////////////////////////////////////////
144
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +0000145#if SK_SUPPORT_GPU
146
Brian Salomon4cbb6e62017-10-25 15:12:19 -0400147#include "GrColorSpaceInfo.h"
bsalomon@google.com77af6802013-10-02 13:04:56 +0000148#include "GrCoordTransform.h"
bsalomon6251d172014-10-15 10:50:36 -0700149#include "GrFragmentProcessor.h"
egdaniel64c47282015-11-13 06:54:19 -0800150#include "glsl/GrGLSLFragmentProcessor.h"
egdaniel018fb622015-10-28 07:26:40 -0700151#include "glsl/GrGLSLProgramDataManager.h"
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +0000152
egdaniel605dd0f2014-11-12 08:35:25 -0800153class GrInvariantOutput;
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000154
155/*
bsalomon@google.comd8b5fac2012-11-01 17:02:46 +0000156 * The interpretation of the texture matrix depends on the sample mode. The
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000157 * texture matrix is applied both when the texture coordinates are explicit
158 * and when vertex positions are used as texture coordinates. In the latter
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000159 * case the texture matrix is applied to the pre-view-matrix position
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000160 * values.
161 *
162 * Normal SampleMode
163 * The post-matrix texture coordinates are in normalize space with (0,0) at
164 * the top-left and (1,1) at the bottom right.
165 * RadialGradient
166 * The matrix specifies the radial gradient parameters.
167 * (0,0) in the post-matrix space is center of the radial gradient.
168 * Radial2Gradient
169 * Matrix transforms to space where first circle is centered at the
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000170 * origin. The second circle will be centered (x, 0) where x may be
171 * 0 and is provided by setRadial2Params. The post-matrix space is
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000172 * normalized such that 1 is the second radius - first radius.
173 * SweepGradient
174 * The angle from the origin of texture coordinates in post-matrix space
175 * determines the gradient value.
176 */
177
rileya@google.comb3e50f22012-08-20 17:43:08 +0000178 class GrTextureStripAtlas;
179
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000180// Base class for Gr gradient effects
joshualittb0a8a372014-09-23 09:50:21 -0700181class GrGradientEffect : public GrFragmentProcessor {
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000182public:
brianosman9557c272016-09-15 06:59:15 -0700183 struct CreateArgs {
184 CreateArgs(GrContext* context,
185 const SkGradientShaderBase* shader,
186 const SkMatrix* matrix,
brianosmanb9c51372016-09-15 11:09:45 -0700187 SkShader::TileMode tileMode,
Brian Osman5911a7c2017-10-25 12:52:31 -0400188 const SkColorSpace* dstColorSpace)
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400189 : fContext(context)
190 , fShader(shader)
191 , fMatrix(matrix)
Brian Osman5911a7c2017-10-25 12:52:31 -0400192 , fDstColorSpace(dstColorSpace) {
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400193 switch (tileMode) {
194 case SkShader::kClamp_TileMode:
195 fWrapMode = GrSamplerState::WrapMode::kClamp;
196 break;
197 case SkShader::kRepeat_TileMode:
198 fWrapMode = GrSamplerState::WrapMode::kRepeat;
199 break;
200 case SkShader::kMirror_TileMode:
201 fWrapMode = GrSamplerState::WrapMode::kMirrorRepeat;
202 break;
203 }
204 }
205
206 CreateArgs(GrContext* context,
207 const SkGradientShaderBase* shader,
208 const SkMatrix* matrix,
209 GrSamplerState::WrapMode wrapMode,
Brian Osman5911a7c2017-10-25 12:52:31 -0400210 const SkColorSpace* dstColorSpace)
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400211 : fContext(context)
212 , fShader(shader)
213 , fMatrix(matrix)
214 , fWrapMode(wrapMode)
Brian Osman5911a7c2017-10-25 12:52:31 -0400215 , fDstColorSpace(dstColorSpace) {}
brianosman9557c272016-09-15 06:59:15 -0700216
217 GrContext* fContext;
218 const SkGradientShaderBase* fShader;
219 const SkMatrix* fMatrix;
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400220 GrSamplerState::WrapMode fWrapMode;
Brian Osman5911a7c2017-10-25 12:52:31 -0400221 const SkColorSpace* fDstColorSpace;
brianosman9557c272016-09-15 06:59:15 -0700222 };
223
fmenozzi55d318d2016-08-09 08:05:57 -0700224 class GLSLProcessor;
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000225
Brian Salomond3b65972017-03-22 12:05:03 -0400226 ~GrGradientEffect() override;
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000227
rileya@google.comb3e50f22012-08-20 17:43:08 +0000228 bool useAtlas() const { return SkToBool(-1 != fRow); }
fmenozzicd9a1d02016-08-15 07:03:47 -0700229 SkScalar getYCoord() const { return fYCoord; }
rileya@google.comb3e50f22012-08-20 17:43:08 +0000230
fmenozzicd9a1d02016-08-15 07:03:47 -0700231 enum ColorType {
232 kTwo_ColorType,
Brian Osmana8e57442017-09-11 17:21:35 -0400233 kThree_ColorType, // 0, t, 1
fmenozzicd9a1d02016-08-15 07:03:47 -0700234 kTexture_ColorType,
Brian Salomon466ad992016-10-13 16:08:36 -0400235 kSingleHardStop_ColorType, // 0, t, t, 1
fmenozzicd9a1d02016-08-15 07:03:47 -0700236 kHardStopLeftEdged_ColorType, // 0, 0, 1
237 kHardStopRightEdged_ColorType, // 0, 1, 1
fmenozzicd9a1d02016-08-15 07:03:47 -0700238 };
239
240 ColorType getColorType() const { return fColorType; }
241
242 // Determines the type of gradient, one of:
243 // - Two-color
244 // - Symmetric three-color
245 // - Texture
246 // - Centered hard stop
247 // - Left-edged hard stop
248 // - Right-edged hard stop
249 ColorType determineColorType(const SkGradientShaderBase& shader);
bsalomon@google.com82d12232013-09-09 15:36:26 +0000250
251 enum PremulType {
252 kBeforeInterp_PremulType,
253 kAfterInterp_PremulType,
254 };
255
256 PremulType getPremulType() const { return fPremulType; }
257
Brian Osmand43f7b62017-10-19 15:42:01 -0400258 const GrColor4f* getColors4f(int pos) const {
brianosmanb9c51372016-09-15 11:09:45 -0700259 SkASSERT(fColorType != kTexture_ColorType);
260 SkASSERT(pos < fColors4f.count());
261 return &fColors4f[pos];
262 }
263
bsalomon@google.comd4726202012-08-03 14:34:46 +0000264protected:
Ethan Nicholasabff9562017-10-09 10:54:08 -0400265 GrGradientEffect(ClassID classID, const CreateArgs&, bool isOpaque);
Brian Salomonf8480b92017-07-27 15:45:59 -0400266 explicit GrGradientEffect(const GrGradientEffect&); // facilitates clone() implementations
Brian Salomon587e08f2017-01-27 10:59:27 -0500267
Brian Osman5911a7c2017-10-25 12:52:31 -0400268 // Helper function used by derived class factories to handle color space transformation and
269 // modulation by input alpha.
270 static std::unique_ptr<GrFragmentProcessor> AdjustFP(
271 std::unique_ptr<GrGradientEffect> gradientFP, const CreateArgs& args) {
272 if (!gradientFP->isValid()) {
273 return nullptr;
274 }
275 std::unique_ptr<GrFragmentProcessor> fp;
276 // With analytic gradients, we pre-convert the stops to the destination color space, so no
277 // xform is needed. With texture-based gradients, we leave the data in the source color
278 // space (to avoid clamping if we can't use F16)... Add an extra FP to do the xform.
279 if (kTexture_ColorType == gradientFP->getColorType()) {
Brian Osmanf06ead92017-10-30 13:47:41 -0400280 // Our texture is always either F16 or sRGB, so the data is "linear" in the shader.
281 // Create our xform assuming float inputs, which will suppress any extra sRGB work.
282 // We do support having a transfer function on the color space of the stops, so
283 // this FP may include that transformation.
Brian Osman5911a7c2017-10-25 12:52:31 -0400284 fp = GrColorSpaceXformEffect::Make(std::move(gradientFP),
285 args.fShader->fColorSpace.get(),
Brian Osmanf06ead92017-10-30 13:47:41 -0400286 kRGBA_float_GrPixelConfig,
Brian Osman5911a7c2017-10-25 12:52:31 -0400287 args.fDstColorSpace);
288 } else {
289 fp = std::move(gradientFP);
290 }
291 return GrFragmentProcessor::MulOutputByInputAlpha(std::move(fp));
292 }
293
294#if GR_TEST_UTILS
Brian Osmane75c19f2016-10-10 11:26:43 -0400295 /** Helper struct that stores (and populates) parameters to construct a random gradient.
Brian Osmana2196532016-10-17 12:48:13 -0400296 If fUseColors4f is true, then the SkColor4f factory should be called, with fColors4f and
297 fColorSpace. Otherwise, the SkColor factory should be called, with fColors. fColorCount
298 will be the number of color stops in either case, and fColors and fStops can be passed to
299 the gradient factory. (The constructor may decide not to use stops, in which case fStops
300 will be nullptr). */
Brian Osman3f748602016-10-03 18:29:03 -0400301 struct RandomGradientParams {
Brian Salomon5d4cd9e2017-02-09 11:16:46 -0500302 static const int kMaxRandomGradientColors = 5;
Brian Osmane75c19f2016-10-10 11:26:43 -0400303
Brian Osman3f748602016-10-03 18:29:03 -0400304 RandomGradientParams(SkRandom* r);
305
Brian Osmana2196532016-10-17 12:48:13 -0400306 bool fUseColors4f;
Brian Osman3f748602016-10-03 18:29:03 -0400307 SkColor fColors[kMaxRandomGradientColors];
Brian Osmana2196532016-10-17 12:48:13 -0400308 SkColor4f fColors4f[kMaxRandomGradientColors];
309 sk_sp<SkColorSpace> fColorSpace;
Brian Osman3f748602016-10-03 18:29:03 -0400310 SkScalar fStopStorage[kMaxRandomGradientColors];
311 SkShader::TileMode fTileMode;
312 int fColorCount;
313 SkScalar* fStops;
314 };
Hal Canary6f6961e2017-01-31 13:50:44 -0500315 #endif
bsalomon@google.comd4726202012-08-03 14:34:46 +0000316
mtklein36352bf2015-03-25 18:17:31 -0700317 bool onIsEqual(const GrFragmentProcessor&) const override;
bsalomon@google.com68b58c92013-01-17 16:50:08 +0000318
commit-bot@chromium.org5fd7d5c2013-10-04 01:20:09 +0000319 const GrCoordTransform& getCoordTransform() const { return fCoordTransform; }
320
Brian Salomon6af27012017-06-09 08:21:42 -0400321 /** Checks whether the constructor failed to fully initialize the processor. */
Brian Salomon06e547c2017-06-09 16:11:32 -0400322 bool isValid() const {
323 return fColorType != kTexture_ColorType || fTextureSampler.isInitialized();
324 }
Brian Salomon6af27012017-06-09 08:21:42 -0400325
bsalomon@google.comd4726202012-08-03 14:34:46 +0000326private:
Brian Salomon587e08f2017-01-27 10:59:27 -0500327 static OptimizationFlags OptFlags(bool isOpaque);
328
Brian Osmand43f7b62017-10-19 15:42:01 -0400329 SkTDArray<GrColor4f> fColors4f;
brianosmanb9c51372016-09-15 11:09:45 -0700330
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400331 SkTDArray<SkScalar> fPositions;
332 GrSamplerState::WrapMode fWrapMode;
fmenozzicd9a1d02016-08-15 07:03:47 -0700333
bsalomon@google.com77af6802013-10-02 13:04:56 +0000334 GrCoordTransform fCoordTransform;
Brian Salomon0bbecb22016-11-17 11:38:22 -0500335 TextureSampler fTextureSampler;
bsalomon@google.com81712882012-11-01 17:12:34 +0000336 SkScalar fYCoord;
rileya@google.comb3e50f22012-08-20 17:43:08 +0000337 GrTextureStripAtlas* fAtlas;
338 int fRow;
bsalomon@google.com371e1052013-01-11 21:08:55 +0000339 bool fIsOpaque;
fmenozzicd9a1d02016-08-15 07:03:47 -0700340 ColorType fColorType;
341 PremulType fPremulType; // This is already baked into the table for texture gradients, and
342 // only changes behavior for gradients that don't use a texture.
joshualittb0a8a372014-09-23 09:50:21 -0700343 typedef GrFragmentProcessor INHERITED;
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000344
345};
346
347///////////////////////////////////////////////////////////////////////////////
348
fmenozzicd9a1d02016-08-15 07:03:47 -0700349// Base class for GL gradient effects
fmenozzi55d318d2016-08-09 08:05:57 -0700350class GrGradientEffect::GLSLProcessor : public GrGLSLFragmentProcessor {
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000351public:
fmenozzicd9a1d02016-08-15 07:03:47 -0700352 GLSLProcessor() {
353 fCachedYCoord = SK_ScalarMax;
354 }
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000355
wangyixb1daa862015-08-18 11:29:31 -0700356protected:
Brian Salomonab015ef2017-04-04 10:15:51 -0400357 void onSetData(const GrGLSLProgramDataManager&, const GrFragmentProcessor&) override;
rileya@google.comb3e50f22012-08-20 17:43:08 +0000358
bsalomon@google.comf78df332012-10-29 12:43:38 +0000359protected:
bsalomon63e99f72014-07-21 08:03:14 -0700360 /**
361 * Subclasses must call this. It will return a key for the part of the shader code controlled
362 * by the base class. The subclasses must stick it in their key and then pass it to the below
363 * emit* functions from their emitCode function.
364 */
joshualittb0a8a372014-09-23 09:50:21 -0700365 static uint32_t GenBaseGradientKey(const GrProcessor&);
bsalomon63e99f72014-07-21 08:03:14 -0700366
367 // Emits the uniform used as the y-coord to texture samples in derived classes. Subclasses
368 // should call this method from their emitCode().
egdaniel7ea439b2015-12-03 09:20:44 -0800369 void emitUniforms(GrGLSLUniformHandler*, const GrGradientEffect&);
bsalomon63e99f72014-07-21 08:03:14 -0700370
fmenozzicd9a1d02016-08-15 07:03:47 -0700371 // Emit code that gets a fragment's color from an expression for t; has branches for
372 // several control flows inside -- 2-color gradients, 3-color symmetric gradients, 4+
373 // color gradients that use the traditional texture lookup, as well as several varieties
374 // of hard stop gradients
cdalton85285412016-02-18 12:37:07 -0800375 void emitColor(GrGLSLFPFragmentBuilder* fragBuilder,
egdaniel7ea439b2015-12-03 09:20:44 -0800376 GrGLSLUniformHandler* uniformHandler,
Brian Salomon1edc5b92016-11-29 13:43:46 -0500377 const GrShaderCaps* shaderCaps,
joshualitt60030bc2014-11-25 14:21:55 -0800378 const GrGradientEffect&,
bsalomon63e99f72014-07-21 08:03:14 -0700379 const char* gradientTValue,
bsalomon63e99f72014-07-21 08:03:14 -0700380 const char* outputColor,
381 const char* inputColor,
bsalomonb58a2b42016-09-26 06:55:02 -0700382 const TextureSamplers&);
bsalomon63e99f72014-07-21 08:03:14 -0700383
384private:
Florin Malitab81a8b92017-08-08 12:14:17 -0400385 void emitAnalyticalColor(GrGLSLFPFragmentBuilder* fragBuilder,
386 GrGLSLUniformHandler* uniformHandler,
387 const GrShaderCaps* shaderCaps,
388 const GrGradientEffect&,
389 const char* gradientTValue,
390 const char* outputColor,
391 const char* inputColor);
392
bsalomon@google.comd8b5fac2012-11-01 17:02:46 +0000393 enum {
Brian Osmanfe3e8582017-10-20 11:27:49 -0400394 // First bit for premul before/after interpolation
fmenozzicd9a1d02016-08-15 07:03:47 -0700395 kPremulBeforeInterpKey = 1,
bsalomon@google.com82d12232013-09-09 15:36:26 +0000396
fmenozzicd9a1d02016-08-15 07:03:47 -0700397 // Next three bits for 2/3 color type or different special
Brian Osmanfe3e8582017-10-20 11:27:49 -0400398 // hard stop cases ('none' means using texture atlas)
fmenozzicd9a1d02016-08-15 07:03:47 -0700399 kTwoColorKey = 2,
400 kThreeColorKey = 4,
Brian Salomonf8480b92017-07-27 15:45:59 -0400401
Brian Osman2ab4b2b2017-09-12 11:20:56 -0400402 kHardStopCenteredKey = 6,
403 kHardStopZeroZeroOneKey = 8,
404 kHardStopZeroOneOneKey = 10,
fmenozzicd9a1d02016-08-15 07:03:47 -0700405
406 // Next two bits for tile mode
407 kClampTileMode = 16,
408 kRepeatTileMode = 32,
409 kMirrorTileMode = 48,
410
411 // Lower six bits for premul, 2/3 color type, and tile mode
412 kReservedBits = 6,
bsalomon@google.comd8b5fac2012-11-01 17:02:46 +0000413 };
414
bsalomon@google.com81712882012-11-01 17:12:34 +0000415 SkScalar fCachedYCoord;
fmenozzicd9a1d02016-08-15 07:03:47 -0700416 GrGLSLProgramDataManager::UniformHandle fColorsUni;
Brian Osmana8e57442017-09-11 17:21:35 -0400417 GrGLSLProgramDataManager::UniformHandle fExtraStopT;
egdaniel018fb622015-10-28 07:26:40 -0700418 GrGLSLProgramDataManager::UniformHandle fFSYUni;
rileya@google.comb3e50f22012-08-20 17:43:08 +0000419
egdaniel64c47282015-11-13 06:54:19 -0800420 typedef GrGLSLFragmentProcessor INHERITED;
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000421};
422
423#endif
424
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +0000425#endif