// 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 #include #include #include #include #include "OpenGLESDispatch/GLESv2Dispatch.h" #include "gfxstream/host/Features.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, bool glesDynamicVersion); EGLint mGuestConfig; EGLConfig mHostConfig; std::vector mAttribValues; bool mGlesDynamicVersion = false; }; // 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, const gfxstream::host::FeatureSet& features); // 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::const_iterator begin() const { return mConfigs.begin(); } std::vector::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 mConfigs; EGLDisplay mDisplay = 0; GLESDispatchMaxVersion mGlesDispatchMaxVersion; bool mGlesDynamicVersion = false; }; } // namespace gl } // namespace gfxstream