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 namespace tcu 29 { 30 class CommandLine; 31 class Platform; 32 class RenderTarget; 33 } 34 35 namespace glw 36 { 37 class Functions; 38 class FunctionLoader; 39 } 40 41 namespace glu 42 { 43 44 class ContextType; 45 class ContextInfo; 46 47 enum Profile 48 { 49 PROFILE_ES = 0, //!< OpenGL ES 50 PROFILE_CORE, //!< OpenGL Core Profile 51 PROFILE_COMPATIBILITY, //!< OpenGL Compatibility Profile 52 53 PROFILE_LAST 54 }; 55 56 enum ContextFlags 57 { 58 CONTEXT_ROBUST = (1<<0), //!< Robust context 59 CONTEXT_DEBUG = (1<<1), //!< Debug context 60 CONTEXT_FORWARD_COMPATIBLE = (1<<2) //!< Forward-compatible context 61 }; 62 63 inline ContextFlags operator| (ContextFlags a, ContextFlags b) { return ContextFlags((deUint32)a|(deUint32)b); } 64 inline ContextFlags operator& (ContextFlags a, ContextFlags b) { return ContextFlags((deUint32)a&(deUint32)b); } 65 inline ContextFlags operator~ (ContextFlags a) { return ContextFlags(~(deUint32)a); } 66 67 /*--------------------------------------------------------------------*//*! 68 * \brief Rendering API version and profile. 69 *//*--------------------------------------------------------------------*/ 70 class ApiType 71 { 72 public: 73 ApiType (void) : m_bits(pack(0, 0, PROFILE_LAST)) {} 74 ApiType (int major, int minor, Profile profile) : m_bits(pack(major, minor, profile)) {} 75 76 int getMajorVersion (void) const { return int((m_bits>>MAJOR_SHIFT) & ((1u<<MAJOR_BITS)-1u)); } 77 int getMinorVersion (void) const { return int((m_bits>>MINOR_SHIFT) & ((1u<<MINOR_BITS)-1u)); } 78 Profile getProfile (void) const { return Profile((m_bits>>PROFILE_SHIFT) & ((1u<<PROFILE_BITS)-1u)); } 79 80 bool operator== (ApiType other) const { return m_bits == other.m_bits; } 81 bool operator!= (ApiType other) const { return m_bits != other.m_bits; } 82 83 deUint32 getPacked (void) const { return m_bits; } 84 85 // Shorthands 86 static ApiType es (int major, int minor) { return ApiType(major, minor, PROFILE_ES); } 87 static ApiType core (int major, int minor) { return ApiType(major, minor, PROFILE_CORE); } 88 static ApiType compatibility (int major, int minor) { return ApiType(major, minor, PROFILE_COMPATIBILITY); } 89 90 protected: 91 ApiType (deUint32 bits) : m_bits(bits) {} 92 static ApiType fromBits (deUint32 bits) { return ApiType(bits); } 93 94 static deUint32 pack (int major, int minor, Profile profile); 95 96 deUint32 m_bits; 97 98 enum 99 { 100 MAJOR_BITS = 4, 101 MINOR_BITS = 4, 102 PROFILE_BITS = 2, 103 TOTAL_API_BITS = MAJOR_BITS+MINOR_BITS+PROFILE_BITS, 104 105 MAJOR_SHIFT = 0, 106 MINOR_SHIFT = MAJOR_SHIFT+MAJOR_BITS, 107 PROFILE_SHIFT = MINOR_SHIFT+MINOR_BITS 108 }; 109 } DE_WARN_UNUSED_TYPE; 110 111 inline deUint32 ApiType::pack (int major, int minor, Profile profile) 112 { 113 deUint32 bits = 0; 114 115 DE_ASSERT((deUint32(major) & ~((1<<MAJOR_BITS)-1)) == 0); 116 DE_ASSERT((deUint32(minor) & ~((1<<MINOR_BITS)-1)) == 0); 117 DE_ASSERT((deUint32(profile) & ~((1<<PROFILE_BITS)-1)) == 0); 118 119 bits |= deUint32(major) << MAJOR_SHIFT; 120 bits |= deUint32(minor) << MINOR_SHIFT; 121 bits |= deUint32(profile) << PROFILE_SHIFT; 122 123 return bits; 124 } 125 126 /*--------------------------------------------------------------------*//*! 127 * \brief Rendering context type. 128 * 129 * ContextType differs from API type by adding context flags. They are 130 * crucial in for example determining when GL core context supports 131 * certain API version (forward-compatible bit). 132 * 133 * \note You should NEVER compare ContextTypes against each other, as 134 * you most likely don't want to take flags into account. For example 135 * the test code almost certainly doesn't want to check that you have 136 * EXACTLY ES3.1 context with debug, but without for example robustness. 137 *//*--------------------------------------------------------------------*/ 138 class ContextType : private ApiType 139 { 140 public: 141 ContextType (void) {} 142 ContextType (int major, int minor, Profile profile, ContextFlags flags = ContextFlags(0)); 143 explicit ContextType (ApiType apiType, ContextFlags flags = ContextFlags(0)); 144 145 ApiType getAPI (void) const { return ApiType::fromBits(m_bits & ((1u<<TOTAL_API_BITS)-1u)); } 146 ContextFlags getFlags (void) const { return ContextFlags((m_bits>>FLAGS_SHIFT) & ((1u<<FLAGS_BITS)-1u)); } 147 148 using ApiType::getMajorVersion; 149 using ApiType::getMinorVersion; 150 using ApiType::getProfile; 151 152 protected: 153 static deUint32 pack (deUint32 apiBits, ContextFlags flags); 154 155 enum 156 { 157 FLAGS_BITS = 3, 158 TOTAL_CONTEXT_BITS = TOTAL_API_BITS+FLAGS_BITS, 159 FLAGS_SHIFT = TOTAL_API_BITS 160 }; 161 } DE_WARN_UNUSED_TYPE; 162 163 inline ContextType::ContextType (int major, int minor, Profile profile, ContextFlags flags) 164 : ApiType(major, minor, profile) 165 { 166 m_bits = pack(m_bits, flags); 167 } 168 169 inline ContextType::ContextType (ApiType apiType, ContextFlags flags) 170 : ApiType(apiType) 171 { 172 m_bits = pack(m_bits, flags); 173 } 174 175 inline deUint32 ContextType::pack (deUint32 apiBits, ContextFlags flags) 176 { 177 deUint32 bits = apiBits; 178 179 DE_ASSERT((deUint32(flags) & ~((1<<FLAGS_BITS)-1)) == 0); 180 bits |= deUint32(flags) << FLAGS_SHIFT; 181 182 return bits; 183 } 184 185 inline bool isContextTypeES (ContextType type) { return type.getAPI().getProfile() == PROFILE_ES; } 186 inline bool isContextTypeGLCore (ContextType type) { return type.getAPI().getProfile() == PROFILE_CORE; } 187 inline bool isContextTypeGLCompatibility(ContextType type) { return type.getAPI().getProfile() == PROFILE_COMPATIBILITY; } 188 bool contextSupports (ContextType ctxType, ApiType requiredApiType); 189 190 /*--------------------------------------------------------------------*//*! 191 * \brief Rendering context abstraction. 192 *//*--------------------------------------------------------------------*/ 193 class RenderContext 194 { 195 public: 196 RenderContext (void) {} 197 virtual ~RenderContext (void) {} 198 199 //! Get context type. Must match to type given to ContextFactory::createContext(). 200 virtual ContextType getType (void) const = DE_NULL; 201 202 //! Get GL function table. Should be filled with all core entry points for context type. 203 virtual const glw::Functions& getFunctions (void) const = DE_NULL; 204 205 //! Get render target information. 206 virtual const tcu::RenderTarget& getRenderTarget (void) const = DE_NULL; 207 208 //! Do post-render actions (swap buffers for example). 209 virtual void postIterate (void) = DE_NULL; 210 211 //! Get default framebuffer. 212 virtual deUint32 getDefaultFramebuffer (void) const { return 0; } 213 214 private: 215 RenderContext (const RenderContext& other); // Not allowed! 216 RenderContext& operator= (const RenderContext& other); // Not allowed! 217 }; 218 219 // Utilities 220 221 RenderContext* createDefaultRenderContext (tcu::Platform& platform, const tcu::CommandLine& cmdLine, ApiType apiType); 222 223 void initCoreFunctions (glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType); 224 void initExtensionFunctions (glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType, int numExtensions, const char* const* extensions); 225 226 // \note initFunctions() and initExtensionFunctions() without explicit extension list 227 // use glGetString* to query list of extensions, so it needs current GL context. 228 void initFunctions (glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType); 229 void initExtensionFunctions (glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType); 230 231 bool hasExtension (const glw::Functions& gl, ApiType apiType, const std::string& extension); 232 233 } // glu 234 235 #endif // _GLURENDERCONTEXT_HPP 236