summaryrefslogtreecommitdiff
path: root/src/render/OpenGL.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/render/OpenGL.cpp')
-rw-r--r--src/render/OpenGL.cpp267
1 files changed, 128 insertions, 139 deletions
diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp
index 9aaa99d5..cfc3dc4e 100644
--- a/src/render/OpenGL.cpp
+++ b/src/render/OpenGL.cpp
@@ -60,6 +60,7 @@
using namespace Hyprutils::OS;
using namespace NColorManagement;
using namespace Render;
+using namespace Render::GL;
static inline void loadGLProc(void* pProc, const char* name) {
void* proc = rc<void*>(eglGetProcAddress(name));
@@ -139,6 +140,12 @@ static int openRenderNode(int drmFd) {
return renderFD;
}
+static ShaderFeatureFlags globalFeatures() {
+ return g_pHyprRenderer->m_renderData.pMonitor && g_pHyprRenderer->m_renderData.pMonitor->needsUnmodifiedCopy() && g_pHyprRenderer->m_renderData.currentFB->getMirrorTexture() ?
+ SH_FEAT_MIRROR :
+ 0;
+}
+
void CHyprOpenGLImpl::initEGL(bool gbm) {
std::vector<EGLint> attrs;
if (m_exts.KHR_display_reference) {
@@ -687,8 +694,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;
@@ -728,8 +734,8 @@ void CHyprOpenGLImpl::begin(PHLMONITOR pMonitor, const CRegion& damage_, SP<IFra
if (!m_shadersInitialized)
initShaders();
- const bool HAS_MIRROR_FB = g_pHyprRenderer->m_renderData.pMonitor->m_monitorMirrorFB && g_pHyprRenderer->m_renderData.pMonitor->m_monitorMirrorFB->isAllocated();
- const bool NEEDS_COPY_FB = g_pHyprRenderer->needsACopyFB(g_pHyprRenderer->m_renderData.pMonitor.lock());
+ const bool HAS_MIRROR_FB = g_pHyprRenderer->m_renderData.pMonitor->resources()->hasMirrorFB();
+ const bool NEEDS_COPY_FB = g_pHyprRenderer->m_renderData.pMonitor->needsACopyFB();
g_pHyprRenderer->m_renderData.transformDamage = true;
if (HAS_MIRROR_FB != NEEDS_COPY_FB) {
@@ -749,13 +755,28 @@ 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->resources()->getUnusedWorkBuffer());
+ 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();
+ if UNLIKELY (g_pHyprRenderer->m_renderData.pMonitor->needsUnmodifiedCopy() && !m_fakeFrame) {
+ if (!g_pHyprRenderer->m_renderData.pMonitor->resources()->m_mirrorTex) {
+ GLenum buffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
+ glDrawBuffers(2, buffers);
+ g_pHyprRenderer->m_renderData.pMonitor->resources()->enableMirror();
+ }
+ g_pHyprRenderer->m_renderData.mainFB->enableMirror(g_pHyprRenderer->m_renderData.pMonitor->resources()->m_mirrorTex);
+ } else {
+ if (g_pHyprRenderer->m_renderData.pMonitor->resources()->m_mirrorTex) {
+ GLenum buffers[] = {GL_COLOR_ATTACHMENT0};
+ glDrawBuffers(1, buffers);
+ g_pHyprRenderer->m_renderData.pMonitor->resources()->disableMirror();
+ }
+ g_pHyprRenderer->m_renderData.mainFB->disableMirror();
+ }
+
g_pHyprRenderer->pushMonitorTransformEnabled(false);
}
@@ -786,19 +807,20 @@ void CHyprOpenGLImpl::end() {
// copy the damaged areas into the mirror buffer
// we can't use the offloadFB for mirroring / ss, as it contains artifacts from blurring
- if UNLIKELY (g_pHyprRenderer->needsACopyFB(g_pHyprRenderer->m_renderData.pMonitor.lock()) && !m_fakeFrame)
+ if UNLIKELY (g_pHyprRenderer->m_renderData.pMonitor->needsACopyFB() && !m_fakeFrame)
saveBufferForMirror(monbox);
- g_pHyprRenderer->m_renderData.outFB->bind();
+ const auto TEX = g_pHyprRenderer->m_renderData.currentFB->getTexture();
+ g_pHyprRenderer->bindFB(g_pHyprRenderer->m_renderData.outFB);
blend(false);
const auto PRIMITIVE_BLOCKED = m_finalScreenShader->program() >= 1 || g_pHyprRenderer->m_crashingInProgress ||
g_pHyprRenderer->m_renderData.pMonitor->m_imageDescription->value() != SImageDescription{};
if LIKELY (!PRIMITIVE_BLOCKED || g_pHyprRenderer->m_renderMode != RENDER_MODE_NORMAL)
- renderTexturePrimitive(g_pHyprRenderer->m_renderData.pMonitor->m_offloadFB->getTexture(), monbox);
+ renderTexturePrimitive(TEX, monbox);
else // we need to use renderTexture if we do any CM whatsoever.
- renderTexture(g_pHyprRenderer->m_renderData.pMonitor->m_offloadFB->getTexture(), monbox, {.finalMonitorCM = true});
+ renderTexture(TEX, monbox, {.finalMonitorCM = true});
blend(true);
@@ -807,39 +829,26 @@ void CHyprOpenGLImpl::end() {
g_pHyprRenderer->popMonitorTransformEnabled();
}
- // invalidate our render FBs to signal to the driver we don't need them anymore
- if (g_pHyprRenderer->m_renderData.pMonitor->m_mirrorFB) {
- g_pHyprRenderer->m_renderData.pMonitor->m_mirrorFB->bind();
- GLFB(g_pHyprRenderer->m_renderData.pMonitor->m_mirrorFB)->invalidate({GL_STENCIL_ATTACHMENT, GL_COLOR_ATTACHMENT0});
- }
- if (g_pHyprRenderer->m_renderData.pMonitor->m_mirrorSwapFB) {
- g_pHyprRenderer->m_renderData.pMonitor->m_mirrorSwapFB->bind();
- GLFB(g_pHyprRenderer->m_renderData.pMonitor->m_mirrorSwapFB)->invalidate({GL_STENCIL_ATTACHMENT, GL_COLOR_ATTACHMENT0});
- }
- if (g_pHyprRenderer->m_renderData.pMonitor->m_offloadFB) {
- g_pHyprRenderer->m_renderData.pMonitor->m_offloadFB->bind();
- GLFB(g_pHyprRenderer->m_renderData.pMonitor->m_offloadFB)->invalidate({GL_STENCIL_ATTACHMENT, GL_COLOR_ATTACHMENT0});
- }
- if (g_pHyprRenderer->m_renderData.pMonitor->m_offMainFB) {
- g_pHyprRenderer->m_renderData.pMonitor->m_offMainFB->bind();
- GLFB(g_pHyprRenderer->m_renderData.pMonitor->m_offMainFB)->invalidate({GL_STENCIL_ATTACHMENT, GL_COLOR_ATTACHMENT0});
- }
-
// reset our data
- m_renderData.pMonitor.reset();
g_pHyprRenderer->m_renderData.mouseZoomFactor = 1.f;
g_pHyprRenderer->m_renderData.mouseZoomUseMouse = true;
g_pHyprRenderer->m_renderData.blockScreenShader = false;
- g_pHyprRenderer->m_renderData.currentFB = nullptr;
- g_pHyprRenderer->m_renderData.mainFB = nullptr;
- g_pHyprRenderer->m_renderData.outFB = nullptr;
+ g_pHyprRenderer->m_renderData.currentFB.reset();
+ g_pHyprRenderer->m_renderData.mainFB.reset();
+ g_pHyprRenderer->m_renderData.outFB.reset();
g_pHyprRenderer->popMonitorTransformEnabled();
- // if we dropped to offMain, release it now.
- // if there is a plugin constantly using it, this might be a bit slow,
- // but I haven't seen a single plugin yet use these, so it's better to drop a bit of vram.
- if UNLIKELY (PMONITOR && PMONITOR->m_offMainFB && PMONITOR->m_offMainFB->isAllocated())
- PMONITOR->m_offMainFB->release();
+ // invalidate our render FBs to signal to the driver we don't need them anymore
+ if (!g_pHyprRenderer->m_renderData.pMonitor->useFP16()) { // FIXME wtf?
+ g_pHyprRenderer->m_renderData.pMonitor->resources()->forEachUnusedFB(
+ [](const auto& fb) {
+ fb->bind();
+ GLFB(fb)->invalidate({GL_STENCIL_ATTACHMENT, GL_COLOR_ATTACHMENT0});
+ },
+ false);
+ }
+
+ m_renderData.pMonitor.reset();
static const auto GLDEBUG = CConfigValue<Hyprlang::INT>("debug:gl_debugging");
@@ -963,21 +972,6 @@ void CHyprOpenGLImpl::applyScreenShader(const std::string& path) {
uniformRequireNoDamage(SHADER_POINTER_SHAPE_PREVIOUS, "pointer_shape_previous");
}
-void CHyprOpenGLImpl::clear(const CHyprColor& color) {
- RASSERT(g_pHyprRenderer->m_renderData.pMonitor, "Tried to render without begin()!");
-
- TRACY_GPU_ZONE("RenderClear");
-
- GLCALL(glClearColor(color.r, color.g, color.b, color.a));
-
- if (!g_pHyprRenderer->m_renderData.damage.empty()) {
- g_pHyprRenderer->m_renderData.damage.forEachRect([this](const auto& RECT) {
- scissor(&RECT, g_pHyprRenderer->m_renderData.transformDamage);
- glClear(GL_COLOR_BUFFER_BIT);
- });
- }
-}
-
void CHyprOpenGLImpl::blend(bool enabled) {
if (enabled) {
setCapStatus(GL_BLEND, true);
@@ -1052,16 +1046,13 @@ 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->resources()->m_blurFB->getTexture() : 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;
@@ -1081,7 +1072,7 @@ void CHyprOpenGLImpl::renderRectWithDamageInternal(const CBox& box, const CHyprC
const auto& glMatrix = g_pHyprRenderer->projectBoxToTarget(newBox);
- auto shader = useShader(getShaderVariant(SH_FRAG_QUAD, data.round > 0 ? SH_FEAT_ROUNDING : 0));
+ auto shader = useShader(getShaderVariant(SH_FRAG_QUAD, (data.round > 0 ? SH_FEAT_ROUNDING : 0) | globalFeatures()));
shader->setUniformMatrix3fv(SHADER_PROJ, 1, GL_TRUE, glMatrix.getMatrix());
// premultiply the color as well as we don't work with straight alpha
@@ -1144,28 +1135,9 @@ void CHyprOpenGLImpl::renderTexture(SP<ITexture> tex, const CBox& box, STextureR
static std::map<std::pair<uint32_t, uint32_t>, std::array<GLfloat, 9>> primariesConversionCache;
-static bool isSDR2HDR(const NColorManagement::SImageDescription& imageDescription, const NColorManagement::SImageDescription& targetImageDescription) {
- // might be too strict
- return (imageDescription.transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_SRGB ||
- imageDescription.transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_GAMMA22) &&
- (targetImageDescription.transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_ST2084_PQ ||
- targetImageDescription.transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_HLG);
-}
-
-static bool isHDR2SDR(const NColorManagement::SImageDescription& imageDescription, const NColorManagement::SImageDescription& targetImageDescription) {
- // might be too strict
- return (imageDescription.transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_ST2084_PQ ||
- imageDescription.transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_HLG) &&
- (targetImageDescription.transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_SRGB ||
- targetImageDescription.transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_GAMMA22);
-}
-
void CHyprOpenGLImpl::passCMUniforms(WP<CShader> shader, const NColorManagement::PImageDescription imageDescription,
- const NColorManagement::PImageDescription targetImageDescription, bool modifySDR, float sdrMinLuminance, int sdrMaxLuminance) {
- const auto settings = g_pHyprRenderer->getCMSettings(imageDescription, targetImageDescription,
- g_pHyprRenderer->m_renderData.surface.valid() ? g_pHyprRenderer->m_renderData.surface.lock() : nullptr, modifySDR,
- sdrMinLuminance, sdrMaxLuminance);
-
+ const NColorManagement::PImageDescription targetImageDescription, bool modifySDR, float sdrMinLuminance, int sdrMaxLuminance,
+ const SCMSettings& settings) {
shader->setUniformInt(SHADER_SOURCE_TF, settings.sourceTF);
shader->setUniformInt(SHADER_TARGET_TF, settings.targetTF);
shader->setUniformFloat2(SHADER_SRC_TF_RANGE, settings.srcTFRange.min, settings.srcTFRange.max);
@@ -1209,6 +1181,14 @@ void CHyprOpenGLImpl::passCMUniforms(WP<CShader> shader, const NColorManagement:
}
}
+void CHyprOpenGLImpl::passCMUniforms(WP<CShader> shader, const NColorManagement::PImageDescription imageDescription,
+ const NColorManagement::PImageDescription targetImageDescription, bool modifySDR, float sdrMinLuminance, int sdrMaxLuminance) {
+ const auto settings = g_pHyprRenderer->getCMSettings(imageDescription, targetImageDescription,
+ g_pHyprRenderer->m_renderData.surface.valid() ? g_pHyprRenderer->m_renderData.surface.lock() : nullptr, modifySDR,
+ sdrMinLuminance, sdrMaxLuminance);
+ passCMUniforms(shader, imageDescription, targetImageDescription, modifySDR, sdrMinLuminance, sdrMaxLuminance, settings);
+}
+
void CHyprOpenGLImpl::passCMUniforms(WP<CShader> shader, const PImageDescription imageDescription) {
passCMUniforms(shader, imageDescription, g_pHyprRenderer->workBufferImageDescription(), true, g_pHyprRenderer->m_renderData.pMonitor->m_sdrMinLuminance,
g_pHyprRenderer->m_renderData.pMonitor->m_sdrMaxLuminance);
@@ -1287,7 +1267,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");
@@ -1304,7 +1284,7 @@ WP<CShader> CHyprOpenGLImpl::renderToFBInternal(const STextureRenderData& data,
case TEXTURE_RGBX: shaderFeatures &= ~SH_FEAT_RGBA; break;
// TODO set correct features
- case TEXTURE_EXTERNAL: shader = getShaderVariant(SH_FRAG_EXT, SH_FEAT_ROUNDING | SH_FEAT_DISCARD | SH_FEAT_TINT); break; // might be unused
+ case TEXTURE_EXTERNAL: shader = getShaderVariant(SH_FRAG_EXT, SH_FEAT_ROUNDING | SH_FEAT_DISCARD | SH_FEAT_TINT | globalFeatures()); break; // might be unused
default: RASSERT(false, "tex->m_iTarget unsupported!");
}
@@ -1320,13 +1300,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
@@ -1334,6 +1320,9 @@ WP<CShader> CHyprOpenGLImpl::renderToFBInternal(const STextureRenderData& data,
}();
const auto TARGET_IMAGE_DESCRIPTION = [&] {
+ if (g_pHyprRenderer->m_renderData.currentFB->imageDescription())
+ return g_pHyprRenderer->m_renderData.currentFB->imageDescription();
+
// if we are CM'ing back, use default sRGB
if (data.cmBackToSRGB)
return DEFAULT_IMAGE_DESCRIPTION;
@@ -1370,41 +1359,32 @@ WP<CShader> CHyprOpenGLImpl::renderToFBInternal(const STextureRenderData& data,
shaderFeatures |= SH_FEAT_ROUNDING;
if (!skipCM) {
+ const auto settings = g_pHyprRenderer->getCMSettings(SOURCE_IMAGE_DESCRIPTION, TARGET_IMAGE_DESCRIPTION,
+ g_pHyprRenderer->m_renderData.surface.valid() ? g_pHyprRenderer->m_renderData.surface.lock() : nullptr, true,
+ g_pHyprRenderer->m_renderData.pMonitor->m_sdrMinLuminance, g_pHyprRenderer->m_renderData.pMonitor->m_sdrMaxLuminance);
+
shaderFeatures |= SH_FEAT_CM;
if (TARGET_IMAGE_DESCRIPTION->value().icc.present)
shaderFeatures |= SH_FEAT_ICC;
else {
- const bool needsSDRmod = isSDR2HDR(SOURCE_IMAGE_DESCRIPTION->value(), TARGET_IMAGE_DESCRIPTION->value());
- const bool needsHDRmod = !needsSDRmod && isHDR2SDR(SOURCE_IMAGE_DESCRIPTION->value(), TARGET_IMAGE_DESCRIPTION->value());
- const float maxLuminance = needsHDRmod ?
- SOURCE_IMAGE_DESCRIPTION->value().getTFMaxLuminance(-1) :
- (SOURCE_IMAGE_DESCRIPTION->value().luminances.max > 0 ? SOURCE_IMAGE_DESCRIPTION->value().luminances.max : SOURCE_IMAGE_DESCRIPTION->value().luminances.reference);
- const auto dstMaxLuminance = TARGET_IMAGE_DESCRIPTION->value().luminances.max > 0 ? TARGET_IMAGE_DESCRIPTION->value().luminances.max : 10000;
-
- if (maxLuminance >= dstMaxLuminance * 1.01)
+ if (settings.needsTonemap)
shaderFeatures |= SH_FEAT_TONEMAP;
- if (!data.finalMonitorCM &&
- (SOURCE_IMAGE_DESCRIPTION->value().transferFunction == CM_TRANSFER_FUNCTION_SRGB ||
- SOURCE_IMAGE_DESCRIPTION->value().transferFunction == CM_TRANSFER_FUNCTION_GAMMA22) &&
- TARGET_IMAGE_DESCRIPTION->value().transferFunction == CM_TRANSFER_FUNCTION_ST2084_PQ &&
- ((g_pHyprRenderer->m_renderData.pMonitor->m_sdrSaturation > 0 && g_pHyprRenderer->m_renderData.pMonitor->m_sdrSaturation != 1.0f) ||
- (g_pHyprRenderer->m_renderData.pMonitor->m_sdrBrightness > 0 && g_pHyprRenderer->m_renderData.pMonitor->m_sdrBrightness != 1.0f)))
+ if (!data.finalMonitorCM && settings.needsSDRmod)
shaderFeatures |= SH_FEAT_SDR_MOD;
}
- }
- if (!shader)
- shader = getShaderVariant(SH_FRAG_SURFACE, shaderFeatures);
- shader = useShader(shader);
+ if (!shader)
+ shader = getShaderVariant(SH_FRAG_SURFACE, shaderFeatures | globalFeatures());
+ shader = useShader(shader);
- if (!skipCM) {
- if (data.finalMonitorCM || data.cmBackToSRGB)
- passCMUniforms(shader, SOURCE_IMAGE_DESCRIPTION, TARGET_IMAGE_DESCRIPTION, true, g_pHyprRenderer->m_renderData.pMonitor->m_sdrMinLuminance,
- g_pHyprRenderer->m_renderData.pMonitor->m_sdrMaxLuminance);
- else
- passCMUniforms(shader, SOURCE_IMAGE_DESCRIPTION);
+ passCMUniforms(shader, SOURCE_IMAGE_DESCRIPTION, TARGET_IMAGE_DESCRIPTION, true, g_pHyprRenderer->m_renderData.pMonitor->m_sdrMinLuminance,
+ g_pHyprRenderer->m_renderData.pMonitor->m_sdrMaxLuminance, settings);
+ } else {
+ if (!shader)
+ shader = getShaderVariant(SH_FRAG_SURFACE, shaderFeatures | globalFeatures());
+ shader = useShader(shader);
}
shader->setUniformFloat(SHADER_ALPHA, alpha);
@@ -1458,7 +1438,8 @@ WP<CShader> CHyprOpenGLImpl::renderToFBInternal(const STextureRenderData& data,
void CHyprOpenGLImpl::renderTextureInternal(SP<ITexture> tex, const CBox& box, const STextureRenderData& data) {
RASSERT(g_pHyprRenderer->m_renderData.pMonitor, "Tried to render texture without begin()!");
- RASSERT((tex->ok()), "Attempted to draw nullptr texture!");
+ RASSERT(tex, "Attempted to draw nullptr texture!");
+ RASSERT(tex->ok(), "Attempted to draw invalid texture!");
TRACY_GPU_ZONE("RenderTextureInternalWithDamage");
@@ -1493,7 +1474,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);
@@ -1608,7 +1589,7 @@ void CHyprOpenGLImpl::renderTextureMatte(SP<ITexture> tex, const CBox& box, SP<I
// get transform
const auto& glMatrix = g_pHyprRenderer->projectBoxToTarget(newBox);
- auto shader = useShader(getShaderVariant(SH_FRAG_MATTE));
+ auto shader = useShader(getShaderVariant(SH_FRAG_MATTE, globalFeatures()));
shader->setUniformMatrix3fv(SHADER_PROJ, 1, GL_TRUE, glMatrix.getMatrix());
shader->setUniformInt(SHADER_TEX, 0);
shader->setUniformInt(SHADER_ALPHA_MATTE, 1);
@@ -1665,8 +1646,8 @@ SP<IFramebuffer> CHyprOpenGLImpl::blurFramebufferWithDamage(float a, CRegion* or
damage.expand(std::clamp(*PBLURSIZE, sc<int64_t>(1), sc<int64_t>(40)) * pow(2, BLUR_PASSES));
// helper
- const auto PMIRRORFB = g_pHyprRenderer->m_renderData.pMonitor->m_mirrorFB;
- const auto PMIRRORSWAPFB = g_pHyprRenderer->m_renderData.pMonitor->m_mirrorSwapFB;
+ const auto PMIRRORFB = g_pHyprRenderer->m_renderData.pMonitor->resources()->getUnusedWorkBuffer();
+ const auto PMIRRORSWAPFB = g_pHyprRenderer->m_renderData.pMonitor->resources()->getUnusedWorkBuffer();
auto currentRenderToFB = PMIRRORFB;
@@ -1692,15 +1673,15 @@ SP<IFramebuffer> CHyprOpenGLImpl::blurFramebufferWithDamage(float a, CRegion* or
const bool skipCM = !m_cmSupported || g_pHyprRenderer->workBufferImageDescription()->id() == DEFAULT_IMAGE_DESCRIPTION->id();
if (!skipCM) {
shader = useShader(getShaderVariant(SH_FRAG_BLURPREPARE, SH_FEAT_CM));
- passCMUniforms(shader, m_renderData.pMonitor->m_imageDescription, DEFAULT_IMAGE_DESCRIPTION);
+ passCMUniforms(shader, g_pHyprRenderer->workBufferImageDescription(), DEFAULT_IMAGE_DESCRIPTION);
shader->setUniformFloat(SHADER_SDR_SATURATION,
m_renderData.pMonitor->m_sdrSaturation > 0 &&
- m_renderData.pMonitor->m_imageDescription->value().transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_ST2084_PQ ?
+ g_pHyprRenderer->workBufferImageDescription()->value().transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_ST2084_PQ ?
m_renderData.pMonitor->m_sdrSaturation :
1.0f);
shader->setUniformFloat(SHADER_SDR_BRIGHTNESS,
m_renderData.pMonitor->m_sdrBrightness > 0 &&
- m_renderData.pMonitor->m_imageDescription->value().transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_ST2084_PQ ?
+ g_pHyprRenderer->workBufferImageDescription()->value().transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_ST2084_PQ ?
m_renderData.pMonitor->m_sdrBrightness :
1.0f);
} else
@@ -1808,7 +1789,24 @@ SP<IFramebuffer> CHyprOpenGLImpl::blurFramebufferWithDamage(float a, CRegion* or
currentTex->setTexParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- auto shader = useShader(getShaderVariant(SH_FRAG_BLURFINISH));
+ // From FB to sRGB
+ const bool skipCM = !m_cmSupported || g_pHyprRenderer->workBufferImageDescription()->id() == DEFAULT_IMAGE_DESCRIPTION->id();
+ if (!skipCM) {
+ shader = useShader(getShaderVariant(SH_FRAG_BLURFINISH, SH_FEAT_CM));
+ passCMUniforms(shader, DEFAULT_IMAGE_DESCRIPTION, g_pHyprRenderer->workBufferImageDescription());
+ shader->setUniformFloat(SHADER_SDR_SATURATION,
+ m_renderData.pMonitor->m_sdrSaturation > 0 &&
+ g_pHyprRenderer->workBufferImageDescription()->value().transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_ST2084_PQ ?
+ m_renderData.pMonitor->m_sdrSaturation :
+ 1.0f);
+ shader->setUniformFloat(SHADER_SDR_BRIGHTNESS,
+ m_renderData.pMonitor->m_sdrBrightness > 0 &&
+ g_pHyprRenderer->workBufferImageDescription()->value().transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_ST2084_PQ ?
+ m_renderData.pMonitor->m_sdrBrightness :
+ 1.0f);
+ } else
+ shader = useShader(getShaderVariant(SH_FRAG_BLURFINISH));
+
shader->setUniformMatrix3fv(SHADER_PROJ, 1, GL_TRUE, glMatrix.getMatrix());
shader->setUniformFloat(SHADER_NOISE, *PBLURNOISE);
shader->setUniformFloat(SHADER_BRIGHTNESS, *PBLURBRIGHTNESS);
@@ -2078,10 +2076,10 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const Config::CGradientValue
const bool IS_ICC = g_pHyprRenderer->workBufferImageDescription()->value().icc.present;
const bool skipCM = !m_cmSupported || g_pHyprRenderer->workBufferImageDescription()->id() == DEFAULT_IMAGE_DESCRIPTION->id();
if (!skipCM) {
- shader = useShader(getShaderVariant(SH_FRAG_BORDER1, SH_FEAT_ROUNDING | SH_FEAT_CM | (IS_ICC ? SH_FEAT_ICC : SH_FEAT_TONEMAP | SH_FEAT_SDR_MOD)));
+ shader = useShader(getShaderVariant(SH_FRAG_BORDER1, SH_FEAT_ROUNDING | SH_FEAT_CM | (IS_ICC ? SH_FEAT_ICC : SH_FEAT_TONEMAP | SH_FEAT_SDR_MOD) | globalFeatures()));
passCMUniforms(shader, DEFAULT_IMAGE_DESCRIPTION);
} else
- shader = useShader(getShaderVariant(SH_FRAG_BORDER1, SH_FEAT_ROUNDING));
+ shader = useShader(getShaderVariant(SH_FRAG_BORDER1, SH_FEAT_ROUNDING | globalFeatures()));
shader->setUniformMatrix3fv(SHADER_PROJ, 1, GL_TRUE, glMatrix.getMatrix());
shader->setUniform4fv(SHADER_GRADIENT, grad.m_colorsOkLabA.size() / 4, grad.m_colorsOkLabA);
@@ -2163,10 +2161,10 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const Config::CGradientValue
const bool IS_ICC = g_pHyprRenderer->workBufferImageDescription()->value().icc.present;
const bool skipCM = !m_cmSupported || g_pHyprRenderer->workBufferImageDescription()->id() == DEFAULT_IMAGE_DESCRIPTION->id();
if (!skipCM) {
- shader = useShader(getShaderVariant(SH_FRAG_BORDER1, SH_FEAT_ROUNDING | SH_FEAT_CM | (IS_ICC ? SH_FEAT_ICC : SH_FEAT_TONEMAP | SH_FEAT_SDR_MOD)));
+ shader = useShader(getShaderVariant(SH_FRAG_BORDER1, SH_FEAT_ROUNDING | SH_FEAT_CM | (IS_ICC ? SH_FEAT_ICC : SH_FEAT_TONEMAP | SH_FEAT_SDR_MOD) | globalFeatures()));
passCMUniforms(shader, DEFAULT_IMAGE_DESCRIPTION);
} else
- shader = useShader(getShaderVariant(SH_FRAG_BORDER1, SH_FEAT_ROUNDING));
+ shader = useShader(getShaderVariant(SH_FRAG_BORDER1, SH_FEAT_ROUNDING | globalFeatures()));
shader->setUniformMatrix3fv(SHADER_PROJ, 1, GL_TRUE, glMatrix.getMatrix());
shader->setUniform4fv(SHADER_GRADIENT, grad1.m_colorsOkLabA.size() / 4, grad1.m_colorsOkLabA);
@@ -2240,7 +2238,7 @@ void CHyprOpenGLImpl::renderRoundedShadow(const CBox& box, int round, float roun
const bool IS_ICC = g_pHyprRenderer->workBufferImageDescription()->value().icc.present;
const bool skipCM = !m_cmSupported || g_pHyprRenderer->workBufferImageDescription()->id() == DEFAULT_IMAGE_DESCRIPTION->id();
- auto shader = useShader(getShaderVariant(SH_FRAG_SHADOW, skipCM ? 0 : SH_FEAT_CM | (IS_ICC ? SH_FEAT_ICC : SH_FEAT_TONEMAP | SH_FEAT_SDR_MOD)));
+ 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, DEFAULT_IMAGE_DESCRIPTION);
@@ -2347,16 +2345,17 @@ void CHyprOpenGLImpl::renderInnerGlow(const CBox& box, int round, float rounding
}
void CHyprOpenGLImpl::saveBufferForMirror(const CBox& box) {
- auto& m_renderData = g_pHyprRenderer->m_renderData;
- if (!g_pHyprRenderer->m_renderData.pMonitor->m_monitorMirrorFB->isAllocated())
- 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();
+ const auto TEX = g_pHyprRenderer->m_renderData.pMonitor->resources()->m_mirrorTex ? g_pHyprRenderer->m_renderData.pMonitor->resources()->m_mirrorTex :
+ g_pHyprRenderer->m_renderData.currentFB->getTexture();
+ if (!TEX) {
+ Log::logger->log(Log::ERR, "Invalid source texture for mirror");
+ return;
+ }
+ auto guard = g_pHyprRenderer->bindTempFB(g_pHyprRenderer->m_renderData.pMonitor->resources()->mirrorFB());
blend(false);
- renderTexture(g_pHyprRenderer->m_renderData.currentFB->getTexture(), box,
+ renderTexture(TEX, box,
STextureRenderData{
.damage = &g_pHyprRenderer->m_renderData.finalDamage,
.a = 1.F,
@@ -2367,8 +2366,6 @@ void CHyprOpenGLImpl::saveBufferForMirror(const CBox& box) {
});
blend(true);
-
- g_pHyprRenderer->m_renderData.currentFB->bind();
}
WP<CShader> CHyprOpenGLImpl::useShader(WP<CShader> prog) {
@@ -2397,7 +2394,7 @@ void CHyprOpenGLImpl::destroyMonitorResources(PHLMONITORREF pMonitor) {
Log::logger->log(Log::DEBUG, "Monitor {} -> destroyed all render data", pMonitor->m_name);
}
-void CHyprOpenGLImpl::renderOffToMain(IFramebuffer* off) {
+void CHyprOpenGLImpl::renderOffToMain(SP<IFramebuffer> off) {
CBox monbox = {0, 0, g_pHyprRenderer->m_renderData.pMonitor->m_transformedSize.x, g_pHyprRenderer->m_renderData.pMonitor->m_transformedSize.y};
renderTexturePrimitive(off->getTexture(), monbox);
}
@@ -2579,14 +2576,6 @@ CEGLSync::~CEGLSync() {
Log::logger->log(Log::ERR, "eglDestroySyncKHR failed");
}
-CFileDescriptor& CEGLSync::fd() {
- return m_fd;
-}
-
-CFileDescriptor&& CEGLSync::takeFd() {
- return std::move(m_fd);
-}
-
bool CEGLSync::isValid() {
return m_valid && m_sync != EGL_NO_SYNC_KHR && m_fd.isValid();
}