/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ANDROID_HWUI_SKIA_SHADER_H
#define ANDROID_HWUI_SKIA_SHADER_H

#include <SkShader.h>
#include <SkXfermode.h>

#include <GLES2/gl2.h>

#include "Extensions.h"
#include "ProgramCache.h"
#include "TextureCache.h"
#include "GradientCache.h"
#include "Snapshot.h"

namespace android {
namespace uirenderer {

///////////////////////////////////////////////////////////////////////////////
// Base shader
///////////////////////////////////////////////////////////////////////////////

/**
 * Represents a Skia shader. A shader will modify the GL context and active
 * program to recreate the original effect.
 */
struct SkiaShader {
    /**
     * Type of Skia shader in use.
     */
    enum Type {
        kNone,
        kBitmap,
        kLinearGradient,
        kCircularGradient,
        kSweepGradient,
        kCompose
    };

    SkiaShader(Type type, SkShader* key, SkShader::TileMode tileX, SkShader::TileMode tileY,
            SkMatrix* matrix, bool blend);
    virtual ~SkiaShader();

    virtual SkiaShader* copy() = 0;
    void copyFrom(const SkiaShader& shader);

    virtual void describe(ProgramDescription& description, const Extensions& extensions);
    virtual void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
            GLuint* textureUnit);

    inline SkShader *getSkShader() {
        return mKey;
    }

    inline bool blend() const {
        return mBlend;
    }

    Type type() const {
        return mType;
    }

    virtual void set(TextureCache* textureCache, GradientCache* gradientCache) {
        mTextureCache = textureCache;
        mGradientCache = gradientCache;
    }

    virtual void updateTransforms(Program* program, const mat4& modelView,
            const Snapshot& snapshot) {
    }

    uint32_t getGenerationId() {
        return mGenerationId;
    }

    void setMatrix(SkMatrix* matrix) {
        updateLocalMatrix(matrix);
        mGenerationId++;
    }

    void updateLocalMatrix(const SkMatrix* matrix) {
        if (matrix) {
            mat4 localMatrix(*matrix);
            mShaderMatrix.loadInverse(localMatrix);
        } else {
            mShaderMatrix.loadIdentity();
        }
    }

    void computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView);

protected:
    SkiaShader() {
    }

    /**
     * The appropriate texture unit must have been activated prior to invoking
     * this method.
     */
    inline void bindTexture(Texture* texture, GLenum wrapS, GLenum wrapT);

    Type mType;
    SkShader* mKey;
    SkShader::TileMode mTileX;
    SkShader::TileMode mTileY;
    bool mBlend;

    TextureCache* mTextureCache;
    GradientCache* mGradientCache;

    mat4 mUnitMatrix;
    mat4 mShaderMatrix;

private:
    uint32_t mGenerationId;
}; // struct SkiaShader


///////////////////////////////////////////////////////////////////////////////
// Implementations
///////////////////////////////////////////////////////////////////////////////

/**
 * A shader that draws a bitmap.
 */
struct SkiaBitmapShader: public SkiaShader {
    SkiaBitmapShader(SkBitmap* bitmap, SkShader* key, SkShader::TileMode tileX,
            SkShader::TileMode tileY, SkMatrix* matrix, bool blend);
    SkiaShader* copy();

    void describe(ProgramDescription& description, const Extensions& extensions);
    void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
            GLuint* textureUnit);
    void updateTransforms(Program* program, const mat4& modelView, const Snapshot& snapshot);

private:
    SkiaBitmapShader() {
    }

    /**
     * This method does not work for n == 0.
     */
    inline bool isPowerOfTwo(unsigned int n) {
        return !(n & (n - 1));
    }

    SkBitmap* mBitmap;
    Texture* mTexture;
    GLenum mWrapS;
    GLenum mWrapT;
}; // struct SkiaBitmapShader

/**
 * A shader that draws a linear gradient.
 */
struct SkiaLinearGradientShader: public SkiaShader {
    SkiaLinearGradientShader(float* bounds, uint32_t* colors, float* positions, int count,
            SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend);
    ~SkiaLinearGradientShader();
    SkiaShader* copy();

    void describe(ProgramDescription& description, const Extensions& extensions);
    void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
            GLuint* textureUnit);
    void updateTransforms(Program* program, const mat4& modelView, const Snapshot& snapshot);

private:
    SkiaLinearGradientShader() {
    }

    float* mBounds;
    uint32_t* mColors;
    float* mPositions;
    int mCount;
}; // struct SkiaLinearGradientShader

/**
 * A shader that draws a sweep gradient.
 */
struct SkiaSweepGradientShader: public SkiaShader {
    SkiaSweepGradientShader(float x, float y, uint32_t* colors, float* positions, int count,
            SkShader* key, SkMatrix* matrix, bool blend);
    ~SkiaSweepGradientShader();
    SkiaShader* copy();

    virtual void describe(ProgramDescription& description, const Extensions& extensions);
    void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
            GLuint* textureUnit);
    void updateTransforms(Program* program, const mat4& modelView, const Snapshot& snapshot);

protected:
    SkiaSweepGradientShader(Type type, float x, float y, uint32_t* colors, float* positions,
            int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend);
    SkiaSweepGradientShader() {
    }

    uint32_t* mColors;
    float* mPositions;
    int mCount;
}; // struct SkiaSweepGradientShader

/**
 * A shader that draws a circular gradient.
 */
struct SkiaCircularGradientShader: public SkiaSweepGradientShader {
    SkiaCircularGradientShader(float x, float y, float radius, uint32_t* colors, float* positions,
            int count, SkShader* key,SkShader::TileMode tileMode, SkMatrix* matrix, bool blend);
    SkiaShader* copy();

    void describe(ProgramDescription& description, const Extensions& extensions);

private:
    SkiaCircularGradientShader() {
    }
}; // struct SkiaCircularGradientShader

/**
 * A shader that draws two shaders, composited with an xfermode.
 */
struct SkiaComposeShader: public SkiaShader {
    SkiaComposeShader(SkiaShader* first, SkiaShader* second, SkXfermode::Mode mode, SkShader* key);
    ~SkiaComposeShader();
    SkiaShader* copy();

    void set(TextureCache* textureCache, GradientCache* gradientCache);

    void describe(ProgramDescription& description, const Extensions& extensions);
    void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
            GLuint* textureUnit);

private:
    SkiaComposeShader(): mCleanup(false) {
    }

    void cleanup() {
        mCleanup = true;
    }

    SkiaShader* mFirst;
    SkiaShader* mSecond;
    SkXfermode::Mode mMode;

    bool mCleanup;
}; // struct SkiaComposeShader

}; // namespace uirenderer
}; // namespace android

#endif // ANDROID_HWUI_SKIA_SHADER_H
