From 69a900592e0ce28278ee3c8224838b7e499af698 Mon Sep 17 00:00:00 2001
From: Camilla Berglund <elmindreda@elmindreda.org>
Date: Sun, 2 Dec 2012 16:10:00 +0100
Subject: [PATCH] Added explicit support for sRGB framebuffers.

---
 include/GL/glfw3.h   |  7 +++++++
 src/cocoa_window.m   |  3 +++
 src/internal.h       |  2 ++
 src/opengl.c         |  6 ++++++
 src/win32_opengl.c   | 12 ++++++++++++
 src/win32_platform.h |  1 +
 src/window.c         |  4 ++++
 src/x11_opengl.c     |  8 ++++++++
 src/x11_platform.h   |  1 +
 9 files changed, 44 insertions(+)

diff --git a/include/GL/glfw3.h b/include/GL/glfw3.h
index b5735a96..1954a0c1 100644
--- a/include/GL/glfw3.h
+++ b/include/GL/glfw3.h
@@ -518,6 +518,10 @@ extern "C" {
 /*! @brief The number of samples used for default framebuffer multisampling.
  */
 #define GLFW_FSAA_SAMPLES         0x0002100E
+/*! @brief @c GL_TRUE if the framebuffer should be sRGB capable, or @c GL_FALSE
+ *  otherwise.
+ */
+#define GLFW_SRGB_CAPABLE         0x0002100F
 
 /*! @brief The @link clients client API @endlink to create a context for.
  */
@@ -1020,6 +1024,9 @@ GLFWAPI void glfwDefaultWindowHints(void);
  *  The @ref GLFW_FSAA_SAMPLES hint specifies the desired number of samples to
  *  use for multisampling.
  *
+ *  The @ref GLFW_SRGB_CAPABLE hint specifies whether the framebuffer should be
+ *  sRGB capable.
+ *
  *  The @ref GLFW_CLIENT_API hint specifies which client API to create the
  *  context for.  Possible values are @ref GLFW_OPENGL_API and @ref
  *  GLFW_OPENGL_ES_API.
diff --git a/src/cocoa_window.m b/src/cocoa_window.m
index 24ba6628..040277a7 100644
--- a/src/cocoa_window.m
+++ b/src/cocoa_window.m
@@ -835,6 +835,9 @@ static GLboolean createContext(_GLFWwindow* window,
         ADD_ATTR2(NSOpenGLPFASamples, fbconfig->samples);
     }
 
+    // NOTE: All NSOpenGLPixelFormats on the relevant cards support sRGB
+    // frambuffer, so there's no need (and no way) to request it
+
     ADD_ATTR(0);
 
 #undef ADD_ATTR
diff --git a/src/internal.h b/src/internal.h
index 2ef8f10c..d3084ee9 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -100,6 +100,7 @@ struct _GLFWhints
     GLboolean   resizable;
     GLboolean   visible;
     int         samples;
+    GLboolean   sRGB;
     int         clientAPI;
     int         glMajor;
     int         glMinor;
@@ -160,6 +161,7 @@ struct _GLFWfbconfig
     int         auxBuffers;
     GLboolean   stereo;
     int         samples;
+    GLboolean   sRGB;
     GLFWintptr  platformID;
 };
 
diff --git a/src/opengl.c b/src/opengl.c
index 538bcdfb..931296ce 100644
--- a/src/opengl.c
+++ b/src/opengl.c
@@ -217,6 +217,12 @@ const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,
                 extraDiff += (desired->samples - current->samples) *
                              (desired->samples - current->samples);
             }
+
+            if (desired->sRGB)
+            {
+                if (!current->sRGB)
+                    extraDiff++;
+            }
         }
 
         // Figure out if the current one is better than the best one found so far
diff --git a/src/win32_opengl.c b/src/win32_opengl.c
index f1e911f3..80d7470e 100644
--- a/src/win32_opengl.c
+++ b/src/win32_opengl.c
@@ -72,6 +72,7 @@ static void initWGLExtensions(_GLFWwindow* window)
     // This needs to include every extension used below except for
     // WGL_ARB_extensions_string and WGL_EXT_extensions_string
     window->WGL.ARB_multisample = GL_FALSE;
+    window->WGL.ARB_framebuffer_sRGB = GL_FALSE;
     window->WGL.ARB_create_context = GL_FALSE;
     window->WGL.ARB_create_context_profile = GL_FALSE;
     window->WGL.EXT_create_context_es2_profile = GL_FALSE;
@@ -92,6 +93,9 @@ static void initWGLExtensions(_GLFWwindow* window)
     if (_glfwPlatformExtensionSupported("WGL_ARB_multisample"))
         window->WGL.ARB_multisample = GL_TRUE;
 
+    if (_glfwPlatformExtensionSupported("WGL_ARB_framebuffer_sRGB"))
+        window->WGL.ARB_framebuffer_sRGB = GL_TRUE;
+
     if (_glfwPlatformExtensionSupported("WGL_ARB_create_context"))
     {
         window->WGL.CreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)
@@ -246,6 +250,11 @@ static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found)
                 f->samples = getPixelFormatAttrib(window, i, WGL_SAMPLES_ARB);
             else
                 f->samples = 0;
+
+            if (window->WGL.ARB_framebuffer_sRGB)
+                f->sRGB = getPixelFormatAttrib(window, i, WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB);
+            else
+                f->sRGB = GL_FALSE;
         }
         else
         {
@@ -293,6 +302,9 @@ static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found)
 
             // PFD pixel formats do not support FSAA
             f->samples = 0;
+
+            // PFD pixel formats do not support sRGB
+            f->sRGB = GL_FALSE;
         }
 
         f->platformID = i;
diff --git a/src/win32_platform.h b/src/win32_platform.h
index 217fc2cf..ccabf595 100644
--- a/src/win32_platform.h
+++ b/src/win32_platform.h
@@ -144,6 +144,7 @@ typedef struct _GLFWcontextWGL
     GLboolean                           EXT_swap_control;
     GLboolean                           ARB_multisample;
     GLboolean                           ARB_pixel_format;
+    GLboolean                           ARB_framebuffer_sRGB;
     GLboolean                           ARB_create_context;
     GLboolean                           ARB_create_context_profile;
     GLboolean                           EXT_create_context_es2_profile;
diff --git a/src/window.c b/src/window.c
index ac0fd02f..d4026465 100644
--- a/src/window.c
+++ b/src/window.c
@@ -237,6 +237,7 @@ GLFWAPI GLFWwindow glfwCreateWindow(int width, int height,
     fbconfig.auxBuffers     = Max(_glfwLibrary.hints.auxBuffers, 0);
     fbconfig.stereo         = _glfwLibrary.hints.stereo ? GL_TRUE : GL_FALSE;
     fbconfig.samples        = Max(_glfwLibrary.hints.samples, 0);
+    fbconfig.sRGB           = _glfwLibrary.hints.sRGB ? GL_TRUE : GL_FALSE;
 
     // Set up desired window config
     wndconfig.mode           = mode;
@@ -446,6 +447,9 @@ GLFWAPI void glfwWindowHint(int target, int hint)
         case GLFW_FSAA_SAMPLES:
             _glfwLibrary.hints.samples = hint;
             break;
+        case GLFW_SRGB_CAPABLE:
+            _glfwLibrary.hints.sRGB = hint;
+            break;
         case GLFW_CLIENT_API:
             _glfwLibrary.hints.clientAPI = hint;
             break;
diff --git a/src/x11_opengl.c b/src/x11_opengl.c
index ad77805a..845a1980 100644
--- a/src/x11_opengl.c
+++ b/src/x11_opengl.c
@@ -190,6 +190,11 @@ static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found)
         else
             f->samples = 0;
 
+        if (_glfwLibrary.GLX.ARB_framebuffer_sRGB)
+            f->sRGB = getFBConfigAttrib(window, fbconfigs[i], GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB);
+        else
+            f->sRGB = GL_FALSE;
+
         f->platformID = (GLFWintptr) getFBConfigAttrib(window, fbconfigs[i], GLX_FBCONFIG_ID);
 
         (*found)++;
@@ -527,6 +532,9 @@ int _glfwInitOpenGL(void)
     if (_glfwPlatformExtensionSupported("GLX_ARB_multisample"))
         _glfwLibrary.GLX.ARB_multisample = GL_TRUE;
 
+    if (_glfwPlatformExtensionSupported("GLX_ARB_framebuffer_sRGB"))
+        _glfwLibrary.GLX.ARB_framebuffer_sRGB = GL_TRUE;
+
     if (_glfwPlatformExtensionSupported("GLX_ARB_create_context"))
     {
         _glfwLibrary.GLX.CreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)
diff --git a/src/x11_platform.h b/src/x11_platform.h
index e577c22f..84a2aa85 100644
--- a/src/x11_platform.h
+++ b/src/x11_platform.h
@@ -272,6 +272,7 @@ typedef struct _GLFWlibraryGLX
     GLboolean   EXT_swap_control;
     GLboolean   MESA_swap_control;
     GLboolean   ARB_multisample;
+    GLboolean   ARB_framebuffer_sRGB;
     GLboolean   ARB_create_context;
     GLboolean   ARB_create_context_profile;
     GLboolean   ARB_create_context_robustness;