Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / effects / gradients / SkGradientShaderPriv.h
1 /*
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 "SkGradientBitmapCache.h"
12 #include "SkGradientShader.h"
13 #include "SkClampRange.h"
14 #include "SkColorPriv.h"
15 #include "SkReadBuffer.h"
16 #include "SkWriteBuffer.h"
17 #include "SkMallocPixelRef.h"
18 #include "SkUtils.h"
19 #include "SkTemplates.h"
20 #include "SkShader.h"
21 #include "SkOnce.h"
22
23 static inline void sk_memset32_dither(uint32_t dst[], uint32_t v0, uint32_t v1,
24                                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
43 static inline SkFixed clamp_tileproc(SkFixed x) {
44     return SkClampMax(x, 0xFFFF);
45 }
46
47 // Repeat
48
49 static inline SkFixed repeat_tileproc(SkFixed x) {
50     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
61 static 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
72 typedef SkFixed (*TileProc)(SkFixed);
73
74 ///////////////////////////////////////////////////////////////////////////////
75
76 static const TileProc gTileProcs[] = {
77     clamp_tileproc,
78     repeat_tileproc,
79     mirror_tileproc
80 };
81
82 ///////////////////////////////////////////////////////////////////////////////
83
84 class SkGradientShaderBase : public SkShader {
85 public:
86     struct Descriptor {
87         Descriptor() {
88             sk_bzero(this, sizeof(*this));
89             fTileMode = SkShader::kClamp_TileMode;
90         }
91
92         const SkMatrix*     fLocalMatrix;
93         const SkColor*      fColors;
94         const SkScalar*     fPos;
95         int                 fCount;
96         SkShader::TileMode  fTileMode;
97         uint32_t            fGradFlags;
98
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;
121     };
122
123 public:
124     SkGradientShaderBase(const Descriptor& desc);
125     virtual ~SkGradientShaderBase();
126
127     // 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:
167         GradientShaderBaseContext(const SkGradientShaderBase& shader, const ContextRec&);
168
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
183     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,
191         kCache16Count = (1 << kCache16Bits),
192         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,
198         kCache32Count   = (1 << kCache32Bits),
199         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.
204         kDitherStride32 = kCache32Count,
205         kDitherStride16 = kCache16Count,
206     };
207
208     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
219     uint32_t getGradFlags() const { return fGradFlags; }
220
221 protected:
222     SkGradientShaderBase(SkReadBuffer& );
223     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
224     SK_TO_STRING_OVERRIDE()
225
226     SkMatrix    fPtsToUnit;     // set by subclass
227     TileMode    fTileMode;
228     TileProc    fTileProc;
229     int         fColorCount;
230     uint8_t     fGradFlags;
231
232     struct Rec {
233         SkFixed     fPos;   // 0...1
234         uint32_t    fScale; // (1 << 24) / range
235     };
236     Rec*        fRecs;
237
238     void commonAsAGradient(GradientInfo*, bool flipGrad = false) const;
239
240     virtual bool onAsLuminanceColor(SkColor*) const SK_OVERRIDE;
241
242     /*
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();
257
258 private:
259     enum {
260         kColorStorageCount = 4, // more than this many colors, and we'll use sk_malloc for the space
261
262         kStorageSize = kColorStorageCount * (sizeof(SkColor) + sizeof(SkScalar) + sizeof(Rec))
263     };
264     SkColor     fStorage[(kStorageSize + 3) >> 2];
265     SkColor*    fOrigColors; // original colors, before modulation by paint in context.
266     SkScalar*   fOrigPos;   // original positions
267     bool        fColorsAreOpaque;
268
269     GradientShaderCache* refCache(U8CPU alpha) const;
270     mutable SkMutex                           fCacheMutex;
271     mutable SkAutoTUnref<GradientShaderCache> fCache;
272
273     void initCommon();
274
275     typedef SkShader INHERITED;
276 };
277
278 static inline int init_dither_toggle(int x, int y) {
279     x &= 1;
280     y = (y & 1) << 1;
281     return (x | y) * SkGradientShaderBase::kDitherStride32;
282 }
283
284 static inline int next_dither_toggle(int toggle) {
285     return toggle ^ SkGradientShaderBase::kDitherStride32;
286 }
287
288 static inline int init_dither_toggle16(int x, int y) {
289     return ((x ^ y) & 1) * SkGradientShaderBase::kDitherStride16;
290 }
291
292 static inline int next_dither_toggle16(int toggle) {
293     return toggle ^ SkGradientShaderBase::kDitherStride16;
294 }
295
296 ///////////////////////////////////////////////////////////////////////////////
297
298 #if SK_SUPPORT_GPU
299
300 #include "GrCoordTransform.h"
301 #include "GrFragmentProcessor.h"
302 #include "gl/GrGLProcessor.h"
303
304 class GrFragmentStage;
305 class GrBackendProcessorFactory;
306
307 /*
308  * The interpretation of the texture matrix depends on the sample mode. The
309  * texture matrix is applied both when the texture coordinates are explicit
310  * and  when vertex positions are used as texture  coordinates. In the latter
311  * case the texture matrix is applied to the pre-view-matrix position
312  * values.
313  *
314  * Normal SampleMode
315  *  The post-matrix texture coordinates are in normalize space with (0,0) at
316  *  the top-left and (1,1) at the bottom right.
317  * RadialGradient
318  *  The matrix specifies the radial gradient parameters.
319  *  (0,0) in the post-matrix space is center of the radial gradient.
320  * Radial2Gradient
321  *   Matrix transforms to space where first circle is centered at the
322  *   origin. The second circle will be centered (x, 0) where x may be
323  *   0 and is provided by setRadial2Params. The post-matrix space is
324  *   normalized such that 1 is the second radius - first radius.
325  * SweepGradient
326  *  The angle from the origin of texture coordinates in post-matrix space
327  *  determines the gradient value.
328  */
329
330  class GrTextureStripAtlas;
331
332 // Base class for Gr gradient effects
333 class GrGradientEffect : public GrFragmentProcessor {
334 public:
335
336     GrGradientEffect(GrContext* ctx,
337                      const SkGradientShaderBase& shader,
338                      const SkMatrix& matrix,
339                      SkShader::TileMode tileMode);
340
341     virtual ~GrGradientEffect();
342
343     bool useAtlas() const { return SkToBool(-1 != fRow); }
344     SkScalar getYCoord() const { return fYCoord; };
345
346     SkGradientShaderBase::GpuColorType getColorType() const { return fColorType; }
347
348     enum PremulType {
349         kBeforeInterp_PremulType,
350         kAfterInterp_PremulType,
351     };
352
353     PremulType getPremulType() const { return fPremulType; }
354
355     const SkColor* getColors(int pos) const {
356         SkASSERT(fColorType != SkGradientShaderBase::kTexture_GpuColorType);
357         SkASSERT((pos-1) <= fColorType);
358         return &fColors[pos];
359     }
360
361 protected:
362
363     /** Populates a pair of arrays with colors and stop info to construct a random gradient.
364         The function decides whether stop values should be used or not. The return value indicates
365         the number of colors, which will be capped by kMaxRandomGradientColors. colors should be
366         sized to be at least kMaxRandomGradientColors. stops is a pointer to an array of at least
367         size kMaxRandomGradientColors. It may be updated to NULL, indicating that NULL should be
368         passed to the gradient factory rather than the array.
369     */
370     static const int kMaxRandomGradientColors = 4;
371     static int RandomGradientParams(SkRandom* r,
372                                     SkColor colors[kMaxRandomGradientColors],
373                                     SkScalar** stops,
374                                     SkShader::TileMode* tm);
375
376     virtual bool onIsEqual(const GrFragmentProcessor&) const SK_OVERRIDE;
377
378     virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE;
379
380     const GrCoordTransform& getCoordTransform() const { return fCoordTransform; }
381
382 private:
383     static const GrCoordSet kCoordSet = kLocal_GrCoordSet;
384
385     GrCoordTransform fCoordTransform;
386     GrTextureAccess fTextureAccess;
387     SkScalar fYCoord;
388     GrTextureStripAtlas* fAtlas;
389     int fRow;
390     bool fIsOpaque;
391     SkGradientShaderBase::GpuColorType fColorType;
392     SkColor fColors[3]; // More than 3 colors we use texture
393     PremulType fPremulType; // This only changes behavior for two and three color special cases.
394                             // It is already baked into to the table for texture gradients.
395     typedef GrFragmentProcessor INHERITED;
396
397 };
398
399 ///////////////////////////////////////////////////////////////////////////////
400
401 // Base class for GL gradient effects
402 class GrGLGradientEffect : public GrGLFragmentProcessor {
403 public:
404     GrGLGradientEffect(const GrBackendProcessorFactory& factory);
405     virtual ~GrGLGradientEffect();
406
407     virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
408
409 protected:
410     /**
411      * Subclasses must call this. It will return a key for the part of the shader code controlled
412      * by the base class. The subclasses must stick it in their key and then pass it to the below
413      * emit* functions from their emitCode function.
414      */
415     static uint32_t GenBaseGradientKey(const GrProcessor&);
416
417     // Emits the uniform used as the y-coord to texture samples in derived classes. Subclasses
418     // should call this method from their emitCode().
419     void emitUniforms(GrGLFPBuilder* builder, uint32_t baseKey);
420
421
422     // emit code that gets a fragment's color from an expression for t; Has branches for 3 separate
423     // control flows inside -- 2 color gradients, 3 color symmetric gradients (both using
424     // native GLSL mix), and 4+ color gradients that use the traditional texture lookup.
425     void emitColor(GrGLFPBuilder* builder,
426                    const char* gradientTValue,
427                    uint32_t baseKey,
428                    const char* outputColor,
429                    const char* inputColor,
430                    const TextureSamplerArray& samplers);
431
432 private:
433     enum {
434         kPremulTypeKeyBitCnt = 1,
435         kPremulTypeMask = 1,
436         kPremulBeforeInterpKey = kPremulTypeMask,
437
438         kTwoColorKey = 2 << kPremulTypeKeyBitCnt,
439         kThreeColorKey = 3 << kPremulTypeKeyBitCnt,
440         kColorKeyMask = kTwoColorKey | kThreeColorKey,
441         kColorKeyBitCnt = 2,
442
443         // Subclasses must shift any key bits they produce up by this amount
444         // and combine with the result of GenBaseGradientKey.
445         kBaseKeyBitCnt = (kPremulTypeKeyBitCnt + kColorKeyBitCnt)
446     };
447     GR_STATIC_ASSERT(kBaseKeyBitCnt <= 32);
448
449     static SkGradientShaderBase::GpuColorType ColorTypeFromKey(uint32_t baseKey){
450         if (kTwoColorKey == (baseKey & kColorKeyMask)) {
451             return SkGradientShaderBase::kTwo_GpuColorType;
452         } else if (kThreeColorKey == (baseKey & kColorKeyMask)) {
453             return SkGradientShaderBase::kThree_GpuColorType;
454         } else {return SkGradientShaderBase::kTexture_GpuColorType;}
455     }
456
457     static GrGradientEffect::PremulType PremulTypeFromKey(uint32_t baseKey){
458         if (kPremulBeforeInterpKey == (baseKey & kPremulTypeMask)) {
459             return GrGradientEffect::kBeforeInterp_PremulType;
460         } else {
461             return GrGradientEffect::kAfterInterp_PremulType;
462         }
463     }
464
465     SkScalar fCachedYCoord;
466     GrGLProgramDataManager::UniformHandle fFSYUni;
467     GrGLProgramDataManager::UniformHandle fColorStartUni;
468     GrGLProgramDataManager::UniformHandle fColorMidUni;
469     GrGLProgramDataManager::UniformHandle fColorEndUni;
470
471     typedef GrGLFragmentProcessor INHERITED;
472 };
473
474 #endif
475
476 #endif