Atlas - osmesa_context.c
Home / ext / glfw / src Lines: 1 | Size: 11917 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 _glfwPlatformFreeModule(_glfw.osmesa.handle); 184 _glfw.osmesa.handle = NULL; 185} 186 187#define SET_ATTRIB(a, v) \ 188{ \ 189 assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \ 190 attribs[index++] = a; \ 191 attribs[index++] = v; \ 192} 193 194GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window, 195 const _GLFWctxconfig* ctxconfig, 196 const _GLFWfbconfig* fbconfig) 197{ 198 OSMesaContext share = NULL; 199 const int accumBits = fbconfig->accumRedBits + 200 fbconfig->accumGreenBits + 201 fbconfig->accumBlueBits + 202 fbconfig->accumAlphaBits; 203 204 if (ctxconfig->client == GLFW_OPENGL_ES_API) 205 { 206 _glfwInputError(GLFW_API_UNAVAILABLE, 207 "OSMesa: OpenGL ES is not available on OSMesa"); 208 return GLFW_FALSE; 209 } 210 211 if (ctxconfig->share) 212 share = ctxconfig->share->context.osmesa.handle; 213 214 if (OSMesaCreateContextAttribs) 215 { 216 int index = 0, attribs[40]; 217 218 SET_ATTRIB(OSMESA_FORMAT, OSMESA_RGBA); 219 SET_ATTRIB(OSMESA_DEPTH_BITS, fbconfig->depthBits); 220 SET_ATTRIB(OSMESA_STENCIL_BITS, fbconfig->stencilBits); 221 SET_ATTRIB(OSMESA_ACCUM_BITS, accumBits); 222 223 if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE) 224 { 225 SET_ATTRIB(OSMESA_PROFILE, OSMESA_CORE_PROFILE); 226 } 227 else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE) 228 { 229 SET_ATTRIB(OSMESA_PROFILE, OSMESA_COMPAT_PROFILE); 230 } 231 232 if (ctxconfig->major != 1 || ctxconfig->minor != 0) 233 { 234 SET_ATTRIB(OSMESA_CONTEXT_MAJOR_VERSION, ctxconfig->major); 235 SET_ATTRIB(OSMESA_CONTEXT_MINOR_VERSION, ctxconfig->minor); 236 } 237 238 if (ctxconfig->forward) 239 { 240 _glfwInputError(GLFW_VERSION_UNAVAILABLE, 241 "OSMesa: Forward-compatible contexts not supported"); 242 return GLFW_FALSE; 243 } 244 245 SET_ATTRIB(0, 0); 246 247 window->context.osmesa.handle = 248 OSMesaCreateContextAttribs(attribs, share); 249 } 250 else 251 { 252 if (ctxconfig->profile) 253 { 254 _glfwInputError(GLFW_VERSION_UNAVAILABLE, 255 "OSMesa: OpenGL profiles unavailable"); 256 return GLFW_FALSE; 257 } 258 259 window->context.osmesa.handle = 260 OSMesaCreateContextExt(OSMESA_RGBA, 261 fbconfig->depthBits, 262 fbconfig->stencilBits, 263 accumBits, 264 share); 265 } 266 267 if (window->context.osmesa.handle == NULL) 268 { 269 _glfwInputError(GLFW_VERSION_UNAVAILABLE, 270 "OSMesa: Failed to create context"); 271 return GLFW_FALSE; 272 } 273 274 window->context.makeCurrent = makeContextCurrentOSMesa; 275 window->context.swapBuffers = swapBuffersOSMesa; 276 window->context.swapInterval = swapIntervalOSMesa; 277 window->context.extensionSupported = extensionSupportedOSMesa; 278 window->context.getProcAddress = getProcAddressOSMesa; 279 window->context.destroy = destroyContextOSMesa; 280 281 return GLFW_TRUE; 282} 283 284#undef SET_ATTRIB 285 286 287////////////////////////////////////////////////////////////////////////// 288////// GLFW native API ////// 289////////////////////////////////////////////////////////////////////////// 290 291GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* handle, int* width, 292 int* height, int* format, void** buffer) 293{ 294 void* mesaBuffer; 295 GLint mesaWidth, mesaHeight, mesaFormat; 296 297 _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE); 298 299 _GLFWwindow* window = (_GLFWwindow*) handle; 300 assert(window != NULL); 301 302 if (window->context.source != GLFW_OSMESA_CONTEXT_API) 303 { 304 _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); 305 return GLFW_FALSE; 306 } 307 308 if (!OSMesaGetColorBuffer(window->context.osmesa.handle, 309 &mesaWidth, &mesaHeight, 310 &mesaFormat, &mesaBuffer)) 311 { 312 _glfwInputError(GLFW_PLATFORM_ERROR, 313 "OSMesa: Failed to retrieve color buffer"); 314 return GLFW_FALSE; 315 } 316 317 if (width) 318 *width = mesaWidth; 319 if (height) 320 *height = mesaHeight; 321 if (format) 322 *format = mesaFormat; 323 if (buffer) 324 *buffer = mesaBuffer; 325 326 return GLFW_TRUE; 327} 328 329GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* handle, 330 int* width, int* height, 331 int* bytesPerValue, 332 void** buffer) 333{ 334 void* mesaBuffer; 335 GLint mesaWidth, mesaHeight, mesaBytes; 336 337 _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE); 338 339 _GLFWwindow* window = (_GLFWwindow*) handle; 340 assert(window != NULL); 341 342 if (window->context.source != GLFW_OSMESA_CONTEXT_API) 343 { 344 _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); 345 return GLFW_FALSE; 346 } 347 348 if (!OSMesaGetDepthBuffer(window->context.osmesa.handle, 349 &mesaWidth, &mesaHeight, 350 &mesaBytes, &mesaBuffer)) 351 { 352 _glfwInputError(GLFW_PLATFORM_ERROR, 353 "OSMesa: Failed to retrieve depth buffer"); 354 return GLFW_FALSE; 355 } 356 357 if (width) 358 *width = mesaWidth; 359 if (height) 360 *height = mesaHeight; 361 if (bytesPerValue) 362 *bytesPerValue = mesaBytes; 363 if (buffer) 364 *buffer = mesaBuffer; 365 366 return GLFW_TRUE; 367} 368 369GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* handle) 370{ 371 _GLFW_REQUIRE_INIT_OR_RETURN(NULL); 372 373 _GLFWwindow* window = (_GLFWwindow*) handle; 374 assert(window != NULL); 375 376 if (window->context.source != GLFW_OSMESA_CONTEXT_API) 377 { 378 _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); 379 return NULL; 380 } 381 382 return window->context.osmesa.handle; 383} 384 385[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.