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 
operator |(ContextFlags a,ContextFlags b)68 inline ContextFlags	operator| (ContextFlags a, ContextFlags b)	{ return ContextFlags((deUint32)a|(deUint32)b);	}
operator &(ContextFlags a,ContextFlags b)69 inline ContextFlags	operator& (ContextFlags a, ContextFlags b)	{ return ContextFlags((deUint32)a&(deUint32)b);	}
operator ~(ContextFlags a)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:
ApiType(void)78 						ApiType			(void) : m_bits(pack(0, 0, PROFILE_LAST)) {}
ApiType(int major,int minor,Profile profile)79 						ApiType			(int major, int minor, Profile profile) : m_bits(pack(major, minor, profile)) {}
80 
getMajorVersion(void) const81 	int					getMajorVersion	(void) const	{ return int((m_bits>>MAJOR_SHIFT)			& ((1u<<MAJOR_BITS)-1u));	}
getMinorVersion(void) const82 	int					getMinorVersion	(void) const	{ return int((m_bits>>MINOR_SHIFT)			& ((1u<<MINOR_BITS)-1u));	}
getProfile(void) const83 	Profile				getProfile		(void) const	{ return Profile((m_bits>>PROFILE_SHIFT)	& ((1u<<PROFILE_BITS)-1u));	}
84 
operator ==(ApiType other) const85 	bool				operator==		(ApiType other) const	{ return m_bits == other.m_bits;						}
operator !=(ApiType other) const86 	bool				operator!=		(ApiType other) const	{ return m_bits != other.m_bits;						}
87 
getPacked(void) const88 	deUint32			getPacked		(void) const	{ return m_bits;												}
89 
90 	// Shorthands
es(int major,int minor)91 	static ApiType		es				(int major, int minor)	{ return ApiType(major, minor, PROFILE_ES);				}
core(int major,int minor)92 	static ApiType		core			(int major, int minor)	{ return ApiType(major, minor, PROFILE_CORE);			}
compatibility(int major,int minor)93 	static ApiType		compatibility	(int major, int minor)	{ return ApiType(major, minor, PROFILE_COMPATIBILITY);	}
94 
95 protected:
ApiType(deUint32 bits)96 						ApiType			(deUint32 bits) : m_bits(bits) {}
fromBits(deUint32 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 
pack(int major,int minor,Profile profile)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:
ContextType(void)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 
getAPI(void) const150 	ApiType				getAPI			(void) const	{ return ApiType::fromBits(m_bits & ((1u<<TOTAL_API_BITS)-1u));			}
getFlags(void) const151 	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 
ContextType(int major,int minor,Profile profile,ContextFlags flags)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 
ContextType(ApiType apiType,ContextFlags flags)174 inline ContextType::ContextType (ApiType apiType, ContextFlags flags)
175 	: ApiType(apiType)
176 {
177 	m_bits = pack(m_bits, flags);
178 }
179 
pack(deUint32 apiBits,ContextFlags flags)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 
isContextTypeES(ContextType type)191 inline bool		isContextTypeES				(ContextType type)	{ return type.getAPI().getProfile() == PROFILE_ES;				}
isContextTypeGLCore(ContextType type)192 inline bool		isContextTypeGLCore			(ContextType type)	{ return type.getAPI().getProfile() == PROFILE_CORE;			}
isContextTypeGLCompatibility(ContextType type)193 inline bool		isContextTypeGLCompatibility(ContextType type)	{ return type.getAPI().getProfile() == PROFILE_COMPATIBILITY;	}
isES2Context(ContextType type)194 inline bool		isES2Context				(ContextType type)	{ return isContextTypeES(type) && type.getMajorVersion() == 2; }
195 bool			contextSupports				(ContextType ctxType, ApiType requiredApiType);
196 
197 const char*		getApiTypeDescription		(ApiType type);
198 
199 /*--------------------------------------------------------------------*//*!
200  * \brief Rendering context abstraction.
201  *//*--------------------------------------------------------------------*/
202 class RenderContext
203 {
204 public:
RenderContext(void)205 										RenderContext			(void) {}
~RenderContext(void)206 	virtual								~RenderContext			(void) {}
207 
208 	//! Get context type. Must match to type given to ContextFactory::createContext().
209 	virtual ContextType					getType					(void) const	= DE_NULL;
210 
211 	//! Get GL function table. Should be filled with all core entry points for context type.
212 	virtual const glw::Functions&		getFunctions			(void) const	= DE_NULL;
213 
214 	//! Get render target information.
215 	virtual const tcu::RenderTarget&	getRenderTarget			(void) const	= DE_NULL;
216 
217 	//! Do post-render actions (swap buffers for example).
218 	virtual void						postIterate				(void)			= DE_NULL;
219 
220 	//! Get default framebuffer.
getDefaultFramebuffer(void) const221 	virtual deUint32					getDefaultFramebuffer	(void) const { return 0; }
222 
223 	//! Get extension function address.
224 	virtual glw::GenericFuncType		getProcAddress			(const char* name) const;
225 
226 	//! Make context current in thread. Optional to support.
227 	virtual void						makeCurrent				(void);
228 
229 private:
230 										RenderContext			(const RenderContext& other); // Not allowed!
231 	RenderContext&						operator=				(const RenderContext& other); // Not allowed!
232 };
233 
234 // Utilities
235 
236 RenderContext*		createRenderContext				(tcu::Platform& platform, const tcu::CommandLine& cmdLine, const RenderConfig& config, const RenderContext* sharedContext = DE_NULL);
237 RenderContext*		createDefaultRenderContext		(tcu::Platform& platform, const tcu::CommandLine& cmdLine, ApiType apiType);
238 
239 void				initCoreFunctions				(glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType);
240 void				initExtensionFunctions			(glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType, int numExtensions, const char* const* extensions);
241 
242 // \note initFunctions() and initExtensionFunctions() without explicit extension list
243 //		 use glGetString* to query list of extensions, so it needs current GL context.
244 void				initFunctions					(glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType);
245 void				initExtensionFunctions			(glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType);
246 
247 bool				hasExtension					(const glw::Functions& gl, ApiType apiType, const std::string& extension);
248 
249 } // glu
250 
251 #endif // _GLURENDERCONTEXT_HPP
252