// 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.

#pragma once

#include <stddef.h>
#include <vector>

#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES/gl.h>

#include "OpenGLESDispatch/GLESv2Dispatch.h"

namespace gfxstream {
namespace gl {

// A class used to model an EGL config that is exposed to the guest.
//
// This really wraps a host EGLConfig handle, and provides a few cached
// attributes that can be retrieved through direct accessors, like
// getDepthSize().
//
// Each EmulatedEglConfig is identified by a unique id which is its index in
// an EmulatedEglConfigList instance (as declared below). It is not related to
// the host EGLConfig value or its EGL_CONFIG_ID.
//
// One doesn't create an EmulatedEglConfig instance. Instead, create and initialize
// an EmulatedEglConfigList from the host EGLDisplay, and use its size() and get()
// methods to access it.
class EmulatedEglConfig {
  public:
    EmulatedEglConfig(EmulatedEglConfig&&) = default;
    EmulatedEglConfig& operator=(EmulatedEglConfig&&) = default;

    // Retrieve host EGLConfig.
    EGLConfig getHostEglConfig() const { return mHostConfig; }

    EGLint getGuestEglConfig() const { return mGuestConfig; }

    // Get depth size in bits.
    GLuint getDepthSize() const { return mAttribValues[0]; }

    // Get stencil size in bits.
    GLuint getStencilSize() const { return mAttribValues[1]; }

    // Get renderable type mask.
    GLuint getRenderableType() const { return mAttribValues[2]; }

    // Get surface type mask.
    GLuint getSurfaceType() const { return mAttribValues[3]; }

    // Get the EGL_CONFIG_ID value. This is the same as the one of the
    // underlying host EGLConfig handle.
    GLint getConfigId() const { return (GLint)mAttribValues[4]; }

  private:
    friend class EmulatedEglConfigList;

    explicit EmulatedEglConfig(EGLint guestConfig,
                               EGLConfig hostConfig,
                               EGLDisplay hostDisplay);

    EGLint mGuestConfig;
    EGLConfig mHostConfig;
    std::vector<GLint> mAttribValues;
};

// A class to model the list of EmulatedEglConfig for a given EGLDisplay, this is
// built from the list of host EGLConfig handles, filtered to only accept
// configs that are useful by the rendering library (e.g. they must support
// PBuffers and RGB pixel values).
//
// Usage is the following:
//
// 1) Create new instance by passing host EGLDisplay value.
//
// 2) Call empty() to check that the list is not empty, which would indicate
//    an error during creation.
//
// 3) EmulatedEglConfig instances are identified by numbers in 0..(N-1) range, where
//    N is the result of the size() method.
//
// 4) Convert an EmulatedEglConfig id into an EmulatedEglConfig instance with get().
//
// 5) Use getPackInfo() and packConfigs() to retrieve information about
//    available configs to the guest.
class EmulatedEglConfigList {
  public:
    // Create a new list of EmulatedEglConfig instance, by querying all compatible
    // host configs from |display|. A compatible config is one that supports
    // Pbuffers and RGB pixel values.
    //
    // After construction, call empty() to check if there are items.
    // An empty list means there was an error during construction.
    explicit EmulatedEglConfigList(EGLDisplay display,
                                   GLESDispatchMaxVersion dispatchMaxVersion);

    // Return true iff the list is empty. true means there was an error
    // during construction.
    bool empty() const { return mConfigs.empty(); }

    // Return the number of EmulatedEglConfig instances in the list.
    // Each instance is identified by a number from 0 to N-1,
    // where N is the result of this function.
    size_t size() const { return mConfigs.size(); }

    // Retrieve the EmulatedEglConfig instance associated with |guestId|,
    // which must be an integer between 0 and |size() - 1|. Returns
    // NULL in case of failure.
    const EmulatedEglConfig* get(int guestId) const {
        if (guestId >= 0 && guestId < mConfigs.size()) {
            return &mConfigs[guestId];
        } else {
            return NULL;
        }
    }

    std::vector<EmulatedEglConfig>::const_iterator begin() const { return mConfigs.begin(); }
    std::vector<EmulatedEglConfig>::const_iterator end() const { return mConfigs.end(); }

    // Use |attribs| a list of EGL attribute name/values terminated by
    // EGL_NONE, to select a set of matching EmulatedEglConfig instances.
    //
    // On success, returns the number of matching instances.
    // If |configs| is not NULL, it will be populated with the guest IDs
    // of the matched EmulatedEglConfig instances.
    //
    // |configsSize| is the number of entries in the |configs| array. The
    // function will never write more than |configsSize| entries into
    // |configsSize|.
    EGLint chooseConfig(const EGLint* attribs,
                        EGLint* configs,
                        EGLint configsSize) const;

    // Retrieve information that can be sent to the guest before packed
    // config list information. If |numConfigs| is NULL, then |*numConfigs|
    // will be set on return to the number of config instances.
    // If |numAttribs| is not NULL, then |*numAttribs| will be set on return
    // to the number of attribute values cached by each EmulatedEglConfig instance.
    void getPackInfo(EGLint* mumConfigs, EGLint* numAttribs) const;

    // Write the full list information into an array of EGLuint items.
    // |buffer| is the output buffer that will receive the data.
    // |bufferByteSize| is the buffer size in bytes.
    // On success, this returns
    EGLint packConfigs(GLuint bufferByteSize, GLuint* buffer) const;

  private:
    EmulatedEglConfigList(const EmulatedEglConfigList& other) = delete;

    std::vector<EmulatedEglConfig> mConfigs;
    EGLDisplay mDisplay = 0;
    GLESDispatchMaxVersion mGlesDispatchMaxVersion;
};

}  // namespace gl
}  // namespace gfxstream
