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