summaryrefslogtreecommitdiff
path: root/libs/glfw-3.3.8/src/osmesa_context.c
diff options
context:
space:
mode:
Diffstat (limited to 'libs/glfw-3.3.8/src/osmesa_context.c')
-rw-r--r--libs/glfw-3.3.8/src/osmesa_context.c386
1 files changed, 386 insertions, 0 deletions
diff --git a/libs/glfw-3.3.8/src/osmesa_context.c b/libs/glfw-3.3.8/src/osmesa_context.c
new file mode 100644
index 0000000..4072728
--- /dev/null
+++ b/libs/glfw-3.3.8/src/osmesa_context.c
@@ -0,0 +1,386 @@
+//========================================================================
+// GLFW 3.3 OSMesa - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2016 Google Inc.
+// Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.org>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+// Please use C89 style variable declarations in this file because VS 2010
+//========================================================================
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "internal.h"
+
+
+static void makeContextCurrentOSMesa(_GLFWwindow* window)
+{
+ if (window)
+ {
+ int width, height;
+ _glfwPlatformGetFramebufferSize(window, &width, &height);
+
+ // Check to see if we need to allocate a new buffer
+ if ((window->context.osmesa.buffer == NULL) ||
+ (width != window->context.osmesa.width) ||
+ (height != window->context.osmesa.height))
+ {
+ free(window->context.osmesa.buffer);
+
+ // Allocate the new buffer (width * height * 8-bit RGBA)
+ window->context.osmesa.buffer = calloc(4, (size_t) width * height);
+ window->context.osmesa.width = width;
+ window->context.osmesa.height = height;
+ }
+
+ if (!OSMesaMakeCurrent(window->context.osmesa.handle,
+ window->context.osmesa.buffer,
+ GL_UNSIGNED_BYTE,
+ width, height))
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "OSMesa: Failed to make context current");
+ return;
+ }
+ }
+
+ _glfwPlatformSetTls(&_glfw.contextSlot, window);
+}
+
+static GLFWglproc getProcAddressOSMesa(const char* procname)
+{
+ return (GLFWglproc) OSMesaGetProcAddress(procname);
+}
+
+static void destroyContextOSMesa(_GLFWwindow* window)
+{
+ if (window->context.osmesa.handle)
+ {
+ OSMesaDestroyContext(window->context.osmesa.handle);
+ window->context.osmesa.handle = NULL;
+ }
+
+ if (window->context.osmesa.buffer)
+ {
+ free(window->context.osmesa.buffer);
+ window->context.osmesa.width = 0;
+ window->context.osmesa.height = 0;
+ }
+}
+
+static void swapBuffersOSMesa(_GLFWwindow* window)
+{
+ // No double buffering on OSMesa
+}
+
+static void swapIntervalOSMesa(int interval)
+{
+ // No swap interval on OSMesa
+}
+
+static int extensionSupportedOSMesa(const char* extension)
+{
+ // OSMesa does not have extensions
+ return GLFW_FALSE;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
+GLFWbool _glfwInitOSMesa(void)
+{
+ int i;
+ const char* sonames[] =
+ {
+#if defined(_GLFW_OSMESA_LIBRARY)
+ _GLFW_OSMESA_LIBRARY,
+#elif defined(_WIN32)
+ "libOSMesa.dll",
+ "OSMesa.dll",
+#elif defined(__APPLE__)
+ "libOSMesa.8.dylib",
+#elif defined(__CYGWIN__)
+ "libOSMesa-8.so",
+#elif defined(__OpenBSD__) || defined(__NetBSD__)
+ "libOSMesa.so",
+#else
+ "libOSMesa.so.8",
+ "libOSMesa.so.6",
+#endif
+ NULL
+ };
+
+ if (_glfw.osmesa.handle)
+ return GLFW_TRUE;
+
+ for (i = 0; sonames[i]; i++)
+ {
+ _glfw.osmesa.handle = _glfw_dlopen(sonames[i]);
+ if (_glfw.osmesa.handle)
+ break;
+ }
+
+ if (!_glfw.osmesa.handle)
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE, "OSMesa: Library not found");
+ return GLFW_FALSE;
+ }
+
+ _glfw.osmesa.CreateContextExt = (PFN_OSMesaCreateContextExt)
+ _glfw_dlsym(_glfw.osmesa.handle, "OSMesaCreateContextExt");
+ _glfw.osmesa.CreateContextAttribs = (PFN_OSMesaCreateContextAttribs)
+ _glfw_dlsym(_glfw.osmesa.handle, "OSMesaCreateContextAttribs");
+ _glfw.osmesa.DestroyContext = (PFN_OSMesaDestroyContext)
+ _glfw_dlsym(_glfw.osmesa.handle, "OSMesaDestroyContext");
+ _glfw.osmesa.MakeCurrent = (PFN_OSMesaMakeCurrent)
+ _glfw_dlsym(_glfw.osmesa.handle, "OSMesaMakeCurrent");
+ _glfw.osmesa.GetColorBuffer = (PFN_OSMesaGetColorBuffer)
+ _glfw_dlsym(_glfw.osmesa.handle, "OSMesaGetColorBuffer");
+ _glfw.osmesa.GetDepthBuffer = (PFN_OSMesaGetDepthBuffer)
+ _glfw_dlsym(_glfw.osmesa.handle, "OSMesaGetDepthBuffer");
+ _glfw.osmesa.GetProcAddress = (PFN_OSMesaGetProcAddress)
+ _glfw_dlsym(_glfw.osmesa.handle, "OSMesaGetProcAddress");
+
+ if (!_glfw.osmesa.CreateContextExt ||
+ !_glfw.osmesa.DestroyContext ||
+ !_glfw.osmesa.MakeCurrent ||
+ !_glfw.osmesa.GetColorBuffer ||
+ !_glfw.osmesa.GetDepthBuffer ||
+ !_glfw.osmesa.GetProcAddress)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "OSMesa: Failed to load required entry points");
+
+ _glfwTerminateOSMesa();
+ return GLFW_FALSE;
+ }
+
+ return GLFW_TRUE;
+}
+
+void _glfwTerminateOSMesa(void)
+{
+ if (_glfw.osmesa.handle)
+ {
+ _glfw_dlclose(_glfw.osmesa.handle);
+ _glfw.osmesa.handle = NULL;
+ }
+}
+
+#define setAttrib(a, v) \
+{ \
+ assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
+ attribs[index++] = a; \
+ attribs[index++] = v; \
+}
+
+GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
+ const _GLFWctxconfig* ctxconfig,
+ const _GLFWfbconfig* fbconfig)
+{
+ OSMesaContext share = NULL;
+ const int accumBits = fbconfig->accumRedBits +
+ fbconfig->accumGreenBits +
+ fbconfig->accumBlueBits +
+ fbconfig->accumAlphaBits;
+
+ if (ctxconfig->client == GLFW_OPENGL_ES_API)
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE,
+ "OSMesa: OpenGL ES is not available on OSMesa");
+ return GLFW_FALSE;
+ }
+
+ if (ctxconfig->share)
+ share = ctxconfig->share->context.osmesa.handle;
+
+ if (OSMesaCreateContextAttribs)
+ {
+ int index = 0, attribs[40];
+
+ setAttrib(OSMESA_FORMAT, OSMESA_RGBA);
+ setAttrib(OSMESA_DEPTH_BITS, fbconfig->depthBits);
+ setAttrib(OSMESA_STENCIL_BITS, fbconfig->stencilBits);
+ setAttrib(OSMESA_ACCUM_BITS, accumBits);
+
+ if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)
+ {
+ setAttrib(OSMESA_PROFILE, OSMESA_CORE_PROFILE);
+ }
+ else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)
+ {
+ setAttrib(OSMESA_PROFILE, OSMESA_COMPAT_PROFILE);
+ }
+
+ if (ctxconfig->major != 1 || ctxconfig->minor != 0)
+ {
+ setAttrib(OSMESA_CONTEXT_MAJOR_VERSION, ctxconfig->major);
+ setAttrib(OSMESA_CONTEXT_MINOR_VERSION, ctxconfig->minor);
+ }
+
+ if (ctxconfig->forward)
+ {
+ _glfwInputError(GLFW_VERSION_UNAVAILABLE,
+ "OSMesa: Forward-compatible contexts not supported");
+ return GLFW_FALSE;
+ }
+
+ setAttrib(0, 0);
+
+ window->context.osmesa.handle =
+ OSMesaCreateContextAttribs(attribs, share);
+ }
+ else
+ {
+ if (ctxconfig->profile)
+ {
+ _glfwInputError(GLFW_VERSION_UNAVAILABLE,
+ "OSMesa: OpenGL profiles unavailable");
+ return GLFW_FALSE;
+ }
+
+ window->context.osmesa.handle =
+ OSMesaCreateContextExt(OSMESA_RGBA,
+ fbconfig->depthBits,
+ fbconfig->stencilBits,
+ accumBits,
+ share);
+ }
+
+ if (window->context.osmesa.handle == NULL)
+ {
+ _glfwInputError(GLFW_VERSION_UNAVAILABLE,
+ "OSMesa: Failed to create context");
+ return GLFW_FALSE;
+ }
+
+ window->context.makeCurrent = makeContextCurrentOSMesa;
+ window->context.swapBuffers = swapBuffersOSMesa;
+ window->context.swapInterval = swapIntervalOSMesa;
+ window->context.extensionSupported = extensionSupportedOSMesa;
+ window->context.getProcAddress = getProcAddressOSMesa;
+ window->context.destroy = destroyContextOSMesa;
+
+ return GLFW_TRUE;
+}
+
+#undef setAttrib
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW native API //////
+//////////////////////////////////////////////////////////////////////////
+
+GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* handle, int* width,
+ int* height, int* format, void** buffer)
+{
+ void* mesaBuffer;
+ GLint mesaWidth, mesaHeight, mesaFormat;
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
+
+ if (window->context.source != GLFW_OSMESA_CONTEXT_API)
+ {
+ _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
+ return GLFW_FALSE;
+ }
+
+ if (!OSMesaGetColorBuffer(window->context.osmesa.handle,
+ &mesaWidth, &mesaHeight,
+ &mesaFormat, &mesaBuffer))
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "OSMesa: Failed to retrieve color buffer");
+ return GLFW_FALSE;
+ }
+
+ if (width)
+ *width = mesaWidth;
+ if (height)
+ *height = mesaHeight;
+ if (format)
+ *format = mesaFormat;
+ if (buffer)
+ *buffer = mesaBuffer;
+
+ return GLFW_TRUE;
+}
+
+GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* handle,
+ int* width, int* height,
+ int* bytesPerValue,
+ void** buffer)
+{
+ void* mesaBuffer;
+ GLint mesaWidth, mesaHeight, mesaBytes;
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
+
+ if (window->context.source != GLFW_OSMESA_CONTEXT_API)
+ {
+ _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
+ return GLFW_FALSE;
+ }
+
+ if (!OSMesaGetDepthBuffer(window->context.osmesa.handle,
+ &mesaWidth, &mesaHeight,
+ &mesaBytes, &mesaBuffer))
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "OSMesa: Failed to retrieve depth buffer");
+ return GLFW_FALSE;
+ }
+
+ if (width)
+ *width = mesaWidth;
+ if (height)
+ *height = mesaHeight;
+ if (bytesPerValue)
+ *bytesPerValue = mesaBytes;
+ if (buffer)
+ *buffer = mesaBuffer;
+
+ return GLFW_TRUE;
+}
+
+GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* handle)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+
+ if (window->context.source != GLFW_OSMESA_CONTEXT_API)
+ {
+ _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
+ return NULL;
+ }
+
+ return window->context.osmesa.handle;
+}
+