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

#include "GLTestAtlasTextRenderer.h"
#include "../gl/GLTestContext.h"
#include "SkBitmap.h"
#include "TestAtlasTextRenderer.h"
#include "gl/GrGLDefines.h"
#include "gl/GrGLUtil.h"

using sk_gpu_test::GLTestContext;

namespace {

class GLTestAtlasTextRenderer : public sk_gpu_test::TestAtlasTextRenderer {
public:
    GLTestAtlasTextRenderer(std::unique_ptr<GLTestContext>);

    void* createTexture(AtlasFormat, int width, int height) override;

    void deleteTexture(void* textureHandle) override;

    void setTextureData(void* textureHandle, const void* data, int x, int y, int width, int height,
                        size_t rowBytes) override;

    void drawSDFGlyphs(void* targetHandle, void* textureHandle, const SDFVertex vertices[],
                       int quadCnt) override;

    void* makeTargetHandle(int width, int height) override;

    void targetDeleted(void* targetHandle) override;

    SkBitmap readTargetHandle(void* targetHandle) override;

    void clearTarget(void* targetHandle, uint32_t color) override;

    bool initialized() const { return 0 != fProgram; }

private:
    struct AtlasTexture {
        GrGLuint fID;
        AtlasFormat fFormat;
        int fWidth;
        int fHeight;
    };

    struct Target {
        GrGLuint fFBOID;
        GrGLuint fRBID;
        int fWidth;
        int fHeight;
    };

    std::unique_ptr<GLTestContext> fContext;
    GrGLuint fProgram = 0;
    GrGLint fDstScaleAndTranslateLocation = 0;
    GrGLint fAtlasInvSizeLocation = 0;
    GrGLint fSamplerLocation = 0;
};

#define callgl(NAME, ...) fContext->gl()->fFunctions.f##NAME(__VA_ARGS__)
#define checkgl()                                               \
    do {                                                        \
        static constexpr auto line = __LINE__;                  \
        auto error = fContext->gl()->fFunctions.fGetError();    \
        if (error != GR_GL_NO_ERROR) {                          \
            SkDebugf("GL ERROR: 0x%x, line %d\n", error, line); \
        }                                                       \
    } while (false)

GLTestAtlasTextRenderer::GLTestAtlasTextRenderer(std::unique_ptr<GLTestContext> context)
        : fContext(std::move(context)) {
    auto restore = fContext->makeCurrentAndAutoRestore();

    // First check whether the GL is supported so we can avoid spammy failures on systems
    // where the GL simply doesn't work with this class.
    const char* versionStr = reinterpret_cast<const char*>(callgl(GetString, GR_GL_VERSION));
    auto version = GrGLGetVersionFromString(versionStr);
    auto standard = GrGLGetStandardInUseFromString(versionStr);
    switch (standard) {
        case kWebGL_GrGLStandard:
        case kNone_GrGLStandard:
            return;
        case kGLES_GrGLStandard:
            if (version < GR_GL_VER(3, 0)) {
                return;
            }
            break;
        case kGL_GrGLStandard: {
            if (version < GR_GL_VER(4, 3)) {
                return;
            }
            GrGLint profileMask;
            callgl(GetIntegerv, GR_GL_CONTEXT_PROFILE_MASK, &profileMask);
            if (profileMask & GR_GL_CONTEXT_CORE_PROFILE_BIT) {
                return;
            }
        }
    }

    auto vs = callgl(CreateShader, GR_GL_VERTEX_SHADER);
    static constexpr char kGLVersionString[] = "#version 430 compatibility";
    static constexpr char kGLESVersionString[] = "#version 300 es";
    GrGLint lengths[2];
    const GrGLchar* strings[2];
    switch (fContext->gl()->fStandard) {
        case kGL_GrGLStandard:
            strings[0] = kGLVersionString;
            lengths[0] = static_cast<GrGLint>(SK_ARRAY_COUNT(kGLVersionString)) - 1;
            break;
        case kGLES_GrGLStandard:
            strings[0] = kGLESVersionString;
            lengths[0] = static_cast<GrGLint>(SK_ARRAY_COUNT(kGLESVersionString)) - 1;
            break;
        default:
            strings[0] = nullptr;
            lengths[0] = 0;
            break;
    }

    static constexpr const char kVS[] = R"(
        uniform vec4 uDstScaleAndTranslate;
        uniform vec2 uAtlasInvSize;

        layout (location = 0) in vec3 inPosition;
        layout (location = 1) in vec4 inColor;
        layout (location = 2) in uvec2 inTextureCoords;

        out vec2 vTexCoord;
        out vec4 vColor;
        out vec2 vIntTexCoord;

        void main() {
            vec2 intCoords;
            // floor(vec2) doesn't seem to work on some ES devices.
            intCoords.x = floor(float(inTextureCoords.x));
            intCoords.y = floor(float(inTextureCoords.y));
            vTexCoord = intCoords * uAtlasInvSize;
            vIntTexCoord = intCoords;
            vColor = inColor;
            gl_Position = vec4(inPosition.x * uDstScaleAndTranslate.x + uDstScaleAndTranslate.y,
                               inPosition.y * uDstScaleAndTranslate.z + uDstScaleAndTranslate.w,
                               0.0, inPosition.z);
        }
    )";
    strings[1] = kVS;
    lengths[1] = SK_ARRAY_COUNT(kVS) - 1;
    callgl(ShaderSource, vs, 2, strings, lengths);
    callgl(CompileShader, vs);
    GrGLint compileStatus;
    callgl(GetShaderiv, vs, GR_GL_COMPILE_STATUS, &compileStatus);
    if (compileStatus == GR_GL_FALSE) {
        GrGLint logLength;
        callgl(GetShaderiv, vs, GR_GL_INFO_LOG_LENGTH, &logLength);
        std::unique_ptr<GrGLchar[]> log(new GrGLchar[logLength + 1]);
        log[logLength] = '\0';
        callgl(GetShaderInfoLog, vs, logLength, &logLength, log.get());
        SkDebugf("Vertex Shader failed to compile\n%s", log.get());
        callgl(DeleteShader, vs);
        return;
    }

    auto fs = callgl(CreateShader, GR_GL_FRAGMENT_SHADER);
    static constexpr const char kFS[] = R"(
        uniform sampler2D uSampler;

        in vec2 vTexCoord;
        in vec4 vColor;
        in vec2 vIntTexCoord;

        layout (location = 0) out vec4 outColor;

        void main() {
            float sdfValue = texture(uSampler, vTexCoord).r;
            float distance = 7.96875 * (sdfValue - 0.50196078431000002);
            vec2 dist_grad = vec2(dFdx(distance), dFdy(distance));
            vec2 Jdx = dFdx(vIntTexCoord);
            vec2 Jdy = dFdy(vIntTexCoord);
            float dg_len2 = dot(dist_grad, dist_grad);
            if (dg_len2 < 0.0001) {
                dist_grad = vec2(0.7071, 0.7071);
            } else {
                dist_grad = dist_grad * inversesqrt(dg_len2);
            }
            vec2 grad = vec2(dist_grad.x * Jdx.x + dist_grad.y * Jdy.x,
                             dist_grad.x * Jdx.y + dist_grad.y * Jdy.y);
            float afwidth = abs(0.65000000000000002 * length(grad));
            float value = smoothstep(-afwidth, afwidth, distance);
            outColor = value * vec4(vColor.rgb * vColor.a, vColor.a);
        }
    )";
    strings[1] = kFS;
    lengths[1] = SK_ARRAY_COUNT(kFS) - 1;
    callgl(ShaderSource, fs, 2, strings, lengths);
    callgl(CompileShader, fs);
    callgl(GetShaderiv, fs, GR_GL_COMPILE_STATUS, &compileStatus);
    if (compileStatus == GR_GL_FALSE) {
        GrGLint logLength;
        callgl(GetShaderiv, fs, GR_GL_INFO_LOG_LENGTH, &logLength);
        std::unique_ptr<GrGLchar[]> log(new GrGLchar[logLength + 1]);
        log[logLength] = '\0';
        callgl(GetShaderInfoLog, fs, logLength, &logLength, log.get());
        SkDebugf("Fragment Shader failed to compile\n%s", log.get());
        callgl(DeleteShader, vs);
        callgl(DeleteShader, fs);
        return;
    }

    fProgram = callgl(CreateProgram);
    if (!fProgram) {
        callgl(DeleteShader, vs);
        callgl(DeleteShader, fs);
        return;
    }

    callgl(AttachShader, fProgram, vs);
    callgl(AttachShader, fProgram, fs);
    callgl(LinkProgram, fProgram);
    GrGLint linkStatus;
    callgl(GetProgramiv, fProgram, GR_GL_LINK_STATUS, &linkStatus);
    if (linkStatus == GR_GL_FALSE) {
        GrGLint logLength = 0;
        callgl(GetProgramiv, vs, GR_GL_INFO_LOG_LENGTH, &logLength);
        std::unique_ptr<GrGLchar[]> log(new GrGLchar[logLength + 1]);
        log[logLength] = '\0';
        callgl(GetProgramInfoLog, vs, logLength, &logLength, log.get());
        SkDebugf("Program failed to link\n%s", log.get());
        callgl(DeleteShader, vs);
        callgl(DeleteShader, fs);
        callgl(DeleteProgram, fProgram);
        fProgram = 0;
        return;
    }
    fDstScaleAndTranslateLocation = callgl(GetUniformLocation, fProgram, "uDstScaleAndTranslate");
    fAtlasInvSizeLocation = callgl(GetUniformLocation, fProgram, "uAtlasInvSize");
    fSamplerLocation = callgl(GetUniformLocation, fProgram, "uSampler");
    if (fDstScaleAndTranslateLocation < 0 || fAtlasInvSizeLocation < 0 || fSamplerLocation < 0) {
        callgl(DeleteShader, vs);
        callgl(DeleteShader, fs);
        callgl(DeleteProgram, fProgram);
        fProgram = 0;
    }

    checkgl();
}

inline bool atlas_format_to_gl_types(SkAtlasTextRenderer::AtlasFormat format,
                                     GrGLenum* internalFormat, GrGLenum* externalFormat,
                                     GrGLenum* type) {
    switch (format) {
        case SkAtlasTextRenderer::AtlasFormat::kA8:
            *internalFormat = GR_GL_R8;
            *externalFormat = GR_GL_RED;
            *type = GR_GL_UNSIGNED_BYTE;
            return true;
    }
    return false;
}

inline int atlas_format_bytes_per_pixel(SkAtlasTextRenderer::AtlasFormat format) {
    switch (format) {
        case SkAtlasTextRenderer::AtlasFormat::kA8:
            return 1;
    }
    return 0;
}

void* GLTestAtlasTextRenderer::createTexture(AtlasFormat format, int width, int height) {
    GrGLenum internalFormat;
    GrGLenum externalFormat;
    GrGLenum type;
    if (!atlas_format_to_gl_types(format, &internalFormat, &externalFormat, &type)) {
        return nullptr;
    }
    auto restore = fContext->makeCurrentAndAutoRestore();

    GrGLuint id;
    callgl(GenTextures, 1, &id);
    if (!id) {
        return nullptr;
    }

    callgl(BindTexture, GR_GL_TEXTURE_2D, id);
    callgl(TexImage2D, GR_GL_TEXTURE_2D, 0, internalFormat, width, height, 0, externalFormat, type,
           nullptr);
    checkgl();

    AtlasTexture* atlas = new AtlasTexture;
    atlas->fID = id;
    atlas->fFormat = format;
    atlas->fWidth = width;
    atlas->fHeight = height;
    return atlas;
}

void GLTestAtlasTextRenderer::deleteTexture(void* textureHandle) {
    auto restore = fContext->makeCurrentAndAutoRestore();

    auto* atlasTexture = reinterpret_cast<const AtlasTexture*>(textureHandle);

    callgl(DeleteTextures, 1, &atlasTexture->fID);
    checkgl();

    delete atlasTexture;
}

void GLTestAtlasTextRenderer::setTextureData(void* textureHandle, const void* data, int x, int y,
                                             int width, int height, size_t rowBytes) {
    auto restore = fContext->makeCurrentAndAutoRestore();

    auto atlasTexture = reinterpret_cast<const AtlasTexture*>(textureHandle);

    GrGLenum internalFormat;
    GrGLenum externalFormat;
    GrGLenum type;
    if (!atlas_format_to_gl_types(atlasTexture->fFormat, &internalFormat, &externalFormat, &type)) {
        return;
    }
    int bpp = atlas_format_bytes_per_pixel(atlasTexture->fFormat);
    GrGLint rowLength = static_cast<GrGLint>(rowBytes / bpp);
    if (static_cast<size_t>(rowLength * bpp) != rowBytes) {
        return;
    }
    callgl(PixelStorei, GR_GL_UNPACK_ALIGNMENT, 1);
    callgl(PixelStorei, GR_GL_UNPACK_ROW_LENGTH, rowLength);
    callgl(BindTexture, GR_GL_TEXTURE_2D, atlasTexture->fID);
    callgl(TexSubImage2D, GR_GL_TEXTURE_2D, 0, x, y, width, height, externalFormat, type, data);
    checkgl();
}

void GLTestAtlasTextRenderer::drawSDFGlyphs(void* targetHandle, void* textureHandle,
                                            const SDFVertex vertices[], int quadCnt) {
    auto restore = fContext->makeCurrentAndAutoRestore();

    auto target = reinterpret_cast<const Target*>(targetHandle);
    auto atlas = reinterpret_cast<const AtlasTexture*>(textureHandle);

    callgl(UseProgram, fProgram);

    callgl(ActiveTexture, GR_GL_TEXTURE0);
    callgl(BindTexture, GR_GL_TEXTURE_2D, atlas->fID);
    callgl(TexParameteri, GR_GL_TEXTURE_2D, GR_GL_TEXTURE_MAG_FILTER, GR_GL_LINEAR);
    callgl(TexParameteri, GR_GL_TEXTURE_2D, GR_GL_TEXTURE_MIN_FILTER, GR_GL_LINEAR);

    float uniformScaleAndTranslate[4] = {2.f / target->fWidth, -1.f, 2.f / target->fHeight, -1.f};
    callgl(Uniform4fv, fDstScaleAndTranslateLocation, 1, uniformScaleAndTranslate);
    callgl(Uniform2f, fAtlasInvSizeLocation, 1.f / atlas->fWidth, 1.f / atlas->fHeight);
    callgl(Uniform1i, fSamplerLocation, 0);

    callgl(BindFramebuffer, GR_GL_FRAMEBUFFER, target->fFBOID);
    callgl(Viewport, 0, 0, target->fWidth, target->fHeight);

    callgl(Enable, GR_GL_BLEND);
    callgl(BlendFunc, GR_GL_ONE, GR_GL_ONE_MINUS_SRC_ALPHA);
    callgl(Disable, GR_GL_DEPTH_TEST);

    callgl(BindVertexArray, 0);
    callgl(BindBuffer, GR_GL_ARRAY_BUFFER, 0);
    callgl(BindBuffer, GR_GL_ELEMENT_ARRAY_BUFFER, 0);
    callgl(VertexAttribPointer, 0, 3, GR_GL_FLOAT, GR_GL_FALSE, sizeof(SDFVertex), vertices);
    size_t colorOffset = 3 * sizeof(float);
    callgl(VertexAttribPointer, 1, 4, GR_GL_UNSIGNED_BYTE, GR_GL_TRUE, sizeof(SDFVertex),
           reinterpret_cast<const char*>(vertices) + colorOffset);
    size_t texOffset = colorOffset + sizeof(uint32_t);
    callgl(VertexAttribIPointer, 2, 2, GR_GL_UNSIGNED_SHORT, sizeof(SDFVertex),
           reinterpret_cast<const char*>(vertices) + texOffset);
    callgl(EnableVertexAttribArray, 0);
    callgl(EnableVertexAttribArray, 1);
    callgl(EnableVertexAttribArray, 2);

    std::unique_ptr<uint16_t[]> indices(new uint16_t[quadCnt * 6]);
    for (int q = 0; q < quadCnt; ++q) {
        indices[q * 6 + 0] = 0 + 4 * q;
        indices[q * 6 + 1] = 1 + 4 * q;
        indices[q * 6 + 2] = 2 + 4 * q;
        indices[q * 6 + 3] = 2 + 4 * q;
        indices[q * 6 + 4] = 1 + 4 * q;
        indices[q * 6 + 5] = 3 + 4 * q;
    }
    callgl(DrawElements, GR_GL_TRIANGLES, 6 * quadCnt, GR_GL_UNSIGNED_SHORT, indices.get());
    checkgl();
}

void* GLTestAtlasTextRenderer::makeTargetHandle(int width, int height) {
    auto restore = fContext->makeCurrentAndAutoRestore();

    GrGLuint fbo;
    callgl(GenFramebuffers, 1, &fbo);
    if (!fbo) {
        return nullptr;
    }
    GrGLuint rb;
    callgl(GenRenderbuffers, 1, &rb);
    if (!rb) {
        callgl(DeleteFramebuffers, 1, &fbo);
        return nullptr;
    }
    callgl(BindFramebuffer, GR_GL_FRAMEBUFFER, fbo);
    callgl(BindRenderbuffer, GR_GL_RENDERBUFFER, rb);
    callgl(RenderbufferStorage, GR_GL_RENDERBUFFER, GR_GL_RGBA8, width, height);
    callgl(FramebufferRenderbuffer, GR_GL_FRAMEBUFFER, GR_GL_COLOR_ATTACHMENT0, GR_GL_RENDERBUFFER,
           rb);
    GrGLenum status = callgl(CheckFramebufferStatus, GR_GL_FRAMEBUFFER);
    if (GR_GL_FRAMEBUFFER_COMPLETE != status) {
        callgl(DeleteFramebuffers, 1, &fbo);
        callgl(DeleteRenderbuffers, 1, &rb);
        return nullptr;
    }
    callgl(Disable, GR_GL_SCISSOR_TEST);
    callgl(ClearColor, 0, 0, 0, 0.0);
    callgl(Clear, GR_GL_COLOR_BUFFER_BIT);
    checkgl();
    Target* target = new Target;
    target->fFBOID = fbo;
    target->fRBID = rb;
    target->fWidth = width;
    target->fHeight = height;
    return target;
}

void GLTestAtlasTextRenderer::targetDeleted(void* targetHandle) {
    auto restore = fContext->makeCurrentAndAutoRestore();

    Target* target = reinterpret_cast<Target*>(targetHandle);
    callgl(DeleteFramebuffers, 1, &target->fFBOID);
    callgl(DeleteRenderbuffers, 1, &target->fRBID);
    delete target;
}

SkBitmap GLTestAtlasTextRenderer::readTargetHandle(void* targetHandle) {
    auto restore = fContext->makeCurrentAndAutoRestore();

    Target* target = reinterpret_cast<Target*>(targetHandle);

    auto info =
            SkImageInfo::Make(target->fWidth, target->fHeight, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
    SkBitmap bmp;
    bmp.setInfo(info, sizeof(uint32_t) * target->fWidth);
    bmp.allocPixels();

    callgl(BindFramebuffer, GR_GL_FRAMEBUFFER, target->fFBOID);
    callgl(ReadPixels, 0, 0, target->fWidth, target->fHeight, GR_GL_RGBA, GR_GL_UNSIGNED_BYTE,
           bmp.getPixels());
    checkgl();
    return bmp;
}

void GLTestAtlasTextRenderer::clearTarget(void* targetHandle, uint32_t color) {
    auto restore = fContext->makeCurrentAndAutoRestore();

    Target* target = reinterpret_cast<Target*>(targetHandle);
    callgl(BindFramebuffer, GR_GL_FRAMEBUFFER, target->fFBOID);
    callgl(Disable, GR_GL_SCISSOR_TEST);
    float r = ((color >>  0) & 0xff) / 255.f;
    float g = ((color >>  8) & 0xff) / 255.f;
    float b = ((color >> 16) & 0xff) / 255.f;
    float a = ((color >> 24) & 0xff) / 255.f;
    callgl(ClearColor, r, g, b, a);
    callgl(Clear, GR_GL_COLOR_BUFFER_BIT);
}

}  // anonymous namespace

namespace sk_gpu_test {

sk_sp<TestAtlasTextRenderer> MakeGLTestAtlasTextRenderer() {
    std::unique_ptr<GLTestContext> context(CreatePlatformGLTestContext(kGL_GrGLStandard));
    if (!context) {
        context.reset(CreatePlatformGLTestContext(kGLES_GrGLStandard));
    }
    if (!context) {
        return nullptr;
    }
    auto restorer = context->makeCurrentAndAutoRestore();
    auto renderer = sk_make_sp<GLTestAtlasTextRenderer>(std::move(context));
    return renderer->initialized() ? std::move(renderer) : nullptr;
}

}  // namespace sk_gpu_test
