From 6967a31450441fc5605c05db6f65505dace4b263 Mon Sep 17 00:00:00 2001 From: Vaxry <43317083+vaxerski@users.noreply.github.com> Date: Sat, 8 Jun 2024 10:07:59 +0200 Subject: wayland/core: move to new impl (#6268) * wayland/core/dmabuf: move to new impl it's the final countdown --- src/render/Texture.cpp | 106 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 101 insertions(+), 5 deletions(-) (limited to 'src/render/Texture.cpp') diff --git a/src/render/Texture.cpp b/src/render/Texture.cpp index 1820d0fb..aef8e4ac 100644 --- a/src/render/Texture.cpp +++ b/src/render/Texture.cpp @@ -1,16 +1,54 @@ #include "Texture.hpp" +#include "Renderer.hpp" +#include "../Compositor.hpp" +#include "../protocols/types/Buffer.hpp" +#include "../helpers/Format.hpp" CTexture::CTexture() { // naffin' } +CTexture::~CTexture() { + if (m_bNonOwning) + return; + + g_pHyprRenderer->makeEGLCurrent(); + destroyTexture(); +} + +CTexture::CTexture(uint32_t drmFormat, uint8_t* pixels, uint32_t stride, const Vector2D& size_) { + g_pHyprRenderer->makeEGLCurrent(); + + const auto format = FormatUtils::getPixelFormatFromDRM(drmFormat); + ASSERT(format); + + m_iType = format->withAlpha ? TEXTURE_RGBA : TEXTURE_RGBX; + m_vSize = size_; + allocate(); + + GLCALL(glBindTexture(GL_TEXTURE_2D, m_iTexID)); + GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); + GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); +#ifndef GLES2 + if (format->flipRB) { + GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE)); + GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED)); + } +#endif + 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)); + GLCALL(glBindTexture(GL_TEXTURE_2D, 0)); +} + CTexture::CTexture(wlr_texture* tex) { RASSERT(wlr_texture_is_gles2(tex), "wlr_texture provided to CTexture that isn't GLES2!"); wlr_gles2_texture_attribs attrs; wlr_gles2_texture_get_attribs(tex, &attrs); - m_iTarget = attrs.target; - m_iTexID = attrs.tex; + m_iTarget = attrs.target; + m_iTexID = attrs.tex; + m_bNonOwning = true; if (m_iTarget == GL_TEXTURE_2D) m_iType = attrs.has_alpha ? TEXTURE_RGBA : TEXTURE_RGBX; @@ -20,14 +58,72 @@ CTexture::CTexture(wlr_texture* tex) { m_vSize = Vector2D(tex->width, tex->height); } +CTexture::CTexture(const SDMABUFAttrs& attrs, void* image) { + if (!g_pHyprOpenGL->m_sProc.glEGLImageTargetTexture2DOES) { + Debug::log(ERR, "Cannot create a dmabuf texture: no glEGLImageTargetTexture2DOES"); + return; + } + + m_iTarget = GL_TEXTURE_2D; + m_iType = TEXTURE_RGBA; + m_vSize = attrs.size; + m_iType = FormatUtils::isFormatOpaque(attrs.format) ? TEXTURE_RGBX : TEXTURE_RGBA; + allocate(); + m_pEglImage = image; + + GLCALL(glBindTexture(GL_TEXTURE_2D, m_iTexID)); + GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); + GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); + GLCALL(g_pHyprOpenGL->m_sProc.glEGLImageTargetTexture2DOES(m_iTarget, image)); + GLCALL(glBindTexture(GL_TEXTURE_2D, 0)); +} + +void CTexture::update(uint32_t drmFormat, uint8_t* pixels, uint32_t stride, const CRegion& damage) { + g_pHyprRenderer->makeEGLCurrent(); + + const auto format = FormatUtils::getPixelFormatFromDRM(drmFormat); + ASSERT(format); + + glBindTexture(GL_TEXTURE_2D, m_iTexID); + + auto rects = damage.copy().intersect(CBox{{}, m_vSize}).getRects(); + +#ifndef GLES2 + if (format->flipRB) { + GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE)); + GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED)); + } +#endif + + for (auto& rect : rects) { + GLCALL(glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, stride / format->bytesPerBlock)); + 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)); + } + + GLCALL(glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, 0)); + GLCALL(glPixelStorei(GL_UNPACK_SKIP_PIXELS_EXT, 0)); + GLCALL(glPixelStorei(GL_UNPACK_SKIP_ROWS_EXT, 0)); + + glBindTexture(GL_TEXTURE_2D, 0); +} + void CTexture::destroyTexture() { if (m_iTexID) { - glDeleteTextures(1, &m_iTexID); + GLCALL(glDeleteTextures(1, &m_iTexID)); m_iTexID = 0; } + + if (m_pEglImage) + g_pHyprOpenGL->m_sProc.eglDestroyImageKHR(wlr_egl_get_display(g_pCompositor->m_sWLREGL), m_pEglImage); + m_pEglImage = nullptr; } void CTexture::allocate() { if (!m_iTexID) - glGenTextures(1, &m_iTexID); -} \ No newline at end of file + GLCALL(glGenTextures(1, &m_iTexID)); +} -- cgit v1.2.3