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 } // namespace tcu
37
38 namespace glw
39 {
40 class Functions;
41 class FunctionLoader;
42 } // namespace glw
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)
69 {
70 return ContextFlags((uint32_t)a | (uint32_t)b);
71 }
operator &(ContextFlags a,ContextFlags b)72 inline ContextFlags operator&(ContextFlags a, ContextFlags b)
73 {
74 return ContextFlags((uint32_t)a & (uint32_t)b);
75 }
operator ~(ContextFlags a)76 inline ContextFlags operator~(ContextFlags a)
77 {
78 return ContextFlags(~(uint32_t)a);
79 }
80
81 /*--------------------------------------------------------------------*//*!
82 * \brief Rendering API version and profile.
83 *//*--------------------------------------------------------------------*/
84 class ApiType
85 {
86 public:
ApiType(void)87 ApiType(void) : m_bits(pack(0, 0, PROFILE_LAST))
88 {
89 }
ApiType(int major,int minor,Profile profile)90 ApiType(int major, int minor, Profile profile) : m_bits(pack(major, minor, profile))
91 {
92 }
93
getMajorVersion(void) const94 int getMajorVersion(void) const
95 {
96 return int((m_bits >> MAJOR_SHIFT) & ((1u << MAJOR_BITS) - 1u));
97 }
getMinorVersion(void) const98 int getMinorVersion(void) const
99 {
100 return int((m_bits >> MINOR_SHIFT) & ((1u << MINOR_BITS) - 1u));
101 }
getProfile(void) const102 Profile getProfile(void) const
103 {
104 return Profile((m_bits >> PROFILE_SHIFT) & ((1u << PROFILE_BITS) - 1u));
105 }
106
operator ==(ApiType other) const107 bool operator==(ApiType other) const
108 {
109 return m_bits == other.m_bits;
110 }
operator !=(ApiType other) const111 bool operator!=(ApiType other) const
112 {
113 return m_bits != other.m_bits;
114 }
115
getPacked(void) const116 uint32_t getPacked(void) const
117 {
118 return m_bits;
119 }
120
121 // Shorthands
es(int major,int minor)122 static ApiType es(int major, int minor)
123 {
124 return ApiType(major, minor, PROFILE_ES);
125 }
core(int major,int minor)126 static ApiType core(int major, int minor)
127 {
128 return ApiType(major, minor, PROFILE_CORE);
129 }
compatibility(int major,int minor)130 static ApiType compatibility(int major, int minor)
131 {
132 return ApiType(major, minor, PROFILE_COMPATIBILITY);
133 }
134
135 protected:
ApiType(uint32_t bits)136 ApiType(uint32_t bits) : m_bits(bits)
137 {
138 }
fromBits(uint32_t bits)139 static ApiType fromBits(uint32_t bits)
140 {
141 return ApiType(bits);
142 }
143
144 static uint32_t pack(int major, int minor, Profile profile);
145
146 uint32_t m_bits;
147
148 enum
149 {
150 MAJOR_BITS = 4,
151 MINOR_BITS = 4,
152 PROFILE_BITS = 2,
153 TOTAL_API_BITS = MAJOR_BITS + MINOR_BITS + PROFILE_BITS,
154
155 MAJOR_SHIFT = 0,
156 MINOR_SHIFT = MAJOR_SHIFT + MAJOR_BITS,
157 PROFILE_SHIFT = MINOR_SHIFT + MINOR_BITS
158 };
159 } DE_WARN_UNUSED_TYPE;
160
pack(int major,int minor,Profile profile)161 inline uint32_t ApiType::pack(int major, int minor, Profile profile)
162 {
163 uint32_t bits = 0;
164
165 DE_ASSERT((uint32_t(major) & ~((1 << MAJOR_BITS) - 1)) == 0);
166 DE_ASSERT((uint32_t(minor) & ~((1 << MINOR_BITS) - 1)) == 0);
167 DE_ASSERT((uint32_t(profile) & ~((1 << PROFILE_BITS) - 1)) == 0);
168
169 bits |= uint32_t(major) << MAJOR_SHIFT;
170 bits |= uint32_t(minor) << MINOR_SHIFT;
171 bits |= uint32_t(profile) << PROFILE_SHIFT;
172
173 return bits;
174 }
175
176 /*--------------------------------------------------------------------*//*!
177 * \brief Rendering context type.
178 *
179 * ContextType differs from API type by adding context flags. They are
180 * crucial in for example determining when GL core context supports
181 * certain API version (forward-compatible bit).
182 *
183 * \note You should NEVER compare ContextTypes against each other, as
184 * you most likely don't want to take flags into account. For example
185 * the test code almost certainly doesn't want to check that you have
186 * EXACTLY ES3.1 context with debug, but without for example robustness.
187 *//*--------------------------------------------------------------------*/
188 class ContextType : private ApiType
189 {
190 public:
ContextType(void)191 ContextType(void)
192 {
193 }
194 ContextType(int major, int minor, Profile profile, ContextFlags flags = ContextFlags(0));
195 explicit ContextType(ApiType apiType, ContextFlags flags = ContextFlags(0));
196
getAPI(void) const197 ApiType getAPI(void) const
198 {
199 return ApiType::fromBits(m_bits & ((1u << TOTAL_API_BITS) - 1u));
200 }
setAPI(const ApiType & apiType)201 void setAPI(const ApiType &apiType)
202 {
203 m_bits = apiType.getPacked();
204 }
205
getFlags(void) const206 ContextFlags getFlags(void) const
207 {
208 return ContextFlags((m_bits >> FLAGS_SHIFT) & ((1u << FLAGS_BITS) - 1u));
209 }
210
211 using ApiType::getMajorVersion;
212 using ApiType::getMinorVersion;
213 using ApiType::getProfile;
214
215 protected:
216 static uint32_t pack(uint32_t apiBits, ContextFlags flags);
217
218 enum
219 {
220 FLAGS_BITS = 4,
221 TOTAL_CONTEXT_BITS = TOTAL_API_BITS + FLAGS_BITS,
222 FLAGS_SHIFT = TOTAL_API_BITS
223 };
224 } DE_WARN_UNUSED_TYPE;
225
ContextType(int major,int minor,Profile profile,ContextFlags flags)226 inline ContextType::ContextType(int major, int minor, Profile profile, ContextFlags flags)
227 : ApiType(major, minor, profile)
228 {
229 m_bits = pack(m_bits, flags);
230 }
231
ContextType(ApiType apiType,ContextFlags flags)232 inline ContextType::ContextType(ApiType apiType, ContextFlags flags) : ApiType(apiType)
233 {
234 m_bits = pack(m_bits, flags);
235 }
236
pack(uint32_t apiBits,ContextFlags flags)237 inline uint32_t ContextType::pack(uint32_t apiBits, ContextFlags flags)
238 {
239 uint32_t bits = apiBits;
240
241 DE_ASSERT((uint32_t(flags) & ~((1u << FLAGS_BITS) - 1u)) == 0);
242
243 bits |= uint32_t(flags) << FLAGS_SHIFT;
244
245 return bits;
246 }
247
isContextTypeES(ContextType type)248 inline bool isContextTypeES(ContextType type)
249 {
250 return type.getAPI().getProfile() == PROFILE_ES;
251 }
isContextTypeGLCore(ContextType type)252 inline bool isContextTypeGLCore(ContextType type)
253 {
254 return type.getAPI().getProfile() == PROFILE_CORE;
255 }
isContextTypeGLCompatibility(ContextType type)256 inline bool isContextTypeGLCompatibility(ContextType type)
257 {
258 return type.getAPI().getProfile() == PROFILE_COMPATIBILITY;
259 }
isES2Context(ContextType type)260 inline bool isES2Context(ContextType type)
261 {
262 return isContextTypeES(type) && type.getMajorVersion() == 2;
263 }
264 bool contextSupports(ContextType ctxType, ApiType requiredApiType);
265
266 const char *getApiTypeDescription(ApiType type);
267
268 /*--------------------------------------------------------------------*//*!
269 * \brief Rendering context abstraction.
270 *//*--------------------------------------------------------------------*/
271 class RenderContext
272 {
273 public:
RenderContext(void)274 RenderContext(void)
275 {
276 }
~RenderContext(void)277 virtual ~RenderContext(void)
278 {
279 }
280
281 //! Get context type. Must match to type given to ContextFactory::createContext().
282 virtual ContextType getType(void) const = DE_NULL;
283
284 //! Get GL function table. Should be filled with all core entry points for context type.
285 virtual const glw::Functions &getFunctions(void) const = DE_NULL;
286
287 //! Get render target information.
288 virtual const tcu::RenderTarget &getRenderTarget(void) const = DE_NULL;
289
290 //! Do post-render actions (swap buffers for example).
291 virtual void postIterate(void) = DE_NULL;
292
293 //! Get default framebuffer.
getDefaultFramebuffer(void) const294 virtual uint32_t getDefaultFramebuffer(void) const
295 {
296 return 0;
297 }
298
299 //! Get extension function address.
300 virtual glw::GenericFuncType getProcAddress(const char *name) const;
301
302 //! Make context current in thread. Optional to support.
303 virtual void makeCurrent(void);
304
305 private:
306 RenderContext(const RenderContext &other); // Not allowed!
307 RenderContext &operator=(const RenderContext &other); // Not allowed!
308 };
309
310 // Utilities
311
312 RenderContext *createRenderContext(tcu::Platform &platform, const tcu::CommandLine &cmdLine, const RenderConfig &config,
313 const RenderContext *sharedContext = DE_NULL);
314 RenderContext *createDefaultRenderContext(tcu::Platform &platform, const tcu::CommandLine &cmdLine, ApiType apiType);
315
316 void initCoreFunctions(glw::Functions *dst, const glw::FunctionLoader *loader, ApiType apiType);
317 void initExtensionFunctions(glw::Functions *dst, const glw::FunctionLoader *loader, ApiType apiType, int numExtensions,
318 const char *const *extensions);
319
320 // \note initFunctions() and initExtensionFunctions() without explicit extension list
321 // use glGetString* to query list of extensions, so it needs current GL context.
322 void initFunctions(glw::Functions *dst, const glw::FunctionLoader *loader, ApiType apiType);
323 void initExtensionFunctions(glw::Functions *dst, const glw::FunctionLoader *loader, ApiType apiType);
324
325 bool hasExtension(const glw::Functions &gl, ApiType apiType, const std::string &extension);
326
327 } // namespace glu
328
329 #endif // _GLURENDERCONTEXT_HPP
330