/*
 Copyright (C) 2016 Igalia S.L.

 This library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Library General Public
 License as published by the Free Software Foundation; either
 version 2 of the License, or (at your option) any later version.

 This library is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 Library General Public License for more details.

 You should have received a copy of the GNU Library General Public License
 along with this library; see the file COPYING.LIB.  If not, write to
 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 Boston, MA 02110-1301, USA.
 */


#include "config.h"
#include "VideoTextureCopierGStreamer.h"

#if USE(GSTREAMER_GL)

#include "FloatRect.h"
#include "GLContext.h"
#include "ImageOrientation.h"
#include "TextureMapperShaderProgram.h"

namespace WebCore {

VideoTextureCopierGStreamer::VideoTextureCopierGStreamer(ColorConversion colorConversion)
{
    GLContext* previousContext = GLContext::current();
    ASSERT(previousContext);
    PlatformDisplay::sharedDisplayForCompositing().sharingGLContext()->makeContextCurrent();

    glGenFramebuffers(1, &m_framebuffer);
    glGenTextures(1, &m_resultTexture);

#if !USE(OPENGL_ES)
    // For OpenGL > 3.2 we need to have a VAO.
    if (GLContext::current()->version() >= 320)
        glGenVertexArrays(1, &m_vao);
#endif

    static const GLfloat vertices[] = { 0, 0, 1, 0, 1, 1, 0, 1 };
    glGenBuffers(1, &m_vbo);
    glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 8, vertices, GL_STATIC_DRAW);

    updateColorConversionMatrix(colorConversion);
    updateTextureSpaceMatrix();

    previousContext->makeContextCurrent();
}

VideoTextureCopierGStreamer::~VideoTextureCopierGStreamer()
{
    GLContext* previousContext = GLContext::current();
    PlatformDisplay::sharedDisplayForCompositing().sharingGLContext()->makeContextCurrent();

    glDeleteFramebuffers(1, &m_framebuffer);
    glDeleteBuffers(1, &m_vbo);
    glDeleteTextures(1, &m_resultTexture);
#if !USE(OPENGL_ES)
    if (m_vao)
        glDeleteVertexArrays(1, &m_vao);
#endif
    m_shaderProgram = nullptr;

    if (previousContext)
        previousContext->makeContextCurrent();
}

void VideoTextureCopierGStreamer::updateColorConversionMatrix(ColorConversion colorConversion)
{
    switch (colorConversion) {
    case ColorConversion::ConvertBGRAToRGBA:
        m_colorConversionMatrix.setMatrix(0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0);
        break;
    case ColorConversion::ConvertARGBToRGBA:
        m_colorConversionMatrix.setMatrix(0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0);
        break;
    case ColorConversion::NoConvert:
        m_colorConversionMatrix.makeIdentity();
        break;
    default:
        RELEASE_ASSERT_NOT_REACHED();
    }
}

void VideoTextureCopierGStreamer::updateTextureSpaceMatrix()
{
    m_textureSpaceMatrix.makeIdentity();

    switch (m_orientation) {
    case ImageOrientation::OriginTopLeft:
        break;
    case ImageOrientation::OriginRightTop:
        m_textureSpaceMatrix.rotate(-90);
        m_textureSpaceMatrix.translate(-1, 0);
        break;
    case ImageOrientation::OriginBottomRight:
        m_textureSpaceMatrix.rotate(180);
        m_textureSpaceMatrix.translate(-1, -1);
        break;
    case ImageOrientation::OriginLeftBottom:
        m_textureSpaceMatrix.rotate(-270);
        m_textureSpaceMatrix.translate(0, -1);
        break;
    default:
        ASSERT_NOT_REACHED();
    }

    if (!m_flipY) {
        m_textureSpaceMatrix.flipY();
        m_textureSpaceMatrix.translate(0, -1);
    }
}

void VideoTextureCopierGStreamer::updateTransformationMatrix()
{
    FloatRect targetRect = FloatRect(FloatPoint(), m_size);
    TransformationMatrix identityMatrix;
    m_modelViewMatrix = TransformationMatrix(identityMatrix).multiply(TransformationMatrix::rectToRect(FloatRect(0, 0, 1, 1), targetRect));

    // Taken from TextureMapperGL.
    const float nearValue = 9999999;
    const float farValue = -99999;

    m_projectionMatrix = TransformationMatrix(2.0 / float(m_size.width()), 0, 0, 0,
        0, (-2.0) / float(m_size.height()), 0, 0,
        0, 0, -2.f / (farValue - nearValue), 0,
        -1, 1, -(farValue + nearValue) / (farValue - nearValue), 1);
}

bool VideoTextureCopierGStreamer::copyVideoTextureToPlatformTexture(TextureMapperPlatformLayerBuffer& inputTexture, IntSize& frameSize, GLuint outputTexture, GLenum outputTarget, GLint level, GLenum internalFormat, GLenum format, GLenum type, bool flipY, ImageOrientation sourceOrientation)
{
    if (!m_framebuffer || !m_vbo || frameSize.isEmpty())
        return false;

    if (m_size != frameSize) {
        m_size = frameSize;
        updateTransformationMatrix();
    }

    if (m_flipY != flipY || m_orientation != sourceOrientation) {
        m_flipY = flipY;
        m_orientation = sourceOrientation;
        updateTextureSpaceMatrix();
    }

    // Save previous context and activate the sharing one.
    GLContext* previousContext = GLContext::current();
    ASSERT(previousContext);
    PlatformDisplay::sharedDisplayForCompositing().sharingGLContext()->makeContextCurrent();

    // Determine what shader program to use and create it if necessary.
    using Buffer = TextureMapperPlatformLayerBuffer;
    TextureMapperShaderProgram::Options options;
    WTF::switchOn(inputTexture.textureVariant(),
        [&](const Buffer::RGBTexture&) { options = TextureMapperShaderProgram::TextureRGB; },
        [&](const Buffer::YUVTexture& texture) {
            switch (texture.numberOfPlanes) {
            case 1:
                ASSERT(texture.yuvPlane[0] == texture.yuvPlane[1] && texture.yuvPlane[1] == texture.yuvPlane[2]);
                ASSERT(texture.yuvPlaneOffset[0] == 2 && texture.yuvPlaneOffset[1] == 1 && !texture.yuvPlaneOffset[2]);
                options = TextureMapperShaderProgram::TexturePackedYUV;
                break;
            case 2:
                ASSERT(!texture.yuvPlaneOffset[0]);
                options = texture.yuvPlaneOffset[1] ? TextureMapperShaderProgram::TextureNV21 : TextureMapperShaderProgram::TextureNV12;
                break;
            case 3:
                ASSERT(!texture.yuvPlaneOffset[0] && !texture.yuvPlaneOffset[1] && !texture.yuvPlaneOffset[2]);
                options = TextureMapperShaderProgram::TextureYUV;
                break;
            }
        });

    if (options != m_shaderOptions) {
        m_shaderProgram = TextureMapperShaderProgram::create(options);
        m_shaderOptions = options;
    }
    if (!m_shaderProgram) {
        previousContext->makeContextCurrent();
        return false;
    }

    // Save previous bound framebuffer, texture and viewport.
    GLint boundFramebuffer = 0;
    GLint boundTexture = 0;
    GLint previousViewport[4] = { 0, 0, 0, 0};
    glGetIntegerv(GL_FRAMEBUFFER_BINDING, &boundFramebuffer);
    glGetIntegerv(GL_TEXTURE_BINDING_2D, &boundTexture);
    glGetIntegerv(GL_VIEWPORT, previousViewport);

    // Use our own output texture if we are not given one.
    if (!outputTexture)
        outputTexture = m_resultTexture;

    // Set proper parameters to the output texture and allocate uninitialized memory for it.
    glBindTexture(outputTarget, outputTexture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexImage2D(outputTarget, level, internalFormat, m_size.width(), m_size.height(), 0, format, type, nullptr);

    // Bind framebuffer to paint and attach the destination texture to it.
    glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, outputTexture, 0);

    // Set the viewport.
    glViewport(0, 0, m_size.width(), m_size.height());

    // Set program parameters.
    glUseProgram(m_shaderProgram->programID());

    WTF::switchOn(inputTexture.textureVariant(),
        [&](const Buffer::RGBTexture& texture) {
            glUniform1i(m_shaderProgram->samplerLocation(), 0);

            glActiveTexture(GL_TEXTURE0);
            glBindTexture(GL_TEXTURE_2D, texture.id);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        },
        [&](const Buffer::YUVTexture& texture) {
            switch (texture.numberOfPlanes) {
            case 1:
                glUniform1i(m_shaderProgram->samplerLocation(), texture.yuvPlane[0]);
                break;
            case 2:
                glUniform1i(m_shaderProgram->samplerYLocation(), texture.yuvPlane[0]);
                glUniform1i(m_shaderProgram->samplerULocation(), texture.yuvPlane[1]);
                break;
            case 3:
                glUniform1i(m_shaderProgram->samplerYLocation(), texture.yuvPlane[0]);
                glUniform1i(m_shaderProgram->samplerULocation(), texture.yuvPlane[1]);
                glUniform1i(m_shaderProgram->samplerVLocation(), texture.yuvPlane[2]);
                break;
            }
            glUniformMatrix3fv(m_shaderProgram->yuvToRgbLocation(), 1, GL_FALSE, static_cast<const GLfloat *>(&texture.yuvToRgbMatrix[0]));

            for (int i = texture.numberOfPlanes - 1; i >= 0; --i) {
                glActiveTexture(GL_TEXTURE0 + i);
                glBindTexture(GL_TEXTURE_2D, texture.planes[i]);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
            }
        });

    m_shaderProgram->setMatrix(m_shaderProgram->modelViewMatrixLocation(), m_modelViewMatrix);
    m_shaderProgram->setMatrix(m_shaderProgram->projectionMatrixLocation(), m_projectionMatrix);
    m_shaderProgram->setMatrix(m_shaderProgram->textureSpaceMatrixLocation(), m_textureSpaceMatrix);
    m_shaderProgram->setMatrix(m_shaderProgram->textureColorSpaceMatrixLocation(), m_colorConversionMatrix);

    // Perform the copy.
#if !USE(OPENGL_ES)
    if (GLContext::current()->version() >= 320 && m_vao)
        glBindVertexArray(m_vao);
#endif
    glEnableVertexAttribArray(m_shaderProgram->vertexLocation());
    glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
    glVertexAttribPointer(m_shaderProgram->vertexLocation(), 2, GL_FLOAT, false, 0, 0);
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glDisableVertexAttribArray(m_shaderProgram->vertexLocation());
    glUseProgram(0);

    // Restore previous bindings and viewport.
    glBindFramebuffer(GL_FRAMEBUFFER, boundFramebuffer);
    glBindTexture(outputTarget, boundTexture);
    glViewport(previousViewport[0], previousViewport[1], previousViewport[2], previousViewport[3]);

    bool ok = (glGetError() == GL_NO_ERROR);

    // Restore previous context.
    previousContext->makeContextCurrent();
    return ok;
}

} // namespace WebCore

#endif // USE(GSTREAMER_GL)
