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 31namespace tcu 32{ 33class CommandLine; 34class Platform; 35class RenderTarget; 36} 37 38namespace glw 39{ 40class Functions; 41class FunctionLoader; 42} 43 44namespace glu 45{ 46 47class ContextType; 48class ContextInfo; 49struct RenderConfig; 50 51enum 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 60enum 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 68inline ContextFlags operator| (ContextFlags a, ContextFlags b) { return ContextFlags((deUint32)a|(deUint32)b); } 69inline ContextFlags operator& (ContextFlags a, ContextFlags b) { return ContextFlags((deUint32)a&(deUint32)b); } 70inline ContextFlags operator~ (ContextFlags a) { return ContextFlags(~(deUint32)a); } 71 72/*--------------------------------------------------------------------*//*! 73 * \brief Rendering API version and profile. 74 *//*--------------------------------------------------------------------*/ 75class ApiType 76{ 77public: 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 95protected: 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 116inline 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 *//*--------------------------------------------------------------------*/ 143class ContextType : private ApiType 144{ 145public: 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 void setAPI (const ApiType& apiType) { m_bits = apiType.getPacked(); } 152 153 ContextFlags getFlags (void) const { return ContextFlags((m_bits>>FLAGS_SHIFT) & ((1u<<FLAGS_BITS)-1u)); } 154 155 using ApiType::getMajorVersion; 156 using ApiType::getMinorVersion; 157 using ApiType::getProfile; 158 159protected: 160 static deUint32 pack (deUint32 apiBits, ContextFlags flags); 161 162 enum 163 { 164 FLAGS_BITS = 4, 165 TOTAL_CONTEXT_BITS = TOTAL_API_BITS+FLAGS_BITS, 166 FLAGS_SHIFT = TOTAL_API_BITS 167 }; 168} DE_WARN_UNUSED_TYPE; 169 170inline ContextType::ContextType (int major, int minor, Profile profile, ContextFlags flags) 171 : ApiType(major, minor, profile) 172{ 173 m_bits = pack(m_bits, flags); 174} 175 176inline ContextType::ContextType (ApiType apiType, ContextFlags flags) 177 : ApiType(apiType) 178{ 179 m_bits = pack(m_bits, flags); 180} 181 182inline deUint32 ContextType::pack (deUint32 apiBits, ContextFlags flags) 183{ 184 deUint32 bits = apiBits; 185 186 DE_ASSERT((deUint32(flags) & ~((1u<<FLAGS_BITS)-1u)) == 0); 187 188 bits |= deUint32(flags) << FLAGS_SHIFT; 189 190 return bits; 191} 192 193inline bool isContextTypeES (ContextType type) { return type.getAPI().getProfile() == PROFILE_ES; } 194inline bool isContextTypeGLCore (ContextType type) { return type.getAPI().getProfile() == PROFILE_CORE; } 195inline bool isContextTypeGLCompatibility(ContextType type) { return type.getAPI().getProfile() == PROFILE_COMPATIBILITY; } 196inline bool isES2Context (ContextType type) { return isContextTypeES(type) && type.getMajorVersion() == 2; } 197bool contextSupports (ContextType ctxType, ApiType requiredApiType); 198 199const char* getApiTypeDescription (ApiType type); 200 201/*--------------------------------------------------------------------*//*! 202 * \brief Rendering context abstraction. 203 *//*--------------------------------------------------------------------*/ 204class RenderContext 205{ 206public: 207 RenderContext (void) {} 208 virtual ~RenderContext (void) {} 209 210 //! Get context type. Must match to type given to ContextFactory::createContext(). 211 virtual ContextType getType (void) const = DE_NULL; 212 213 //! Get GL function table. Should be filled with all core entry points for context type. 214 virtual const glw::Functions& getFunctions (void) const = DE_NULL; 215 216 //! Get render target information. 217 virtual const tcu::RenderTarget& getRenderTarget (void) const = DE_NULL; 218 219 //! Do post-render actions (swap buffers for example). 220 virtual void postIterate (void) = DE_NULL; 221 222 //! Get default framebuffer. 223 virtual deUint32 getDefaultFramebuffer (void) const { return 0; } 224 225 //! Get extension function address. 226 virtual glw::GenericFuncType getProcAddress (const char* name) const; 227 228 //! Make context current in thread. Optional to support. 229 virtual void makeCurrent (void); 230 231private: 232 RenderContext (const RenderContext& other); // Not allowed! 233 RenderContext& operator= (const RenderContext& other); // Not allowed! 234}; 235 236// Utilities 237 238RenderContext* createRenderContext (tcu::Platform& platform, const tcu::CommandLine& cmdLine, const RenderConfig& config, const RenderContext* sharedContext = DE_NULL); 239RenderContext* createDefaultRenderContext (tcu::Platform& platform, const tcu::CommandLine& cmdLine, ApiType apiType); 240 241void initCoreFunctions (glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType); 242void initExtensionFunctions (glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType, int numExtensions, const char* const* extensions); 243 244// \note initFunctions() and initExtensionFunctions() without explicit extension list 245// use glGetString* to query list of extensions, so it needs current GL context. 246void initFunctions (glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType); 247void initExtensionFunctions (glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType); 248 249bool hasExtension (const glw::Functions& gl, ApiType apiType, const std::string& extension); 250 251} // glu 252 253#endif // _GLURENDERCONTEXT_HPP 254