summaryrefslogtreecommitdiff
path: root/src/render/Texture.cpp
diff options
context:
space:
mode:
authorVaxry <43317083+vaxerski@users.noreply.github.com>2024-06-08 10:07:59 +0200
committerGitHub <noreply@github.com>2024-06-08 10:07:59 +0200
commit6967a31450441fc5605c05db6f65505dace4b263 (patch)
tree255a3cff7f3e2eb8a50c952eab9b270a7937561d /src/render/Texture.cpp
parentc31d9ef4172452f6f219f91d9b87a24d91f0cf3a (diff)
wayland/core: move to new impl (#6268)
* wayland/core/dmabuf: move to new impl it's the final countdown
Diffstat (limited to 'src/render/Texture.cpp')
-rw-r--r--src/render/Texture.cpp106
1 files changed, 101 insertions, 5 deletions
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));
+}