summaryrefslogtreecommitdiff
path: root/src/render/Renderer.cpp
diff options
context:
space:
mode:
authorUjinT34 <41110182+UjinT34@users.noreply.github.com>2026-03-07 00:44:10 +0300
committerGitHub <noreply@github.com>2026-03-06 21:44:10 +0000
commit4152ac76d0813d9d0f67d2f04653a13fa6e17433 (patch)
treec341f1883cf5a182d32e4ad00192ba8786a9bb75 /src/render/Renderer.cpp
parenta5858018d896e0e0f0db517f893cd9a0936dd881 (diff)
renderer: refactor Texture, Framebuffer and Renderbuffer (#13437)
Part 1 of the renderer refactors
Diffstat (limited to 'src/render/Renderer.cpp')
-rw-r--r--src/render/Renderer.cpp166
1 files changed, 152 insertions, 14 deletions
diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp
index 8a1cf4b3..165f580a 100644
--- a/src/render/Renderer.cpp
+++ b/src/render/Renderer.cpp
@@ -3,6 +3,7 @@
#include "../helpers/math/Math.hpp"
#include <algorithm>
#include <aquamarine/output/Output.hpp>
+#include <cmath>
#include <filesystem>
#include "../config/ConfigValue.hpp"
#include "../config/ConfigManager.hpp"
@@ -29,10 +30,12 @@
#include "../layout/LayoutManager.hpp"
#include "../layout/space/Space.hpp"
#include "../i18n/Engine.hpp"
+#include "desktop/DesktopTypes.hpp"
#include "../event/EventBus.hpp"
#include "helpers/CursorShapes.hpp"
+#include "helpers/MainLoopExecutor.hpp"
#include "helpers/Monitor.hpp"
-#include "helpers/cm/ColorManagement.hpp"
+#include "macros.hpp"
#include "pass/TexPassElement.hpp"
#include "pass/ClearPassElement.hpp"
#include "pass/RectPassElement.hpp"
@@ -42,7 +45,18 @@
#include "../protocols/ColorManagement.hpp"
#include "../protocols/types/ContentType.hpp"
#include "../helpers/MiscFunctions.hpp"
+#include "render/AsyncResourceGatherer.hpp"
+#include "render/Framebuffer.hpp"
#include "render/OpenGL.hpp"
+#include "render/Texture.hpp"
+#include "render/gl/GLFramebuffer.hpp"
+#include "render/gl/GLTexture.hpp"
+#include <hyprutils/math/Mat3x3.hpp>
+#include <hyprutils/math/Region.hpp>
+#include <hyprutils/math/Vector2D.hpp>
+#include <hyprutils/memory/SharedPtr.hpp>
+#include <optional>
+#include <pango/pangocairo.h>
#include <hyprutils/utils/ScopeGuard.hpp>
using namespace Hyprutils::Utils;
@@ -643,13 +657,13 @@ void CHyprRenderer::renderWindow(PHLWINDOW pWindow, PHLMONITOR pMonitor, const T
}
if (TRANSFORMERSPRESENT) {
- CFramebuffer* last = g_pHyprOpenGL->m_renderData.currentFB;
+ IFramebuffer* last = g_pHyprOpenGL->m_renderData.currentFB.get();
for (auto const& t : pWindow->m_transformers) {
last = t->transform(last);
}
g_pHyprOpenGL->bindBackOnMain();
- g_pHyprOpenGL->renderOffToMain(last);
+ g_pHyprOpenGL->renderOffToMain(dc<CGLFramebuffer*>(last));
}
}
@@ -733,6 +747,36 @@ void CHyprRenderer::renderWindow(PHLWINDOW pWindow, PHLMONITOR pMonitor, const T
g_pHyprOpenGL->m_renderData.currentWindow.reset();
}
+SP<ITexture> CHyprRenderer::createTexture(const SP<Aquamarine::IBuffer> buffer, bool keepDataCopy) {
+ if (!buffer)
+ return createTexture();
+
+ auto attrs = buffer->dmabuf();
+
+ if (!attrs.success) {
+ // attempt shm
+ auto shm = buffer->shm();
+
+ if (!shm.success) {
+ Log::logger->log(Log::ERR, "Cannot create a texture: buffer has no dmabuf or shm");
+ return createTexture(buffer->opaque);
+ }
+
+ auto [pixelData, fmt, bufLen] = buffer->beginDataPtr(0);
+
+ return createTexture(fmt, pixelData, bufLen, shm.size, keepDataCopy, buffer->opaque);
+ }
+
+ auto tex = createTexture(attrs, buffer->opaque);
+
+ if (!tex) {
+ Log::logger->log(Log::ERR, "Cannot create a texture: failed to create an Image");
+ return createTexture(buffer->opaque);
+ }
+
+ return tex;
+}
+
void CHyprRenderer::renderLayer(PHLLS pLayer, PHLMONITOR pMonitor, const Time::steady_tp& time, bool popups, bool lockscreen) {
if (!pLayer)
return;
@@ -2313,13 +2357,13 @@ void CHyprRenderer::initiateManualCrash() {
**PDT = 0;
}
-SP<CRenderbuffer> CHyprRenderer::getOrCreateRenderbuffer(SP<Aquamarine::IBuffer> buffer, uint32_t fmt) {
+SP<IRenderbuffer> CHyprRenderer::getOrCreateRenderbuffer(SP<Aquamarine::IBuffer> buffer, uint32_t fmt) {
auto it = std::ranges::find_if(m_renderbuffers, [&](const auto& other) { return other->m_hlBuffer == buffer; });
if (it != m_renderbuffers.end())
return *it;
- auto buf = makeShared<CRenderbuffer>(buffer, fmt);
+ auto buf = makeShared<CGLRenderbuffer>(buffer, fmt);
if (!buf->good())
return nullptr;
@@ -2343,7 +2387,7 @@ void CHyprRenderer::unsetEGL() {
eglMakeCurrent(g_pHyprOpenGL->m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
}
-bool CHyprRenderer::beginRender(PHLMONITOR pMonitor, CRegion& damage, eRenderMode mode, SP<IHLBuffer> buffer, CFramebuffer* fb, bool simple) {
+bool CHyprRenderer::beginRender(PHLMONITOR pMonitor, CRegion& damage, eRenderMode mode, SP<IHLBuffer> buffer, SP<IFramebuffer> fb, bool simple) {
makeEGLCurrent();
@@ -2475,11 +2519,11 @@ void CHyprRenderer::endRender(const std::function<void()>& renderingDoneCallback
}
}
-void CHyprRenderer::onRenderbufferDestroy(CRenderbuffer* rb) {
+void CHyprRenderer::onRenderbufferDestroy(CGLRenderbuffer* rb) {
std::erase_if(m_renderbuffers, [&](const auto& rbo) { return rbo.get() == rb; });
}
-SP<CRenderbuffer> CHyprRenderer::getCurrentRBO() {
+SP<IRenderbuffer> CHyprRenderer::getCurrentRBO() {
return m_currentRenderbuffer;
}
@@ -2532,7 +2576,10 @@ void CHyprRenderer::makeSnapshot(PHLWINDOW pWindow) {
makeEGLCurrent();
- const auto PFRAMEBUFFER = &g_pHyprOpenGL->m_windowFramebuffers[ref];
+ if (!g_pHyprOpenGL->m_windowFramebuffers.contains(ref))
+ g_pHyprOpenGL->m_windowFramebuffers[ref] = g_pHyprRenderer->createFB();
+
+ const auto PFRAMEBUFFER = g_pHyprOpenGL->m_windowFramebuffers[ref];
PFRAMEBUFFER->alloc(PMONITOR->m_pixelSize.x, PMONITOR->m_pixelSize.y, DRM_FORMAT_ABGR8888);
@@ -2565,7 +2612,10 @@ void CHyprRenderer::makeSnapshot(PHLLS pLayer) {
makeEGLCurrent();
- const auto PFRAMEBUFFER = &g_pHyprOpenGL->m_layerFramebuffers[pLayer];
+ if (!g_pHyprOpenGL->m_layerFramebuffers.contains(pLayer))
+ g_pHyprOpenGL->m_layerFramebuffers[pLayer] = g_pHyprRenderer->createFB();
+
+ const auto PFRAMEBUFFER = g_pHyprOpenGL->m_layerFramebuffers[pLayer];
PFRAMEBUFFER->alloc(PMONITOR->m_pixelSize.x, PMONITOR->m_pixelSize.y, DRM_FORMAT_ABGR8888);
@@ -2599,7 +2649,10 @@ void CHyprRenderer::makeSnapshot(WP<Desktop::View::CPopup> popup) {
makeEGLCurrent();
- const auto PFRAMEBUFFER = &g_pHyprOpenGL->m_popupFramebuffers[popup];
+ if (!g_pHyprOpenGL->m_popupFramebuffers.contains(popup))
+ g_pHyprOpenGL->m_popupFramebuffers[popup] = g_pHyprRenderer->createFB();
+
+ const auto PFRAMEBUFFER = g_pHyprOpenGL->m_popupFramebuffers[popup];
PFRAMEBUFFER->alloc(PMONITOR->m_pixelSize.x, PMONITOR->m_pixelSize.y, DRM_FORMAT_ABGR8888);
@@ -2648,7 +2701,7 @@ void CHyprRenderer::renderSnapshot(PHLWINDOW pWindow) {
if (!g_pHyprOpenGL->m_windowFramebuffers.contains(ref))
return;
- const auto FBDATA = &g_pHyprOpenGL->m_windowFramebuffers.at(ref);
+ const auto FBDATA = g_pHyprOpenGL->m_windowFramebuffers.at(ref);
if (!FBDATA->getTexture())
return;
@@ -2704,7 +2757,7 @@ void CHyprRenderer::renderSnapshot(PHLLS pLayer) {
if (!g_pHyprOpenGL->m_layerFramebuffers.contains(pLayer))
return;
- const auto FBDATA = &g_pHyprOpenGL->m_layerFramebuffers.at(pLayer);
+ const auto FBDATA = g_pHyprOpenGL->m_layerFramebuffers.at(pLayer);
if (!FBDATA->getTexture())
return;
@@ -2748,7 +2801,7 @@ void CHyprRenderer::renderSnapshot(WP<Desktop::View::CPopup> popup) {
static CConfigValue PBLURIGNOREA = CConfigValue<Hyprlang::FLOAT>("decoration:blur:popups_ignorealpha");
- const auto FBDATA = &g_pHyprOpenGL->m_popupFramebuffers.at(popup);
+ const auto FBDATA = g_pHyprOpenGL->m_popupFramebuffers.at(popup);
if (!FBDATA->getTexture())
return;
@@ -2813,4 +2866,89 @@ bool CHyprRenderer::shouldBlur(WP<Desktop::View::CPopup> p) {
bool CHyprRenderer::reloadShaders(const std::string& path) {
return g_pHyprOpenGL->initShaders(path);
+}
+
+SP<ITexture> CHyprRenderer::createStencilTexture(const int width, const int height) {
+ makeEGLCurrent();
+ auto tex = makeShared<CGLTexture>();
+ tex->allocate({width, height});
+
+ return tex;
+}
+
+SP<ITexture> CHyprRenderer::createTexture(bool opaque) {
+ makeEGLCurrent();
+ return makeShared<CGLTexture>(opaque);
+}
+
+SP<ITexture> CHyprRenderer::createTexture(uint32_t drmFormat, uint8_t* pixels, uint32_t stride, const Vector2D& size, bool keepDataCopy, bool opaque) {
+ makeEGLCurrent();
+ return makeShared<CGLTexture>(drmFormat, pixels, stride, size, keepDataCopy, opaque);
+}
+
+SP<ITexture> CHyprRenderer::createTexture(const Aquamarine::SDMABUFAttrs& attrs, bool opaque) {
+ makeEGLCurrent();
+ const auto image = g_pHyprOpenGL->createEGLImage(attrs);
+ if (!image)
+ return nullptr;
+ return makeShared<CGLTexture>(attrs, image, opaque);
+}
+
+SP<ITexture> CHyprRenderer::createTexture(const int width, const int height, unsigned char* const data) {
+ makeEGLCurrent();
+ SP<ITexture> tex = makeShared<CGLTexture>();
+
+ tex->allocate({width, height});
+
+ tex->m_size = {width, height};
+ // copy the data to an OpenGL texture we have
+ const GLint glFormat = GL_RGBA;
+ const GLint glType = GL_UNSIGNED_BYTE;
+
+ tex->bind();
+ tex->setTexParameter(GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ tex->setTexParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ tex->setTexParameter(GL_TEXTURE_SWIZZLE_R, GL_BLUE);
+ tex->setTexParameter(GL_TEXTURE_SWIZZLE_B, GL_RED);
+
+ glTexImage2D(GL_TEXTURE_2D, 0, glFormat, tex->m_size.x, tex->m_size.y, 0, glFormat, glType, data);
+ tex->unbind();
+
+ return tex;
+}
+
+SP<ITexture> CHyprRenderer::createTexture(cairo_surface_t* cairo) {
+ makeEGLCurrent();
+ const auto CAIROFORMAT = cairo_image_surface_get_format(cairo);
+ auto tex = makeShared<CGLTexture>();
+
+ tex->allocate({cairo_image_surface_get_width(cairo), cairo_image_surface_get_height(cairo)});
+
+ const GLint glIFormat = CAIROFORMAT == CAIRO_FORMAT_RGB96F ? GL_RGB32F : GL_RGBA;
+ const GLint glFormat = CAIROFORMAT == CAIRO_FORMAT_RGB96F ? GL_RGB : GL_RGBA;
+ const GLint glType = CAIROFORMAT == CAIRO_FORMAT_RGB96F ? GL_FLOAT : GL_UNSIGNED_BYTE;
+
+ const auto DATA = cairo_image_surface_get_data(cairo);
+ tex->bind();
+ tex->setTexParameter(GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ tex->setTexParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+
+ if (CAIROFORMAT != CAIRO_FORMAT_RGB96F) {
+ tex->setTexParameter(GL_TEXTURE_SWIZZLE_R, GL_BLUE);
+ tex->setTexParameter(GL_TEXTURE_SWIZZLE_B, GL_RED);
+ }
+
+ glTexImage2D(GL_TEXTURE_2D, 0, glIFormat, tex->m_size.x, tex->m_size.y, 0, glFormat, glType, DATA);
+
+ return tex;
+}
+
+SP<ITexture> CHyprRenderer::createTexture(std::span<const float> lut3D, size_t N) {
+ makeEGLCurrent();
+ return makeShared<CGLTexture>(lut3D, N);
+}
+
+SP<IFramebuffer> CHyprRenderer::createFB(const std::string& name) {
+ makeEGLCurrent();
+ return makeShared<CGLFramebuffer>(name);
} \ No newline at end of file