texture image descriptions

This commit is contained in:
UjinT34 2026-03-09 14:25:24 +03:00
parent ed53cf4501
commit 57d602bbdf
10 changed files with 52 additions and 33 deletions

View file

@ -453,7 +453,6 @@ void IElementRenderer::drawTex(WP<CTexPassElement> element, const CRegion& damag
m_renderData.renderModif.applyToRegion(inverseOpaque);
inverseOpaque.intersect(element->m_data.damage);
element->m_data.blurredBG = g_pHyprRenderer->blurMainFramebuffer(element->m_data.a, &inverseOpaque);
m_renderData.currentFB->bind();
} else
element->m_data.blurredBG = m_renderData.pMonitor->m_blurFB ? m_renderData.pMonitor->m_blurFB->getTexture() : nullptr;

View file

@ -61,7 +61,7 @@ bool CHyprGLRenderer::beginFullFakeRenderInternal(PHLMONITOR pMonitor, CRegion&
initRender();
RASSERT(fb, "Cannot render FULL_FAKE without a provided fb!");
fb->bind();
bindFB(fb);
if (simple)
g_pHyprOpenGL->beginSimple(pMonitor, damage, nullptr, fb);
else

View file

@ -676,8 +676,7 @@ void CHyprOpenGLImpl::beginSimple(PHLMONITOR pMonitor, const CRegion& damage, SP
m_fakeFrame = true;
g_pHyprRenderer->m_renderData.currentFB = FBO;
FBO->bind();
g_pHyprRenderer->bindFB(FBO);
m_offloadedFramebuffer = false;
g_pHyprRenderer->m_renderData.mainFB = g_pHyprRenderer->m_renderData.currentFB;
@ -738,9 +737,8 @@ void CHyprOpenGLImpl::begin(PHLMONITOR pMonitor, const CRegion& damage_, SP<IFra
applyScreenShader(*PSHADER);
}
g_pHyprRenderer->m_renderData.pMonitor->m_offloadFB->bind();
g_pHyprRenderer->m_renderData.currentFB = g_pHyprRenderer->m_renderData.pMonitor->m_offloadFB;
m_offloadedFramebuffer = true;
g_pHyprRenderer->bindFB(g_pHyprRenderer->m_renderData.pMonitor->m_offloadFB);
m_offloadedFramebuffer = true;
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();
@ -777,7 +775,7 @@ void CHyprOpenGLImpl::end() {
if UNLIKELY (g_pHyprRenderer->needsACopyFB(g_pHyprRenderer->m_renderData.pMonitor.lock()) && !m_fakeFrame)
saveBufferForMirror(monbox);
g_pHyprRenderer->m_renderData.outFB->bind();
g_pHyprRenderer->bindFB(g_pHyprRenderer->m_renderData.outFB);
blend(false);
const auto PRIMITIVE_BLOCKED = m_finalScreenShader->program() >= 1 || g_pHyprRenderer->m_crashingInProgress ||
@ -1026,16 +1024,14 @@ void CHyprOpenGLImpl::renderRectWithBlurInternal(const CBox& box, const CHyprCol
CRegion damage{g_pHyprRenderer->m_renderData.damage};
damage.intersect(box);
auto POUTFB = data.xray ? (g_pHyprRenderer->m_renderData.pMonitor->m_blurFB ? g_pHyprRenderer->m_renderData.pMonitor->m_blurFB->getTexture() : nullptr) :
g_pHyprRenderer->blurMainFramebuffer(data.blurA, &damage);
g_pHyprRenderer->m_renderData.currentFB->bind();
auto blurredBG = data.xray ? (g_pHyprRenderer->m_renderData.pMonitor->m_blurFB ? g_pHyprRenderer->m_renderData.pMonitor->m_blurFB->getTexture() : nullptr) :
g_pHyprRenderer->blurMainFramebuffer(data.blurA, &damage);
CBox MONITORBOX = {0, 0, g_pHyprRenderer->m_renderData.pMonitor->m_transformedSize.x, g_pHyprRenderer->m_renderData.pMonitor->m_transformedSize.y};
g_pHyprRenderer->pushMonitorTransformEnabled(true);
const auto SAVEDRENDERMODIF = g_pHyprRenderer->m_renderData.renderModif;
g_pHyprRenderer->m_renderData.renderModif = {}; // fix shit
renderTexture(POUTFB, MONITORBOX,
renderTexture(blurredBG, MONITORBOX,
STextureRenderData{.damage = &damage, .a = data.blurA, .round = data.round, .roundingPower = 2.F, .allowCustomUV = false, .allowDim = false, .noAA = false});
g_pHyprRenderer->popMonitorTransformEnabled();
g_pHyprRenderer->m_renderData.renderModif = SAVEDRENDERMODIF;
@ -1261,7 +1257,7 @@ WP<CShader> CHyprOpenGLImpl::renderToOutputInternal() {
return shader;
}
WP<CShader> CHyprOpenGLImpl::renderToFBInternal(const STextureRenderData& data, eTextureType texType, const CBox& newBox) {
WP<CShader> CHyprOpenGLImpl::renderToFBInternal(SP<ITexture> tex, const STextureRenderData& data, eTextureType texType, const CBox& newBox) {
static const auto PPASS = CConfigValue<Hyprlang::INT>("render:cm_fs_passthrough");
static const auto PENABLECM = CConfigValue<Hyprlang::INT>("render:cm_enabled");
static auto PBLEND = CConfigValue<Hyprlang::INT>("render:use_shader_blur_blend");
@ -1294,13 +1290,19 @@ WP<CShader> CHyprOpenGLImpl::renderToFBInternal(const STextureRenderData& data,
// chosenSdrEotf contains the valid eotf for this display
const auto SOURCE_IMAGE_DESCRIPTION = [&] {
if (tex->m_imageDescription)
return tex->m_imageDescription;
// if valid CM surface, use that as a source
if (g_pHyprRenderer->m_renderData.surface.valid() && g_pHyprRenderer->m_renderData.surface->m_colorManagement.valid())
return CImageDescription::from(g_pHyprRenderer->m_renderData.surface->m_colorManagement->imageDescription());
if (data.cmBackToSRGB)
return g_pHyprRenderer->m_renderData.pMonitor->m_imageDescription;
// 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
if (data.cmBackToSRGB || data.finalMonitorCM) // NOLINTNEXTLINE
if (data.finalMonitorCM) // NOLINTNEXTLINE
return WORK_BUFFER_IMAGE_DESCRIPTION;
// otherwise, default
@ -1308,6 +1310,9 @@ WP<CShader> CHyprOpenGLImpl::renderToFBInternal(const STextureRenderData& data,
}();
const auto TARGET_IMAGE_DESCRIPTION = [&] {
if (g_pHyprRenderer->m_renderData.currentFB->getTexture()->m_imageDescription)
return g_pHyprRenderer->m_renderData.currentFB->getTexture()->m_imageDescription;
// if we are CM'ing back, use default sRGB
if (data.cmBackToSRGB)
return DEFAULT_IMAGE_DESCRIPTION;
@ -1467,7 +1472,7 @@ void CHyprOpenGLImpl::renderTextureInternal(SP<ITexture> tex, const CBox& box, c
tex->setTexParameter(GL_TEXTURE_MIN_FILTER, tex->minFilter);
}
auto shader = renderToOutput ? renderToOutputInternal() : renderToFBInternal(data, tex->m_type, newBox);
auto shader = renderToOutput ? renderToOutputInternal() : renderToFBInternal(tex, data, tex->m_type, newBox);
shader->setUniformMatrix3fv(SHADER_PROJ, 1, GL_TRUE, glMatrix.getMatrix());
shader->setUniformInt(SHADER_TEX, 0);
@ -2280,7 +2285,7 @@ void CHyprOpenGLImpl::saveBufferForMirror(const CBox& box) {
g_pHyprRenderer->m_renderData.pMonitor->m_monitorMirrorFB->alloc(m_renderData.pMonitor->m_pixelSize.x, m_renderData.pMonitor->m_pixelSize.y,
m_renderData.pMonitor->m_output->state->state().drmFormat);
g_pHyprRenderer->m_renderData.pMonitor->m_monitorMirrorFB->bind();
auto guard = g_pHyprRenderer->bindTempFB(g_pHyprRenderer->m_renderData.pMonitor->m_monitorMirrorFB);
blend(false);
@ -2295,8 +2300,6 @@ void CHyprOpenGLImpl::saveBufferForMirror(const CBox& box) {
});
blend(true);
g_pHyprRenderer->m_renderData.currentFB->bind();
}
WP<CShader> CHyprOpenGLImpl::useShader(WP<CShader> prog) {

View file

@ -346,7 +346,7 @@ namespace Render::GL {
void renderRectWithBlurInternal(const CBox&, const CHyprColor&, const SRectRenderData& data);
void renderRectWithDamageInternal(const CBox&, const CHyprColor&, const SRectRenderData& data);
WP<CShader> renderToOutputInternal();
WP<CShader> renderToFBInternal(const STextureRenderData& data, eTextureType texType, const CBox& newBox);
WP<CShader> renderToFBInternal(SP<ITexture> tex, const STextureRenderData& data, eTextureType texType, const CBox& newBox);
void renderTextureInternal(SP<ITexture>, const CBox&, const STextureRenderData& data);
void renderTextureWithBlurInternal(SP<ITexture>, const CBox&, const STextureRenderData& data);

View file

@ -56,6 +56,7 @@
#include <hyprutils/math/Region.hpp>
#include <hyprutils/math/Vector2D.hpp>
#include <hyprutils/memory/SharedPtr.hpp>
#include <hyprutils/memory/UniquePtr.hpp>
#include <optional>
#include <pango/pangocairo.h>
@ -502,14 +503,12 @@ void IHyprRenderer::renderWorkspaceWindows(PHLMONITOR pMonitor, PHLWORKSPACE pWo
void IHyprRenderer::bindOffMain() {
RASSERT(m_renderData.pMonitor->m_offMainFB->isAllocated(), "IHyprRenderer::beginRender should allocate monitor FBs")
m_renderData.pMonitor->m_offMainFB->bind();
bindFB(m_renderData.pMonitor->m_offMainFB);
draw(CClearPassElement::SClearData{{0, 0, 0, 0}});
m_renderData.currentFB = m_renderData.pMonitor->m_offMainFB;
}
void IHyprRenderer::bindBackOnMain() {
m_renderData.mainFB->bind();
m_renderData.currentFB = m_renderData.mainFB;
bindFB(m_renderData.mainFB);
}
void IHyprRenderer::renderWindow(PHLWINDOW pWindow, PHLMONITOR pMonitor, const Time::steady_tp& time, bool decorate, eRenderPassMode mode, bool ignorePosition, bool standalone) {
@ -814,6 +813,17 @@ void IHyprRenderer::draw(const CTextureMatteElement::STextureMatteData& data, co
elementRenderer()->drawElement(makeUnique<CTextureMatteElement>(data), damage);
}
void IHyprRenderer::bindFB(SP<IFramebuffer> fb) {
fb->bind();
m_renderData.currentFB = fb;
}
UP<CScopeGuard> IHyprRenderer::bindTempFB(SP<IFramebuffer> fb) {
const auto oldFB = m_renderData.currentFB;
bindFB(fb);
return makeUnique<CScopeGuard>([this, oldFB] { bindFB(oldFB); });
}
bool IHyprRenderer::preBlurQueued(PHLMONITORREF pMonitor) {
static auto PBLURNEWOPTIMIZE = CConfigValue<Hyprlang::INT>("decoration:blur:new_optimizations");
static auto PBLUR = CConfigValue<Hyprlang::INT>("decoration:blur:enabled");
@ -1735,6 +1745,7 @@ SP<ITexture> IHyprRenderer::blurMainFramebuffer(float a, CRegion* originalDamage
return m_renderData.pMonitor->m_mirrorFB->getTexture(); // return something to sample from at least
}
auto guard = bindTempFB(m_renderData.currentFB); // blurFramebuffer messes with FB bindings
return blurFramebuffer(m_renderData.currentFB, a, originalDamage);
}
@ -1746,7 +1757,7 @@ void IHyprRenderer::preBlurForCurrentMonitor(CRegion* fakeDamage) {
if (!m_renderData.pMonitor->m_blurFB)
return;
m_renderData.pMonitor->m_blurFB->alloc(m_renderData.pMonitor->m_pixelSize.x, m_renderData.pMonitor->m_pixelSize.y, m_renderData.pMonitor->m_output->state->state().drmFormat);
m_renderData.pMonitor->m_blurFB->bind();
auto guard = bindTempFB(m_renderData.pMonitor->m_blurFB);
draw(CClearPassElement::SClearData{{0, 0, 0, 0}});
@ -1761,8 +1772,6 @@ void IHyprRenderer::preBlurForCurrentMonitor(CRegion* fakeDamage) {
*fakeDamage); // .noAA = true
popMonitorTransformEnabled();
m_renderData.currentFB->bind();
}
static bool isSDR2HDR(const NColorManagement::SImageDescription& imageDescription, const NColorManagement::SImageDescription& targetImageDescription) {

View file

@ -4,6 +4,7 @@
#include <cstdint>
#include <hyprgraphics/color/Color.hpp>
#include <hyprutils/math/Box.hpp>
#include <hyprutils/utils/ScopeGuard.hpp>
#include <list>
#include <optional>
#include "OpenGL.hpp"
@ -43,6 +44,8 @@ namespace Screenshare {
};
namespace Render {
using CScopeGuard = Hyprutils::Utils::CScopeGuard;
class IElementRenderer;
class CRenderPass;
@ -147,6 +150,8 @@ namespace Render {
void draw(const CSurfacePassElement::SRenderData& data, const CRegion& damage = {});
void draw(const CTexPassElement::SRenderData& data, const CRegion& damage = {});
void draw(const CTextureMatteElement::STextureMatteData& data, const CRegion& damage = {});
virtual void bindFB(SP<IFramebuffer> fb);
UP<CScopeGuard> bindTempFB(SP<IFramebuffer> fb);
virtual UP<ISyncFDManager> createSyncFDManager() = 0;
virtual WP<IElementRenderer> elementRenderer() = 0;
virtual SP<ITexture> createStencilTexture(const int width, const int height) = 0;

View file

@ -1,6 +1,7 @@
#pragma once
#include "../defines.hpp"
#include "helpers/cm/ColorManagement.hpp"
#include <aquamarine/buffer/Buffer.hpp>
#include <hyprutils/math/Misc.hpp>
#include <span>
@ -44,6 +45,9 @@ namespace Render {
uint32_t m_drmFormat = 0; // for shm
bool m_isSynchronous = false;
// CM
NColorManagement::PImageDescription m_imageDescription;
// TODO move to GLTexture
GLuint m_texID = 0;
GLenum magFilter = GL_LINEAR; // useNearestNeighbor overwrites these

View file

@ -237,11 +237,10 @@ void CHyprDropShadowDecoration::render(PHLMONITOR pMonitor, float const& a) {
// we'll take the liberty of using this as it should not be used rn
const auto alphaFB = g_pHyprRenderer->m_renderData.pMonitor->m_mirrorFB;
const auto alphaSwapFB = g_pHyprRenderer->m_renderData.pMonitor->m_mirrorSwapFB;
const auto LASTFB = g_pHyprRenderer->m_renderData.currentFB;
CBox monbox = {0, 0, pMonitor->m_transformedSize.x, pMonitor->m_transformedSize.y};
alphaFB->bind();
auto guard = g_pHyprRenderer->bindTempFB(alphaFB);
// build the matte
// 10-bit formats have dogshit alpha channels, so we have to use the matte to its fullest.
@ -262,12 +261,12 @@ void CHyprDropShadowDecoration::render(PHLMONITOR pMonitor, float const& a) {
},
monbox);
alphaSwapFB->bind();
g_pHyprRenderer->bindFB(alphaSwapFB);
// alpha swap just has the shadow color. It will be the "texture" to render.
g_pHyprRenderer->draw(CRectPassElement::SRectData{.box = data.fullBox, .color = PWINDOW->m_realShadowColor->value().stripA(), .round = 0}, monbox);
LASTFB->bind();
guard.reset();
g_pHyprRenderer->pushMonitorTransformEnabled(true);
g_pHyprRenderer->m_renderData.renderModif.enabled = false;

View file

@ -68,7 +68,7 @@ void CGLElementRenderer::draw(WP<CFramebufferElement> element, const CRegion& da
}
}
fb->bind();
g_pHyprRenderer->bindFB(fb);
};
void CGLElementRenderer::draw(WP<CPreBlurElement> element, const CRegion& damage) {

View file

@ -65,7 +65,7 @@ CGLRenderbuffer::CGLRenderbuffer(SP<Aquamarine::IBuffer> buffer, uint32_t format
void CGLRenderbuffer::bind() {
g_pHyprOpenGL->makeEGLCurrent();
m_framebuffer->bind();
g_pHyprRenderer->bindFB(m_framebuffer);
}
void CGLRenderbuffer::unbind() {