blob: 7084dc67b8bf75f213857ae3fcbdd5ec79a5ec28 [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"
Florin Malita39d71de2017-10-31 11:33:49 -040018#include "SkTemplates.h"
rileya@google.com1c6d64b2012-07-27 15:49:05 +000019
Florin Malitad4e9ec82017-10-25 18:00:26 -040020class SkColorSpace;
Florin Malita39d71de2017-10-31 11:33:49 -040021class SkColorSpaceXformer;
Florin Malitad4e9ec82017-10-25 18:00:26 -040022class SkRasterPipeline;
23class SkReadBuffer;
24class SkWriteBuffer;
rileya@google.com1c6d64b2012-07-27 15:49:05 +000025
Florin Malita4aed1382017-05-25 10:38:07 -040026class SkGradientShaderBase : public SkShaderBase {
rileya@google.com1c6d64b2012-07-27 15:49:05 +000027public:
reed@google.com437d6eb2013-05-23 19:03:05 +000028 struct Descriptor {
29 Descriptor() {
30 sk_bzero(this, sizeof(*this));
31 fTileMode = SkShader::kClamp_TileMode;
32 }
skia.committer@gmail.com3e2345a2013-05-24 07:01:26 +000033
reedaddf2ed2014-08-11 08:28:24 -070034 const SkMatrix* fLocalMatrix;
brianosmane25d71c2016-09-28 11:27:28 -070035 const SkColor4f* fColors;
brianosmanb9c51372016-09-15 11:09:45 -070036 sk_sp<SkColorSpace> fColorSpace;
reed@google.com437d6eb2013-05-23 19:03:05 +000037 const SkScalar* fPos;
38 int fCount;
39 SkShader::TileMode fTileMode;
commit-bot@chromium.org6c5aea22014-04-22 16:25:15 +000040 uint32_t fGradFlags;
reed9fa60da2014-08-21 07:59:51 -070041
42 void flatten(SkWriteBuffer&) const;
43 };
44
45 class DescriptorScope : public Descriptor {
46 public:
47 DescriptorScope() {}
mtklein88fd0fb2014-12-01 06:56:38 -080048
reed9fa60da2014-08-21 07:59:51 -070049 bool unflatten(SkReadBuffer&);
50
51 // fColors and fPos always point into local memory, so they can be safely mutated
52 //
brianosmane25d71c2016-09-28 11:27:28 -070053 SkColor4f* mutableColors() { return const_cast<SkColor4f*>(fColors); }
reed9fa60da2014-08-21 07:59:51 -070054 SkScalar* mutablePos() { return const_cast<SkScalar*>(fPos); }
55
56 private:
57 enum {
58 kStorageCount = 16
59 };
brianosmane25d71c2016-09-28 11:27:28 -070060 SkColor4f fColorStorage[kStorageCount];
reed9fa60da2014-08-21 07:59:51 -070061 SkScalar fPosStorage[kStorageCount];
62 SkMatrix fLocalMatrixStorage;
63 SkAutoMalloc fDynamicStorage;
reed@google.com437d6eb2013-05-23 19:03:05 +000064 };
65
mtkleincc695fe2014-12-10 10:29:19 -080066 SkGradientShaderBase(const Descriptor& desc, const SkMatrix& ptsToUnit);
Brian Salomond3b65972017-03-22 12:05:03 -040067 ~SkGradientShaderBase() override;
rileya@google.com1c6d64b2012-07-27 15:49:05 +000068
mtklein36352bf2015-03-25 18:17:31 -070069 bool isOpaque() const override;
rileya@google.com1c6d64b2012-07-27 15:49:05 +000070
brianosmand4546092016-09-22 12:31:58 -070071 enum class GradientBitmapType : uint8_t {
72 kLegacy,
73 kSRGB,
74 kHalfFloat,
75 };
76
77 void getGradientTableBitmap(SkBitmap*, GradientBitmapType bitmapType) const;
rileya@google.com1c6d64b2012-07-27 15:49:05 +000078
commit-bot@chromium.org6c5aea22014-04-22 16:25:15 +000079 uint32_t getGradFlags() const { return fGradFlags; }
commit-bot@chromium.org53783b02014-04-17 21:09:49 +000080
Florin Malita0e36b3f2017-06-05 23:33:45 -040081 SkColor4f getXformedColor(size_t index, SkColorSpace*) const;
82
rileya@google.com1c6d64b2012-07-27 15:49:05 +000083protected:
fmalitabc590c02016-02-22 09:12:33 -080084 class GradientShaderBase4fContext;
85
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000086 SkGradientShaderBase(SkReadBuffer& );
mtklein36352bf2015-03-25 18:17:31 -070087 void flatten(SkWriteBuffer&) const override;
commit-bot@chromium.org0f10f7b2014-03-13 18:02:17 +000088 SK_TO_STRING_OVERRIDE()
rileya@google.com1c6d64b2012-07-27 15:49:05 +000089
Florin Malita5f379a82017-10-18 16:22:35 -040090 void commonAsAGradient(GradientInfo*) const;
skia.committer@gmail.comd3b28e82014-04-22 03:05:17 +000091
mtklein36352bf2015-03-25 18:17:31 -070092 bool onAsLuminanceColor(SkColor*) const override;
reed8367b8c2014-08-22 08:30:20 -070093
Florin Malita84d7cf92017-10-25 15:31:54 -040094 void initLinearBitmap(SkBitmap* bitmap, GradientBitmapType) const;
brianosmand4546092016-09-22 12:31:58 -070095
Mike Reed1d8c42e2017-08-29 14:58:19 -040096 bool onAppendStages(const StageRec&) const override;
Mike Kleina3771842017-05-04 19:38:48 -040097
Florin Malita50b20842017-07-29 19:08:28 -040098 virtual void appendGradientStages(SkArenaAlloc* alloc, SkRasterPipeline* tPipeline,
99 SkRasterPipeline* postPipeline) const = 0;
Mike Kleina3771842017-05-04 19:38:48 -0400100
fmalita088e21b2016-10-05 09:28:42 -0700101 template <typename T, typename... Args>
Herb Derby83e939b2017-02-07 14:25:11 -0500102 static Context* CheckedMakeContext(SkArenaAlloc* alloc, Args&&... args) {
103 auto* ctx = alloc->make<T>(std::forward<Args>(args)...);
fmalita088e21b2016-10-05 09:28:42 -0700104 if (!ctx->isValid()) {
fmalita088e21b2016-10-05 09:28:42 -0700105 return nullptr;
106 }
107 return ctx;
108 }
109
Florin Malita39d71de2017-10-31 11:33:49 -0400110 struct AutoXformColors {
111 AutoXformColors(const SkGradientShaderBase&, SkColorSpaceXformer*);
112
113 SkAutoSTMalloc<8, SkColor> fColors;
114 };
115
Mike Kleina3771842017-05-04 19:38:48 -0400116 const SkMatrix fPtsToUnit;
117 TileMode fTileMode;
Mike Kleina3771842017-05-04 19:38:48 -0400118 uint8_t fGradFlags;
Mike Kleina3771842017-05-04 19:38:48 -0400119
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000120private:
121 enum {
122 kColorStorageCount = 4, // more than this many colors, and we'll use sk_malloc for the space
123
Florin Malita39d71de2017-10-31 11:33:49 -0400124 kStorageSize = kColorStorageCount * (sizeof(SkColor4f) + sizeof(SkScalar))
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000125 };
Florin Malita39d71de2017-10-31 11:33:49 -0400126 SkColor4f fStorage[(kStorageSize + sizeof(SkColor4f) - 1) / sizeof(SkColor4f)];
127
reedf3182eb2015-11-17 08:12:19 -0800128public:
Florin Malitaed6ae562017-10-28 11:06:48 -0400129 SkScalar getPos(int i) const {
130 SkASSERT(i < fColorCount);
131 return fOrigPos ? fOrigPos[i] : SkIntToScalar(i) / (fColorCount - 1);
132 }
133
Florin Malita39d71de2017-10-31 11:33:49 -0400134 SkColor getLegacyColor(int i) const {
135 SkASSERT(i < fColorCount);
136 return fOrigColors4f[i].toSkColor();
137 }
138
brianosmanb9c51372016-09-15 11:09:45 -0700139 SkColor4f* fOrigColors4f; // original colors, as linear floats
140 SkScalar* fOrigPos; // original positions
141 int fColorCount;
Florin Malita39d71de2017-10-31 11:33:49 -0400142 sk_sp<SkColorSpace> fColorSpace; // color space of gradient stops
reedf3182eb2015-11-17 08:12:19 -0800143
144 bool colorsAreOpaque() const { return fColorsAreOpaque; }
145
fmenozzicd9a1d02016-08-15 07:03:47 -0700146 TileMode getTileMode() const { return fTileMode; }
fmenozzicd9a1d02016-08-15 07:03:47 -0700147
reedf3182eb2015-11-17 08:12:19 -0800148private:
brianosmanb9c51372016-09-15 11:09:45 -0700149 bool fColorsAreOpaque;
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000150
Florin Malita4aed1382017-05-25 10:38:07 -0400151 typedef SkShaderBase INHERITED;
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000152};
153
154///////////////////////////////////////////////////////////////////////////////
155
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +0000156#if SK_SUPPORT_GPU
157
Brian Salomon4cbb6e62017-10-25 15:12:19 -0400158#include "GrColorSpaceInfo.h"
bsalomon@google.com77af6802013-10-02 13:04:56 +0000159#include "GrCoordTransform.h"
bsalomon6251d172014-10-15 10:50:36 -0700160#include "GrFragmentProcessor.h"
egdaniel64c47282015-11-13 06:54:19 -0800161#include "glsl/GrGLSLFragmentProcessor.h"
egdaniel018fb622015-10-28 07:26:40 -0700162#include "glsl/GrGLSLProgramDataManager.h"
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +0000163
egdaniel605dd0f2014-11-12 08:35:25 -0800164class GrInvariantOutput;
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000165
166/*
bsalomon@google.comd8b5fac2012-11-01 17:02:46 +0000167 * The interpretation of the texture matrix depends on the sample mode. The
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000168 * texture matrix is applied both when the texture coordinates are explicit
169 * and when vertex positions are used as texture coordinates. In the latter
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000170 * case the texture matrix is applied to the pre-view-matrix position
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000171 * values.
172 *
173 * Normal SampleMode
174 * The post-matrix texture coordinates are in normalize space with (0,0) at
175 * the top-left and (1,1) at the bottom right.
176 * RadialGradient
177 * The matrix specifies the radial gradient parameters.
178 * (0,0) in the post-matrix space is center of the radial gradient.
179 * Radial2Gradient
180 * Matrix transforms to space where first circle is centered at the
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000181 * origin. The second circle will be centered (x, 0) where x may be
182 * 0 and is provided by setRadial2Params. The post-matrix space is
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000183 * normalized such that 1 is the second radius - first radius.
184 * SweepGradient
185 * The angle from the origin of texture coordinates in post-matrix space
186 * determines the gradient value.
187 */
188
rileya@google.comb3e50f22012-08-20 17:43:08 +0000189 class GrTextureStripAtlas;
190
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000191// Base class for Gr gradient effects
joshualittb0a8a372014-09-23 09:50:21 -0700192class GrGradientEffect : public GrFragmentProcessor {
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000193public:
brianosman9557c272016-09-15 06:59:15 -0700194 struct CreateArgs {
195 CreateArgs(GrContext* context,
196 const SkGradientShaderBase* shader,
197 const SkMatrix* matrix,
brianosmanb9c51372016-09-15 11:09:45 -0700198 SkShader::TileMode tileMode,
Brian Osman5911a7c2017-10-25 12:52:31 -0400199 const SkColorSpace* dstColorSpace)
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400200 : fContext(context)
201 , fShader(shader)
202 , fMatrix(matrix)
Brian Osman5911a7c2017-10-25 12:52:31 -0400203 , fDstColorSpace(dstColorSpace) {
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400204 switch (tileMode) {
205 case SkShader::kClamp_TileMode:
206 fWrapMode = GrSamplerState::WrapMode::kClamp;
207 break;
208 case SkShader::kRepeat_TileMode:
209 fWrapMode = GrSamplerState::WrapMode::kRepeat;
210 break;
211 case SkShader::kMirror_TileMode:
212 fWrapMode = GrSamplerState::WrapMode::kMirrorRepeat;
213 break;
214 }
215 }
216
217 CreateArgs(GrContext* context,
218 const SkGradientShaderBase* shader,
219 const SkMatrix* matrix,
220 GrSamplerState::WrapMode wrapMode,
Brian Osman5911a7c2017-10-25 12:52:31 -0400221 const SkColorSpace* dstColorSpace)
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400222 : fContext(context)
223 , fShader(shader)
224 , fMatrix(matrix)
225 , fWrapMode(wrapMode)
Brian Osman5911a7c2017-10-25 12:52:31 -0400226 , fDstColorSpace(dstColorSpace) {}
brianosman9557c272016-09-15 06:59:15 -0700227
228 GrContext* fContext;
229 const SkGradientShaderBase* fShader;
230 const SkMatrix* fMatrix;
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400231 GrSamplerState::WrapMode fWrapMode;
Brian Osman5911a7c2017-10-25 12:52:31 -0400232 const SkColorSpace* fDstColorSpace;
brianosman9557c272016-09-15 06:59:15 -0700233 };
234
fmenozzi55d318d2016-08-09 08:05:57 -0700235 class GLSLProcessor;
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000236
Brian Salomond3b65972017-03-22 12:05:03 -0400237 ~GrGradientEffect() override;
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000238
rileya@google.comb3e50f22012-08-20 17:43:08 +0000239 bool useAtlas() const { return SkToBool(-1 != fRow); }
fmenozzicd9a1d02016-08-15 07:03:47 -0700240 SkScalar getYCoord() const { return fYCoord; }
rileya@google.comb3e50f22012-08-20 17:43:08 +0000241
fmenozzicd9a1d02016-08-15 07:03:47 -0700242 enum ColorType {
243 kTwo_ColorType,
Brian Osmana8e57442017-09-11 17:21:35 -0400244 kThree_ColorType, // 0, t, 1
fmenozzicd9a1d02016-08-15 07:03:47 -0700245 kTexture_ColorType,
Brian Salomon466ad992016-10-13 16:08:36 -0400246 kSingleHardStop_ColorType, // 0, t, t, 1
fmenozzicd9a1d02016-08-15 07:03:47 -0700247 kHardStopLeftEdged_ColorType, // 0, 0, 1
248 kHardStopRightEdged_ColorType, // 0, 1, 1
fmenozzicd9a1d02016-08-15 07:03:47 -0700249 };
250
251 ColorType getColorType() const { return fColorType; }
252
253 // Determines the type of gradient, one of:
254 // - Two-color
255 // - Symmetric three-color
256 // - Texture
257 // - Centered hard stop
258 // - Left-edged hard stop
259 // - Right-edged hard stop
260 ColorType determineColorType(const SkGradientShaderBase& shader);
bsalomon@google.com82d12232013-09-09 15:36:26 +0000261
262 enum PremulType {
263 kBeforeInterp_PremulType,
264 kAfterInterp_PremulType,
265 };
266
267 PremulType getPremulType() const { return fPremulType; }
268
Brian Osmand43f7b62017-10-19 15:42:01 -0400269 const GrColor4f* getColors4f(int pos) const {
brianosmanb9c51372016-09-15 11:09:45 -0700270 SkASSERT(fColorType != kTexture_ColorType);
271 SkASSERT(pos < fColors4f.count());
272 return &fColors4f[pos];
273 }
274
bsalomon@google.comd4726202012-08-03 14:34:46 +0000275protected:
Ethan Nicholasabff9562017-10-09 10:54:08 -0400276 GrGradientEffect(ClassID classID, const CreateArgs&, bool isOpaque);
Brian Salomonf8480b92017-07-27 15:45:59 -0400277 explicit GrGradientEffect(const GrGradientEffect&); // facilitates clone() implementations
Brian Salomon587e08f2017-01-27 10:59:27 -0500278
Brian Osman5911a7c2017-10-25 12:52:31 -0400279 // Helper function used by derived class factories to handle color space transformation and
280 // modulation by input alpha.
281 static std::unique_ptr<GrFragmentProcessor> AdjustFP(
282 std::unique_ptr<GrGradientEffect> gradientFP, const CreateArgs& args) {
283 if (!gradientFP->isValid()) {
284 return nullptr;
285 }
286 std::unique_ptr<GrFragmentProcessor> fp;
287 // With analytic gradients, we pre-convert the stops to the destination color space, so no
288 // xform is needed. With texture-based gradients, we leave the data in the source color
289 // space (to avoid clamping if we can't use F16)... Add an extra FP to do the xform.
290 if (kTexture_ColorType == gradientFP->getColorType()) {
Brian Osmanf06ead92017-10-30 13:47:41 -0400291 // Our texture is always either F16 or sRGB, so the data is "linear" in the shader.
292 // Create our xform assuming float inputs, which will suppress any extra sRGB work.
293 // We do support having a transfer function on the color space of the stops, so
294 // this FP may include that transformation.
Brian Osman5911a7c2017-10-25 12:52:31 -0400295 fp = GrColorSpaceXformEffect::Make(std::move(gradientFP),
296 args.fShader->fColorSpace.get(),
Brian Osmanf06ead92017-10-30 13:47:41 -0400297 kRGBA_float_GrPixelConfig,
Brian Osman5911a7c2017-10-25 12:52:31 -0400298 args.fDstColorSpace);
299 } else {
300 fp = std::move(gradientFP);
301 }
302 return GrFragmentProcessor::MulOutputByInputAlpha(std::move(fp));
303 }
304
305#if GR_TEST_UTILS
Brian Osmane75c19f2016-10-10 11:26:43 -0400306 /** Helper struct that stores (and populates) parameters to construct a random gradient.
Brian Osmana2196532016-10-17 12:48:13 -0400307 If fUseColors4f is true, then the SkColor4f factory should be called, with fColors4f and
308 fColorSpace. Otherwise, the SkColor factory should be called, with fColors. fColorCount
309 will be the number of color stops in either case, and fColors and fStops can be passed to
310 the gradient factory. (The constructor may decide not to use stops, in which case fStops
311 will be nullptr). */
Brian Osman3f748602016-10-03 18:29:03 -0400312 struct RandomGradientParams {
Brian Salomon5d4cd9e2017-02-09 11:16:46 -0500313 static const int kMaxRandomGradientColors = 5;
Brian Osmane75c19f2016-10-10 11:26:43 -0400314
Brian Osman3f748602016-10-03 18:29:03 -0400315 RandomGradientParams(SkRandom* r);
316
Brian Osmana2196532016-10-17 12:48:13 -0400317 bool fUseColors4f;
Brian Osman3f748602016-10-03 18:29:03 -0400318 SkColor fColors[kMaxRandomGradientColors];
Brian Osmana2196532016-10-17 12:48:13 -0400319 SkColor4f fColors4f[kMaxRandomGradientColors];
320 sk_sp<SkColorSpace> fColorSpace;
Brian Osman3f748602016-10-03 18:29:03 -0400321 SkScalar fStopStorage[kMaxRandomGradientColors];
322 SkShader::TileMode fTileMode;
323 int fColorCount;
324 SkScalar* fStops;
325 };
Hal Canary6f6961e2017-01-31 13:50:44 -0500326 #endif
bsalomon@google.comd4726202012-08-03 14:34:46 +0000327
mtklein36352bf2015-03-25 18:17:31 -0700328 bool onIsEqual(const GrFragmentProcessor&) const override;
bsalomon@google.com68b58c92013-01-17 16:50:08 +0000329
commit-bot@chromium.org5fd7d5c2013-10-04 01:20:09 +0000330 const GrCoordTransform& getCoordTransform() const { return fCoordTransform; }
331
Brian Salomon6af27012017-06-09 08:21:42 -0400332 /** Checks whether the constructor failed to fully initialize the processor. */
Brian Salomon06e547c2017-06-09 16:11:32 -0400333 bool isValid() const {
334 return fColorType != kTexture_ColorType || fTextureSampler.isInitialized();
335 }
Brian Salomon6af27012017-06-09 08:21:42 -0400336
bsalomon@google.comd4726202012-08-03 14:34:46 +0000337private:
Brian Salomon587e08f2017-01-27 10:59:27 -0500338 static OptimizationFlags OptFlags(bool isOpaque);
339
Brian Osmand43f7b62017-10-19 15:42:01 -0400340 SkTDArray<GrColor4f> fColors4f;
brianosmanb9c51372016-09-15 11:09:45 -0700341
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400342 SkTDArray<SkScalar> fPositions;
343 GrSamplerState::WrapMode fWrapMode;
fmenozzicd9a1d02016-08-15 07:03:47 -0700344
bsalomon@google.com77af6802013-10-02 13:04:56 +0000345 GrCoordTransform fCoordTransform;
Brian Salomon0bbecb22016-11-17 11:38:22 -0500346 TextureSampler fTextureSampler;
bsalomon@google.com81712882012-11-01 17:12:34 +0000347 SkScalar fYCoord;
rileya@google.comb3e50f22012-08-20 17:43:08 +0000348 GrTextureStripAtlas* fAtlas;
349 int fRow;
bsalomon@google.com371e1052013-01-11 21:08:55 +0000350 bool fIsOpaque;
fmenozzicd9a1d02016-08-15 07:03:47 -0700351 ColorType fColorType;
352 PremulType fPremulType; // This is already baked into the table for texture gradients, and
353 // only changes behavior for gradients that don't use a texture.
joshualittb0a8a372014-09-23 09:50:21 -0700354 typedef GrFragmentProcessor INHERITED;
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000355
356};
357
358///////////////////////////////////////////////////////////////////////////////
359
fmenozzicd9a1d02016-08-15 07:03:47 -0700360// Base class for GL gradient effects
fmenozzi55d318d2016-08-09 08:05:57 -0700361class GrGradientEffect::GLSLProcessor : public GrGLSLFragmentProcessor {
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000362public:
fmenozzicd9a1d02016-08-15 07:03:47 -0700363 GLSLProcessor() {
364 fCachedYCoord = SK_ScalarMax;
365 }
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000366
wangyixb1daa862015-08-18 11:29:31 -0700367protected:
Brian Salomonab015ef2017-04-04 10:15:51 -0400368 void onSetData(const GrGLSLProgramDataManager&, const GrFragmentProcessor&) override;
rileya@google.comb3e50f22012-08-20 17:43:08 +0000369
bsalomon@google.comf78df332012-10-29 12:43:38 +0000370protected:
bsalomon63e99f72014-07-21 08:03:14 -0700371 /**
372 * Subclasses must call this. It will return a key for the part of the shader code controlled
373 * by the base class. The subclasses must stick it in their key and then pass it to the below
374 * emit* functions from their emitCode function.
375 */
joshualittb0a8a372014-09-23 09:50:21 -0700376 static uint32_t GenBaseGradientKey(const GrProcessor&);
bsalomon63e99f72014-07-21 08:03:14 -0700377
378 // Emits the uniform used as the y-coord to texture samples in derived classes. Subclasses
379 // should call this method from their emitCode().
egdaniel7ea439b2015-12-03 09:20:44 -0800380 void emitUniforms(GrGLSLUniformHandler*, const GrGradientEffect&);
bsalomon63e99f72014-07-21 08:03:14 -0700381
fmenozzicd9a1d02016-08-15 07:03:47 -0700382 // Emit code that gets a fragment's color from an expression for t; has branches for
383 // several control flows inside -- 2-color gradients, 3-color symmetric gradients, 4+
384 // color gradients that use the traditional texture lookup, as well as several varieties
385 // of hard stop gradients
cdalton85285412016-02-18 12:37:07 -0800386 void emitColor(GrGLSLFPFragmentBuilder* fragBuilder,
egdaniel7ea439b2015-12-03 09:20:44 -0800387 GrGLSLUniformHandler* uniformHandler,
Brian Salomon1edc5b92016-11-29 13:43:46 -0500388 const GrShaderCaps* shaderCaps,
joshualitt60030bc2014-11-25 14:21:55 -0800389 const GrGradientEffect&,
bsalomon63e99f72014-07-21 08:03:14 -0700390 const char* gradientTValue,
bsalomon63e99f72014-07-21 08:03:14 -0700391 const char* outputColor,
392 const char* inputColor,
bsalomonb58a2b42016-09-26 06:55:02 -0700393 const TextureSamplers&);
bsalomon63e99f72014-07-21 08:03:14 -0700394
395private:
Florin Malitab81a8b92017-08-08 12:14:17 -0400396 void emitAnalyticalColor(GrGLSLFPFragmentBuilder* fragBuilder,
397 GrGLSLUniformHandler* uniformHandler,
398 const GrShaderCaps* shaderCaps,
399 const GrGradientEffect&,
400 const char* gradientTValue,
401 const char* outputColor,
402 const char* inputColor);
403
bsalomon@google.comd8b5fac2012-11-01 17:02:46 +0000404 enum {
Brian Osmanfe3e8582017-10-20 11:27:49 -0400405 // First bit for premul before/after interpolation
fmenozzicd9a1d02016-08-15 07:03:47 -0700406 kPremulBeforeInterpKey = 1,
bsalomon@google.com82d12232013-09-09 15:36:26 +0000407
fmenozzicd9a1d02016-08-15 07:03:47 -0700408 // Next three bits for 2/3 color type or different special
Brian Osmanfe3e8582017-10-20 11:27:49 -0400409 // hard stop cases ('none' means using texture atlas)
fmenozzicd9a1d02016-08-15 07:03:47 -0700410 kTwoColorKey = 2,
411 kThreeColorKey = 4,
Brian Salomonf8480b92017-07-27 15:45:59 -0400412
Brian Osman2ab4b2b2017-09-12 11:20:56 -0400413 kHardStopCenteredKey = 6,
414 kHardStopZeroZeroOneKey = 8,
415 kHardStopZeroOneOneKey = 10,
fmenozzicd9a1d02016-08-15 07:03:47 -0700416
417 // Next two bits for tile mode
418 kClampTileMode = 16,
419 kRepeatTileMode = 32,
420 kMirrorTileMode = 48,
421
422 // Lower six bits for premul, 2/3 color type, and tile mode
423 kReservedBits = 6,
bsalomon@google.comd8b5fac2012-11-01 17:02:46 +0000424 };
425
bsalomon@google.com81712882012-11-01 17:12:34 +0000426 SkScalar fCachedYCoord;
fmenozzicd9a1d02016-08-15 07:03:47 -0700427 GrGLSLProgramDataManager::UniformHandle fColorsUni;
Brian Osmana8e57442017-09-11 17:21:35 -0400428 GrGLSLProgramDataManager::UniformHandle fExtraStopT;
egdaniel018fb622015-10-28 07:26:40 -0700429 GrGLSLProgramDataManager::UniformHandle fFSYUni;
rileya@google.comb3e50f22012-08-20 17:43:08 +0000430
egdaniel64c47282015-11-13 06:54:19 -0800431 typedef GrGLSLFragmentProcessor INHERITED;
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000432};
433
434#endif
435
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +0000436#endif