summaryrefslogtreecommitdiff
path: root/contrib/SDL-3.2.8/src/video/emscripten/SDL_emscriptenopengles.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/SDL-3.2.8/src/video/emscripten/SDL_emscriptenopengles.c')
-rw-r--r--contrib/SDL-3.2.8/src/video/emscripten/SDL_emscriptenopengles.c162
1 files changed, 162 insertions, 0 deletions
diff --git a/contrib/SDL-3.2.8/src/video/emscripten/SDL_emscriptenopengles.c b/contrib/SDL-3.2.8/src/video/emscripten/SDL_emscriptenopengles.c
new file mode 100644
index 0000000..227cdc5
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/emscripten/SDL_emscriptenopengles.c
@@ -0,0 +1,162 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
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#include "SDL_internal.h"
22
23#ifdef SDL_VIDEO_DRIVER_EMSCRIPTEN
24
25#include <emscripten/emscripten.h>
26#include <emscripten/html5_webgl.h>
27#include <GLES2/gl2.h>
28
29#include "SDL_emscriptenvideo.h"
30#include "SDL_emscriptenopengles.h"
31
32bool Emscripten_GLES_LoadLibrary(SDL_VideoDevice *_this, const char *path)
33{
34 return true;
35}
36
37void Emscripten_GLES_UnloadLibrary(SDL_VideoDevice *_this)
38{
39}
40
41SDL_FunctionPointer Emscripten_GLES_GetProcAddress(SDL_VideoDevice *_this, const char *proc)
42{
43 return emscripten_webgl_get_proc_address(proc);
44}
45
46bool Emscripten_GLES_SetSwapInterval(SDL_VideoDevice *_this, int interval)
47{
48 if (interval < 0) {
49 return SDL_SetError("Late swap tearing currently unsupported");
50 }
51
52 if (Emscripten_ShouldSetSwapInterval(interval)) {
53 if (interval == 0) {
54 emscripten_set_main_loop_timing(EM_TIMING_SETTIMEOUT, 0);
55 } else {
56 emscripten_set_main_loop_timing(EM_TIMING_RAF, interval);
57 }
58 }
59
60 return true;
61}
62
63bool Emscripten_GLES_GetSwapInterval(SDL_VideoDevice *_this, int *interval)
64{
65 int mode, value;
66
67 emscripten_get_main_loop_timing(&mode, &value);
68
69 if (mode == EM_TIMING_RAF) {
70 *interval = value;
71 return true;
72 } else {
73 *interval = 0;
74 return true;
75 }
76}
77
78SDL_GLContext Emscripten_GLES_CreateContext(SDL_VideoDevice *_this, SDL_Window *window)
79{
80 SDL_WindowData *window_data;
81
82 EmscriptenWebGLContextAttributes attribs;
83 EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context;
84
85 emscripten_webgl_init_context_attributes(&attribs);
86
87 attribs.alpha = _this->gl_config.alpha_size > 0;
88 attribs.depth = _this->gl_config.depth_size > 0;
89 attribs.stencil = _this->gl_config.stencil_size > 0;
90 attribs.antialias = _this->gl_config.multisamplebuffers == 1;
91
92 if (_this->gl_config.major_version == 3)
93 attribs.majorVersion = 2; // WebGL 2.0 ~= GLES 3.0
94
95 window_data = window->internal;
96
97 if (window_data->gl_context) {
98 SDL_SetError("Cannot create multiple webgl contexts per window");
99 return NULL;
100 }
101
102 context = emscripten_webgl_create_context(window_data->canvas_id, &attribs);
103
104 if (context < 0) {
105 SDL_SetError("Could not create webgl context");
106 return NULL;
107 }
108
109 if (emscripten_webgl_make_context_current(context) != EMSCRIPTEN_RESULT_SUCCESS) {
110 emscripten_webgl_destroy_context(context);
111 return NULL;
112 }
113
114 window_data->gl_context = (SDL_GLContext)context;
115
116 return (SDL_GLContext)context;
117}
118
119bool Emscripten_GLES_DestroyContext(SDL_VideoDevice *_this, SDL_GLContext context)
120{
121 SDL_Window *window;
122
123 // remove the context from its window
124 for (window = _this->windows; window; window = window->next) {
125 SDL_WindowData *window_data = window->internal;
126
127 if (window_data->gl_context == context) {
128 window_data->gl_context = NULL;
129 }
130 }
131
132 emscripten_webgl_destroy_context((EMSCRIPTEN_WEBGL_CONTEXT_HANDLE)context);
133 return true;
134}
135
136bool Emscripten_GLES_SwapWindow(SDL_VideoDevice *_this, SDL_Window *window)
137{
138 if (emscripten_has_asyncify() && SDL_GetHintBoolean(SDL_HINT_EMSCRIPTEN_ASYNCIFY, true)) {
139 // give back control to browser for screen refresh
140 emscripten_sleep(0);
141 }
142 return true;
143}
144
145bool Emscripten_GLES_MakeCurrent(SDL_VideoDevice *_this, SDL_Window *window, SDL_GLContext context)
146{
147 // it isn't possible to reuse contexts across canvases
148 if (window && context) {
149 SDL_WindowData *window_data = window->internal;
150
151 if (context != window_data->gl_context) {
152 return SDL_SetError("Cannot make context current to another window");
153 }
154 }
155
156 if (emscripten_webgl_make_context_current((EMSCRIPTEN_WEBGL_CONTEXT_HANDLE)context) != EMSCRIPTEN_RESULT_SUCCESS) {
157 return SDL_SetError("Unable to make context current");
158 }
159 return true;
160}
161
162#endif // SDL_VIDEO_DRIVER_EMSCRIPTEN