/*
* Copyright (C) 2016 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 "YUVConverter.h"

#include <assert.h>
#include <stdio.h>
#include <string>

#include "OpenGLESDispatch/DispatchTables.h"
#include "host-common/feature_control.h"
#include "host-common/misc.h"


#define FATAL(fmt,...) do { \
    fprintf(stderr, "%s: FATAL: " fmt "\n", __func__, ##__VA_ARGS__); \
    assert(false); \
} while(0)

#define YUV_CONVERTER_DEBUG 0

#if YUV_CONVERTER_DEBUG
#define YUV_DEBUG_LOG(fmt, ...)                                                     \
    fprintf(stderr, "yuv-converter: %s:%d " fmt "\n", __func__, __LINE__, \
            ##__VA_ARGS__);
#else
#define YUV_DEBUG_LOG(fmt, ...)
#endif

bool isInterleaved(FrameworkFormat format) {
    switch (format) {
    case FRAMEWORK_FORMAT_NV12:
    case FRAMEWORK_FORMAT_P010:
        return true;
    case FRAMEWORK_FORMAT_YUV_420_888:
        return feature_is_enabled(kFeature_YUV420888toNV21);
    case FRAMEWORK_FORMAT_YV12:
        return false;
    default:
        FATAL("Invalid for format:%d", format);
        return false;
    }
}

enum class YUVInterleaveDirection {
    VU = 0,
    UV = 1,
};

YUVInterleaveDirection getInterleaveDirection(FrameworkFormat format) {
    if (!isInterleaved(format)) {
        FATAL("Format:%d not interleaved", format);
    }

    switch (format) {
    case FRAMEWORK_FORMAT_NV12:
    case FRAMEWORK_FORMAT_P010:
        return YUVInterleaveDirection::UV;
    case FRAMEWORK_FORMAT_YUV_420_888:
        if (feature_is_enabled(kFeature_YUV420888toNV21)) {
            return YUVInterleaveDirection::VU;
        }
        FATAL("Format:%d not interleaved", format);
        return YUVInterleaveDirection::UV;
    case FRAMEWORK_FORMAT_YV12:
    default:
        FATAL("Format:%d not interleaved", format);
        return YUVInterleaveDirection::UV;
    }
}

GLint getGlTextureFormat(FrameworkFormat format, YUVPlane plane) {
    switch (format) {
    case FRAMEWORK_FORMAT_YV12:
        switch (plane) {
        case YUVPlane::Y:
        case YUVPlane::U:
        case YUVPlane::V:
            return GL_R8;
        case YUVPlane::UV:
            FATAL("Invalid plane:%d for format:%d", plane, format);
            return 0;
        }
    case FRAMEWORK_FORMAT_YUV_420_888:
        if (feature_is_enabled(kFeature_YUV420888toNV21)) {
            switch (plane) {
            case YUVPlane::Y:
                return GL_R8;
            case YUVPlane::UV:
                return GL_RG8;
            case YUVPlane::U:
            case YUVPlane::V:
                FATAL("Invalid plane:%d for format:%d", plane, format);
                return 0;
            }
        } else {
            switch (plane) {
            case YUVPlane::Y:
            case YUVPlane::U:
            case YUVPlane::V:
                return GL_R8;
            case YUVPlane::UV:
                FATAL("Invalid plane:%d for format:%d", plane, format);
                return 0;
            }
        }
    case FRAMEWORK_FORMAT_NV12:
        switch (plane) {
        case YUVPlane::Y:
            return GL_R8;
        case YUVPlane::UV:
            return GL_RG8;
        case YUVPlane::U:
        case YUVPlane::V:
            FATAL("Invalid plane:%d for format:%d", plane, format);
            return 0;
        }
    case FRAMEWORK_FORMAT_P010:
        switch (plane) {
        case YUVPlane::Y:
            return GL_R16UI;
        case YUVPlane::UV:
            return GL_RG16UI;
        case YUVPlane::U:
        case YUVPlane::V:
            FATAL("Invalid plane:%d for format:%d", plane, format);
            return 0;
        }
    default:
        FATAL("Invalid format:%d", format);
        return 0;
    }
}

GLenum getGlPixelFormat(FrameworkFormat format, YUVPlane plane) {
    switch (format) {
    case FRAMEWORK_FORMAT_YV12:
        switch (plane) {
        case YUVPlane::Y:
        case YUVPlane::U:
        case YUVPlane::V:
            return GL_RED;
        case YUVPlane::UV:
            FATAL("Invalid plane:%d for format:%d", plane, format);
            return 0;
        }
    case FRAMEWORK_FORMAT_YUV_420_888:
        if (feature_is_enabled(kFeature_YUV420888toNV21)) {
            switch (plane) {
            case YUVPlane::Y:
                return GL_RED;
            case YUVPlane::UV:
                return GL_RG;
            case YUVPlane::U:
            case YUVPlane::V:
                FATAL("Invalid plane:%d for format:%d", plane, format);
                return 0;
            }
        } else {
            switch (plane) {
            case YUVPlane::Y:
            case YUVPlane::U:
            case YUVPlane::V:
                return GL_RED;
            case YUVPlane::UV:
                FATAL("Invalid plane:%d for format:%d", plane, format);
                return 0;
            }
        }
    case FRAMEWORK_FORMAT_NV12:
        switch (plane) {
        case YUVPlane::Y:
            return GL_RED;
        case YUVPlane::UV:
            return GL_RG;
        case YUVPlane::U:
        case YUVPlane::V:
            FATAL("Invalid plane:%d for format:%d", plane, format);
            return 0;
        }
    case FRAMEWORK_FORMAT_P010:
        switch (plane) {
        case YUVPlane::Y:
            return GL_RED_INTEGER;
        case YUVPlane::UV:
            return GL_RG_INTEGER;
        case YUVPlane::U:
        case YUVPlane::V:
            FATAL("Invalid plane:%d for format:%d", plane, format);
            return 0;
        }
    default:
        FATAL("Invalid format:%d", format);
        return 0;
    }
}

GLsizei getGlPixelType(FrameworkFormat format, YUVPlane plane) {
    switch (format) {
    case FRAMEWORK_FORMAT_YV12:
        switch (plane) {
        case YUVPlane::Y:
        case YUVPlane::U:
        case YUVPlane::V:
            return GL_UNSIGNED_BYTE;
        case YUVPlane::UV:
            FATAL("Invalid plane:%d for format:%d", plane, format);
            return 0;
        }
    case FRAMEWORK_FORMAT_YUV_420_888:
        if (feature_is_enabled(kFeature_YUV420888toNV21)) {
            switch (plane) {
            case YUVPlane::Y:
            case YUVPlane::UV:
                return GL_UNSIGNED_BYTE;
            case YUVPlane::U:
            case YUVPlane::V:
                FATAL("Invalid plane:%d for format:%d", plane, format);
                return 0;
            }
        } else {
            switch (plane) {
            case YUVPlane::Y:
            case YUVPlane::U:
            case YUVPlane::V:
                return GL_UNSIGNED_BYTE;
            case YUVPlane::UV:
                FATAL("Invalid plane:%d for format:%d", plane, format);
                return 0;
            }
        }
    case FRAMEWORK_FORMAT_NV12:
        switch (plane) {
        case YUVPlane::Y:
        case YUVPlane::UV:
            return GL_UNSIGNED_BYTE;
        case YUVPlane::U:
        case YUVPlane::V:
            FATAL("Invalid plane:%d for format:%d", plane, format);
            return 0;
        }
    case FRAMEWORK_FORMAT_P010:
        switch (plane) {
        case YUVPlane::Y:
        case YUVPlane::UV:
            return GL_UNSIGNED_SHORT;
        case YUVPlane::U:
        case YUVPlane::V:
            FATAL("Invalid plane:%d for format:%d", plane, format);
            return 0;
        }
    default:
        FATAL("Invalid format:%d", format);
        return 0;
    }
}

// NV12 and YUV420 are all packed
static void NV12ToYUV420PlanarInPlaceConvert(int nWidth,
                                             int nHeight,
                                             uint8_t* pFrame,
                                             uint8_t* pQuad) {
    std::vector<uint8_t> tmp;
    if (pQuad == nullptr) {
        tmp.resize(nWidth * nHeight / 4);
        pQuad = tmp.data();
    }
    int nPitch = nWidth;
    uint8_t *puv = pFrame + nPitch * nHeight, *pu = puv,
            *pv = puv + nPitch * nHeight / 4;
    for (int y = 0; y < nHeight / 2; y++) {
        for (int x = 0; x < nWidth / 2; x++) {
            pu[y * nPitch / 2 + x] = puv[y * nPitch + x * 2];
            pQuad[y * nWidth / 2 + x] = puv[y * nPitch + x * 2 + 1];
        }
    }
    memcpy(pv, pQuad, nWidth * nHeight / 4);
}

inline uint32_t alignToPower2(uint32_t val, uint32_t align) {
    return (val + (align - 1)) & ~(align - 1);
}

// getYUVOffsets(), given a YUV-formatted buffer that is arranged
// according to the spec
// https://developer.android.com/reference/android/graphics/ImageFormat.html#YUV
// In particular, Android YUV widths are aligned to 16 pixels.
// Inputs:
// |yv12|: the YUV-formatted buffer
// Outputs:
// |yOffset|: offset into |yv12| of the start of the Y component
// |uOffset|: offset into |yv12| of the start of the U component
// |vOffset|: offset into |yv12| of the start of the V component
static void getYUVOffsets(int width,
                          int height,
                          FrameworkFormat format,
                          uint32_t* yOffset,
                          uint32_t* uOffset,
                          uint32_t* vOffset,
                          uint32_t* yWidth,
                          uint32_t* cWidth) {
    uint32_t yStride, cStride, cHeight, cSize;
    switch (format) {
    case FRAMEWORK_FORMAT_YV12:
        // Luma stride is 32 bytes aligned.
        yStride = alignToPower2(width, 32);
        // Chroma stride is 16 bytes aligned.
        cStride = alignToPower2(yStride / 2, 16);
        cHeight = height / 2;
        cSize = cStride * cHeight;
        *yOffset = 0;
        *vOffset = yStride * height;
        *uOffset = (*vOffset) + cSize;
        *yWidth = yStride;
        *cWidth = cStride;
        break;
    case FRAMEWORK_FORMAT_YUV_420_888:
        if (feature_is_enabled(kFeature_YUV420888toNV21)) {
            yStride = width;
            cStride = yStride / 2;
            cHeight = height / 2;
            *yOffset = 0;
            *vOffset = yStride * height;
            *uOffset = (*vOffset) + 1;
            *yWidth = yStride;
            *cWidth = cStride;
        } else {
            yStride = width;
            cStride = yStride / 2;
            cHeight = height / 2;
            cSize = cStride * cHeight;
            *yOffset = 0;
            *uOffset = yStride * height;
            *vOffset = (*uOffset) + cSize;
            *yWidth = yStride;
            *cWidth = cStride;
        }
        break;
    case FRAMEWORK_FORMAT_NV12:
        yStride = width;
        cStride = yStride / 2;
        cHeight = height / 2;
        cSize = cStride * cHeight;
        *yOffset = 0;
        *uOffset = yStride * height;
        *vOffset = (*uOffset) + 1;
        *yWidth = yStride;
        *cWidth = cStride;
        break;
    case FRAMEWORK_FORMAT_P010:
        *yWidth = width;
        *cWidth = width / 2;
        yStride = width * /*bytes per pixel=*/2;
        cStride = *cWidth * /*bytes per pixel=*/2;
        cHeight = height / 2;
        cSize = cStride * cHeight;
        *yOffset = 0;
        *uOffset = yStride * height;
        *vOffset = (*uOffset) + 2;
        break;
    case FRAMEWORK_FORMAT_GL_COMPATIBLE:
        FATAL("Input not a YUV format! (FRAMEWORK_FORMAT_GL_COMPATIBLE)");
    default:
        FATAL("Unknown format: 0x%x", format);
    }
}

// Allocates an OpenGL texture that is large enough for a single plane of
// a YUV buffer of the given format and returns the texture name in the
// `outTextureName` argument.
void YUVConverter::createYUVGLTex(GLenum textureUnit,
                                  GLsizei width,
                                  GLsizei height,
                                  FrameworkFormat format,
                                  YUVPlane plane,
                                  GLuint* outTextureName) {
    YUV_DEBUG_LOG("w:%d h:%d format:%d plane:%d", width, height, format, plane);

    s_gles2.glActiveTexture(textureUnit);
    s_gles2.glGenTextures(1, outTextureName);
    s_gles2.glBindTexture(GL_TEXTURE_2D, *outTextureName);
    s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    GLint unprevAlignment = 0;
    s_gles2.glGetIntegerv(GL_UNPACK_ALIGNMENT, &unprevAlignment);
    s_gles2.glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    const GLint textureFormat = getGlTextureFormat(format, plane);
    const GLenum pixelFormat = getGlPixelFormat(format, plane);
    const GLenum pixelType = getGlPixelType(format, plane);
    s_gles2.glTexImage2D(GL_TEXTURE_2D, 0, textureFormat, width, height, 0, pixelFormat, pixelType, NULL);
    s_gles2.glPixelStorei(GL_UNPACK_ALIGNMENT, unprevAlignment);
    s_gles2.glActiveTexture(GL_TEXTURE0);
}

static void readYUVTex(GLuint tex, FrameworkFormat format, YUVPlane plane, void* pixels) {
    YUV_DEBUG_LOG("format%d plane:%d pixels:%p", format, plane, pixels);

    GLuint prevTexture = 0;
    s_gles2.glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint*)&prevTexture);
    s_gles2.glBindTexture(GL_TEXTURE_2D, tex);
    GLint prevAlignment = 0;
    s_gles2.glGetIntegerv(GL_PACK_ALIGNMENT, &prevAlignment);
    s_gles2.glPixelStorei(GL_PACK_ALIGNMENT, 1);
    const GLenum pixelFormat = getGlPixelFormat(format, plane);
    const GLenum pixelType = getGlPixelType(format, plane);
    if (s_gles2.glGetTexImage) {
        s_gles2.glGetTexImage(GL_TEXTURE_2D, 0, pixelFormat, pixelType, pixels);
    } else {
        YUV_DEBUG_LOG("empty glGetTexImage");
    }

    s_gles2.glPixelStorei(GL_PACK_ALIGNMENT, prevAlignment);
    s_gles2.glBindTexture(GL_TEXTURE_2D, prevTexture);
}

// Updates a given YUV buffer's plane texture at the coordinates
// (x, y, width, height), with the raw YUV data in |pixels|.  We
// cannot view the result properly until after conversion; this is
// to be used only as input to the conversion shader.
static void subUpdateYUVGLTex(GLenum texture_unit,
                              GLuint tex,
                              int x,
                              int y,
                              int width,
                              int height,
                              FrameworkFormat format,
                              YUVPlane plane,
                              const void* pixels) {
    YUV_DEBUG_LOG("x:%d y:%d w:%d h:%d format:%d plane:%d", x, y, width, height, format, plane);

    const GLenum pixelFormat = getGlPixelFormat(format, plane);
    const GLenum pixelType = getGlPixelType(format, plane);

    s_gles2.glActiveTexture(texture_unit);
    s_gles2.glBindTexture(GL_TEXTURE_2D, tex);
    GLint unprevAlignment = 0;
    s_gles2.glGetIntegerv(GL_UNPACK_ALIGNMENT, &unprevAlignment);
    s_gles2.glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    s_gles2.glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, pixelFormat, pixelType, pixels);
    s_gles2.glPixelStorei(GL_UNPACK_ALIGNMENT, unprevAlignment);
    s_gles2.glActiveTexture(GL_TEXTURE0);
}

void YUVConverter::createYUVGLShader() {
    YUV_DEBUG_LOG("format:%d", mFormat);

    // P010 needs uint samplers.
    if (mFormat == FRAMEWORK_FORMAT_P010 && !mHasGlsl3Support) {
        return;
    }

    static const char kVertShader[] = R"(
precision highp float;
attribute mediump vec4 aPosition;
attribute highp vec2 aTexCoord;
varying highp vec2 vTexCoord;
void main(void) {
  gl_Position = aPosition;
  vTexCoord = aTexCoord;
}
    )";

    static const char kFragShaderVersion3[] = R"(#version 300 es)";

    static const char kFragShaderBegin[] = R"(
precision highp float;

varying highp vec2 vTexCoord;

uniform highp float uYWidthCutoff;
uniform highp float uCWidthCutoff;
    )";

    static const char kSamplerUniforms[] = R"(
uniform sampler2D uSamplerY;
uniform sampler2D uSamplerU;
uniform sampler2D uSamplerV;
    )";
    static const char kSamplerUniformsUint[] = R"(
uniform usampler2D uSamplerY;
uniform usampler2D uSamplerU;
uniform usampler2D uSamplerV;
    )";

    static const char kFragShaderMainBegin[] = R"(
void main(void) {
    highp vec2 yTexCoords = vTexCoord;
    highp vec2 uvTexCoords = vTexCoord;

    // For textures with extra padding for alignment (e.g. YV12 pads to 16),
    // scale the coordinates to only sample from the non-padded area.
    yTexCoords.x *= uYWidthCutoff;
    uvTexCoords.y *= uCWidthCutoff;

    highp vec3 yuv;
)";

    static const char kSampleY[] = R"(
    yuv[0] = texture2D(uSamplerY, yTexCoords).r;
    )";
    static const char kSampleUV[] = R"(
    yuv[1] = texture2D(uSamplerU, uvTexCoords).r;
    yuv[2] = texture2D(uSamplerV, uvTexCoords).r;
    )";
    static const char kSampleInterleavedUV[] = R"(
    // Note: uSamplerU and vSamplerV refer to the same texture.
    yuv[1] = texture2D(uSamplerU, uvTexCoords).r;
    yuv[2] = texture2D(uSamplerV, uvTexCoords).g;
    )";
    static const char kSampleInterleavedVU[] = R"(
    // Note: uSamplerU and vSamplerV refer to the same texture.
    yuv[1] = texture2D(uSamplerU, uvTexCoords).g;
    yuv[2] = texture2D(uSamplerV, uvTexCoords).r;
    )";

    static const char kSampleP010[] = R"(
        uint yRaw = texture(uSamplerY, yTexCoords).r;
        uint uRaw = texture(uSamplerU, uvTexCoords).r;
        uint vRaw = texture(uSamplerV, uvTexCoords).g;

        // P010 values are stored in the upper 10-bits of 16-bit unsigned shorts.
        yuv[0] = float(yRaw >> 6) / 1023.0;
        yuv[1] = float(uRaw >> 6) / 1023.0;
        yuv[2] = float(vRaw >> 6) / 1023.0;
    )";

    static const char kFragShaderMainEnd[] = R"(
    yuv[0] = yuv[0] - 0.0625;
    yuv[1] = 0.96 * (yuv[1] - 0.5);
    yuv[2] = (yuv[2] - 0.5);

    highp float yscale = 1.1643835616438356;
    highp vec3 rgb = mat3(            yscale,               yscale,            yscale,
                                           0, -0.39176229009491365, 2.017232142857143,
                          1.5960267857142856,  -0.8129676472377708,                 0) * yuv;

    gl_FragColor = vec4(rgb, 1.0);
}
    )";

    std::string vertShaderSource(kVertShader);
    std::string fragShaderSource;

    if (mFormat == FRAMEWORK_FORMAT_P010) {
        fragShaderSource += kFragShaderVersion3;
    }

    fragShaderSource += kFragShaderBegin;

    if (mFormat == FRAMEWORK_FORMAT_P010) {
        fragShaderSource += kSamplerUniformsUint;
    } else {
        fragShaderSource += kSamplerUniforms;
    }

    fragShaderSource += kFragShaderMainBegin;

    switch (mFormat) {
    case FRAMEWORK_FORMAT_NV12:
    case FRAMEWORK_FORMAT_YUV_420_888:
    case FRAMEWORK_FORMAT_YV12:
        fragShaderSource += kSampleY;
        if (isInterleaved(mFormat)) {
            if (getInterleaveDirection(mFormat) == YUVInterleaveDirection::UV) {
                fragShaderSource += kSampleInterleavedUV;
            } else {
                fragShaderSource += kSampleInterleavedVU;
            }
        } else {
            fragShaderSource += kSampleUV;
        }
        break;
    case FRAMEWORK_FORMAT_P010:
        fragShaderSource += kSampleP010;
        break;
    default:
        FATAL("%s: invalid format:%d", __FUNCTION__, mFormat);
        return;
    }

    fragShaderSource += kFragShaderMainEnd;

    YUV_DEBUG_LOG("format:%d vert-source:%s frag-source:%s", mFormat, vertShaderSource.c_str(), fragShaderSource.c_str());

    const GLchar* const vertShaderSourceChars = vertShaderSource.c_str();
    const GLchar* const fragShaderSourceChars = fragShaderSource.c_str();
    const GLint vertShaderSourceLen = vertShaderSource.length();
    const GLint fragShaderSourceLen = fragShaderSource.length();

    GLuint vertShader = s_gles2.glCreateShader(GL_VERTEX_SHADER);
    GLuint fragShader = s_gles2.glCreateShader(GL_FRAGMENT_SHADER);
    s_gles2.glShaderSource(vertShader, 1, &vertShaderSourceChars, &vertShaderSourceLen);
    s_gles2.glShaderSource(fragShader, 1, &fragShaderSourceChars, &fragShaderSourceLen);
    s_gles2.glCompileShader(vertShader);
    s_gles2.glCompileShader(fragShader);

    for (GLuint shader : {vertShader, fragShader}) {
        GLint status = GL_FALSE;
        s_gles2.glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
        if (status == GL_FALSE) {
            GLchar error[1024];
            s_gles2.glGetShaderInfoLog(shader, sizeof(error), nullptr, &error[0]);
            FATAL("Failed to compile YUV conversion shader: %s", error);
            s_gles2.glDeleteShader(shader);
            return;
        }
    }

    mProgram = s_gles2.glCreateProgram();
    s_gles2.glAttachShader(mProgram, vertShader);
    s_gles2.glAttachShader(mProgram, fragShader);
    s_gles2.glLinkProgram(mProgram);

    GLint status = GL_FALSE;
    s_gles2.glGetProgramiv(mProgram, GL_LINK_STATUS, &status);
    if (status == GL_FALSE) {
        GLchar error[1024];
        s_gles2.glGetProgramInfoLog(mProgram, sizeof(error), 0, &error[0]);
        FATAL("Failed to link YUV conversion program: %s", error);
        s_gles2.glDeleteProgram(mProgram);
        mProgram = 0;
        return;
    }

    mUniformLocYWidthCutoff = s_gles2.glGetUniformLocation(mProgram, "uYWidthCutoff");
    mUniformLocCWidthCutoff = s_gles2.glGetUniformLocation(mProgram, "uCWidthCutoff");
    mUniformLocSamplerY = s_gles2.glGetUniformLocation(mProgram, "uSamplerY");
    mUniformLocSamplerU = s_gles2.glGetUniformLocation(mProgram, "uSamplerU");
    mUniformLocSamplerV = s_gles2.glGetUniformLocation(mProgram, "uSamplerV");
    mAttributeLocPos = s_gles2.glGetAttribLocation(mProgram, "aPosition");
    mAttributeLocTexCoord = s_gles2.glGetAttribLocation(mProgram, "aTexCoord");

    s_gles2.glDeleteShader(vertShader);
    s_gles2.glDeleteShader(fragShader);
}

void YUVConverter::createYUVGLFullscreenQuad() {
    s_gles2.glGenBuffers(1, &mQuadVertexBuffer);
    s_gles2.glGenBuffers(1, &mQuadIndexBuffer);

    static const float kVertices[] = {
        +1, -1, +0, +1, +0,
        +1, +1, +0, +1, +1,
        -1, +1, +0, +0, +1,
        -1, -1, +0, +0, +0,
    };

    static const GLubyte kIndices[] = { 0, 1, 2, 2, 3, 0 };

    s_gles2.glBindBuffer(GL_ARRAY_BUFFER, mQuadVertexBuffer);
    s_gles2.glBufferData(GL_ARRAY_BUFFER, sizeof(kVertices), kVertices, GL_STATIC_DRAW);
    s_gles2.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mQuadIndexBuffer);
    s_gles2.glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(kIndices), kIndices, GL_STATIC_DRAW);
}

static void doYUVConversionDraw(GLuint program,
                                GLint uniformLocYWidthCutoff,
                                GLint uniformLocCWidthCutoff,
                                GLint uniformLocYSampler,
                                GLint uniformLocUSampler,
                                GLint uniformLocVSampler,
                                GLint attributeLocTexCoord,
                                GLint attributeLocPos,
                                GLuint quadVertexBuffer,
                                GLuint quadIndexBuffer,
                                float uYWidthCutoff,
                                float uCWidthCutoff) {
    const GLsizei kVertexAttribStride = 5 * sizeof(GL_FLOAT);
    const GLvoid* kVertexAttribPosOffset = (GLvoid*)0;
    const GLvoid* kVertexAttribCoordOffset = (GLvoid*)(3 * sizeof(GL_FLOAT));

    s_gles2.glUseProgram(program);

    s_gles2.glUniform1f(uniformLocYWidthCutoff, uYWidthCutoff);
    s_gles2.glUniform1f(uniformLocCWidthCutoff, uCWidthCutoff);

    s_gles2.glUniform1i(uniformLocYSampler, 0);
    s_gles2.glUniform1i(uniformLocUSampler, 1);
    s_gles2.glUniform1i(uniformLocVSampler, 2);

    s_gles2.glBindBuffer(GL_ARRAY_BUFFER, quadVertexBuffer);
    s_gles2.glEnableVertexAttribArray(attributeLocPos);
    s_gles2.glEnableVertexAttribArray(attributeLocTexCoord);

    s_gles2.glVertexAttribPointer(attributeLocPos, 3, GL_FLOAT, false,
                                  kVertexAttribStride,
                                  kVertexAttribPosOffset);
    s_gles2.glVertexAttribPointer(attributeLocTexCoord, 2, GL_FLOAT, false,
                                  kVertexAttribStride,
                                  kVertexAttribCoordOffset);

    s_gles2.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quadIndexBuffer);
    s_gles2.glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0);

    s_gles2.glDisableVertexAttribArray(attributeLocPos);
    s_gles2.glDisableVertexAttribArray(attributeLocTexCoord);
}

// initialize(): allocate GPU memory for YUV components,
// and create shaders and vertex data.
YUVConverter::YUVConverter(int width, int height, FrameworkFormat format)
    : mWidth(width),
      mHeight(height),
      mFormat(format),
      mColorBufferFormat(format) {}

void YUVConverter::init(int width, int height, FrameworkFormat format) {
    YUV_DEBUG_LOG("w:%d h:%d format:%d", width, height, format);

    uint32_t yOffset, uOffset, vOffset, ywidth, cwidth, cheight;
    getYUVOffsets(width, height, mFormat, &yOffset, &uOffset, &vOffset, &ywidth, &cwidth);
    cheight = height / 2;

    mWidth = width;
    mHeight = height;
    if (!mTextureY) {
        createYUVGLTex(GL_TEXTURE0, ywidth, height, mFormat, YUVPlane::Y, &mTextureY);
    }
    if (isInterleaved(mFormat)) {
        if (!mTextureU) {
            createYUVGLTex(GL_TEXTURE1, cwidth, cheight, mFormat, YUVPlane::UV, &mTextureU);
            mTextureV = mTextureU;
        }
    } else {
        if (!mTextureU) {
            createYUVGLTex(GL_TEXTURE1, cwidth, cheight, mFormat, YUVPlane::U, &mTextureU);
        }
        if (!mTextureV) {
            createYUVGLTex(GL_TEXTURE2, cwidth, cheight, mFormat, YUVPlane::V, &mTextureV);
        }
    }

    int glesMajor;
    int glesMinor;
    emugl::getGlesVersion(&glesMajor, &glesMinor);
    mHasGlsl3Support = glesMajor >= 3;
    YUV_DEBUG_LOG("YUVConverter has GLSL ES 3 support:%s (major:%d minor:%d", (mHasGlsl3Support ? "yes" : "no"), glesMajor, glesMinor);

    createYUVGLShader();
    createYUVGLFullscreenQuad();
}

void YUVConverter::saveGLState() {
    s_gles2.glGetFloatv(GL_VIEWPORT, mCurrViewport);
    s_gles2.glGetIntegerv(GL_ACTIVE_TEXTURE, &mCurrTexUnit);
    s_gles2.glGetIntegerv(GL_TEXTURE_BINDING_2D, &mCurrTexBind);
    s_gles2.glGetIntegerv(GL_CURRENT_PROGRAM, &mCurrProgram);
    s_gles2.glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &mCurrVbo);
    s_gles2.glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &mCurrIbo);
}

void YUVConverter::restoreGLState() {
    s_gles2.glViewport(mCurrViewport[0], mCurrViewport[1],
                       mCurrViewport[2], mCurrViewport[3]);
    s_gles2.glActiveTexture(mCurrTexUnit);
    s_gles2.glUseProgram(mCurrProgram);
    s_gles2.glBindBuffer(GL_ARRAY_BUFFER, mCurrVbo);
    s_gles2.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mCurrIbo);
}

uint32_t YUVConverter::getDataSize() {
    uint32_t align = (mFormat == FRAMEWORK_FORMAT_YV12) ? 16 : 1;
    uint32_t yStride = (mWidth + (align - 1)) & ~(align - 1);
    uint32_t uvStride = (yStride / 2 + (align - 1)) & ~(align - 1);
    uint32_t uvHeight = mHeight / 2;
    uint32_t dataSize = yStride * mHeight + 2 * (uvHeight * uvStride);
    return dataSize;
}

void YUVConverter::readPixels(uint8_t* pixels, uint32_t pixels_size) {
    YUV_DEBUG_LOG("w:%d h:%d format:%d pixels:%p pixels-size:%d", mWidth, mHeight, mFormat, pixels, pixels_size);

    uint32_t yOffset, uOffset, vOffset, ywidth, cwidth;
    getYUVOffsets(mWidth, mHeight, mFormat, &yOffset, &uOffset, &vOffset, &ywidth, &cwidth);

    if (isInterleaved(mFormat)) {
        readYUVTex(mTextureV, mFormat, YUVPlane::UV, pixels + std::min(uOffset, vOffset));
    } else {
        readYUVTex(mTextureU, mFormat, YUVPlane::U, pixels + uOffset);
        readYUVTex(mTextureV, mFormat, YUVPlane::V, pixels + vOffset);
    }

    if (mFormat == FRAMEWORK_FORMAT_NV12 && mColorBufferFormat == FRAMEWORK_FORMAT_YUV_420_888) {
        NV12ToYUV420PlanarInPlaceConvert(mWidth, mHeight, pixels, pixels);
    }

    // Read the Y plane last because so that we can use it as a scratch space.
    readYUVTex(mTextureY, mFormat, YUVPlane::Y, pixels + yOffset);
}

void YUVConverter::swapTextures(uint32_t type, uint32_t* textures) {
    FrameworkFormat format = static_cast<FrameworkFormat>(type);

    if (isInterleaved(format)) {
        std::swap(textures[0], mTextureY);
        std::swap(textures[1], mTextureU);
        mTextureV = mTextureU;
    } else {
        std::swap(textures[0], mTextureY);
        std::swap(textures[1], mTextureU);
        std::swap(textures[2], mTextureV);
    }

    mFormat = format;
}

void YUVConverter::drawConvert(int x, int y, int width, int height, const char* pixels) {
    YUV_DEBUG_LOG("x:%d y:%d w:%d h:%d", x, y, width, height);

    saveGLState();
    if (pixels && (width != mWidth || height != mHeight)) {
        reset();
    }

    if (mProgram == 0) {
        init(width, height, mFormat);
    }

    if (mFormat == FRAMEWORK_FORMAT_P010 && !mHasGlsl3Support) {
        // TODO: perhaps fallback to just software conversion.
        return;
    }

    s_gles2.glViewport(x, y, width, height);
    uint32_t yOffset, uOffset, vOffset, ywidth, cwidth, cheight;
    getYUVOffsets(width, height, mFormat, &yOffset, &uOffset, &vOffset, &ywidth, &cwidth);
    cheight = height / 2;
    updateCutoffs(width, ywidth, width / 2, cwidth);

    if (pixels) {
        subUpdateYUVGLTex(GL_TEXTURE0, mTextureY, x, y, ywidth, height, mFormat, YUVPlane::Y, pixels + yOffset);
        if (isInterleaved(mFormat)) {
            subUpdateYUVGLTex(GL_TEXTURE1, mTextureU, x, y, cwidth, cheight, mFormat, YUVPlane::UV, pixels + std::min(uOffset, vOffset));
        } else {
            subUpdateYUVGLTex(GL_TEXTURE1, mTextureU, x, y, cwidth, cheight, mFormat, YUVPlane::U, pixels + uOffset);
            subUpdateYUVGLTex(GL_TEXTURE2, mTextureV, x, y, cwidth, cheight, mFormat, YUVPlane::V, pixels + vOffset);
        }
    } else {
        // special case: draw from texture, only support NV12 for now
        // as cuvid's native format is NV12.
        // TODO: add more formats if there are such needs in the future.
        assert(mFormat == FRAMEWORK_FORMAT_NV12);
    }

    s_gles2.glActiveTexture(GL_TEXTURE0);
    s_gles2.glBindTexture(GL_TEXTURE_2D, mTextureY);
    s_gles2.glActiveTexture(GL_TEXTURE1);
    s_gles2.glBindTexture(GL_TEXTURE_2D, mTextureU);
    s_gles2.glActiveTexture(GL_TEXTURE2);
    s_gles2.glBindTexture(GL_TEXTURE_2D, mTextureV);

    doYUVConversionDraw(mProgram,
                        mUniformLocYWidthCutoff,
                        mUniformLocCWidthCutoff,
                        mUniformLocSamplerY,
                        mUniformLocSamplerU,
                        mUniformLocSamplerV,
                        mAttributeLocTexCoord,
                        mAttributeLocPos,
                        mQuadVertexBuffer,
                        mQuadIndexBuffer,
                        mYWidthCutoff,
                        mCWidthCutoff);

    restoreGLState();
}

void YUVConverter::updateCutoffs(float width, float ywidth,
                                 float halfwidth, float cwidth) {
    switch (mFormat) {
    case FRAMEWORK_FORMAT_YV12:
        mYWidthCutoff = ((float)width) / ((float)ywidth);
        mCWidthCutoff = ((float)halfwidth) / ((float)cwidth);
        break;
    case FRAMEWORK_FORMAT_NV12:
    case FRAMEWORK_FORMAT_P010:
    case FRAMEWORK_FORMAT_YUV_420_888:
        mYWidthCutoff = 1.0f;
        mCWidthCutoff = 1.0f;
        break;
    case FRAMEWORK_FORMAT_GL_COMPATIBLE:
        FATAL("Input not a YUV format!");
    }
}

void YUVConverter::reset() {
    if (mQuadIndexBuffer) s_gles2.glDeleteBuffers(1, &mQuadIndexBuffer);
    if (mQuadVertexBuffer) s_gles2.glDeleteBuffers(1, &mQuadVertexBuffer);
    if (mProgram) s_gles2.glDeleteProgram(mProgram);
    if (mTextureY) s_gles2.glDeleteTextures(1, &mTextureY);
    if (isInterleaved(mFormat)) {
        if (mTextureU) s_gles2.glDeleteTextures(1, &mTextureU);
    } else {
        if (mTextureU) s_gles2.glDeleteTextures(1, &mTextureU);
        if (mTextureV) s_gles2.glDeleteTextures(1, &mTextureV);
    }
    mQuadIndexBuffer = 0;
    mQuadVertexBuffer = 0;
    mProgram = 0;
    mTextureY = 0;
    mTextureU = 0;
    mTextureV = 0;
}

YUVConverter::~YUVConverter() {
    reset();
}
