// 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 "TextureDraw.h"

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

#include <algorithm>
#include <string>

#include "OpenGLESDispatch/DispatchTables.h"
#include "host-common/crash_reporter.h"
#include "host-common/logging.h"

#ifndef NDEBUG
#define DEBUG_TEXTURE_DRAW
#endif

namespace gfxstream {
namespace gl {
namespace {

// Helper function to create a new shader.
// |shaderType| is the shader type (e.g. GL_VERTEX_SHADER).
// |shaderText| is a 0-terminated C string for the shader source to use.
// On success, return the handle of the new compiled shader, or 0 on failure.
GLuint createShader(GLint shaderType, const char* shaderText) {
    // Create new shader handle and attach source.
    GLuint shader = s_gles2.glCreateShader(shaderType);
    if (!shader) {
        return 0;
    }
    const GLchar* text = static_cast<const GLchar*>(shaderText);
    const GLint textLen = ::strlen(shaderText);
    s_gles2.glShaderSource(shader, 1, &text, &textLen);

    // Compiler the shader.
    GLint success;
    s_gles2.glCompileShader(shader);
    s_gles2.glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
    if (success == GL_FALSE) {
        GLint infoLogLength;
        s_gles2.glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
        std::string infoLog(infoLogLength + 1, '\0');
        fprintf(stderr, "%s: TextureDraw shader compile failed.\n", __func__);
        s_gles2.glGetShaderInfoLog(shader, infoLogLength, 0, &infoLog[0]);
        fprintf(stderr, "%s: Info log:\n%s\n", __func__,
                infoLog.c_str());
        fprintf(stderr, "%s: Source:\n%s\n", __func__,
                shaderText);
        s_gles2.glDeleteShader(shader);

        // No point in continuing as it's going to be a black screen.
        // Send a crash report.
        // emugl::emugl_crash_reporter(
        //     "FATAL: Could not compile shader for guest framebuffer blit. "
        //     "There may be an issue with the GPU drivers on your machine. "
        //     "Try using software rendering; launch the emulator "
        //     "from the command line with -gpu swiftshader_indirect. ");
    }

    return shader;
}

// No scaling / projection since we want to fill the whole viewport with
// the texture, hence a trivial vertex shader that only supports translation.
// Note: we used to have a proper free-angle rotation support in this shader,
//  but looks like SwiftShader doesn't support either complicated calculations
//  for gl_Position/varyings or just doesn't like trigonometric functions in
//  shader; anyway the new code has hardcoded texture coordinate mapping for
//  different rotation angles and works in both native OpenGL and SwiftShader.
const char kVertexShaderSource[] =
    "attribute vec4 position;\n"
    "attribute vec2 inCoord;\n"
    "varying vec2 outCoord;\n"
    "uniform vec2 translation;\n"
    "uniform vec2 scale;\n"
    "uniform vec2 coordTranslation;\n"
    "uniform vec2 coordScale;\n"

    "void main(void) {\n"
    "  gl_Position.xy = position.xy * scale.xy - translation.xy;\n"
    "  gl_Position.zw = position.zw;\n"
    "  outCoord = inCoord * coordScale + coordTranslation;\n"
    "}\n";

// Similarly, just interpolate texture coordinates.
const char kFragmentShaderSource[] =
    "#define kComposeModeDevice 2\n"
    "precision mediump float;\n"
    "varying lowp vec2 outCoord;\n"
    "uniform sampler2D tex;\n"
    "uniform float alpha;\n"
    "uniform int composeMode;\n"
    "uniform vec4 color ;\n"

    "void main(void) {\n"
    "  if (composeMode == kComposeModeDevice) {\n"
    "    gl_FragColor = alpha * texture2D(tex, outCoord);\n"
    "  } else {\n"
    "    gl_FragColor = alpha * color;\n"
    "  }\n"
    "}\n";

// Hard-coded arrays of vertex information.
struct Vertex {
    float pos[3];
    float coord[2];
};

const Vertex kVertices[] = {
    // 0 degree
    {{ +1, -1, +0 }, { +1, +0 }},
    {{ +1, +1, +0 }, { +1, +1 }},
    {{ -1, +1, +0 }, { +0, +1 }},
    {{ -1, -1, +0 }, { +0, +0 }},
    // 90 degree clock-wise
    {{ +1, -1, +0 }, { +1, +1 }},
    {{ +1, +1, +0 }, { +0, +1 }},
    {{ -1, +1, +0 }, { +0, +0 }},
    {{ -1, -1, +0 }, { +1, +0 }},
    // 180 degree clock-wise
    {{ +1, -1, +0 }, { +0, +1 }},
    {{ +1, +1, +0 }, { +0, +0 }},
    {{ -1, +1, +0 }, { +1, +0 }},
    {{ -1, -1, +0 }, { +1, +1 }},
    // 270 degree clock-wise
    {{ +1, -1, +0 }, { +0, +0 }},
    {{ +1, +1, +0 }, { +1, +0 }},
    {{ -1, +1, +0 }, { +1, +1 }},
    {{ -1, -1, +0 }, { +0, +1 }},
    // flip horizontally
    {{ +1, -1, +0 }, { +0, +0 }},
    {{ +1, +1, +0 }, { +0, +1 }},
    {{ -1, +1, +0 }, { +1, +1 }},
    {{ -1, -1, +0 }, { +1, +0 }},
    // flip vertically
    {{ +1, -1, +0 }, { +1, +1 }},
    {{ +1, +1, +0 }, { +1, +0 }},
    {{ -1, +1, +0 }, { +0, +0 }},
    {{ -1, -1, +0 }, { +0, +1 }},
    // flip source image horizontally, the rotate 90 degrees clock-wise
    {{ +1, -1, +0 }, { +0, +1 }},
    {{ +1, +1, +0 }, { +1, +1 }},
    {{ -1, +1, +0 }, { +1, +0 }},
    {{ -1, -1, +0 }, { +0, +0 }},
    // flip source image vertically, the rotate 90 degrees clock-wise
    {{ +1, -1, +0 }, { +1, +0 }},
    {{ +1, +1, +0 }, { +0, +0 }},
    {{ -1, +1, +0 }, { +0, +1 }},
    {{ -1, -1, +0 }, { +1, +1 }},
};

// Vertex indices for predefined rotation angles.
const GLubyte kIndices[] = {
    0, 1, 2, 2, 3, 0,      // 0
    4, 5, 6, 6, 7, 4,      // 90
    8, 9, 10, 10, 11, 8,   // 180
    12, 13, 14, 14, 15, 12, // 270
    16, 17, 18 ,18, 19, 16, // flip h
    20, 21, 22, 22, 23, 20, // flip v
    24, 25, 26, 26, 27, 24, // flip h, 90
    28, 29, 30, 30, 31, 28  // flip v, 90
};

const GLint kIndicesPerDraw = 6;

}  // namespace

TextureDraw::TextureDraw()
    : mVertexShader(0),
      mFragmentShader(0),
      mProgram(0),
      mCoordTranslation(-1),
      mCoordScale(-1),
      mPositionSlot(-1),
      mInCoordSlot(-1),
      mScaleSlot(-1),
      mTextureSlot(-1),
      mTranslationSlot(-1),
      mMaskTexture(0),
      mMaskTextureWidth(0),
      mMaskTextureHeight(0),
      mHaveNewMask(false),
      mMaskIsValid(false),
      mShouldReallocateTexture(true) {
    // Create shaders and program.
    mVertexShader = createShader(GL_VERTEX_SHADER, kVertexShaderSource);
    mFragmentShader = createShader(GL_FRAGMENT_SHADER, kFragmentShaderSource);

    mProgram = s_gles2.glCreateProgram();
    s_gles2.glAttachShader(mProgram, mVertexShader);
    s_gles2.glAttachShader(mProgram, mFragmentShader);

    GLint success;
    s_gles2.glLinkProgram(mProgram);
    s_gles2.glGetProgramiv(mProgram, GL_LINK_STATUS, &success);
    if (success == GL_FALSE) {
        GLchar messages[256];
        s_gles2.glGetProgramInfoLog(
                mProgram, sizeof(messages), 0, &messages[0]);
        ERR("%s: Could not create/link program: %s\n", __FUNCTION__, messages);
        s_gles2.glDeleteProgram(mProgram);
        mProgram = 0;
        return;
    }

    s_gles2.glUseProgram(mProgram);

    // Retrieve attribute/uniform locations.
    mPositionSlot = s_gles2.glGetAttribLocation(mProgram, "position");
    s_gles2.glEnableVertexAttribArray(mPositionSlot);

    mInCoordSlot = s_gles2.glGetAttribLocation(mProgram, "inCoord");
    s_gles2.glEnableVertexAttribArray(mInCoordSlot);

    mAlpha = s_gles2.glGetUniformLocation(mProgram, "alpha");
    mComposeMode = s_gles2.glGetUniformLocation(mProgram, "composeMode");
    mColor = s_gles2.glGetUniformLocation(mProgram, "color");
    mCoordTranslation = s_gles2.glGetUniformLocation(mProgram, "coordTranslation");
    mCoordScale = s_gles2.glGetUniformLocation(mProgram, "coordScale");
    mScaleSlot = s_gles2.glGetUniformLocation(mProgram, "scale");
    mTranslationSlot = s_gles2.glGetUniformLocation(mProgram, "translation");
    mTextureSlot = s_gles2.glGetUniformLocation(mProgram, "tex");

    // set default uniform values
    s_gles2.glUniform1f(mAlpha, 1.0);
    s_gles2.glUniform1i(mComposeMode, 2);
    s_gles2.glUniform2f(mTranslationSlot, 0.0, 0.0);
    s_gles2.glUniform2f(mScaleSlot, 1.0, 1.0);
    s_gles2.glUniform2f(mCoordTranslation, 0.0, 0.0);
    s_gles2.glUniform2f(mCoordScale, 1.0, 1.0);

#if 0
    printf("SLOTS position=%d inCoord=%d texture=%d translation=%d\n",
          mPositionSlot, mInCoordSlot, mTextureSlot, mTranslationSlot);
#endif

    // Create vertex and index buffers.
    s_gles2.glGenBuffers(1, &mVertexBuffer);
    s_gles2.glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
    s_gles2.glBufferData(
            GL_ARRAY_BUFFER, sizeof(kVertices), kVertices, GL_STATIC_DRAW);

    s_gles2.glGenBuffers(1, &mIndexBuffer);
    s_gles2.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
    s_gles2.glBufferData(GL_ELEMENT_ARRAY_BUFFER,
                         sizeof(kIndices),
                         kIndices,
                         GL_STATIC_DRAW);

    // Reset state.
    s_gles2.glUseProgram(0);
    s_gles2.glDisableVertexAttribArray(mPositionSlot);
    s_gles2.glDisableVertexAttribArray(mInCoordSlot);
    s_gles2.glBindBuffer(GL_ARRAY_BUFFER, 0);
    s_gles2.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    // Create a texture handle for use with an overlay mask
    s_gles2.glGenTextures(1, &mMaskTexture);
}

bool TextureDraw::drawImpl(GLuint texture, float rotation,
                           float dx, float dy, bool wantOverlay) {
    if (!mProgram) {
        ERR("%s: no program\n", __FUNCTION__);
        return false;
    }

    // TODO(digit): Save previous program state.

    s_gles2.glUseProgram(mProgram);

    s_gles2.glEnable(GL_BLEND);
    s_gles2.glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
#ifdef DEBUG_TEXTURE_DRAW
    GLenum err = s_gles2.glGetError();
    if (err != GL_NO_ERROR) {
        ERR("%s: Could not use program error=0x%x\n",
            __FUNCTION__, err);
    }
#endif

    // Setup the |position| attribute values.
    s_gles2.glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);

#ifdef DEBUG_TEXTURE_DRAW
    err = s_gles2.glGetError();
    if (err != GL_NO_ERROR) {
        ERR("%s: Could not bind GL_ARRAY_BUFFER error=0x%x\n",
            __FUNCTION__, err);
    }
#endif

    s_gles2.glEnableVertexAttribArray(mPositionSlot);
    s_gles2.glVertexAttribPointer(mPositionSlot,
                                  3,
                                  GL_FLOAT,
                                  GL_FALSE,
                                  sizeof(Vertex),
                                  0);

#ifdef DEBUG_TEXTURE_DRAW
    err = s_gles2.glGetError();
    if (err != GL_NO_ERROR) {
        ERR("%s: Could glVertexAttribPointer with mPositionSlot error=0x%x\n",
            __FUNCTION__, err);
    }
#endif

    // Setup the |inCoord| attribute values.
    s_gles2.glEnableVertexAttribArray(mInCoordSlot);
    s_gles2.glVertexAttribPointer(mInCoordSlot,
                                  2,
                                  GL_FLOAT,
                                  GL_FALSE,
                                  sizeof(Vertex),
                                  reinterpret_cast<GLvoid*>(
                                        static_cast<uintptr_t>(
                                                sizeof(float) * 3)));

    // setup the |texture| uniform value.
    s_gles2.glActiveTexture(GL_TEXTURE0);
    s_gles2.glBindTexture(GL_TEXTURE_2D, texture);
    s_gles2.glUniform1i(mTextureSlot, 0);

    // setup the |translation| uniform value.
    s_gles2.glUniform2f(mTranslationSlot, dx, dy);

#ifdef DEBUG_TEXTURE_DRAW
    // Validate program, just to be sure.
    s_gles2.glValidateProgram(mProgram);
    GLint validState = 0;
    s_gles2.glGetProgramiv(mProgram, GL_VALIDATE_STATUS, &validState);
    if (validState == GL_FALSE) {
        GLchar messages[256] = {};
        s_gles2.glGetProgramInfoLog(
                mProgram, sizeof(messages), 0, &messages[0]);
        ERR("%s: Could not run program: '%s'\n", __FUNCTION__, messages);
        return false;
    }
#endif

    // Do the rendering.
    s_gles2.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
#ifdef DEBUG_TEXTURE_DRAW
    err = s_gles2.glGetError();
    if (err != GL_NO_ERROR) {
        ERR("%s: Could not glBindBuffer(GL_ELEMENT_ARRAY_BUFFER) error=0x%x\n",
            __FUNCTION__, err);
    }
#endif

    // We may only get 0, 90, 180, 270 in |rotation| so far.
    const int intRotation = ((int)rotation)/90;
    assert(intRotation >= 0 && intRotation <= 3);
    intptr_t indexShift = 0;
    switch (intRotation) {
    case 0:
        indexShift = 5 * kIndicesPerDraw;
        break;
    case 1:
        indexShift = 7 * kIndicesPerDraw;
        break;
    case 2:
        indexShift = 4 * kIndicesPerDraw;
        break;
    case 3:
        indexShift = 6 * kIndicesPerDraw;
        break;
    }
    s_gles2.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    s_gles2.glClear(GL_COLOR_BUFFER_BIT);
    s_gles2.glDrawElements(GL_TRIANGLES, kIndicesPerDraw, GL_UNSIGNED_BYTE,
                           (const GLvoid*)indexShift);

    bool shouldDrawMask = false;
    GLfloat scale[2];
    s_gles2.glGetUniformfv(mProgram, mScaleSlot, scale);
    GLfloat overlayScale[2];
    {
        android::base::AutoLock lock(mMaskLock);
        if (wantOverlay && mHaveNewMask) {
            // Create a texture from the mask image and make it
            // available to be blended
            GLint prevUnpackAlignment;
            s_gles2.glGetIntegerv(GL_UNPACK_ALIGNMENT, &prevUnpackAlignment);
            s_gles2.glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

            s_gles2.glBindTexture(GL_TEXTURE_2D, mMaskTexture);

            s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
            s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

            if (mShouldReallocateTexture) {
                mMaskTextureWidth = mMaskWidth;
                mMaskTextureHeight = mMaskHeight;
                // mMaskPixels is actually not used here, we only use
                // glTexImage2D here to resize the texture
                s_gles2.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8,
                                     mMaskTextureWidth, mMaskTextureHeight, 0,
                                     GL_RGBA, GL_UNSIGNED_BYTE,
                                     mMaskPixels.data());
                mShouldReallocateTexture = false;
            }

            // Put the new texture in the center.
            s_gles2.glTexSubImage2D(
                    GL_TEXTURE_2D, 0, (mMaskTextureWidth - mMaskWidth) / 2,
                    (mMaskTextureHeight - mMaskHeight) / 2, mMaskWidth,
                    mMaskHeight, GL_RGBA, GL_UNSIGNED_BYTE, mMaskPixels.data());

            s_gles2.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
            s_gles2.glEnable(GL_BLEND);

            s_gles2.glPixelStorei(GL_UNPACK_ALIGNMENT, prevUnpackAlignment);

            mHaveNewMask = false;
            mMaskIsValid = true;
        }
        shouldDrawMask = mMaskIsValid && wantOverlay;
        // Scale the texture to only show that actual mask.
        overlayScale[0] = static_cast<float>(mMaskTextureWidth) /
                          static_cast<float>(mMaskWidth) * scale[0];
        overlayScale[1] = static_cast<float>(mMaskTextureHeight) /
                          static_cast<float>(mMaskHeight) * scale[1];
    }

    if (shouldDrawMask) {
        if (mBlendResetNeeded) {
            s_gles2.glEnable(GL_BLEND);
            mBlendResetNeeded = false;
        }
        s_gles2.glUniform2f(mScaleSlot, overlayScale[0], overlayScale[1]);
        // mMaskTexture should only be accessed on the thread where drawImpl is
        // called, hence no need for lock.
        s_gles2.glBindTexture(GL_TEXTURE_2D, mMaskTexture);
        s_gles2.glDrawElements(GL_TRIANGLES, kIndicesPerDraw, GL_UNSIGNED_BYTE,
                               (const GLvoid*)indexShift);
        // Reset to the "normal" texture
        s_gles2.glBindTexture(GL_TEXTURE_2D, texture);
        s_gles2.glUniform2f(mScaleSlot, scale[0], scale[1]);
    }

#ifdef DEBUG_TEXTURE_DRAW
    err = s_gles2.glGetError();
    if (err != GL_NO_ERROR) {
        ERR("%s: Could not glDrawElements() error=0x%x\n",
            __FUNCTION__, err);
    }
#endif

    // TODO(digit): Restore previous program state.
    // For now, reset back to zero and assume other users will
    // follow the same protocol.
    s_gles2.glUseProgram(0);
    s_gles2.glDisableVertexAttribArray(mPositionSlot);
    s_gles2.glDisableVertexAttribArray(mInCoordSlot);
    s_gles2.glBindBuffer(GL_ARRAY_BUFFER, 0);
    s_gles2.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    return true;
}

TextureDraw::~TextureDraw() {
    s_gles2.glDeleteBuffers(1, &mIndexBuffer);
    s_gles2.glDeleteBuffers(1, &mVertexBuffer);

    if (mFragmentShader) {
        s_gles2.glDeleteShader(mFragmentShader);
    }
    if (mVertexShader) {
        s_gles2.glDeleteShader(mVertexShader);
    }
    if (mMaskTexture) {
        s_gles2.glDeleteTextures(1, &mMaskTexture);
    }
}

void TextureDraw::setScreenMask(int width, int height, const unsigned char* rgbaData) {
    android::base::AutoLock lock(mMaskLock);
    if (width <= 0 || height <= 0 || rgbaData == nullptr) {
        mMaskIsValid = false;
        return;
    }

    mShouldReallocateTexture =
            (width > mMaskTextureWidth) || (height > mMaskTextureHeight);
    auto nextMaskTextureWidth = std::max(width, mMaskTextureWidth);
    auto nextMaskTextureHeight = std::max(height, mMaskTextureHeight);
    mMaskPixels.resize(nextMaskTextureWidth * nextMaskTextureHeight * 4);
    // Save the data for use in the right context
    std::copy(rgbaData, rgbaData + width * height * 4, mMaskPixels.begin());

    mHaveNewMask = true;
    mMaskWidth = width;
    mMaskHeight = height;
}

void TextureDraw::preDrawLayer() {
    if (!mProgram) {
        ERR("%s: no program\n", __FUNCTION__);
        return;
    }
    s_gles2.glUseProgram(mProgram);
#ifdef DEBUG_TEXTURE_DRAW
    GLenum err = s_gles2.glGetError();
    if (err != GL_NO_ERROR) {
        ERR("%s: Could not use program error=0x%x\n",
            __FUNCTION__, err);
    }
#endif

    s_gles2.glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
#ifdef DEBUG_TEXTURE_DRAW
    err = s_gles2.glGetError();
    if (err != GL_NO_ERROR) {
        ERR("%s: Could not bind GL_ARRAY_BUFFER error=0x%x\n",
            __FUNCTION__, err);
    }
#endif
    s_gles2.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
#ifdef DEBUG_TEXTURE_DRAW
    err = s_gles2.glGetError();
    if (err != GL_NO_ERROR) {
        ERR("%s: Could not glBindBuffer(GL_ELEMENT_ARRAY_BUFFER) error=0x%x\n",
            __FUNCTION__, err);
    }
#endif

    s_gles2.glEnableVertexAttribArray(mPositionSlot);
    s_gles2.glVertexAttribPointer(mPositionSlot,
                                  3,
                                  GL_FLOAT,
                                  GL_FALSE,
                                  sizeof(Vertex),
                                  0);

    s_gles2.glEnableVertexAttribArray(mInCoordSlot);
    s_gles2.glVertexAttribPointer(mInCoordSlot,
                                  2,
                                  GL_FLOAT,
                                  GL_FALSE,
                                  sizeof(Vertex),
                                  reinterpret_cast<GLvoid*>(
                                        static_cast<uintptr_t>(
                                                sizeof(float) * 3)));
#ifdef DEBUG_TEXTURE_DRAW
    err = s_gles2.glGetError();
    if (err != GL_NO_ERROR) {
        ERR("%s: Could glVertexAttribPointer with mPositionSlot error=0x%x\n",
            __FUNCTION__, err);
    }
#endif

   // set composition default
    s_gles2.glUniform1i(mComposeMode, 2);
    s_gles2.glActiveTexture(GL_TEXTURE0);
    s_gles2.glUniform1i(mTextureSlot, 0);
    s_gles2.glEnable(GL_BLEND);
    s_gles2.glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
}

void TextureDraw::prepareForDrawLayer() {
    // clear color
    s_gles2.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

void TextureDraw::drawLayer(const ComposeLayer& layer, int frameWidth, int frameHeight,
                            int cbWidth, int cbHeight, GLuint texture) {
    preDrawLayer();
    switch(layer.composeMode) {
        case HWC2_COMPOSITION_DEVICE:
            s_gles2.glBindTexture(GL_TEXTURE_2D, texture);
            break;
        case HWC2_COMPOSITION_SOLID_COLOR: {
            s_gles2.glUniform1i(mComposeMode, layer.composeMode);
            s_gles2.glUniform4f(mColor,
                                layer.color.r/255.0, layer.color.g/255.0,
                                layer.color.b/255.0, layer.color.a/255.0);
            break;
        }
        case HWC2_COMPOSITION_CLIENT:
        case HWC2_COMPOSITION_CURSOR:
        case HWC2_COMPOSITION_SIDEBAND:
        case HWC2_COMPOSITION_INVALID:
        default:
            ERR("%s: invalid composition mode %d", __FUNCTION__, layer.composeMode);
            return;
    }

    switch(layer.blendMode) {
        case HWC2_BLEND_MODE_NONE:
            s_gles2.glDisable(GL_BLEND);
            mBlendResetNeeded = true;
            break;
        case HWC2_BLEND_MODE_PREMULTIPLIED:
            break;
        case HWC2_BLEND_MODE_INVALID:
        case HWC2_BLEND_MODE_COVERAGE:
        default:
            ERR("%s: invalid blendMode %d", __FUNCTION__, layer.blendMode);
            return;
    }

    s_gles2.glUniform1f(mAlpha, layer.alpha);

    float edges[4];
    edges[0] = 1 - 2.0 * (frameWidth - layer.displayFrame.left)/frameWidth;
    edges[1] = 1 - 2.0 * (frameHeight - layer.displayFrame.top)/frameHeight;
    edges[2] = 1 - 2.0 * (frameWidth - layer.displayFrame.right)/frameWidth;
    edges[3] = 1- 2.0 * (frameHeight - layer.displayFrame.bottom)/frameHeight;

    float crop[4];
    crop[0] = layer.crop.left/cbWidth;
    crop[1] = layer.crop.top/cbHeight;
    crop[2] = layer.crop.right/cbWidth;
    crop[3] = layer.crop.bottom/cbHeight;

    // setup the |translation| uniform value.
    s_gles2.glUniform2f(mTranslationSlot, (-edges[2] - edges[0])/2,
                        (-edges[3] - edges[1])/2);
    s_gles2.glUniform2f(mScaleSlot, (edges[2] - edges[0])/2,
                        (edges[1] - edges[3])/2);
    s_gles2.glUniform2f(mCoordTranslation, crop[0], crop[3]);
    s_gles2.glUniform2f(mCoordScale, crop[2] - crop[0], crop[1] - crop[3]);

    intptr_t indexShift;
    switch(layer.transform) {
    case HWC_TRANSFORM_ROT_90:
        indexShift = 1 * kIndicesPerDraw;
        break;
    case HWC_TRANSFORM_ROT_180:
        indexShift = 2 * kIndicesPerDraw;
        break;
    case HWC_TRANSFORM_ROT_270:
        indexShift = 3 * kIndicesPerDraw;
        break;
    case HWC_TRANSFORM_FLIP_H:
        indexShift = 4 * kIndicesPerDraw;
        break;
    case HWC_TRANSFORM_FLIP_V:
        indexShift = 5 * kIndicesPerDraw;
        break;
    case HWC_TRANSFORM_FLIP_H_ROT_90:
        indexShift = 6 * kIndicesPerDraw;
        break;
    case HWC_TRANSFORM_FLIP_V_ROT_90:
        indexShift = 7 * kIndicesPerDraw;
        break;
    default:
        indexShift = 0;
    }
    s_gles2.glDrawElements(GL_TRIANGLES, kIndicesPerDraw, GL_UNSIGNED_BYTE,
                           (const GLvoid*)indexShift);
#ifdef DEBUG_TEXTURE_DRAW
    GLenum err = s_gles2.glGetError();
    if (err != GL_NO_ERROR) {
        ERR("%s: Could not glDrawElements() error=0x%x\n",
            __FUNCTION__, err);
    }
#endif

    // restore the default value for the next draw layer
    if (layer.composeMode != HWC2_COMPOSITION_DEVICE) {
        s_gles2.glUniform1i(mComposeMode, HWC2_COMPOSITION_DEVICE);
    }
    if (layer.blendMode != HWC2_BLEND_MODE_PREMULTIPLIED) {
        s_gles2.glEnable(GL_BLEND);
        mBlendResetNeeded = false;
        s_gles2.glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
    }
}

// Do Post right after drawing each layer, so keep using this program
void TextureDraw::cleanupForDrawLayer() {
    s_gles2.glUniform1f(mAlpha, 1.0);
    s_gles2.glUniform1i(mComposeMode, HWC2_COMPOSITION_DEVICE);
    s_gles2.glUniform2f(mTranslationSlot, 0.0, 0.0);
    s_gles2.glUniform2f(mScaleSlot, 1.0, 1.0);
    s_gles2.glUniform2f(mCoordTranslation, 0.0, 0.0);
    s_gles2.glUniform2f(mCoordScale, 1.0, 1.0);
}

}  // namespace gl
}  // namespace gfxstream
