/*
 * 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 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
