mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-07-20 14:22:00 +00:00
[client] egl: fix SPICE video rendering to a HDR surface
If the last state had HDR enabled, the spice video surface was being rendered as HDR even though the SPICE video content is SDR. This corrects this.
This commit is contained in:
@@ -464,12 +464,13 @@ bool egl_desktopRender(EGL_Desktop * desktop, unsigned int outputWidth,
|
||||
egl_desktopRectsUpdate(desktop->mesh, rects, width, height);
|
||||
|
||||
*fullFrame = false;
|
||||
const bool hdr = desktop->hdr && !desktop->useSpice;
|
||||
const bool processFrame = atomic_exchange(&desktop->processFrame, false) ||
|
||||
egl_postProcessConfigModified(desktop->pp);
|
||||
if (processFrame &&
|
||||
egl_postProcessRun(desktop->pp, tex, desktop->mesh,
|
||||
width, height, outputWidth, outputHeight, dma,
|
||||
desktop->hdr && desktop->hdrPQ) &&
|
||||
hdr && desktop->hdrPQ) &&
|
||||
egl_postProcessNeedsFullFrame(desktop->pp))
|
||||
{
|
||||
/* The filter output may have changed everywhere, but this only applies to
|
||||
@@ -529,7 +530,7 @@ bool egl_desktopRender(EGL_Desktop * desktop, unsigned int outputWidth,
|
||||
egl_uniformMatrix3x2fv(shader->uTransform , 1, GL_FALSE, desktop->matrix);
|
||||
egl_uniform1f (shader->uNVGain , desktop->nvGain);
|
||||
egl_uniform1i (shader->uCBMode , desktop->cbMode);
|
||||
egl_uniform1i (shader->uIsHDR , desktop->hdr);
|
||||
egl_uniform1i (shader->uIsHDR , hdr);
|
||||
egl_uniform1i (shader->uMapHDRtoSDR, desktop->mapHDRtoSDR && !desktop->nativeHDR);
|
||||
egl_uniform1f (shader->uMapHDRGain , mapHDRGain);
|
||||
egl_uniform1i (shader->uMapHDRPQ , desktop->hdrPQ);
|
||||
|
||||
@@ -619,8 +619,8 @@ static bool egl_updateHDRState(struct Inst * this, bool force)
|
||||
app_getProp(LG_DS_NATIVE_HDR, &nativeHDR);
|
||||
const bool surfaceCompatible = this->format.hdrPQ ?
|
||||
this->surfaceSupportsPQ : this->surfaceSupportsSCRGB;
|
||||
const bool useNativeHDR = this->format.hdr && surfaceCompatible && nativeHDR &&
|
||||
!app_getHDRDescFailed();
|
||||
const bool useNativeHDR = !this->showSpice && this->format.hdr &&
|
||||
surfaceCompatible && nativeHDR && !app_getHDRDescFailed();
|
||||
|
||||
if (!force && this->nativeHDR == useNativeHDR)
|
||||
return false;
|
||||
|
||||
@@ -778,26 +778,7 @@ int main_frameThread(void * unused)
|
||||
!g_state.lgr->ops.supports || RENDERER(supports,
|
||||
lgrFormat.hdrPQ ? LG_SUPPORTS_HDR_PQ : LG_SUPPORTS_HDR_SCRGB);
|
||||
LG_UNLOCK(g_state.lgrLock);
|
||||
|
||||
if (g_state.ds->setHDRImageDescription)
|
||||
{
|
||||
if (lgrFormat.hdr && !rendererSupportsNativeHDR)
|
||||
{
|
||||
LG_RendererFormat sdrSurfaceFormat = lgrFormat;
|
||||
sdrSurfaceFormat.hdr = false;
|
||||
g_state.ds->setHDRImageDescription(&sdrSurfaceFormat);
|
||||
DEBUG_WARN("Renderer surface cannot represent the native HDR "
|
||||
"encoding; using software HDR mapping");
|
||||
atomic_store(&g_state.hdrDescFailed, true);
|
||||
}
|
||||
else if (!g_state.ds->setHDRImageDescription(&lgrFormat))
|
||||
{
|
||||
DEBUG_WARN("Display server failed to apply HDR image description");
|
||||
atomic_store(&g_state.hdrDescFailed, true);
|
||||
}
|
||||
else
|
||||
atomic_store(&g_state.hdrDescFailed, false);
|
||||
}
|
||||
renderQueue_surfaceFormat(lgrFormat, rendererSupportsNativeHDR);
|
||||
|
||||
g_state.srcSize.x = lgrFormat.screenWidth;
|
||||
g_state.srcSize.y = lgrFormat.screenHeight;
|
||||
|
||||
@@ -22,15 +22,67 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "common/debug.h"
|
||||
#include "common/ll.h"
|
||||
#include "main.h"
|
||||
#include "overlays.h"
|
||||
|
||||
struct ll * l_renderQueue = NULL;
|
||||
static bool l_showSpice;
|
||||
static bool l_surfaceFormatValid;
|
||||
static bool l_rendererSupportsNativeHDR;
|
||||
static LG_RendererFormat l_surfaceFormat;
|
||||
|
||||
static void updateSurfaceFormat(void)
|
||||
{
|
||||
if (!g_state.ds->setHDRImageDescription)
|
||||
return;
|
||||
|
||||
LG_RendererFormat format = {};
|
||||
if (l_surfaceFormatValid)
|
||||
format = l_surfaceFormat;
|
||||
|
||||
if (l_showSpice)
|
||||
{
|
||||
// The SPICE display is always 8-bit SDR, regardless of the last format
|
||||
// received from the Looking Glass host.
|
||||
format.hdr = false;
|
||||
format.hdrPQ = false;
|
||||
format.hdrMetadata = false;
|
||||
g_state.ds->setHDRImageDescription(&format);
|
||||
atomic_store(&g_state.hdrDescFailed, false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!l_surfaceFormatValid)
|
||||
return;
|
||||
|
||||
if (format.hdr && !l_rendererSupportsNativeHDR)
|
||||
{
|
||||
format.hdr = false;
|
||||
format.hdrPQ = false;
|
||||
format.hdrMetadata = false;
|
||||
g_state.ds->setHDRImageDescription(&format);
|
||||
DEBUG_WARN("Renderer surface cannot represent the native HDR encoding; "
|
||||
"using software HDR mapping");
|
||||
atomic_store(&g_state.hdrDescFailed, true);
|
||||
}
|
||||
else if (!g_state.ds->setHDRImageDescription(&format))
|
||||
{
|
||||
DEBUG_WARN("Display server failed to apply HDR image description");
|
||||
atomic_store(&g_state.hdrDescFailed, true);
|
||||
}
|
||||
else
|
||||
atomic_store(&g_state.hdrDescFailed, false);
|
||||
}
|
||||
|
||||
void renderQueue_init(void)
|
||||
{
|
||||
l_renderQueue = ll_new();
|
||||
l_renderQueue = ll_new();
|
||||
l_showSpice = false;
|
||||
l_surfaceFormatValid = false;
|
||||
l_rendererSupportsNativeHDR = false;
|
||||
memset(&l_surfaceFormat, 0, sizeof(l_surfaceFormat));
|
||||
}
|
||||
|
||||
void renderQueue_free(void)
|
||||
@@ -103,6 +155,18 @@ void renderQueue_spiceShow(bool show)
|
||||
app_invalidateWindow(true);
|
||||
}
|
||||
|
||||
void renderQueue_surfaceFormat(const LG_RendererFormat format,
|
||||
bool rendererSupportsNativeHDR)
|
||||
{
|
||||
RenderCommand * cmd = malloc(sizeof(*cmd));
|
||||
cmd->op = SURFACE_OP_FORMAT;
|
||||
cmd->surfaceFormat.format = format;
|
||||
cmd->surfaceFormat.rendererSupportsNativeHDR =
|
||||
rendererSupportsNativeHDR;
|
||||
ll_push(l_renderQueue, cmd);
|
||||
app_invalidateWindow(true);
|
||||
}
|
||||
|
||||
void renderQueue_cursorState(bool visible, int x, int y, int hx, int hy)
|
||||
{
|
||||
RenderCommand * cmd = malloc(sizeof(*cmd));
|
||||
@@ -157,11 +221,21 @@ void renderQueue_process(void)
|
||||
break;
|
||||
|
||||
case SPICE_OP_SHOW:
|
||||
l_showSpice = cmd->spiceShow.show;
|
||||
RENDERER(spiceShow, cmd->spiceShow.show);
|
||||
updateSurfaceFormat();
|
||||
if (cmd->spiceShow.show)
|
||||
overlaySplash_show(false);
|
||||
break;
|
||||
|
||||
case SURFACE_OP_FORMAT:
|
||||
l_surfaceFormat = cmd->surfaceFormat.format;
|
||||
l_surfaceFormatValid = true;
|
||||
l_rendererSupportsNativeHDR =
|
||||
cmd->surfaceFormat.rendererSupportsNativeHDR;
|
||||
updateSurfaceFormat();
|
||||
break;
|
||||
|
||||
case CURSOR_OP_STATE:
|
||||
RENDERER(onMouseEvent, cmd->cursorState.visible, cmd->cursorState.x,
|
||||
cmd->cursorState.y, cmd->cursorState.hx, cmd->cursorState.hy);
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
*/
|
||||
|
||||
#include "common/ll.h"
|
||||
#include "interface/renderer.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -28,6 +29,7 @@ typedef struct
|
||||
SPICE_OP_DRAW_FILL,
|
||||
SPICE_OP_DRAW_BITMAP,
|
||||
SPICE_OP_SHOW,
|
||||
SURFACE_OP_FORMAT,
|
||||
CURSOR_OP_STATE,
|
||||
CURSOR_OP_IMAGE,
|
||||
}
|
||||
@@ -65,6 +67,13 @@ typedef struct
|
||||
}
|
||||
spiceShow;
|
||||
|
||||
struct
|
||||
{
|
||||
LG_RendererFormat format;
|
||||
bool rendererSupportsNativeHDR;
|
||||
}
|
||||
surfaceFormat;
|
||||
|
||||
struct
|
||||
{
|
||||
bool visible;
|
||||
@@ -103,6 +112,9 @@ void renderQueue_spiceDrawBitmap(int x, int y, int width, int height, int stride
|
||||
|
||||
void renderQueue_spiceShow(bool show);
|
||||
|
||||
void renderQueue_surfaceFormat(const LG_RendererFormat format,
|
||||
bool rendererSupportsNativeHDR);
|
||||
|
||||
void renderQueue_cursorState(bool visible, int x, int y, int hx, int hy);
|
||||
|
||||
void renderQueue_cursorImage(bool monochrome, int width, int height, int pitch,
|
||||
|
||||
Reference in New Issue
Block a user