From 4152ac76d0813d9d0f67d2f04653a13fa6e17433 Mon Sep 17 00:00:00 2001 From: UjinT34 <41110182+UjinT34@users.noreply.github.com> Date: Sat, 7 Mar 2026 00:44:10 +0300 Subject: renderer: refactor Texture, Framebuffer and Renderbuffer (#13437) Part 1 of the renderer refactors --- src/render/Texture.cpp | 263 +++---------------------------------------------- 1 file changed, 11 insertions(+), 252 deletions(-) (limited to 'src/render/Texture.cpp') diff --git a/src/render/Texture.cpp b/src/render/Texture.cpp index 1a35e488..28ae4b41 100644 --- a/src/render/Texture.cpp +++ b/src/render/Texture.cpp @@ -1,265 +1,24 @@ #include "Texture.hpp" -#include "Renderer.hpp" -#include "../Compositor.hpp" -#include "../protocols/types/Buffer.hpp" -#include "../helpers/Format.hpp" #include -CTexture::CTexture() = default; - -CTexture::~CTexture() { - if (!g_pCompositor || g_pCompositor->m_isShuttingDown || !g_pHyprRenderer) - return; - - g_pHyprRenderer->makeEGLCurrent(); - destroyTexture(); -} - -CTexture::CTexture(uint32_t drmFormat, uint8_t* pixels, uint32_t stride, const Vector2D& size_, bool keepDataCopy) : m_drmFormat(drmFormat), m_keepDataCopy(keepDataCopy) { - createFromShm(drmFormat, pixels, stride, size_); -} - -CTexture::CTexture(const Aquamarine::SDMABUFAttrs& attrs, void* image) { - createFromDma(attrs, image); -} - -CTexture::CTexture(const SP buffer, bool keepDataCopy) : m_keepDataCopy(keepDataCopy) { - if (!buffer) - return; - - m_opaque = buffer->opaque; - - 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; - } - - auto [pixelData, fmt, bufLen] = buffer->beginDataPtr(0); - - m_drmFormat = fmt; - - createFromShm(fmt, pixelData, bufLen, shm.size); - return; +ITexture::ITexture(uint32_t drmFormat, uint8_t* pixels, uint32_t stride, const Vector2D& size, bool keepDataCopy, bool opaque) : + m_size(size), m_opaque(opaque), m_drmFormat(drmFormat), m_keepDataCopy(keepDataCopy) { + if (m_keepDataCopy && stride && pixels) { + m_dataCopy.resize(stride * size.y); + memcpy(m_dataCopy.data(), pixels, stride * size.y); } - - auto image = g_pHyprOpenGL->createEGLImage(buffer->dmabuf()); - - if (!image) { - Log::logger->log(Log::ERR, "Cannot create a texture: failed to create an EGLImage"); - return; - } - - createFromDma(attrs, image); } -CTexture::CTexture(std::span lut3D, size_t N) : m_type(TEXTURE_3D_LUT), m_target(GL_TEXTURE_3D), m_size(lut3D.size() / 3, 1), m_isSynchronous(true) { - allocate(); - bind(); - - GLCALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); - setTexParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR); - setTexParameter(GL_TEXTURE_MAG_FILTER, GL_LINEAR); - setTexParameter(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - setTexParameter(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - setTexParameter(GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); +ITexture::ITexture(std::span lut3D, size_t N) : m_type(TEXTURE_3D_LUT), m_size(lut3D.size() / 3, 1), m_isSynchronous(true) {} - // Expand RGB->RGBA on upload (alpha=1) - std::vector rgba; - rgba.resize(N * N * N * 4); - for (size_t i = 0, j = 0; i < N * N * N; ++i, j += 3) { - rgba[i * 4 + 0] = lut3D[j + 0]; - rgba[i * 4 + 1] = lut3D[j + 1]; - rgba[i * 4 + 2] = lut3D[j + 2]; - rgba[i * 4 + 3] = 1.F; - } - - GLCALL(glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA16F, N, N, N, 0, GL_RGBA, GL_FLOAT, rgba.data())); - - unbind(); +bool ITexture::ok() { + return false; } -void CTexture::createFromShm(uint32_t drmFormat, uint8_t* pixels, uint32_t stride, const Vector2D& size_) { - g_pHyprRenderer->makeEGLCurrent(); - - const auto format = NFormatUtils::getPixelFormatFromDRM(drmFormat); - ASSERT(format); - - m_type = format->withAlpha ? TEXTURE_RGBA : TEXTURE_RGBX; - m_size = size_; - m_isSynchronous = true; - m_target = GL_TEXTURE_2D; - allocate(); - bind(); - setTexParameter(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - setTexParameter(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - if (format->swizzle.has_value()) - swizzle(format->swizzle.value()); - - bool alignmentChanged = false; - if (format->bytesPerBlock != 4) { - const GLint alignment = (stride % 4 == 0) ? 4 : 1; - GLCALL(glPixelStorei(GL_UNPACK_ALIGNMENT, alignment)); - alignmentChanged = true; - } - - GLCALL(glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, stride / format->bytesPerBlock)); - GLCALL(glTexImage2D(GL_TEXTURE_2D, 0, format->glInternalFormat ? format->glInternalFormat : format->glFormat, size_.x, size_.y, 0, format->glFormat, format->glType, pixels)); - GLCALL(glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, 0)); - if (alignmentChanged) - GLCALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 4)); - - unbind(); - - if (m_keepDataCopy) { - m_dataCopy.resize(stride * size_.y); - memcpy(m_dataCopy.data(), pixels, stride * size_.y); - } -} - -void CTexture::createFromDma(const Aquamarine::SDMABUFAttrs& attrs, void* image) { - if (!g_pHyprOpenGL->m_proc.glEGLImageTargetTexture2DOES) { - Log::logger->log(Log::ERR, "Cannot create a dmabuf texture: no glEGLImageTargetTexture2DOES"); - return; - } - - m_opaque = NFormatUtils::isFormatOpaque(attrs.format); - - // #TODO external only formats should be external aswell. - // also needs a seperate color shader. - /*if (NFormatUtils::isFormatYUV(attrs.format)) { - m_target = GL_TEXTURE_EXTERNAL_OES; - m_type = TEXTURE_EXTERNAL; - } else {*/ - m_target = GL_TEXTURE_2D; - m_type = NFormatUtils::isFormatOpaque(attrs.format) ? TEXTURE_RGBX : TEXTURE_RGBA; - //} - - m_size = attrs.size; - allocate(); - m_eglImage = image; - - bind(); - setTexParameter(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - setTexParameter(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - GLCALL(g_pHyprOpenGL->m_proc.glEGLImageTargetTexture2DOES(m_target, image)); - unbind(); +bool ITexture::isDMA() { + return false; } -void CTexture::update(uint32_t drmFormat, uint8_t* pixels, uint32_t stride, const CRegion& damage) { - if (damage.empty()) - return; - - g_pHyprRenderer->makeEGLCurrent(); - - const auto format = NFormatUtils::getPixelFormatFromDRM(drmFormat); - ASSERT(format); - - bind(); - - if (format->swizzle.has_value()) - swizzle(format->swizzle.value()); - - bool alignmentChanged = false; - if (format->bytesPerBlock != 4) { - const GLint alignment = (stride % 4 == 0) ? 4 : 1; - GLCALL(glPixelStorei(GL_UNPACK_ALIGNMENT, alignment)); - alignmentChanged = true; - } - - GLCALL(glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, stride / format->bytesPerBlock)); - - damage.copy().intersect(CBox{{}, m_size}).forEachRect([&format, &pixels](const auto& rect) { - GLCALL(glPixelStorei(GL_UNPACK_SKIP_PIXELS_EXT, rect.x1)); - GLCALL(glPixelStorei(GL_UNPACK_SKIP_ROWS_EXT, rect.y1)); - - int width = rect.x2 - rect.x1; - int height = rect.y2 - rect.y1; - GLCALL(glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x1, rect.y1, width, height, format->glFormat, format->glType, pixels)); - }); - - if (alignmentChanged) - GLCALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 4)); - - GLCALL(glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, 0)); - GLCALL(glPixelStorei(GL_UNPACK_SKIP_PIXELS_EXT, 0)); - GLCALL(glPixelStorei(GL_UNPACK_SKIP_ROWS_EXT, 0)); - - unbind(); - - if (m_keepDataCopy) { - m_dataCopy.resize(stride * m_size.y); - memcpy(m_dataCopy.data(), pixels, stride * m_size.y); - } -} - -void CTexture::destroyTexture() { - if (m_texID) { - GLCALL(glDeleteTextures(1, &m_texID)); - m_texID = 0; - } - - if (m_eglImage) - g_pHyprOpenGL->m_proc.eglDestroyImageKHR(g_pHyprOpenGL->m_eglDisplay, m_eglImage); - m_eglImage = nullptr; - m_cachedStates.fill(std::nullopt); -} - -void CTexture::allocate() { - if (!m_texID) - GLCALL(glGenTextures(1, &m_texID)); -} - -const std::vector& CTexture::dataCopy() { +const std::vector& ITexture::dataCopy() { return m_dataCopy; } - -void CTexture::bind() { - GLCALL(glBindTexture(m_target, m_texID)); -} - -void CTexture::unbind() { - GLCALL(glBindTexture(m_target, 0)); -} - -constexpr std::optional CTexture::getCacheStateIndex(GLenum pname) { - switch (pname) { - case GL_TEXTURE_WRAP_S: return TEXTURE_PAR_WRAP_S; - case GL_TEXTURE_WRAP_T: return TEXTURE_PAR_WRAP_T; - case GL_TEXTURE_MAG_FILTER: return TEXTURE_PAR_MAG_FILTER; - case GL_TEXTURE_MIN_FILTER: return TEXTURE_PAR_MIN_FILTER; - case GL_TEXTURE_SWIZZLE_R: return TEXTURE_PAR_SWIZZLE_R; - case GL_TEXTURE_SWIZZLE_B: return TEXTURE_PAR_SWIZZLE_B; - default: return std::nullopt; - } -} - -void CTexture::setTexParameter(GLenum pname, GLint param) { - const auto cacheIndex = getCacheStateIndex(pname); - - if (!cacheIndex) { - GLCALL(glTexParameteri(m_target, pname, param)); - return; - } - - const auto idx = cacheIndex.value(); - - if (m_cachedStates[idx] == param) - return; - - m_cachedStates[idx] = param; - GLCALL(glTexParameteri(m_target, pname, param)); -} - -void CTexture::swizzle(const std::array& colors) { - setTexParameter(GL_TEXTURE_SWIZZLE_R, colors.at(0)); - setTexParameter(GL_TEXTURE_SWIZZLE_G, colors.at(1)); - setTexParameter(GL_TEXTURE_SWIZZLE_B, colors.at(2)); - setTexParameter(GL_TEXTURE_SWIZZLE_A, colors.at(3)); -} -- cgit v1.2.3