GCC Code Coverage Report


Directory: ./
File: submodules/raylib/src/external/glfw/src/osmesa_context.c
Date: 2023-09-29 04:53:15
Exec Total Coverage
Lines: 0 146 0.0%
Branches: 0 86 0.0%

Line Branch Exec Source
1 //========================================================================
2 // GLFW 3.4 OSMesa - www.glfw.org
3 //------------------------------------------------------------------------
4 // Copyright (c) 2016 Google Inc.
5 // Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.org>
6 //
7 // This software is provided 'as-is', without any express or implied
8 // warranty. In no event will the authors be held liable for any damages
9 // arising from the use of this software.
10 //
11 // Permission is granted to anyone to use this software for any purpose,
12 // including commercial applications, and to alter it and redistribute it
13 // freely, subject to the following restrictions:
14 //
15 // 1. The origin of this software must not be misrepresented; you must not
16 // claim that you wrote the original software. If you use this software
17 // in a product, an acknowledgment in the product documentation would
18 // be appreciated but is not required.
19 //
20 // 2. Altered source versions must be plainly marked as such, and must not
21 // be misrepresented as being the original software.
22 //
23 // 3. This notice may not be removed or altered from any source
24 // distribution.
25 //
26 //========================================================================
27 // Please use C89 style variable declarations in this file because VS 2010
28 //========================================================================
29
30 #include <stdlib.h>
31 #include <string.h>
32 #include <assert.h>
33
34 #include "internal.h"
35
36
37 ✗ static void makeContextCurrentOSMesa(_GLFWwindow* window)
38 {
39 ✗ if (window)
40 {
41 int width, height;
42 ✗ _glfw.platform.getFramebufferSize(window, &width, &height);
43
44 // Check to see if we need to allocate a new buffer
45 ✗ if ((window->context.osmesa.buffer == NULL) ||
46 ✗ (width != window->context.osmesa.width) ||
47 ✗ (height != window->context.osmesa.height))
48 {
49 ✗ _glfw_free(window->context.osmesa.buffer);
50
51 // Allocate the new buffer (width * height * 8-bit RGBA)
52 ✗ window->context.osmesa.buffer = _glfw_calloc(4, (size_t) width * height);
53 ✗ window->context.osmesa.width = width;
54 ✗ window->context.osmesa.height = height;
55 }
56
57 ✗ if (!OSMesaMakeCurrent(window->context.osmesa.handle,
58 window->context.osmesa.buffer,
59 GL_UNSIGNED_BYTE,
60 width, height))
61 {
62 ✗ _glfwInputError(GLFW_PLATFORM_ERROR,
63 "OSMesa: Failed to make context current");
64 ✗ return;
65 }
66 }
67
68 ✗ _glfwPlatformSetTls(&_glfw.contextSlot, window);
69 }
70
71 ✗ static GLFWglproc getProcAddressOSMesa(const char* procname)
72 {
73 ✗ return (GLFWglproc) OSMesaGetProcAddress(procname);
74 }
75
76 ✗ static void destroyContextOSMesa(_GLFWwindow* window)
77 {
78 ✗ if (window->context.osmesa.handle)
79 {
80 ✗ OSMesaDestroyContext(window->context.osmesa.handle);
81 ✗ window->context.osmesa.handle = NULL;
82 }
83
84 ✗ if (window->context.osmesa.buffer)
85 {
86 ✗ _glfw_free(window->context.osmesa.buffer);
87 ✗ window->context.osmesa.width = 0;
88 ✗ window->context.osmesa.height = 0;
89 }
90 }
91
92 ✗ static void swapBuffersOSMesa(_GLFWwindow* window)
93 {
94 // No double buffering on OSMesa
95 }
96
97 ✗ static void swapIntervalOSMesa(int interval)
98 {
99 // No swap interval on OSMesa
100 }
101
102 ✗ static int extensionSupportedOSMesa(const char* extension)
103 {
104 // OSMesa does not have extensions
105 ✗ return GLFW_FALSE;
106 }
107
108
109 //////////////////////////////////////////////////////////////////////////
110 ////// GLFW internal API //////
111 //////////////////////////////////////////////////////////////////////////
112
113 ✗ GLFWbool _glfwInitOSMesa(void)
114 {
115 int i;
116 ✗ const char* sonames[] =
117 {
118 #if defined(_GLFW_OSMESA_LIBRARY)
119 _GLFW_OSMESA_LIBRARY,
120 #elif defined(_WIN32)
121 "libOSMesa.dll",
122 "OSMesa.dll",
123 #elif defined(__APPLE__)
124 "libOSMesa.8.dylib",
125 #elif defined(__CYGWIN__)
126 "libOSMesa-8.so",
127 #elif defined(__OpenBSD__) || defined(__NetBSD__)
128 "libOSMesa.so",
129 #else
130 "libOSMesa.so.8",
131 "libOSMesa.so.6",
132 #endif
133 NULL
134 };
135
136 ✗ if (_glfw.osmesa.handle)
137 return GLFW_TRUE;
138
139 ✗ for (i = 0; sonames[i]; i++)
140 {
141 ✗ _glfw.osmesa.handle = _glfwPlatformLoadModule(sonames[i]);
142 ✗ if (_glfw.osmesa.handle)
143 break;
144 }
145
146 ✗ if (!_glfw.osmesa.handle)
147 {
148 ✗ _glfwInputError(GLFW_API_UNAVAILABLE, "OSMesa: Library not found");
149 ✗ return GLFW_FALSE;
150 }
151
152 ✗ _glfw.osmesa.CreateContextExt = (PFN_OSMesaCreateContextExt)
153 ✗ _glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaCreateContextExt");
154 ✗ _glfw.osmesa.CreateContextAttribs = (PFN_OSMesaCreateContextAttribs)
155 ✗ _glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaCreateContextAttribs");
156 ✗ _glfw.osmesa.DestroyContext = (PFN_OSMesaDestroyContext)
157 ✗ _glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaDestroyContext");
158 ✗ _glfw.osmesa.MakeCurrent = (PFN_OSMesaMakeCurrent)
159 ✗ _glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaMakeCurrent");
160 ✗ _glfw.osmesa.GetColorBuffer = (PFN_OSMesaGetColorBuffer)
161 ✗ _glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaGetColorBuffer");
162 ✗ _glfw.osmesa.GetDepthBuffer = (PFN_OSMesaGetDepthBuffer)
163 ✗ _glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaGetDepthBuffer");
164 ✗ _glfw.osmesa.GetProcAddress = (PFN_OSMesaGetProcAddress)
165 ✗ _glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaGetProcAddress");
166
167 ✗ if (!_glfw.osmesa.CreateContextExt ||
168 ✗ !_glfw.osmesa.DestroyContext ||
169 ✗ !_glfw.osmesa.MakeCurrent ||
170 ✗ !_glfw.osmesa.GetColorBuffer ||
171 ✗ !_glfw.osmesa.GetDepthBuffer ||
172 !_glfw.osmesa.GetProcAddress)
173 {
174 ✗ _glfwInputError(GLFW_PLATFORM_ERROR,
175 "OSMesa: Failed to load required entry points");
176
177 ✗ _glfwTerminateOSMesa();
178 ✗ return GLFW_FALSE;
179 }
180
181 return GLFW_TRUE;
182 }
183
184 ✗ void _glfwTerminateOSMesa(void)
185 {
186 ✗ if (_glfw.osmesa.handle)
187 {
188 ✗ _glfwPlatformFreeModule(_glfw.osmesa.handle);
189 ✗ _glfw.osmesa.handle = NULL;
190 }
191 }
192
193 #define SET_ATTRIB(a, v) \
194 { \
195 assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
196 attribs[index++] = a; \
197 attribs[index++] = v; \
198 }
199
200 ✗ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
201 const _GLFWctxconfig* ctxconfig,
202 const _GLFWfbconfig* fbconfig)
203 {
204 OSMesaContext share = NULL;
205 ✗ const int accumBits = fbconfig->accumRedBits +
206 ✗ fbconfig->accumGreenBits +
207 ✗ fbconfig->accumBlueBits +
208 ✗ fbconfig->accumAlphaBits;
209
210 ✗ if (ctxconfig->client == GLFW_OPENGL_ES_API)
211 {
212 ✗ _glfwInputError(GLFW_API_UNAVAILABLE,
213 "OSMesa: OpenGL ES is not available on OSMesa");
214 ✗ return GLFW_FALSE;
215 }
216
217 ✗ if (ctxconfig->share)
218 ✗ share = ctxconfig->share->context.osmesa.handle;
219
220 ✗ if (OSMesaCreateContextAttribs)
221 {
222 int index = 0, attribs[40];
223
224 ✗ SET_ATTRIB(OSMESA_FORMAT, OSMESA_RGBA);
225 ✗ SET_ATTRIB(OSMESA_DEPTH_BITS, fbconfig->depthBits);
226 ✗ SET_ATTRIB(OSMESA_STENCIL_BITS, fbconfig->stencilBits);
227 ✗ SET_ATTRIB(OSMESA_ACCUM_BITS, accumBits);
228
229 ✗ if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)
230 {
231 ✗ SET_ATTRIB(OSMESA_PROFILE, OSMESA_CORE_PROFILE);
232 }
233 ✗ else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)
234 {
235 ✗ SET_ATTRIB(OSMESA_PROFILE, OSMESA_COMPAT_PROFILE);
236 }
237
238 ✗ if (ctxconfig->major != 1 || ctxconfig->minor != 0)
239 {
240 ✗ SET_ATTRIB(OSMESA_CONTEXT_MAJOR_VERSION, ctxconfig->major);
241 ✗ SET_ATTRIB(OSMESA_CONTEXT_MINOR_VERSION, ctxconfig->minor);
242 }
243
244 ✗ if (ctxconfig->forward)
245 {
246 ✗ _glfwInputError(GLFW_VERSION_UNAVAILABLE,
247 "OSMesa: Forward-compatible contexts not supported");
248 ✗ return GLFW_FALSE;
249 }
250
251 ✗ SET_ATTRIB(0, 0);
252
253 ✗ window->context.osmesa.handle =
254 ✗ OSMesaCreateContextAttribs(attribs, share);
255 }
256 else
257 {
258 ✗ if (ctxconfig->profile)
259 {
260 ✗ _glfwInputError(GLFW_VERSION_UNAVAILABLE,
261 "OSMesa: OpenGL profiles unavailable");
262 ✗ return GLFW_FALSE;
263 }
264
265 ✗ window->context.osmesa.handle =
266 ✗ OSMesaCreateContextExt(OSMESA_RGBA,
267 ✗ fbconfig->depthBits,
268 ✗ fbconfig->stencilBits,
269 accumBits,
270 share);
271 }
272
273 ✗ if (window->context.osmesa.handle == NULL)
274 {
275 ✗ _glfwInputError(GLFW_VERSION_UNAVAILABLE,
276 "OSMesa: Failed to create context");
277 ✗ return GLFW_FALSE;
278 }
279
280 ✗ window->context.makeCurrent = makeContextCurrentOSMesa;
281 ✗ window->context.swapBuffers = swapBuffersOSMesa;
282 ✗ window->context.swapInterval = swapIntervalOSMesa;
283 ✗ window->context.extensionSupported = extensionSupportedOSMesa;
284 ✗ window->context.getProcAddress = getProcAddressOSMesa;
285 ✗ window->context.destroy = destroyContextOSMesa;
286
287 ✗ return GLFW_TRUE;
288 }
289
290 #undef SET_ATTRIB
291
292
293 //////////////////////////////////////////////////////////////////////////
294 ////// GLFW native API //////
295 //////////////////////////////////////////////////////////////////////////
296
297 ✗ GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* handle, int* width,
298 int* height, int* format, void** buffer)
299 {
300 void* mesaBuffer;
301 GLint mesaWidth, mesaHeight, mesaFormat;
302 _GLFWwindow* window = (_GLFWwindow*) handle;
303 assert(window != NULL);
304
305 ✗ _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
306
307 ✗ if (window->context.source != GLFW_OSMESA_CONTEXT_API)
308 {
309 ✗ _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
310 ✗ return GLFW_FALSE;
311 }
312
313 ✗ if (!OSMesaGetColorBuffer(window->context.osmesa.handle,
314 &mesaWidth, &mesaHeight,
315 &mesaFormat, &mesaBuffer))
316 {
317 ✗ _glfwInputError(GLFW_PLATFORM_ERROR,
318 "OSMesa: Failed to retrieve color buffer");
319 ✗ return GLFW_FALSE;
320 }
321
322 ✗ if (width)
323 ✗ *width = mesaWidth;
324 ✗ if (height)
325 ✗ *height = mesaHeight;
326 ✗ if (format)
327 ✗ *format = mesaFormat;
328 ✗ if (buffer)
329 ✗ *buffer = mesaBuffer;
330
331 return GLFW_TRUE;
332 }
333
334 ✗ GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* handle,
335 int* width, int* height,
336 int* bytesPerValue,
337 void** buffer)
338 {
339 void* mesaBuffer;
340 GLint mesaWidth, mesaHeight, mesaBytes;
341 _GLFWwindow* window = (_GLFWwindow*) handle;
342 assert(window != NULL);
343
344 ✗ _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
345
346 ✗ if (window->context.source != GLFW_OSMESA_CONTEXT_API)
347 {
348 ✗ _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
349 ✗ return GLFW_FALSE;
350 }
351
352 ✗ if (!OSMesaGetDepthBuffer(window->context.osmesa.handle,
353 &mesaWidth, &mesaHeight,
354 &mesaBytes, &mesaBuffer))
355 {
356 ✗ _glfwInputError(GLFW_PLATFORM_ERROR,
357 "OSMesa: Failed to retrieve depth buffer");
358 ✗ return GLFW_FALSE;
359 }
360
361 ✗ if (width)
362 ✗ *width = mesaWidth;
363 ✗ if (height)
364 ✗ *height = mesaHeight;
365 ✗ if (bytesPerValue)
366 ✗ *bytesPerValue = mesaBytes;
367 ✗ if (buffer)
368 ✗ *buffer = mesaBuffer;
369
370 return GLFW_TRUE;
371 }
372
373 ✗ GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* handle)
374 {
375 _GLFWwindow* window = (_GLFWwindow*) handle;
376 ✗ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
377
378 ✗ if (window->context.source != GLFW_OSMESA_CONTEXT_API)
379 {
380 ✗ _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
381 ✗ return NULL;
382 }
383
384 ✗ return window->context.osmesa.handle;
385 }
386
387