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