mirror of
https://github.com/moonlight-stream/moonlight-qt
synced 2024-12-15 05:42:28 +00:00
Plumb HDR metadata and horizontal scrolling with Sunshine
This commit is contained in:
parent
17cad6b3ca
commit
8a0142bd0f
6 changed files with 88 additions and 66 deletions
|
@ -227,6 +227,21 @@ void SdlInputHandler::handleMouseWheelEvent(SDL_MouseWheelEvent* event)
|
||||||
|
|
||||||
LiSendHighResScrollEvent((short)(event->preciseY * 120)); // WHEEL_DELTA
|
LiSendHighResScrollEvent((short)(event->preciseY * 120)); // WHEEL_DELTA
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (event->preciseX != 0.0f) {
|
||||||
|
// Invert the scroll direction if needed
|
||||||
|
if (m_ReverseScrollDirection) {
|
||||||
|
event->preciseX = -event->preciseY;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef Q_OS_DARWIN
|
||||||
|
// HACK: Clamp the scroll values on macOS to prevent OS scroll acceleration
|
||||||
|
// from generating wild scroll deltas when scrolling quickly.
|
||||||
|
event->preciseX = SDL_clamp(event->preciseX, -1.0f, 1.0f);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
LiSendHighResHScrollEvent((short)(event->preciseX * 120)); // WHEEL_DELTA
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
if (event->y != 0) {
|
if (event->y != 0) {
|
||||||
// Invert the scroll direction if needed
|
// Invert the scroll direction if needed
|
||||||
|
@ -241,6 +256,20 @@ void SdlInputHandler::handleMouseWheelEvent(SDL_MouseWheelEvent* event)
|
||||||
|
|
||||||
LiSendScrollEvent((signed char)event->y);
|
LiSendScrollEvent((signed char)event->y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (event->x != 0) {
|
||||||
|
// Invert the scroll direction if needed
|
||||||
|
if (m_ReverseScrollDirection) {
|
||||||
|
event->x = -event->x;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef Q_OS_DARWIN
|
||||||
|
// See comment above
|
||||||
|
event->x = SDL_clamp(event->x, -1, 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
LiSendHScrollEvent((signed char)event->x);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -235,10 +235,6 @@ bool Session::chooseDecoder(StreamingPreferences::VideoDecoderSelection vds,
|
||||||
params.testOnly = testOnly;
|
params.testOnly = testOnly;
|
||||||
params.vds = vds;
|
params.vds = vds;
|
||||||
|
|
||||||
memset(¶ms.hdrMetadata, 0, sizeof(params.hdrMetadata));
|
|
||||||
params.hdrMetadata.eotf = 2; // SMPTE ST 2084
|
|
||||||
params.hdrMetadata.staticMetadataDescriptorId = 0; // Static Metadata Type 1
|
|
||||||
|
|
||||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
"V-sync %s",
|
"V-sync %s",
|
||||||
enableVsync ? "enabled" : "disabled");
|
enableVsync ? "enabled" : "disabled");
|
||||||
|
|
|
@ -28,23 +28,6 @@ typedef struct _VIDEO_STATS {
|
||||||
uint32_t measurementStartTimestamp;
|
uint32_t measurementStartTimestamp;
|
||||||
} VIDEO_STATS, *PVIDEO_STATS;
|
} VIDEO_STATS, *PVIDEO_STATS;
|
||||||
|
|
||||||
typedef struct _HDR_MASTERING_METADATA {
|
|
||||||
uint8_t eotf;
|
|
||||||
uint8_t staticMetadataDescriptorId;
|
|
||||||
struct {
|
|
||||||
uint16_t x;
|
|
||||||
uint16_t y;
|
|
||||||
} displayPrimaries[3];
|
|
||||||
struct {
|
|
||||||
uint16_t x;
|
|
||||||
uint16_t y;
|
|
||||||
} whitePoint;
|
|
||||||
uint16_t maxDisplayMasteringLuminance;
|
|
||||||
uint16_t minDisplayMasteringLuminance;
|
|
||||||
uint16_t maxContentLightLevel;
|
|
||||||
uint16_t maxFrameAverageLightLevel;
|
|
||||||
} HDR_MASTERING_METADATA, *PHDR_MASTERING_METADATA;
|
|
||||||
|
|
||||||
typedef struct _DECODER_PARAMETERS {
|
typedef struct _DECODER_PARAMETERS {
|
||||||
SDL_Window* window;
|
SDL_Window* window;
|
||||||
StreamingPreferences::VideoDecoderSelection vds;
|
StreamingPreferences::VideoDecoderSelection vds;
|
||||||
|
@ -56,7 +39,6 @@ typedef struct _DECODER_PARAMETERS {
|
||||||
bool enableVsync;
|
bool enableVsync;
|
||||||
bool enableFramePacing;
|
bool enableFramePacing;
|
||||||
bool testOnly;
|
bool testOnly;
|
||||||
HDR_MASTERING_METADATA hdrMetadata;
|
|
||||||
} DECODER_PARAMETERS, *PDECODER_PARAMETERS;
|
} DECODER_PARAMETERS, *PDECODER_PARAMETERS;
|
||||||
|
|
||||||
class IVideoDecoder {
|
class IVideoDecoder {
|
||||||
|
|
|
@ -512,19 +512,25 @@ void D3D11VARenderer::setHdrMode(bool enabled)
|
||||||
|
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
DXGI_HDR_METADATA_HDR10 hdr10Metadata;
|
DXGI_HDR_METADATA_HDR10 hdr10Metadata;
|
||||||
|
SS_HDR_METADATA sunshineHdrMetadata;
|
||||||
|
|
||||||
hdr10Metadata.RedPrimary[0] = m_DecoderParams.hdrMetadata.displayPrimaries[0].x;
|
// Sunshine will have HDR metadata but GFE will not
|
||||||
hdr10Metadata.RedPrimary[1] = m_DecoderParams.hdrMetadata.displayPrimaries[0].y;
|
if (!LiGetHdrMetadata(&sunshineHdrMetadata)) {
|
||||||
hdr10Metadata.GreenPrimary[0] = m_DecoderParams.hdrMetadata.displayPrimaries[1].x;
|
RtlZeroMemory(&sunshineHdrMetadata, sizeof(sunshineHdrMetadata));
|
||||||
hdr10Metadata.GreenPrimary[1] = m_DecoderParams.hdrMetadata.displayPrimaries[1].y;
|
}
|
||||||
hdr10Metadata.BluePrimary[0] = m_DecoderParams.hdrMetadata.displayPrimaries[2].x;
|
|
||||||
hdr10Metadata.BluePrimary[1] = m_DecoderParams.hdrMetadata.displayPrimaries[2].y;
|
hdr10Metadata.RedPrimary[0] = sunshineHdrMetadata.displayPrimaries[0].x;
|
||||||
hdr10Metadata.WhitePoint[0] = m_DecoderParams.hdrMetadata.whitePoint.x;
|
hdr10Metadata.RedPrimary[1] = sunshineHdrMetadata.displayPrimaries[0].y;
|
||||||
hdr10Metadata.WhitePoint[1] = m_DecoderParams.hdrMetadata.whitePoint.y;
|
hdr10Metadata.GreenPrimary[0] = sunshineHdrMetadata.displayPrimaries[1].x;
|
||||||
hdr10Metadata.MaxMasteringLuminance = m_DecoderParams.hdrMetadata.maxDisplayMasteringLuminance;
|
hdr10Metadata.GreenPrimary[1] = sunshineHdrMetadata.displayPrimaries[1].y;
|
||||||
hdr10Metadata.MinMasteringLuminance = m_DecoderParams.hdrMetadata.minDisplayMasteringLuminance;
|
hdr10Metadata.BluePrimary[0] = sunshineHdrMetadata.displayPrimaries[2].x;
|
||||||
hdr10Metadata.MaxContentLightLevel = m_DecoderParams.hdrMetadata.maxContentLightLevel;
|
hdr10Metadata.BluePrimary[1] = sunshineHdrMetadata.displayPrimaries[2].y;
|
||||||
hdr10Metadata.MaxFrameAverageLightLevel = m_DecoderParams.hdrMetadata.maxFrameAverageLightLevel;
|
hdr10Metadata.WhitePoint[0] = sunshineHdrMetadata.whitePoint.x;
|
||||||
|
hdr10Metadata.WhitePoint[1] = sunshineHdrMetadata.whitePoint.y;
|
||||||
|
hdr10Metadata.MaxMasteringLuminance = sunshineHdrMetadata.maxDisplayLuminance;
|
||||||
|
hdr10Metadata.MinMasteringLuminance = sunshineHdrMetadata.minDisplayLuminance;
|
||||||
|
hdr10Metadata.MaxContentLightLevel = sunshineHdrMetadata.maxContentLightLevel;
|
||||||
|
hdr10Metadata.MaxFrameAverageLightLevel = sunshineHdrMetadata.maxFrameAverageLightLevel;
|
||||||
|
|
||||||
hr = m_SwapChain->SetHDRMetaData(DXGI_HDR_METADATA_TYPE_HDR10, sizeof(hdr10Metadata), &hdr10Metadata);
|
hr = m_SwapChain->SetHDRMetaData(DXGI_HDR_METADATA_TYPE_HDR10, sizeof(hdr10Metadata), &hdr10Metadata);
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
|
|
|
@ -421,35 +421,6 @@ bool DrmRenderer::initialize(PDECODER_PARAMETERS params)
|
||||||
drmModeFreeObjectProperties(props);
|
drmModeFreeObjectProperties(props);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have an HDR output metadata property, construct the metadata blob
|
|
||||||
// to apply when we are called to enter HDR mode.
|
|
||||||
if (m_HdrOutputMetadataProp != nullptr) {
|
|
||||||
DrmDefs::hdr_output_metadata outputMetadata;
|
|
||||||
|
|
||||||
outputMetadata.metadata_type = 0; // HDMI_STATIC_METADATA_TYPE1
|
|
||||||
outputMetadata.hdmi_metadata_type1.eotf = params->hdrMetadata.eotf;
|
|
||||||
outputMetadata.hdmi_metadata_type1.metadata_type = params->hdrMetadata.staticMetadataDescriptorId;
|
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
outputMetadata.hdmi_metadata_type1.display_primaries[i].x = params->hdrMetadata.displayPrimaries[i].x;
|
|
||||||
outputMetadata.hdmi_metadata_type1.display_primaries[i].y = params->hdrMetadata.displayPrimaries[i].y;
|
|
||||||
}
|
|
||||||
outputMetadata.hdmi_metadata_type1.white_point.x = params->hdrMetadata.whitePoint.x;
|
|
||||||
outputMetadata.hdmi_metadata_type1.white_point.y = params->hdrMetadata.whitePoint.y;
|
|
||||||
outputMetadata.hdmi_metadata_type1.max_display_mastering_luminance = params->hdrMetadata.maxDisplayMasteringLuminance;
|
|
||||||
outputMetadata.hdmi_metadata_type1.min_display_mastering_luminance = params->hdrMetadata.minDisplayMasteringLuminance;
|
|
||||||
outputMetadata.hdmi_metadata_type1.max_cll = params->hdrMetadata.maxContentLightLevel;
|
|
||||||
outputMetadata.hdmi_metadata_type1.max_fall = params->hdrMetadata.maxFrameAverageLightLevel;
|
|
||||||
|
|
||||||
err = drmModeCreatePropertyBlob(m_DrmFd, &outputMetadata, sizeof(outputMetadata), &m_HdrOutputMetadataBlobId);
|
|
||||||
if (err < 0) {
|
|
||||||
m_HdrOutputMetadataBlobId = 0;
|
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
|
||||||
"drmModeCreatePropertyBlob() failed: %d",
|
|
||||||
errno);
|
|
||||||
// Non-fatal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we got this far, we can do direct rendering via the DRM FD.
|
// If we got this far, we can do direct rendering via the DRM FD.
|
||||||
m_SupportsDirectRendering = true;
|
m_SupportsDirectRendering = true;
|
||||||
|
|
||||||
|
@ -496,7 +467,45 @@ int DrmRenderer::getRendererAttributes()
|
||||||
|
|
||||||
void DrmRenderer::setHdrMode(bool enabled)
|
void DrmRenderer::setHdrMode(bool enabled)
|
||||||
{
|
{
|
||||||
if (m_HdrOutputMetadataProp != nullptr && m_HdrOutputMetadataBlobId != 0) {
|
if (m_HdrOutputMetadataProp != nullptr) {
|
||||||
|
if (m_HdrOutputMetadataBlobId != 0) {
|
||||||
|
drmModeDestroyPropertyBlob(m_DrmFd, m_HdrOutputMetadataBlobId);
|
||||||
|
m_HdrOutputMetadataBlobId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enabled) {
|
||||||
|
DrmDefs::hdr_output_metadata outputMetadata;
|
||||||
|
SS_HDR_METADATA sunshineHdrMetadata;
|
||||||
|
|
||||||
|
// Sunshine will have HDR metadata but GFE will not
|
||||||
|
if (!LiGetHdrMetadata(&sunshineHdrMetadata)) {
|
||||||
|
memset(&sunshineHdrMetadata, 0, sizeof(sunshineHdrMetadata));
|
||||||
|
}
|
||||||
|
|
||||||
|
outputMetadata.metadata_type = 0; // HDMI_STATIC_METADATA_TYPE1
|
||||||
|
outputMetadata.hdmi_metadata_type1.eotf = 2; // SMPTE ST 2084
|
||||||
|
outputMetadata.hdmi_metadata_type1.metadata_type = 0; // Static Metadata Type 1
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
outputMetadata.hdmi_metadata_type1.display_primaries[i].x = sunshineHdrMetadata.displayPrimaries[i].x;
|
||||||
|
outputMetadata.hdmi_metadata_type1.display_primaries[i].y = sunshineHdrMetadata.displayPrimaries[i].y;
|
||||||
|
}
|
||||||
|
outputMetadata.hdmi_metadata_type1.white_point.x = sunshineHdrMetadata.whitePoint.x;
|
||||||
|
outputMetadata.hdmi_metadata_type1.white_point.y = sunshineHdrMetadata.whitePoint.y;
|
||||||
|
outputMetadata.hdmi_metadata_type1.max_display_mastering_luminance = sunshineHdrMetadata.maxDisplayLuminance;
|
||||||
|
outputMetadata.hdmi_metadata_type1.min_display_mastering_luminance = sunshineHdrMetadata.minDisplayLuminance;
|
||||||
|
outputMetadata.hdmi_metadata_type1.max_cll = sunshineHdrMetadata.maxContentLightLevel;
|
||||||
|
outputMetadata.hdmi_metadata_type1.max_fall = sunshineHdrMetadata.maxFrameAverageLightLevel;
|
||||||
|
|
||||||
|
err = drmModeCreatePropertyBlob(m_DrmFd, &outputMetadata, sizeof(outputMetadata), &m_HdrOutputMetadataBlobId);
|
||||||
|
if (err < 0) {
|
||||||
|
m_HdrOutputMetadataBlobId = 0;
|
||||||
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"drmModeCreatePropertyBlob() failed: %d",
|
||||||
|
errno);
|
||||||
|
// Non-fatal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int err = drmModeObjectSetProperty(m_DrmFd, m_ConnectorId, DRM_MODE_OBJECT_CONNECTOR,
|
int err = drmModeObjectSetProperty(m_DrmFd, m_ConnectorId, DRM_MODE_OBJECT_CONNECTOR,
|
||||||
m_HdrOutputMetadataProp->prop_id,
|
m_HdrOutputMetadataProp->prop_id,
|
||||||
enabled ? m_HdrOutputMetadataBlobId : 0);
|
enabled ? m_HdrOutputMetadataBlobId : 0);
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 7d9df5b731fa9c90535bc94f74a9d92b7f7d79a0
|
Subproject commit 07beb0f0a520106c49fda7664369b29e6938ea6e
|
Loading…
Reference in a new issue