mirror of
https://github.com/love2d/love.git
synced 2026-08-20 04:30:09 +02:00
macOS: fix colors appearing oversaturated on P3 displays.
The fix only applies to macOS 11+ when using OpenGL.
This commit is contained in:
@@ -26,6 +26,8 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
typedef struct SDL_Window SDL_Window;
|
||||||
|
|
||||||
namespace love
|
namespace love
|
||||||
{
|
{
|
||||||
namespace macos
|
namespace macos
|
||||||
@@ -55,6 +57,12 @@ void requestAttention(bool continuous);
|
|||||||
void setMetalLayerVSync(void *metallayer, bool vsync);
|
void setMetalLayerVSync(void *metallayer, bool vsync);
|
||||||
bool getMetalLayerVSync(void *metallayer);
|
bool getMetalLayerVSync(void *metallayer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Explicitly sets the window's color space to be sRGB - which stops the OS
|
||||||
|
* from interpreting the backbuffer output as P3 on P3-capable displays.
|
||||||
|
**/
|
||||||
|
void setWindowSRGBColorSpace(SDL_Window *window);
|
||||||
|
|
||||||
} // macos
|
} // macos
|
||||||
} // love
|
} // love
|
||||||
|
|
||||||
|
|||||||
+20
-3
@@ -27,9 +27,11 @@
|
|||||||
#import <QuartzCore/CAMetalLayer.h>
|
#import <QuartzCore/CAMetalLayer.h>
|
||||||
|
|
||||||
#ifdef LOVE_MACOSX_SDL_DIRECT_INCLUDE
|
#ifdef LOVE_MACOSX_SDL_DIRECT_INCLUDE
|
||||||
# include <SDL.h>
|
#include <SDL.h>
|
||||||
|
#include <SDL_syswm.h>
|
||||||
#else
|
#else
|
||||||
# include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
|
#include <SDL2/SDL_syswm.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace love
|
namespace love
|
||||||
@@ -112,7 +114,22 @@ bool getMetalLayerVSync(void *metallayer)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // osx
|
void setWindowSRGBColorSpace(SDL_Window *window)
|
||||||
|
{
|
||||||
|
@autoreleasepool
|
||||||
|
{
|
||||||
|
// This works on earlier macOS versions, but performance may be worse
|
||||||
|
// (at least, it was back when I tested in December 2016).
|
||||||
|
if (@available(macOS 11.0, *))
|
||||||
|
{
|
||||||
|
SDL_SysWMinfo info = {};
|
||||||
|
if (SDL_GetWindowWMInfo(window, &info))
|
||||||
|
info.info.cocoa.window.colorSpace = [NSColorSpace sRGBColorSpace];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // macos
|
||||||
} // love
|
} // love
|
||||||
|
|
||||||
#endif // LOVE_MACOS
|
#endif // LOVE_MACOS
|
||||||
|
|||||||
@@ -479,12 +479,6 @@ bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int
|
|||||||
metalLayer.device = device;
|
metalLayer.device = device;
|
||||||
metalLayer.pixelFormat = isGammaCorrect() ? MTLPixelFormatBGRA8Unorm_sRGB : MTLPixelFormatBGRA8Unorm;
|
metalLayer.pixelFormat = isGammaCorrect() ? MTLPixelFormatBGRA8Unorm_sRGB : MTLPixelFormatBGRA8Unorm;
|
||||||
|
|
||||||
// Explicitly turn off color matching, for now (eg don't make sRGB content
|
|
||||||
// appear correct on P3 displays). It looks better with color matching, but
|
|
||||||
// having it off matches the OpenGL backend and there's some cost to it.
|
|
||||||
// TODO: revisit this?
|
|
||||||
metalLayer.colorspace = nil;
|
|
||||||
|
|
||||||
// This is set to NO when there are pending screen captures.
|
// This is set to NO when there are pending screen captures.
|
||||||
metalLayer.framebufferOnly = YES;
|
metalLayer.framebufferOnly = YES;
|
||||||
|
|
||||||
|
|||||||
@@ -366,27 +366,29 @@ bool Window::createWindowAndContext(int x, int y, int w, int h, Uint32 windowfla
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (renderer == love::graphics::Renderer::RENDERER_OPENGL) {
|
if (attribs != nullptr && renderer == love::graphics::Renderer::RENDERER_OPENGL)
|
||||||
if (attribs != nullptr)
|
{
|
||||||
|
#ifdef LOVE_MACOS
|
||||||
|
love::macos::setWindowSRGBColorSpace(window);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
glcontext = SDL_GL_CreateContext(window);
|
||||||
|
|
||||||
|
if (!glcontext)
|
||||||
|
contexterror = std::string(SDL_GetError());
|
||||||
|
|
||||||
|
// Make sure the context's version is at least what we requested.
|
||||||
|
if (glcontext && !checkGLVersion(*attribs, glversion))
|
||||||
{
|
{
|
||||||
glcontext = SDL_GL_CreateContext(window);
|
SDL_GL_DeleteContext(glcontext);
|
||||||
|
glcontext = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
if (!glcontext)
|
if (!glcontext)
|
||||||
contexterror = std::string(SDL_GetError());
|
{
|
||||||
|
SDL_DestroyWindow(window);
|
||||||
// Make sure the context's version is at least what we requested.
|
window = nullptr;
|
||||||
if (glcontext && !checkGLVersion(*attribs, glversion))
|
return false;
|
||||||
{
|
|
||||||
SDL_GL_DeleteContext(glcontext);
|
|
||||||
glcontext = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!glcontext)
|
|
||||||
{
|
|
||||||
SDL_DestroyWindow(window);
|
|
||||||
window = nullptr;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user