11c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com/*
21c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com * Copyright 2012 Google Inc.
31c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com *
41c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com * Use of this source code is governed by a BSD-style license that can be
51c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com * found in the LICENSE file.
61c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com */
71c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
81c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com#ifndef SkGradientShaderPriv_DEFINED
91c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com#define SkGradientShaderPriv_DEFINED
101c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
11a6cac4ce3896669e1b5935def0a84b4456ec9777reed#include "SkGradientBitmapCache.h"
121c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com#include "SkGradientShader.h"
131c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com#include "SkClampRange.h"
141c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com#include "SkColorPriv.h"
158b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkReadBuffer.h"
168b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkWriteBuffer.h"
171c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com#include "SkMallocPixelRef.h"
181c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com#include "SkUtils.h"
191c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com#include "SkTemplates.h"
201c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com#include "SkShader.h"
2187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org#include "SkOnce.h"
221c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
2305af1afd429808913683da75644e48bece12e820humper@google.comstatic inline void sk_memset32_dither(uint32_t dst[], uint32_t v0, uint32_t v1,
241c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com                               int count) {
251c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com    if (count > 0) {
261c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com        if (v0 == v1) {
271c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com            sk_memset32(dst, v0, count);
281c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com        } else {
291c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com            int pairs = count >> 1;
301c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com            for (int i = 0; i < pairs; i++) {
311c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com                *dst++ = v0;
321c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com                *dst++ = v1;
331c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com            }
341c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com            if (count & 1) {
351c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com                *dst = v0;
361c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com            }
371c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com        }
381c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com    }
391c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com}
401c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
411c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com//  Clamp
421c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
4305af1afd429808913683da75644e48bece12e820humper@google.comstatic inline SkFixed clamp_tileproc(SkFixed x) {
441c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com    return SkClampMax(x, 0xFFFF);
451c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com}
461c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
471c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com// Repeat
481c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
4905af1afd429808913683da75644e48bece12e820humper@google.comstatic inline SkFixed repeat_tileproc(SkFixed x) {
501c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com    return x & 0xFFFF;
511c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com}
521c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
531c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com// Mirror
541c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
551c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com// Visual Studio 2010 (MSC_VER=1600) optimizes bit-shift code incorrectly.
561c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com// See http://code.google.com/p/skia/issues/detail?id=472
571c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com#if defined(_MSC_VER) && (_MSC_VER >= 1600)
581c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com#pragma optimize("", off)
591c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com#endif
601c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
611c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.comstatic inline SkFixed mirror_tileproc(SkFixed x) {
621c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com    int s = x << 15 >> 31;
631c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com    return (x ^ s) & 0xFFFF;
641c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com}
651c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
661c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com#if defined(_MSC_VER) && (_MSC_VER >= 1600)
671c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com#pragma optimize("", on)
681c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com#endif
691c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
701c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com///////////////////////////////////////////////////////////////////////////////
711c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
721c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.comtypedef SkFixed (*TileProc)(SkFixed);
731c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
741c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com///////////////////////////////////////////////////////////////////////////////
751c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
761c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.comstatic const TileProc gTileProcs[] = {
771c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com    clamp_tileproc,
781c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com    repeat_tileproc,
791c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com    mirror_tileproc
801c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com};
811c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
821c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com///////////////////////////////////////////////////////////////////////////////
831c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
841c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.comclass SkGradientShaderBase : public SkShader {
851c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.compublic:
86437d6eb4e0d91710fdeb7ecedb694f658458ae00reed@google.com    struct Descriptor {
87437d6eb4e0d91710fdeb7ecedb694f658458ae00reed@google.com        Descriptor() {
88437d6eb4e0d91710fdeb7ecedb694f658458ae00reed@google.com            sk_bzero(this, sizeof(*this));
89437d6eb4e0d91710fdeb7ecedb694f658458ae00reed@google.com            fTileMode = SkShader::kClamp_TileMode;
90437d6eb4e0d91710fdeb7ecedb694f658458ae00reed@google.com        }
913e2345a8d56cb76bc43e4421a3e9e3681ecd9ebaskia.committer@gmail.com
92addf2edf3da20f053daa3897cfe2c52d7369a7b1reed        const SkMatrix*     fLocalMatrix;
93437d6eb4e0d91710fdeb7ecedb694f658458ae00reed@google.com        const SkColor*      fColors;
94437d6eb4e0d91710fdeb7ecedb694f658458ae00reed@google.com        const SkScalar*     fPos;
95437d6eb4e0d91710fdeb7ecedb694f658458ae00reed@google.com        int                 fCount;
96437d6eb4e0d91710fdeb7ecedb694f658458ae00reed@google.com        SkShader::TileMode  fTileMode;
976c5aea2f10033d527b7785dd0d7b7d5ca65bccdacommit-bot@chromium.org        uint32_t            fGradFlags;
989fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed
999fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed        void flatten(SkWriteBuffer&) const;
1009fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed    };
1019fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed
1029fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed    class DescriptorScope : public Descriptor {
1039fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed    public:
1049fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed        DescriptorScope() {}
1059fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed
1069fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed        bool unflatten(SkReadBuffer&);
1079fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed
1089fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed        // fColors and fPos always point into local memory, so they can be safely mutated
1099fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed        //
1109fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed        SkColor* mutableColors() { return const_cast<SkColor*>(fColors); }
1119fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed        SkScalar* mutablePos() { return const_cast<SkScalar*>(fPos); }
1129fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed
1139fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed    private:
1149fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed        enum {
1159fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed            kStorageCount = 16
1169fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed        };
1179fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed        SkColor fColorStorage[kStorageCount];
1189fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed        SkScalar fPosStorage[kStorageCount];
1199fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed        SkMatrix fLocalMatrixStorage;
1209fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed        SkAutoMalloc fDynamicStorage;
121437d6eb4e0d91710fdeb7ecedb694f658458ae00reed@google.com    };
122437d6eb4e0d91710fdeb7ecedb694f658458ae00reed@google.com
123437d6eb4e0d91710fdeb7ecedb694f658458ae00reed@google.compublic:
124addf2edf3da20f053daa3897cfe2c52d7369a7b1reed    SkGradientShaderBase(const Descriptor& desc);
1251c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com    virtual ~SkGradientShaderBase();
1261c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
12787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    // The cache is initialized on-demand when getCache16/32 is called.
12887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    class GradientShaderCache : public SkRefCnt {
12987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    public:
13087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        GradientShaderCache(U8CPU alpha, const SkGradientShaderBase& shader);
13187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        ~GradientShaderCache();
13287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org
13387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        const uint16_t*     getCache16();
13487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        const SkPMColor*    getCache32();
13587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org
13687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        SkMallocPixelRef* getCache32PixelRef() const { return fCache32PixelRef; }
13787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org
13887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        unsigned getAlpha() const { return fCacheAlpha; }
13987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org
14087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    private:
14187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        // Working pointers. If either is NULL, we need to recompute the corresponding cache values.
14287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        uint16_t*   fCache16;
14387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        SkPMColor*  fCache32;
14487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org
14587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        uint16_t*         fCache16Storage;    // Storage for fCache16, allocated on demand.
14687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        SkMallocPixelRef* fCache32PixelRef;
14787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        const unsigned    fCacheAlpha;        // The alpha value we used when we computed the cache.
14887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org                                              // Larger than 8bits so we can store uninitialized
14987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org                                              // value.
15087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org
15187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        const SkGradientShaderBase& fShader;
15287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org
15387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        // Make sure we only initialize the caches once.
15487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        bool    fCache16Inited, fCache32Inited;
15587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        SkMutex fCache16Mutex, fCache32Mutex;
15687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org
15787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        static void initCache16(GradientShaderCache* cache);
15887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        static void initCache32(GradientShaderCache* cache);
15987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org
16087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        static void Build16bitCache(uint16_t[], SkColor c0, SkColor c1, int count);
16187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        static void Build32bitCache(SkPMColor[], SkColor c0, SkColor c1, int count,
16287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org                                    U8CPU alpha, uint32_t gradFlags);
16387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    };
16487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org
16587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    class GradientShaderBaseContext : public SkShader::Context {
16687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    public:
167e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org        GradientShaderBaseContext(const SkGradientShaderBase& shader, const ContextRec&);
16887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org
16987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        virtual uint32_t getFlags() const SK_OVERRIDE { return fFlags; }
17087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org
17187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    protected:
17287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        SkMatrix    fDstToIndex;
17387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        SkMatrix::MapXYProc fDstToIndexProc;
17487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        uint8_t     fDstToIndexClass;
17587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        uint8_t     fFlags;
17687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org
17787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        SkAutoTUnref<GradientShaderCache> fCache;
17887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org
17987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    private:
18087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        typedef SkShader::Context INHERITED;
18187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    };
18287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org
1831c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com    virtual bool isOpaque() const SK_OVERRIDE;
1841c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
1851c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com    void getGradientTableBitmap(SkBitmap*) const;
1861c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
1871c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com    enum {
1881c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com        /// Seems like enough for visual accuracy. TODO: if pos[] deserves
1891c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com        /// it, use a larger cache.
1901c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com        kCache16Bits    = 8,
1913c2102c2d2cdad328a0d87329e1a973f12775836reed@google.com        kCache16Count = (1 << kCache16Bits),
1921c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com        kCache16Shift   = 16 - kCache16Bits,
1931c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com        kSqrt16Shift    = 8 - kCache16Bits,
1941c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
1951c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com        /// Seems like enough for visual accuracy. TODO: if pos[] deserves
1961c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com        /// it, use a larger cache.
1971c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com        kCache32Bits    = 8,
19860040292be58ac553298209fb2e0684a4cb17dccreed@google.com        kCache32Count   = (1 << kCache32Bits),
1991c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com        kCache32Shift   = 16 - kCache32Bits,
2001c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com        kSqrt32Shift    = 8 - kCache32Bits,
2011c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
2021c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com        /// This value is used to *read* the dither cache; it may be 0
2031c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com        /// if dithering is disabled.
2041c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com        kDitherStride32 = kCache32Count,
2051c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com        kDitherStride16 = kCache16Count,
2061c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com    };
2071c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
208996402bddb4d886c38dee17341e5833500901933commit-bot@chromium.org    enum GpuColorType {
209996402bddb4d886c38dee17341e5833500901933commit-bot@chromium.org        kTwo_GpuColorType,
210996402bddb4d886c38dee17341e5833500901933commit-bot@chromium.org        kThree_GpuColorType, // Symmetric three color
211996402bddb4d886c38dee17341e5833500901933commit-bot@chromium.org        kTexture_GpuColorType
212996402bddb4d886c38dee17341e5833500901933commit-bot@chromium.org    };
213996402bddb4d886c38dee17341e5833500901933commit-bot@chromium.org
214996402bddb4d886c38dee17341e5833500901933commit-bot@chromium.org    // Determines and returns the gradient is a two color gradient, symmetric three color gradient
215996402bddb4d886c38dee17341e5833500901933commit-bot@chromium.org    // or other (texture gradient). If it is two or symmetric three color, the colors array will
216996402bddb4d886c38dee17341e5833500901933commit-bot@chromium.org    // also be filled with the gradient colors
217996402bddb4d886c38dee17341e5833500901933commit-bot@chromium.org    GpuColorType getGpuColorType(SkColor colors[3]) const;
218996402bddb4d886c38dee17341e5833500901933commit-bot@chromium.org
2196c5aea2f10033d527b7785dd0d7b7d5ca65bccdacommit-bot@chromium.org    uint32_t getGradFlags() const { return fGradFlags; }
22053783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org
2211c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.comprotected:
2228b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org    SkGradientShaderBase(SkReadBuffer& );
2238b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org    virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
2240f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org    SK_TO_STRING_OVERRIDE()
2251c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
2261c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com    SkMatrix    fPtsToUnit;     // set by subclass
2271c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com    TileMode    fTileMode;
2281c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com    TileProc    fTileProc;
2291c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com    int         fColorCount;
2303d3a860d0ba878adb905512a45c500a67532b0a3reed@google.com    uint8_t     fGradFlags;
2311c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
2321c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com    struct Rec {
2331c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com        SkFixed     fPos;   // 0...1
2341c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com        uint32_t    fScale; // (1 << 24) / range
2351c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com    };
2361c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com    Rec*        fRecs;
2371c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
23844d83c1e81b0555efa94f78e2a53b862208cdd06commit-bot@chromium.org    void commonAsAGradient(GradientInfo*, bool flipGrad = false) const;
239d3b28e8847358460aeae745da44e474f6a7ab25dskia.committer@gmail.com
2408367b8cb7a6b2f163ee41365323cb219b7049b15reed    virtual bool onAsLuminanceColor(SkColor*) const SK_OVERRIDE;
2418367b8cb7a6b2f163ee41365323cb219b7049b15reed
24244d83c1e81b0555efa94f78e2a53b862208cdd06commit-bot@chromium.org    /*
24344d83c1e81b0555efa94f78e2a53b862208cdd06commit-bot@chromium.org     * Takes in pointers to gradient color and Rec info as colorSrc and recSrc respectively.
24444d83c1e81b0555efa94f78e2a53b862208cdd06commit-bot@chromium.org     * Count is the number of colors in the gradient
24544d83c1e81b0555efa94f78e2a53b862208cdd06commit-bot@chromium.org     * It will then flip all the color and rec information and return in their respective Dst
24644d83c1e81b0555efa94f78e2a53b862208cdd06commit-bot@chromium.org     * pointers. It is assumed that space has already been allocated for the Dst pointers.
24744d83c1e81b0555efa94f78e2a53b862208cdd06commit-bot@chromium.org     * The rec src and dst are only assumed to be valid if count > 2
24844d83c1e81b0555efa94f78e2a53b862208cdd06commit-bot@chromium.org     */
24944d83c1e81b0555efa94f78e2a53b862208cdd06commit-bot@chromium.org    static void FlipGradientColors(SkColor* colorDst, Rec* recDst,
25044d83c1e81b0555efa94f78e2a53b862208cdd06commit-bot@chromium.org                                   SkColor* colorSrc, Rec* recSrc,
25144d83c1e81b0555efa94f78e2a53b862208cdd06commit-bot@chromium.org                                   int count);
25244d83c1e81b0555efa94f78e2a53b862208cdd06commit-bot@chromium.org
25344d83c1e81b0555efa94f78e2a53b862208cdd06commit-bot@chromium.org    // V23_COMPATIBILITY_CODE
25444d83c1e81b0555efa94f78e2a53b862208cdd06commit-bot@chromium.org    // Used for 2-pt conical gradients since we sort start/end cirlces by radius
25544d83c1e81b0555efa94f78e2a53b862208cdd06commit-bot@chromium.org    // Assumes space has already been allocated for fOrigColors
25644d83c1e81b0555efa94f78e2a53b862208cdd06commit-bot@chromium.org    void flipGradientColors();
2571c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
2581c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.comprivate:
2591c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com    enum {
2601c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com        kColorStorageCount = 4, // more than this many colors, and we'll use sk_malloc for the space
2611c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
2629fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed        kStorageSize = kColorStorageCount * (sizeof(SkColor) + sizeof(SkScalar) + sizeof(Rec))
2631c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com    };
2641c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com    SkColor     fStorage[(kStorageSize + 3) >> 2];
26587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    SkColor*    fOrigColors; // original colors, before modulation by paint in context.
2669fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed    SkScalar*   fOrigPos;   // original positions
2671c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com    bool        fColorsAreOpaque;
2681c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
26987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    GradientShaderCache* refCache(U8CPU alpha) const;
27087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    mutable SkMutex                           fCacheMutex;
27187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    mutable SkAutoTUnref<GradientShaderCache> fCache;
2721c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
2731c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com    void initCommon();
2741c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
2751c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com    typedef SkShader INHERITED;
2761c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com};
2771c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
27855853db3cce9539746fe202519a534c85ecdf62creed@google.comstatic inline int init_dither_toggle(int x, int y) {
27960040292be58ac553298209fb2e0684a4cb17dccreed@google.com    x &= 1;
28060040292be58ac553298209fb2e0684a4cb17dccreed@google.com    y = (y & 1) << 1;
28160040292be58ac553298209fb2e0684a4cb17dccreed@google.com    return (x | y) * SkGradientShaderBase::kDitherStride32;
28255853db3cce9539746fe202519a534c85ecdf62creed@google.com}
28355853db3cce9539746fe202519a534c85ecdf62creed@google.com
28455853db3cce9539746fe202519a534c85ecdf62creed@google.comstatic inline int next_dither_toggle(int toggle) {
28555853db3cce9539746fe202519a534c85ecdf62creed@google.com    return toggle ^ SkGradientShaderBase::kDitherStride32;
28655853db3cce9539746fe202519a534c85ecdf62creed@google.com}
28755853db3cce9539746fe202519a534c85ecdf62creed@google.com
28855853db3cce9539746fe202519a534c85ecdf62creed@google.comstatic inline int init_dither_toggle16(int x, int y) {
28955853db3cce9539746fe202519a534c85ecdf62creed@google.com    return ((x ^ y) & 1) * SkGradientShaderBase::kDitherStride16;
29055853db3cce9539746fe202519a534c85ecdf62creed@google.com}
29155853db3cce9539746fe202519a534c85ecdf62creed@google.com
29255853db3cce9539746fe202519a534c85ecdf62creed@google.comstatic inline int next_dither_toggle16(int toggle) {
29355853db3cce9539746fe202519a534c85ecdf62creed@google.com    return toggle ^ SkGradientShaderBase::kDitherStride16;
29455853db3cce9539746fe202519a534c85ecdf62creed@google.com}
29555853db3cce9539746fe202519a534c85ecdf62creed@google.com
2961c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com///////////////////////////////////////////////////////////////////////////////
2971c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
298cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
299cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com
30077af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com#include "GrCoordTransform.h"
301b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "gl/GrGLProcessor.h"
302cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com
303b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass GrProcessorStage;
304b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass GrBackendProcessorFactory;
3051c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
3061c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com/*
307d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com * The interpretation of the texture matrix depends on the sample mode. The
3081c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com * texture matrix is applied both when the texture coordinates are explicit
3091c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com * and  when vertex positions are used as texture  coordinates. In the latter
310fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com * case the texture matrix is applied to the pre-view-matrix position
3111c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com * values.
3121c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com *
3131c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com * Normal SampleMode
3141c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com *  The post-matrix texture coordinates are in normalize space with (0,0) at
3151c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com *  the top-left and (1,1) at the bottom right.
3161c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com * RadialGradient
3171c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com *  The matrix specifies the radial gradient parameters.
3181c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com *  (0,0) in the post-matrix space is center of the radial gradient.
3191c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com * Radial2Gradient
3201c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com *   Matrix transforms to space where first circle is centered at the
321fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com *   origin. The second circle will be centered (x, 0) where x may be
322fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com *   0 and is provided by setRadial2Params. The post-matrix space is
3231c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com *   normalized such that 1 is the second radius - first radius.
3241c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com * SweepGradient
3251c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com *  The angle from the origin of texture coordinates in post-matrix space
3261c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com *  determines the gradient value.
3271c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com */
3281c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
329b3e50f23c57d058820701219e66b6bfb8e0681a4rileya@google.com class GrTextureStripAtlas;
330b3e50f23c57d058820701219e66b6bfb8e0681a4rileya@google.com
3311c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com// Base class for Gr gradient effects
332b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass GrGradientEffect : public GrFragmentProcessor {
3331c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.compublic:
3341c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
3351ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.com    GrGradientEffect(GrContext* ctx,
3361ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.com                     const SkGradientShaderBase& shader,
337d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com                     const SkMatrix& matrix,
3381ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.com                     SkShader::TileMode tileMode);
3391c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
3401c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com    virtual ~GrGradientEffect();
3411c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
342b3e50f23c57d058820701219e66b6bfb8e0681a4rileya@google.com    bool useAtlas() const { return SkToBool(-1 != fRow); }
34381712883419f76e25d2ffec38a9438284a45a48dbsalomon@google.com    SkScalar getYCoord() const { return fYCoord; };
344b3e50f23c57d058820701219e66b6bfb8e0681a4rileya@google.com
34568b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com    virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
3469a070f24f1450091dfe25cacec8bd375ec7a0e50skia.committer@gmail.com
347996402bddb4d886c38dee17341e5833500901933commit-bot@chromium.org    SkGradientShaderBase::GpuColorType getColorType() const { return fColorType; }
34882d1223aece4703bc9f3a3612cbabaa8c2f2809bbsalomon@google.com
34982d1223aece4703bc9f3a3612cbabaa8c2f2809bbsalomon@google.com    enum PremulType {
35082d1223aece4703bc9f3a3612cbabaa8c2f2809bbsalomon@google.com        kBeforeInterp_PremulType,
35182d1223aece4703bc9f3a3612cbabaa8c2f2809bbsalomon@google.com        kAfterInterp_PremulType,
35282d1223aece4703bc9f3a3612cbabaa8c2f2809bbsalomon@google.com    };
35382d1223aece4703bc9f3a3612cbabaa8c2f2809bbsalomon@google.com
35482d1223aece4703bc9f3a3612cbabaa8c2f2809bbsalomon@google.com    PremulType getPremulType() const { return fPremulType; }
35582d1223aece4703bc9f3a3612cbabaa8c2f2809bbsalomon@google.com
35682d1223aece4703bc9f3a3612cbabaa8c2f2809bbsalomon@google.com    const SkColor* getColors(int pos) const {
357996402bddb4d886c38dee17341e5833500901933commit-bot@chromium.org        SkASSERT(fColorType != SkGradientShaderBase::kTexture_GpuColorType);
35882d1223aece4703bc9f3a3612cbabaa8c2f2809bbsalomon@google.com        SkASSERT((pos-1) <= fColorType);
35982d1223aece4703bc9f3a3612cbabaa8c2f2809bbsalomon@google.com        return &fColors[pos];
36082d1223aece4703bc9f3a3612cbabaa8c2f2809bbsalomon@google.com    }
361371e105da5d9fdfff3b4242b37ff6fc09214c8c8bsalomon@google.com
362d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.comprotected:
3631c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
364d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com    /** Populates a pair of arrays with colors and stop info to construct a random gradient.
365d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com        The function decides whether stop values should be used or not. The return value indicates
366d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com        the number of colors, which will be capped by kMaxRandomGradientColors. colors should be
367d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com        sized to be at least kMaxRandomGradientColors. stops is a pointer to an array of at least
368d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com        size kMaxRandomGradientColors. It may be updated to NULL, indicating that NULL should be
369d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com        passed to the gradient factory rather than the array.
370d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com    */
371d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com    static const int kMaxRandomGradientColors = 4;
372e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org    static int RandomGradientParams(SkRandom* r,
373d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com                                    SkColor colors[kMaxRandomGradientColors],
374d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com                                    SkScalar** stops,
375d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com                                    SkShader::TileMode* tm);
376d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com
377b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
37868b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com
3795fd7d5c20a15094da3fb6dc1d59955fd8f3217d7commit-bot@chromium.org    const GrCoordTransform& getCoordTransform() const { return fCoordTransform; }
3805fd7d5c20a15094da3fb6dc1d59955fd8f3217d7commit-bot@chromium.org
381d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.comprivate:
38277af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com    static const GrCoordSet kCoordSet = kLocal_GrCoordSet;
38368b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com
38477af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com    GrCoordTransform fCoordTransform;
3856d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com    GrTextureAccess fTextureAccess;
38681712883419f76e25d2ffec38a9438284a45a48dbsalomon@google.com    SkScalar fYCoord;
387b3e50f23c57d058820701219e66b6bfb8e0681a4rileya@google.com    GrTextureStripAtlas* fAtlas;
388b3e50f23c57d058820701219e66b6bfb8e0681a4rileya@google.com    int fRow;
389371e105da5d9fdfff3b4242b37ff6fc09214c8c8bsalomon@google.com    bool fIsOpaque;
390996402bddb4d886c38dee17341e5833500901933commit-bot@chromium.org    SkGradientShaderBase::GpuColorType fColorType;
391996402bddb4d886c38dee17341e5833500901933commit-bot@chromium.org    SkColor fColors[3]; // More than 3 colors we use texture
39282d1223aece4703bc9f3a3612cbabaa8c2f2809bbsalomon@google.com    PremulType fPremulType; // This only changes behavior for two and three color special cases.
39382d1223aece4703bc9f3a3612cbabaa8c2f2809bbsalomon@google.com                            // It is already baked into to the table for texture gradients.
394b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    typedef GrFragmentProcessor INHERITED;
3951c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
3961c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com};
3971c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
3981c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com///////////////////////////////////////////////////////////////////////////////
3991c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
4008ea78d83dc4e8243c16eedf8100a3987c54123fabsalomon@google.com// Base class for GL gradient effects
401b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass GrGLGradientEffect : public GrGLFragmentProcessor {
4021c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.compublic:
403b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GrGLGradientEffect(const GrBackendProcessorFactory& factory);
4040707c29413a5a3cc1c2d14b8c65b3692af5c7411bsalomon@google.com    virtual ~GrGLGradientEffect();
4051c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
406b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
407b3e50f23c57d058820701219e66b6bfb8e0681a4rileya@google.com
408f78df33efc72167f94da1b0476c9a86ba18a5f2cbsalomon@google.comprotected:
40963e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    /**
41063e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon     * Subclasses must call this. It will return a key for the part of the shader code controlled
41163e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon     * by the base class. The subclasses must stick it in their key and then pass it to the below
41263e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon     * emit* functions from their emitCode function.
41363e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon     */
414b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    static uint32_t GenBaseGradientKey(const GrProcessor&);
41563e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon
41663e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    // Emits the uniform used as the y-coord to texture samples in derived classes. Subclasses
41763e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    // should call this method from their emitCode().
41830ba436f04e61d4505fb854d5fc56079636e0788joshualitt    void emitUniforms(GrGLProgramBuilder* builder, uint32_t baseKey);
41963e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon
42063e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon
42163e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    // emit code that gets a fragment's color from an expression for t; Has branches for 3 separate
42263e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    // control flows inside -- 2 color gradients, 3 color symmetric gradients (both using
42363e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    // native GLSL mix), and 4+ color gradients that use the traditional texture lookup.
42430ba436f04e61d4505fb854d5fc56079636e0788joshualitt    void emitColor(GrGLProgramBuilder* builder,
42563e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon                   const char* gradientTValue,
42663e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon                   uint32_t baseKey,
42763e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon                   const char* outputColor,
42863e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon                   const char* inputColor,
42963e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon                   const TextureSamplerArray& samplers);
43063e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon
43163e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomonprivate:
432d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com    enum {
43382d1223aece4703bc9f3a3612cbabaa8c2f2809bbsalomon@google.com        kPremulTypeKeyBitCnt = 1,
43477af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com        kPremulTypeMask = 1,
43582d1223aece4703bc9f3a3612cbabaa8c2f2809bbsalomon@google.com        kPremulBeforeInterpKey = kPremulTypeMask,
43682d1223aece4703bc9f3a3612cbabaa8c2f2809bbsalomon@google.com
43777af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com        kTwoColorKey = 2 << kPremulTypeKeyBitCnt,
43877af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com        kThreeColorKey = 3 << kPremulTypeKeyBitCnt,
43982d1223aece4703bc9f3a3612cbabaa8c2f2809bbsalomon@google.com        kColorKeyMask = kTwoColorKey | kThreeColorKey,
44082d1223aece4703bc9f3a3612cbabaa8c2f2809bbsalomon@google.com        kColorKeyBitCnt = 2,
44182d1223aece4703bc9f3a3612cbabaa8c2f2809bbsalomon@google.com
44282d1223aece4703bc9f3a3612cbabaa8c2f2809bbsalomon@google.com        // Subclasses must shift any key bits they produce up by this amount
44382d1223aece4703bc9f3a3612cbabaa8c2f2809bbsalomon@google.com        // and combine with the result of GenBaseGradientKey.
44477af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com        kBaseKeyBitCnt = (kPremulTypeKeyBitCnt + kColorKeyBitCnt)
445d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com    };
44663e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    GR_STATIC_ASSERT(kBaseKeyBitCnt <= 32);
447d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com
44863e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    static SkGradientShaderBase::GpuColorType ColorTypeFromKey(uint32_t baseKey){
44963e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon        if (kTwoColorKey == (baseKey & kColorKeyMask)) {
450996402bddb4d886c38dee17341e5833500901933commit-bot@chromium.org            return SkGradientShaderBase::kTwo_GpuColorType;
45163e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon        } else if (kThreeColorKey == (baseKey & kColorKeyMask)) {
452996402bddb4d886c38dee17341e5833500901933commit-bot@chromium.org            return SkGradientShaderBase::kThree_GpuColorType;
453996402bddb4d886c38dee17341e5833500901933commit-bot@chromium.org        } else {return SkGradientShaderBase::kTexture_GpuColorType;}
45482d1223aece4703bc9f3a3612cbabaa8c2f2809bbsalomon@google.com    }
45582d1223aece4703bc9f3a3612cbabaa8c2f2809bbsalomon@google.com
45663e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    static GrGradientEffect::PremulType PremulTypeFromKey(uint32_t baseKey){
45763e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon        if (kPremulBeforeInterpKey == (baseKey & kPremulTypeMask)) {
45882d1223aece4703bc9f3a3612cbabaa8c2f2809bbsalomon@google.com            return GrGradientEffect::kBeforeInterp_PremulType;
45982d1223aece4703bc9f3a3612cbabaa8c2f2809bbsalomon@google.com        } else {
46082d1223aece4703bc9f3a3612cbabaa8c2f2809bbsalomon@google.com            return GrGradientEffect::kAfterInterp_PremulType;
46182d1223aece4703bc9f3a3612cbabaa8c2f2809bbsalomon@google.com        }
46282d1223aece4703bc9f3a3612cbabaa8c2f2809bbsalomon@google.com    }
46382d1223aece4703bc9f3a3612cbabaa8c2f2809bbsalomon@google.com
46481712883419f76e25d2ffec38a9438284a45a48dbsalomon@google.com    SkScalar fCachedYCoord;
4657510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen    GrGLProgramDataManager::UniformHandle fFSYUni;
4667510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen    GrGLProgramDataManager::UniformHandle fColorStartUni;
4677510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen    GrGLProgramDataManager::UniformHandle fColorMidUni;
4687510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen    GrGLProgramDataManager::UniformHandle fColorEndUni;
469b3e50f23c57d058820701219e66b6bfb8e0681a4rileya@google.com
470b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    typedef GrGLFragmentProcessor INHERITED;
4711c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com};
4721c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
4731c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com#endif
4741c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com
475cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
476