Generalize SDR white level handling into a color scale
This gives applications better control over how and when light levels are adjusted when working with HDR content and display.
This commit is contained in:
@@ -35,6 +35,8 @@ static int renderer_index = 0;
|
||||
static int stage_count = 6;
|
||||
static int stage_index = 0;
|
||||
static int done;
|
||||
static float SDR_color_scale = 1.0f;
|
||||
static float HDR_color_scale = 1.0f;
|
||||
|
||||
static void FreeRenderer(void)
|
||||
{
|
||||
@@ -47,6 +49,7 @@ static void CreateRenderer(void)
|
||||
{
|
||||
SDL_PropertiesID props;
|
||||
SDL_RendererInfo info;
|
||||
float SDR_white_level;
|
||||
|
||||
props = SDL_CreateProperties();
|
||||
SDL_SetProperty(props, SDL_PROP_RENDERER_CREATE_WINDOW_POINTER, window);
|
||||
@@ -62,6 +65,16 @@ static void CreateRenderer(void)
|
||||
SDL_GetRendererInfo(renderer, &info);
|
||||
SDL_Log("Created renderer %s\n", info.name);
|
||||
renderer_name = info.name;
|
||||
|
||||
/* If HDR is enabled... */
|
||||
if (colorspace == SDL_COLORSPACE_SCRGB) {
|
||||
SDR_white_level = 200.0f;
|
||||
} else {
|
||||
SDR_white_level = 80.0f;
|
||||
}
|
||||
SDR_color_scale = SDR_white_level / 80.0f;
|
||||
|
||||
SDL_SetRenderColorScale(renderer, SDR_color_scale);
|
||||
}
|
||||
|
||||
static void NextRenderer( void )
|
||||
@@ -429,7 +442,9 @@ static void RenderGradientDrawing(void)
|
||||
|
||||
DrawTextWhite(x, y, "HDR gradient (%d nits)", 400);
|
||||
y += TEXT_LINE_ADVANCE;
|
||||
SDL_SetRenderColorScale(renderer, HDR_color_scale);
|
||||
DrawGradient(x, y, WINDOW_WIDTH - 2 * x, 64.0f, 0.0f, sRGBfromNits(400.0f));
|
||||
SDL_SetRenderColorScale(renderer, SDR_color_scale);
|
||||
y += 64.0f;
|
||||
|
||||
y += TEXT_LINE_ADVANCE;
|
||||
@@ -437,7 +452,9 @@ static void RenderGradientDrawing(void)
|
||||
|
||||
DrawTextWhite(x, y, "HDR gradient (%d nits)", 1000);
|
||||
y += TEXT_LINE_ADVANCE;
|
||||
SDL_SetRenderColorScale(renderer, HDR_color_scale);
|
||||
DrawGradient(x, y, WINDOW_WIDTH - 2 * x, 64.0f, 0.0f, sRGBfromNits(1000));
|
||||
SDL_SetRenderColorScale(renderer, SDR_color_scale);
|
||||
y += 64.0f;
|
||||
}
|
||||
|
||||
|
||||
@@ -646,6 +646,10 @@ static SDL_bool GetTextureForD3D11Frame(AVFrame *frame, SDL_Texture **texture)
|
||||
SDL_QueryTexture(*texture, NULL, NULL, &texture_width, &texture_height);
|
||||
}
|
||||
if (!*texture || (UINT)texture_width != desc.Width || (UINT)texture_height != desc.Height) {
|
||||
SDL_bool HDR_display = SDL_TRUE;
|
||||
SDL_bool HDR_video = SDL_FALSE;
|
||||
float display_white_level, video_white_level;
|
||||
|
||||
if (*texture) {
|
||||
SDL_DestroyTexture(*texture);
|
||||
}
|
||||
@@ -658,9 +662,11 @@ static SDL_bool GetTextureForD3D11Frame(AVFrame *frame, SDL_Texture **texture)
|
||||
break;
|
||||
case DXGI_FORMAT_P010:
|
||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_FORMAT_NUMBER, SDL_PIXELFORMAT_P010);
|
||||
HDR_video = SDL_TRUE;
|
||||
break;
|
||||
case DXGI_FORMAT_P016:
|
||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_FORMAT_NUMBER, SDL_PIXELFORMAT_P016);
|
||||
HDR_video = SDL_TRUE;
|
||||
break;
|
||||
default:
|
||||
/* This should be checked above */
|
||||
@@ -675,6 +681,20 @@ static SDL_bool GetTextureForD3D11Frame(AVFrame *frame, SDL_Texture **texture)
|
||||
if (!*texture) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (HDR_video != HDR_display) {
|
||||
/* Use some reasonable assumptions for white levels */
|
||||
if (HDR_display) {
|
||||
display_white_level = 200.0f; /* SDR white level */
|
||||
video_white_level = 80.0f;
|
||||
} else {
|
||||
display_white_level = 80.0f;
|
||||
video_white_level = 400.0f;
|
||||
}
|
||||
SDL_SetRenderColorScale(renderer, display_white_level / video_white_level);
|
||||
} else {
|
||||
SDL_SetRenderColorScale(renderer, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
ID3D11Resource *dx11_resource = SDL_GetProperty(SDL_GetTextureProperties(*texture), SDL_PROP_TEXTURE_D3D11_TEXTURE_POINTER, NULL);
|
||||
|
||||
Reference in New Issue
Block a user