Home | History | Annotate | Download | only in opengl
      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);
    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