diff options
Diffstat (limited to 'src/render')
| -rw-r--r-- | src/render/OpenGL.cpp | 50 | ||||
| -rw-r--r-- | src/render/OpenGL.hpp | 1 | ||||
| -rw-r--r-- | src/render/Renderer.cpp | 29 | ||||
| -rw-r--r-- | src/render/Shader.cpp | 1 | ||||
| -rw-r--r-- | src/render/Shader.hpp | 1 | ||||
| -rw-r--r-- | src/render/gl/GLElementRenderer.cpp | 25 | ||||
| -rw-r--r-- | src/render/gl/GLFramebuffer.cpp | 11 | ||||
| -rw-r--r-- | src/render/gl/GLFramebuffer.hpp | 6 | ||||
| -rw-r--r-- | src/render/pass/TexPassElement.hpp | 1 | ||||
| -rw-r--r-- | src/render/shaders/glsl/blur1.glsl | 8 | ||||
| -rw-r--r-- | src/render/shaders/glsl/blurFinish.glsl | 6 | ||||
| -rw-r--r-- | src/render/shaders/glsl/cm_helpers.glsl | 11 | ||||
| -rw-r--r-- | src/render/shaders/glsl/constants.h | 1 | ||||
| -rw-r--r-- | src/render/shaders/glsl/inner_glow.frag | 41 | ||||
| -rw-r--r-- | src/render/shaders/glsl/inner_glow.glsl | 55 | ||||
| -rw-r--r-- | src/render/shaders/glsl/quad.frag | 7 | ||||
| -rw-r--r-- | src/render/shaders/glsl/shadow.frag | 34 | ||||
| -rw-r--r-- | src/render/shaders/glsl/shadow.glsl | 58 | ||||
| -rw-r--r-- | src/render/shaders/glsl/tonemap.glsl | 25 |
19 files changed, 135 insertions, 236 deletions
diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 6bb04cfa..0a53442e 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -34,6 +34,7 @@ #include "../managers/screenshare/ScreenshareManager.hpp" #include "../notification/NotificationOverlay.hpp" #include "errorOverlay/Overlay.hpp" +#include "helpers/Color.hpp" #include "macros.hpp" #include "pass/TexPassElement.hpp" #include "pass/RectPassElement.hpp" @@ -758,6 +759,7 @@ void CHyprOpenGLImpl::begin(PHLMONITOR pMonitor, const CRegion& damage_, SP<IFra g_pHyprRenderer->bindFB(g_pHyprRenderer->m_renderData.pMonitor->resources()->getUnusedWorkBuffer()); m_offloadedFramebuffer = true; + GLFB(g_pHyprRenderer->m_renderData.currentFB)->clearAfterInvalidation(); g_pHyprRenderer->m_renderData.mainFB = g_pHyprRenderer->m_renderData.currentFB; g_pHyprRenderer->m_renderData.outFB = fb ? fb : dc<CHyprGLRenderer*>(g_pHyprRenderer.get())->m_currentRenderbuffer->getFB(); @@ -1062,6 +1064,19 @@ void CHyprOpenGLImpl::renderRectWithBlurInternal(const CBox& box, const CHyprCol renderRectWithDamageInternal(box, col, data); } +using ColorConversionKey = std::tuple<float, float, float, float, uint64_t>; +static std::map<ColorConversionKey, CHyprColor> colorConversionCache; + +static CHyprColor getConvertedColor(const CHyprColor& color) { + const auto targetId = g_pHyprRenderer->workBufferImageDescription()->id(); + const ColorConversionKey key = {color.r, color.g, color.b, color.a, targetId}; + if (colorConversionCache.contains(key)) + return colorConversionCache[key]; + const auto converted = convertColor(color, DEFAULT_SRGB_IMAGE_DESCRIPTION, g_pHyprRenderer->workBufferImageDescription()); + colorConversionCache[key] = converted; + return converted; +} + void CHyprOpenGLImpl::renderRectWithDamageInternal(const CBox& box, const CHyprColor& col, const SRectRenderData& data) { auto& m_renderData = g_pHyprRenderer->m_renderData; RASSERT((box.width > 0 && box.height > 0), "Tried to render rect with width/height < 0!"); @@ -1078,7 +1093,10 @@ void CHyprOpenGLImpl::renderRectWithDamageInternal(const CBox& box, const CHyprC shader->setUniformMatrix3fv(SHADER_PROJ, 1, GL_TRUE, glMatrix.getMatrix()); // premultiply the color as well as we don't work with straight alpha - shader->setUniformFloat4(SHADER_COLOR, col.r * col.a, col.g * col.a, col.b * col.a, col.a); + const auto premultiplied = CHyprColor(col.r * col.a, col.g * col.a, col.b * col.a, col.a); + const auto converted = getConvertedColor(premultiplied); + shader->setUniformFloat4(SHADER_COLOR, converted.r, converted.g, converted.b, converted.a); + shader->setUniformFloat4(SHADER_COLOR_SRGB, premultiplied.r, premultiplied.g, premultiplied.b, premultiplied.a); CBox transformedBox = box; transformedBox.transform(Math::wlTransformToHyprutils(Math::invertTransform(m_renderData.pMonitor->m_transform)), m_renderData.pMonitor->m_transformedSize.x, @@ -1298,7 +1316,7 @@ WP<CShader> CHyprOpenGLImpl::renderToFBInternal(SP<ITexture> tex, const STexture shaderFeatures &= ~SH_FEAT_RGBA; const auto surface = g_pHyprRenderer->m_renderData.surface; - const auto WORK_BUFFER_IMAGE_DESCRIPTION = g_pHyprRenderer->workBufferImageDescription(); + const auto WORK_BUFFER_IMAGE_DESCRIPTION = g_pHyprRenderer->m_renderData.pMonitor->workBufferImageDescription(); // chosenSdrEotf contains the valid eotf for this display @@ -1311,7 +1329,7 @@ WP<CShader> CHyprOpenGLImpl::renderToFBInternal(SP<ITexture> tex, const STexture return CImageDescription::from(surface->m_colorManagement->imageDescription()); if (data.cmBackToSRGB) - return g_pHyprRenderer->m_renderData.pMonitor->m_imageDescription; + return tex->m_imageDescription ? tex->m_imageDescription : WORK_BUFFER_IMAGE_DESCRIPTION; // otherwise, if we are CM'ing back into source, use chosen, because that's what our work buffer is in // the same applies to the final monitor CM @@ -1660,6 +1678,7 @@ SP<IFramebuffer> CHyprOpenGLImpl::blurFramebufferWithDamage(float a, CRegion* or static auto PBLEND = CConfigValue<Config::INTEGER>("render:use_shader_blur_blend"); PMIRRORSWAPFB->bind(); + GLFB(PMIRRORSWAPFB)->clearAfterInvalidation(); glActiveTexture(GL_TEXTURE0); @@ -1754,6 +1773,7 @@ SP<IFramebuffer> CHyprOpenGLImpl::blurFramebufferWithDamage(float a, CRegion* or // draw the things. // first draw is swap -> mirr PMIRRORFB->bind(); + GLFB(PMIRRORFB)->clearAfterInvalidation(); PMIRRORSWAPFB->getTexture()->bind(); // damage region will be scaled, make a temp @@ -2240,14 +2260,12 @@ void CHyprOpenGLImpl::renderRoundedShadow(const CBox& box, int round, float roun blend(true); - const bool IS_ICC = g_pHyprRenderer->workBufferImageDescription()->value().icc.present; - const bool skipCM = !m_cmSupported || !g_pHyprRenderer->workBufferImageDescription()->needsCM(getDefaultImageDescription()); - auto shader = useShader(getShaderVariant(SH_FRAG_SHADOW, skipCM ? 0 : SH_FEAT_CM | (IS_ICC ? SH_FEAT_ICC : SH_FEAT_TONEMAP | SH_FEAT_SDR_MOD) | globalFeatures())); - if (!skipCM) - passCMUniforms(shader, getDefaultImageDescription()); + auto shader = useShader(getShaderVariant(SH_FRAG_SHADOW, globalFeatures())); shader->setUniformMatrix3fv(SHADER_PROJ, 1, GL_TRUE, glMatrix.getMatrix()); - shader->setUniformFloat4(SHADER_COLOR, col.r, col.g, col.b, col.a * a); + const auto converted = getConvertedColor(col); + shader->setUniformFloat4(SHADER_COLOR, converted.r, converted.g, converted.b, converted.a * a); + shader->setUniformFloat4(SHADER_COLOR_SRGB, col.r, col.g, col.b, col.a * a); const auto TOPLEFT = Vector2D(range + round, range + round); const auto BOTTOMRIGHT = Vector2D(newBox.width - (range + round), newBox.height - (range + round)); @@ -2334,14 +2352,12 @@ void CHyprOpenGLImpl::renderInnerGlow(const CBox& box, int round, float rounding blend(true); - const bool IS_ICC = g_pHyprRenderer->workBufferImageDescription()->value().icc.present; - const bool skipCM = !m_cmSupported || !g_pHyprRenderer->workBufferImageDescription()->needsCM(getDefaultImageDescription()); - auto shader = useShader(getShaderVariant(SH_FRAG_INNER_GLOW, skipCM ? 0 : SH_FEAT_CM | (IS_ICC ? SH_FEAT_ICC : SH_FEAT_TONEMAP | SH_FEAT_SDR_MOD))); - if (!skipCM) - passCMUniforms(shader, getDefaultImageDescription()); + auto shader = useShader(getShaderVariant(SH_FRAG_INNER_GLOW, globalFeatures())); shader->setUniformMatrix3fv(SHADER_PROJ, 1, GL_TRUE, glMatrix.getMatrix()); - shader->setUniformFloat4(SHADER_COLOR, col.r, col.g, col.b, col.a * a); + const auto converted = getConvertedColor(col); + shader->setUniformFloat4(SHADER_COLOR, converted.r, converted.g, converted.b, converted.a * a); + shader->setUniformFloat4(SHADER_COLOR_SRGB, col.r, col.g, col.b, col.a * a); const auto TOPLEFT = Vector2D(round, round); const auto BOTTOMRIGHT = Vector2D(newBox.width - round, newBox.height - round); @@ -2385,7 +2401,8 @@ void CHyprOpenGLImpl::saveBufferForMirror(const CBox& box) { Log::logger->log(Log::ERR, "Invalid source texture for mirror"); return; } - auto guard = g_pHyprRenderer->bindTempFB(g_pHyprRenderer->m_renderData.pMonitor->resources()->mirrorFB()); + auto fb = g_pHyprRenderer->m_renderData.pMonitor->resources()->mirrorFB(); + auto guard = g_pHyprRenderer->bindTempFB(fb); Log::logger->log(Log::TRACE, "CM: saveBufferForMirror {} -> {}", TEX->m_imageDescription->value(), g_pHyprRenderer->m_renderData.currentFB->imageDescription()->value()); @@ -2398,7 +2415,6 @@ void CHyprOpenGLImpl::saveBufferForMirror(const CBox& box) { .round = 0, .discardActive = false, .allowCustomUV = false, - .cmBackToSRGB = true, }); blend(true); diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index 82b8f054..2434c0ed 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -174,7 +174,6 @@ namespace Render::GL { GLenum wrapX = GL_CLAMP_TO_EDGE, wrapY = GL_CLAMP_TO_EDGE; bool cmBackToSRGB = false; bool finalMonitorCM = false; - SP<CMonitor> cmBackToSRGBSource; uint32_t discardMode = DISCARD_OPAQUE; float discardOpacity = 0.f; diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 635bef55..0cb713f1 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -2020,18 +2020,8 @@ void IHyprRenderer::renderMonitor(PHLMONITOR pMonitor, bool commit) { } handleFullscreenSettings(pMonitor); return; - } else if (!pMonitor->m_lastScanout.expired() || pMonitor->m_directScanoutIsActive) { - Log::logger->log(Log::DEBUG, "Left a direct scanout."); - pMonitor->m_lastScanout.reset(); - pMonitor->m_previousFSWindow.reset(); // recalc fs settings - pMonitor->m_directScanoutIsActive = false; - - // reset DRM format, but only if needed since it might modeset - if (pMonitor->m_output->state->state().drmFormat != pMonitor->m_prevDrmFormat) - pMonitor->m_output->state->setFormat(pMonitor->m_prevDrmFormat); - - pMonitor->m_drmFormat = pMonitor->m_prevDrmFormat; - } + } else if (!pMonitor->m_lastScanout.expired() || pMonitor->m_directScanoutIsActive) + pMonitor->handleDSleave(); } Event::bus()->m_events.render.pre.emit(pMonitor); @@ -3049,6 +3039,7 @@ void IHyprRenderer::makeSnapshot(PHLWINDOW pWindow) { const auto PFRAMEBUFFER = ref->m_snapshotFB; PFRAMEBUFFER->alloc(PMONITOR->m_pixelSize.x, PMONITOR->m_pixelSize.y, DRM_FORMAT_ABGR8888); + PFRAMEBUFFER->setImageDescription(workBufferImageDescription()); beginFullFakeRender(PMONITOR, fakeDamage, PFRAMEBUFFER); @@ -3090,6 +3081,7 @@ void IHyprRenderer::makeSnapshot(PHLLS pLayer) { const auto PFRAMEBUFFER = pLayer->m_snapshotFB; PFRAMEBUFFER->alloc(PMONITOR->m_pixelSize.x, PMONITOR->m_pixelSize.y, DRM_FORMAT_ABGR8888); + PFRAMEBUFFER->setImageDescription(workBufferImageDescription()); beginFullFakeRender(PMONITOR, fakeDamage, PFRAMEBUFFER); @@ -3132,6 +3124,7 @@ void IHyprRenderer::makeSnapshot(WP<Desktop::View::CPopup> popup) { const auto PFRAMEBUFFER = popup->m_snapshotFB; PFRAMEBUFFER->alloc(PMONITOR->m_pixelSize.x, PMONITOR->m_pixelSize.y, DRM_FORMAT_ABGR8888); + PFRAMEBUFFER->setImageDescription(workBufferImageDescription()); beginFullFakeRender(PMONITOR, fakeDamage, PFRAMEBUFFER); @@ -3314,14 +3307,10 @@ void IHyprRenderer::renderSnapshot(WP<Desktop::View::CPopup> popup) { } NColorManagement::PImageDescription IHyprRenderer::workBufferImageDescription() { - // TODO - // const bool IS_MONITOR_ICC = m_renderData.pMonitor->m_imageDescription.valid() && m_renderData.pMonitor->m_imageDescription->value().icc.present; - // const auto sdrEOTF = NTransferFunction::fromConfig(IS_MONITOR_ICC); - // const auto CHOSEN_SDR_EOTF = sdrEOTF != NTransferFunction::TF_SRGB ? NColorManagement::CM_TRANSFER_FUNCTION_GAMMA22 : NColorManagement::CM_TRANSFER_FUNCTION_SRGB; - - return m_renderData.pMonitor->useFP16() ? - LINEAR_IMAGE_DESCRIPTION : - m_renderData.pMonitor->m_imageDescription; //CImageDescription::from(NColorManagement::SImageDescription{.transferFunction = CHOSEN_SDR_EOTF}); + if (!m_renderData.pMonitor) + return LINEAR_IMAGE_DESCRIPTION; + + return m_renderData.pMonitor->workBufferImageDescription(); } bool IHyprRenderer::shouldBlur(PHLLS ls) { diff --git a/src/render/Shader.cpp b/src/render/Shader.cpp index 3359de66..8a7b8ba9 100644 --- a/src/render/Shader.cpp +++ b/src/render/Shader.cpp @@ -126,6 +126,7 @@ void CShader::getUniformLocations() { m_uniformLocations[SHADER_PROJ] = getUniform("proj"); m_uniformLocations[SHADER_COLOR] = getUniform("color"); + m_uniformLocations[SHADER_COLOR_SRGB] = getUniform("colorSRGB"); m_uniformLocations[SHADER_ALPHA_MATTE] = getUniform("texMatte"); m_uniformLocations[SHADER_TEX_TYPE] = getUniform("texType"); diff --git a/src/render/Shader.hpp b/src/render/Shader.hpp index 84a4014c..cf15c805 100644 --- a/src/render/Shader.hpp +++ b/src/render/Shader.hpp @@ -7,6 +7,7 @@ enum eShaderUniform : uint8_t { SHADER_PROJ = 0, SHADER_COLOR, + SHADER_COLOR_SRGB, SHADER_ALPHA_MATTE, SHADER_TEX_TYPE, SHADER_SOURCE_TF, diff --git a/src/render/gl/GLElementRenderer.cpp b/src/render/gl/GLElementRenderer.cpp index dbf62cb8..c20fffc0 100644 --- a/src/render/gl/GLElementRenderer.cpp +++ b/src/render/gl/GLElementRenderer.cpp @@ -114,19 +114,18 @@ void CGLElementRenderer::draw(WP<CTexPassElement> element, const CRegion& damage .blurredBG = m_data.blurredBG, // common settings - .damage = m_data.damage.empty() ? &damage : &m_data.damage, - .surface = m_data.surface, - .a = m_data.a, - .round = m_data.round, - .roundingPower = m_data.roundingPower, - .discardActive = m_data.discardActive, - .allowCustomUV = m_data.allowCustomUV, - .cmBackToSRGB = m_data.cmBackToSRGB, - .cmBackToSRGBSource = m_data.cmBackToSRGBSource, - .discardMode = m_data.ignoreAlpha.has_value() ? sc<uint32_t>(DISCARD_ALPHA) : m_data.discardMode, - .discardOpacity = m_data.ignoreAlpha.has_value() ? *m_data.ignoreAlpha : m_data.discardOpacity, - .clipRegion = m_data.clipRegion, - .currentLS = m_data.currentLS, + .damage = m_data.damage.empty() ? &damage : &m_data.damage, + .surface = m_data.surface, + .a = m_data.a, + .round = m_data.round, + .roundingPower = m_data.roundingPower, + .discardActive = m_data.discardActive, + .allowCustomUV = m_data.allowCustomUV, + .cmBackToSRGB = m_data.cmBackToSRGB, + .discardMode = m_data.ignoreAlpha.has_value() ? sc<uint32_t>(DISCARD_ALPHA) : m_data.discardMode, + .discardOpacity = m_data.ignoreAlpha.has_value() ? *m_data.ignoreAlpha : m_data.discardOpacity, + .clipRegion = m_data.clipRegion, + .currentLS = m_data.currentLS, .primarySurfaceUVTopLeft = g_pHyprRenderer->m_renderData.primarySurfaceUVTopLeft, .primarySurfaceUVBottomRight = g_pHyprRenderer->m_renderData.primarySurfaceUVBottomRight, diff --git a/src/render/gl/GLFramebuffer.cpp b/src/render/gl/GLFramebuffer.cpp index d8b198c3..196f3327 100644 --- a/src/render/gl/GLFramebuffer.cpp +++ b/src/render/gl/GLFramebuffer.cpp @@ -171,4 +171,15 @@ void CGLFramebuffer::invalidate(const std::vector<GLenum>& attachments) { return; glInvalidateFramebuffer(GL_FRAMEBUFFER, attachments.size(), attachments.data()); + m_cleared = false; +} + +void CGLFramebuffer::clearAfterInvalidation() { + if (m_cleared) + return; + + m_cleared = true; + glClearColor(0, 0, 0, 0); + g_pHyprOpenGL->scissor(nullptr); + glClear(GL_COLOR_BUFFER_BIT); } diff --git a/src/render/gl/GLFramebuffer.hpp b/src/render/gl/GLFramebuffer.hpp index 1be5d0e0..34051656 100644 --- a/src/render/gl/GLFramebuffer.hpp +++ b/src/render/gl/GLFramebuffer.hpp @@ -21,11 +21,15 @@ namespace Render::GL { GLuint getFBID(); void invalidate(const std::vector<GLenum>& attachments); + // clear at most once per invalidate() + void clearAfterInvalidation(); + protected: bool internalAlloc(int w, int h, DRMFormat format = DRM_FORMAT_ARGB8888) override; private: - GLuint m_fb = -1; + GLuint m_fb = -1; + bool m_cleared = false; friend class CGLRenderbuffer; }; diff --git a/src/render/pass/TexPassElement.hpp b/src/render/pass/TexPassElement.hpp index 6c0cfab1..413f9875 100644 --- a/src/render/pass/TexPassElement.hpp +++ b/src/render/pass/TexPassElement.hpp @@ -31,7 +31,6 @@ class CTexPassElement : public IPassElement { std::optional<float> ignoreAlpha; std::optional<bool> blockBlurOptimization; bool cmBackToSRGB = false; - SP<CMonitor> cmBackToSRGBSource; bool discardActive = false; bool allowCustomUV = false; diff --git a/src/render/shaders/glsl/blur1.glsl b/src/render/shaders/glsl/blur1.glsl index 86a37d88..8d9e39ae 100644 --- a/src/render/shaders/glsl/blur1.glsl +++ b/src/render/shaders/glsl/blur1.glsl @@ -104,10 +104,10 @@ vec4 blur1(vec2 v_texcoord, sampler2D tex, float radius, vec2 halfpixel, int pas // That garbage maps to 0.0-1.0 range with UINT8 buffer and doesn't have any significant impact on the end result. // FP16 garbage maps to -65,504 - 65,504 and defines the end result. Clamp it here to 0.0 - 1.0 to get the same quality outcome as with UINT8. // Rerendering an undamaged area to get some insignificant color accuracy increase on blur edges isn't worth it. - sum += clamp(texture(tex, uv - halfpixel.xy * radius), 0.0, 1.0); - sum += clamp(texture(tex, uv + halfpixel.xy * radius), 0.0, 1.0); - sum += clamp(texture(tex, uv + vec2(halfpixel.x, -halfpixel.y) * radius), 0.0, 1.0); - sum += clamp(texture(tex, uv - vec2(halfpixel.x, -halfpixel.y) * radius), 0.0, 1.0); + sum += texture(tex, uv - halfpixel.xy * radius); + sum += texture(tex, uv + halfpixel.xy * radius); + sum += texture(tex, uv + vec2(halfpixel.x, -halfpixel.y) * radius); + sum += texture(tex, uv - vec2(halfpixel.x, -halfpixel.y) * radius); vec4 color = sum / 8.0; diff --git a/src/render/shaders/glsl/blurFinish.glsl b/src/render/shaders/glsl/blurFinish.glsl index e7e1f1c6..bdfe2bc8 100644 --- a/src/render/shaders/glsl/blurFinish.glsl +++ b/src/render/shaders/glsl/blurFinish.glsl @@ -30,7 +30,11 @@ vec4 blurFinish(vec4 pixColor, vec2 v_texcoord, float noise, float brightness pixColor.rgb *= min(1.0, brightness); #if USE_CM - pixColor = doColorManagement(pixColor, sourceTF, targetTF, convertMatrix, srcTFRange, dstTFRange); + if (targetTF == CM_TRANSFER_FUNCTION_EXT_LINEAR) { + pixColor = doColorManagement(pixColor, sourceTF, targetTF, convertMatrix, srcTFRange, vec2(0.0, 203.0)); // FIXME wtf + } else { + pixColor = doColorManagement(pixColor, sourceTF, targetTF, convertMatrix, srcTFRange, dstTFRange); + } #endif return pixColor; diff --git a/src/render/shaders/glsl/cm_helpers.glsl b/src/render/shaders/glsl/cm_helpers.glsl index 0d8c68e9..ae4b63ae 100644 --- a/src/render/shaders/glsl/cm_helpers.glsl +++ b/src/render/shaders/glsl/cm_helpers.glsl @@ -127,6 +127,7 @@ vec3 tfST240(vec3 color) { vec3 toLinearRGB(vec3 color, int tf) { switch (tf) { + case CM_TRANSFER_FUNCTION_LINEAR: return color; case CM_TRANSFER_FUNCTION_EXT_LINEAR: return color; case CM_TRANSFER_FUNCTION_ST2084_PQ: return tfInvPQ(color); case CM_TRANSFER_FUNCTION_GAMMA22: return pow(max(color, vec3(0.0)), vec3(2.2)); @@ -179,7 +180,7 @@ vec3 fromLinearRGB(vec3 color, int tf) { } vec4 fromLinear(vec4 color, int tf) { - if (tf == CM_TRANSFER_FUNCTION_EXT_LINEAR) + if (tf == CM_TRANSFER_FUNCTION_EXT_LINEAR || tf == CM_TRANSFER_FUNCTION_LINEAR) return color; color.rgb /= max(color.a, 0.001); @@ -189,6 +190,9 @@ vec4 fromLinear(vec4 color, int tf) { } vec4 fromLinearNit(vec4 color, int tf, vec2 range) { + if (tf == CM_TRANSFER_FUNCTION_LINEAR) + return color; + color.rgb = (color.rgb - range[0] * color.a) / (range[1] - range[0]); // @gulafaran color.rgb /= max(color.a, 0.001); color.rgb = fromLinearRGB(color.rgb, tf); @@ -231,7 +235,8 @@ vec4 pixColor.rgb *= pixColor.a; #else pixColor.rgb = convertMatrix * pixColor.rgb; - pixColor = toNit(pixColor, srcTFRange); + if (srcTF != CM_TRANSFER_FUNCTION_LINEAR) + pixColor = toNit(pixColor, srcTFRange); pixColor.rgb *= pixColor.a; #if USE_TONEMAP pixColor = tonemap(pixColor, dstxyz, maxLuminance, dstMaxLuminance, dstRefLuminance, srcRefLuminance); @@ -258,4 +263,4 @@ vec4 #endif } -#endif
\ No newline at end of file +#endif diff --git a/src/render/shaders/glsl/constants.h b/src/render/shaders/glsl/constants.h index bbab5284..db8b2cc1 100644 --- a/src/render/shaders/glsl/constants.h +++ b/src/render/shaders/glsl/constants.h @@ -1,6 +1,7 @@ #ifndef CONSTANTS_H #define CONSTANTS_H //enum eTransferFunction +#define CM_TRANSFER_FUNCTION_LINEAR 0 // not normalised #define CM_TRANSFER_FUNCTION_BT1886 1 #define CM_TRANSFER_FUNCTION_GAMMA22 2 #define CM_TRANSFER_FUNCTION_GAMMA28 3 diff --git a/src/render/shaders/glsl/inner_glow.frag b/src/render/shaders/glsl/inner_glow.frag index 2fc405c0..63369e0a 100644 --- a/src/render/shaders/glsl/inner_glow.frag +++ b/src/render/shaders/glsl/inner_glow.frag @@ -8,10 +8,7 @@ precision highp float; in vec4 v_color; in vec2 v_texcoord; -uniform int sourceTF; // eTransferFunction -uniform int targetTF; // eTransferFunction -uniform mat3 targetPrimariesXYZ; - +uniform vec4 colorSRGB; uniform vec2 topLeft; uniform vec2 bottomRight; uniform vec2 fullSize; @@ -20,38 +17,22 @@ uniform float roundingPower; uniform float range; uniform float shadowPower; -#if USE_CM -#include "cm_helpers.glsl" -#include "CM.glsl" -#endif - #include "inner_glow.glsl" layout(location = 0) out vec4 fragColor; +#if USE_MIRROR +layout(location = 1) out vec4 mirrorColor; +#endif void main() { vec4 pixColor = v_color; - - fragColor = getInnerGlow(pixColor, v_texcoord, radius, roundingPower, topLeft, fullSize, range, shadowPower, bottomRight -#if USE_CM - , - sourceTF, targetTF, convertMatrix, srcTFRange, dstTFRange -#if USE_ICC - , - iccLut3D, iccLutSize +#if USE_MIRROR + vec4[2] pixColors = #else -#if USE_TONEMAP || USE_SDR_MOD - , - targetPrimariesXYZ -#endif -#if USE_TONEMAP - , - maxLuminance, dstMaxLuminance, dstRefLuminance, srcRefLuminance -#endif -#if USE_SDR_MOD - , - sdrSaturation, sdrBrightnessMultiplier -#endif + fragColor = #endif + getInnerGlow(pixColor, colorSRGB, v_texcoord, radius, roundingPower, topLeft, fullSize, range, shadowPower, bottomRight); +#if USE_MIRROR + fragColor = pixColors[0]; + mirrorColor = pixColors[1]; #endif - ); } diff --git a/src/render/shaders/glsl/inner_glow.glsl b/src/render/shaders/glsl/inner_glow.glsl index b0d55b19..307c3648 100644 --- a/src/render/shaders/glsl/inner_glow.glsl +++ b/src/render/shaders/glsl/inner_glow.glsl @@ -5,8 +5,6 @@ #ifndef INNER_GLOW_GLSL #define INNER_GLOW_GLSL -#include "cm_helpers.glsl" - float innerGlowAlpha(float distFromEdge, float range, float glowPower) { if (distFromEdge >= range) return 0.0; @@ -26,29 +24,7 @@ float innerGlowSmin(float a, float b, float k) { return min(a, b) - h * h * h * k * (1.0 / 6.0); } -vec4 getInnerGlow(vec4 pixColor, vec2 v_texcoord, float radius, float roundingPower, vec2 topLeft, vec2 fullSize, float range, float glowPower, vec2 bottomRight -#if USE_CM - , - int sourceTF, int targetTF, mat3 convertMatrix, vec2 srcTFRange, vec2 dstTFRange -#if USE_ICC - , - highp sampler3D iccLut3D, float iccLutSize -#else -#if USE_TONEMAP || USE_SDR_MOD - , - mat3 targetPrimariesXYZ -#endif -#if USE_TONEMAP - , - float maxLuminance, float dstMaxLuminance, float dstRefLuminance, float srcRefLuminance -#endif -#if USE_SDR_MOD - , - float sdrSaturation, float sdrBrightnessMultiplier -#endif -#endif -#endif -) { +vec4 getInnerGlow(vec4 pixColor, vec4 colorSRGB, vec2 v_texcoord, float radius, float roundingPower, vec2 topLeft, vec2 fullSize, float range, float glowPower, vec2 bottomRight) { vec2 pixCoord = fullSize * v_texcoord; // clip to the rounded rectangle shape using actual SDF @@ -79,28 +55,15 @@ vec4 getInnerGlow(vec4 pixColor, vec2 v_texcoord, float radius, float roundingPo // premultiply pixColor.rgb *= pixColor[3]; -#if USE_CM - pixColor = doColorManagement(pixColor, sourceTF, targetTF, convertMatrix, srcTFRange, dstTFRange -#if USE_ICC - , - iccLut3D, iccLutSize +#if USE_MIRROR + vec4[2] pixColors; + pixColors[0] = pixColor; + pixColors[1] = colorSRGB; + pixColors[1].a = pixColor.a; + pixColors[1].rgb *= pixColors[1].a; + return pixColors; #else -#if USE_TONEMAP || USE_SDR_MOD - , - targetPrimariesXYZ -#endif -#if USE_TONEMAP - , - maxLuminance, dstMaxLuminance, dstRefLuminance, srcRefLuminance -#endif -#if USE_SDR_MOD - , - sdrSaturation, sdrBrightnessMultiplier -#endif -#endif - ); -#endif - return pixColor; +#endif } #endif diff --git a/src/render/shaders/glsl/quad.frag b/src/render/shaders/glsl/quad.frag index dc1945af..46d42a8c 100644 --- a/src/render/shaders/glsl/quad.frag +++ b/src/render/shaders/glsl/quad.frag @@ -7,6 +7,7 @@ precision highp float; in vec4 v_color; +uniform vec4 colorSRGB; #if USE_ROUNDING uniform float radius; uniform float roundingPower; @@ -28,6 +29,10 @@ void main() { fragColor = pixColor; #if USE_MIRROR - mirrorColor = fragColor; +#if USE_ROUNDING + mirrorColor = rounding(colorSRGB, radius, roundingPower, topLeft, fullSize); +#else + mirrorColor = colorSRGB; +#endif #endif } diff --git a/src/render/shaders/glsl/shadow.frag b/src/render/shaders/glsl/shadow.frag index e91e9a14..eb6f3174 100644 --- a/src/render/shaders/glsl/shadow.frag +++ b/src/render/shaders/glsl/shadow.frag @@ -8,10 +8,7 @@ precision highp float; in vec4 v_color; in vec2 v_texcoord; -uniform int sourceTF; // eTransferFunction -uniform int targetTF; // eTransferFunction -uniform mat3 targetPrimariesXYZ; - +uniform vec4 colorSRGB; uniform vec2 topLeft; uniform vec2 bottomRight; uniform vec2 windowTopLeft; @@ -23,11 +20,6 @@ uniform float range; uniform float shadowPower; uniform float thick; -#if USE_CM -#include "cm_helpers.glsl" -#include "CM.glsl" -#endif - #include "shadow.glsl" layout(location = 0) out vec4 fragColor; @@ -41,29 +33,7 @@ void main() { #else fragColor = #endif - getShadow(pixColor, v_texcoord, radius, roundingPower, topLeft, fullSize, range, shadowPower, bottomRight, windowTopLeft, windowBottomRight, thick -#if USE_CM - , - sourceTF, targetTF, convertMatrix, srcTFRange, dstTFRange -#if USE_ICC - , - iccLut3D, iccLutSize -#else -#if USE_TONEMAP || USE_SDR_MOD - , - targetPrimariesXYZ -#endif -#if USE_TONEMAP - , - maxLuminance, dstMaxLuminance, dstRefLuminance, srcRefLuminance -#endif -#if USE_SDR_MOD - , - sdrSaturation, sdrBrightnessMultiplier -#endif -#endif -#endif - ); + getShadow(pixColor, colorSRGB, v_texcoord, radius, roundingPower, topLeft, fullSize, range, shadowPower, bottomRight, windowTopLeft, windowBottomRight, thick); #if USE_MIRROR fragColor = pixColors[0]; mirrorColor = pixColors[1]; diff --git a/src/render/shaders/glsl/shadow.glsl b/src/render/shaders/glsl/shadow.glsl index fdfa697c..ba68bc49 100644 --- a/src/render/shaders/glsl/shadow.glsl +++ b/src/render/shaders/glsl/shadow.glsl @@ -5,7 +5,6 @@ #ifndef SHADOW_GLSL #define SHADOW_GLSL -#include "cm_helpers.glsl" #include "rounding.glsl" float pixAlphaRoundedDistance(float distanceToCorner, float radius, float range, float shadowPower) { @@ -54,30 +53,8 @@ vec4[2] #else vec4 #endif - getShadow(vec4 pixColor, vec2 v_texcoord, float borderRadius, float roundingPower, vec2 topLeft, vec2 fullSize, float range, float shadowPower, vec2 bottomRight, - vec2 windowTopLeft, vec2 windowBottomRight, float windowRadius -#if USE_CM - , - int sourceTF, int targetTF, mat3 convertMatrix, vec2 srcTFRange, vec2 dstTFRange -#if USE_ICC - , - highp sampler3D iccLut3D, float iccLutSize -#else -#if USE_TONEMAP || USE_SDR_MOD - , - mat3 targetPrimariesXYZ -#endif -#if USE_TONEMAP - , - float maxLuminance, float dstMaxLuminance, float dstRefLuminance, float srcRefLuminance -#endif -#if USE_SDR_MOD - , - float sdrSaturation, float sdrBrightnessMultiplier -#endif -#endif -#endif - ) { + getShadow(vec4 pixColor, vec4 colorSRGB, vec2 v_texcoord, float borderRadius, float roundingPower, vec2 topLeft, vec2 fullSize, float range, float shadowPower, vec2 bottomRight, + vec2 windowTopLeft, vec2 windowBottomRight, float windowRadius) { float radius = range + borderRadius; float originalAlpha = pixColor[3]; @@ -144,33 +121,12 @@ vec4 // premultiply pixColor.rgb *= pixColor[3]; -#if USE_CM -#if USE_MIRROR - vec4[2] pixColors = -#else - pixColor = -#endif - doColorManagement(pixColor, sourceTF, targetTF, convertMatrix, srcTFRange, dstTFRange -#if USE_ICC - , - iccLut3D, iccLutSize -#else -#if USE_TONEMAP || USE_SDR_MOD - , - targetPrimariesXYZ -#endif -#if USE_TONEMAP - , - maxLuminance, dstMaxLuminance, dstRefLuminance, srcRefLuminance -#endif -#if USE_SDR_MOD - , - sdrSaturation, sdrBrightnessMultiplier -#endif -#endif - ); -#endif #if USE_MIRROR + vec4[2] pixColors; + pixColors[0] = pixColor; + pixColors[1] = colorSRGB; + pixColors[1].a = pixColor.a; + pixColors[1].rgb *= pixColors[1].a; return pixColors; #else return pixColor; diff --git a/src/render/shaders/glsl/tonemap.glsl b/src/render/shaders/glsl/tonemap.glsl index dcce45a6..a2db7e6e 100644 --- a/src/render/shaders/glsl/tonemap.glsl +++ b/src/render/shaders/glsl/tonemap.glsl @@ -50,21 +50,16 @@ vec4 tonemap(vec4 color, mat3 dstXYZ, float maxLuminance, float dstMaxLuminance, float E = pow(clamp(ICtCp[0], 0.0, 1.0), PQ_INV_M2); float luminance = pow((max(E - PQ_C1, 0.0)) / (PQ_C2 - PQ_C3 * E), PQ_INV_M1) * HDR_MAX_LUMINANCE; - float linearPart = min(luminance, dstRefLuminance); - float luminanceAboveRef = max(luminance - dstRefLuminance, 0.0); - float maxExcessLuminance = max(maxLuminance - dstRefLuminance, 1.0); - float shoulder = log((luminanceAboveRef / maxExcessLuminance + 1.0) * (M_E - 1.0)); - float mappedHigh = shoulder * (dstMaxLuminance - dstRefLuminance); - float newLum = clamp(linearPart + mappedHigh, 0.0, dstMaxLuminance); + float luminanceRatio = max(luminance / dstRefLuminance, 0.0); + float srcScale = maxLuminance / dstRefLuminance; + float dstScale = dstMaxLuminance / dstRefLuminance; + float v = (dstScale * (1.0 + srcScale) - srcScale) / pow(srcScale, 2.0); + float newLuminance = (luminanceRatio * (1.0 + luminanceRatio * v) / (1.0 + luminanceRatio)) * dstRefLuminance; - // scale src to dst reference - float refScale = dstRefLuminance / srcRefLuminance; + E = pow(clamp(newLuminance / HDR_MAX_LUMINANCE, 0.0, 1.0), PQ_M1); + ICtCp[0] = pow((PQ_C1 + PQ_C2 * E) / (1.0 + PQ_C3 * E), PQ_M2); - // kind of works but doesn't use newLum at all - return vec4(fromLMS * toLinear(vec4(ICtCpPQInv * ICtCp, 1.0), CM_TRANSFER_FUNCTION_ST2084_PQ).rgb * HDR_MAX_LUMINANCE * refScale, color[3]); - // breaks with overriden monitor luminances. might be caused by incorrect imput values - // @gulafaran - // vec3 outRGB = fromLMS * toLinear(vec4(ICtCpPQInv * ICtCp, 1.0), CM_TRANSFER_FUNCTION_ST2084_PQ).rgb; - // outRGB *= (newLum / max(luminance, 0.0001)); // actually apply the tone mapping - // return vec4(clamp(outRGB * HDR_MAX_LUMINANCE * refScale, 0.0, dstMaxLuminance), color[3]); + color = vec4(fromLMS * toLinear(vec4(ICtCpPQInv * ICtCp, 1.0), CM_TRANSFER_FUNCTION_ST2084_PQ).rgb * HDR_MAX_LUMINANCE, color[3]); + + return clamp(color, 0.0, dstMaxLuminance); } |
