backends/drm: support arbitrary input transfer functions in the icc shader
This commit is contained in:
parent
50717a2f9a
commit
5b86dba6bf
7 changed files with 28 additions and 6 deletions
|
@ -183,7 +183,7 @@ bool EglGbmLayerSurface::endRendering(const QRegion &damagedRegion, OutputFrame
|
||||||
GLFramebuffer::pushFramebuffer(fbo);
|
GLFramebuffer::pushFramebuffer(fbo);
|
||||||
ShaderBinder binder = m_surface->iccShader ? ShaderBinder(m_surface->iccShader->shader()) : ShaderBinder(ShaderTrait::MapTexture | ShaderTrait::TransformColorspace);
|
ShaderBinder binder = m_surface->iccShader ? ShaderBinder(m_surface->iccShader->shader()) : ShaderBinder(ShaderTrait::MapTexture | ShaderTrait::TransformColorspace);
|
||||||
if (m_surface->iccShader) {
|
if (m_surface->iccShader) {
|
||||||
m_surface->iccShader->setUniforms(m_surface->iccProfile, m_surface->intermediaryColorDescription.referenceLuminance(), m_surface->channelFactors);
|
m_surface->iccShader->setUniforms(m_surface->iccProfile, m_surface->intermediaryColorDescription, m_surface->channelFactors);
|
||||||
} else {
|
} else {
|
||||||
QMatrix4x4 ctm;
|
QMatrix4x4 ctm;
|
||||||
ctm(0, 0) = m_surface->channelFactors.x();
|
ctm(0, 0) = m_surface->channelFactors.x();
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
// SPDX-FileCopyrightText: 2023 Xaver Hugl <xaver.hugl@gmail.com>
|
// SPDX-FileCopyrightText: 2023 Xaver Hugl <xaver.hugl@gmail.com>
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
#include "colormanagement.glsl"
|
||||||
precision highp float;
|
precision highp float;
|
||||||
precision highp sampler2D;
|
precision highp sampler2D;
|
||||||
precision highp sampler3D;
|
precision highp sampler3D;
|
||||||
|
@ -7,7 +8,6 @@ precision highp sampler3D;
|
||||||
in vec2 texcoord0;
|
in vec2 texcoord0;
|
||||||
|
|
||||||
uniform sampler2D src;
|
uniform sampler2D src;
|
||||||
uniform float referenceLuminance;
|
|
||||||
|
|
||||||
uniform mat4 toXYZD50;
|
uniform mat4 toXYZD50;
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@ vec3 sample1DLut(vec3 input, sampler2D lut, int lutSize) {
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec4 tex = texture2D(src, texcoord0);
|
vec4 tex = texture2D(src, texcoord0);
|
||||||
|
tex = encodingToNits(tex, sourceNamedTransferFunction);
|
||||||
tex.rgb /= max(tex.a, 0.001);
|
tex.rgb /= max(tex.a, 0.001);
|
||||||
tex.rgb /= referenceLuminance;
|
tex.rgb /= referenceLuminance;
|
||||||
tex.rgb = (toXYZD50 * vec4(tex.rgb, 1.0)).rgb;
|
tex.rgb = (toXYZD50 * vec4(tex.rgb, 1.0)).rgb;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#version 140
|
#version 140
|
||||||
// SPDX-FileCopyrightText: 2023 Xaver Hugl <xaver.hugl@gmail.com>
|
// SPDX-FileCopyrightText: 2023 Xaver Hugl <xaver.hugl@gmail.com>
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
#include "colormanagement.glsl"
|
||||||
precision highp float;
|
precision highp float;
|
||||||
precision highp sampler2D;
|
precision highp sampler2D;
|
||||||
precision highp sampler3D;
|
precision highp sampler3D;
|
||||||
|
@ -10,7 +11,6 @@ in vec2 texcoord0;
|
||||||
out vec4 fragColor;
|
out vec4 fragColor;
|
||||||
|
|
||||||
uniform sampler2D src;
|
uniform sampler2D src;
|
||||||
uniform float referenceLuminance;
|
|
||||||
|
|
||||||
uniform mat4 toXYZD50;
|
uniform mat4 toXYZD50;
|
||||||
|
|
||||||
|
@ -40,6 +40,7 @@ vec3 sample1DLut(in vec3 srcColor, in sampler2D lut, in int lutSize) {
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec4 tex = texture(src, texcoord0);
|
vec4 tex = texture(src, texcoord0);
|
||||||
|
tex = encodingToNits(tex, sourceNamedTransferFunction);
|
||||||
tex.rgb /= max(tex.a, 0.001);
|
tex.rgb /= max(tex.a, 0.001);
|
||||||
tex.rgb /= referenceLuminance;
|
tex.rgb /= referenceLuminance;
|
||||||
tex.rgb = (toXYZD50 * vec4(tex.rgb, 1.0)).rgb;
|
tex.rgb = (toXYZD50 * vec4(tex.rgb, 1.0)).rgb;
|
||||||
|
|
|
@ -22,6 +22,7 @@ IccShader::IccShader()
|
||||||
{
|
{
|
||||||
m_locations = {
|
m_locations = {
|
||||||
.src = m_shader->uniformLocation("src"),
|
.src = m_shader->uniformLocation("src"),
|
||||||
|
.sourceNamedTransferFunction = m_shader->uniformLocation("sourceNamedTransferFunction"),
|
||||||
.referenceLuminance = m_shader->uniformLocation("referenceLuminance"),
|
.referenceLuminance = m_shader->uniformLocation("referenceLuminance"),
|
||||||
.toXYZD50 = m_shader->uniformLocation("toXYZD50"),
|
.toXYZD50 = m_shader->uniformLocation("toXYZD50"),
|
||||||
.bsize = m_shader->uniformLocation("Bsize"),
|
.bsize = m_shader->uniformLocation("Bsize"),
|
||||||
|
@ -145,7 +146,7 @@ GLShader *IccShader::shader() const
|
||||||
return m_shader.get();
|
return m_shader.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void IccShader::setUniforms(const std::shared_ptr<IccProfile> &profile, float referenceLuminance, const QVector3D &channelFactors)
|
void IccShader::setUniforms(const std::shared_ptr<IccProfile> &profile, const ColorDescription &inputColor, const QVector3D &channelFactors)
|
||||||
{
|
{
|
||||||
// this failing can be silently ignored, it should only happen with GPU resets and gets corrected later
|
// this failing can be silently ignored, it should only happen with GPU resets and gets corrected later
|
||||||
setProfile(profile);
|
setProfile(profile);
|
||||||
|
@ -155,7 +156,8 @@ void IccShader::setUniforms(const std::shared_ptr<IccProfile> &profile, float re
|
||||||
nightColor(1, 1) = channelFactors.y();
|
nightColor(1, 1) = channelFactors.y();
|
||||||
nightColor(2, 2) = channelFactors.z();
|
nightColor(2, 2) = channelFactors.z();
|
||||||
m_shader->setUniform(m_locations.toXYZD50, m_toXYZD50 * nightColor);
|
m_shader->setUniform(m_locations.toXYZD50, m_toXYZD50 * nightColor);
|
||||||
m_shader->setUniform(m_locations.referenceLuminance, referenceLuminance);
|
m_shader->setUniform(m_locations.sourceNamedTransferFunction, inputColor.transferFunction().type);
|
||||||
|
m_shader->setUniform(m_locations.referenceLuminance, inputColor.referenceLuminance());
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
if (m_B) {
|
if (m_B) {
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
SPDX-License-Identifier: GPL-2.0-or-later
|
SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include "core/colorspace.h"
|
||||||
|
|
||||||
#include <QMatrix4x4>
|
#include <QMatrix4x4>
|
||||||
#include <QSizeF>
|
#include <QSizeF>
|
||||||
|
@ -25,7 +26,7 @@ public:
|
||||||
~IccShader();
|
~IccShader();
|
||||||
|
|
||||||
GLShader *shader() const;
|
GLShader *shader() const;
|
||||||
void setUniforms(const std::shared_ptr<IccProfile> &profile, float referenceLuminance, const QVector3D &channelFactors);
|
void setUniforms(const std::shared_ptr<IccProfile> &profile, const ColorDescription &inputColor, const QVector3D &channelFactors);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool setProfile(const std::shared_ptr<IccProfile> &profile);
|
bool setProfile(const std::shared_ptr<IccProfile> &profile);
|
||||||
|
@ -42,6 +43,7 @@ private:
|
||||||
struct Locations
|
struct Locations
|
||||||
{
|
{
|
||||||
int src;
|
int src;
|
||||||
|
int sourceNamedTransferFunction;
|
||||||
int referenceLuminance;
|
int referenceLuminance;
|
||||||
int toXYZD50;
|
int toXYZD50;
|
||||||
int bsize;
|
int bsize;
|
||||||
|
|
|
@ -307,6 +307,12 @@ bool GLShader::setUniform(const char *name, float value)
|
||||||
return setUniform(location, value);
|
return setUniform(location, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GLShader::setUniform(const char *name, double value)
|
||||||
|
{
|
||||||
|
const int location = uniformLocation(name);
|
||||||
|
return setUniform(location, value);
|
||||||
|
}
|
||||||
|
|
||||||
bool GLShader::setUniform(const char *name, int value)
|
bool GLShader::setUniform(const char *name, int value)
|
||||||
{
|
{
|
||||||
const int location = uniformLocation(name);
|
const int location = uniformLocation(name);
|
||||||
|
@ -357,6 +363,14 @@ bool GLShader::setUniform(int location, float value)
|
||||||
return (location >= 0);
|
return (location >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GLShader::setUniform(int location, double value)
|
||||||
|
{
|
||||||
|
if (location >= 0) {
|
||||||
|
glUniform1f(location, value);
|
||||||
|
}
|
||||||
|
return (location >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
bool GLShader::setUniform(int location, int value)
|
bool GLShader::setUniform(int location, int value)
|
||||||
{
|
{
|
||||||
if (location >= 0) {
|
if (location >= 0) {
|
||||||
|
|
|
@ -46,6 +46,7 @@ public:
|
||||||
int uniformLocation(const char *name);
|
int uniformLocation(const char *name);
|
||||||
|
|
||||||
bool setUniform(const char *name, float value);
|
bool setUniform(const char *name, float value);
|
||||||
|
bool setUniform(const char *name, double value);
|
||||||
bool setUniform(const char *name, int value);
|
bool setUniform(const char *name, int value);
|
||||||
bool setUniform(const char *name, const QVector2D &value);
|
bool setUniform(const char *name, const QVector2D &value);
|
||||||
bool setUniform(const char *name, const QVector3D &value);
|
bool setUniform(const char *name, const QVector3D &value);
|
||||||
|
@ -55,6 +56,7 @@ public:
|
||||||
bool setUniform(const char *name, const QColor &color);
|
bool setUniform(const char *name, const QColor &color);
|
||||||
|
|
||||||
bool setUniform(int location, float value);
|
bool setUniform(int location, float value);
|
||||||
|
bool setUniform(int location, double value);
|
||||||
bool setUniform(int location, int value);
|
bool setUniform(int location, int value);
|
||||||
bool setUniform(int location, int xValue, int yValue, int zValue);
|
bool setUniform(int location, int xValue, int yValue, int zValue);
|
||||||
bool setUniform(int location, const QVector2D &value);
|
bool setUniform(int location, const QVector2D &value);
|
||||||
|
|
Loading…
Reference in a new issue