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)); }
setAPI(const ApiType & apiType)151 void setAPI (const ApiType& apiType) { m_bits = apiType.getPacked(); }
152
getFlags(void) const153 ContextFlags getFlags (void) const { return ContextFlags((m_bits>>FLAGS_SHIFT) & ((1u<<FLAGS_BITS)-1u)); }
154
155 using ApiType::getMajorVersion;
156 using ApiType::getMinorVersion;
157 using ApiType::getProfile;
158
159 protected:
160 static deUint32 pack (deUint32 apiBits, ContextFlags flags);
161
162 enum
163 {
164 FLAGS_BITS = 4,
165 TOTAL_CONTEXT_BITS = TOTAL_API_BITS+FLAGS_BITS,
166 FLAGS_SHIFT = TOTAL_API_BITS
167 };
168 } DE_WARN_UNUSED_TYPE;
169
ContextType(int major,int minor,Profile profile,ContextFlags flags)170 inline ContextType::ContextType (int major, int minor, Profile profile, ContextFlags flags)
171 : ApiType(major, minor, profile)
172 {
173 m_bits = pack(m_bits, flags);
174 }
175
ContextType(ApiType apiType,ContextFlags flags)176 inline ContextType::ContextType (ApiType apiType, ContextFlags flags)
177 : ApiType(apiType)
178 {
179 m_bits = pack(m_bits, flags);
180 }
181
pack(deUint32 apiBits,ContextFlags flags)182 inline deUint32 ContextType::pack (deUint32 apiBits, ContextFlags flags)
183 {
184 deUint32 bits = apiBits;
185
186 DE_ASSERT((deUint32(flags) & ~((1u<<FLAGS_BITS)-1u)) == 0);
187
188 bits |= deUint32(flags) << FLAGS_SHIFT;
189
190 return bits;
191 }
192
isContextTypeES(ContextType type)193 inline bool isContextTypeES (ContextType type) { return type.getAPI().getProfile() == PROFILE_ES; }
isContextTypeGLCore(ContextType type)194 inline bool isContextTypeGLCore (ContextType type) { return type.getAPI().getProfile() == PROFILE_CORE; }
isContextTypeGLCompatibility(ContextType type)195 inline bool isContextTypeGLCompatibility(ContextType type) { return type.getAPI().getProfile() == PROFILE_COMPATIBILITY; }
isES2Context(ContextType type)196 inline bool isES2Context (ContextType type) { return isContextTypeES(type) && type.getMajorVersion() == 2; }
197 bool contextSupports (ContextType ctxType, ApiType requiredApiType);
198
199 const char* getApiTypeDescription (ApiType type);
200
201 /*--------------------------------------------------------------------*//*!
202 * \brief Rendering context abstraction.
203 *//*--------------------------------------------------------------------*/
204 class RenderContext
205 {
206 public:
RenderContext(void)207 RenderContext (void) {}
~RenderContext(void)208 virtual ~RenderContext (void) {}
209
210 //! Get context type. Must match to type given to ContextFactory::createContext().
211 virtual ContextType getType (void) const = DE_NULL;
212
213 //! Get GL function table. Should be filled with all core entry points for context type.
214 virtual const glw::Functions& getFunctions (void) const = DE_NULL;
215
216 //! Get render target information.
217 virtual const tcu::RenderTarget& getRenderTarget (void) const = DE_NULL;
218
219 //! Do post-render actions (swap buffers for example).
220 virtual void postIterate (void) = DE_NULL;
221
222 //! Get default framebuffer.
getDefaultFramebuffer(void) const223 virtual deUint32 getDefaultFramebuffer (void) const { return 0; }
224
225 //! Get extension function address.
226 virtual glw::GenericFuncType getProcAddress (const char* name) const;
227
228 //! Make context current in thread. Optional to support.
229 virtual void makeCurrent (void);
230
231 private:
232 RenderContext (const RenderContext& other); // Not allowed!
233 RenderContext& operator= (const RenderContext& other); // Not allowed!
234 };
235
236 // Utilities
237
238 RenderContext* createRenderContext (tcu::Platform& platform, const tcu::CommandLine& cmdLine, const RenderConfig& config, const RenderContext* sharedContext = DE_NULL);
239 RenderContext* createDefaultRenderContext (tcu::Platform& platform, const tcu::CommandLine& cmdLine, ApiType apiType);
240
241 void initCoreFunctions (glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType);
242 void initExtensionFunctions (glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType, int numExtensions, const char* const* extensions);
243
244 // \note initFunctions() and initExtensionFunctions() without explicit extension list
245 // use glGetString* to query list of extensions, so it needs current GL context.
246 void initFunctions (glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType);
247 void initExtensionFunctions (glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType);
248
249 bool hasExtension (const glw::Functions& gl, ApiType apiType, const std::string& extension);
250
251 } // glu
252
253 #endif // _GLURENDERCONTEXT_HPP
254