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
28namespace tcu
29{
30class CommandLine;
31class Platform;
32class RenderTarget;
33}
34
35namespace glw
36{
37class Functions;
38class FunctionLoader;
39}
40
41namespace glu
42{
43
44class ContextType;
45class ContextInfo;
46
47enum 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
56enum 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
63inline ContextFlags	operator| (ContextFlags a, ContextFlags b)	{ return ContextFlags((deUint32)a|(deUint32)b);	}
64inline ContextFlags	operator& (ContextFlags a, ContextFlags b)	{ return ContextFlags((deUint32)a&(deUint32)b);	}
65inline ContextFlags	operator~ (ContextFlags a)					{ return ContextFlags(~(deUint32)a);			}
66
67/*--------------------------------------------------------------------*//*!
68 * \brief Rendering API version and profile.
69 *//*--------------------------------------------------------------------*/
70class ApiType
71{
72public:
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
90protected:
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
111inline 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 *//*--------------------------------------------------------------------*/
138class ContextType : private ApiType
139{
140public:
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
152protected:
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
163inline 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
169inline ContextType::ContextType (ApiType apiType, ContextFlags flags)
170	: ApiType(apiType)
171{
172	m_bits = pack(m_bits, flags);
173}
174
175inline 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
185inline bool		isContextTypeES				(ContextType type)	{ return type.getAPI().getProfile() == PROFILE_ES;				}
186inline bool		isContextTypeGLCore			(ContextType type)	{ return type.getAPI().getProfile() == PROFILE_CORE;			}
187inline bool		isContextTypeGLCompatibility(ContextType type)	{ return type.getAPI().getProfile() == PROFILE_COMPATIBILITY;	}
188bool			contextSupports				(ContextType ctxType, ApiType requiredApiType);
189
190/*--------------------------------------------------------------------*//*!
191 * \brief Rendering context abstraction.
192 *//*--------------------------------------------------------------------*/
193class RenderContext
194{
195public:
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
214private:
215										RenderContext			(const RenderContext& other); // Not allowed!
216	RenderContext&						operator=				(const RenderContext& other); // Not allowed!
217};
218
219// Utilities
220
221RenderContext*		createDefaultRenderContext		(tcu::Platform& platform, const tcu::CommandLine& cmdLine, ApiType apiType);
222
223void				initCoreFunctions				(glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType);
224void				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.
228void				initFunctions					(glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType);
229void				initExtensionFunctions			(glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType);
230
231bool				hasExtension					(const glw::Functions& gl, ApiType apiType, const std::string& extension);
232
233} // glu
234
235#endif // _GLURENDERCONTEXT_HPP
236