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