diff --git a/src/posix/cocoa/i_video.mm b/src/posix/cocoa/i_video.mm index 3b04c64a0..242cb489b 100644 --- a/src/posix/cocoa/i_video.mm +++ b/src/posix/cocoa/i_video.mm @@ -1086,6 +1086,20 @@ SDLGLFB::SDLGLFB(void*, const int width, const int height, int, int, const bool , m_lock(-1) , m_isUpdatePending(false) { + CGGammaValue gammaTable[GAMMA_TABLE_SIZE]; + uint32_t actualChannelSize; + + const CGError result = CGGetDisplayTransferByTable(kCGDirectMainDisplay, GAMMA_CHANNEL_SIZE, + gammaTable, &gammaTable[GAMMA_CHANNEL_SIZE], &gammaTable[GAMMA_CHANNEL_SIZE * 2], &actualChannelSize); + m_supportsGamma = kCGErrorSuccess == result && GAMMA_CHANNEL_SIZE == actualChannelSize; + + if (m_supportsGamma) + { + for (uint32_t i = 0; i < GAMMA_TABLE_SIZE; ++i) + { + m_originalGamma[i] = static_cast(gammaTable[i] * 65535.0f); + } + } } SDLGLFB::SDLGLFB() @@ -1169,10 +1183,26 @@ void SDLGLFB::SwapBuffers() void SDLGLFB::SetGammaTable(WORD* table) { + if (m_supportsGamma) + { + CGGammaValue gammaTable[GAMMA_TABLE_SIZE]; + + for (uint32_t i = 0; i < GAMMA_TABLE_SIZE; ++i) + { + gammaTable[i] = static_cast(table[i] / 65535.0f); + } + + CGSetDisplayTransferByTable(kCGDirectMainDisplay, GAMMA_CHANNEL_SIZE, + gammaTable, &gammaTable[GAMMA_CHANNEL_SIZE], &gammaTable[GAMMA_CHANNEL_SIZE * 2]); + } } void SDLGLFB::ResetGammaTable() { + if (m_supportsGamma) + { + SetGammaTable(m_originalGamma); + } } int SDLGLFB::GetClientWidth() diff --git a/src/posix/cocoa/sdlglvideo.h b/src/posix/cocoa/sdlglvideo.h index 4a63a9193..cab846a15 100644 --- a/src/posix/cocoa/sdlglvideo.h +++ b/src/posix/cocoa/sdlglvideo.h @@ -71,7 +71,12 @@ protected: int m_lock; bool m_isUpdatePending; - static const bool m_supportsGamma = false; + static const uint32_t GAMMA_CHANNEL_SIZE = 256; + static const uint32_t GAMMA_CHANNEL_COUNT = 3; + static const uint32_t GAMMA_TABLE_SIZE = GAMMA_CHANNEL_SIZE * GAMMA_CHANNEL_COUNT; + + bool m_supportsGamma; + WORD m_originalGamma[GAMMA_TABLE_SIZE]; SDLGLFB();