context.c
Go to the documentation of this file.
00001 //========================================================================
00002 // GLFW 3.1 - www.glfw.org
00003 //------------------------------------------------------------------------
00004 // Copyright (c) 2002-2006 Marcus Geelnard
00005 // Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
00006 //
00007 // This software is provided 'as-is', without any express or implied
00008 // warranty. In no event will the authors be held liable for any damages
00009 // arising from the use of this software.
00010 //
00011 // Permission is granted to anyone to use this software for any purpose,
00012 // including commercial applications, and to alter it and redistribute it
00013 // freely, subject to the following restrictions:
00014 //
00015 // 1. The origin of this software must not be misrepresented; you must not
00016 //    claim that you wrote the original software. If you use this software
00017 //    in a product, an acknowledgment in the product documentation would
00018 //    be appreciated but is not required.
00019 //
00020 // 2. Altered source versions must be plainly marked as such, and must not
00021 //    be misrepresented as being the original software.
00022 //
00023 // 3. This notice may not be removed or altered from any source
00024 //    distribution.
00025 //
00026 //========================================================================
00027 
00028 #include "internal.h"
00029 
00030 #include <stdio.h>
00031 #include <string.h>
00032 #include <limits.h>
00033 #include <stdio.h>
00034 
00035 
00036 // Parses the client API version string and extracts the version number
00037 //
00038 static GLboolean parseVersionString(int* api, int* major, int* minor, int* rev)
00039 {
00040     int i;
00041     _GLFWwindow* window;
00042     const char* version;
00043     const char* prefixes[] =
00044     {
00045         "OpenGL ES-CM ",
00046         "OpenGL ES-CL ",
00047         "OpenGL ES ",
00048         NULL
00049     };
00050 
00051     *api = GLFW_OPENGL_API;
00052 
00053     window = _glfwPlatformGetCurrentContext();
00054 
00055     version = (const char*) window->GetString(GL_VERSION);
00056     if (!version)
00057     {
00058         _glfwInputError(GLFW_PLATFORM_ERROR,
00059                         "Failed to retrieve context version string");
00060         return GL_FALSE;
00061     }
00062 
00063     for (i = 0;  prefixes[i];  i++)
00064     {
00065         const size_t length = strlen(prefixes[i]);
00066 
00067         if (strncmp(version, prefixes[i], length) == 0)
00068         {
00069             version += length;
00070             *api = GLFW_OPENGL_ES_API;
00071             break;
00072         }
00073     }
00074 
00075     if (!sscanf(version, "%d.%d.%d", major, minor, rev))
00076     {
00077         _glfwInputError(GLFW_PLATFORM_ERROR,
00078                         "No version found in context version string");
00079         return GL_FALSE;
00080     }
00081 
00082     return GL_TRUE;
00083 }
00084 
00085 
00089 
00090 GLboolean _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
00091 {
00092     if (ctxconfig->api != GLFW_OPENGL_API &&
00093         ctxconfig->api != GLFW_OPENGL_ES_API)
00094     {
00095         _glfwInputError(GLFW_INVALID_ENUM, "Invalid client API");
00096         return GL_FALSE;
00097     }
00098 
00099     if (ctxconfig->api == GLFW_OPENGL_API)
00100     {
00101         if ((ctxconfig->major < 1 || ctxconfig->minor < 0) ||
00102             (ctxconfig->major == 1 && ctxconfig->minor > 5) ||
00103             (ctxconfig->major == 2 && ctxconfig->minor > 1) ||
00104             (ctxconfig->major == 3 && ctxconfig->minor > 3))
00105         {
00106             // OpenGL 1.0 is the smallest valid version
00107             // OpenGL 1.x series ended with version 1.5
00108             // OpenGL 2.x series ended with version 2.1
00109             // OpenGL 3.x series ended with version 3.3
00110             // For now, let everything else through
00111 
00112             _glfwInputError(GLFW_INVALID_VALUE,
00113                             "Invalid OpenGL version %i.%i",
00114                             ctxconfig->major, ctxconfig->minor);
00115             return GL_FALSE;
00116         }
00117 
00118         if (ctxconfig->profile)
00119         {
00120             if (ctxconfig->profile != GLFW_OPENGL_CORE_PROFILE &&
00121                 ctxconfig->profile != GLFW_OPENGL_COMPAT_PROFILE)
00122             {
00123                 _glfwInputError(GLFW_INVALID_ENUM,
00124                                 "Invalid OpenGL profile");
00125                 return GL_FALSE;
00126             }
00127 
00128             if (ctxconfig->major < 3 ||
00129                 (ctxconfig->major == 3 && ctxconfig->minor < 2))
00130             {
00131                 // Desktop OpenGL context profiles are only defined for version 3.2
00132                 // and above
00133 
00134                 _glfwInputError(GLFW_INVALID_VALUE,
00135                                 "Context profiles are only defined for OpenGL version 3.2 and above");
00136                 return GL_FALSE;
00137             }
00138         }
00139 
00140         if (ctxconfig->forward && ctxconfig->major < 3)
00141         {
00142             // Forward-compatible contexts are only defined for OpenGL version 3.0 and above
00143             _glfwInputError(GLFW_INVALID_VALUE,
00144                             "Forward-compatibility is only defined for OpenGL version 3.0 and above");
00145             return GL_FALSE;
00146         }
00147     }
00148     else if (ctxconfig->api == GLFW_OPENGL_ES_API)
00149     {
00150         if (ctxconfig->major < 1 || ctxconfig->minor < 0 ||
00151             (ctxconfig->major == 1 && ctxconfig->minor > 1) ||
00152             (ctxconfig->major == 2 && ctxconfig->minor > 0))
00153         {
00154             // OpenGL ES 1.0 is the smallest valid version
00155             // OpenGL ES 1.x series ended with version 1.1
00156             // OpenGL ES 2.x series ended with version 2.0
00157             // For now, let everything else through
00158 
00159             _glfwInputError(GLFW_INVALID_VALUE,
00160                             "Invalid OpenGL ES version %i.%i",
00161                             ctxconfig->major, ctxconfig->minor);
00162             return GL_FALSE;
00163         }
00164     }
00165 
00166     if (ctxconfig->robustness)
00167     {
00168         if (ctxconfig->robustness != GLFW_NO_RESET_NOTIFICATION &&
00169             ctxconfig->robustness != GLFW_LOSE_CONTEXT_ON_RESET)
00170         {
00171             _glfwInputError(GLFW_INVALID_ENUM,
00172                             "Invalid context robustness mode");
00173             return GL_FALSE;
00174         }
00175     }
00176 
00177     if (ctxconfig->release)
00178     {
00179         if (ctxconfig->release != GLFW_RELEASE_BEHAVIOR_NONE &&
00180             ctxconfig->release != GLFW_RELEASE_BEHAVIOR_FLUSH)
00181         {
00182             _glfwInputError(GLFW_INVALID_ENUM,
00183                             "Invalid context release behavior");
00184             return GL_FALSE;
00185         }
00186     }
00187 
00188     return GL_TRUE;
00189 }
00190 
00191 const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,
00192                                          const _GLFWfbconfig* alternatives,
00193                                          unsigned int count)
00194 {
00195     unsigned int i;
00196     unsigned int missing, leastMissing = UINT_MAX;
00197     unsigned int colorDiff, leastColorDiff = UINT_MAX;
00198     unsigned int extraDiff, leastExtraDiff = UINT_MAX;
00199     const _GLFWfbconfig* current;
00200     const _GLFWfbconfig* closest = NULL;
00201 
00202     for (i = 0;  i < count;  i++)
00203     {
00204         current = alternatives + i;
00205 
00206         if (desired->stereo > 0 && current->stereo == 0)
00207         {
00208             // Stereo is a hard constraint
00209             continue;
00210         }
00211 
00212         if (desired->doublebuffer != current->doublebuffer)
00213         {
00214             // Double buffering is a hard constraint
00215             continue;
00216         }
00217 
00218         // Count number of missing buffers
00219         {
00220             missing = 0;
00221 
00222             if (desired->alphaBits > 0 && current->alphaBits == 0)
00223                 missing++;
00224 
00225             if (desired->depthBits > 0 && current->depthBits == 0)
00226                 missing++;
00227 
00228             if (desired->stencilBits > 0 && current->stencilBits == 0)
00229                 missing++;
00230 
00231             if (desired->auxBuffers > 0 &&
00232                 current->auxBuffers < desired->auxBuffers)
00233             {
00234                 missing += desired->auxBuffers - current->auxBuffers;
00235             }
00236 
00237             if (desired->samples > 0 && current->samples == 0)
00238             {
00239                 // Technically, several multisampling buffers could be
00240                 // involved, but that's a lower level implementation detail and
00241                 // not important to us here, so we count them as one
00242                 missing++;
00243             }
00244         }
00245 
00246         // These polynomials make many small channel size differences matter
00247         // less than one large channel size difference
00248 
00249         // Calculate color channel size difference value
00250         {
00251             colorDiff = 0;
00252 
00253             if (desired->redBits != GLFW_DONT_CARE)
00254             {
00255                 colorDiff += (desired->redBits - current->redBits) *
00256                              (desired->redBits - current->redBits);
00257             }
00258 
00259             if (desired->greenBits != GLFW_DONT_CARE)
00260             {
00261                 colorDiff += (desired->greenBits - current->greenBits) *
00262                              (desired->greenBits - current->greenBits);
00263             }
00264 
00265             if (desired->blueBits != GLFW_DONT_CARE)
00266             {
00267                 colorDiff += (desired->blueBits - current->blueBits) *
00268                              (desired->blueBits - current->blueBits);
00269             }
00270         }
00271 
00272         // Calculate non-color channel size difference value
00273         {
00274             extraDiff = 0;
00275 
00276             if (desired->alphaBits != GLFW_DONT_CARE)
00277             {
00278                 extraDiff += (desired->alphaBits - current->alphaBits) *
00279                              (desired->alphaBits - current->alphaBits);
00280             }
00281 
00282             if (desired->depthBits != GLFW_DONT_CARE)
00283             {
00284                 extraDiff += (desired->depthBits - current->depthBits) *
00285                              (desired->depthBits - current->depthBits);
00286             }
00287 
00288             if (desired->stencilBits != GLFW_DONT_CARE)
00289             {
00290                 extraDiff += (desired->stencilBits - current->stencilBits) *
00291                              (desired->stencilBits - current->stencilBits);
00292             }
00293 
00294             if (desired->accumRedBits != GLFW_DONT_CARE)
00295             {
00296                 extraDiff += (desired->accumRedBits - current->accumRedBits) *
00297                              (desired->accumRedBits - current->accumRedBits);
00298             }
00299 
00300             if (desired->accumGreenBits != GLFW_DONT_CARE)
00301             {
00302                 extraDiff += (desired->accumGreenBits - current->accumGreenBits) *
00303                              (desired->accumGreenBits - current->accumGreenBits);
00304             }
00305 
00306             if (desired->accumBlueBits != GLFW_DONT_CARE)
00307             {
00308                 extraDiff += (desired->accumBlueBits - current->accumBlueBits) *
00309                              (desired->accumBlueBits - current->accumBlueBits);
00310             }
00311 
00312             if (desired->accumAlphaBits != GLFW_DONT_CARE)
00313             {
00314                 extraDiff += (desired->accumAlphaBits - current->accumAlphaBits) *
00315                              (desired->accumAlphaBits - current->accumAlphaBits);
00316             }
00317 
00318             if (desired->samples != GLFW_DONT_CARE)
00319             {
00320                 extraDiff += (desired->samples - current->samples) *
00321                              (desired->samples - current->samples);
00322             }
00323 
00324             if (desired->sRGB && !current->sRGB)
00325                 extraDiff++;
00326         }
00327 
00328         // Figure out if the current one is better than the best one found so far
00329         // Least number of missing buffers is the most important heuristic,
00330         // then color buffer size match and lastly size match for other buffers
00331 
00332         if (missing < leastMissing)
00333             closest = current;
00334         else if (missing == leastMissing)
00335         {
00336             if ((colorDiff < leastColorDiff) ||
00337                 (colorDiff == leastColorDiff && extraDiff < leastExtraDiff))
00338             {
00339                 closest = current;
00340             }
00341         }
00342 
00343         if (current == closest)
00344         {
00345             leastMissing = missing;
00346             leastColorDiff = colorDiff;
00347             leastExtraDiff = extraDiff;
00348         }
00349     }
00350 
00351     return closest;
00352 }
00353 
00354 GLboolean _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig)
00355 {
00356     _GLFWwindow* window = _glfwPlatformGetCurrentContext();
00357 
00358     window->GetIntegerv = (PFNGLGETINTEGERVPROC) glfwGetProcAddress("glGetIntegerv");
00359     window->GetString = (PFNGLGETSTRINGPROC) glfwGetProcAddress("glGetString");
00360     window->Clear = (PFNGLCLEARPROC) glfwGetProcAddress("glClear");
00361 
00362     if (!parseVersionString(&window->context.api,
00363                             &window->context.major,
00364                             &window->context.minor,
00365                             &window->context.revision))
00366     {
00367         return GL_FALSE;
00368     }
00369 
00370 #if defined(_GLFW_USE_OPENGL)
00371     if (window->context.major > 2)
00372     {
00373         // OpenGL 3.0+ uses a different function for extension string retrieval
00374         // We cache it here instead of in glfwExtensionSupported mostly to alert
00375         // users as early as possible that their build may be broken
00376 
00377         window->GetStringi = (PFNGLGETSTRINGIPROC) glfwGetProcAddress("glGetStringi");
00378         if (!window->GetStringi)
00379         {
00380             _glfwInputError(GLFW_PLATFORM_ERROR,
00381                             "Entry point retrieval is broken");
00382             return GL_FALSE;
00383         }
00384     }
00385 
00386     if (window->context.api == GLFW_OPENGL_API)
00387     {
00388         // Read back context flags (OpenGL 3.0 and above)
00389         if (window->context.major >= 3)
00390         {
00391             GLint flags;
00392             window->GetIntegerv(GL_CONTEXT_FLAGS, &flags);
00393 
00394             if (flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)
00395                 window->context.forward = GL_TRUE;
00396 
00397             if (flags & GL_CONTEXT_FLAG_DEBUG_BIT)
00398                 window->context.debug = GL_TRUE;
00399             else if (glfwExtensionSupported("GL_ARB_debug_output") &&
00400                      ctxconfig->debug)
00401             {
00402                 // HACK: This is a workaround for older drivers (pre KHR_debug)
00403                 //       not setting the debug bit in the context flags for
00404                 //       debug contexts
00405                 window->context.debug = GL_TRUE;
00406             }
00407         }
00408 
00409         // Read back OpenGL context profile (OpenGL 3.2 and above)
00410         if (window->context.major > 3 ||
00411             (window->context.major == 3 && window->context.minor >= 2))
00412         {
00413             GLint mask;
00414             window->GetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask);
00415 
00416             if (mask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT)
00417                 window->context.profile = GLFW_OPENGL_COMPAT_PROFILE;
00418             else if (mask & GL_CONTEXT_CORE_PROFILE_BIT)
00419                 window->context.profile = GLFW_OPENGL_CORE_PROFILE;
00420             else if (glfwExtensionSupported("GL_ARB_compatibility"))
00421             {
00422                 // HACK: This is a workaround for the compatibility profile bit
00423                 //       not being set in the context flags if an OpenGL 3.2+
00424                 //       context was created without having requested a specific
00425                 //       version
00426                 window->context.profile = GLFW_OPENGL_COMPAT_PROFILE;
00427             }
00428         }
00429 
00430         // Read back robustness strategy
00431         if (glfwExtensionSupported("GL_ARB_robustness"))
00432         {
00433             // NOTE: We avoid using the context flags for detection, as they are
00434             //       only present from 3.0 while the extension applies from 1.1
00435 
00436             GLint strategy;
00437             window->GetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB, &strategy);
00438 
00439             if (strategy == GL_LOSE_CONTEXT_ON_RESET_ARB)
00440                 window->context.robustness = GLFW_LOSE_CONTEXT_ON_RESET;
00441             else if (strategy == GL_NO_RESET_NOTIFICATION_ARB)
00442                 window->context.robustness = GLFW_NO_RESET_NOTIFICATION;
00443         }
00444     }
00445     else
00446     {
00447         // Read back robustness strategy
00448         if (glfwExtensionSupported("GL_EXT_robustness"))
00449         {
00450             // NOTE: The values of these constants match those of the OpenGL ARB
00451             //       one, so we can reuse them here
00452 
00453             GLint strategy;
00454             window->GetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB, &strategy);
00455 
00456             if (strategy == GL_LOSE_CONTEXT_ON_RESET_ARB)
00457                 window->context.robustness = GLFW_LOSE_CONTEXT_ON_RESET;
00458             else if (strategy == GL_NO_RESET_NOTIFICATION_ARB)
00459                 window->context.robustness = GLFW_NO_RESET_NOTIFICATION;
00460         }
00461     }
00462 
00463     if (glfwExtensionSupported("GL_KHR_context_flush_control"))
00464     {
00465         GLint behavior;
00466         window->GetIntegerv(GL_CONTEXT_RELEASE_BEHAVIOR, &behavior);
00467 
00468         if (behavior == GL_NONE)
00469             window->context.release = GLFW_RELEASE_BEHAVIOR_NONE;
00470         else if (behavior == GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH)
00471             window->context.release = GLFW_RELEASE_BEHAVIOR_FLUSH;
00472     }
00473 #endif // _GLFW_USE_OPENGL
00474 
00475     return GL_TRUE;
00476 }
00477 
00478 GLboolean _glfwIsValidContext(const _GLFWctxconfig* ctxconfig)
00479 {
00480     _GLFWwindow* window = _glfwPlatformGetCurrentContext();
00481 
00482     if (window->context.major < ctxconfig->major ||
00483         (window->context.major == ctxconfig->major &&
00484          window->context.minor < ctxconfig->minor))
00485     {
00486         // The desired OpenGL version is greater than the actual version
00487         // This only happens if the machine lacks {GLX|WGL}_ARB_create_context
00488         // /and/ the user has requested an OpenGL version greater than 1.0
00489 
00490         // For API consistency, we emulate the behavior of the
00491         // {GLX|WGL}_ARB_create_context extension and fail here
00492 
00493         _glfwInputError(GLFW_VERSION_UNAVAILABLE, NULL);
00494         return GL_FALSE;
00495     }
00496 
00497     return GL_TRUE;
00498 }
00499 
00500 int _glfwStringInExtensionString(const char* string, const char* extensions)
00501 {
00502     const char* start = extensions;
00503 
00504     for (;;)
00505     {
00506         const char* where;
00507         const char* terminator;
00508 
00509         where = strstr(start, string);
00510         if (!where)
00511             return GL_FALSE;
00512 
00513         terminator = where + strlen(string);
00514         if (where == start || *(where - 1) == ' ')
00515         {
00516             if (*terminator == ' ' || *terminator == '\0')
00517                 break;
00518         }
00519 
00520         start = terminator;
00521     }
00522 
00523     return GL_TRUE;
00524 }
00525 
00526 
00530 
00531 GLFWAPI void glfwMakeContextCurrent(GLFWwindow* handle)
00532 {
00533     _GLFWwindow* window = (_GLFWwindow*) handle;
00534     _GLFW_REQUIRE_INIT();
00535     _glfwPlatformMakeContextCurrent(window);
00536 }
00537 
00538 GLFWAPI GLFWwindow* glfwGetCurrentContext(void)
00539 {
00540     _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
00541     return (GLFWwindow*) _glfwPlatformGetCurrentContext();
00542 }
00543 
00544 GLFWAPI void glfwSwapBuffers(GLFWwindow* handle)
00545 {
00546     _GLFWwindow* window = (_GLFWwindow*) handle;
00547     _GLFW_REQUIRE_INIT();
00548     _glfwPlatformSwapBuffers(window);
00549 }
00550 
00551 GLFWAPI void glfwSwapInterval(int interval)
00552 {
00553     _GLFW_REQUIRE_INIT();
00554 
00555     if (!_glfwPlatformGetCurrentContext())
00556     {
00557         _glfwInputError(GLFW_NO_CURRENT_CONTEXT, NULL);
00558         return;
00559     }
00560 
00561     _glfwPlatformSwapInterval(interval);
00562 }
00563 
00564 GLFWAPI int glfwExtensionSupported(const char* extension)
00565 {
00566     _GLFWwindow* window;
00567 
00568     _GLFW_REQUIRE_INIT_OR_RETURN(GL_FALSE);
00569 
00570     window = _glfwPlatformGetCurrentContext();
00571     if (!window)
00572     {
00573         _glfwInputError(GLFW_NO_CURRENT_CONTEXT, NULL);
00574         return GL_FALSE;
00575     }
00576 
00577     if (*extension == '\0')
00578     {
00579         _glfwInputError(GLFW_INVALID_VALUE, NULL);
00580         return GL_FALSE;
00581     }
00582 
00583 #if defined(_GLFW_USE_OPENGL)
00584     if (window->context.major >= 3)
00585     {
00586         int i;
00587         GLint count;
00588 
00589         // Check if extension is in the modern OpenGL extensions string list
00590 
00591         window->GetIntegerv(GL_NUM_EXTENSIONS, &count);
00592 
00593         for (i = 0;  i < count;  i++)
00594         {
00595             const char* en = (const char*) window->GetStringi(GL_EXTENSIONS, i);
00596             if (!en)
00597             {
00598                 _glfwInputError(GLFW_PLATFORM_ERROR,
00599                                 "Failed to retrieve extension string %i", i);
00600                 return GL_FALSE;
00601             }
00602 
00603             if (strcmp(en, extension) == 0)
00604                 return GL_TRUE;
00605         }
00606     }
00607     else
00608 #endif // _GLFW_USE_OPENGL
00609     {
00610         // Check if extension is in the old style OpenGL extensions string
00611 
00612         const char* extensions = (const char*) window->GetString(GL_EXTENSIONS);
00613         if (!extensions)
00614         {
00615             _glfwInputError(GLFW_PLATFORM_ERROR,
00616                             "Failed to retrieve extension string");
00617             return GL_FALSE;
00618         }
00619 
00620         if (_glfwStringInExtensionString(extension, extensions))
00621             return GL_TRUE;
00622     }
00623 
00624     // Check if extension is in the platform-specific string
00625     return _glfwPlatformExtensionSupported(extension);
00626 }
00627 
00628 GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname)
00629 {
00630     _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
00631 
00632     if (!_glfwPlatformGetCurrentContext())
00633     {
00634         _glfwInputError(GLFW_NO_CURRENT_CONTEXT, NULL);
00635         return NULL;
00636     }
00637 
00638     return _glfwPlatformGetProcAddress(procname);
00639 }
00640 


librealsense
Author(s): Sergey Dorodnicov , Mark Horn , Reagan Lopez
autogenerated on Tue Jun 25 2019 19:54:38