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

#include "OpenGLESDispatch/EGLDispatch.h"
#include "gfxstream/host/Features.h"
#include "host-common/opengl/emugl_config.h"
#include "host-common/logging.h"
#include "host-common/misc.h"
#include "host-common/opengl/misc.h"

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

namespace gfxstream {
namespace gl {
namespace {

#ifndef EGL_PRESERVED_RESOURCES
#define EGL_PRESERVED_RESOURCES 0x3030
#endif

const GLuint kConfigAttributes[] = {
    EGL_DEPTH_SIZE,     // must be first - see getDepthSize()
    EGL_STENCIL_SIZE,   // must be second - see getStencilSize()
    EGL_RENDERABLE_TYPE,// must be third - see getRenderableType()
    EGL_SURFACE_TYPE,   // must be fourth - see getSurfaceType()
    EGL_CONFIG_ID,      // must be fifth  - see chooseConfig()
    EGL_BUFFER_SIZE,
    EGL_ALPHA_SIZE,
    EGL_BLUE_SIZE,
    EGL_GREEN_SIZE,
    EGL_RED_SIZE,
    EGL_CONFIG_CAVEAT,
    EGL_LEVEL,
    EGL_MAX_PBUFFER_HEIGHT,
    EGL_MAX_PBUFFER_PIXELS,
    EGL_MAX_PBUFFER_WIDTH,
    EGL_NATIVE_RENDERABLE,
    EGL_NATIVE_VISUAL_ID,
    EGL_NATIVE_VISUAL_TYPE,
    EGL_PRESERVED_RESOURCES,
    EGL_SAMPLES,
    EGL_SAMPLE_BUFFERS,
    EGL_TRANSPARENT_TYPE,
    EGL_TRANSPARENT_BLUE_VALUE,
    EGL_TRANSPARENT_GREEN_VALUE,
    EGL_TRANSPARENT_RED_VALUE,
    EGL_BIND_TO_TEXTURE_RGB,
    EGL_BIND_TO_TEXTURE_RGBA,
    EGL_MIN_SWAP_INTERVAL,
    EGL_MAX_SWAP_INTERVAL,
    EGL_LUMINANCE_SIZE,
    EGL_ALPHA_MASK_SIZE,
    EGL_COLOR_BUFFER_TYPE,
    //EGL_MATCH_NATIVE_PIXMAP,
    EGL_RECORDABLE_ANDROID,
    EGL_CONFORMANT
};

const size_t kConfigAttributesLen =
        sizeof(kConfigAttributes) / sizeof(kConfigAttributes[0]);

bool isCompatibleHostConfig(EGLConfig config, EGLDisplay display) {
    // Filter out configs which do not support pbuffers, since they
    // are used to implement window surfaces.
    EGLint surfaceType;
    s_egl.eglGetConfigAttrib(
            display, config, EGL_SURFACE_TYPE, &surfaceType);
    if (!(surfaceType & EGL_PBUFFER_BIT)) {
        return false;
    }

    // Filter out configs that do not support RGB pixel values.
    EGLint redSize = 0, greenSize = 0, blueSize = 0;
    s_egl.eglGetConfigAttrib(
            display, config,EGL_RED_SIZE, &redSize);
    s_egl.eglGetConfigAttrib(
            display, config, EGL_GREEN_SIZE, &greenSize);
    s_egl.eglGetConfigAttrib(
            display, config, EGL_BLUE_SIZE, &blueSize);
    if (!redSize || !greenSize || !blueSize) {
        return false;
    }

    return true;
}

}  // namespace

EmulatedEglConfig::EmulatedEglConfig(EGLint guestConfig,
                                     EGLConfig hostConfig,
                                     EGLDisplay hostDisplay,
                                     bool glesDynamicVersion)
        : mGuestConfig(guestConfig),
          mHostConfig(hostConfig),
          mAttribValues(kConfigAttributesLen),
          mGlesDynamicVersion(glesDynamicVersion) {
    for (size_t i = 0; i < kConfigAttributesLen; ++i) {
        mAttribValues[i] = 0;
        s_egl.eglGetConfigAttrib(hostDisplay,
                                 hostConfig,
                                 kConfigAttributes[i],
                                 &mAttribValues[i]);

        // This implementation supports guest window surfaces by wrapping
        // them around host Pbuffers, so always report it to the guest.
        if (kConfigAttributes[i] == EGL_SURFACE_TYPE) {
            mAttribValues[i] |= EGL_WINDOW_BIT;
        }

        // Don't report ES3 renderable type if we don't support it.
        if (kConfigAttributes[i] == EGL_RENDERABLE_TYPE) {
            if (!mGlesDynamicVersion && mAttribValues[i] & EGL_OPENGL_ES3_BIT) {
                mAttribValues[i] &= ~EGL_OPENGL_ES3_BIT;
            }
        }
    }
}

EmulatedEglConfigList::EmulatedEglConfigList(EGLDisplay display,
                                             GLESDispatchMaxVersion version,
                                             const gfxstream::host::FeatureSet& features)
        : mDisplay(display),
          mGlesDispatchMaxVersion(version),
          mGlesDynamicVersion(features.GlesDynamicVersion.enabled) {
    if (display == EGL_NO_DISPLAY) {
        ERR("Invalid display value %p (EGL_NO_DISPLAY).", (void*)display);
        return;
    }

    EGLint numHostConfigs = 0;
    if (!s_egl.eglGetConfigs(display, NULL, 0, &numHostConfigs)) {
        ERR("Failed to get number of host EGL configs.");
        return;
    }
    std::vector<EGLConfig> hostConfigs(numHostConfigs);
    s_egl.eglGetConfigs(display, hostConfigs.data(), numHostConfigs, &numHostConfigs);

    for (EGLConfig hostConfig : hostConfigs) {
        // Filter out configs that are not compatible with our implementation.
        if (!isCompatibleHostConfig(hostConfig, display)) {
            continue;
        }

        const EGLint guestConfig = static_cast<EGLint>(mConfigs.size());
        mConfigs.push_back(EmulatedEglConfig(guestConfig, hostConfig, display, mGlesDynamicVersion));
    }
}

int EmulatedEglConfigList::chooseConfig(const EGLint* attribs,
                                        EGLint* configs,
                                        EGLint configsSize) const {
    EGLint numHostConfigs = 0;
    if (!s_egl.eglGetConfigs(mDisplay, NULL, 0, &numHostConfigs)) {
        ERR("Failed to get number of host EGL configs.");
        return 0;
    }

    // If EGL_SURFACE_TYPE appears in |attribs|, the value passed to
    // eglChooseConfig should be forced to EGL_PBUFFER_BIT because that's
    // what it used by the current implementation, exclusively. This forces
    // the rewrite of |attribs| into a new array.
    bool hasSurfaceType = false;
    bool wantSwapPreserved = false;
    int surfaceTypeIdx = 0;
    int numAttribs = 0;
    std::vector<EGLint> newAttribs;
    while (attribs[numAttribs] != EGL_NONE) {
        if (attribs[numAttribs] == EGL_SURFACE_TYPE) {
            hasSurfaceType = true;
            surfaceTypeIdx = numAttribs;
            if (attribs[numAttribs+1] & EGL_SWAP_BEHAVIOR_PRESERVED_BIT) {
                wantSwapPreserved = true;
            }
        }

        // Reject config if guest asked for ES3 and we don't have it.
        if (attribs[numAttribs] == EGL_RENDERABLE_TYPE) {
            if (attribs[numAttribs + 1] != EGL_DONT_CARE &&
                attribs[numAttribs + 1] & EGL_OPENGL_ES3_BIT_KHR &&
                (!mGlesDynamicVersion || mGlesDispatchMaxVersion < GLES_DISPATCH_MAX_VERSION_3_0)) {
                return 0;
            }
        }
        numAttribs += 2;
    }

    if (numAttribs) {
        newAttribs.resize(numAttribs);
        memcpy(&newAttribs[0], attribs, numAttribs * sizeof(EGLint));
    }

    int apiLevel;
    emugl::getAvdInfo(NULL, &apiLevel);

    if (!hasSurfaceType) {
        newAttribs.push_back(EGL_SURFACE_TYPE);
        newAttribs.push_back(0);
    } else if (wantSwapPreserved && apiLevel <= 19) {
        newAttribs[surfaceTypeIdx + 1] &= ~(EGLint)EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
    }
    if (emugl::getRenderer() == SELECTED_RENDERER_SWIFTSHADER ||
        emugl::getRenderer() == SELECTED_RENDERER_SWIFTSHADER_INDIRECT ||
        emugl::getRenderer() == SELECTED_RENDERER_ANGLE ||
        emugl::getRenderer() == SELECTED_RENDERER_ANGLE_INDIRECT) {
        newAttribs.push_back(EGL_CONFIG_CAVEAT);
        newAttribs.push_back(EGL_DONT_CARE);
    }

    newAttribs.push_back(EGL_NONE);


    std::vector<EGLConfig> matchedConfigs(numHostConfigs);
    if (s_egl.eglChooseConfig(mDisplay,
                              &newAttribs[0],
                              matchedConfigs.data(),
                              numHostConfigs,
                              &numHostConfigs) == EGL_FALSE) {
        return -s_egl.eglGetError();
    }

    int result = 0;
    for (int n = 0; n < numHostConfigs; ++n) {
        // Don't count or write more than |configsSize| items if |configs|
        // is not NULL.
        if (configs && configsSize > 0 && result >= configsSize) {
            break;
        }
        // Skip incompatible host configs.
        if (!isCompatibleHostConfig(matchedConfigs[n], mDisplay)) {
            continue;
        }
        // Find the EmulatedEglConfig with the same EGL_CONFIG_ID
        EGLint hostConfigId;
        s_egl.eglGetConfigAttrib(
                mDisplay, matchedConfigs[n], EGL_CONFIG_ID, &hostConfigId);
        for (const EmulatedEglConfig& config : mConfigs) {
            if (config.getConfigId() == hostConfigId) {
                // There is a match. Write it to |configs| if it is not NULL.
                if (configs && result < configsSize) {
                    configs[result] = config.getGuestEglConfig();
                }
                result++;
                break;
            }
        }
    }

    return result;
}


void EmulatedEglConfigList::getPackInfo(EGLint* numConfigs,
                               EGLint* numAttributes) const {
    if (numConfigs) {
        *numConfigs = mConfigs.size();
    }
    if (numAttributes) {
        *numAttributes = static_cast<EGLint>(kConfigAttributesLen);
    }
}

EGLint EmulatedEglConfigList::packConfigs(GLuint bufferByteSize, GLuint* buffer) const {
    GLuint numAttribs = static_cast<GLuint>(kConfigAttributesLen);
    GLuint kGLuintSize = static_cast<GLuint>(sizeof(GLuint));
    GLuint neededByteSize = (mConfigs.size() + 1) * numAttribs * kGLuintSize;
    if (!buffer || bufferByteSize < neededByteSize) {
        return -neededByteSize;
    }
    // Write to the buffer the config attribute ids, followed for each one
    // of the configs, their values.
    memcpy(buffer, kConfigAttributes, kConfigAttributesLen * kGLuintSize);

    for (int i = 0; i < mConfigs.size(); ++i) {
        memcpy(buffer + (i + 1) * kConfigAttributesLen,
               mConfigs[i].mAttribValues.data(),
               kConfigAttributesLen * kGLuintSize);
    }
    return mConfigs.size();
}

}  // namespace gl
}  // namespace gfxstream