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
operator |(ContextFlags a,ContextFlags b)63 inline ContextFlags operator| (ContextFlags a, ContextFlags b) { return ContextFlags((deUint32)a|(deUint32)b); }
operator &(ContextFlags a,ContextFlags b)64 inline ContextFlags operator& (ContextFlags a, ContextFlags b) { return ContextFlags((deUint32)a&(deUint32)b); }
operator ~(ContextFlags a)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:
ApiType(void)73 ApiType (void) : m_bits(pack(0, 0, PROFILE_LAST)) {}
ApiType(int major,int minor,Profile profile)74 ApiType (int major, int minor, Profile profile) : m_bits(pack(major, minor, profile)) {}
75
getMajorVersion(void) const76 int getMajorVersion (void) const { return int((m_bits>>MAJOR_SHIFT) & ((1u<<MAJOR_BITS)-1u)); }
getMinorVersion(void) const77 int getMinorVersion (void) const { return int((m_bits>>MINOR_SHIFT) & ((1u<<MINOR_BITS)-1u)); }
getProfile(void) const78 Profile getProfile (void) const { return Profile((m_bits>>PROFILE_SHIFT) & ((1u<<PROFILE_BITS)-1u)); }
79
operator ==(ApiType other) const80 bool operator== (ApiType other) const { return m_bits == other.m_bits; }
operator !=(ApiType other) const81 bool operator!= (ApiType other) const { return m_bits != other.m_bits; }
82
83 // Shorthands
es(int major,int minor)84 static ApiType es (int major, int minor) { return ApiType(major, minor, PROFILE_ES); }
core(int major,int minor)85 static ApiType core (int major, int minor) { return ApiType(major, minor, PROFILE_CORE); }
compatibility(int major,int minor)86 static ApiType compatibility (int major, int minor) { return ApiType(major, minor, PROFILE_COMPATIBILITY); }
87
88 protected:
ApiType(deUint32 bits)89 ApiType (deUint32 bits) : m_bits(bits) {}
fromBits(deUint32 bits)90 static ApiType fromBits (deUint32 bits) { return ApiType(bits); }
91
92 static deUint32 pack (int major, int minor, Profile profile);
93
94 deUint32 m_bits;
95
96 enum
97 {
98 MAJOR_BITS = 4,
99 MINOR_BITS = 4,
100 PROFILE_BITS = 2,
101 TOTAL_API_BITS = MAJOR_BITS+MINOR_BITS+PROFILE_BITS,
102
103 MAJOR_SHIFT = 0,
104 MINOR_SHIFT = MAJOR_SHIFT+MAJOR_BITS,
105 PROFILE_SHIFT = MINOR_SHIFT+MINOR_BITS
106 };
107 };
108
pack(int major,int minor,Profile profile)109 inline deUint32 ApiType::pack (int major, int minor, Profile profile)
110 {
111 deUint32 bits = 0;
112
113 DE_ASSERT((deUint32(major) & ~((1<<MAJOR_BITS)-1)) == 0);
114 DE_ASSERT((deUint32(minor) & ~((1<<MINOR_BITS)-1)) == 0);
115 DE_ASSERT((deUint32(profile) & ~((1<<PROFILE_BITS)-1)) == 0);
116
117 bits |= deUint32(major) << MAJOR_SHIFT;
118 bits |= deUint32(minor) << MINOR_SHIFT;
119 bits |= deUint32(profile) << PROFILE_SHIFT;
120
121 return bits;
122 }
123
124 /*--------------------------------------------------------------------*//*!
125 * \brief Rendering context type.
126 *
127 * ContextType differs from API type by adding context flags. They are
128 * crucial in for example determining when GL core context supports
129 * certain API version (forward-compatible bit).
130 *
131 * \note You should NEVER compare ContextTypes against each other, as
132 * you most likely don't want to take flags into account. For example
133 * the test code almost certainly doesn't want to check that you have
134 * EXACTLY ES3.1 context with debug, but without for example robustness.
135 *//*--------------------------------------------------------------------*/
136 class ContextType : private ApiType
137 {
138 public:
ContextType(void)139 ContextType (void) {}
140 ContextType (int major, int minor, Profile profile, ContextFlags flags = ContextFlags(0));
141 explicit ContextType (ApiType apiType, ContextFlags flags = ContextFlags(0));
142
getAPI(void) const143 ApiType getAPI (void) const { return ApiType::fromBits(m_bits & ((1u<<TOTAL_API_BITS)-1u)); }
getFlags(void) const144 ContextFlags getFlags (void) const { return ContextFlags((m_bits>>FLAGS_SHIFT) & ((1u<<FLAGS_BITS)-1u)); }
145
146 using ApiType::getMajorVersion;
147 using ApiType::getMinorVersion;
148 using ApiType::getProfile;
149
150 protected:
151 static deUint32 pack (deUint32 apiBits, ContextFlags flags);
152
153 enum
154 {
155 FLAGS_BITS = 3,
156 TOTAL_CONTEXT_BITS = TOTAL_API_BITS+FLAGS_BITS,
157 FLAGS_SHIFT = TOTAL_API_BITS
158 };
159 };
160
ContextType(int major,int minor,Profile profile,ContextFlags flags)161 inline ContextType::ContextType (int major, int minor, Profile profile, ContextFlags flags)
162 : ApiType(major, minor, profile)
163 {
164 m_bits = pack(m_bits, flags);
165 }
166
ContextType(ApiType apiType,ContextFlags flags)167 inline ContextType::ContextType (ApiType apiType, ContextFlags flags)
168 : ApiType(apiType)
169 {
170 m_bits = pack(m_bits, flags);
171 }
172
pack(deUint32 apiBits,ContextFlags flags)173 inline deUint32 ContextType::pack (deUint32 apiBits, ContextFlags flags)
174 {
175 deUint32 bits = apiBits;
176
177 DE_ASSERT((deUint32(flags) & ~((1<<FLAGS_BITS)-1)) == 0);
178 bits |= deUint32(flags) << FLAGS_SHIFT;
179
180 return bits;
181 }
182
isContextTypeES(ContextType type)183 inline bool isContextTypeES (ContextType type) { return type.getAPI().getProfile() == PROFILE_ES; }
isContextTypeGLCore(ContextType type)184 inline bool isContextTypeGLCore (ContextType type) { return type.getAPI().getProfile() == PROFILE_CORE; }
isContextTypeGLCompatibility(ContextType type)185 inline bool isContextTypeGLCompatibility(ContextType type) { return type.getAPI().getProfile() == PROFILE_COMPATIBILITY; }
186 bool contextSupports (ContextType ctxType, ApiType requiredApiType);
187
188 /*--------------------------------------------------------------------*//*!
189 * \brief Rendering context abstraction.
190 *//*--------------------------------------------------------------------*/
191 class RenderContext
192 {
193 public:
RenderContext(void)194 RenderContext (void) {}
~RenderContext(void)195 virtual ~RenderContext (void) {}
196
197 //! Get context type. Must match to type given to ContextFactory::createContext().
198 virtual ContextType getType (void) const = DE_NULL;
199
200 //! Get GL function table. Should be filled with all core entry points for context type.
201 virtual const glw::Functions& getFunctions (void) const = DE_NULL;
202
203 //! Get render target information.
204 virtual const tcu::RenderTarget& getRenderTarget (void) const = DE_NULL;
205
206 //! Do post-render actions (swap buffers for example).
207 virtual void postIterate (void) = DE_NULL;
208
209 //! Get default framebuffer.
getDefaultFramebuffer(void) const210 virtual deUint32 getDefaultFramebuffer (void) const { return 0; }
211
212 private:
213 RenderContext (const RenderContext& other); // Not allowed!
214 RenderContext& operator= (const RenderContext& other); // Not allowed!
215 };
216
217 // Utilities
218
219 RenderContext* createDefaultRenderContext (tcu::Platform& platform, const tcu::CommandLine& cmdLine, ApiType apiType);
220
221 void initCoreFunctions (glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType);
222 void initExtensionFunctions (glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType, int numExtensions, const char* const* extensions);
223
224 // \note initFunctions() and initExtensionFunctions() without explicit extension list
225 // use glGetString* to query list of extensions, so it needs current GL context.
226 void initFunctions (glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType);
227 void initExtensionFunctions (glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType);
228
229 } // glu
230
231 #endif // _GLURENDERCONTEXT_HPP
232