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

#include "OpenGLESDispatch/EGLDispatch.h"

#include "aemu/base/system/System.h"
#include "aemu/base/misc/StringUtils.h"
#include "host-common/feature_control.h"
#include "host-common/opengl/misc.h"

#include <algorithm>

namespace gfxstream {
namespace gl {

// Config + context attributes to query the underlying OpenGL if it is
// a OpenGL ES backend. Only try for OpenGL ES 3, and assume OpenGL ES 2
// exists (if it doesn't, this is the least of our problems).
static const EGLint gles3ConfigAttribs[] =
    { EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
      EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT, EGL_NONE };

static const EGLint pbufAttribs[] =
    { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE };

static const EGLint gles31Attribs[] =
   { EGL_CONTEXT_MAJOR_VERSION_KHR, 3,
     EGL_CONTEXT_MINOR_VERSION_KHR, 1, EGL_NONE };

static const EGLint gles30Attribs[] =
   { EGL_CONTEXT_MAJOR_VERSION_KHR, 3,
     EGL_CONTEXT_MINOR_VERSION_KHR, 0, EGL_NONE };

static bool sTryContextCreation(EGLDisplay dpy, GLESDispatchMaxVersion ver) {
    EGLConfig config;
    EGLSurface surface;

    const EGLint* contextAttribs = nullptr;

    // Assume ES2 capable.
    if (ver == GLES_DISPATCH_MAX_VERSION_2) return true;

    switch (ver) {
    case GLES_DISPATCH_MAX_VERSION_3_0:
        contextAttribs = gles30Attribs;
        break;
    case GLES_DISPATCH_MAX_VERSION_3_1:
        contextAttribs = gles31Attribs;
        break;
    default:
        break;
    }

    if (!contextAttribs) return false;

    int numConfigs;
    if (!s_egl.eglChooseConfig(
            dpy, gles3ConfigAttribs, &config, 1, &numConfigs) ||
        numConfigs == 0) {
        return false;
    }

    surface = s_egl.eglCreatePbufferSurface(dpy, config, pbufAttribs);
    if (surface == EGL_NO_SURFACE) {
        return false;
    }

    EGLContext ctx = s_egl.eglCreateContext(dpy, config, EGL_NO_CONTEXT,
                                            contextAttribs);

    if (ctx == EGL_NO_CONTEXT) {
        s_egl.eglDestroySurface(dpy, surface);
        return false;
    } else {
        s_egl.eglDestroyContext(dpy, ctx);
        s_egl.eglDestroySurface(dpy, surface);
        return true;
    }
}

GLESDispatchMaxVersion calcMaxVersionFromDispatch(const gfxstream::host::FeatureSet& features,
                                                  EGLDisplay dpy) {
    // TODO: 3.1 is the highest
    GLESDispatchMaxVersion maxVersion =
       GLES_DISPATCH_MAX_VERSION_3_1;

    // TODO: CTS conformance for OpenGL ES 3.1
    bool playStoreImage = features.PlayStoreImage.enabled;

    if (emugl::getRenderer() == SELECTED_RENDERER_HOST
        || emugl::getRenderer() == SELECTED_RENDERER_SWIFTSHADER_INDIRECT
        || emugl::getRenderer() == SELECTED_RENDERER_ANGLE_INDIRECT
        || emugl::getRenderer() == SELECTED_RENDERER_ANGLE9_INDIRECT) {
        if (s_egl.eglGetMaxGLESVersion) {
            maxVersion =
                (GLESDispatchMaxVersion)s_egl.eglGetMaxGLESVersion(dpy);
        }
    } else {
        if (playStoreImage ||
            !sTryContextCreation(dpy, GLES_DISPATCH_MAX_VERSION_3_1)) {
            maxVersion = GLES_DISPATCH_MAX_VERSION_3_0;
            if (!sTryContextCreation(dpy, GLES_DISPATCH_MAX_VERSION_3_0)) {
                maxVersion = GLES_DISPATCH_MAX_VERSION_2;
            }
        }
    }

    if (playStoreImage) {
        maxVersion =
            std::min(maxVersion,
                     GLES_DISPATCH_MAX_VERSION_3_0);
    }

    int maj = 2; int min = 0;
    switch (maxVersion) {
        case GLES_DISPATCH_MAX_VERSION_2:
            maj = 2; min = 0; break;
        case GLES_DISPATCH_MAX_VERSION_3_0:
            maj = 3; min = 0; break;
        case GLES_DISPATCH_MAX_VERSION_3_1:
            maj = 3; min = 1; break;
        case GLES_DISPATCH_MAX_VERSION_3_2:
            maj = 3; min = 2; break;
        default:
            break;
    }

    emugl::setGlesVersion(maj, min);

    return maxVersion;
}

// For determining whether or not to use core profile OpenGL.
// (Note: This does not affect the detection of possible core profile configs,
// just whether to use them)
bool shouldEnableCoreProfile() {
    int dispatchMaj, dispatchMin;

    emugl::getGlesVersion(&dispatchMaj, &dispatchMin);
    return emugl::getRenderer() == SELECTED_RENDERER_HOST &&
           dispatchMaj > 2;
}

void sAddExtensionIfSupported(GLESDispatchMaxVersion currVersion,
                              const std::string& from,
                              GLESDispatchMaxVersion extVersion,
                              const std::string& ext,
                              std::string& to) {
    // If we chose a GLES version less than or equal to
    // the |extVersion| the extension |ext| is tagged with,
    // filter it according to the whitelist.
    if (emugl::hasExtension(from.c_str(), ext.c_str()) &&
        currVersion > extVersion) {
        to += ext;
        to += " ";
    }
}

static bool sWhitelistedExtensionsGLES2(const std::string& hostExt) {

#define WHITELIST(ext) \
    if (hostExt == #ext) return true; \

WHITELIST(GL_OES_compressed_ETC1_RGB8_texture)
WHITELIST(GL_OES_depth24)
WHITELIST(GL_OES_depth32)
WHITELIST(GL_OES_depth_texture)
WHITELIST(GL_OES_depth_texture_cube_map)
WHITELIST(GL_OES_EGL_image)
WHITELIST(GL_OES_EGL_image_external)
WHITELIST(GL_OES_EGL_sync)
WHITELIST(GL_OES_element_index_uint)
WHITELIST(GL_OES_framebuffer_object)
WHITELIST(GL_OES_packed_depth_stencil)
WHITELIST(GL_OES_rgb8_rgba8)
WHITELIST(GL_OES_standard_derivatives)
WHITELIST(GL_OES_texture_float)
WHITELIST(GL_OES_texture_float_linear)
WHITELIST(GL_OES_texture_half_float)
WHITELIST(GL_OES_texture_half_float_linear)
WHITELIST(GL_OES_texture_npot)
WHITELIST(GL_OES_texture_3D)
WHITELIST(GL_OVR_multiview2)
WHITELIST(GL_EXT_multiview_texture_multisample)
WHITELIST(GL_EXT_blend_minmax)
WHITELIST(GL_EXT_color_buffer_half_float)
WHITELIST(GL_EXT_draw_buffers)
WHITELIST(GL_EXT_instanced_arrays)
WHITELIST(GL_EXT_occlusion_query_boolean)
WHITELIST(GL_EXT_read_format_bgra)
WHITELIST(GL_EXT_texture_compression_rgtc)
WHITELIST(GL_EXT_texture_filter_anisotropic)
WHITELIST(GL_EXT_texture_format_BGRA8888)
WHITELIST(GL_EXT_texture_rg)
WHITELIST(GL_ANGLE_framebuffer_blit)
WHITELIST(GL_ANGLE_framebuffer_multisample)
WHITELIST(GL_ANGLE_instanced_arrays)
WHITELIST(GL_CHROMIUM_texture_filtering_hint)
WHITELIST(GL_NV_fence)
WHITELIST(GL_NV_framebuffer_blit)
WHITELIST(GL_NV_read_depth)

#if defined(__linux__)
WHITELIST(GL_EXT_texture_compression_bptc)
WHITELIST(GL_EXT_texture_compression_s3tc)
#endif

#undef WHITELIST

    return false;
}

std::string filterExtensionsBasedOnMaxVersion(const gfxstream::host::FeatureSet& features,
                                              GLESDispatchMaxVersion ver,
                                              const std::string& exts) {
    // We need to advertise ES 2 extensions if:
    // a. the dispatch version on the host is ES 2
    // b. the guest image is not updated for ES 3+
    // (GLESDynamicVersion is disabled)
    if (ver > GLES_DISPATCH_MAX_VERSION_2 && features.GlesDynamicVersion.enabled) {
        return exts;
    }

    std::string filteredExtensions;
    filteredExtensions.reserve(4096);
    auto add = [&filteredExtensions](const std::string& hostExt) {
        if (!hostExt.empty() &&
            sWhitelistedExtensionsGLES2(hostExt)) {
            filteredExtensions += hostExt;
            filteredExtensions += " ";
        }
    };

    android::base::split<std::string>(exts, " ", add);

    return filteredExtensions;
}

}  // namespace gl
}  // namespace gfxstream
