/*
 * Copyright (C) 2015 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.
 */
#include "GlopBuilder.h"

#include "Caches.h"
#include "Glop.h"
#include "Matrix.h"
#include "Patch.h"
#include "renderstate/MeshState.h"
#include "renderstate/RenderState.h"
#include "SkiaShader.h"
#include "Texture.h"
#include "utils/PaintUtils.h"
#include "VertexBuffer.h"

#include <GLES2/gl2.h>
#include <SkPaint.h>

#define DEBUG_GLOP_BUILDER 0

#if DEBUG_GLOP_BUILDER

#define TRIGGER_STAGE(stageFlag) \
    LOG_ALWAYS_FATAL_IF((stageFlag) & mStageFlags, "Stage %d cannot be run twice", (stageFlag)); \
    mStageFlags = static_cast<StageFlags>(mStageFlags | (stageFlag))

#define REQUIRE_STAGES(requiredFlags) \
    LOG_ALWAYS_FATAL_IF((mStageFlags & (requiredFlags)) != (requiredFlags), \
            "not prepared for current stage")

#else

#define TRIGGER_STAGE(stageFlag) ((void)0)
#define REQUIRE_STAGES(requiredFlags) ((void)0)

#endif

namespace android {
namespace uirenderer {

static void setUnitQuadTextureCoords(Rect uvs, TextureVertex* quadVertex) {
    quadVertex[0] = {0, 0, uvs.left, uvs.top};
    quadVertex[1] = {1, 0, uvs.right, uvs.top};
    quadVertex[2] = {0, 1, uvs.left, uvs.bottom};
    quadVertex[3] = {1, 1, uvs.right, uvs.bottom};
}

GlopBuilder::GlopBuilder(RenderState& renderState, Caches& caches, Glop* outGlop)
        : mRenderState(renderState)
        , mCaches(caches)
        , mShader(nullptr)
        , mOutGlop(outGlop) {
    mStageFlags = kInitialStage;
}

////////////////////////////////////////////////////////////////////////////////
// Mesh
////////////////////////////////////////////////////////////////////////////////

GlopBuilder& GlopBuilder::setMeshTexturedIndexedVbo(GLuint vbo, GLsizei elementCount) {
    TRIGGER_STAGE(kMeshStage);

    mOutGlop->mesh.primitiveMode = GL_TRIANGLES;
    mOutGlop->mesh.indices = { mRenderState.meshState().getQuadListIBO(), nullptr };
    mOutGlop->mesh.vertices = {
            vbo,
            VertexAttribFlags::TextureCoord,
            nullptr, (const void*) kMeshTextureOffset, nullptr,
            kTextureVertexStride };
    mOutGlop->mesh.elementCount = elementCount;
    return *this;
}

GlopBuilder& GlopBuilder::setMeshUnitQuad() {
    TRIGGER_STAGE(kMeshStage);

    mOutGlop->mesh.primitiveMode = GL_TRIANGLE_STRIP;
    mOutGlop->mesh.indices = { 0, nullptr };
    mOutGlop->mesh.vertices = {
            mRenderState.meshState().getUnitQuadVBO(),
            VertexAttribFlags::None,
            nullptr, nullptr, nullptr,
            kTextureVertexStride };
    mOutGlop->mesh.elementCount = 4;
    return *this;
}

GlopBuilder& GlopBuilder::setMeshTexturedUnitQuad(const UvMapper* uvMapper) {
    if (uvMapper) {
        // can't use unit quad VBO, so build UV vertices manually
        return setMeshTexturedUvQuad(uvMapper, Rect(1, 1));
    }

    TRIGGER_STAGE(kMeshStage);

    mOutGlop->mesh.primitiveMode = GL_TRIANGLE_STRIP;
    mOutGlop->mesh.indices = { 0, nullptr };
    mOutGlop->mesh.vertices = {
            mRenderState.meshState().getUnitQuadVBO(),
            VertexAttribFlags::TextureCoord,
            nullptr, (const void*) kMeshTextureOffset, nullptr,
            kTextureVertexStride };
    mOutGlop->mesh.elementCount = 4;
    return *this;
}

GlopBuilder& GlopBuilder::setMeshTexturedUvQuad(const UvMapper* uvMapper, Rect uvs) {
    TRIGGER_STAGE(kMeshStage);

    if (CC_UNLIKELY(uvMapper)) {
        uvMapper->map(uvs);
    }
    setUnitQuadTextureCoords(uvs, &mOutGlop->mesh.mappedVertices[0]);

    const TextureVertex* textureVertex = mOutGlop->mesh.mappedVertices;
    mOutGlop->mesh.primitiveMode = GL_TRIANGLE_STRIP;
    mOutGlop->mesh.indices = { 0, nullptr };
    mOutGlop->mesh.vertices = {
            0,
            VertexAttribFlags::TextureCoord,
            &textureVertex[0].x, &textureVertex[0].u, nullptr,
            kTextureVertexStride };
    mOutGlop->mesh.elementCount = 4;
    return *this;
}

GlopBuilder& GlopBuilder::setMeshIndexedQuads(Vertex* vertexData, int quadCount) {
    TRIGGER_STAGE(kMeshStage);

    mOutGlop->mesh.primitiveMode = GL_TRIANGLES;
    mOutGlop->mesh.indices = { mRenderState.meshState().getQuadListIBO(), nullptr };
    mOutGlop->mesh.vertices = {
            0,
            VertexAttribFlags::None,
            vertexData, nullptr, nullptr,
            kVertexStride };
    mOutGlop->mesh.elementCount = 6 * quadCount;
    return *this;
}

GlopBuilder& GlopBuilder::setMeshTexturedIndexedQuads(TextureVertex* vertexData, int elementCount) {
    TRIGGER_STAGE(kMeshStage);

    mOutGlop->mesh.primitiveMode = GL_TRIANGLES;
    mOutGlop->mesh.indices = { mRenderState.meshState().getQuadListIBO(), nullptr };
    mOutGlop->mesh.vertices = {
            0,
            VertexAttribFlags::TextureCoord,
            &vertexData[0].x, &vertexData[0].u, nullptr,
            kTextureVertexStride };
    mOutGlop->mesh.elementCount = elementCount;
    return *this;
}

GlopBuilder& GlopBuilder::setMeshTexturedMesh(TextureVertex* vertexData, int elementCount) {
    TRIGGER_STAGE(kMeshStage);

    mOutGlop->mesh.primitiveMode = GL_TRIANGLES;
    mOutGlop->mesh.indices = { 0, nullptr };
    mOutGlop->mesh.vertices = {
            0,
            VertexAttribFlags::TextureCoord,
            &vertexData[0].x, &vertexData[0].u, nullptr,
            kTextureVertexStride };
    mOutGlop->mesh.elementCount = elementCount;
    return *this;
}

GlopBuilder& GlopBuilder::setMeshColoredTexturedMesh(ColorTextureVertex* vertexData, int elementCount) {
    TRIGGER_STAGE(kMeshStage);

    mOutGlop->mesh.primitiveMode = GL_TRIANGLES;
    mOutGlop->mesh.indices = { 0, nullptr };
    mOutGlop->mesh.vertices = {
            0,
            VertexAttribFlags::TextureCoord | VertexAttribFlags::Color,
            &vertexData[0].x, &vertexData[0].u, &vertexData[0].r,
            kColorTextureVertexStride };
    mOutGlop->mesh.elementCount = elementCount;
    return *this;
}

GlopBuilder& GlopBuilder::setMeshVertexBuffer(const VertexBuffer& vertexBuffer, bool shadowInterp) {
    TRIGGER_STAGE(kMeshStage);

    const VertexBuffer::MeshFeatureFlags flags = vertexBuffer.getMeshFeatureFlags();

    bool alphaVertex = flags & VertexBuffer::kAlpha;
    bool indices = flags & VertexBuffer::kIndices;

    mOutGlop->mesh.primitiveMode = GL_TRIANGLE_STRIP;
    mOutGlop->mesh.indices = { 0, vertexBuffer.getIndices() };
    mOutGlop->mesh.vertices = {
            0,
            alphaVertex ? VertexAttribFlags::Alpha : VertexAttribFlags::None,
            vertexBuffer.getBuffer(), nullptr, nullptr,
            alphaVertex ? kAlphaVertexStride : kVertexStride };
    mOutGlop->mesh.elementCount = indices
                ? vertexBuffer.getIndexCount() : vertexBuffer.getVertexCount();

    mDescription.useShadowAlphaInterp = shadowInterp;
    return *this;
}

GlopBuilder& GlopBuilder::setMeshPatchQuads(const Patch& patch) {
    TRIGGER_STAGE(kMeshStage);

    mOutGlop->mesh.primitiveMode = GL_TRIANGLES;
    mOutGlop->mesh.indices = { mRenderState.meshState().getQuadListIBO(), nullptr };
    mOutGlop->mesh.vertices = {
            mCaches.patchCache.getMeshBuffer(),
            VertexAttribFlags::TextureCoord,
            (void*)patch.positionOffset, (void*)patch.textureOffset, nullptr,
            kTextureVertexStride };
    mOutGlop->mesh.elementCount = patch.indexCount;
    return *this;
}

////////////////////////////////////////////////////////////////////////////////
// Fill
////////////////////////////////////////////////////////////////////////////////

void GlopBuilder::setFill(int color, float alphaScale,
        SkXfermode::Mode mode, Blend::ModeOrderSwap modeUsage,
        const SkShader* shader, const SkColorFilter* colorFilter) {
    if (mode != SkXfermode::kClear_Mode) {
        float alpha = (SkColorGetA(color) / 255.0f) * alphaScale;
        if (!shader) {
            float colorScale = alpha / 255.0f;
            mOutGlop->fill.color = {
                    colorScale * SkColorGetR(color),
                    colorScale * SkColorGetG(color),
                    colorScale * SkColorGetB(color),
                    alpha
            };
        } else {
            mOutGlop->fill.color = { 1, 1, 1, alpha };
        }
    } else {
        mOutGlop->fill.color = { 0, 0, 0, 1 };
    }

    mOutGlop->blend = { GL_ZERO, GL_ZERO };
    if (mOutGlop->fill.color.a < 1.0f
            || (mOutGlop->mesh.vertices.attribFlags & VertexAttribFlags::Alpha)
            || (mOutGlop->fill.texture.texture && mOutGlop->fill.texture.texture->blend)
            || mOutGlop->roundRectClipState
            || PaintUtils::isBlendedShader(shader)
            || PaintUtils::isBlendedColorFilter(colorFilter)
            || mode != SkXfermode::kSrcOver_Mode) {
        if (CC_LIKELY(mode <= SkXfermode::kScreen_Mode)) {
            Blend::getFactors(mode, modeUsage,
                    &mOutGlop->blend.src, &mOutGlop->blend.dst);
        } else {
            // These blend modes are not supported by OpenGL directly and have
            // to be implemented using shaders. Since the shader will perform
            // the blending, don't enable GL blending off here
            // If the blend mode cannot be implemented using shaders, fall
            // back to the default SrcOver blend mode instead
            if (CC_UNLIKELY(mCaches.extensions().hasFramebufferFetch())) {
                mDescription.framebufferMode = mode;
                mDescription.swapSrcDst = (modeUsage == Blend::ModeOrderSwap::Swap);
                // blending in shader, don't enable
            } else {
                // unsupported
                Blend::getFactors(SkXfermode::kSrcOver_Mode, modeUsage,
                        &mOutGlop->blend.src, &mOutGlop->blend.dst);
            }
        }
    }
    mShader = shader; // shader resolved in ::build()

    if (colorFilter) {
        SkColor color;
        SkXfermode::Mode mode;
        SkScalar srcColorMatrix[20];
        if (colorFilter->asColorMode(&color, &mode)) {
            mOutGlop->fill.filterMode = mDescription.colorOp = ProgramDescription::ColorFilterMode::Blend;
            mDescription.colorMode = mode;

            const float alpha = SkColorGetA(color) / 255.0f;
            float colorScale = alpha / 255.0f;
            mOutGlop->fill.filter.color = {
                    colorScale * SkColorGetR(color),
                    colorScale * SkColorGetG(color),
                    colorScale * SkColorGetB(color),
                    alpha,
            };
        } else if (colorFilter->asColorMatrix(srcColorMatrix)) {
            mOutGlop->fill.filterMode = mDescription.colorOp = ProgramDescription::ColorFilterMode::Matrix;

            float* colorMatrix = mOutGlop->fill.filter.matrix.matrix;
            memcpy(colorMatrix, srcColorMatrix, 4 * sizeof(float));
            memcpy(&colorMatrix[4], &srcColorMatrix[5], 4 * sizeof(float));
            memcpy(&colorMatrix[8], &srcColorMatrix[10], 4 * sizeof(float));
            memcpy(&colorMatrix[12], &srcColorMatrix[15], 4 * sizeof(float));

            // Skia uses the range [0..255] for the addition vector, but we need
            // the [0..1] range to apply the vector in GLSL
            float* colorVector = mOutGlop->fill.filter.matrix.vector;
            colorVector[0] = srcColorMatrix[4] / 255.0f;
            colorVector[1] = srcColorMatrix[9] / 255.0f;
            colorVector[2] = srcColorMatrix[14] / 255.0f;
            colorVector[3] = srcColorMatrix[19] / 255.0f;
        } else {
            LOG_ALWAYS_FATAL("unsupported ColorFilter");
        }
    } else {
        mOutGlop->fill.filterMode = ProgramDescription::ColorFilterMode::None;
    }
}

GlopBuilder& GlopBuilder::setFillTexturePaint(Texture& texture,
        const int textureFillFlags, const SkPaint* paint, float alphaScale) {
    TRIGGER_STAGE(kFillStage);
    REQUIRE_STAGES(kMeshStage | kRoundRectClipStage);

    GLenum filter = (textureFillFlags & TextureFillFlags::ForceFilter)
            ? GL_LINEAR : PaintUtils::getFilter(paint);
    mOutGlop->fill.texture = { &texture,
            GL_TEXTURE_2D, filter, GL_CLAMP_TO_EDGE, nullptr };

    if (paint) {
        int color = paint->getColor();
        SkShader* shader = paint->getShader();

        if (!(textureFillFlags & TextureFillFlags::IsAlphaMaskTexture)) {
            // Texture defines color, so disable shaders, and reset all non-alpha color channels
            color |= 0x00FFFFFF;
            shader = nullptr;
        }
        setFill(color, alphaScale,
                PaintUtils::getXfermode(paint->getXfermode()), Blend::ModeOrderSwap::NoSwap,
                shader, paint->getColorFilter());
    } else {
        mOutGlop->fill.color = { alphaScale, alphaScale, alphaScale, alphaScale };

        if (alphaScale < 1.0f
                || (mOutGlop->mesh.vertices.attribFlags & VertexAttribFlags::Alpha)
                || texture.blend
                || mOutGlop->roundRectClipState) {
            Blend::getFactors(SkXfermode::kSrcOver_Mode, Blend::ModeOrderSwap::NoSwap,
                    &mOutGlop->blend.src, &mOutGlop->blend.dst);
        } else {
            mOutGlop->blend = { GL_ZERO, GL_ZERO };
        }
    }

    if (textureFillFlags & TextureFillFlags::IsAlphaMaskTexture) {
        mDescription.modulate = mOutGlop->fill.color.isNotBlack();
        mDescription.hasAlpha8Texture = true;
    } else {
        mDescription.modulate = mOutGlop->fill.color.a < 1.0f;
    }
    return *this;
}

GlopBuilder& GlopBuilder::setFillPaint(const SkPaint& paint, float alphaScale) {
    TRIGGER_STAGE(kFillStage);
    REQUIRE_STAGES(kMeshStage | kRoundRectClipStage);

    mOutGlop->fill.texture = { nullptr, GL_INVALID_ENUM, GL_INVALID_ENUM, GL_INVALID_ENUM, nullptr };

    setFill(paint.getColor(), alphaScale,
            PaintUtils::getXfermode(paint.getXfermode()), Blend::ModeOrderSwap::NoSwap,
            paint.getShader(), paint.getColorFilter());
    mDescription.modulate = mOutGlop->fill.color.a < 1.0f;
    return *this;
}

GlopBuilder& GlopBuilder::setFillPathTexturePaint(PathTexture& texture,
        const SkPaint& paint, float alphaScale) {
    TRIGGER_STAGE(kFillStage);
    REQUIRE_STAGES(kMeshStage | kRoundRectClipStage);

    //specify invalid filter/clamp, since these are always static for PathTextures
    mOutGlop->fill.texture = { &texture, GL_TEXTURE_2D, GL_INVALID_ENUM, GL_INVALID_ENUM, nullptr };

    setFill(paint.getColor(), alphaScale,
            PaintUtils::getXfermode(paint.getXfermode()), Blend::ModeOrderSwap::NoSwap,
            paint.getShader(), paint.getColorFilter());

    mDescription.hasAlpha8Texture = true;
    mDescription.modulate = mOutGlop->fill.color.isNotBlack();
    return *this;
}

GlopBuilder& GlopBuilder::setFillShadowTexturePaint(ShadowTexture& texture, int shadowColor,
        const SkPaint& paint, float alphaScale) {
    TRIGGER_STAGE(kFillStage);
    REQUIRE_STAGES(kMeshStage | kRoundRectClipStage);

    //specify invalid filter/clamp, since these are always static for ShadowTextures
    mOutGlop->fill.texture = { &texture, GL_TEXTURE_2D, GL_INVALID_ENUM, GL_INVALID_ENUM, nullptr };

    const int ALPHA_BITMASK = SK_ColorBLACK;
    const int COLOR_BITMASK = ~ALPHA_BITMASK;
    if ((shadowColor & ALPHA_BITMASK) == ALPHA_BITMASK) {
        // shadow color is fully opaque: override its alpha with that of paint
        shadowColor &= paint.getColor() | COLOR_BITMASK;
    }

    setFill(shadowColor, alphaScale,
            PaintUtils::getXfermode(paint.getXfermode()), Blend::ModeOrderSwap::NoSwap,
            paint.getShader(), paint.getColorFilter());

    mDescription.hasAlpha8Texture = true;
    mDescription.modulate = mOutGlop->fill.color.isNotBlack();
    return *this;
}

GlopBuilder& GlopBuilder::setFillBlack() {
    TRIGGER_STAGE(kFillStage);
    REQUIRE_STAGES(kMeshStage | kRoundRectClipStage);

    mOutGlop->fill.texture = { nullptr, GL_INVALID_ENUM, GL_INVALID_ENUM, GL_INVALID_ENUM, nullptr };
    setFill(SK_ColorBLACK, 1.0f, SkXfermode::kSrcOver_Mode, Blend::ModeOrderSwap::NoSwap,
            nullptr, nullptr);
    return *this;
}

GlopBuilder& GlopBuilder::setFillClear() {
    TRIGGER_STAGE(kFillStage);
    REQUIRE_STAGES(kMeshStage | kRoundRectClipStage);

    mOutGlop->fill.texture = { nullptr, GL_INVALID_ENUM, GL_INVALID_ENUM, GL_INVALID_ENUM, nullptr };
    setFill(SK_ColorBLACK, 1.0f, SkXfermode::kClear_Mode, Blend::ModeOrderSwap::NoSwap,
            nullptr, nullptr);
    return *this;
}

GlopBuilder& GlopBuilder::setFillLayer(Texture& texture, const SkColorFilter* colorFilter,
        float alpha, SkXfermode::Mode mode, Blend::ModeOrderSwap modeUsage) {
    TRIGGER_STAGE(kFillStage);
    REQUIRE_STAGES(kMeshStage | kRoundRectClipStage);

    mOutGlop->fill.texture = { &texture,
            GL_TEXTURE_2D, GL_LINEAR, GL_CLAMP_TO_EDGE, nullptr };

    setFill(SK_ColorWHITE, alpha, mode, modeUsage, nullptr, colorFilter);

    mDescription.modulate = mOutGlop->fill.color.a < 1.0f;
    return *this;
}

GlopBuilder& GlopBuilder::setFillTextureLayer(Layer& layer, float alpha) {
    TRIGGER_STAGE(kFillStage);
    REQUIRE_STAGES(kMeshStage | kRoundRectClipStage);

    mOutGlop->fill.texture = { &(layer.getTexture()),
            layer.getRenderTarget(), GL_LINEAR, GL_CLAMP_TO_EDGE, &layer.getTexTransform() };

    setFill(SK_ColorWHITE, alpha, layer.getMode(), Blend::ModeOrderSwap::NoSwap,
            nullptr, layer.getColorFilter());

    mDescription.modulate = mOutGlop->fill.color.a < 1.0f;
    mDescription.hasTextureTransform = true;
    return *this;
}

////////////////////////////////////////////////////////////////////////////////
// Transform
////////////////////////////////////////////////////////////////////////////////

GlopBuilder& GlopBuilder::setTransform(const Matrix4& canvas, const int transformFlags) {
    TRIGGER_STAGE(kTransformStage);

    mOutGlop->transform.canvas = canvas;
    mOutGlop->transform.transformFlags = transformFlags;
    return *this;
}

////////////////////////////////////////////////////////////////////////////////
// ModelView
////////////////////////////////////////////////////////////////////////////////

GlopBuilder& GlopBuilder::setModelViewMapUnitToRect(const Rect destination) {
    TRIGGER_STAGE(kModelViewStage);

    mOutGlop->transform.modelView.loadTranslate(destination.left, destination.top, 0.0f);
    mOutGlop->transform.modelView.scale(destination.getWidth(), destination.getHeight(), 1.0f);
    mOutGlop->bounds = destination;
    return *this;
}

GlopBuilder& GlopBuilder::setModelViewMapUnitToRectSnap(const Rect destination) {
    TRIGGER_STAGE(kModelViewStage);
    REQUIRE_STAGES(kTransformStage | kFillStage);

    float left = destination.left;
    float top = destination.top;

    const Matrix4& meshTransform = mOutGlop->transform.meshTransform();
    if (CC_LIKELY(meshTransform.isPureTranslate())) {
        // snap by adjusting the model view matrix
        const float translateX = meshTransform.getTranslateX();
        const float translateY = meshTransform.getTranslateY();

        left = (int) floorf(left + translateX + 0.5f) - translateX;
        top = (int) floorf(top + translateY + 0.5f) - translateY;
        mOutGlop->fill.texture.filter = GL_NEAREST;
    }

    mOutGlop->transform.modelView.loadTranslate(left, top, 0.0f);
    mOutGlop->transform.modelView.scale(destination.getWidth(), destination.getHeight(), 1.0f);
    mOutGlop->bounds = destination;
    return *this;
}

GlopBuilder& GlopBuilder::setModelViewOffsetRect(float offsetX, float offsetY, const Rect source) {
    TRIGGER_STAGE(kModelViewStage);

    mOutGlop->transform.modelView.loadTranslate(offsetX, offsetY, 0.0f);
    mOutGlop->bounds = source;
    mOutGlop->bounds.translate(offsetX, offsetY);
    return *this;
}

GlopBuilder& GlopBuilder::setModelViewOffsetRectSnap(float offsetX, float offsetY, const Rect source) {
    TRIGGER_STAGE(kModelViewStage);
    REQUIRE_STAGES(kTransformStage | kFillStage);

    const Matrix4& meshTransform = mOutGlop->transform.meshTransform();
    if (CC_LIKELY(meshTransform.isPureTranslate())) {
        // snap by adjusting the model view matrix
        const float translateX = meshTransform.getTranslateX();
        const float translateY = meshTransform.getTranslateY();

        offsetX = (int) floorf(offsetX + translateX + source.left + 0.5f) - translateX - source.left;
        offsetY = (int) floorf(offsetY + translateY + source.top + 0.5f) - translateY - source.top;
        mOutGlop->fill.texture.filter = GL_NEAREST;
    }

    mOutGlop->transform.modelView.loadTranslate(offsetX, offsetY, 0.0f);
    mOutGlop->bounds = source;
    mOutGlop->bounds.translate(offsetX, offsetY);
    return *this;
}

////////////////////////////////////////////////////////////////////////////////
// RoundRectClip
////////////////////////////////////////////////////////////////////////////////

GlopBuilder& GlopBuilder::setRoundRectClipState(const RoundRectClipState* roundRectClipState) {
    TRIGGER_STAGE(kRoundRectClipStage);

    mOutGlop->roundRectClipState = roundRectClipState;
    mDescription.hasRoundRectClip = roundRectClipState != nullptr;
    return *this;
}

////////////////////////////////////////////////////////////////////////////////
// Build
////////////////////////////////////////////////////////////////////////////////

void verify(const ProgramDescription& description, const Glop& glop) {
    if (glop.fill.texture.texture != nullptr) {
        LOG_ALWAYS_FATAL_IF(((description.hasTexture && description.hasExternalTexture)
                        || (!description.hasTexture && !description.hasExternalTexture)
                        || ((glop.mesh.vertices.attribFlags & VertexAttribFlags::TextureCoord) == 0)),
                "Texture %p, hT%d, hET %d, attribFlags %x",
                glop.fill.texture.texture,
                description.hasTexture, description.hasExternalTexture,
                glop.mesh.vertices.attribFlags);
    } else {
        LOG_ALWAYS_FATAL_IF((description.hasTexture
                        || description.hasExternalTexture
                        || ((glop.mesh.vertices.attribFlags & VertexAttribFlags::TextureCoord) != 0)),
                "No texture, hT%d, hET %d, attribFlags %x",
                description.hasTexture, description.hasExternalTexture,
                glop.mesh.vertices.attribFlags);
    }

    if ((glop.mesh.vertices.attribFlags & VertexAttribFlags::Alpha)
            && glop.mesh.vertices.bufferObject) {
        LOG_ALWAYS_FATAL("VBO and alpha attributes are not currently compatible");
    }

    if (description.hasTextureTransform != (glop.fill.texture.textureTransform != nullptr)) {
        LOG_ALWAYS_FATAL("Texture transform incorrectly specified");
    }
}

void GlopBuilder::build() {
    REQUIRE_STAGES(kAllStages);
    if (mOutGlop->mesh.vertices.attribFlags & VertexAttribFlags::TextureCoord) {
        if (mOutGlop->fill.texture.target == GL_TEXTURE_2D) {
            mDescription.hasTexture = true;
        } else {
            mDescription.hasExternalTexture = true;
        }
    }

    mDescription.hasColors = mOutGlop->mesh.vertices.attribFlags & VertexAttribFlags::Color;
    mDescription.hasVertexAlpha = mOutGlop->mesh.vertices.attribFlags & VertexAttribFlags::Alpha;

    // Enable debug highlight when what we're about to draw is tested against
    // the stencil buffer and if stencil highlight debugging is on
    mDescription.hasDebugHighlight = !Properties::debugOverdraw
            && Properties::debugStencilClip == StencilClipDebug::ShowHighlight
            && mRenderState.stencil().isTestEnabled();

    // serialize shader info into ShaderData
    GLuint textureUnit = mOutGlop->fill.texture.texture ? 1 : 0;

    if (CC_LIKELY(!mShader)) {
        mOutGlop->fill.skiaShaderData.skiaShaderType = kNone_SkiaShaderType;
    } else {
        Matrix4 shaderMatrix;
        if (mOutGlop->transform.transformFlags & TransformFlags::MeshIgnoresCanvasTransform) {
            // canvas level transform was built into the modelView and geometry,
            // so the shader matrix must reverse this
            shaderMatrix.loadInverse(mOutGlop->transform.canvas);
            shaderMatrix.multiply(mOutGlop->transform.modelView);
        } else {
            shaderMatrix = mOutGlop->transform.modelView;
        }
        SkiaShader::store(mCaches, *mShader, shaderMatrix,
                &textureUnit, &mDescription, &(mOutGlop->fill.skiaShaderData));
    }

    // duplicates ProgramCache's definition of color uniform presence
    const bool singleColor = !mDescription.hasTexture
            && !mDescription.hasExternalTexture
            && !mDescription.hasGradient
            && !mDescription.hasBitmap;
    mOutGlop->fill.colorEnabled = mDescription.modulate || singleColor;

    verify(mDescription, *mOutGlop);

    // Final step: populate program and map bounds into render target space
    mOutGlop->fill.program = mCaches.programCache.get(mDescription);
    mOutGlop->transform.meshTransform().mapRect(mOutGlop->bounds);
}

void GlopBuilder::dump(const Glop& glop) {
    ALOGD("Glop Mesh");
    const Glop::Mesh& mesh = glop.mesh;
    ALOGD("    primitive mode: %d", mesh.primitiveMode);
    ALOGD("    indices: buffer obj %x, indices %p", mesh.indices.bufferObject, mesh.indices.indices);

    const Glop::Mesh::Vertices& vertices = glop.mesh.vertices;
    ALOGD("    vertices: buffer obj %x, flags %x, pos %p, tex %p, clr %p, stride %d",
            vertices.bufferObject, vertices.attribFlags,
            vertices.position, vertices.texCoord, vertices.color, vertices.stride);
    ALOGD("    element count: %d", mesh.elementCount);

    ALOGD("Glop Fill");
    const Glop::Fill& fill = glop.fill;
    ALOGD("    program %p", fill.program);
    if (fill.texture.texture) {
        ALOGD("    texture %p, target %d, filter %d, clamp %d",
                fill.texture.texture, fill.texture.target, fill.texture.filter, fill.texture.clamp);
        if (fill.texture.textureTransform) {
            fill.texture.textureTransform->dump("texture transform");
        }
    }
    ALOGD_IF(fill.colorEnabled, "    color (argb) %.2f %.2f %.2f %.2f",
            fill.color.a, fill.color.r, fill.color.g, fill.color.b);
    ALOGD_IF(fill.filterMode != ProgramDescription::ColorFilterMode::None,
            "    filterMode %d", (int)fill.filterMode);
    ALOGD_IF(fill.skiaShaderData.skiaShaderType, "    shader type %d",
            fill.skiaShaderData.skiaShaderType);

    ALOGD("Glop transform");
    glop.transform.modelView.dump("  model view");
    glop.transform.canvas.dump("  canvas");
    ALOGD_IF(glop.transform.transformFlags, "  transformFlags 0x%x", glop.transform.transformFlags);

    ALOGD_IF(glop.roundRectClipState, "Glop RRCS %p", glop.roundRectClipState);

    ALOGD("Glop blend %d %d", glop.blend.src, glop.blend.dst);
    ALOGD("Glop bounds " RECT_STRING, RECT_ARGS(glop.bounds));
}

} /* namespace uirenderer */
} /* namespace android */
