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