blob: 983c3ef124697e1b6a1b475fdec5712da344230d [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 "SkFixed.h"
16#include "SkMatrix.h"
Florin Malita4aed1382017-05-25 10:38:07 -040017#include "SkShaderBase.h"
Florin Malitad4e9ec82017-10-25 18:00:26 -040018#include "SkTDArray.h"
rileya@google.com1c6d64b2012-07-27 15:49:05 +000019
Florin Malitad4e9ec82017-10-25 18:00:26 -040020class SkColorSpace;
21class SkRasterPipeline;
22class SkReadBuffer;
23class SkWriteBuffer;
rileya@google.com1c6d64b2012-07-27 15:49:05 +000024
Florin Malita4aed1382017-05-25 10:38:07 -040025class SkGradientShaderBase : public SkShaderBase {
rileya@google.com1c6d64b2012-07-27 15:49:05 +000026public:
reed@google.com437d6eb2013-05-23 19:03:05 +000027 struct Descriptor {
28 Descriptor() {
29 sk_bzero(this, sizeof(*this));
30 fTileMode = SkShader::kClamp_TileMode;
31 }
skia.committer@gmail.com3e2345a2013-05-24 07:01:26 +000032
reedaddf2ed2014-08-11 08:28:24 -070033 const SkMatrix* fLocalMatrix;
brianosmane25d71c2016-09-28 11:27:28 -070034 const SkColor4f* fColors;
brianosmanb9c51372016-09-15 11:09:45 -070035 sk_sp<SkColorSpace> fColorSpace;
reed@google.com437d6eb2013-05-23 19:03:05 +000036 const SkScalar* fPos;
37 int fCount;
38 SkShader::TileMode fTileMode;
commit-bot@chromium.org6c5aea22014-04-22 16:25:15 +000039 uint32_t fGradFlags;
reed9fa60da2014-08-21 07:59:51 -070040
41 void flatten(SkWriteBuffer&) const;
42 };
43
44 class DescriptorScope : public Descriptor {
45 public:
46 DescriptorScope() {}
mtklein88fd0fb2014-12-01 06:56:38 -080047
reed9fa60da2014-08-21 07:59:51 -070048 bool unflatten(SkReadBuffer&);
49
50 // fColors and fPos always point into local memory, so they can be safely mutated
51 //
brianosmane25d71c2016-09-28 11:27:28 -070052 SkColor4f* mutableColors() { return const_cast<SkColor4f*>(fColors); }
reed9fa60da2014-08-21 07:59:51 -070053 SkScalar* mutablePos() { return const_cast<SkScalar*>(fPos); }
54
55 private:
56 enum {
57 kStorageCount = 16
58 };
brianosmane25d71c2016-09-28 11:27:28 -070059 SkColor4f fColorStorage[kStorageCount];
reed9fa60da2014-08-21 07:59:51 -070060 SkScalar fPosStorage[kStorageCount];
61 SkMatrix fLocalMatrixStorage;
62 SkAutoMalloc fDynamicStorage;
reed@google.com437d6eb2013-05-23 19:03:05 +000063 };
64
mtkleincc695fe2014-12-10 10:29:19 -080065 SkGradientShaderBase(const Descriptor& desc, const SkMatrix& ptsToUnit);
Brian Salomond3b65972017-03-22 12:05:03 -040066 ~SkGradientShaderBase() override;
rileya@google.com1c6d64b2012-07-27 15:49:05 +000067
mtklein36352bf2015-03-25 18:17:31 -070068 bool isOpaque() const override;
rileya@google.com1c6d64b2012-07-27 15:49:05 +000069
brianosmand4546092016-09-22 12:31:58 -070070 enum class GradientBitmapType : uint8_t {
71 kLegacy,
72 kSRGB,
73 kHalfFloat,
74 };
75
76 void getGradientTableBitmap(SkBitmap*, GradientBitmapType bitmapType) const;
rileya@google.com1c6d64b2012-07-27 15:49:05 +000077
commit-bot@chromium.org6c5aea22014-04-22 16:25:15 +000078 uint32_t getGradFlags() const { return fGradFlags; }
commit-bot@chromium.org53783b02014-04-17 21:09:49 +000079
Florin Malita0e36b3f2017-06-05 23:33:45 -040080 SkColor4f getXformedColor(size_t index, SkColorSpace*) const;
81
rileya@google.com1c6d64b2012-07-27 15:49:05 +000082protected:
Mike Kleina3771842017-05-04 19:38:48 -040083 struct Rec {
84 SkFixed fPos; // 0...1
85 uint32_t fScale; // (1 << 24) / range
86 };
87
fmalitabc590c02016-02-22 09:12:33 -080088 class GradientShaderBase4fContext;
89
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000090 SkGradientShaderBase(SkReadBuffer& );
mtklein36352bf2015-03-25 18:17:31 -070091 void flatten(SkWriteBuffer&) const override;
commit-bot@chromium.org0f10f7b2014-03-13 18:02:17 +000092 SK_TO_STRING_OVERRIDE()
rileya@google.com1c6d64b2012-07-27 15:49:05 +000093
Florin Malita5f379a82017-10-18 16:22:35 -040094 void commonAsAGradient(GradientInfo*) const;
skia.committer@gmail.comd3b28e82014-04-22 03:05:17 +000095
mtklein36352bf2015-03-25 18:17:31 -070096 bool onAsLuminanceColor(SkColor*) const override;
reed8367b8c2014-08-22 08:30:20 -070097
Florin Malita84d7cf92017-10-25 15:31:54 -040098 void initLinearBitmap(SkBitmap* bitmap, GradientBitmapType) const;
brianosmand4546092016-09-22 12:31:58 -070099
Mike Reed1d8c42e2017-08-29 14:58:19 -0400100 bool onAppendStages(const StageRec&) const override;
Mike Kleina3771842017-05-04 19:38:48 -0400101
Florin Malita50b20842017-07-29 19:08:28 -0400102 virtual void appendGradientStages(SkArenaAlloc* alloc, SkRasterPipeline* tPipeline,
103 SkRasterPipeline* postPipeline) const = 0;
Mike Kleina3771842017-05-04 19:38:48 -0400104
fmalita088e21b2016-10-05 09:28:42 -0700105 template <typename T, typename... Args>
Herb Derby83e939b2017-02-07 14:25:11 -0500106 static Context* CheckedMakeContext(SkArenaAlloc* alloc, Args&&... args) {
107 auto* ctx = alloc->make<T>(std::forward<Args>(args)...);
fmalita088e21b2016-10-05 09:28:42 -0700108 if (!ctx->isValid()) {
fmalita088e21b2016-10-05 09:28:42 -0700109 return nullptr;
110 }
111 return ctx;
112 }
113
Mike Kleina3771842017-05-04 19:38:48 -0400114 const SkMatrix fPtsToUnit;
115 TileMode fTileMode;
Mike Kleina3771842017-05-04 19:38:48 -0400116 uint8_t fGradFlags;
117 Rec* fRecs;
118
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000119private:
120 enum {
121 kColorStorageCount = 4, // more than this many colors, and we'll use sk_malloc for the space
122
brianosmanb9c51372016-09-15 11:09:45 -0700123 kStorageSize = kColorStorageCount *
124 (sizeof(SkColor) + sizeof(SkScalar) + sizeof(Rec) + sizeof(SkColor4f))
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000125 };
brianosmanb9c51372016-09-15 11:09:45 -0700126 SkColor fStorage[(kStorageSize + 3) >> 2];
reedf3182eb2015-11-17 08:12:19 -0800127public:
Florin Malitaed6ae562017-10-28 11:06:48 -0400128 SkScalar getPos(int i) const {
129 SkASSERT(i < fColorCount);
130 return fOrigPos ? fOrigPos[i] : SkIntToScalar(i) / (fColorCount - 1);
131 }
132
brianosmanb9c51372016-09-15 11:09:45 -0700133 SkColor* fOrigColors; // original colors, before modulation by paint in context.
134 SkColor4f* fOrigColors4f; // original colors, as linear floats
135 SkScalar* fOrigPos; // original positions
136 int fColorCount;
137 sk_sp<SkColorSpace> fColorSpace; // color space of gradient stops
reedf3182eb2015-11-17 08:12:19 -0800138
139 bool colorsAreOpaque() const { return fColorsAreOpaque; }
140
fmenozzicd9a1d02016-08-15 07:03:47 -0700141 TileMode getTileMode() const { return fTileMode; }
142 Rec* getRecs() const { return fRecs; }
143
reedf3182eb2015-11-17 08:12:19 -0800144private:
brianosmanb9c51372016-09-15 11:09:45 -0700145 bool fColorsAreOpaque;
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000146
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000147 void initCommon();
148
Florin Malita4aed1382017-05-25 10:38:07 -0400149 typedef SkShaderBase INHERITED;
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000150};
151
152///////////////////////////////////////////////////////////////////////////////
153
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +0000154#if SK_SUPPORT_GPU
155
Brian Salomon4cbb6e62017-10-25 15:12:19 -0400156#include "GrColorSpaceInfo.h"
bsalomon@google.com77af6802013-10-02 13:04:56 +0000157#include "GrCoordTransform.h"
bsalomon6251d172014-10-15 10:50:36 -0700158#include "GrFragmentProcessor.h"
egdaniel64c47282015-11-13 06:54:19 -0800159#include "glsl/GrGLSLFragmentProcessor.h"
egdaniel018fb622015-10-28 07:26:40 -0700160#include "glsl/GrGLSLProgramDataManager.h"
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +0000161
egdaniel605dd0f2014-11-12 08:35:25 -0800162class GrInvariantOutput;
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000163
164/*
bsalomon@google.comd8b5fac2012-11-01 17:02:46 +0000165 * The interpretation of the texture matrix depends on the sample mode. The
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000166 * texture matrix is applied both when the texture coordinates are explicit
167 * and when vertex positions are used as texture coordinates. In the latter
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000168 * case the texture matrix is applied to the pre-view-matrix position
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000169 * values.
170 *
171 * Normal SampleMode
172 * The post-matrix texture coordinates are in normalize space with (0,0) at
173 * the top-left and (1,1) at the bottom right.
174 * RadialGradient
175 * The matrix specifies the radial gradient parameters.
176 * (0,0) in the post-matrix space is center of the radial gradient.
177 * Radial2Gradient
178 * Matrix transforms to space where first circle is centered at the
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000179 * origin. The second circle will be centered (x, 0) where x may be
180 * 0 and is provided by setRadial2Params. The post-matrix space is
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000181 * normalized such that 1 is the second radius - first radius.
182 * SweepGradient
183 * The angle from the origin of texture coordinates in post-matrix space
184 * determines the gradient value.
185 */
186
rileya@google.comb3e50f22012-08-20 17:43:08 +0000187 class GrTextureStripAtlas;
188
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000189// Base class for Gr gradient effects
joshualittb0a8a372014-09-23 09:50:21 -0700190class GrGradientEffect : public GrFragmentProcessor {
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000191public:
brianosman9557c272016-09-15 06:59:15 -0700192 struct CreateArgs {
193 CreateArgs(GrContext* context,
194 const SkGradientShaderBase* shader,
195 const SkMatrix* matrix,
brianosmanb9c51372016-09-15 11:09:45 -0700196 SkShader::TileMode tileMode,
Brian Osman5911a7c2017-10-25 12:52:31 -0400197 const SkColorSpace* dstColorSpace)
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400198 : fContext(context)
199 , fShader(shader)
200 , fMatrix(matrix)
Brian Osman5911a7c2017-10-25 12:52:31 -0400201 , fDstColorSpace(dstColorSpace) {
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400202 switch (tileMode) {
203 case SkShader::kClamp_TileMode:
204 fWrapMode = GrSamplerState::WrapMode::kClamp;
205 break;
206 case SkShader::kRepeat_TileMode:
207 fWrapMode = GrSamplerState::WrapMode::kRepeat;
208 break;
209 case SkShader::kMirror_TileMode:
210 fWrapMode = GrSamplerState::WrapMode::kMirrorRepeat;
211 break;
212 }
213 }
214
215 CreateArgs(GrContext* context,
216 const SkGradientShaderBase* shader,
217 const SkMatrix* matrix,
218 GrSamplerState::WrapMode wrapMode,
Brian Osman5911a7c2017-10-25 12:52:31 -0400219 const SkColorSpace* dstColorSpace)
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400220 : fContext(context)
221 , fShader(shader)
222 , fMatrix(matrix)
223 , fWrapMode(wrapMode)
Brian Osman5911a7c2017-10-25 12:52:31 -0400224 , fDstColorSpace(dstColorSpace) {}
brianosman9557c272016-09-15 06:59:15 -0700225
226 GrContext* fContext;
227 const SkGradientShaderBase* fShader;
228 const SkMatrix* fMatrix;
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400229 GrSamplerState::WrapMode fWrapMode;
Brian Osman5911a7c2017-10-25 12:52:31 -0400230 const SkColorSpace* fDstColorSpace;
brianosman9557c272016-09-15 06:59:15 -0700231 };
232
fmenozzi55d318d2016-08-09 08:05:57 -0700233 class GLSLProcessor;
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000234
Brian Salomond3b65972017-03-22 12:05:03 -0400235 ~GrGradientEffect() override;
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000236
rileya@google.comb3e50f22012-08-20 17:43:08 +0000237 bool useAtlas() const { return SkToBool(-1 != fRow); }
fmenozzicd9a1d02016-08-15 07:03:47 -0700238 SkScalar getYCoord() const { return fYCoord; }
rileya@google.comb3e50f22012-08-20 17:43:08 +0000239
fmenozzicd9a1d02016-08-15 07:03:47 -0700240 enum ColorType {
241 kTwo_ColorType,
Brian Osmana8e57442017-09-11 17:21:35 -0400242 kThree_ColorType, // 0, t, 1
fmenozzicd9a1d02016-08-15 07:03:47 -0700243 kTexture_ColorType,
Brian Salomon466ad992016-10-13 16:08:36 -0400244 kSingleHardStop_ColorType, // 0, t, t, 1
fmenozzicd9a1d02016-08-15 07:03:47 -0700245 kHardStopLeftEdged_ColorType, // 0, 0, 1
246 kHardStopRightEdged_ColorType, // 0, 1, 1
fmenozzicd9a1d02016-08-15 07:03:47 -0700247 };
248
249 ColorType getColorType() const { return fColorType; }
250
251 // Determines the type of gradient, one of:
252 // - Two-color
253 // - Symmetric three-color
254 // - Texture
255 // - Centered hard stop
256 // - Left-edged hard stop
257 // - Right-edged hard stop
258 ColorType determineColorType(const SkGradientShaderBase& shader);
bsalomon@google.com82d12232013-09-09 15:36:26 +0000259
260 enum PremulType {
261 kBeforeInterp_PremulType,
262 kAfterInterp_PremulType,
263 };
264
265 PremulType getPremulType() const { return fPremulType; }
266
Brian Osmand43f7b62017-10-19 15:42:01 -0400267 const GrColor4f* getColors4f(int pos) const {
brianosmanb9c51372016-09-15 11:09:45 -0700268 SkASSERT(fColorType != kTexture_ColorType);
269 SkASSERT(pos < fColors4f.count());
270 return &fColors4f[pos];
271 }
272
bsalomon@google.comd4726202012-08-03 14:34:46 +0000273protected:
Ethan Nicholasabff9562017-10-09 10:54:08 -0400274 GrGradientEffect(ClassID classID, const CreateArgs&, bool isOpaque);
Brian Salomonf8480b92017-07-27 15:45:59 -0400275 explicit GrGradientEffect(const GrGradientEffect&); // facilitates clone() implementations
Brian Salomon587e08f2017-01-27 10:59:27 -0500276
Brian Osman5911a7c2017-10-25 12:52:31 -0400277 // Helper function used by derived class factories to handle color space transformation and
278 // modulation by input alpha.
279 static std::unique_ptr<GrFragmentProcessor> AdjustFP(
280 std::unique_ptr<GrGradientEffect> gradientFP, const CreateArgs& args) {
281 if (!gradientFP->isValid()) {
282 return nullptr;
283 }
284 std::unique_ptr<GrFragmentProcessor> fp;
285 // With analytic gradients, we pre-convert the stops to the destination color space, so no
286 // xform is needed. With texture-based gradients, we leave the data in the source color
287 // space (to avoid clamping if we can't use F16)... Add an extra FP to do the xform.
288 if (kTexture_ColorType == gradientFP->getColorType()) {
289 fp = GrColorSpaceXformEffect::Make(std::move(gradientFP),
290 args.fShader->fColorSpace.get(),
291 args.fDstColorSpace);
292 } else {
293 fp = std::move(gradientFP);
294 }
295 return GrFragmentProcessor::MulOutputByInputAlpha(std::move(fp));
296 }
297
298#if GR_TEST_UTILS
Brian Osmane75c19f2016-10-10 11:26:43 -0400299 /** Helper struct that stores (and populates) parameters to construct a random gradient.
Brian Osmana2196532016-10-17 12:48:13 -0400300 If fUseColors4f is true, then the SkColor4f factory should be called, with fColors4f and
301 fColorSpace. Otherwise, the SkColor factory should be called, with fColors. fColorCount
302 will be the number of color stops in either case, and fColors and fStops can be passed to
303 the gradient factory. (The constructor may decide not to use stops, in which case fStops
304 will be nullptr). */
Brian Osman3f748602016-10-03 18:29:03 -0400305 struct RandomGradientParams {
Brian Salomon5d4cd9e2017-02-09 11:16:46 -0500306 static const int kMaxRandomGradientColors = 5;
Brian Osmane75c19f2016-10-10 11:26:43 -0400307
Brian Osman3f748602016-10-03 18:29:03 -0400308 RandomGradientParams(SkRandom* r);
309
Brian Osmana2196532016-10-17 12:48:13 -0400310 bool fUseColors4f;
Brian Osman3f748602016-10-03 18:29:03 -0400311 SkColor fColors[kMaxRandomGradientColors];
Brian Osmana2196532016-10-17 12:48:13 -0400312 SkColor4f fColors4f[kMaxRandomGradientColors];
313 sk_sp<SkColorSpace> fColorSpace;
Brian Osman3f748602016-10-03 18:29:03 -0400314 SkScalar fStopStorage[kMaxRandomGradientColors];
315 SkShader::TileMode fTileMode;
316 int fColorCount;
317 SkScalar* fStops;
318 };
Hal Canary6f6961e2017-01-31 13:50:44 -0500319 #endif
bsalomon@google.comd4726202012-08-03 14:34:46 +0000320
mtklein36352bf2015-03-25 18:17:31 -0700321 bool onIsEqual(const GrFragmentProcessor&) const override;
bsalomon@google.com68b58c92013-01-17 16:50:08 +0000322
commit-bot@chromium.org5fd7d5c2013-10-04 01:20:09 +0000323 const GrCoordTransform& getCoordTransform() const { return fCoordTransform; }
324
Brian Salomon6af27012017-06-09 08:21:42 -0400325 /** Checks whether the constructor failed to fully initialize the processor. */
Brian Salomon06e547c2017-06-09 16:11:32 -0400326 bool isValid() const {
327 return fColorType != kTexture_ColorType || fTextureSampler.isInitialized();
328 }
Brian Salomon6af27012017-06-09 08:21:42 -0400329
bsalomon@google.comd4726202012-08-03 14:34:46 +0000330private:
Brian Salomon587e08f2017-01-27 10:59:27 -0500331 static OptimizationFlags OptFlags(bool isOpaque);
332
Brian Osmand43f7b62017-10-19 15:42:01 -0400333 SkTDArray<GrColor4f> fColors4f;
brianosmanb9c51372016-09-15 11:09:45 -0700334
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400335 SkTDArray<SkScalar> fPositions;
336 GrSamplerState::WrapMode fWrapMode;
fmenozzicd9a1d02016-08-15 07:03:47 -0700337
bsalomon@google.com77af6802013-10-02 13:04:56 +0000338 GrCoordTransform fCoordTransform;
Brian Salomon0bbecb22016-11-17 11:38:22 -0500339 TextureSampler fTextureSampler;
bsalomon@google.com81712882012-11-01 17:12:34 +0000340 SkScalar fYCoord;
rileya@google.comb3e50f22012-08-20 17:43:08 +0000341 GrTextureStripAtlas* fAtlas;
342 int fRow;
bsalomon@google.com371e1052013-01-11 21:08:55 +0000343 bool fIsOpaque;
fmenozzicd9a1d02016-08-15 07:03:47 -0700344 ColorType fColorType;
345 PremulType fPremulType; // This is already baked into the table for texture gradients, and
346 // only changes behavior for gradients that don't use a texture.
joshualittb0a8a372014-09-23 09:50:21 -0700347 typedef GrFragmentProcessor INHERITED;
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000348
349};
350
351///////////////////////////////////////////////////////////////////////////////
352
fmenozzicd9a1d02016-08-15 07:03:47 -0700353// Base class for GL gradient effects
fmenozzi55d318d2016-08-09 08:05:57 -0700354class GrGradientEffect::GLSLProcessor : public GrGLSLFragmentProcessor {
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000355public:
fmenozzicd9a1d02016-08-15 07:03:47 -0700356 GLSLProcessor() {
357 fCachedYCoord = SK_ScalarMax;
358 }
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000359
wangyixb1daa862015-08-18 11:29:31 -0700360protected:
Brian Salomonab015ef2017-04-04 10:15:51 -0400361 void onSetData(const GrGLSLProgramDataManager&, const GrFragmentProcessor&) override;
rileya@google.comb3e50f22012-08-20 17:43:08 +0000362
bsalomon@google.comf78df332012-10-29 12:43:38 +0000363protected:
bsalomon63e99f72014-07-21 08:03:14 -0700364 /**
365 * Subclasses must call this. It will return a key for the part of the shader code controlled
366 * by the base class. The subclasses must stick it in their key and then pass it to the below
367 * emit* functions from their emitCode function.
368 */
joshualittb0a8a372014-09-23 09:50:21 -0700369 static uint32_t GenBaseGradientKey(const GrProcessor&);
bsalomon63e99f72014-07-21 08:03:14 -0700370
371 // Emits the uniform used as the y-coord to texture samples in derived classes. Subclasses
372 // should call this method from their emitCode().
egdaniel7ea439b2015-12-03 09:20:44 -0800373 void emitUniforms(GrGLSLUniformHandler*, const GrGradientEffect&);
bsalomon63e99f72014-07-21 08:03:14 -0700374
fmenozzicd9a1d02016-08-15 07:03:47 -0700375 // Emit code that gets a fragment's color from an expression for t; has branches for
376 // several control flows inside -- 2-color gradients, 3-color symmetric gradients, 4+
377 // color gradients that use the traditional texture lookup, as well as several varieties
378 // of hard stop gradients
cdalton85285412016-02-18 12:37:07 -0800379 void emitColor(GrGLSLFPFragmentBuilder* fragBuilder,
egdaniel7ea439b2015-12-03 09:20:44 -0800380 GrGLSLUniformHandler* uniformHandler,
Brian Salomon1edc5b92016-11-29 13:43:46 -0500381 const GrShaderCaps* shaderCaps,
joshualitt60030bc2014-11-25 14:21:55 -0800382 const GrGradientEffect&,
bsalomon63e99f72014-07-21 08:03:14 -0700383 const char* gradientTValue,
bsalomon63e99f72014-07-21 08:03:14 -0700384 const char* outputColor,
385 const char* inputColor,
bsalomonb58a2b42016-09-26 06:55:02 -0700386 const TextureSamplers&);
bsalomon63e99f72014-07-21 08:03:14 -0700387
388private:
Florin Malitab81a8b92017-08-08 12:14:17 -0400389 void emitAnalyticalColor(GrGLSLFPFragmentBuilder* fragBuilder,
390 GrGLSLUniformHandler* uniformHandler,
391 const GrShaderCaps* shaderCaps,
392 const GrGradientEffect&,
393 const char* gradientTValue,
394 const char* outputColor,
395 const char* inputColor);
396
bsalomon@google.comd8b5fac2012-11-01 17:02:46 +0000397 enum {
Brian Osmanfe3e8582017-10-20 11:27:49 -0400398 // First bit for premul before/after interpolation
fmenozzicd9a1d02016-08-15 07:03:47 -0700399 kPremulBeforeInterpKey = 1,
bsalomon@google.com82d12232013-09-09 15:36:26 +0000400
fmenozzicd9a1d02016-08-15 07:03:47 -0700401 // Next three bits for 2/3 color type or different special
Brian Osmanfe3e8582017-10-20 11:27:49 -0400402 // hard stop cases ('none' means using texture atlas)
fmenozzicd9a1d02016-08-15 07:03:47 -0700403 kTwoColorKey = 2,
404 kThreeColorKey = 4,
Brian Salomonf8480b92017-07-27 15:45:59 -0400405
Brian Osman2ab4b2b2017-09-12 11:20:56 -0400406 kHardStopCenteredKey = 6,
407 kHardStopZeroZeroOneKey = 8,
408 kHardStopZeroOneOneKey = 10,
fmenozzicd9a1d02016-08-15 07:03:47 -0700409
410 // Next two bits for tile mode
411 kClampTileMode = 16,
412 kRepeatTileMode = 32,
413 kMirrorTileMode = 48,
414
415 // Lower six bits for premul, 2/3 color type, and tile mode
416 kReservedBits = 6,
bsalomon@google.comd8b5fac2012-11-01 17:02:46 +0000417 };
418
bsalomon@google.com81712882012-11-01 17:12:34 +0000419 SkScalar fCachedYCoord;
fmenozzicd9a1d02016-08-15 07:03:47 -0700420 GrGLSLProgramDataManager::UniformHandle fColorsUni;
Brian Osmana8e57442017-09-11 17:21:35 -0400421 GrGLSLProgramDataManager::UniformHandle fExtraStopT;
egdaniel018fb622015-10-28 07:26:40 -0700422 GrGLSLProgramDataManager::UniformHandle fFSYUni;
rileya@google.comb3e50f22012-08-20 17:43:08 +0000423
egdaniel64c47282015-11-13 06:54:19 -0800424 typedef GrGLSLFragmentProcessor INHERITED;
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000425};
426
427#endif
428
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +0000429#endif