diff options
author | Vaxry <[email protected]> | 2024-06-08 10:07:59 +0200 |
---|---|---|
committer | GitHub <[email protected]> | 2024-06-08 10:07:59 +0200 |
commit | 6967a31450441fc5605c05db6f65505dace4b263 (patch) | |
tree | 255a3cff7f3e2eb8a50c952eab9b270a7937561d /src/render/OpenGL.cpp | |
parent | c31d9ef4172452f6f219f91d9b87a24d91f0cf3a (diff) | |
download | Hyprland-6967a31450441fc5605c05db6f65505dace4b263.tar.gz Hyprland-6967a31450441fc5605c05db6f65505dace4b263.zip |
wayland/core: move to new impl (#6268)
* wayland/core/dmabuf: move to new impl
it's the final countdown
Diffstat (limited to 'src/render/OpenGL.cpp')
-rw-r--r-- | src/render/OpenGL.cpp | 453 |
1 files changed, 257 insertions, 196 deletions
diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index a1e6f73e..d4e8faa6 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -7,6 +7,8 @@ #include "../config/ConfigValue.hpp" #include "../desktop/LayerSurface.hpp" #include "../protocols/LayerShell.hpp" +#include "../protocols/core/Compositor.hpp" +#include <xf86drm.h> inline void loadGLProc(void* pProc, const char* name) { void* proc = (void*)eglGetProcAddress(name); @@ -21,7 +23,8 @@ CHyprOpenGLImpl::CHyprOpenGLImpl() { RASSERT(eglMakeCurrent(wlr_egl_get_display(g_pCompositor->m_sWLREGL), EGL_NO_SURFACE, EGL_NO_SURFACE, wlr_egl_get_context(g_pCompositor->m_sWLREGL)), "Couldn't unset current EGL!"); - auto* const EXTENSIONS = (const char*)glGetString(GL_EXTENSIONS); + auto* const EXTENSIONS = (const char*)glGetString(GL_EXTENSIONS); + const std::string EGLEXTENSIONS = (const char*)eglQueryString(wlr_egl_get_display(g_pCompositor->m_sWLREGL), EGL_EXTENSIONS); RASSERT(EXTENSIONS, "Couldn't retrieve openGL extensions!"); @@ -33,12 +36,25 @@ CHyprOpenGLImpl::CHyprOpenGLImpl() { Debug::log(LOG, "Using: {}", (char*)glGetString(GL_VERSION)); Debug::log(LOG, "Vendor: {}", (char*)glGetString(GL_VENDOR)); Debug::log(LOG, "Renderer: {}", (char*)glGetString(GL_RENDERER)); - Debug::log(LOG, "Supported extensions size: {}", std::count(m_szExtensions.begin(), m_szExtensions.end(), ' ')); + Debug::log(LOG, "Supported extensions: ({}) {}", std::count(m_szExtensions.begin(), m_szExtensions.end(), ' '), m_szExtensions); loadGLProc(&m_sProc.glEGLImageTargetRenderbufferStorageOES, "glEGLImageTargetRenderbufferStorageOES"); + loadGLProc(&m_sProc.eglCreateImageKHR, "eglCreateImageKHR"); loadGLProc(&m_sProc.eglDestroyImageKHR, "eglDestroyImageKHR"); + loadGLProc(&m_sProc.eglQueryDmaBufFormatsEXT, "eglQueryDmaBufFormatsEXT"); + loadGLProc(&m_sProc.eglQueryDmaBufModifiersEXT, "eglQueryDmaBufModifiersEXT"); + loadGLProc(&m_sProc.glEGLImageTargetTexture2DOES, "glEGLImageTargetTexture2DOES"); - m_sExts.EXT_read_format_bgra = m_szExtensions.contains("GL_EXT_read_format_bgra"); + m_sExts.EXT_read_format_bgra = m_szExtensions.contains("GL_EXT_read_format_bgra"); + m_sExts.EXT_image_dma_buf_import = EGLEXTENSIONS.contains("EXT_image_dma_buf_import"); + m_sExts.EXT_image_dma_buf_import_modifiers = EGLEXTENSIONS.contains("EXT_image_dma_buf_import_modifiers"); + + RASSERT(m_szExtensions.contains("GL_EXT_texture_format_BGRA8888"), "GL_EXT_texture_format_BGRA8888 support by the GPU driver is required"); + + if (!m_sExts.EXT_read_format_bgra) + Debug::log(WARN, "Your GPU does not support GL_EXT_read_format_bgra, this may cause issues with texture importing"); + if (!m_sExts.EXT_image_dma_buf_import || !m_sExts.EXT_image_dma_buf_import_modifiers) + Debug::log(WARN, "Your GPU does not support DMABUFs, this will possibly cause issues and will take a hit on the performance."); #ifdef USE_TRACY_GPU @@ -54,6 +70,8 @@ CHyprOpenGLImpl::CHyprOpenGLImpl() { Debug::log(WARN, "!RENDERER: Using the legacy GLES2 renderer!"); #endif + initDRMFormats(); + static auto P = g_pHookSystem->hookDynamic("preRender", [&](void* self, SCallbackInfo& info, std::any data) { preRender(std::any_cast<CMonitor*>(data)); }); RASSERT(eglMakeCurrent(wlr_egl_get_display(g_pCompositor->m_sWLREGL), EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT), "Couldn't unset current EGL!"); @@ -61,6 +79,171 @@ CHyprOpenGLImpl::CHyprOpenGLImpl() { m_tGlobalTimer.reset(); } +std::vector<uint64_t> CHyprOpenGLImpl::getModsForFormat(EGLint format) { + // TODO: return std::expected when clang supports it + + if (!m_sExts.EXT_image_dma_buf_import_modifiers) + return {}; + + EGLint len = 0; + if (!m_sProc.eglQueryDmaBufModifiersEXT(wlr_egl_get_display(g_pCompositor->m_sWLREGL), format, 0, nullptr, nullptr, &len)) { + Debug::log(ERR, "EGL: Failed to query mods"); + return {}; + } + + if (len <= 0) + return {}; + + std::vector<uint64_t> mods; + std::vector<EGLBoolean> external; + + mods.resize(len); + external.resize(len); + + m_sProc.eglQueryDmaBufModifiersEXT(wlr_egl_get_display(g_pCompositor->m_sWLREGL), format, len, mods.data(), external.data(), &len); + + std::vector<uint64_t> result; + for (size_t i = 0; i < mods.size(); ++i) { + if (external.at(i)) + continue; + + result.push_back(mods.at(i)); + } + + return result; +} + +void CHyprOpenGLImpl::initDRMFormats() { + const auto DISABLE_MODS = envEnabled("HYPRLAND_EGL_NO_MODIFIERS"); + if (DISABLE_MODS) + Debug::log(WARN, "HYPRLAND_EGL_NO_MODIFIERS set, disabling modifiers"); + + if (!m_sExts.EXT_image_dma_buf_import) { + Debug::log(ERR, "EGL: No dmabuf import, DMABufs will not work."); + return; + } + + std::vector<EGLint> formats; + + if (!m_sExts.EXT_image_dma_buf_import_modifiers || !m_sProc.eglQueryDmaBufFormatsEXT) { + formats.push_back(DRM_FORMAT_ARGB8888); + formats.push_back(DRM_FORMAT_XRGB8888); + Debug::log(WARN, "EGL: No mod support"); + } else { + EGLint len = 0; + m_sProc.eglQueryDmaBufFormatsEXT(wlr_egl_get_display(g_pCompositor->m_sWLREGL), 0, nullptr, &len); + formats.resize(len); + m_sProc.eglQueryDmaBufFormatsEXT(wlr_egl_get_display(g_pCompositor->m_sWLREGL), len, formats.data(), &len); + } + + if (formats.size() == 0) { + Debug::log(ERR, "EGL: Failed to get formats, DMABufs will not work."); + return; + } + + wlr_log(WLR_DEBUG, "Supported DMA-BUF formats:"); + + std::vector<SDRMFormat> dmaFormats; + + for (auto& fmt : formats) { + std::vector<uint64_t> mods; + if (!DISABLE_MODS) + mods = getModsForFormat(fmt); + else + mods = {DRM_FORMAT_MOD_LINEAR}; + + m_bHasModifiers = m_bHasModifiers || mods.size() > 0; + + if (mods.size() == 0) + continue; + + dmaFormats.push_back(SDRMFormat{ + .format = fmt, + .mods = mods, + }); + + std::vector<std::pair<uint64_t, std::string>> modifierData; + + auto fmtName = drmGetFormatName(fmt); + Debug::log(LOG, "EGL: GPU Supports Format {} (0x{:x})", fmtName ? fmtName : "?unknown?", fmt); + for (auto& mod : mods) { + auto modName = drmGetFormatModifierName(mod); + modifierData.emplace_back(std::make_pair<>(mod, modName ? modName : "?unknown?")); + free(modName); + } + free(fmtName); + + mods.clear(); + std::sort(modifierData.begin(), modifierData.end(), [](const auto& a, const auto& b) { + if (a.first == 0) + return false; + if (a.second.contains("DCC")) + return false; + return true; + }); + + for (auto& [m, name] : modifierData) { + Debug::log(LOG, "EGL: | with modifier {} (0x{:x})", name, m); + mods.emplace_back(m); + } + } + + Debug::log(LOG, "EGL: {} formats found in total. Some modifiers may be omitted as they are external-only.", dmaFormats.size()); + + drmFormats = dmaFormats; +} + +EGLImageKHR CHyprOpenGLImpl::createEGLImage(const SDMABUFAttrs& attrs) { + std::vector<uint32_t> attribs; + + attribs.push_back(EGL_WIDTH); + attribs.push_back(attrs.size.x); + attribs.push_back(EGL_HEIGHT); + attribs.push_back(attrs.size.y); + attribs.push_back(EGL_LINUX_DRM_FOURCC_EXT); + attribs.push_back(attrs.format); + + struct { + EGLint fd; + EGLint offset; + EGLint pitch; + EGLint modlo; + EGLint modhi; + } attrNames[4] = { + {EGL_DMA_BUF_PLANE0_FD_EXT, EGL_DMA_BUF_PLANE0_OFFSET_EXT, EGL_DMA_BUF_PLANE0_PITCH_EXT, EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT, EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT}, + {EGL_DMA_BUF_PLANE1_FD_EXT, EGL_DMA_BUF_PLANE1_OFFSET_EXT, EGL_DMA_BUF_PLANE1_PITCH_EXT, EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT, EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT}, + {EGL_DMA_BUF_PLANE2_FD_EXT, EGL_DMA_BUF_PLANE2_OFFSET_EXT, EGL_DMA_BUF_PLANE2_PITCH_EXT, EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT, EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT}, + {EGL_DMA_BUF_PLANE3_FD_EXT, EGL_DMA_BUF_PLANE3_OFFSET_EXT, EGL_DMA_BUF_PLANE3_PITCH_EXT, EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT, EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT}}; + + for (int i = 0; i < attrs.planes; i++) { + attribs.push_back(attrNames[i].fd); + attribs.push_back(attrs.fds[i]); + attribs.push_back(attrNames[i].offset); + attribs.push_back(attrs.offsets[i]); + attribs.push_back(attrNames[i].pitch); + attribs.push_back(attrs.strides[i]); + if (m_bHasModifiers && attrs.modifier != DRM_FORMAT_MOD_INVALID) { + attribs.push_back(attrNames[i].modlo); + attribs.push_back(attrs.modifier & 0xFFFFFFFF); + attribs.push_back(attrNames[i].modhi); + attribs.push_back(attrs.modifier >> 32); + } + } + + attribs.push_back(EGL_IMAGE_PRESERVED_KHR); + attribs.push_back(EGL_TRUE); + + attribs.push_back(EGL_NONE); + + EGLImageKHR image = m_sProc.eglCreateImageKHR(wlr_egl_get_display(g_pCompositor->m_sWLREGL), EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, nullptr, (int*)attribs.data()); + if (image == EGL_NO_IMAGE_KHR) { + Debug::log(ERR, "EGL: EGLCreateImageKHR failed: {}", eglGetError()); + return EGL_NO_IMAGE_KHR; + } + + return image; +} + void CHyprOpenGLImpl::logShaderError(const GLuint& shader, bool program) { GLint maxLength = 0; if (program) @@ -339,12 +522,12 @@ void CHyprOpenGLImpl::begin(CMonitor* pMonitor, const CRegion& damage_, CFramebu // ensure a framebuffer for the monitor exists if (m_RenderData.pCurrentMonData->offloadFB.m_vSize != pMonitor->vecPixelSize) { - m_RenderData.pCurrentMonData->stencilTex.allocate(); + m_RenderData.pCurrentMonData->stencilTex->allocate(); - m_RenderData.pCurrentMonData->offloadFB.m_pStencilTex = &m_RenderData.pCurrentMonData->stencilTex; - m_RenderData.pCurrentMonData->mirrorFB.m_pStencilTex = &m_RenderData.pCurrentMonData->stencilTex; - m_RenderData.pCurrentMonData->mirrorSwapFB.m_pStencilTex = &m_RenderData.pCurrentMonData->stencilTex; - m_RenderData.pCurrentMonData->offMainFB.m_pStencilTex = &m_RenderData.pCurrentMonData->stencilTex; + m_RenderData.pCurrentMonData->offloadFB.m_pStencilTex = m_RenderData.pCurrentMonData->stencilTex; + m_RenderData.pCurrentMonData->mirrorFB.m_pStencilTex = m_RenderData.pCurrentMonData->stencilTex; + m_RenderData.pCurrentMonData->mirrorSwapFB.m_pStencilTex = m_RenderData.pCurrentMonData->stencilTex; + m_RenderData.pCurrentMonData->offMainFB.m_pStencilTex = m_RenderData.pCurrentMonData->stencilTex; m_RenderData.pCurrentMonData->offloadFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y, pMonitor->drmFormat); m_RenderData.pCurrentMonData->mirrorFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y, pMonitor->drmFormat); @@ -381,8 +564,8 @@ void CHyprOpenGLImpl::begin(CMonitor* pMonitor, const CRegion& damage_, CFramebu // we can render to the rbo / fbo (fake) directly const auto PFBO = fb ? fb : PRBO->getFB(); m_RenderData.currentFB = PFBO; - if (PFBO->m_pStencilTex != &m_RenderData.pCurrentMonData->stencilTex) { - PFBO->m_pStencilTex = &m_RenderData.pCurrentMonData->stencilTex; + if (PFBO->m_pStencilTex != m_RenderData.pCurrentMonData->stencilTex) { + PFBO->m_pStencilTex = m_RenderData.pCurrentMonData->stencilTex; PFBO->addStencil(); } PFBO->bind(); @@ -863,19 +1046,7 @@ void CHyprOpenGLImpl::renderRectWithDamage(CBox* box, const CColor& col, CRegion scissor((CBox*)nullptr); } -void CHyprOpenGLImpl::renderTexture(wlr_texture* tex, CBox* pBox, float alpha, int round, bool allowCustomUV) { - RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!"); - - renderTexture(CTexture(tex), pBox, alpha, round, false, allowCustomUV); -} - -void CHyprOpenGLImpl::renderTextureWithDamage(wlr_texture* tex, CBox* pBox, CRegion* damage, float alpha, int round, bool allowCustomUV) { - RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!"); - - renderTextureWithDamage(CTexture(tex), pBox, damage, alpha, round, false, allowCustomUV); -} - -void CHyprOpenGLImpl::renderTexture(const CTexture& tex, CBox* pBox, float alpha, int round, bool discardActive, bool allowCustomUV) { +void CHyprOpenGLImpl::renderTexture(SP<CTexture> tex, CBox* pBox, float alpha, int round, bool discardActive, bool allowCustomUV) { RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!"); renderTextureInternalWithDamage(tex, pBox, alpha, &m_RenderData.damage, round, discardActive, false, allowCustomUV, true); @@ -883,7 +1054,7 @@ void CHyprOpenGLImpl::renderTexture(const CTexture& tex, CBox* pBox, float alpha scissor((CBox*)nullptr); } -void CHyprOpenGLImpl::renderTextureWithDamage(const CTexture& tex, CBox* pBox, CRegion* damage, float alpha, int round, bool discardActive, bool allowCustomUV) { +void CHyprOpenGLImpl::renderTextureWithDamage(SP<CTexture> tex, CBox* pBox, CRegion* damage, float alpha, int round, bool discardActive, bool allowCustomUV) { RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!"); renderTextureInternalWithDamage(tex, pBox, alpha, damage, round, discardActive, false, allowCustomUV, true); @@ -891,10 +1062,10 @@ void CHyprOpenGLImpl::renderTextureWithDamage(const CTexture& tex, CBox* pBox, C scissor((CBox*)nullptr); } -void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, CBox* pBox, float alpha, CRegion* damage, int round, bool discardActive, bool noAA, bool allowCustomUV, +void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP<CTexture> tex, CBox* pBox, float alpha, CRegion* damage, int round, bool discardActive, bool noAA, bool allowCustomUV, bool allowDim) { RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!"); - RASSERT((tex.m_iTexID > 0), "Attempted to draw NULL texture!"); + RASSERT((tex->m_iTexID > 0), "Attempted to draw NULL texture!"); TRACY_GPU_ZONE("RenderTextureInternalWithDamage"); @@ -934,11 +1105,11 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, CBox* shader = &m_RenderData.pCurrentMonData->m_shPASSTHRURGBA; usingFinalShader = true; } else { - switch (tex.m_iType) { + switch (tex->m_iType) { case TEXTURE_RGBA: shader = &m_RenderData.pCurrentMonData->m_shRGBA; break; case TEXTURE_RGBX: shader = &m_RenderData.pCurrentMonData->m_shRGBX; break; case TEXTURE_EXTERNAL: shader = &m_RenderData.pCurrentMonData->m_shEXT; break; - default: RASSERT(false, "tex.m_iTarget unsupported!"); + default: RASSERT(false, "tex->m_iTarget unsupported!"); } } } @@ -947,14 +1118,14 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, CBox* shader = &m_RenderData.pCurrentMonData->m_shRGBX; glActiveTexture(GL_TEXTURE0); - glBindTexture(tex.m_iTarget, tex.m_iTexID); + glBindTexture(tex->m_iTarget, tex->m_iTexID); if (m_RenderData.useNearestNeighbor) { - glTexParameteri(tex.m_iTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(tex.m_iTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(tex->m_iTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(tex->m_iTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } else { - glTexParameteri(tex.m_iTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(tex.m_iTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(tex->m_iTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(tex->m_iTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } glUseProgram(shader->program); @@ -1057,12 +1228,12 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, CBox* glDisableVertexAttribArray(shader->posAttrib); glDisableVertexAttribArray(shader->texAttrib); - glBindTexture(tex.m_iTarget, 0); + glBindTexture(tex->m_iTarget, 0); } -void CHyprOpenGLImpl::renderTexturePrimitive(const CTexture& tex, CBox* pBox) { +void CHyprOpenGLImpl::renderTexturePrimitive(SP<CTexture> tex, CBox* pBox) { RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!"); - RASSERT((tex.m_iTexID > 0), "Attempted to draw NULL texture!"); + RASSERT((tex->m_iTexID > 0), "Attempted to draw NULL texture!"); TRACY_GPU_ZONE("RenderTexturePrimitive"); @@ -1083,7 +1254,7 @@ void CHyprOpenGLImpl::renderTexturePrimitive(const CTexture& tex, CBox* pBox) { CShader* shader = &m_RenderData.pCurrentMonData->m_shPASSTHRURGBA; glActiveTexture(GL_TEXTURE0); - glBindTexture(tex.m_iTarget, tex.m_iTexID); + glBindTexture(tex->m_iTarget, tex->m_iTexID); glUseProgram(shader->program); @@ -1111,12 +1282,12 @@ void CHyprOpenGLImpl::renderTexturePrimitive(const CTexture& tex, CBox* pBox) { glDisableVertexAttribArray(shader->posAttrib); glDisableVertexAttribArray(shader->texAttrib); - glBindTexture(tex.m_iTarget, 0); + glBindTexture(tex->m_iTarget, 0); } -void CHyprOpenGLImpl::renderTextureMatte(const CTexture& tex, CBox* pBox, CFramebuffer& matte) { +void CHyprOpenGLImpl::renderTextureMatte(SP<CTexture> tex, CBox* pBox, CFramebuffer& matte) { RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!"); - RASSERT((tex.m_iTexID > 0), "Attempted to draw NULL texture!"); + RASSERT((tex->m_iTexID > 0), "Attempted to draw NULL texture!"); TRACY_GPU_ZONE("RenderTextureMatte"); @@ -1148,10 +1319,10 @@ void CHyprOpenGLImpl::renderTextureMatte(const CTexture& tex, CBox* pBox, CFrame glUniform1i(shader->alphaMatte, 1); glActiveTexture(GL_TEXTURE0); - glBindTexture(tex.m_iTarget, tex.m_iTexID); + glBindTexture(tex->m_iTarget, tex->m_iTexID); glActiveTexture(GL_TEXTURE0 + 1); - glBindTexture(matte.m_cTex.m_iTarget, matte.m_cTex.m_iTexID); + glBindTexture(matte.m_cTex->m_iTarget, matte.m_cTex->m_iTexID); glVertexAttribPointer(shader->posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts); glVertexAttribPointer(shader->texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts); @@ -1169,7 +1340,7 @@ void CHyprOpenGLImpl::renderTextureMatte(const CTexture& tex, CBox* pBox, CFrame glDisableVertexAttribArray(shader->posAttrib); glDisableVertexAttribArray(shader->texAttrib); - glBindTexture(tex.m_iTarget, 0); + glBindTexture(tex->m_iTarget, 0); } // This probably isn't the fastest @@ -1221,9 +1392,9 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o glActiveTexture(GL_TEXTURE0); - glBindTexture(m_RenderData.currentFB->m_cTex.m_iTarget, m_RenderData.currentFB->m_cTex.m_iTexID); + glBindTexture(m_RenderData.currentFB->m_cTex->m_iTarget, m_RenderData.currentFB->m_cTex->m_iTexID); - glTexParameteri(m_RenderData.currentFB->m_cTex.m_iTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(m_RenderData.currentFB->m_cTex->m_iTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glUseProgram(m_RenderData.pCurrentMonData->m_shBLURPREPARE.program); @@ -1265,9 +1436,9 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o glActiveTexture(GL_TEXTURE0); - glBindTexture(currentRenderToFB->m_cTex.m_iTarget, currentRenderToFB->m_cTex.m_iTexID); + glBindTexture(currentRenderToFB->m_cTex->m_iTarget, currentRenderToFB->m_cTex->m_iTexID); - glTexParameteri(currentRenderToFB->m_cTex.m_iTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(currentRenderToFB->m_cTex->m_iTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glUseProgram(pShader->program); @@ -1315,7 +1486,7 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o // draw the things. // first draw is swap -> mirr PMIRRORFB->bind(); - glBindTexture(PMIRRORSWAPFB->m_cTex.m_iTarget, PMIRRORSWAPFB->m_cTex.m_iTexID); + glBindTexture(PMIRRORSWAPFB->m_cTex->m_iTarget, PMIRRORSWAPFB->m_cTex->m_iTexID); // damage region will be scaled, make a temp CRegion tempDamage{damage}; @@ -1343,9 +1514,9 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o glActiveTexture(GL_TEXTURE0); - glBindTexture(currentRenderToFB->m_cTex.m_iTarget, currentRenderToFB->m_cTex.m_iTexID); + glBindTexture(currentRenderToFB->m_cTex->m_iTarget, currentRenderToFB->m_cTex->m_iTexID); - glTexParameteri(currentRenderToFB->m_cTex.m_iTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(currentRenderToFB->m_cTex->m_iTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glUseProgram(m_RenderData.pCurrentMonData->m_shBLURFINISH.program); @@ -1383,7 +1554,7 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o } // finish - glBindTexture(PMIRRORFB->m_cTex.m_iTarget, 0); + glBindTexture(PMIRRORFB->m_cTex->m_iTarget, 0); blend(BLENDBEFORE); @@ -1417,23 +1588,23 @@ void CHyprOpenGLImpl::preRender(CMonitor* pMonitor) { if (pWindow->m_sAdditionalConfigData.forceNoBlur) return false; - if (pWindow->m_pWLSurface.small() && !pWindow->m_pWLSurface.m_bFillIgnoreSmall) + if (pWindow->m_pWLSurface->small() && !pWindow->m_pWLSurface->m_bFillIgnoreSmall) return true; - const auto PSURFACE = pWindow->m_pWLSurface.wlr(); + const auto PSURFACE = pWindow->m_pWLSurface->resource(); const auto PWORKSPACE = pWindow->m_pWorkspace; const float A = pWindow->m_fAlpha.value() * pWindow->m_fActiveInactiveAlpha.value() * PWORKSPACE->m_fAlpha.value(); if (A >= 1.f) { - if (PSURFACE->opaque) - return false; + // if (PSURFACE->opaque) + // return false; CRegion inverseOpaque; - pixman_box32_t surfbox = {0, 0, PSURFACE->current.width, PSURFACE->current.height}; - CRegion opaqueRegion{&PSURFACE->current.opaque}; - inverseOpaque.set(opaqueRegion).invert(&surfbox).intersect(0, 0, PSURFACE->current.width, PSURFACE->current.height); + pixman_box32_t surfbox = {0, 0, PSURFACE->current.size.x, PSURFACE->current.size.y}; + CRegion opaqueRegion{PSURFACE->current.opaque}; + inverseOpaque.set(opaqueRegion).invert(&surfbox).intersect(0, 0, PSURFACE->current.size.x, PSURFACE->current.size.y); if (inverseOpaque.empty()) return false; @@ -1461,8 +1632,8 @@ void CHyprOpenGLImpl::preRender(CMonitor* pMonitor) { if (!ls->layerSurface || ls->xray != 1) continue; - if (ls->layerSurface->surface->opaque && ls->alpha.value() >= 1.f) - continue; + // if (ls->layerSurface->surface->opaque && ls->alpha.value() >= 1.f) + // continue; hasWindows = true; break; @@ -1527,7 +1698,7 @@ bool CHyprOpenGLImpl::shouldUseNewBlurOptimizations(PHLLS pLayer, PHLWINDOW pWin static auto PBLURNEWOPTIMIZE = CConfigValue<Hyprlang::INT>("decoration:blur:new_optimizations"); static auto PBLURXRAY = CConfigValue<Hyprlang::INT>("decoration:blur:xray"); - if (!m_RenderData.pCurrentMonData->blurFB.m_cTex.m_iTexID) + if (!m_RenderData.pCurrentMonData->blurFB.m_cTex->m_iTexID) return false; if (pWindow && pWindow->m_sAdditionalConfigData.xray.toUnderlying() == 0) @@ -1545,7 +1716,7 @@ bool CHyprOpenGLImpl::shouldUseNewBlurOptimizations(PHLLS pLayer, PHLWINDOW pWin return false; } -void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, CBox* pBox, float a, wlr_surface* pSurface, int round, bool blockBlurOptimization, float blurA) { +void CHyprOpenGLImpl::renderTextureWithBlur(SP<CTexture> tex, CBox* pBox, float a, SP<CWLSurfaceResource> pSurface, int round, bool blockBlurOptimization, float blurA) { RASSERT(m_RenderData.pMonitor, "Tried to render texture with blur without begin()!"); static auto PBLURENABLED = CConfigValue<Hyprlang::INT>("decoration:blur:enabled"); @@ -1570,11 +1741,11 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, CBox* pBox, flo // amazing hack: the surface has an opaque region! CRegion inverseOpaque; - if (a >= 1.f && std::round(pSurface->current.width * m_RenderData.pMonitor->scale) == pBox->w && - std::round(pSurface->current.height * m_RenderData.pMonitor->scale) == pBox->h) { - pixman_box32_t surfbox = {0, 0, pSurface->current.width * pSurface->current.scale, pSurface->current.height * pSurface->current.scale}; - inverseOpaque = &pSurface->current.opaque; - inverseOpaque.invert(&surfbox).intersect(0, 0, pSurface->current.width * pSurface->current.scale, pSurface->current.height * pSurface->current.scale); + if (a >= 1.f && std::round(pSurface->current.size.x * m_RenderData.pMonitor->scale) == pBox->w && + std::round(pSurface->current.size.y * m_RenderData.pMonitor->scale) == pBox->h) { + pixman_box32_t surfbox = {0, 0, pSurface->current.size.x * pSurface->current.scale, pSurface->current.size.y * pSurface->current.scale}; + inverseOpaque = pSurface->current.opaque; + inverseOpaque.invert(&surfbox).intersect(0, 0, pSurface->current.size.x * pSurface->current.scale, pSurface->current.size.y * pSurface->current.scale); if (inverseOpaque.empty()) { renderTexture(tex, pBox, a, round, false, true); @@ -1765,7 +1936,7 @@ void CHyprOpenGLImpl::makeRawWindowSnapshot(PHLWINDOW pWindow, CFramebuffer* pFr g_pHyprRenderer->makeEGLCurrent(); - pFramebuffer->m_pStencilTex = &m_RenderData.pCurrentMonData->stencilTex; + pFramebuffer->m_pStencilTex = m_RenderData.pCurrentMonData->stencilTex; pFramebuffer->alloc(PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y, PMONITOR->drmFormat); @@ -1903,7 +2074,7 @@ void CHyprOpenGLImpl::renderSnapshot(PHLWINDOW pWindow) { const auto FBDATA = &m_mWindowFramebuffers.at(ref); - if (!FBDATA->m_cTex.m_iTexID) + if (!FBDATA->m_cTex->m_iTexID) return; const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID); @@ -1942,7 +2113,7 @@ void CHyprOpenGLImpl::renderSnapshot(PHLLS pLayer) { const auto FBDATA = &m_mLayerFramebuffers.at(pLayer); - if (!FBDATA->m_cTex.m_iTexID) + if (!FBDATA->m_cTex->m_iTexID) return; const auto PMONITOR = g_pCompositor->getMonitorFromID(pLayer->monitorID); @@ -2077,7 +2248,7 @@ void CHyprOpenGLImpl::renderMirrored() { monbox.y = (monitor->vecTransformedSize.y - monbox.h) / 2; const auto PFB = &m_mMonitorRenderResources[mirrored].monitorMirrorFB; - if (!PFB->isAllocated() || PFB->m_cTex.m_iTexID <= 0) + if (!PFB->isAllocated() || PFB->m_cTex->m_iTexID <= 0) return; // replace monitor projection to undo the mirrored monitor's projection @@ -2179,12 +2350,12 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(CMonitor* pMonitor) { } // create a new one with cairo - CTexture tex; + SP<CTexture> tex = makeShared<CTexture>(); - const auto CAIROISURFACE = cairo_image_surface_create_from_png(texPath.c_str()); - const auto CAIROFORMAT = cairo_image_surface_get_format(CAIROISURFACE); + const auto CAIROISURFACE = cairo_image_surface_create_from_png(texPath.c_str()); + const auto CAIROFORMAT = cairo_image_surface_get_format(CAIROISURFACE); - tex.allocate(); + tex->allocate(); const Vector2D IMAGESIZE = {cairo_image_surface_get_width(CAIROISURFACE), cairo_image_surface_get_height(CAIROISURFACE)}; // calc the target box @@ -2220,8 +2391,8 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(CMonitor* pMonitor) { cairo_surface_flush(CAIROSURFACE); - CBox box = {origin.x, origin.y, IMAGESIZE.x * scale, IMAGESIZE.y * scale}; - tex.m_vSize = IMAGESIZE * scale; + CBox box = {origin.x, origin.y, IMAGESIZE.x * scale, IMAGESIZE.y * scale}; + tex->m_vSize = IMAGESIZE * scale; // copy the data to an OpenGL texture we have const GLint glIFormat = CAIROFORMAT == CAIRO_FORMAT_RGB96F ? @@ -2235,7 +2406,7 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(CMonitor* pMonitor) { const GLint glType = CAIROFORMAT == CAIRO_FORMAT_RGB96F ? GL_FLOAT : GL_UNSIGNED_BYTE; const auto DATA = cairo_image_surface_get_data(CAIROSURFACE); - glBindTexture(GL_TEXTURE_2D, tex.m_iTexID); + glBindTexture(GL_TEXTURE_2D, tex->m_iTexID); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); #ifndef GLES2 @@ -2244,7 +2415,7 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(CMonitor* pMonitor) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED); } #endif - glTexImage2D(GL_TEXTURE_2D, 0, glIFormat, tex.m_vSize.x, tex.m_vSize.y, 0, glFormat, glType, DATA); + glTexImage2D(GL_TEXTURE_2D, 0, glIFormat, tex->m_vSize.x, tex->m_vSize.y, 0, glFormat, glType, DATA); cairo_surface_destroy(CAIROSURFACE); cairo_surface_destroy(CAIROISURFACE); @@ -2293,7 +2464,7 @@ void CHyprOpenGLImpl::destroyMonitorResources(CMonitor* pMonitor) { RESIT->second.monitorMirrorFB.release(); RESIT->second.blurFB.release(); RESIT->second.offMainFB.release(); - RESIT->second.stencilTex.destroyTexture(); + RESIT->second.stencilTex->destroyTexture(); g_pHyprOpenGL->m_mMonitorRenderResources.erase(RESIT); } @@ -2343,109 +2514,6 @@ void CHyprOpenGLImpl::setRenderModifEnabled(bool enabled) { m_RenderData.renderModif.enabled = enabled; } -inline const SGLPixelFormat GLES2_FORMATS[] = { - { - .drmFormat = DRM_FORMAT_ARGB8888, - .glFormat = GL_BGRA_EXT, - .glType = GL_UNSIGNED_BYTE, - .withAlpha = true, - }, - { - .drmFormat = DRM_FORMAT_XRGB8888, - .glFormat = GL_BGRA_EXT, - .glType = GL_UNSIGNED_BYTE, - .withAlpha = false, - }, - { - .drmFormat = DRM_FORMAT_XBGR8888, - .glFormat = GL_RGBA, - .glType = GL_UNSIGNED_BYTE, - .withAlpha = false, - }, - { - .drmFormat = DRM_FORMAT_ABGR8888, - .glFormat = GL_RGBA, - .glType = GL_UNSIGNED_BYTE, - .withAlpha = true, - }, - { - .drmFormat = DRM_FORMAT_BGR888, - .glFormat = GL_RGB, - .glType = GL_UNSIGNED_BYTE, - .withAlpha = false, - }, -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - { - .drmFormat = DRM_FORMAT_RGBX4444, - .glFormat = GL_RGBA, - .glType = GL_UNSIGNED_SHORT_4_4_4_4, - .withAlpha = false, - }, - { - .drmFormat = DRM_FORMAT_RGBA4444, - .glFormat = GL_RGBA, - .glType = GL_UNSIGNED_SHORT_4_4_4_4, - .withAlpha = true, - }, - { - .drmFormat = DRM_FORMAT_RGBX5551, - .glFormat = GL_RGBA, - .glType = GL_UNSIGNED_SHORT_5_5_5_1, - .withAlpha = false, - }, - { - .drmFormat = DRM_FORMAT_RGBA5551, - .glFormat = GL_RGBA, - .glType = GL_UNSIGNED_SHORT_5_5_5_1, - .withAlpha = true, - }, - { - .drmFormat = DRM_FORMAT_RGB565, - .glFormat = GL_RGB, - .glType = GL_UNSIGNED_SHORT_5_6_5, - .withAlpha = false, - }, - { - .drmFormat = DRM_FORMAT_XBGR2101010, - .glFormat = GL_RGBA, - .glType = GL_UNSIGNED_INT_2_10_10_10_REV_EXT, - .withAlpha = false, - }, - { - .drmFormat = DRM_FORMAT_ABGR2101010, - .glFormat = GL_RGBA, - .glType = GL_UNSIGNED_INT_2_10_10_10_REV_EXT, - .withAlpha = true, - }, - { - .drmFormat = DRM_FORMAT_XBGR16161616F, - .glFormat = GL_RGBA, - .glType = GL_HALF_FLOAT_OES, - .withAlpha = false, - }, - { - .drmFormat = DRM_FORMAT_ABGR16161616F, - .glFormat = GL_RGBA, - .glType = GL_HALF_FLOAT_OES, - .withAlpha = true, - }, - { - .drmFormat = DRM_FORMAT_XBGR16161616, - .glInternalFormat = GL_RGBA16_EXT, - .glFormat = GL_RGBA, - .glType = GL_UNSIGNED_SHORT, - .withAlpha = false, - }, - { - .drmFormat = DRM_FORMAT_ABGR16161616, - .glInternalFormat = GL_RGBA16_EXT, - .glFormat = GL_RGBA, - .glType = GL_UNSIGNED_SHORT, - .withAlpha = true, - }, -#endif -}; - uint32_t CHyprOpenGLImpl::getPreferredReadFormat(CMonitor* pMonitor) { GLint glf = -1, glt = -1, as = 0; /*glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &glf); @@ -2453,14 +2521,12 @@ uint32_t CHyprOpenGLImpl::getPreferredReadFormat(CMonitor* pMonitor) { glGetIntegerv(GL_ALPHA_BITS, &as);*/ if (glf == 0 || glt == 0) { - glf = drmFormatToGL(pMonitor->drmFormat); - glt = glFormatToType(glf); + glf = FormatUtils::drmFormatToGL(pMonitor->drmFormat); + glt = FormatUtils::glFormatToType(glf); } - for (auto& fmt : GLES2_FORMATS) { - if (fmt.glFormat == glf && fmt.glType == glt && fmt.withAlpha == (as > 0)) - return fmt.drmFormat; - } + if (const auto FMT = FormatUtils::getPixelFormatFromGL(glf, glt, as > 0); FMT) + return FMT->drmFormat; if (m_sExts.EXT_read_format_bgra) return DRM_FORMAT_XRGB8888; @@ -2468,13 +2534,8 @@ uint32_t CHyprOpenGLImpl::getPreferredReadFormat(CMonitor* pMonitor) { return DRM_FORMAT_XBGR8888; } -const SGLPixelFormat* CHyprOpenGLImpl::getPixelFormatFromDRM(uint32_t drmFormat) { - for (auto& fmt : GLES2_FORMATS) { - if (fmt.drmFormat == drmFormat) - return &fmt; - } - - return nullptr; +std::vector<SDRMFormat> CHyprOpenGLImpl::getDRMFormats() { + return drmFormats; } void SRenderModifData::applyToBox(CBox& box) { |