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 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