blob: d1ac77bc920c5299e533cdbadc33b6e679a724f6 [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
reeda6cac4c2014-08-21 10:50:25 -070011#include "SkGradientBitmapCache.h"
rileya@google.com1c6d64b2012-07-27 15:49:05 +000012#include "SkGradientShader.h"
13#include "SkClampRange.h"
14#include "SkColorPriv.h"
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000015#include "SkReadBuffer.h"
16#include "SkWriteBuffer.h"
rileya@google.com1c6d64b2012-07-27 15:49:05 +000017#include "SkMallocPixelRef.h"
rileya@google.com1c6d64b2012-07-27 15:49:05 +000018#include "SkUtils.h"
19#include "SkTemplates.h"
rileya@google.com1c6d64b2012-07-27 15:49:05 +000020#include "SkShader.h"
commit-bot@chromium.org87fcd952014-04-23 19:10:51 +000021#include "SkOnce.h"
rileya@google.com1c6d64b2012-07-27 15:49:05 +000022
humper@google.com05af1af2013-01-07 16:47:43 +000023static inline void sk_memset32_dither(uint32_t dst[], uint32_t v0, uint32_t v1,
rileya@google.com1c6d64b2012-07-27 15:49:05 +000024 int count) {
25 if (count > 0) {
26 if (v0 == v1) {
27 sk_memset32(dst, v0, count);
28 } else {
29 int pairs = count >> 1;
30 for (int i = 0; i < pairs; i++) {
31 *dst++ = v0;
32 *dst++ = v1;
33 }
34 if (count & 1) {
35 *dst = v0;
36 }
37 }
38 }
39}
40
41// Clamp
42
humper@google.com05af1af2013-01-07 16:47:43 +000043static inline SkFixed clamp_tileproc(SkFixed x) {
rileya@google.com1c6d64b2012-07-27 15:49:05 +000044 return SkClampMax(x, 0xFFFF);
45}
46
47// Repeat
48
humper@google.com05af1af2013-01-07 16:47:43 +000049static inline SkFixed repeat_tileproc(SkFixed x) {
rileya@google.com1c6d64b2012-07-27 15:49:05 +000050 return x & 0xFFFF;
51}
52
53// Mirror
54
55// Visual Studio 2010 (MSC_VER=1600) optimizes bit-shift code incorrectly.
56// See http://code.google.com/p/skia/issues/detail?id=472
57#if defined(_MSC_VER) && (_MSC_VER >= 1600)
58#pragma optimize("", off)
59#endif
60
61static inline SkFixed mirror_tileproc(SkFixed x) {
62 int s = x << 15 >> 31;
63 return (x ^ s) & 0xFFFF;
64}
65
66#if defined(_MSC_VER) && (_MSC_VER >= 1600)
67#pragma optimize("", on)
68#endif
69
70///////////////////////////////////////////////////////////////////////////////
71
72typedef SkFixed (*TileProc)(SkFixed);
73
74///////////////////////////////////////////////////////////////////////////////
75
76static const TileProc gTileProcs[] = {
77 clamp_tileproc,
78 repeat_tileproc,
79 mirror_tileproc
80};
81
82///////////////////////////////////////////////////////////////////////////////
83
84class SkGradientShaderBase : public SkShader {
85public:
reed@google.com437d6eb2013-05-23 19:03:05 +000086 struct Descriptor {
87 Descriptor() {
88 sk_bzero(this, sizeof(*this));
89 fTileMode = SkShader::kClamp_TileMode;
90 }
skia.committer@gmail.com3e2345a2013-05-24 07:01:26 +000091
reedaddf2ed2014-08-11 08:28:24 -070092 const SkMatrix* fLocalMatrix;
reed@google.com437d6eb2013-05-23 19:03:05 +000093 const SkColor* fColors;
94 const SkScalar* fPos;
95 int fCount;
96 SkShader::TileMode fTileMode;
commit-bot@chromium.org6c5aea22014-04-22 16:25:15 +000097 uint32_t fGradFlags;
reed9fa60da2014-08-21 07:59:51 -070098
99 void flatten(SkWriteBuffer&) const;
100 };
101
102 class DescriptorScope : public Descriptor {
103 public:
104 DescriptorScope() {}
105
106 bool unflatten(SkReadBuffer&);
107
108 // fColors and fPos always point into local memory, so they can be safely mutated
109 //
110 SkColor* mutableColors() { return const_cast<SkColor*>(fColors); }
111 SkScalar* mutablePos() { return const_cast<SkScalar*>(fPos); }
112
113 private:
114 enum {
115 kStorageCount = 16
116 };
117 SkColor fColorStorage[kStorageCount];
118 SkScalar fPosStorage[kStorageCount];
119 SkMatrix fLocalMatrixStorage;
120 SkAutoMalloc fDynamicStorage;
reed@google.com437d6eb2013-05-23 19:03:05 +0000121 };
122
123public:
reedaddf2ed2014-08-11 08:28:24 -0700124 SkGradientShaderBase(const Descriptor& desc);
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000125 virtual ~SkGradientShaderBase();
126
commit-bot@chromium.org87fcd952014-04-23 19:10:51 +0000127 // The cache is initialized on-demand when getCache16/32 is called.
128 class GradientShaderCache : public SkRefCnt {
129 public:
130 GradientShaderCache(U8CPU alpha, const SkGradientShaderBase& shader);
131 ~GradientShaderCache();
132
133 const uint16_t* getCache16();
134 const SkPMColor* getCache32();
135
136 SkMallocPixelRef* getCache32PixelRef() const { return fCache32PixelRef; }
137
138 unsigned getAlpha() const { return fCacheAlpha; }
139
140 private:
141 // Working pointers. If either is NULL, we need to recompute the corresponding cache values.
142 uint16_t* fCache16;
143 SkPMColor* fCache32;
144
145 uint16_t* fCache16Storage; // Storage for fCache16, allocated on demand.
146 SkMallocPixelRef* fCache32PixelRef;
147 const unsigned fCacheAlpha; // The alpha value we used when we computed the cache.
148 // Larger than 8bits so we can store uninitialized
149 // value.
150
151 const SkGradientShaderBase& fShader;
152
153 // Make sure we only initialize the caches once.
154 bool fCache16Inited, fCache32Inited;
155 SkMutex fCache16Mutex, fCache32Mutex;
156
157 static void initCache16(GradientShaderCache* cache);
158 static void initCache32(GradientShaderCache* cache);
159
160 static void Build16bitCache(uint16_t[], SkColor c0, SkColor c1, int count);
161 static void Build32bitCache(SkPMColor[], SkColor c0, SkColor c1, int count,
162 U8CPU alpha, uint32_t gradFlags);
163 };
164
165 class GradientShaderBaseContext : public SkShader::Context {
166 public:
commit-bot@chromium.orge901b6d2014-05-01 19:31:31 +0000167 GradientShaderBaseContext(const SkGradientShaderBase& shader, const ContextRec&);
commit-bot@chromium.org87fcd952014-04-23 19:10:51 +0000168
169 virtual uint32_t getFlags() const SK_OVERRIDE { return fFlags; }
170
171 protected:
172 SkMatrix fDstToIndex;
173 SkMatrix::MapXYProc fDstToIndexProc;
174 uint8_t fDstToIndexClass;
175 uint8_t fFlags;
176
177 SkAutoTUnref<GradientShaderCache> fCache;
178
179 private:
180 typedef SkShader::Context INHERITED;
181 };
182
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000183 virtual bool isOpaque() const SK_OVERRIDE;
184
185 void getGradientTableBitmap(SkBitmap*) const;
186
187 enum {
188 /// Seems like enough for visual accuracy. TODO: if pos[] deserves
189 /// it, use a larger cache.
190 kCache16Bits = 8,
reed@google.com3c2102c2013-02-01 12:59:40 +0000191 kCache16Count = (1 << kCache16Bits),
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000192 kCache16Shift = 16 - kCache16Bits,
193 kSqrt16Shift = 8 - kCache16Bits,
194
195 /// Seems like enough for visual accuracy. TODO: if pos[] deserves
196 /// it, use a larger cache.
197 kCache32Bits = 8,
reed@google.com60040292013-02-04 18:21:23 +0000198 kCache32Count = (1 << kCache32Bits),
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000199 kCache32Shift = 16 - kCache32Bits,
200 kSqrt32Shift = 8 - kCache32Bits,
201
202 /// This value is used to *read* the dither cache; it may be 0
203 /// if dithering is disabled.
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000204 kDitherStride32 = kCache32Count,
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000205 kDitherStride16 = kCache16Count,
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000206 };
207
commit-bot@chromium.org996402b2014-04-18 14:42:11 +0000208 enum GpuColorType {
209 kTwo_GpuColorType,
210 kThree_GpuColorType, // Symmetric three color
211 kTexture_GpuColorType
212 };
213
214 // Determines and returns the gradient is a two color gradient, symmetric three color gradient
215 // or other (texture gradient). If it is two or symmetric three color, the colors array will
216 // also be filled with the gradient colors
217 GpuColorType getGpuColorType(SkColor colors[3]) const;
218
commit-bot@chromium.org6c5aea22014-04-22 16:25:15 +0000219 uint32_t getGradFlags() const { return fGradFlags; }
commit-bot@chromium.org53783b02014-04-17 21:09:49 +0000220
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000221protected:
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +0000222 SkGradientShaderBase(SkReadBuffer& );
223 virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
commit-bot@chromium.org0f10f7b2014-03-13 18:02:17 +0000224 SK_TO_STRING_OVERRIDE()
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000225
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000226 SkMatrix fPtsToUnit; // set by subclass
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000227 TileMode fTileMode;
228 TileProc fTileProc;
229 int fColorCount;
reed@google.com3d3a8602013-05-24 14:58:44 +0000230 uint8_t fGradFlags;
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000231
232 struct Rec {
233 SkFixed fPos; // 0...1
234 uint32_t fScale; // (1 << 24) / range
235 };
236 Rec* fRecs;
237
commit-bot@chromium.org44d83c12014-04-21 13:10:25 +0000238 void commonAsAGradient(GradientInfo*, bool flipGrad = false) const;
skia.committer@gmail.comd3b28e82014-04-22 03:05:17 +0000239
reed8367b8c2014-08-22 08:30:20 -0700240 virtual bool onAsLuminanceColor(SkColor*) const SK_OVERRIDE;
241
commit-bot@chromium.org44d83c12014-04-21 13:10:25 +0000242 /*
243 * Takes in pointers to gradient color and Rec info as colorSrc and recSrc respectively.
244 * Count is the number of colors in the gradient
245 * It will then flip all the color and rec information and return in their respective Dst
246 * pointers. It is assumed that space has already been allocated for the Dst pointers.
247 * The rec src and dst are only assumed to be valid if count > 2
248 */
249 static void FlipGradientColors(SkColor* colorDst, Rec* recDst,
250 SkColor* colorSrc, Rec* recSrc,
251 int count);
252
253 // V23_COMPATIBILITY_CODE
254 // Used for 2-pt conical gradients since we sort start/end cirlces by radius
255 // Assumes space has already been allocated for fOrigColors
256 void flipGradientColors();
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000257
258private:
259 enum {
260 kColorStorageCount = 4, // more than this many colors, and we'll use sk_malloc for the space
261
reed9fa60da2014-08-21 07:59:51 -0700262 kStorageSize = kColorStorageCount * (sizeof(SkColor) + sizeof(SkScalar) + sizeof(Rec))
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000263 };
264 SkColor fStorage[(kStorageSize + 3) >> 2];
commit-bot@chromium.org87fcd952014-04-23 19:10:51 +0000265 SkColor* fOrigColors; // original colors, before modulation by paint in context.
reed9fa60da2014-08-21 07:59:51 -0700266 SkScalar* fOrigPos; // original positions
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000267 bool fColorsAreOpaque;
268
commit-bot@chromium.org87fcd952014-04-23 19:10:51 +0000269 GradientShaderCache* refCache(U8CPU alpha) const;
270 mutable SkMutex fCacheMutex;
271 mutable SkAutoTUnref<GradientShaderCache> fCache;
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000272
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000273 void initCommon();
274
275 typedef SkShader INHERITED;
276};
277
reed@google.com55853db2013-02-01 19:34:59 +0000278static inline int init_dither_toggle(int x, int y) {
reed@google.com60040292013-02-04 18:21:23 +0000279 x &= 1;
280 y = (y & 1) << 1;
281 return (x | y) * SkGradientShaderBase::kDitherStride32;
reed@google.com55853db2013-02-01 19:34:59 +0000282}
283
284static inline int next_dither_toggle(int toggle) {
285 return toggle ^ SkGradientShaderBase::kDitherStride32;
286}
287
288static inline int init_dither_toggle16(int x, int y) {
289 return ((x ^ y) & 1) * SkGradientShaderBase::kDitherStride16;
290}
291
292static inline int next_dither_toggle16(int toggle) {
293 return toggle ^ SkGradientShaderBase::kDitherStride16;
294}
295
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000296///////////////////////////////////////////////////////////////////////////////
297
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +0000298#if SK_SUPPORT_GPU
299
bsalomon@google.com77af6802013-10-02 13:04:56 +0000300#include "GrCoordTransform.h"
joshualittb0a8a372014-09-23 09:50:21 -0700301#include "gl/GrGLProcessor.h"
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +0000302
joshualittb0a8a372014-09-23 09:50:21 -0700303class GrProcessorStage;
304class GrBackendProcessorFactory;
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000305
306/*
bsalomon@google.comd8b5fac2012-11-01 17:02:46 +0000307 * The interpretation of the texture matrix depends on the sample mode. The
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000308 * texture matrix is applied both when the texture coordinates are explicit
309 * and when vertex positions are used as texture coordinates. In the latter
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000310 * case the texture matrix is applied to the pre-view-matrix position
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000311 * values.
312 *
313 * Normal SampleMode
314 * The post-matrix texture coordinates are in normalize space with (0,0) at
315 * the top-left and (1,1) at the bottom right.
316 * RadialGradient
317 * The matrix specifies the radial gradient parameters.
318 * (0,0) in the post-matrix space is center of the radial gradient.
319 * Radial2Gradient
320 * Matrix transforms to space where first circle is centered at the
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000321 * origin. The second circle will be centered (x, 0) where x may be
322 * 0 and is provided by setRadial2Params. The post-matrix space is
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000323 * normalized such that 1 is the second radius - first radius.
324 * SweepGradient
325 * The angle from the origin of texture coordinates in post-matrix space
326 * determines the gradient value.
327 */
328
rileya@google.comb3e50f22012-08-20 17:43:08 +0000329 class GrTextureStripAtlas;
330
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000331// Base class for Gr gradient effects
joshualittb0a8a372014-09-23 09:50:21 -0700332class GrGradientEffect : public GrFragmentProcessor {
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000333public:
334
bsalomon@google.com1ce49fc2012-09-18 14:14:49 +0000335 GrGradientEffect(GrContext* ctx,
336 const SkGradientShaderBase& shader,
bsalomon@google.comd8b5fac2012-11-01 17:02:46 +0000337 const SkMatrix& matrix,
bsalomon@google.com1ce49fc2012-09-18 14:14:49 +0000338 SkShader::TileMode tileMode);
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000339
340 virtual ~GrGradientEffect();
341
rileya@google.comb3e50f22012-08-20 17:43:08 +0000342 bool useAtlas() const { return SkToBool(-1 != fRow); }
bsalomon@google.com81712882012-11-01 17:12:34 +0000343 SkScalar getYCoord() const { return fYCoord; };
rileya@google.comb3e50f22012-08-20 17:43:08 +0000344
commit-bot@chromium.org996402b2014-04-18 14:42:11 +0000345 SkGradientShaderBase::GpuColorType getColorType() const { return fColorType; }
bsalomon@google.com82d12232013-09-09 15:36:26 +0000346
347 enum PremulType {
348 kBeforeInterp_PremulType,
349 kAfterInterp_PremulType,
350 };
351
352 PremulType getPremulType() const { return fPremulType; }
353
354 const SkColor* getColors(int pos) const {
commit-bot@chromium.org996402b2014-04-18 14:42:11 +0000355 SkASSERT(fColorType != SkGradientShaderBase::kTexture_GpuColorType);
bsalomon@google.com82d12232013-09-09 15:36:26 +0000356 SkASSERT((pos-1) <= fColorType);
357 return &fColors[pos];
358 }
bsalomon@google.com371e1052013-01-11 21:08:55 +0000359
bsalomon@google.comd4726202012-08-03 14:34:46 +0000360protected:
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000361
bsalomon@google.comd4726202012-08-03 14:34:46 +0000362 /** Populates a pair of arrays with colors and stop info to construct a random gradient.
363 The function decides whether stop values should be used or not. The return value indicates
364 the number of colors, which will be capped by kMaxRandomGradientColors. colors should be
365 sized to be at least kMaxRandomGradientColors. stops is a pointer to an array of at least
366 size kMaxRandomGradientColors. It may be updated to NULL, indicating that NULL should be
367 passed to the gradient factory rather than the array.
368 */
369 static const int kMaxRandomGradientColors = 4;
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000370 static int RandomGradientParams(SkRandom* r,
bsalomon@google.comd4726202012-08-03 14:34:46 +0000371 SkColor colors[kMaxRandomGradientColors],
372 SkScalar** stops,
373 SkShader::TileMode* tm);
374
joshualittb0a8a372014-09-23 09:50:21 -0700375 virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
bsalomon@google.com68b58c92013-01-17 16:50:08 +0000376
egdaniel1a8ecdf2014-10-03 06:24:12 -0700377 virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE;
378
commit-bot@chromium.org5fd7d5c2013-10-04 01:20:09 +0000379 const GrCoordTransform& getCoordTransform() const { return fCoordTransform; }
380
bsalomon@google.comd4726202012-08-03 14:34:46 +0000381private:
bsalomon@google.com77af6802013-10-02 13:04:56 +0000382 static const GrCoordSet kCoordSet = kLocal_GrCoordSet;
bsalomon@google.com68b58c92013-01-17 16:50:08 +0000383
bsalomon@google.com77af6802013-10-02 13:04:56 +0000384 GrCoordTransform fCoordTransform;
bsalomon@google.com6d003d12012-09-11 15:45:20 +0000385 GrTextureAccess fTextureAccess;
bsalomon@google.com81712882012-11-01 17:12:34 +0000386 SkScalar fYCoord;
rileya@google.comb3e50f22012-08-20 17:43:08 +0000387 GrTextureStripAtlas* fAtlas;
388 int fRow;
bsalomon@google.com371e1052013-01-11 21:08:55 +0000389 bool fIsOpaque;
commit-bot@chromium.org996402b2014-04-18 14:42:11 +0000390 SkGradientShaderBase::GpuColorType fColorType;
391 SkColor fColors[3]; // More than 3 colors we use texture
bsalomon@google.com82d12232013-09-09 15:36:26 +0000392 PremulType fPremulType; // This only changes behavior for two and three color special cases.
393 // It is already baked into to the table for texture gradients.
joshualittb0a8a372014-09-23 09:50:21 -0700394 typedef GrFragmentProcessor INHERITED;
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000395
396};
397
398///////////////////////////////////////////////////////////////////////////////
399
bsalomon@google.com8ea78d82012-10-24 20:11:30 +0000400// Base class for GL gradient effects
joshualittb0a8a372014-09-23 09:50:21 -0700401class GrGLGradientEffect : public GrGLFragmentProcessor {
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000402public:
joshualittb0a8a372014-09-23 09:50:21 -0700403 GrGLGradientEffect(const GrBackendProcessorFactory& factory);
bsalomon@google.com0707c292012-10-25 21:45:42 +0000404 virtual ~GrGLGradientEffect();
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000405
joshualittb0a8a372014-09-23 09:50:21 -0700406 virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
rileya@google.comb3e50f22012-08-20 17:43:08 +0000407
bsalomon@google.comf78df332012-10-29 12:43:38 +0000408protected:
bsalomon63e99f72014-07-21 08:03:14 -0700409 /**
410 * Subclasses must call this. It will return a key for the part of the shader code controlled
411 * by the base class. The subclasses must stick it in their key and then pass it to the below
412 * emit* functions from their emitCode function.
413 */
joshualittb0a8a372014-09-23 09:50:21 -0700414 static uint32_t GenBaseGradientKey(const GrProcessor&);
bsalomon63e99f72014-07-21 08:03:14 -0700415
416 // Emits the uniform used as the y-coord to texture samples in derived classes. Subclasses
417 // should call this method from their emitCode().
joshualitt15988992014-10-09 15:04:05 -0700418 void emitUniforms(GrGLFPBuilder* builder, uint32_t baseKey);
bsalomon63e99f72014-07-21 08:03:14 -0700419
420
421 // emit code that gets a fragment's color from an expression for t; Has branches for 3 separate
422 // control flows inside -- 2 color gradients, 3 color symmetric gradients (both using
423 // native GLSL mix), and 4+ color gradients that use the traditional texture lookup.
joshualitt15988992014-10-09 15:04:05 -0700424 void emitColor(GrGLFPBuilder* builder,
bsalomon63e99f72014-07-21 08:03:14 -0700425 const char* gradientTValue,
426 uint32_t baseKey,
427 const char* outputColor,
428 const char* inputColor,
429 const TextureSamplerArray& samplers);
430
431private:
bsalomon@google.comd8b5fac2012-11-01 17:02:46 +0000432 enum {
bsalomon@google.com82d12232013-09-09 15:36:26 +0000433 kPremulTypeKeyBitCnt = 1,
bsalomon@google.com77af6802013-10-02 13:04:56 +0000434 kPremulTypeMask = 1,
bsalomon@google.com82d12232013-09-09 15:36:26 +0000435 kPremulBeforeInterpKey = kPremulTypeMask,
436
bsalomon@google.com77af6802013-10-02 13:04:56 +0000437 kTwoColorKey = 2 << kPremulTypeKeyBitCnt,
438 kThreeColorKey = 3 << kPremulTypeKeyBitCnt,
bsalomon@google.com82d12232013-09-09 15:36:26 +0000439 kColorKeyMask = kTwoColorKey | kThreeColorKey,
440 kColorKeyBitCnt = 2,
441
442 // Subclasses must shift any key bits they produce up by this amount
443 // and combine with the result of GenBaseGradientKey.
bsalomon@google.com77af6802013-10-02 13:04:56 +0000444 kBaseKeyBitCnt = (kPremulTypeKeyBitCnt + kColorKeyBitCnt)
bsalomon@google.comd8b5fac2012-11-01 17:02:46 +0000445 };
bsalomon63e99f72014-07-21 08:03:14 -0700446 GR_STATIC_ASSERT(kBaseKeyBitCnt <= 32);
bsalomon@google.comd8b5fac2012-11-01 17:02:46 +0000447
bsalomon63e99f72014-07-21 08:03:14 -0700448 static SkGradientShaderBase::GpuColorType ColorTypeFromKey(uint32_t baseKey){
449 if (kTwoColorKey == (baseKey & kColorKeyMask)) {
commit-bot@chromium.org996402b2014-04-18 14:42:11 +0000450 return SkGradientShaderBase::kTwo_GpuColorType;
bsalomon63e99f72014-07-21 08:03:14 -0700451 } else if (kThreeColorKey == (baseKey & kColorKeyMask)) {
commit-bot@chromium.org996402b2014-04-18 14:42:11 +0000452 return SkGradientShaderBase::kThree_GpuColorType;
453 } else {return SkGradientShaderBase::kTexture_GpuColorType;}
bsalomon@google.com82d12232013-09-09 15:36:26 +0000454 }
455
bsalomon63e99f72014-07-21 08:03:14 -0700456 static GrGradientEffect::PremulType PremulTypeFromKey(uint32_t baseKey){
457 if (kPremulBeforeInterpKey == (baseKey & kPremulTypeMask)) {
bsalomon@google.com82d12232013-09-09 15:36:26 +0000458 return GrGradientEffect::kBeforeInterp_PremulType;
459 } else {
460 return GrGradientEffect::kAfterInterp_PremulType;
461 }
462 }
463
bsalomon@google.com81712882012-11-01 17:12:34 +0000464 SkScalar fCachedYCoord;
kkinnunen7510b222014-07-30 00:04:16 -0700465 GrGLProgramDataManager::UniformHandle fFSYUni;
466 GrGLProgramDataManager::UniformHandle fColorStartUni;
467 GrGLProgramDataManager::UniformHandle fColorMidUni;
468 GrGLProgramDataManager::UniformHandle fColorEndUni;
rileya@google.comb3e50f22012-08-20 17:43:08 +0000469
joshualittb0a8a372014-09-23 09:50:21 -0700470 typedef GrGLFragmentProcessor INHERITED;
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000471};
472
473#endif
474
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +0000475#endif