summaryrefslogtreecommitdiff
path: root/contrib/SDL-3.2.8/src/video/qnx/SDL_qnxgl.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/SDL-3.2.8/src/video/qnx/SDL_qnxgl.c')
-rw-r--r--contrib/SDL-3.2.8/src/video/qnx/SDL_qnxgl.c277
1 files changed, 277 insertions, 0 deletions
diff --git a/contrib/SDL-3.2.8/src/video/qnx/SDL_qnxgl.c b/contrib/SDL-3.2.8/src/video/qnx/SDL_qnxgl.c
new file mode 100644
index 0000000..639e556
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/qnx/SDL_qnxgl.c
@@ -0,0 +1,277 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 2017 BlackBerry Limited
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21
22#include "../../SDL_internal.h"
23#include "SDL_qnx.h"
24
25static EGLDisplay egl_disp;
26
27/**
28 * Detertmines the pixel format to use based on the current display and EGL
29 * configuration.
30 * @param egl_conf EGL configuration to use
31 * @return A SCREEN_FORMAT* constant for the pixel format to use
32 */
33static int chooseFormat(EGLConfig egl_conf)
34{
35 EGLint buffer_bit_depth;
36 EGLint alpha_bit_depth;
37
38 eglGetConfigAttrib(egl_disp, egl_conf, EGL_BUFFER_SIZE, &buffer_bit_depth);
39 eglGetConfigAttrib(egl_disp, egl_conf, EGL_ALPHA_SIZE, &alpha_bit_depth);
40
41 switch (buffer_bit_depth) {
42 case 32:
43 return SCREEN_FORMAT_RGBX8888;
44 case 24:
45 return SDL_PIXELFORMAT_RGB24;
46 case 16:
47 switch (alpha_bit_depth) {
48 case 4:
49 return SCREEN_FORMAT_RGBX4444;
50 case 1:
51 return SCREEN_FORMAT_RGBA5551;
52 default:
53 return SCREEN_FORMAT_RGB565;
54 }
55 default:
56 return 0;
57 }
58}
59
60/**
61 * Enumerates the supported EGL configurations and chooses a suitable one.
62 * @param[out] pconf The chosen configuration
63 * @param[out] pformat The chosen pixel format
64 * @return true if successful, -1 on error
65 */
66bool glGetConfig(EGLConfig *pconf, int *pformat)
67{
68 EGLConfig egl_conf = (EGLConfig)0;
69 EGLConfig *egl_configs;
70 EGLint egl_num_configs;
71 EGLint val;
72 EGLBoolean rc;
73 EGLint i;
74
75 // Determine the numbfer of configurations.
76 rc = eglGetConfigs(egl_disp, NULL, 0, &egl_num_configs);
77 if (rc != EGL_TRUE) {
78 return false;
79 }
80
81 if (egl_num_configs == 0) {
82 return false;
83 }
84
85 // Allocate enough memory for all configurations.
86 egl_configs = SDL_malloc(egl_num_configs * sizeof(*egl_configs));
87 if (!egl_configs) {
88 return false;
89 }
90
91 // Get the list of configurations.
92 rc = eglGetConfigs(egl_disp, egl_configs, egl_num_configs,
93 &egl_num_configs);
94 if (rc != EGL_TRUE) {
95 SDL_free(egl_configs);
96 return false;
97 }
98
99 // Find a good configuration.
100 for (i = 0; i < egl_num_configs; i++) {
101 eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_SURFACE_TYPE, &val);
102 if (!(val & EGL_WINDOW_BIT)) {
103 continue;
104 }
105
106 eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_RENDERABLE_TYPE, &val);
107 if (!(val & EGL_OPENGL_ES2_BIT)) {
108 continue;
109 }
110
111 eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_DEPTH_SIZE, &val);
112 if (val == 0) {
113 continue;
114 }
115
116 egl_conf = egl_configs[i];
117 break;
118 }
119
120 SDL_free(egl_configs);
121 *pconf = egl_conf;
122 *pformat = chooseFormat(egl_conf);
123
124 return true;
125}
126
127/**
128 * Initializes the EGL library.
129 * @param SDL_VideoDevice *_this
130 * @param name unused
131 * @return 0 if successful, -1 on error
132 */
133bool glLoadLibrary(SDL_VideoDevice *_this, const char *name)
134{
135 EGLNativeDisplayType disp_id = EGL_DEFAULT_DISPLAY;
136
137 egl_disp = eglGetDisplay(disp_id);
138 if (egl_disp == EGL_NO_DISPLAY) {
139 return false;
140 }
141
142 if (eglInitialize(egl_disp, NULL, NULL) == EGL_FALSE) {
143 return false;
144 }
145
146 return true;
147}
148
149/**
150 * Finds the address of an EGL extension function.
151 * @param proc Function name
152 * @return Function address
153 */
154SDL_FunctionPointer glGetProcAddress(SDL_VideoDevice *_this, const char *proc)
155{
156 return eglGetProcAddress(proc);
157}
158
159/**
160 * Associates the given window with the necessary EGL structures for drawing and
161 * displaying content.
162 * @param SDL_VideoDevice *_this
163 * @param window The SDL window to create the context for
164 * @return A pointer to the created context, if successful, NULL on error
165 */
166SDL_GLContext glCreateContext(SDL_VideoDevice *_this, SDL_Window *window)
167{
168 window_impl_t *impl = (window_impl_t *)window->internal;
169 EGLContext context;
170 EGLSurface surface;
171
172 struct {
173 EGLint client_version[2];
174 EGLint none;
175 } egl_ctx_attr = {
176 .client_version = { EGL_CONTEXT_CLIENT_VERSION, 2 },
177 .none = EGL_NONE
178 };
179
180 struct {
181 EGLint render_buffer[2];
182 EGLint none;
183 } egl_surf_attr = {
184 .render_buffer = { EGL_RENDER_BUFFER, EGL_BACK_BUFFER },
185 .none = EGL_NONE
186 };
187
188 context = eglCreateContext(egl_disp, impl->conf, EGL_NO_CONTEXT,
189 (EGLint *)&egl_ctx_attr);
190 if (context == EGL_NO_CONTEXT) {
191 return NULL;
192 }
193
194 surface = eglCreateWindowSurface(egl_disp, impl->conf,
195 (EGLNativeWindowType)impl->window,
196 (EGLint *)&egl_surf_attr);
197 if (surface == EGL_NO_SURFACE) {
198 return NULL;
199 }
200
201 eglMakeCurrent(egl_disp, surface, surface, context);
202
203 impl->surface = surface;
204 return context;
205}
206
207/**
208 * Sets a new value for the number of frames to display before swapping buffers.
209 * @param SDL_VideoDevice *_this
210 * @param interval New interval value
211 * @return 0 if successful, -1 on error
212 */
213bool glSetSwapInterval(SDL_VideoDevice *_this, int interval)
214{
215 if (eglSwapInterval(egl_disp, interval) != EGL_TRUE) {
216 return false;
217 }
218
219 return true;
220}
221
222/**
223 * Swaps the EGL buffers associated with the given window
224 * @param SDL_VideoDevice *_this
225 * @param window Window to swap buffers for
226 * @return 0 if successful, -1 on error
227 */
228bool glSwapWindow(SDL_VideoDevice *_this, SDL_Window *window)
229{
230 // !!! FIXME: should we migrate this all over to use SDL_egl.c?
231 window_impl_t *impl = (window_impl_t *)window->internal;
232 return eglSwapBuffers(egl_disp, impl->surface) == EGL_TRUE ? 0 : -1;
233}
234
235/**
236 * Makes the given context the current one for drawing operations.
237 * @param SDL_VideoDevice *_this
238 * @param window SDL window associated with the context (maybe NULL)
239 * @param context The context to activate
240 * @return 0 if successful, -1 on error
241 */
242bool glMakeCurrent(SDL_VideoDevice *_this, SDL_Window *window, SDL_GLContext context)
243{
244 window_impl_t *impl;
245 EGLSurface surface = NULL;
246
247 if (window) {
248 impl = (window_impl_t *)window->internal;
249 surface = impl->surface;
250 }
251
252 if (eglMakeCurrent(egl_disp, surface, surface, context) != EGL_TRUE) {
253 return false;
254 }
255
256 return true;
257}
258
259/**
260 * Destroys a context.
261 * @param SDL_VideoDevice *_this
262 * @param context The context to destroy
263 */
264bool glDeleteContext(SDL_VideoDevice *_this, SDL_GLContext context)
265{
266 eglDestroyContext(egl_disp, context);
267 return true;
268}
269
270/**
271 * Terminates access to the EGL library.
272 * @param SDL_VideoDevice *_this
273 */
274void glUnloadLibrary(SDL_VideoDevice *_this)
275{
276 eglTerminate(egl_disp);
277}