/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkGradientShaderPriv_DEFINED
#define SkGradientShaderPriv_DEFINED

#include "SkGradientBitmapCache.h"
#include "SkGradientShader.h"
#include "SkClampRange.h"
#include "SkColorPriv.h"
#include "SkColorSpace.h"
#include "SkReadBuffer.h"
#include "SkWriteBuffer.h"
#include "SkMallocPixelRef.h"
#include "SkUtils.h"
#include "SkShader.h"
#include "SkOnce.h"

#if SK_SUPPORT_GPU
    #define GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS 1
#endif

static inline void sk_memset32_dither(uint32_t dst[], uint32_t v0, uint32_t v1,
                               int count) {
    if (count > 0) {
        if (v0 == v1) {
            sk_memset32(dst, v0, count);
        } else {
            int pairs = count >> 1;
            for (int i = 0; i < pairs; i++) {
                *dst++ = v0;
                *dst++ = v1;
            }
            if (count & 1) {
                *dst = v0;
            }
        }
    }
}

//  Clamp

static inline SkFixed clamp_tileproc(SkFixed x) {
    return SkClampMax(x, 0xFFFF);
}

// Repeat

static inline SkFixed repeat_tileproc(SkFixed x) {
    return x & 0xFFFF;
}

// Mirror

static inline SkFixed mirror_tileproc(SkFixed x) {
    int s = SkLeftShift(x, 15) >> 31;
    return (x ^ s) & 0xFFFF;
}

///////////////////////////////////////////////////////////////////////////////

typedef SkFixed (*TileProc)(SkFixed);

///////////////////////////////////////////////////////////////////////////////

static const TileProc gTileProcs[] = {
    clamp_tileproc,
    repeat_tileproc,
    mirror_tileproc
};

///////////////////////////////////////////////////////////////////////////////

class SkGradientShaderBase : public SkShader {
public:
    struct Descriptor {
        Descriptor() {
            sk_bzero(this, sizeof(*this));
            fTileMode = SkShader::kClamp_TileMode;
        }

        const SkMatrix*     fLocalMatrix;
        const SkColor4f*    fColors;
        sk_sp<SkColorSpace> fColorSpace;
        const SkScalar*     fPos;
        int                 fCount;
        SkShader::TileMode  fTileMode;
        uint32_t            fGradFlags;

        void flatten(SkWriteBuffer&) const;
    };

    class DescriptorScope : public Descriptor {
    public:
        DescriptorScope() {}

        bool unflatten(SkReadBuffer&);

        // fColors and fPos always point into local memory, so they can be safely mutated
        //
        SkColor4f* mutableColors() { return const_cast<SkColor4f*>(fColors); }
        SkScalar* mutablePos() { return const_cast<SkScalar*>(fPos); }

    private:
        enum {
            kStorageCount = 16
        };
        SkColor4f fColorStorage[kStorageCount];
        SkScalar fPosStorage[kStorageCount];
        SkMatrix fLocalMatrixStorage;
        SkAutoMalloc fDynamicStorage;
    };

    SkGradientShaderBase(const Descriptor& desc, const SkMatrix& ptsToUnit);
    virtual ~SkGradientShaderBase();

    // The cache is initialized on-demand when getCache32 is called.
    class GradientShaderCache : public SkRefCnt {
    public:
        GradientShaderCache(U8CPU alpha, bool dither, const SkGradientShaderBase& shader);
        ~GradientShaderCache();

        const SkPMColor*    getCache32();

        SkMallocPixelRef* getCache32PixelRef() const { return fCache32PixelRef; }

        unsigned getAlpha() const { return fCacheAlpha; }
        bool getDither() const { return fCacheDither; }

    private:
        // Working pointer. If it's nullptr, we need to recompute the cache values.
        SkPMColor*  fCache32;

        SkMallocPixelRef* fCache32PixelRef;
        const unsigned    fCacheAlpha;        // The alpha value we used when we computed the cache.
                                              // Larger than 8bits so we can store uninitialized
                                              // value.
        const bool        fCacheDither;       // The dither flag used when we computed the cache.

        const SkGradientShaderBase& fShader;

        // Make sure we only initialize the cache once.
        SkOnce fCache32InitOnce;

        static void initCache32(GradientShaderCache* cache);

        static void Build32bitCache(SkPMColor[], SkColor c0, SkColor c1, int count,
                                    U8CPU alpha, uint32_t gradFlags, bool dither);
    };

    class GradientShaderBaseContext : public SkShader::Context {
    public:
        GradientShaderBaseContext(const SkGradientShaderBase& shader, const ContextRec&);

        uint32_t getFlags() const override { return fFlags; }

        bool isValid() const;

    protected:
        SkMatrix    fDstToIndex;
        SkMatrix::MapXYProc fDstToIndexProc;
        uint8_t     fDstToIndexClass;
        uint8_t     fFlags;
        bool        fDither;

        sk_sp<GradientShaderCache> fCache;

    private:
        typedef SkShader::Context INHERITED;
    };

    bool isOpaque() const override;

    enum class GradientBitmapType : uint8_t {
        kLegacy,
        kSRGB,
        kHalfFloat,
    };

    void getGradientTableBitmap(SkBitmap*, GradientBitmapType bitmapType) const;

    enum {
        /// Seems like enough for visual accuracy. TODO: if pos[] deserves
        /// it, use a larger cache.
        kCache32Bits    = 8,
        kCache32Count   = (1 << kCache32Bits),
        kCache32Shift   = 16 - kCache32Bits,
        kSqrt32Shift    = 8 - kCache32Bits,

        /// This value is used to *read* the dither cache; it may be 0
        /// if dithering is disabled.
        kDitherStride32 = kCache32Count,
    };

    uint32_t getGradFlags() const { return fGradFlags; }

protected:
    class GradientShaderBase4fContext;

    SkGradientShaderBase(SkReadBuffer& );
    void flatten(SkWriteBuffer&) const override;
    SK_TO_STRING_OVERRIDE()

    const SkMatrix fPtsToUnit;
    TileMode    fTileMode;
    TileProc    fTileProc;
    uint8_t     fGradFlags;

    struct Rec {
        SkFixed     fPos;   // 0...1
        uint32_t    fScale; // (1 << 24) / range
    };
    Rec*        fRecs;

    void commonAsAGradient(GradientInfo*, bool flipGrad = false) const;

    bool onAsLuminanceColor(SkColor*) const override;


    void initLinearBitmap(SkBitmap* bitmap) const;

    /*
     * Takes in pointers to gradient color and Rec info as colorSrc and recSrc respectively.
     * Count is the number of colors in the gradient
     * It will then flip all the color and rec information and return in their respective Dst
     * pointers. It is assumed that space has already been allocated for the Dst pointers.
     * The rec src and dst are only assumed to be valid if count > 2
     */
    static void FlipGradientColors(SkColor* colorDst, Rec* recDst,
                                   SkColor* colorSrc, Rec* recSrc,
                                   int count);

    template <typename T, typename... Args>
    static Context* CheckedCreateContext(void* storage, Args&&... args) {
        auto* ctx = new (storage) T(std::forward<Args>(args)...);
        if (!ctx->isValid()) {
            ctx->~T();
            return nullptr;
        }
        return ctx;
    }

private:
    enum {
        kColorStorageCount = 4, // more than this many colors, and we'll use sk_malloc for the space

        kStorageSize = kColorStorageCount *
                       (sizeof(SkColor) + sizeof(SkScalar) + sizeof(Rec) + sizeof(SkColor4f))
    };
    SkColor             fStorage[(kStorageSize + 3) >> 2];
public:
    SkColor*            fOrigColors;   // original colors, before modulation by paint in context.
    SkColor4f*          fOrigColors4f; // original colors, as linear floats
    SkScalar*           fOrigPos;      // original positions
    int                 fColorCount;
    sk_sp<SkColorSpace> fColorSpace; // color space of gradient stops

    bool colorsAreOpaque() const { return fColorsAreOpaque; }

    TileMode getTileMode() const { return fTileMode; }
    Rec* getRecs() const { return fRecs; }

private:
    bool                fColorsAreOpaque;

    sk_sp<GradientShaderCache> refCache(U8CPU alpha, bool dither) const;
    mutable SkMutex                    fCacheMutex;
    mutable sk_sp<GradientShaderCache> fCache;

    void initCommon();

    typedef SkShader INHERITED;
};

static inline int init_dither_toggle(int x, int y) {
    x &= 1;
    y = (y & 1) << 1;
    return (x | y) * SkGradientShaderBase::kDitherStride32;
}

static inline int next_dither_toggle(int toggle) {
    return toggle ^ SkGradientShaderBase::kDitherStride32;
}

///////////////////////////////////////////////////////////////////////////////

#if SK_SUPPORT_GPU

#include "GrColorSpaceXform.h"
#include "GrCoordTransform.h"
#include "GrFragmentProcessor.h"
#include "glsl/GrGLSLFragmentProcessor.h"
#include "glsl/GrGLSLProgramDataManager.h"

class GrInvariantOutput;

/*
 * The interpretation of the texture matrix depends on the sample mode. The
 * texture matrix is applied both when the texture coordinates are explicit
 * and  when vertex positions are used as texture  coordinates. In the latter
 * case the texture matrix is applied to the pre-view-matrix position
 * values.
 *
 * Normal SampleMode
 *  The post-matrix texture coordinates are in normalize space with (0,0) at
 *  the top-left and (1,1) at the bottom right.
 * RadialGradient
 *  The matrix specifies the radial gradient parameters.
 *  (0,0) in the post-matrix space is center of the radial gradient.
 * Radial2Gradient
 *   Matrix transforms to space where first circle is centered at the
 *   origin. The second circle will be centered (x, 0) where x may be
 *   0 and is provided by setRadial2Params. The post-matrix space is
 *   normalized such that 1 is the second radius - first radius.
 * SweepGradient
 *  The angle from the origin of texture coordinates in post-matrix space
 *  determines the gradient value.
 */

 class GrTextureStripAtlas;

// Base class for Gr gradient effects
class GrGradientEffect : public GrFragmentProcessor {
public:
    struct CreateArgs {
        CreateArgs(GrContext* context,
                   const SkGradientShaderBase* shader,
                   const SkMatrix* matrix,
                   SkShader::TileMode tileMode,
                   sk_sp<GrColorSpaceXform> colorSpaceXform,
                   bool gammaCorrect)
            : fContext(context)
            , fShader(shader)
            , fMatrix(matrix)
            , fTileMode(tileMode)
            , fColorSpaceXform(std::move(colorSpaceXform))
            , fGammaCorrect(gammaCorrect) {}

        GrContext*                  fContext;
        const SkGradientShaderBase* fShader;
        const SkMatrix*             fMatrix;
        SkShader::TileMode          fTileMode;
        sk_sp<GrColorSpaceXform>    fColorSpaceXform;
        bool                        fGammaCorrect;
    };

    class GLSLProcessor;

    GrGradientEffect(const CreateArgs&);

    virtual ~GrGradientEffect();

    bool useAtlas() const { return SkToBool(-1 != fRow); }
    SkScalar getYCoord() const { return fYCoord; }

    enum ColorType {
        kTwo_ColorType,
        kThree_ColorType, // Symmetric three color
        kTexture_ColorType,

#if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS
        kSingleHardStop_ColorType,     // 0, t, t, 1
        kHardStopLeftEdged_ColorType,  // 0, 0, 1
        kHardStopRightEdged_ColorType, // 0, 1, 1
#endif
    };

    ColorType getColorType() const { return fColorType; }

    // Determines the type of gradient, one of:
    //    - Two-color
    //    - Symmetric three-color
    //    - Texture
    //    - Centered hard stop
    //    - Left-edged hard stop
    //    - Right-edged hard stop
    ColorType determineColorType(const SkGradientShaderBase& shader);

    enum PremulType {
        kBeforeInterp_PremulType,
        kAfterInterp_PremulType,
    };

    PremulType getPremulType() const { return fPremulType; }

    const SkColor* getColors(int pos) const {
        SkASSERT(fColorType != kTexture_ColorType);
        SkASSERT(pos < fColors.count());
        return &fColors[pos];
    }

    const SkColor4f* getColors4f(int pos) const {
        SkASSERT(fColorType != kTexture_ColorType);
        SkASSERT(pos < fColors4f.count());
        return &fColors4f[pos];
    }

protected:
    /** Helper struct that stores (and populates) parameters to construct a random gradient.
        If fUseColors4f is true, then the SkColor4f factory should be called, with fColors4f and
        fColorSpace. Otherwise, the SkColor factory should be called, with fColors. fColorCount
        will be the number of color stops in either case, and fColors and fStops can be passed to
        the gradient factory. (The constructor may decide not to use stops, in which case fStops
        will be nullptr). */
    struct RandomGradientParams {
        static const int kMaxRandomGradientColors = 4;

        RandomGradientParams(SkRandom* r);

        bool fUseColors4f;
        SkColor fColors[kMaxRandomGradientColors];
        SkColor4f fColors4f[kMaxRandomGradientColors];
        sk_sp<SkColorSpace> fColorSpace;
        SkScalar fStopStorage[kMaxRandomGradientColors];
        SkShader::TileMode fTileMode;
        int fColorCount;
        SkScalar* fStops;
    };

    bool onIsEqual(const GrFragmentProcessor&) const override;

    void onComputeInvariantOutput(GrInvariantOutput* inout) const override;

    const GrCoordTransform& getCoordTransform() const { return fCoordTransform; }

private:
    // If we're in legacy mode, then fColors will be populated. If we're gamma-correct, then
    // fColors4f and fColorSpaceXform will be populated.
    SkTDArray<SkColor>       fColors;

    SkTDArray<SkColor4f>     fColors4f;
    sk_sp<GrColorSpaceXform> fColorSpaceXform;

    SkTDArray<SkScalar>      fPositions;
    SkShader::TileMode       fTileMode;

    GrCoordTransform fCoordTransform;
    TextureSampler fTextureSampler;
    SkScalar fYCoord;
    GrTextureStripAtlas* fAtlas;
    int fRow;
    bool fIsOpaque;
    ColorType fColorType;
    PremulType fPremulType; // This is already baked into the table for texture gradients, and
                            // only changes behavior for gradients that don't use a texture.
    typedef GrFragmentProcessor INHERITED;

};

///////////////////////////////////////////////////////////////////////////////

// Base class for GL gradient effects
class GrGradientEffect::GLSLProcessor : public GrGLSLFragmentProcessor {
public:
    GLSLProcessor() {
        fCachedYCoord = SK_ScalarMax;
    }

protected:
    void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override;

protected:
    /**
     * Subclasses must call this. It will return a key for the part of the shader code controlled
     * by the base class. The subclasses must stick it in their key and then pass it to the below
     * emit* functions from their emitCode function.
     */
    static uint32_t GenBaseGradientKey(const GrProcessor&);

    // Emits the uniform used as the y-coord to texture samples in derived classes. Subclasses
    // should call this method from their emitCode().
    void emitUniforms(GrGLSLUniformHandler*, const GrGradientEffect&);

    // Emit code that gets a fragment's color from an expression for t; has branches for
    // several control flows inside -- 2-color gradients, 3-color symmetric gradients, 4+
    // color gradients that use the traditional texture lookup, as well as several varieties
    // of hard stop gradients
    void emitColor(GrGLSLFPFragmentBuilder* fragBuilder,
                   GrGLSLUniformHandler* uniformHandler,
                   const GrGLSLCaps* caps,
                   const GrGradientEffect&,
                   const char* gradientTValue,
                   const char* outputColor,
                   const char* inputColor,
                   const TextureSamplers&);

private:
    enum {
        // First bit for premul before/after interp
        kPremulBeforeInterpKey  =  1,

        // Next three bits for 2/3 color type or different special
        // hard stop cases (neither means using texture atlas)
        kTwoColorKey            =  2,
        kThreeColorKey          =  4,
#if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS
        kHardStopCenteredKey    =  6,
        kHardStopZeroZeroOneKey =  8,
        kHardStopZeroOneOneKey  = 10,

        // Next two bits for tile mode
        kClampTileMode          = 16,
        kRepeatTileMode         = 32,
        kMirrorTileMode         = 48,

        // Lower six bits for premul, 2/3 color type, and tile mode
        kReservedBits           = 6,
#endif
    };

    SkScalar fCachedYCoord;
    GrGLSLProgramDataManager::UniformHandle fColorsUni;
    GrGLSLProgramDataManager::UniformHandle fHardStopT;
    GrGLSLProgramDataManager::UniformHandle fFSYUni;
    GrGLSLProgramDataManager::UniformHandle fColorSpaceXformUni;

    typedef GrGLSLFragmentProcessor INHERITED;
};

#endif

#endif
