/*
 * 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 "SkGradientShader.h"

#include "SkArenaAlloc.h"
#include "SkMatrix.h"
#include "SkShaderBase.h"
#include "SkTArray.h"
#include "SkTemplates.h"

class SkColorSpace;
class SkColorSpaceXformer;
class SkRasterPipeline;
class SkReadBuffer;
class SkWriteBuffer;

class SkGradientShaderBase : public SkShaderBase {
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:
        SkSTArray<16, SkColor4f, true> fColorStorage;
        SkSTArray<16, SkScalar , true> fPosStorage;
        SkMatrix                       fLocalMatrixStorage;
    };

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

    bool isOpaque() const override;

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

    void getGradientTableBitmap(SkBitmap*, GradientBitmapType bitmapType) const;

    uint32_t getGradFlags() const { return fGradFlags; }

    SkColor4f getXformedColor(size_t index, SkColorSpace*) const;

protected:
    class GradientShaderBase4fContext;

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

    void commonAsAGradient(GradientInfo*) const;

    bool onAsLuminanceColor(SkColor*) const override;

    void initLinearBitmap(SkBitmap* bitmap, GradientBitmapType) const;

    bool onAppendStages(const StageRec&) const override;

    virtual void appendGradientStages(SkArenaAlloc* alloc, SkRasterPipeline* tPipeline,
                                      SkRasterPipeline* postPipeline) const = 0;

    template <typename T, typename... Args>
    static Context* CheckedMakeContext(SkArenaAlloc* alloc, Args&&... args) {
        auto* ctx = alloc->make<T>(std::forward<Args>(args)...);
        if (!ctx->isValid()) {
            return nullptr;
        }
        return ctx;
    }

    struct AutoXformColors {
        AutoXformColors(const SkGradientShaderBase&, SkColorSpaceXformer*);

        SkAutoSTMalloc<8, SkColor> fColors;
    };

    const SkMatrix fPtsToUnit;
    TileMode       fTileMode;
    uint8_t        fGradFlags;

public:
    SkScalar getPos(int i) const {
        SkASSERT(i < fColorCount);
        return fOrigPos ? fOrigPos[i] : SkIntToScalar(i) / (fColorCount - 1);
    }

    SkColor getLegacyColor(int i) const {
        SkASSERT(i < fColorCount);
        return fOrigColors4f[i].toSkColor();
    }

    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; }

private:
    // Reserve inline space for up to 4 stops.
    static constexpr size_t kInlineStopCount   = 4;
    static constexpr size_t kInlineStorageSize = (sizeof(SkColor4f) + sizeof(SkScalar))
                                               * kInlineStopCount;
    SkAutoSTMalloc<kInlineStorageSize, uint8_t> fStorage;

    bool                                        fColorsAreOpaque;

    typedef SkShaderBase INHERITED;
};

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

#if SK_SUPPORT_GPU

#include "GrColorSpaceInfo.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,
                   SkColorSpace* dstColorSpace)
                : fContext(context)
                , fShader(shader)
                , fMatrix(matrix)
                , fDstColorSpace(dstColorSpace) {
            switch (tileMode) {
                case SkShader::kClamp_TileMode:
                    fWrapMode = GrSamplerState::WrapMode::kClamp;
                    break;
                case SkShader::kRepeat_TileMode:
                    fWrapMode = GrSamplerState::WrapMode::kRepeat;
                    break;
                case SkShader::kMirror_TileMode:
                    fWrapMode = GrSamplerState::WrapMode::kMirrorRepeat;
                    break;
                case SkShader::kDecal_TileMode:
                    // TODO: actually support decal
                    fWrapMode = GrSamplerState::WrapMode::kClamp;
                    break;
            }
        }

        CreateArgs(GrContext* context,
                   const SkGradientShaderBase* shader,
                   const SkMatrix* matrix,
                   GrSamplerState::WrapMode wrapMode,
                   SkColorSpace* dstColorSpace)
                : fContext(context)
                , fShader(shader)
                , fMatrix(matrix)
                , fWrapMode(wrapMode)
                , fDstColorSpace(dstColorSpace) {}

        GrContext*                  fContext;
        const SkGradientShaderBase* fShader;
        const SkMatrix*             fMatrix;
        GrSamplerState::WrapMode    fWrapMode;
        SkColorSpace*               fDstColorSpace;
    };

    class GLSLProcessor;

    ~GrGradientEffect() override;

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

    // Controls the implementation strategy for this effect.
    // NB: all entries need to be reflected in the key.
    enum class InterpolationStrategy : uint8_t {
        kSingle,          // interpolation in a single domain [0,1]
        kThreshold,       // interpolation in two domains [0,T) [T,1], with normal clamping
        kThresholdClamp0, // same as kThreshold, but clamped only on the left edge
        kThresholdClamp1, // same as kThreshold, but clamped only on the right edge
        kTexture,         // texture-based fallback
    };

    enum PremulType {
        kBeforeInterp_PremulType,
        kAfterInterp_PremulType,
    };

protected:
    GrGradientEffect(ClassID classID, const CreateArgs&, bool isOpaque);
    explicit GrGradientEffect(const GrGradientEffect&);  // facilitates clone() implementations

    void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;

    // Helper function used by derived class factories to handle color space transformation and
    // modulation by input alpha.
    static std::unique_ptr<GrFragmentProcessor> AdjustFP(
            std::unique_ptr<GrGradientEffect> gradientFP, const CreateArgs& args) {
        if (!gradientFP->isValid()) {
            return nullptr;
        }
        std::unique_ptr<GrFragmentProcessor> fp;
        // With analytic gradients, we pre-convert the stops to the destination color space, so no
        // xform is needed. With texture-based gradients, we leave the data in the source color
        // space (to avoid clamping if we can't use F16)... Add an extra FP to do the xform.
        if (gradientFP->fStrategy == InterpolationStrategy::kTexture) {
            // Our texture is always either F16 or sRGB, so the data is "linear" in the shader.
            // Create our xform assuming float inputs, which will suppress any extra sRGB work.
            // We do support having a transfer function on the color space of the stops, so
            // this FP may include that transformation.
            fp = GrColorSpaceXformEffect::Make(std::move(gradientFP),
                                               args.fShader->fColorSpace.get(),
                                               args.fDstColorSpace);
        } else {
            fp = std::move(gradientFP);
        }
        return GrFragmentProcessor::MulChildByInputAlpha(std::move(fp));
    }

#if GR_TEST_UTILS
    /** 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 constexpr int kMaxRandomGradientColors = 5;

        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;
    };
    #endif

    bool onIsEqual(const GrFragmentProcessor&) const override;

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

    /** Checks whether the constructor failed to fully initialize the processor. */
    bool isValid() const {
        return fStrategy != InterpolationStrategy::kTexture || fTextureSampler.isInitialized();
    }

private:
    void addInterval(const SkGradientShaderBase&, size_t idx0, size_t idx1, SkColorSpace*);

    static OptimizationFlags OptFlags(bool isOpaque);

    // Interpolation intervals, encoded as 4f tuples of (scale, bias)
    // such that color(t) = t * scale + bias.
    SkSTArray<4, GrColor4f, true> fIntervals;

    GrSamplerState::WrapMode fWrapMode;

    GrCoordTransform fCoordTransform;
    TextureSampler fTextureSampler;
    SkScalar fYCoord;
    sk_sp<GrTextureStripAtlas> fAtlas;
    int fRow;
    bool fIsOpaque;

    InterpolationStrategy fStrategy;
    SkScalar              fThreshold;  // used for InterpolationStrategy::kThreshold
    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;
    }

    static uint32_t GenBaseGradientKey(const GrProcessor&);

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

    // 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 GrShaderCaps* shaderCaps,
                   const GrGradientEffect&,
                   const char* gradientTValue,
                   const char* outputColor,
                   const char* inputColor,
                   const TextureSamplers&);

private:
    void emitAnalyticalColor(GrGLSLFPFragmentBuilder* fragBuilder,
                             GrGLSLUniformHandler* uniformHandler,
                             const GrShaderCaps* shaderCaps,
                             const GrGradientEffect&,
                             const char* gradientTValue,
                             const char* outputColor,
                             const char* inputColor);

    SkScalar fCachedYCoord;
    GrGLSLProgramDataManager::UniformHandle fIntervalsUni;
    GrGLSLProgramDataManager::UniformHandle fThresholdUni;
    GrGLSLProgramDataManager::UniformHandle fFSYUni;

    typedef GrGLSLFragmentProcessor INHERITED;
};

#endif

#endif
