1 // Copyright (C) 2015 The Android Open Source Project 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #pragma once 16 17 #include <stddef.h> 18 #include <vector> 19 20 #include <EGL/egl.h> 21 #include <EGL/eglext.h> 22 #include <GLES/gl.h> 23 24 #include "OpenGLESDispatch/GLESv2Dispatch.h" 25 26 namespace gfxstream { 27 namespace gl { 28 29 // A class used to model an EGL config that is exposed to the guest. 30 // 31 // This really wraps a host EGLConfig handle, and provides a few cached 32 // attributes that can be retrieved through direct accessors, like 33 // getDepthSize(). 34 // 35 // Each EmulatedEglConfig is identified by a unique id which is its index in 36 // an EmulatedEglConfigList instance (as declared below). It is not related to 37 // the host EGLConfig value or its EGL_CONFIG_ID. 38 // 39 // One doesn't create an EmulatedEglConfig instance. Instead, create and initialize 40 // an EmulatedEglConfigList from the host EGLDisplay, and use its size() and get() 41 // methods to access it. 42 class EmulatedEglConfig { 43 public: 44 EmulatedEglConfig(EmulatedEglConfig&&) = default; 45 EmulatedEglConfig& operator=(EmulatedEglConfig&&) = default; 46 47 // Retrieve host EGLConfig. getHostEglConfig()48 EGLConfig getHostEglConfig() const { return mHostConfig; } 49 getGuestEglConfig()50 EGLint getGuestEglConfig() const { return mGuestConfig; } 51 52 // Get depth size in bits. getDepthSize()53 GLuint getDepthSize() const { return mAttribValues[0]; } 54 55 // Get stencil size in bits. getStencilSize()56 GLuint getStencilSize() const { return mAttribValues[1]; } 57 58 // Get renderable type mask. getRenderableType()59 GLuint getRenderableType() const { return mAttribValues[2]; } 60 61 // Get surface type mask. getSurfaceType()62 GLuint getSurfaceType() const { return mAttribValues[3]; } 63 64 // Get the EGL_CONFIG_ID value. This is the same as the one of the 65 // underlying host EGLConfig handle. getConfigId()66 GLint getConfigId() const { return (GLint)mAttribValues[4]; } 67 68 private: 69 friend class EmulatedEglConfigList; 70 71 explicit EmulatedEglConfig(EGLint guestConfig, 72 EGLConfig hostConfig, 73 EGLDisplay hostDisplay); 74 75 EGLint mGuestConfig; 76 EGLConfig mHostConfig; 77 std::vector<GLint> mAttribValues; 78 }; 79 80 // A class to model the list of EmulatedEglConfig for a given EGLDisplay, this is 81 // built from the list of host EGLConfig handles, filtered to only accept 82 // configs that are useful by the rendering library (e.g. they must support 83 // PBuffers and RGB pixel values). 84 // 85 // Usage is the following: 86 // 87 // 1) Create new instance by passing host EGLDisplay value. 88 // 89 // 2) Call empty() to check that the list is not empty, which would indicate 90 // an error during creation. 91 // 92 // 3) EmulatedEglConfig instances are identified by numbers in 0..(N-1) range, where 93 // N is the result of the size() method. 94 // 95 // 4) Convert an EmulatedEglConfig id into an EmulatedEglConfig instance with get(). 96 // 97 // 5) Use getPackInfo() and packConfigs() to retrieve information about 98 // available configs to the guest. 99 class EmulatedEglConfigList { 100 public: 101 // Create a new list of EmulatedEglConfig instance, by querying all compatible 102 // host configs from |display|. A compatible config is one that supports 103 // Pbuffers and RGB pixel values. 104 // 105 // After construction, call empty() to check if there are items. 106 // An empty list means there was an error during construction. 107 explicit EmulatedEglConfigList(EGLDisplay display, 108 GLESDispatchMaxVersion dispatchMaxVersion); 109 110 // Return true iff the list is empty. true means there was an error 111 // during construction. empty()112 bool empty() const { return mConfigs.empty(); } 113 114 // Return the number of EmulatedEglConfig instances in the list. 115 // Each instance is identified by a number from 0 to N-1, 116 // where N is the result of this function. size()117 size_t size() const { return mConfigs.size(); } 118 119 // Retrieve the EmulatedEglConfig instance associated with |guestId|, 120 // which must be an integer between 0 and |size() - 1|. Returns 121 // NULL in case of failure. get(int guestId)122 const EmulatedEglConfig* get(int guestId) const { 123 if (guestId >= 0 && guestId < mConfigs.size()) { 124 return &mConfigs[guestId]; 125 } else { 126 return NULL; 127 } 128 } 129 begin()130 std::vector<EmulatedEglConfig>::const_iterator begin() const { return mConfigs.begin(); } end()131 std::vector<EmulatedEglConfig>::const_iterator end() const { return mConfigs.end(); } 132 133 // Use |attribs| a list of EGL attribute name/values terminated by 134 // EGL_NONE, to select a set of matching EmulatedEglConfig instances. 135 // 136 // On success, returns the number of matching instances. 137 // If |configs| is not NULL, it will be populated with the guest IDs 138 // of the matched EmulatedEglConfig instances. 139 // 140 // |configsSize| is the number of entries in the |configs| array. The 141 // function will never write more than |configsSize| entries into 142 // |configsSize|. 143 EGLint chooseConfig(const EGLint* attribs, 144 EGLint* configs, 145 EGLint configsSize) const; 146 147 // Retrieve information that can be sent to the guest before packed 148 // config list information. If |numConfigs| is NULL, then |*numConfigs| 149 // will be set on return to the number of config instances. 150 // If |numAttribs| is not NULL, then |*numAttribs| will be set on return 151 // to the number of attribute values cached by each EmulatedEglConfig instance. 152 void getPackInfo(EGLint* mumConfigs, EGLint* numAttribs) const; 153 154 // Write the full list information into an array of EGLuint items. 155 // |buffer| is the output buffer that will receive the data. 156 // |bufferByteSize| is the buffer size in bytes. 157 // On success, this returns 158 EGLint packConfigs(GLuint bufferByteSize, GLuint* buffer) const; 159 160 private: 161 EmulatedEglConfigList(const EmulatedEglConfigList& other) = delete; 162 163 std::vector<EmulatedEglConfig> mConfigs; 164 EGLDisplay mDisplay = 0; 165 GLESDispatchMaxVersion mGlesDispatchMaxVersion; 166 }; 167 168 } // namespace gl 169 } // namespace gfxstream 170