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