/*
 * 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 "GlLayer.h"
#include "Glop.h"
#include "Layer.h"
#include "Matrix.h"
#include "Patch.h"
#include "PathCache.h"
#include "SkiaShader.h"
#include "Texture.h"
#include "VertexBuffer.h"
#include "renderstate/MeshState.h"
#include "renderstate/RenderState.h"
#include "utils/PaintUtils.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::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) {
    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();
    mOutGlop->mesh.vertexCount = vertexBuffer.getVertexCount();  // used for glDrawRangeElements()
    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, SkBlendMode mode,
                          Blend::ModeOrderSwap modeUsage, const SkShader* shader,
                          const SkColorFilter* colorFilter) {
    if (mode != SkBlendMode::kClear) {
        if (!shader) {
            FloatColor c;
            c.set(color);
            c.r *= alphaScale;
            c.g *= alphaScale;
            c.b *= alphaScale;
            c.a *= alphaScale;
            mOutGlop->fill.color = c;
        } else {
            float alpha = (SkColorGetA(color) / 255.0f) * alphaScale;
            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 != SkBlendMode::kSrcOver) {
        if (CC_LIKELY(mode <= SkBlendMode::kScreen)) {
            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(SkBlendMode::kSrcOver, modeUsage, &mOutGlop->blend.src,
                                  &mOutGlop->blend.dst);
            }
        }
    }
    mShader = shader;  // shader resolved in ::build()

    if (colorFilter) {
        SkColor color;
        SkBlendMode bmode;
        SkScalar srcColorMatrix[20];
        if (colorFilter->asColorMode(&color, &bmode)) {
            mOutGlop->fill.filterMode = mDescription.colorOp =
                    ProgramDescription::ColorFilterMode::Blend;
            mDescription.colorMode = bmode;
            mOutGlop->fill.filter.color.set(color);
        } 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] = EOCF(srcColorMatrix[4] / 255.0f);
            colorVector[1] = EOCF(srcColorMatrix[9] / 255.0f);
            colorVector[2] = EOCF(srcColorMatrix[14] / 255.0f);
            colorVector[3] = srcColorMatrix[19] / 255.0f;  // alpha is linear
        } else {
            ALOGE("unsupported ColorFilter type: %s", colorFilter->getTypeName());
            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, 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, paint->getBlendMode(), 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(SkBlendMode::kSrcOver, 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, bool shadowInterp) {
    TRIGGER_STAGE(kFillStage);
    REQUIRE_STAGES(kMeshStage | kRoundRectClipStage);

    if (CC_LIKELY(!shadowInterp)) {
        mOutGlop->fill.texture = {nullptr, GL_INVALID_ENUM, GL_INVALID_ENUM, nullptr};
    } else {
        mOutGlop->fill.texture = {mCaches.textureState().getShadowLutTexture(), GL_INVALID_ENUM,
                                  GL_INVALID_ENUM, nullptr};
    }

    setFill(paint.getColor(), alphaScale, paint.getBlendMode(), Blend::ModeOrderSwap::NoSwap,
            paint.getShader(), paint.getColorFilter());
    mDescription.useShadowAlphaInterp = shadowInterp;
    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_INVALID_ENUM, GL_INVALID_ENUM, nullptr};

    setFill(paint.getColor(), alphaScale, paint.getBlendMode(), 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_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, paint.getBlendMode(), 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, nullptr};
    setFill(SK_ColorBLACK, 1.0f, SkBlendMode::kSrcOver, 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, nullptr};
    setFill(SK_ColorBLACK, 1.0f, SkBlendMode::kClear, Blend::ModeOrderSwap::NoSwap, nullptr,
            nullptr);
    return *this;
}

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

    mOutGlop->fill.texture = {&texture, 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(GlLayer& layer, float alpha) {
    TRIGGER_STAGE(kFillStage);
    REQUIRE_STAGES(kMeshStage | kRoundRectClipStage);

    mOutGlop->fill.texture = {&(layer.getTexture()), 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;
}

GlopBuilder& GlopBuilder::setFillExternalTexture(Texture& texture, Matrix4& textureTransform,
                                                 bool requiresFilter) {
    TRIGGER_STAGE(kFillStage);
    REQUIRE_STAGES(kMeshStage | kRoundRectClipStage);

    GLenum filter = requiresFilter ? GL_LINEAR : GL_NEAREST;
    mOutGlop->fill.texture = {&texture, filter, GL_CLAMP_TO_EDGE, &textureTransform};

    setFill(SK_ColorWHITE, 1.0f, SkBlendMode::kSrc, Blend::ModeOrderSwap::NoSwap, nullptr, nullptr);

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

GlopBuilder& GlopBuilder::setGammaCorrection(bool enabled) {
    REQUIRE_STAGES(kFillStage);

    mDescription.hasGammaCorrection = enabled;
    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);
    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);
    return *this;
}

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

    mOutGlop->transform.modelView.loadTranslate(offsetX, offsetY, 0.0f);
    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);
    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 &&
                  !description.useShadowAlphaInterp) ||
                 ((glop.mesh.vertices.attribFlags & VertexAttribFlags::TextureCoord) == 0 &&
                  !description.useShadowAlphaInterp)),
                "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) {
        Texture* texture = mOutGlop->fill.texture.texture;
        if (texture->target() == GL_TEXTURE_2D) {
            mDescription.hasTexture = true;
        } else {
            mDescription.hasExternalTexture = true;
        }
        mDescription.hasLinearTexture = texture->isLinear();
        mDescription.hasColorSpaceConversion = texture->hasColorSpaceConversion();
        mDescription.transferFunction = texture->getTransferFunctionType();
        mDescription.hasTranslucentConversion = texture->blend;
    }

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

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

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