xref: /aosp_15_r20/external/deqp/framework/opengl/gluRenderContext.hpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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