twitchapon-anim

Basic Twitchapon Receiver/Visuals
git clone git://bsandro.tech/twitchapon-anim
Log | Files | Refs | README | LICENSE

osmesa_context.c (11521B)


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