/*
 * Copyright (C) 2017 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 <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <jni.h>
#include <stdlib.h>
#include <android/hardware_buffer.h>
#include <android/log.h>
#include <cmath>
#include <string>
#include <sstream>

#define  LOG_TAG    "VrExtensionsJni"
#define  LOGV(...)  __android_log_print(ANDROID_LOG_VERBOSE,LOG_TAG,__VA_ARGS__)

using PFNEGLGETNATIVECLIENTBUFFERANDROID =
        EGLClientBuffer(EGLAPIENTRYP)(const AHardwareBuffer* buffer);

using PFNGLEGLIMAGETARGETTEXTURE2DOESPROC = void(GL_APIENTRYP)(GLenum target,
                                                               void* image);

using PFNGLBUFFERSTORAGEEXTERNALEXTPROC =
    void(GL_APIENTRYP)(GLenum target, GLintptr offset, GLsizeiptr size,
                       void* clientBuffer, GLbitfield flags);

using PFNGLMAPBUFFERRANGEPROC = void*(GL_APIENTRYP)(GLenum target,
                                                    GLintptr offset,
                                                    GLsizeiptr length,
                                                    GLbitfield access);

using PFNGLUNMAPBUFFERPROC = void*(GL_APIENTRYP)(GLenum target);

PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES;
PFNEGLGETNATIVECLIENTBUFFERANDROID eglGetNativeClientBufferANDROID;
PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR;
PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC glFramebufferTextureMultiviewOVR;
PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC
    glFramebufferTextureMultisampleMultiviewOVR;
PFNGLBUFFERSTORAGEEXTERNALEXTPROC glBufferStorageExternalEXT;
PFNGLMAPBUFFERRANGEPROC glMapBufferRange;
PFNGLUNMAPBUFFERPROC glUnmapBuffer;

#define NO_ERROR 0
#define GL_UNIFORM_BUFFER         0x8A11

// Declare flags that are added to MapBufferRange via EXT_buffer_storage.
// https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_buffer_storage.txt
#define GL_MAP_PERSISTENT_BIT_EXT 0x0040
#define GL_MAP_COHERENT_BIT_EXT   0x0080

// Declare tokens added as a part of EGL_EXT_image_gl_colorspace.
#define EGL_GL_COLORSPACE_DEFAULT_EXT 0x314D

#define LOAD_PROC(NAME, TYPE)                                           \
    NAME = reinterpret_cast<TYPE>(eglGetProcAddress(# NAME))

#define ASSERT(condition, format, args...)      \
    if (!(condition)) {                         \
        fail(env, format, ## args);             \
        return;                                 \
    }

#define ASSERT_TRUE(a) \
    ASSERT((a), "assert failed on (" #a ") at " __FILE__ ":%d", __LINE__)
#define ASSERT_FALSE(a) \
    ASSERT(!(a), "assert failed on (!" #a ") at " __FILE__ ":%d", __LINE__)
#define ASSERT_EQ(a, b) \
    ASSERT((a) == (b), "assert failed on (" #a ") at " __FILE__ ":%d", __LINE__)
#define ASSERT_NE(a, b) \
    ASSERT((a) != (b), "assert failed on (" #a ") at " __FILE__ ":%d", __LINE__)
#define ASSERT_GT(a, b) \
    ASSERT((a) > (b), "assert failed on (" #a ") at " __FILE__ ":%d", __LINE__)
#define ASSERT_NEAR_RGBA(a, b, delta) \
    ASSERT(areNearRgba(a, b, delta),  \
           "assert failed on (" #a ") at " __FILE__ ":%d", __LINE__)

bool areNearRgba(int32_t actual, int32_t expected, int delta) {
    for (int shift = 0; shift < 32; shift += 8) {
        if (std::abs((actual >> shift & 0xFF) - (expected >> shift & 0xFF)) > delta) {
            return false;
        }
    }
    return true;
}

void fail(JNIEnv* env, const char* format, ...) {
    va_list args;
    va_start(args, format);
    char* msg;
    vasprintf(&msg, format, args);
    va_end(args);
    jclass exClass;
    const char* className = "java/lang/AssertionError";
    exClass = env->FindClass(className);
    env->ThrowNew(exClass, msg);
    free(msg);
}

static void testEglImageArray(JNIEnv* env, AHardwareBuffer_Desc desc,
                              int nsamples) {
    ASSERT_GT(desc.layers, 1);
    AHardwareBuffer* hwbuffer = nullptr;
    // If the format is unsupported and allocation fails, skip the test.
    if (AHardwareBuffer_allocate(&desc, &hwbuffer) != NO_ERROR) return;
    // Create EGLClientBuffer from the AHardwareBuffer.
    EGLClientBuffer native_buffer = eglGetNativeClientBufferANDROID(hwbuffer);
    ASSERT_TRUE(native_buffer);
    // Create EGLImage from EGLClientBuffer.
    EGLint attrs[] = {EGL_NONE};
    EGLImageKHR image =
        eglCreateImageKHR(eglGetCurrentDisplay(), EGL_NO_CONTEXT,
                          EGL_NATIVE_BUFFER_ANDROID, native_buffer, attrs);
    ASSERT_TRUE(image);
    // Create OpenGL texture from the EGLImage.
    GLuint texid;
    glGenTextures(1, &texid);
    glBindTexture(GL_TEXTURE_2D_ARRAY, texid);
    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D_ARRAY, image);
    ASSERT_EQ(glGetError(), GL_NO_ERROR);
    // Create FBO and add multiview attachment.
    GLuint fboid;
    glGenFramebuffers(1, &fboid);
    glBindFramebuffer(GL_FRAMEBUFFER, fboid);
    const GLint miplevel = 0;
    const GLint base_view = 0;
    const GLint num_views = desc.layers;
    if (nsamples == 1) {
        glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                         texid, miplevel, base_view, num_views);
    } else {
        glFramebufferTextureMultisampleMultiviewOVR(
            GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texid, miplevel, nsamples,
            base_view, num_views);
    }
    ASSERT_EQ(glGetError(), GL_NO_ERROR);
    ASSERT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER),
              GL_FRAMEBUFFER_COMPLETE);
    // Release memory.
    glDeleteTextures(1, &texid);
    glDeleteFramebuffers(1, &fboid);
    AHardwareBuffer_release(hwbuffer);
}

extern "C" JNIEXPORT void JNICALL
Java_android_vr_cts_VrExtensionBehaviorTest_nativeTestEglImageArray(
    JNIEnv* env, jclass /* unused */) {
    // First, load entry points provided by extensions.
    LOAD_PROC(glEGLImageTargetTexture2DOES,
              PFNGLEGLIMAGETARGETTEXTURE2DOESPROC);
    ASSERT_NE(glEGLImageTargetTexture2DOES, nullptr);
    LOAD_PROC(eglGetNativeClientBufferANDROID,
              PFNEGLGETNATIVECLIENTBUFFERANDROID);
    ASSERT_NE(eglGetNativeClientBufferANDROID, nullptr);
    LOAD_PROC(eglCreateImageKHR, PFNEGLCREATEIMAGEKHRPROC);
    ASSERT_NE(eglCreateImageKHR, nullptr);
    LOAD_PROC(glFramebufferTextureMultiviewOVR,
              PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC);
    ASSERT_NE(glFramebufferTextureMultiviewOVR, nullptr);
    LOAD_PROC(glFramebufferTextureMultisampleMultiviewOVR,
              PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC);
    ASSERT_NE(glFramebufferTextureMultisampleMultiviewOVR, nullptr);
    // Try creating a 32x32 AHardwareBuffer and attaching it to a multiview
    // framebuffer, with various formats and depths.
    AHardwareBuffer_Desc desc = {};
    desc.width = 32;
    desc.height = 32;
    desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
                 AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT;
    const int layers[] = {2, 4};
    const int formats[] = {
      AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM,
      AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
      AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM,
      AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT,
      // Do not test AHARDWAREBUFFER_FORMAT_BLOB, it isn't color-renderable.
    };
    const int samples[] = {1, 2, 4};
    for (int nsamples : samples) {
      for (auto nlayers : layers) {
        for (auto format : formats) {
          desc.layers = nlayers;
          desc.format = format;
          testEglImageArray(env, desc, nsamples);
        }
      }
    }
}

static void testExternalBuffer(JNIEnv* env, uint64_t usage, bool write_hwbuffer,
                               const std::string& test_string) {
    // Create a blob AHardwareBuffer suitable for holding the string.
    AHardwareBuffer_Desc desc = {};
    desc.width = test_string.size();
    desc.height = 1;
    desc.layers = 1;
    desc.format = AHARDWAREBUFFER_FORMAT_BLOB;
    desc.usage = usage;
    AHardwareBuffer* hwbuffer = nullptr;
    int error = AHardwareBuffer_allocate(&desc, &hwbuffer);
    ASSERT_EQ(error, NO_ERROR);
    // Create EGLClientBuffer from the AHardwareBuffer.
    EGLClientBuffer native_buffer = eglGetNativeClientBufferANDROID(hwbuffer);
    ASSERT_TRUE(native_buffer);
    // Create uniform buffer from EGLClientBuffer.
    const GLbitfield flags = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT |
        GL_MAP_COHERENT_BIT_EXT | GL_MAP_PERSISTENT_BIT_EXT;
    GLuint buf = 0;
    glGenBuffers(1, &buf);
    glBindBuffer(GL_UNIFORM_BUFFER, buf);
    ASSERT_EQ(glGetError(), GL_NO_ERROR);
    const GLsizeiptr bufsize = desc.width * desc.height;
    glBufferStorageExternalEXT(GL_UNIFORM_BUFFER, 0,
             bufsize, native_buffer, flags);
    ASSERT_EQ(glGetError(), GL_NO_ERROR);
    // Obtain a writeable pointer using either OpenGL or the Android API,
    // then copy the test string into it.
    if (write_hwbuffer) {
      void* data = nullptr;
      error = AHardwareBuffer_lock(hwbuffer,
                                   AHARDWAREBUFFER_USAGE_CPU_READ_RARELY, -1,
                                   NULL, &data);
      ASSERT_EQ(error, NO_ERROR);
      ASSERT_TRUE(data);
      memcpy(data, test_string.c_str(), test_string.size());
      error = AHardwareBuffer_unlock(hwbuffer, nullptr);
      ASSERT_EQ(error, NO_ERROR);
    } else {
      void* data =
          glMapBufferRange(GL_UNIFORM_BUFFER, 0, bufsize,
                           GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT_EXT);
      ASSERT_EQ(glGetError(), GL_NO_ERROR);
      ASSERT_TRUE(data);
      memcpy(data, test_string.c_str(), test_string.size());
      glUnmapBuffer(GL_UNIFORM_BUFFER);
      ASSERT_EQ(glGetError(), GL_NO_ERROR);
    }
    // Obtain a readable pointer and verify the data.
    void* data = glMapBufferRange(GL_UNIFORM_BUFFER, 0, bufsize, GL_MAP_READ_BIT);
    ASSERT_TRUE(data);
    ASSERT_EQ(strncmp(static_cast<char*>(data), test_string.c_str(),
                      test_string.size()), 0);
    glUnmapBuffer(GL_UNIFORM_BUFFER);
    ASSERT_EQ(glGetError(), GL_NO_ERROR);
    AHardwareBuffer_release(hwbuffer);
}

extern "C" JNIEXPORT void JNICALL
Java_android_vr_cts_VrExtensionBehaviorTest_nativeTestExternalBuffer(
    JNIEnv* env, jclass /* unused */) {
    // First, check for EXT_external_buffer in the extension string.
    auto exts = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
    ASSERT_TRUE(exts && strstr(exts, "GL_EXT_external_buffer"));
    // Next, load entry points provided by extensions.
    LOAD_PROC(eglGetNativeClientBufferANDROID, PFNEGLGETNATIVECLIENTBUFFERANDROID);
    ASSERT_NE(eglGetNativeClientBufferANDROID, nullptr);
    LOAD_PROC(glBufferStorageExternalEXT, PFNGLBUFFERSTORAGEEXTERNALEXTPROC);
    ASSERT_NE(glBufferStorageExternalEXT, nullptr);
    LOAD_PROC(glMapBufferRange, PFNGLMAPBUFFERRANGEPROC);
    ASSERT_NE(glMapBufferRange, nullptr);
    LOAD_PROC(glUnmapBuffer, PFNGLUNMAPBUFFERPROC);
    ASSERT_NE(glUnmapBuffer, nullptr);
    const uint64_t usage = AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN |
        AHARDWAREBUFFER_USAGE_CPU_READ_RARELY |
        AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER |
        AHARDWAREBUFFER_USAGE_SENSOR_DIRECT_DATA;
    const std::string test_string = "Hello, world.";
    // First try writing to the buffer using OpenGL, then try writing to it via
    // the AHardwareBuffer API.
    testExternalBuffer(env, usage, false, test_string);
    testExternalBuffer(env, usage, true, test_string);
}

const GLchar* const kSrgbVertexCode = R"(
    // vertex position in clip space (-1..1)
    attribute vec4 position;
    varying mediump vec2 uv;
    void main() {
      gl_Position = position;
      uv = vec2(0.5 * (position.x + 1.0), 0.5);
    })";

const GLchar* const kSrgbFragmentCode = R"(
    varying mediump vec2 uv;
    uniform sampler2D tex;
    void main() {
      gl_FragColor = texture2D(tex, uv);
    })";

static inline float SrgbChannelToLinear(float cs) {
    if (cs <= 0.04045)
        return cs / 12.92f;
    else
        return std::pow((cs + 0.055f) / 1.055f, 2.4f);
}

static inline float LinearChannelToSrgb(float cs) {
    if (cs <= 0.0f)
        return 0.0f;
    else if (cs < 0.0031308f)
        return 12.92f * cs;
    else if (cs < 1.0f)
        return 1.055f * std::pow(cs, 0.41666f) - 0.055f;
    else
        return 1.0f;
}

static uint32_t SrgbColorToLinear(uint32_t color) {
    float r = SrgbChannelToLinear((color & 0xff) / 255.0f);
    float g = SrgbChannelToLinear(((color >> 8) & 0xff) / 255.0f);
    float b = SrgbChannelToLinear(((color >> 16) & 0xff) / 255.0f);
    uint32_t r8 = r * 255.0f;
    uint32_t g8 = g * 255.0f;
    uint32_t b8 = b * 255.0f;
    uint32_t a8 = color >> 24;
    return (a8 << 24) | (b8 << 16) | (g8 << 8) | r8;
}

static uint32_t LinearColorToSrgb(uint32_t color) {
    float r = LinearChannelToSrgb((color & 0xff) / 255.0f);
    float g = LinearChannelToSrgb(((color >> 8) & 0xff) / 255.0f);
    float b = LinearChannelToSrgb(((color >> 16) & 0xff) / 255.0f);
    uint32_t r8 = r * 255.0f;
    uint32_t g8 = g * 255.0f;
    uint32_t b8 = b * 255.0f;
    uint32_t a8 = color >> 24;
    return (a8 << 24) | (b8 << 16) | (g8 << 8) | r8;
}

static uint32_t LerpColor(uint32_t color0, uint32_t color1, float t) {
    float r0 = (color0 & 0xff) / 255.0f;
    float g0 = ((color0 >> 8) & 0xff) / 255.0f;
    float b0 = ((color0 >> 16) & 0xff) / 255.0f;
    float a0 = ((color0 >> 24) & 0xff) / 255.0f;
    float r1 = (color1 & 0xff) / 255.0f;
    float g1 = ((color1 >> 8) & 0xff) / 255.0f;
    float b1 = ((color1 >> 16) & 0xff) / 255.0f;
    float a1 = ((color1 >> 24) & 0xff) / 255.0f;
    uint32_t r8 = (r0 * (1.0f - t) + r1 * t) * 255.0f;
    uint32_t g8 = (g0 * (1.0f - t) + g1 * t) * 255.0f;
    uint32_t b8 = (b0 * (1.0f - t) + b1 * t) * 255.0f;
    uint32_t a8 = (a0 * (1.0f - t) + a1 * t) * 255.0f;
    return (a8 << 24) | (b8 << 16) | (g8 << 8) | r8;
}

// Choose an odd-numbered framebuffer width so that we can
// extract the middle pixel of a gradient.
constexpr uint32_t kFramebufferWidth = 31;

// Declare the pixel data for the 2x1 texture.
// Color components are ordered like this: AABBGGRR
constexpr uint32_t kTextureData[] = {
    0xff800000,  // Half-Blue
    0xff000080,  // Half-Red
};
constexpr uint32_t kTextureWidth = sizeof(kTextureData) / sizeof(kTextureData[0]);

// Declare expected values for the middle pixel for various sampling behaviors.
const uint32_t kExpectedMiddlePixel_NoSrgb = LerpColor(kTextureData[0], kTextureData[1], 0.5f);
const uint32_t kExpectedMiddlePixel_LinearizeAfterFiltering =
    SrgbColorToLinear(kExpectedMiddlePixel_NoSrgb);
const uint32_t kExpectedMiddlePixel_LinearizeBeforeFiltering =
    LerpColor(SrgbColorToLinear(kTextureData[0]), SrgbColorToLinear(kTextureData[1]), 0.5f);

// Declare expected values for the final pixel color for various blending behaviors.
constexpr uint32_t kBlendDestColor = 0xff000080;
constexpr uint32_t kBlendSourceColor = 0x80800000;
const uint32_t kExpectedBlendedPixel_NoSrgb = LerpColor(kBlendSourceColor, kBlendDestColor, 0.5f);
const uint32_t kExpectedBlendedPixel_Srgb =
    LinearColorToSrgb(LerpColor(kBlendSourceColor, SrgbColorToLinear(kBlendDestColor), 0.5f));

// Define a set of test flags. Not using an enum to avoid lots of casts.
namespace SrgbFlag {
constexpr uint32_t kHardwareBuffer = 1 << 0;
constexpr uint32_t kSrgbFormat = 1 << 1;
constexpr uint32_t kEglColorspaceDefault = 1 << 2;
constexpr uint32_t kEglColorspaceLinear = 1 << 3;
constexpr uint32_t kEglColorspaceSrgb = 1 << 4;
}  // namespace SrgbFlag

static void configureEglColorspace(EGLint attrs[4], uint32_t srgb_flags) {
    if (srgb_flags & SrgbFlag::kEglColorspaceDefault) {
        attrs[0] = EGL_GL_COLORSPACE_KHR;
        attrs[1] = EGL_GL_COLORSPACE_DEFAULT_EXT;
    } else if (srgb_flags & SrgbFlag::kEglColorspaceLinear) {
        attrs[0] = EGL_GL_COLORSPACE_KHR;
        attrs[1] = EGL_GL_COLORSPACE_LINEAR_KHR;
    } else if (srgb_flags & SrgbFlag::kEglColorspaceSrgb) {
        attrs[0] = EGL_GL_COLORSPACE_KHR;
        attrs[1] = EGL_GL_COLORSPACE_SRGB_KHR;
    } else {
        attrs[0] = EGL_NONE;
        attrs[1] = EGL_NONE;
    }
    attrs[2] = EGL_NONE;
    attrs[3] = EGL_NONE;
}

static void printSrgbFlags(std::ostream& out, uint32_t srgb_flags) {
    if (srgb_flags & SrgbFlag::kHardwareBuffer) {
        out << " AHardwareBuffer";
    }
    if (srgb_flags & SrgbFlag::kSrgbFormat) {
        out << " GL_SRGB_ALPHA";
    }
    if (srgb_flags & SrgbFlag::kEglColorspaceDefault) {
        out << " EGL_GL_COLORSPACE_DEFAULT_KHR";
    }
    if (srgb_flags & SrgbFlag::kEglColorspaceLinear) {
        out << " EGL_GL_COLORSPACE_LINEAR_KHR";
    }
    if (srgb_flags & SrgbFlag::kEglColorspaceSrgb) {
        out << " EGL_GL_COLORSPACE_SRGB_KHR";
    }
}

// Draws a gradient and extracts the middle pixel. Returns void to allow ASSERT to work.
static void testLinearMagnification(JNIEnv* env, uint32_t flags, uint32_t* middle_pixel) {
    const bool use_hwbuffer = flags & SrgbFlag::kHardwareBuffer;
    const bool use_srgb_format = flags & SrgbFlag::kSrgbFormat;
    GLuint srgbtex;
    glGenTextures(1, &srgbtex);
    glBindTexture(GL_TEXTURE_2D, srgbtex);
    if (use_hwbuffer) {
        // Create a one-dimensional AHardwareBuffer.
        AHardwareBuffer_Desc desc = {};
        desc.width = kTextureWidth;
        desc.height = 1;
        desc.layers = 1;
        desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
        desc.usage =
                AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT;
        AHardwareBuffer* hwbuffer = nullptr;
        int error = AHardwareBuffer_allocate(&desc, &hwbuffer);
        ASSERT_EQ(error, NO_ERROR);
        // Populate the pixels.
        uint32_t* pixels = nullptr;
        error = AHardwareBuffer_lock(hwbuffer, AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN, -1, nullptr,
                                     reinterpret_cast<void**>(&pixels));
        ASSERT_EQ(error, NO_ERROR);
        ASSERT_TRUE(pixels);
        memcpy(pixels, kTextureData, sizeof(kTextureData));
        error = AHardwareBuffer_unlock(hwbuffer, nullptr);
        ASSERT_EQ(error, NO_ERROR);
        // Create EGLClientBuffer from the AHardwareBuffer.
        EGLClientBuffer native_buffer = eglGetNativeClientBufferANDROID(hwbuffer);
        ASSERT_TRUE(native_buffer);
        // Create EGLImage from EGLClientBuffer.
        EGLint attrs[4];
        configureEglColorspace(attrs, flags);
        EGLImageKHR image = eglCreateImageKHR(eglGetCurrentDisplay(), EGL_NO_CONTEXT,
                                              EGL_NATIVE_BUFFER_ANDROID, native_buffer, attrs);
        ASSERT_TRUE(image);
        // Allocate the OpenGL texture using the EGLImage.
        glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
    } else {
        GLenum internal_format = use_srgb_format ? GL_SRGB8_ALPHA8_EXT : GL_RGBA8_OES;
        GLenum format = use_srgb_format ? GL_SRGB_ALPHA_EXT : GL_RGBA;
        glTexImage2D(GL_TEXTURE_2D, 0, internal_format, kTextureWidth, 1, 0, format,
                     GL_UNSIGNED_BYTE, kTextureData);
    }
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    ASSERT_EQ(glGetError(), GL_NO_ERROR);
    // Clear to an interesting constant color to make it easier to spot bugs.
    glClearColor(1.0, 0.0, 0.5, 0.25);
    glClear(GL_COLOR_BUFFER_BIT);
    // Draw the texture.
    const float kTriangleCoords[] = {-1, -1, -1, 1, 1, -1, 1, 1};
    glBindTexture(GL_TEXTURE_2D, srgbtex);
    const int kPositionSlot = 0;
    glVertexAttribPointer(kPositionSlot, 2, GL_FLOAT, false, 0, kTriangleCoords);
    glEnableVertexAttribArray(kPositionSlot);
    glViewport(0, 0, kFramebufferWidth, 1);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    // Read back the framebuffer.
    glReadPixels(kFramebufferWidth / 2, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, middle_pixel);
    std::ostringstream flag_string;
    printSrgbFlags(flag_string, flags);
    LOGV("Filtered Result: %8.8X Flags =%s", *middle_pixel, flag_string.str().c_str());
    ASSERT_EQ(glGetError(), GL_NO_ERROR);
}

// Blends a color into an (optionally) sRGB-encoded framebuffer and extracts the final color.
// Returns void to allow ASSERT to work.
static void testFramebufferBlending(JNIEnv* env, uint32_t flags, uint32_t* final_color) {
    const bool use_hwbuffer = flags & SrgbFlag::kHardwareBuffer;
    const bool use_srgb_format = flags & SrgbFlag::kSrgbFormat;
    const bool override_egl_colorspace = use_hwbuffer && (flags & SrgbFlag::kEglColorspaceSrgb);
    GLuint tex;
    glGenTextures(1, &tex);
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    // Create a 1x1 half-blue, half-opaque texture.
    const uint32_t kTextureData[] = {
      kBlendSourceColor,
    };
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA,
                 GL_UNSIGNED_BYTE, kTextureData);
    // Create 1x1 framebuffer object.
    GLuint fbo;
    glGenFramebuffers(1, &fbo);
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    GLuint fbotex;
    glGenTextures(1, &fbotex);
    glBindTexture(GL_TEXTURE_2D, fbotex);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    if (use_hwbuffer) {
        AHardwareBuffer_Desc desc = {};
        desc.width = 1;
        desc.height = 1;
        desc.layers = 1;
        desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
        desc.usage =
                AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT;
        AHardwareBuffer* hwbuffer = nullptr;
        int error = AHardwareBuffer_allocate(&desc, &hwbuffer);
        ASSERT_EQ(error, NO_ERROR);
        // Create EGLClientBuffer from the AHardwareBuffer.
        EGLClientBuffer native_buffer = eglGetNativeClientBufferANDROID(hwbuffer);
        ASSERT_TRUE(native_buffer);
        // Create EGLImage from EGLClientBuffer.
        EGLint attrs[4];
        configureEglColorspace(attrs, flags);
        EGLImageKHR image = eglCreateImageKHR(eglGetCurrentDisplay(), EGL_NO_CONTEXT,
                                              EGL_NATIVE_BUFFER_ANDROID, native_buffer, attrs);
        ASSERT_TRUE(image);
        // Allocate the OpenGL texture using the EGLImage.
        glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
    } else {
        GLenum internal_format = use_srgb_format ? GL_SRGB8_ALPHA8_EXT : GL_RGBA8_OES;
        GLenum format = use_srgb_format ? GL_SRGB_ALPHA_EXT : GL_RGBA;
        glTexImage2D(GL_TEXTURE_2D, 0, internal_format, 1, 1, 0, format,
                     GL_UNSIGNED_BYTE, nullptr);
    }
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                           GL_TEXTURE_2D, fbotex, 0);
    ASSERT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER), GL_FRAMEBUFFER_COMPLETE);
    ASSERT_EQ(glGetError(), GL_NO_ERROR);
    // Clear to half-red.
    if (use_srgb_format || override_egl_colorspace) {
        glClearColor(SrgbChannelToLinear(0.5), 0.0, 0.0, 1.0);
    } else {
        glClearColor(0.5, 0.0, 0.0, 1.0);
    }
    glClear(GL_COLOR_BUFFER_BIT);
    // Sanity check the cleared color.
    uint32_t cleared_color = 0;
    glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &cleared_color);
    LOGV("  Cleared Color: %8.8X", cleared_color);
    ASSERT_EQ(cleared_color, kBlendDestColor);
    // Draw the texture.
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    const float kTriangleCoords[] = {-1, -1, -1, 1, 1, -1, 1, 1};
    glBindTexture(GL_TEXTURE_2D, tex);
    const int kPositionSlot = 0;
    glVertexAttribPointer(kPositionSlot, 2, GL_FLOAT, false, 0, kTriangleCoords);
    glEnableVertexAttribArray(kPositionSlot);
    glViewport(0, 0, 1, 1);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    // Read back the framebuffer.
    glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, final_color);
    std::ostringstream flag_string;
    printSrgbFlags(flag_string, flags);
    LOGV("Blending Result: %8.8X Flags =%s", *final_color, flag_string.str().c_str());
    ASSERT_EQ(glGetError(), GL_NO_ERROR);
}

extern "C" JNIEXPORT void JNICALL
Java_android_vr_cts_VrExtensionBehaviorTest_nativeTestSrgbBuffer(
    JNIEnv* env, jclass /* unused */) {
    // First, check the published extension strings against expectations.
    const char *egl_exts =
        eglQueryString(eglGetCurrentDisplay(), EGL_EXTENSIONS);
    LOGV("EGL Extensions: %s", egl_exts);
    ASSERT_TRUE(egl_exts);
    bool egl_colorspace_supported = strstr(egl_exts, "EGL_EXT_image_gl_colorspace");
    auto gl_exts = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
    LOGV("OpenGL Extensions: %s", gl_exts);
    ASSERT_TRUE(gl_exts);
    // Load ancillary entry points provided by extensions.
    LOAD_PROC(eglGetNativeClientBufferANDROID,
              PFNEGLGETNATIVECLIENTBUFFERANDROID);
    ASSERT_NE(eglGetNativeClientBufferANDROID, nullptr);
    LOAD_PROC(eglCreateImageKHR, PFNEGLCREATEIMAGEKHRPROC);
    ASSERT_NE(eglCreateImageKHR, nullptr);
    LOAD_PROC(glEGLImageTargetTexture2DOES,
              PFNGLEGLIMAGETARGETTEXTURE2DOESPROC);
    ASSERT_NE(glEGLImageTargetTexture2DOES, nullptr);
    // Create a plain old one-dimensional FBO to render to.
    GLuint fbo;
    glGenFramebuffers(1, &fbo);
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    GLuint fbotex;
    glGenTextures(1, &fbotex);
    glBindTexture(GL_TEXTURE_2D, fbotex);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kFramebufferWidth, 1, 0, GL_RGBA,
                 GL_UNSIGNED_BYTE, nullptr);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                           GL_TEXTURE_2D, fbotex, 0);
    ASSERT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER), GL_FRAMEBUFFER_COMPLETE);
    ASSERT_EQ(glGetError(), GL_NO_ERROR);
    // Compile and link shaders.
    int program = glCreateProgram();
    int vshader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vshader, 1, &kSrgbVertexCode, nullptr);
    glCompileShader(vshader);
    glAttachShader(program, vshader);
    int fshader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fshader, 1, &kSrgbFragmentCode, nullptr);
    glCompileShader(fshader);
    glAttachShader(program, fshader);
    glLinkProgram(program);
    int status;
    glGetProgramiv(program, GL_LINK_STATUS, &status);
    ASSERT_EQ(status, GL_TRUE);
    glUseProgram(program);
    ASSERT_EQ(glGetError(), GL_NO_ERROR);

    // Filtering test.
    LOGV("Expected value for NoSrgb = %8.8X", kExpectedMiddlePixel_NoSrgb);
    LOGV("Expected value for   Srgb = %8.8X", kExpectedMiddlePixel_LinearizeBeforeFiltering);
    uint32_t middle_pixel;
    // First do a sanity check with plain old pre-linearized textures.
    testLinearMagnification(env, 0, &middle_pixel);
    ASSERT_NEAR_RGBA(middle_pixel, kExpectedMiddlePixel_NoSrgb, 1);
    testLinearMagnification(env, SrgbFlag::kHardwareBuffer, &middle_pixel);
    ASSERT_NEAR_RGBA(middle_pixel, kExpectedMiddlePixel_NoSrgb, 1);
    // Try a "normally allocated" OpenGL texture with an sRGB source format.
    testLinearMagnification(env, SrgbFlag::kSrgbFormat, &middle_pixel);
    ASSERT_NEAR_RGBA(middle_pixel, kExpectedMiddlePixel_LinearizeBeforeFiltering, 1);
    // Try EGL_EXT_image_gl_colorspace.
    if (egl_colorspace_supported) {
        testLinearMagnification(env, SrgbFlag::kHardwareBuffer | SrgbFlag::kEglColorspaceDefault, &middle_pixel);
        ASSERT_NEAR_RGBA(middle_pixel, kExpectedMiddlePixel_NoSrgb, 1);
        testLinearMagnification(env, SrgbFlag::kHardwareBuffer | SrgbFlag::kEglColorspaceLinear, &middle_pixel);
        ASSERT_NEAR_RGBA(middle_pixel, kExpectedMiddlePixel_NoSrgb, 1);
        testLinearMagnification(env, SrgbFlag::kHardwareBuffer | SrgbFlag::kEglColorspaceSrgb, &middle_pixel);
        ASSERT_NEAR_RGBA(middle_pixel, kExpectedMiddlePixel_LinearizeBeforeFiltering, 1);
    }

    // Blending test.
    LOGV("Expected value for NoSrgb = %8.8X", kExpectedBlendedPixel_NoSrgb);
    LOGV("Expected value for   Srgb = %8.8X", kExpectedBlendedPixel_Srgb);
    uint32_t final_color;
    // First do a sanity check with plain old pre-linearized textures.
    testFramebufferBlending(env, 0, &final_color);
    ASSERT_NEAR_RGBA(final_color, kExpectedBlendedPixel_NoSrgb, 1);
    testFramebufferBlending(env, SrgbFlag::kHardwareBuffer, &final_color);
    ASSERT_NEAR_RGBA(final_color, kExpectedBlendedPixel_NoSrgb, 1);
    // Try a "normally allocated" OpenGL texture with an sRGB source format.
    testFramebufferBlending(env, SrgbFlag::kSrgbFormat, &final_color);
    ASSERT_NEAR_RGBA(final_color, kExpectedBlendedPixel_Srgb, 1);
    // Try EGL_EXT_image_gl_colorspace.
    if (egl_colorspace_supported) {
        testFramebufferBlending(env, SrgbFlag::kHardwareBuffer | SrgbFlag::kEglColorspaceDefault, &final_color);
        ASSERT_NEAR_RGBA(final_color, kExpectedBlendedPixel_NoSrgb, 1);
        testFramebufferBlending(env, SrgbFlag::kHardwareBuffer | SrgbFlag::kEglColorspaceLinear, &final_color);
        ASSERT_NEAR_RGBA(final_color, kExpectedBlendedPixel_NoSrgb, 1);
        testFramebufferBlending(env, SrgbFlag::kHardwareBuffer | SrgbFlag::kEglColorspaceSrgb, &final_color);
        ASSERT_NEAR_RGBA(final_color, kExpectedBlendedPixel_Srgb, 1);
    }
}
