1 #ifndef _GLURENDERCONTEXT_HPP 2 #define _GLURENDERCONTEXT_HPP 3 /*------------------------------------------------------------------------- 4 * drawElements Quality Program OpenGL ES Utilities 5 * ------------------------------------------------ 6 * 7 * Copyright 2014 The Android Open Source Project 8 * 9 * Licensed under the Apache License, Version 2.0 (the "License"); 10 * you may not use this file except in compliance with the License. 11 * You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 * 21 *//*! 22 * \file 23 * \brief OpenGL ES rendering context. 24 *//*--------------------------------------------------------------------*/ 25 26 #include "tcuDefs.hpp" 27 28 // glw::GenericFuncType 29 #include "glwFunctionLoader.hpp" 30 31 namespace tcu 32 { 33 class CommandLine; 34 class Platform; 35 class RenderTarget; 36 } 37 38 namespace glw 39 { 40 class Functions; 41 class FunctionLoader; 42 } 43 44 namespace glu 45 { 46 47 class ContextType; 48 class ContextInfo; 49 struct RenderConfig; 50 51 enum Profile 52 { 53 PROFILE_ES = 0, //!< OpenGL ES 54 PROFILE_CORE, //!< OpenGL Core Profile 55 PROFILE_COMPATIBILITY, //!< OpenGL Compatibility Profile 56 57 PROFILE_LAST 58 }; 59 60 enum ContextFlags 61 { 62 CONTEXT_ROBUST = (1<<0), //!< Robust context 63 CONTEXT_DEBUG = (1<<1), //!< Debug context 64 CONTEXT_FORWARD_COMPATIBLE = (1<<2), //!< Forward-compatible context 65 CONTEXT_NO_ERROR = (1<<3) //!< No error context 66 }; 67 68 inline ContextFlags operator| (ContextFlags a, ContextFlags b) { return ContextFlags((deUint32)a|(deUint32)b); } 69 inline ContextFlags operator& (ContextFlags a, ContextFlags b) { return ContextFlags((deUint32)a&(deUint32)b); } 70 inline ContextFlags operator~ (ContextFlags a) { return ContextFlags(~(deUint32)a); } 71 72 /*--------------------------------------------------------------------*//*! 73 * \brief Rendering API version and profile. 74 *//*--------------------------------------------------------------------*/ 75 class ApiType 76 { 77 public: 78 ApiType (void) : m_bits(pack(0, 0, PROFILE_LAST)) {} 79 ApiType (int major, int minor, Profile profile) : m_bits(pack(major, minor, profile)) {} 80 81 int getMajorVersion (void) const { return int((m_bits>>MAJOR_SHIFT) & ((1u<<MAJOR_BITS)-1u)); } 82 int getMinorVersion (void) const { return int((m_bits>>MINOR_SHIFT) & ((1u<<MINOR_BITS)-1u)); } 83 Profile getProfile (void) const { return Profile((m_bits>>PROFILE_SHIFT) & ((1u<<PROFILE_BITS)-1u)); } 84 85 bool operator== (ApiType other) const { return m_bits == other.m_bits; } 86 bool operator!= (ApiType other) const { return m_bits != other.m_bits; } 87 88 deUint32 getPacked (void) const { return m_bits; } 89 90 // Shorthands 91 static ApiType es (int major, int minor) { return ApiType(major, minor, PROFILE_ES); } 92 static ApiType core (int major, int minor) { return ApiType(major, minor, PROFILE_CORE); } 93 static ApiType compatibility (int major, int minor) { return ApiType(major, minor, PROFILE_COMPATIBILITY); } 94 95 protected: 96 ApiType (deUint32 bits) : m_bits(bits) {} 97 static ApiType fromBits (deUint32 bits) { return ApiType(bits); } 98 99 static deUint32 pack (int major, int minor, Profile profile); 100 101 deUint32 m_bits; 102 103 enum 104 { 105 MAJOR_BITS = 4, 106 MINOR_BITS = 4, 107 PROFILE_BITS = 2, 108 TOTAL_API_BITS = MAJOR_BITS+MINOR_BITS+PROFILE_BITS, 109 110 MAJOR_SHIFT = 0, 111 MINOR_SHIFT = MAJOR_SHIFT+MAJOR_BITS, 112 PROFILE_SHIFT = MINOR_SHIFT+MINOR_BITS 113 }; 114 } DE_WARN_UNUSED_TYPE; 115 116 inline deUint32 ApiType::pack (int major, int minor, Profile profile) 117 { 118 deUint32 bits = 0; 119 120 DE_ASSERT((deUint32(major) & ~((1<<MAJOR_BITS)-1)) == 0); 121 DE_ASSERT((deUint32(minor) & ~((1<<MINOR_BITS)-1)) == 0); 122 DE_ASSERT((deUint32(profile) & ~((1<<PROFILE_BITS)-1)) == 0); 123 124 bits |= deUint32(major) << MAJOR_SHIFT; 125 bits |= deUint32(minor) << MINOR_SHIFT; 126 bits |= deUint32(profile) << PROFILE_SHIFT; 127 128 return bits; 129 } 130 131 /*--------------------------------------------------------------------*//*! 132 * \brief Rendering context type. 133 * 134 * ContextType differs from API type by adding context flags. They are 135 * crucial in for example determining when GL core context supports 136 * certain API version (forward-compatible bit). 137 * 138 * \note You should NEVER compare ContextTypes against each other, as 139 * you most likely don't want to take flags into account. For example 140 * the test code almost certainly doesn't want to check that you have 141 * EXACTLY ES3.1 context with debug, but without for example robustness. 142 *//*--------------------------------------------------------------------*/ 143 class ContextType : private ApiType 144 { 145 public: 146 ContextType (void) {} 147 ContextType (int major, int minor, Profile profile, ContextFlags flags = ContextFlags(0)); 148 explicit ContextType (ApiType apiType, ContextFlags flags = ContextFlags(0)); 149 150 ApiType getAPI (void) const { return ApiType::fromBits(m_bits & ((1u<<TOTAL_API_BITS)-1u)); } 151 ContextFlags getFlags (void) const { return ContextFlags((m_bits>>FLAGS_SHIFT) & ((1u<<FLAGS_BITS)-1u)); } 152 153 using ApiType::getMajorVersion; 154 using ApiType::getMinorVersion; 155 using ApiType::getProfile; 156 157 protected: 158 static deUint32 pack (deUint32 apiBits, ContextFlags flags); 159 160 enum 161 { 162 FLAGS_BITS = 4, 163 TOTAL_CONTEXT_BITS = TOTAL_API_BITS+FLAGS_BITS, 164 FLAGS_SHIFT = TOTAL_API_BITS 165 }; 166 } DE_WARN_UNUSED_TYPE; 167 168 inline ContextType::ContextType (int major, int minor, Profile profile, ContextFlags flags) 169 : ApiType(major, minor, profile) 170 { 171 m_bits = pack(m_bits, flags); 172 } 173 174 inline ContextType::ContextType (ApiType apiType, ContextFlags flags) 175 : ApiType(apiType) 176 { 177 m_bits = pack(m_bits, flags); 178 } 179 180 inline deUint32 ContextType::pack (deUint32 apiBits, ContextFlags flags) 181 { 182 deUint32 bits = apiBits; 183 184 DE_ASSERT((deUint32(flags) & ~((1u<<FLAGS_BITS)-1u)) == 0); 185 186 bits |= deUint32(flags) << FLAGS_SHIFT; 187 188 return bits; 189 } 190 191 inline bool isContextTypeES (ContextType type) { return type.getAPI().getProfile() == PROFILE_ES; } 192 inline bool isContextTypeGLCore (ContextType type) { return type.getAPI().getProfile() == PROFILE_CORE; } 193 inline bool isContextTypeGLCompatibility(ContextType type) { return type.getAPI().getProfile() == PROFILE_COMPATIBILITY; } 194 bool contextSupports (ContextType ctxType, ApiType requiredApiType); 195 196 const char* getApiTypeDescription (ApiType type); 197 198 /*--------------------------------------------------------------------*//*! 199 * \brief Rendering context abstraction. 200 *//*--------------------------------------------------------------------*/ 201 class RenderContext 202 { 203 public: 204 RenderContext (void) {} 205 virtual ~RenderContext (void) {} 206 207 //! Get context type. Must match to type given to ContextFactory::createContext(). 208 virtual ContextType getType (void) const = DE_NULL; 209 210 //! Get GL function table. Should be filled with all core entry points for context type. 211 virtual const glw::Functions& getFunctions (void) const = DE_NULL; 212 213 //! Get render target information. 214 virtual const tcu::RenderTarget& getRenderTarget (void) const = DE_NULL; 215 216 //! Do post-render actions (swap buffers for example). 217 virtual void postIterate (void) = DE_NULL; 218 219 //! Get default framebuffer. 220 virtual deUint32 getDefaultFramebuffer (void) const { return 0; } 221 222 //! Get extension function address. 223 virtual glw::GenericFuncType getProcAddress (const char* name) const; 224 225 //! Make context current in thread. Optional to support. 226 virtual void makeCurrent (void); 227 228 private: 229 RenderContext (const RenderContext& other); // Not allowed! 230 RenderContext& operator= (const RenderContext& other); // Not allowed! 231 }; 232 233 // Utilities 234 235 RenderContext* createRenderContext (tcu::Platform& platform, const tcu::CommandLine& cmdLine, const RenderConfig& config, const RenderContext* sharedContext = DE_NULL); 236 RenderContext* createDefaultRenderContext (tcu::Platform& platform, const tcu::CommandLine& cmdLine, ApiType apiType); 237 238 void initCoreFunctions (glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType); 239 void initExtensionFunctions (glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType, int numExtensions, const char* const* extensions); 240 241 // \note initFunctions() and initExtensionFunctions() without explicit extension list 242 // use glGetString* to query list of extensions, so it needs current GL context. 243 void initFunctions (glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType); 244 void initExtensionFunctions (glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType); 245 246 bool hasExtension (const glw::Functions& gl, ApiType apiType, const std::string& extension); 247 248 } // glu 249 250 #endif // _GLURENDERCONTEXT_HPP 251