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

#include "host-common/crash_reporter.h"

#include <algorithm>
#include <string>
#include <assert.h>
#include <string.h>
#include <stdio.h>
#define ERR(...)  fprintf(stderr, __VA_ARGS__)

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);

#ifndef NDEBUG
    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);

#ifndef NDEBUG
    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);

#ifndef NDEBUG
    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);

#ifndef NDEBUG
    // 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);
#ifndef NDEBUG
    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 = std::max(mMaskTextureWidth, mMaskWidth);
                mMaskTextureHeight = std::max(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]);
    }

#ifndef NDEBUG
    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);
#ifndef NDEBUG
    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);
#ifndef NDEBUG
    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);
#ifndef NDEBUG
    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)));
#ifndef NDEBUG
    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);
#ifndef NDEBUG
    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
