@ -1,76 +1,84 @@
//========================================================================
// GLFW 3.3 OSMesa - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2016 Google Inc.
// Copyright (c) 2006-2016 Camilla Berglund <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.
//
//========================================================================
# include <stdlib.h>
# include <stdlib.h>
# include <string.h>
# include <string.h>
# include <assert.h>
# include "internal.h"
# include "internal.h"
# include "osmesa_context.h"
static void makeContextCurrentOSMesa ( _GLFWwindow * window )
static void makeContextCurrentOSMesa ( _GLFWwindow * window )
{
{
if ( window )
if ( window )
{
{
// Check to see if we need to allocate a new buffer.
// Check to see if we need to allocate a new buffer
if ( ( window - > context . osmesa . buffer = = NULL ) | |
if ( ( window - > context . osmesa . buffer = = NULL ) | |
( window - > osmesa . width ! = window - > context . osmesa . width ) | |
( window - > osmesa . width ! = window - > context . osmesa . width ) | |
( window - > osmesa . height ! = window - > context . osmesa . height ) )
( window - > osmesa . height ! = window - > context . osmesa . height ) )
{
{
// Free the current buffer, if necessary.
free ( window - > context . osmesa . buffer ) ;
if ( window - > context . osmesa . buffer ! = NULL )
{
// Allocate the new buffer (width * height * 8-bit RGBA)
free ( window - > context . osmesa . buffer ) ;
window - > context . osmesa . buffer =
}
calloc ( 4 , window - > osmesa . width * window - > osmesa . height ) ;
// Allocate the new buffer (width * height * 1 byte per RGBA
// channel).
window - > context . osmesa . buffer = ( unsigned char * ) malloc (
window - > osmesa . width * window - > osmesa . height * 4 ) ;
// Update the context size.
window - > context . osmesa . width = window - > osmesa . width ;
window - > context . osmesa . width = window - > osmesa . width ;
window - > context . osmesa . height = window - > osmesa . height ;
window - > context . osmesa . height = window - > osmesa . height ;
}
}
// Make the context current.
if ( ! OSMesaMakeCurrent ( window - > context . osmesa . handle ,
if ( ! OSMesaMakeCurrent ( window - > context . osmesa . handle ,
window - > context . osmesa . buffer ,
window - > context . osmesa . buffer ,
0x1401 , // GL_UNSIGNED_BYTE
GL_UNSIGNED_BYTE ,
window - > osmesa . width , window - > osmesa . height ) )
window - > osmesa . width , window - > osmesa . height ) )
{
{
_glfwInputError ( GLFW_PLATFORM_ERROR ,
_glfwInputError ( GLFW_PLATFORM_ERROR ,
" OSMesa: Failed to make context current. " ) ;
" OSMesa: Failed to make context current " ) ;
return ;
return ;
}
}
}
}
else
{
_glfwInputError ( GLFW_PLATFORM_ERROR ,
" OSMesa: Releasing the current context is not supported. " ) ;
}
_glfwPlatformSetCurrentContext ( window ) ;
_glfwPlatformSetCurrentContext ( window ) ;
}
}
static GLFWglproc getProcAddressOSMesa ( const char * procname )
static GLFWglproc getProcAddressOSMesa ( const char * procname )
{
{
_GLFWwindow * window = _glfwPlatformGetCurrentContext ( ) ;
return ( GLFWglproc ) OSMesaGetProcAddress ( procname ) ;
if ( window - > context . osmesa . handle )
{
return ( GLFWglproc ) OSMesaGetProcAddress ( procname ) ;
}
return NULL ;
}
}
static void destroyContextOSMesa ( _GLFWwindow * window )
static void destroyContextOSMesa ( _GLFWwindow * window )
{
{
if ( window - > context . osmesa . handle ! = NULL )
if ( window - > context . osmesa . handle )
{
{
OSMesaDestroyContext ( window - > context . osmesa . handle ) ;
OSMesaDestroyContext ( window - > context . osmesa . handle ) ;
window - > context . osmesa . handle = NULL ;
window - > context . osmesa . handle = NULL ;
}
}
if ( window - > context . osmesa . buffer ! = NULL )
if ( window - > context . osmesa . buffer )
{
{
free ( window - > context . osmesa . buffer ) ;
free ( window - > context . osmesa . buffer ) ;
window - > context . osmesa . width = 0 ;
window - > context . osmesa . width = 0 ;
@ -78,15 +86,23 @@ static void destroyContextOSMesa(_GLFWwindow* window)
}
}
}
}
static void swapBuffersOSMesa ( _GLFWwindow * window ) { }
static void swapBuffersOSMesa ( _GLFWwindow * window )
{
// No double buffering on OSMesa
}
static void swapIntervalOSMesa ( int interval ) { }
static void swapIntervalOSMesa ( int interval )
{
// No swap interval on OSMesa
}
static int extensionSupportedOSMesa ( )
static int extensionSupportedOSMesa ( const char * extension )
{
{
// OSMesa does not have extensions
return GLFW_FALSE ;
return GLFW_FALSE ;
}
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
@ -96,11 +112,13 @@ GLFWbool _glfwInitOSMesa(void)
int i ;
int i ;
const char * sonames [ ] =
const char * sonames [ ] =
{
{
# if defined(_GLFW_ WIN32)
# if defined(_WIN32)
" libOSMesa.dll " ,
" libOSMesa.dll " ,
" OSMesa.dll " ,
" OSMesa.dll " ,
# elif defined(_GLFW_COCOA)
# elif defined(__APPLE__)
" libOSMesa.dylib " ,
" libOSMesa.8.dylib " ,
# elif defined(__CYGWIN__)
" libOSMesa-8.so " ,
# else
# else
" libOSMesa.so.6 " ,
" libOSMesa.so.6 " ,
# endif
# endif
@ -123,20 +141,12 @@ GLFWbool _glfwInitOSMesa(void)
return GLFW_FALSE ;
return GLFW_FALSE ;
}
}
_glfw . osmesa . prefix = ( strncmp ( sonames [ i ] , " lib " , 3 ) = = 0 ) ;
_glfw . osmesa . CreateContextAttribs = ( PFNOSMESACREATECONTEXTATTRIBSPROC )
_glfw_dlsym ( _glfw . osmesa . handle , " OSMesaCreateContextAttribs " ) ;
_glfw . osmesa . CreateContext = ( PFNOSMESACREATECONTEXTPROC )
_glfw_dlsym ( _glfw . osmesa . handle , " OSMesaCreateContext " ) ;
_glfw . osmesa . DestroyContext = ( PFNOSMESADESTROYCONTEXTPROC )
_glfw . osmesa . DestroyContext = ( PFNOSMESADESTROYCONTEXTPROC )
_glfw_dlsym ( _glfw . osmesa . handle , " OSMesaDestroyContext " ) ;
_glfw_dlsym ( _glfw . osmesa . handle , " OSMesaDestroyContext " ) ;
_glfw . osmesa . MakeCurrent = ( PFNOSMESAMAKECURRENTPROC )
_glfw . osmesa . MakeCurrent = ( PFNOSMESAMAKECURRENTPROC )
_glfw_dlsym ( _glfw . osmesa . handle , " OSMesaMakeCurrent " ) ;
_glfw_dlsym ( _glfw . osmesa . handle , " OSMesaMakeCurrent " ) ;
_glfw . osmesa . GetCurrentContext = ( PFNOSMESAGETCURRENTCONTEXTPROC )
_glfw_dlsym ( _glfw . osmesa . handle , " OSMesaGetCurrentContext " ) ;
_glfw . osmesa . PixelStore = ( PFNOSMESAPIXELSTOREPROC )
_glfw_dlsym ( _glfw . osmesa . handle , " OSMesaPixelStore " ) ;
_glfw . osmesa . GetIntegerv = ( PFNOSMESAGETINTEGERVPROC )
_glfw_dlsym ( _glfw . osmesa . handle , " OSMesaGetIntegerv " ) ;
_glfw . osmesa . GetColorBuffer = ( PFNOSMESAGETCOLORBUFFERPROC )
_glfw . osmesa . GetColorBuffer = ( PFNOSMESAGETCOLORBUFFERPROC )
_glfw_dlsym ( _glfw . osmesa . handle , " OSMesaGetColorBuffer " ) ;
_glfw_dlsym ( _glfw . osmesa . handle , " OSMesaGetColorBuffer " ) ;
_glfw . osmesa . GetDepthBuffer = ( PFNOSMESAGETDEPTHBUFFERPROC )
_glfw . osmesa . GetDepthBuffer = ( PFNOSMESAGETDEPTHBUFFERPROC )
@ -144,12 +154,9 @@ GLFWbool _glfwInitOSMesa(void)
_glfw . osmesa . GetProcAddress = ( PFNOSMESAGETPROCADDRESSPROC )
_glfw . osmesa . GetProcAddress = ( PFNOSMESAGETPROCADDRESSPROC )
_glfw_dlsym ( _glfw . osmesa . handle , " OSMesaGetProcAddress " ) ;
_glfw_dlsym ( _glfw . osmesa . handle , " OSMesaGetProcAddress " ) ;
if ( ! _glfw . osmesa . CreateContext | |
if ( ! _glfw . osmesa . CreateContextAttribs | |
! _glfw . osmesa . DestroyContext | |
! _glfw . osmesa . DestroyContext | |
! _glfw . osmesa . MakeCurrent | |
! _glfw . osmesa . MakeCurrent | |
! _glfw . osmesa . GetCurrentContext | |
! _glfw . osmesa . PixelStore | |
! _glfw . osmesa . GetIntegerv | |
! _glfw . osmesa . GetColorBuffer | |
! _glfw . osmesa . GetColorBuffer | |
! _glfw . osmesa . GetDepthBuffer | |
! _glfw . osmesa . GetDepthBuffer | |
! _glfw . osmesa . GetProcAddress )
! _glfw . osmesa . GetProcAddress )
@ -173,30 +180,56 @@ void _glfwTerminateOSMesa(void)
}
}
}
}
# define setAttrib(attribName, attribValue) \
{ \
attribs [ index + + ] = attribName ; \
attribs [ index + + ] = attribValue ; \
assert ( ( size_t ) index < sizeof ( attribs ) / sizeof ( attribs [ 0 ] ) ) ; \
}
GLFWbool _glfwCreateContextOSMesa ( _GLFWwindow * window ,
GLFWbool _glfwCreateContextOSMesa ( _GLFWwindow * window ,
const _GLFWctxconfig * ctxconfig ,
const _GLFWctxconfig * ctxconfig ,
const _GLFWfbconfig * fbconfig )
const _GLFWfbconfig * fbconfig )
{
{
OSMesaContext share ;
OSMesaContext share = NULL ;
int index = 0 , attribs [ 40 ] ;
if ( ctxconfig - > share )
if ( ctxconfig - > share )
share = ctxconfig - > share - > context . osmesa . handle ;
share = ctxconfig - > share - > context . osmesa . handle ;
// Initialize the context.
setAttrib ( OSMESA_FORMAT , OSMESA_RGBA ) ;
window - > context . osmesa . buffer = NULL ;
setAttrib ( OSMESA_DEPTH_BITS , fbconfig - > depthBits ) ;
window - > context . osmesa . width = 0 ;
setAttrib ( OSMESA_STENCIL_BITS , fbconfig - > stencilBits ) ;
window - > context . osmesa . height = 0 ;
setAttrib ( OSMESA_ACCUM_BITS , fbconfig - > accumRedBits +
fbconfig - > accumGreenBits +
fbconfig - > accumBlueBits +
fbconfig - > accumAlphaBits ) ;
// Create to create an OSMesa context.
if ( ctxconfig - > profile = = GLFW_OPENGL_CORE_PROFILE )
window - > context . osmesa . handle = OSMesaCreateContext ( OSMESA_RGBA , share ) ;
{
if ( window - > context . osmesa . handle = = 0 )
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 ) ;
}
setAttrib ( 0 , 0 ) ;
window - > context . osmesa . handle = OSMesaCreateContextAttribs ( attribs , share ) ;
if ( window - > context . osmesa . handle = = NULL )
{
{
_glfwInputError ( GLFW_VERSION_UNAVAILABLE ,
_glfwInputError ( GLFW_VERSION_UNAVAILABLE ,
" OSMesa: Failed to create context. " ) ;
" OSMesa: Failed to create context " ) ;
return GLFW_FALSE ;
return GLFW_FALSE ;
}
}
// Set up the context API.
window - > context . makeCurrent = makeContextCurrentOSMesa ;
window - > context . makeCurrent = makeContextCurrentOSMesa ;
window - > context . swapBuffers = swapBuffersOSMesa ;
window - > context . swapBuffers = swapBuffersOSMesa ;
window - > context . swapInterval = swapIntervalOSMesa ;
window - > context . swapInterval = swapIntervalOSMesa ;
@ -207,7 +240,88 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
return GLFW_TRUE ;
return GLFW_TRUE ;
}
}
# undef setAttrib
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
////// GLFW native API //////
////// 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 ( ! 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 ( ! 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 . client = = GLFW_NO_API )
{
_glfwInputError ( GLFW_NO_WINDOW_CONTEXT , NULL ) ;
return NULL ;
}
return window - > context . osmesa . handle ;
}