blob: 20f8112ecdbce62f920df7fe997879538e45c614 [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"
bsalomon6251d172014-10-15 10:50:36 -0700301#include "GrFragmentProcessor.h"
joshualittb0a8a372014-09-23 09:50:21 -0700302#include "gl/GrGLProcessor.h"
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +0000303
joshualitta5305a12014-10-10 17:47:00 -0700304class GrFragmentStage;
joshualittb0a8a372014-09-23 09:50:21 -0700305class GrBackendProcessorFactory;
egdaniel605dd0f2014-11-12 08:35:25 -0800306class GrInvariantOutput;
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000307
308/*
bsalomon@google.comd8b5fac2012-11-01 17:02:46 +0000309 * The interpretation of the texture matrix depends on the sample mode. The
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000310 * texture matrix is applied both when the texture coordinates are explicit
311 * and when vertex positions are used as texture coordinates. In the latter
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000312 * case the texture matrix is applied to the pre-view-matrix position
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000313 * values.
314 *
315 * Normal SampleMode
316 * The post-matrix texture coordinates are in normalize space with (0,0) at
317 * the top-left and (1,1) at the bottom right.
318 * RadialGradient
319 * The matrix specifies the radial gradient parameters.
320 * (0,0) in the post-matrix space is center of the radial gradient.
321 * Radial2Gradient
322 * Matrix transforms to space where first circle is centered at the
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000323 * origin. The second circle will be centered (x, 0) where x may be
324 * 0 and is provided by setRadial2Params. The post-matrix space is
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000325 * normalized such that 1 is the second radius - first radius.
326 * SweepGradient
327 * The angle from the origin of texture coordinates in post-matrix space
328 * determines the gradient value.
329 */
330
rileya@google.comb3e50f22012-08-20 17:43:08 +0000331 class GrTextureStripAtlas;
332
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000333// Base class for Gr gradient effects
joshualittb0a8a372014-09-23 09:50:21 -0700334class GrGradientEffect : public GrFragmentProcessor {
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000335public:
336
bsalomon@google.com1ce49fc2012-09-18 14:14:49 +0000337 GrGradientEffect(GrContext* ctx,
338 const SkGradientShaderBase& shader,
bsalomon@google.comd8b5fac2012-11-01 17:02:46 +0000339 const SkMatrix& matrix,
bsalomon@google.com1ce49fc2012-09-18 14:14:49 +0000340 SkShader::TileMode tileMode);
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000341
342 virtual ~GrGradientEffect();
343
rileya@google.comb3e50f22012-08-20 17:43:08 +0000344 bool useAtlas() const { return SkToBool(-1 != fRow); }
bsalomon@google.com81712882012-11-01 17:12:34 +0000345 SkScalar getYCoord() const { return fYCoord; };
rileya@google.comb3e50f22012-08-20 17:43:08 +0000346
commit-bot@chromium.org996402b2014-04-18 14:42:11 +0000347 SkGradientShaderBase::GpuColorType getColorType() const { return fColorType; }
bsalomon@google.com82d12232013-09-09 15:36:26 +0000348
349 enum PremulType {
350 kBeforeInterp_PremulType,
351 kAfterInterp_PremulType,
352 };
353
354 PremulType getPremulType() const { return fPremulType; }
355
356 const SkColor* getColors(int pos) const {
commit-bot@chromium.org996402b2014-04-18 14:42:11 +0000357 SkASSERT(fColorType != SkGradientShaderBase::kTexture_GpuColorType);
bsalomon@google.com82d12232013-09-09 15:36:26 +0000358 SkASSERT((pos-1) <= fColorType);
359 return &fColors[pos];
360 }
bsalomon@google.com371e1052013-01-11 21:08:55 +0000361
bsalomon@google.comd4726202012-08-03 14:34:46 +0000362protected:
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000363
bsalomon@google.comd4726202012-08-03 14:34:46 +0000364 /** Populates a pair of arrays with colors and stop info to construct a random gradient.
365 The function decides whether stop values should be used or not. The return value indicates
366 the number of colors, which will be capped by kMaxRandomGradientColors. colors should be
367 sized to be at least kMaxRandomGradientColors. stops is a pointer to an array of at least
368 size kMaxRandomGradientColors. It may be updated to NULL, indicating that NULL should be
369 passed to the gradient factory rather than the array.
370 */
371 static const int kMaxRandomGradientColors = 4;
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000372 static int RandomGradientParams(SkRandom* r,
bsalomon@google.comd4726202012-08-03 14:34:46 +0000373 SkColor colors[kMaxRandomGradientColors],
374 SkScalar** stops,
375 SkShader::TileMode* tm);
376
bsalomon0e08fc12014-10-15 08:19:04 -0700377 virtual bool onIsEqual(const GrFragmentProcessor&) const SK_OVERRIDE;
bsalomon@google.com68b58c92013-01-17 16:50:08 +0000378
egdaniel605dd0f2014-11-12 08:35:25 -0800379 virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE;
egdaniel1a8ecdf2014-10-03 06:24:12 -0700380
commit-bot@chromium.org5fd7d5c2013-10-04 01:20:09 +0000381 const GrCoordTransform& getCoordTransform() const { return fCoordTransform; }
382
bsalomon@google.comd4726202012-08-03 14:34:46 +0000383private:
bsalomon@google.com77af6802013-10-02 13:04:56 +0000384 static const GrCoordSet kCoordSet = kLocal_GrCoordSet;
bsalomon@google.com68b58c92013-01-17 16:50:08 +0000385
bsalomon@google.com77af6802013-10-02 13:04:56 +0000386 GrCoordTransform fCoordTransform;
bsalomon@google.com6d003d12012-09-11 15:45:20 +0000387 GrTextureAccess fTextureAccess;
bsalomon@google.com81712882012-11-01 17:12:34 +0000388 SkScalar fYCoord;
rileya@google.comb3e50f22012-08-20 17:43:08 +0000389 GrTextureStripAtlas* fAtlas;
390 int fRow;
bsalomon@google.com371e1052013-01-11 21:08:55 +0000391 bool fIsOpaque;
commit-bot@chromium.org996402b2014-04-18 14:42:11 +0000392 SkGradientShaderBase::GpuColorType fColorType;
393 SkColor fColors[3]; // More than 3 colors we use texture
bsalomon@google.com82d12232013-09-09 15:36:26 +0000394 PremulType fPremulType; // This only changes behavior for two and three color special cases.
395 // It is already baked into to the table for texture gradients.
joshualittb0a8a372014-09-23 09:50:21 -0700396 typedef GrFragmentProcessor INHERITED;
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000397
398};
399
400///////////////////////////////////////////////////////////////////////////////
401
bsalomon@google.com8ea78d82012-10-24 20:11:30 +0000402// Base class for GL gradient effects
joshualittb0a8a372014-09-23 09:50:21 -0700403class GrGLGradientEffect : public GrGLFragmentProcessor {
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000404public:
joshualittb0a8a372014-09-23 09:50:21 -0700405 GrGLGradientEffect(const GrBackendProcessorFactory& factory);
bsalomon@google.com0707c292012-10-25 21:45:42 +0000406 virtual ~GrGLGradientEffect();
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000407
joshualittb0a8a372014-09-23 09:50:21 -0700408 virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
rileya@google.comb3e50f22012-08-20 17:43:08 +0000409
bsalomon@google.comf78df332012-10-29 12:43:38 +0000410protected:
bsalomon63e99f72014-07-21 08:03:14 -0700411 /**
412 * Subclasses must call this. It will return a key for the part of the shader code controlled
413 * by the base class. The subclasses must stick it in their key and then pass it to the below
414 * emit* functions from their emitCode function.
415 */
joshualittb0a8a372014-09-23 09:50:21 -0700416 static uint32_t GenBaseGradientKey(const GrProcessor&);
bsalomon63e99f72014-07-21 08:03:14 -0700417
418 // Emits the uniform used as the y-coord to texture samples in derived classes. Subclasses
419 // should call this method from their emitCode().
joshualitt15988992014-10-09 15:04:05 -0700420 void emitUniforms(GrGLFPBuilder* builder, uint32_t baseKey);
bsalomon63e99f72014-07-21 08:03:14 -0700421
422
423 // emit code that gets a fragment's color from an expression for t; Has branches for 3 separate
424 // control flows inside -- 2 color gradients, 3 color symmetric gradients (both using
425 // native GLSL mix), and 4+ color gradients that use the traditional texture lookup.
joshualitt15988992014-10-09 15:04:05 -0700426 void emitColor(GrGLFPBuilder* builder,
bsalomon63e99f72014-07-21 08:03:14 -0700427 const char* gradientTValue,
428 uint32_t baseKey,
429 const char* outputColor,
430 const char* inputColor,
431 const TextureSamplerArray& samplers);
432
433private:
bsalomon@google.comd8b5fac2012-11-01 17:02:46 +0000434 enum {
bsalomon@google.com82d12232013-09-09 15:36:26 +0000435 kPremulTypeKeyBitCnt = 1,
bsalomon@google.com77af6802013-10-02 13:04:56 +0000436 kPremulTypeMask = 1,
bsalomon@google.com82d12232013-09-09 15:36:26 +0000437 kPremulBeforeInterpKey = kPremulTypeMask,
438
bsalomon@google.com77af6802013-10-02 13:04:56 +0000439 kTwoColorKey = 2 << kPremulTypeKeyBitCnt,
440 kThreeColorKey = 3 << kPremulTypeKeyBitCnt,
bsalomon@google.com82d12232013-09-09 15:36:26 +0000441 kColorKeyMask = kTwoColorKey | kThreeColorKey,
442 kColorKeyBitCnt = 2,
443
444 // Subclasses must shift any key bits they produce up by this amount
445 // and combine with the result of GenBaseGradientKey.
bsalomon@google.com77af6802013-10-02 13:04:56 +0000446 kBaseKeyBitCnt = (kPremulTypeKeyBitCnt + kColorKeyBitCnt)
bsalomon@google.comd8b5fac2012-11-01 17:02:46 +0000447 };
bsalomon63e99f72014-07-21 08:03:14 -0700448 GR_STATIC_ASSERT(kBaseKeyBitCnt <= 32);
bsalomon@google.comd8b5fac2012-11-01 17:02:46 +0000449
bsalomon63e99f72014-07-21 08:03:14 -0700450 static SkGradientShaderBase::GpuColorType ColorTypeFromKey(uint32_t baseKey){
451 if (kTwoColorKey == (baseKey & kColorKeyMask)) {
commit-bot@chromium.org996402b2014-04-18 14:42:11 +0000452 return SkGradientShaderBase::kTwo_GpuColorType;
bsalomon63e99f72014-07-21 08:03:14 -0700453 } else if (kThreeColorKey == (baseKey & kColorKeyMask)) {
commit-bot@chromium.org996402b2014-04-18 14:42:11 +0000454 return SkGradientShaderBase::kThree_GpuColorType;
455 } else {return SkGradientShaderBase::kTexture_GpuColorType;}
bsalomon@google.com82d12232013-09-09 15:36:26 +0000456 }
457
bsalomon63e99f72014-07-21 08:03:14 -0700458 static GrGradientEffect::PremulType PremulTypeFromKey(uint32_t baseKey){
459 if (kPremulBeforeInterpKey == (baseKey & kPremulTypeMask)) {
bsalomon@google.com82d12232013-09-09 15:36:26 +0000460 return GrGradientEffect::kBeforeInterp_PremulType;
461 } else {
462 return GrGradientEffect::kAfterInterp_PremulType;
463 }
464 }
465
bsalomon@google.com81712882012-11-01 17:12:34 +0000466 SkScalar fCachedYCoord;
kkinnunen7510b222014-07-30 00:04:16 -0700467 GrGLProgramDataManager::UniformHandle fFSYUni;
468 GrGLProgramDataManager::UniformHandle fColorStartUni;
469 GrGLProgramDataManager::UniformHandle fColorMidUni;
470 GrGLProgramDataManager::UniformHandle fColorEndUni;
rileya@google.comb3e50f22012-08-20 17:43:08 +0000471
joshualittb0a8a372014-09-23 09:50:21 -0700472 typedef GrGLFragmentProcessor INHERITED;
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000473};
474
475#endif
476
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +0000477#endif