mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-08-05 22:51:58 -07:00
Core: Move to aquamarine (#6608)
Moves Hyprland from wlroots to aquamarine for the backend. --------- Signed-off-by: Vaxry <vaxry@vaxry.net> Co-authored-by: Mihai Fufezan <mihai@fufexan.net> Co-authored-by: Jan Beich <jbeich@FreeBSD.org> Co-authored-by: vaxerski <vaxerski@users.noreply.github.com> Co-authored-by: UjinT34 <41110182+UjinT34@users.noreply.github.com> Co-authored-by: Tom Englund <tomenglund26@gmail.com> Co-authored-by: Ikalco <73481042+ikalco@users.noreply.github.com> Co-authored-by: diniamo <diniamo53@gmail.com>
This commit is contained in:
@@ -9,6 +9,9 @@
|
||||
#include "../protocols/LayerShell.hpp"
|
||||
#include "../protocols/core/Compositor.hpp"
|
||||
#include <xf86drm.h>
|
||||
#include <fcntl.h>
|
||||
#include <gbm.h>
|
||||
#include <filesystem>
|
||||
|
||||
inline void loadGLProc(void* pProc, const char* name) {
|
||||
void* proc = (void*)eglGetProcAddress(name);
|
||||
@@ -19,17 +22,203 @@ inline void loadGLProc(void* pProc, const char* name) {
|
||||
*(void**)pProc = proc;
|
||||
}
|
||||
|
||||
static enum LogLevel eglLogToLevel(EGLint type) {
|
||||
switch (type) {
|
||||
case EGL_DEBUG_MSG_CRITICAL_KHR: return CRIT;
|
||||
case EGL_DEBUG_MSG_ERROR_KHR: return ERR;
|
||||
case EGL_DEBUG_MSG_WARN_KHR: return WARN;
|
||||
case EGL_DEBUG_MSG_INFO_KHR: return LOG;
|
||||
default: return LOG;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* eglErrorToString(EGLint error) {
|
||||
switch (error) {
|
||||
case EGL_SUCCESS: return "EGL_SUCCESS";
|
||||
case EGL_NOT_INITIALIZED: return "EGL_NOT_INITIALIZED";
|
||||
case EGL_BAD_ACCESS: return "EGL_BAD_ACCESS";
|
||||
case EGL_BAD_ALLOC: return "EGL_BAD_ALLOC";
|
||||
case EGL_BAD_ATTRIBUTE: return "EGL_BAD_ATTRIBUTE";
|
||||
case EGL_BAD_CONTEXT: return "EGL_BAD_CONTEXT";
|
||||
case EGL_BAD_CONFIG: return "EGL_BAD_CONFIG";
|
||||
case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE";
|
||||
case EGL_BAD_DISPLAY: return "EGL_BAD_DISPLAY";
|
||||
case EGL_BAD_DEVICE_EXT: return "EGL_BAD_DEVICE_EXT";
|
||||
case EGL_BAD_SURFACE: return "EGL_BAD_SURFACE";
|
||||
case EGL_BAD_MATCH: return "EGL_BAD_MATCH";
|
||||
case EGL_BAD_PARAMETER: return "EGL_BAD_PARAMETER";
|
||||
case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP";
|
||||
case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW";
|
||||
case EGL_CONTEXT_LOST: return "EGL_CONTEXT_LOST";
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
static void eglLog(EGLenum error, const char* command, EGLint type, EGLLabelKHR thread, EGLLabelKHR obj, const char* msg) {
|
||||
Debug::log(eglLogToLevel(type), "[EGL] Command {} errored out with {} (0x{}): {}", command, eglErrorToString(error), error, msg);
|
||||
}
|
||||
|
||||
static int openRenderNode(int drmFd) {
|
||||
auto renderName = drmGetRenderDeviceNameFromFd(drmFd);
|
||||
if (!renderName) {
|
||||
// This can happen on split render/display platforms, fallback to
|
||||
// primary node
|
||||
renderName = drmGetPrimaryDeviceNameFromFd(drmFd);
|
||||
if (!renderName) {
|
||||
Debug::log(ERR, "drmGetPrimaryDeviceNameFromFd failed");
|
||||
return -1;
|
||||
}
|
||||
Debug::log(LOG, "DRM dev {} has no render node, falling back to primary", renderName);
|
||||
|
||||
drmVersion* render_version = drmGetVersion(drmFd);
|
||||
if (render_version && render_version->name) {
|
||||
Debug::log(LOG, "DRM dev versionName", render_version->name);
|
||||
if (strcmp(render_version->name, "evdi") == 0) {
|
||||
free(renderName);
|
||||
renderName = (char*)malloc(sizeof(char) * 15);
|
||||
strcpy(renderName, "/dev/dri/card0");
|
||||
}
|
||||
drmFreeVersion(render_version);
|
||||
}
|
||||
}
|
||||
|
||||
Debug::log(LOG, "openRenderNode got drm device {}", renderName);
|
||||
|
||||
int renderFD = open(renderName, O_RDWR | O_CLOEXEC);
|
||||
if (renderFD < 0)
|
||||
Debug::log(ERR, "openRenderNode failed to open drm device {}", renderName);
|
||||
|
||||
free(renderName);
|
||||
return renderFD;
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::initEGL(bool gbm) {
|
||||
std::vector<EGLint> attrs;
|
||||
if (m_sExts.KHR_display_reference) {
|
||||
attrs.push_back(EGL_TRACK_REFERENCES_KHR);
|
||||
attrs.push_back(EGL_TRUE);
|
||||
}
|
||||
|
||||
attrs.push_back(EGL_NONE);
|
||||
|
||||
m_pEglDisplay = m_sProc.eglGetPlatformDisplayEXT(gbm ? EGL_PLATFORM_GBM_KHR : EGL_PLATFORM_DEVICE_EXT, gbm ? m_pGbmDevice : nullptr, attrs.data());
|
||||
if (m_pEglDisplay == EGL_NO_DISPLAY)
|
||||
RASSERT(false, "EGL: failed to create a platform display");
|
||||
|
||||
attrs.clear();
|
||||
|
||||
EGLint major, minor;
|
||||
if (eglInitialize(m_pEglDisplay, &major, &minor) == EGL_FALSE)
|
||||
RASSERT(false, "EGL: failed to initialize a platform display");
|
||||
|
||||
const std::string EGLEXTENSIONS = (const char*)eglQueryString(m_pEglDisplay, EGL_EXTENSIONS);
|
||||
|
||||
m_sExts.IMG_context_priority = EGLEXTENSIONS.contains("IMG_context_priority");
|
||||
m_sExts.EXT_create_context_robustness = EGLEXTENSIONS.contains("EXT_create_context_robustness");
|
||||
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");
|
||||
|
||||
if (m_sExts.IMG_context_priority) {
|
||||
Debug::log(LOG, "EGL: IMG_context_priority supported, requesting high");
|
||||
attrs.push_back(EGL_CONTEXT_PRIORITY_LEVEL_IMG);
|
||||
attrs.push_back(EGL_CONTEXT_PRIORITY_HIGH_IMG);
|
||||
}
|
||||
|
||||
if (m_sExts.EXT_create_context_robustness) {
|
||||
Debug::log(LOG, "EGL: EXT_create_context_robustness supported, requesting lose on reset");
|
||||
attrs.push_back(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT);
|
||||
attrs.push_back(EGL_LOSE_CONTEXT_ON_RESET_EXT);
|
||||
}
|
||||
|
||||
attrs.push_back(EGL_CONTEXT_MAJOR_VERSION);
|
||||
attrs.push_back(3);
|
||||
attrs.push_back(EGL_CONTEXT_MINOR_VERSION);
|
||||
attrs.push_back(2);
|
||||
attrs.push_back(EGL_CONTEXT_OPENGL_DEBUG);
|
||||
attrs.push_back(ISDEBUG ? EGL_TRUE : EGL_FALSE);
|
||||
|
||||
attrs.push_back(EGL_NONE);
|
||||
|
||||
m_pEglContext = eglCreateContext(m_pEglDisplay, EGL_NO_CONFIG_KHR, EGL_NO_CONTEXT, attrs.data());
|
||||
if (m_pEglContext == EGL_NO_CONTEXT)
|
||||
RASSERT(false, "EGL: failed to create a context");
|
||||
|
||||
if (m_sExts.IMG_context_priority) {
|
||||
EGLint priority = EGL_CONTEXT_PRIORITY_MEDIUM_IMG;
|
||||
eglQueryContext(m_pEglDisplay, m_pEglContext, EGL_CONTEXT_PRIORITY_LEVEL_IMG, &priority);
|
||||
if (priority != EGL_CONTEXT_PRIORITY_HIGH_IMG)
|
||||
Debug::log(ERR, "EGL: Failed to obtain a high priority context");
|
||||
else
|
||||
Debug::log(LOG, "EGL: Got a high priority context");
|
||||
}
|
||||
|
||||
eglMakeCurrent(m_pEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, m_pEglContext);
|
||||
}
|
||||
|
||||
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!");
|
||||
const std::string EGLEXTENSIONS = (const char*)eglQueryString(EGL_NO_DISPLAY, EGL_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!");
|
||||
Debug::log(LOG, "Supported EGL extensions: ({}) {}", std::count(EGLEXTENSIONS.begin(), EGLEXTENSIONS.end(), ' '), EGLEXTENSIONS);
|
||||
|
||||
m_iDRMFD = g_pCompositor->m_iDRMFD;
|
||||
|
||||
m_sExts.KHR_display_reference = EGLEXTENSIONS.contains("KHR_display_reference");
|
||||
|
||||
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");
|
||||
loadGLProc(&m_sProc.eglDebugMessageControlKHR, "eglDebugMessageControlKHR");
|
||||
loadGLProc(&m_sProc.eglGetPlatformDisplayEXT, "eglGetPlatformDisplayEXT");
|
||||
loadGLProc(&m_sProc.eglCreateSyncKHR, "eglCreateSyncKHR");
|
||||
loadGLProc(&m_sProc.eglDestroySyncKHR, "eglDestroySyncKHR");
|
||||
loadGLProc(&m_sProc.eglDupNativeFenceFDANDROID, "eglDupNativeFenceFDANDROID");
|
||||
loadGLProc(&m_sProc.eglWaitSyncKHR, "eglWaitSyncKHR");
|
||||
|
||||
RASSERT(m_sProc.eglCreateSyncKHR, "Display driver doesn't support eglCreateSyncKHR");
|
||||
RASSERT(m_sProc.eglDupNativeFenceFDANDROID, "Display driver doesn't support eglDupNativeFenceFDANDROID");
|
||||
RASSERT(m_sProc.eglWaitSyncKHR, "Display driver doesn't support eglWaitSyncKHR");
|
||||
|
||||
if (EGLEXTENSIONS.contains("EGL_EXT_device_base") || EGLEXTENSIONS.contains("EGL_EXT_device_enumeration"))
|
||||
loadGLProc(&m_sProc.eglQueryDevicesEXT, "eglQueryDevicesEXT");
|
||||
|
||||
if (EGLEXTENSIONS.contains("EGL_EXT_device_base") || EGLEXTENSIONS.contains("EGL_EXT_device_query")) {
|
||||
loadGLProc(&m_sProc.eglQueryDeviceStringEXT, "eglQueryDeviceStringEXT");
|
||||
loadGLProc(&m_sProc.eglQueryDisplayAttribEXT, "eglQueryDisplayAttribEXT");
|
||||
}
|
||||
|
||||
if (EGLEXTENSIONS.contains("EGL_KHR_debug")) {
|
||||
loadGLProc(&m_sProc.eglDebugMessageControlKHR, "eglDebugMessageControlKHR");
|
||||
static const EGLAttrib debugAttrs[] = {
|
||||
EGL_DEBUG_MSG_CRITICAL_KHR, EGL_TRUE, EGL_DEBUG_MSG_ERROR_KHR, EGL_TRUE, EGL_DEBUG_MSG_WARN_KHR, EGL_TRUE, EGL_DEBUG_MSG_INFO_KHR, EGL_TRUE, EGL_NONE,
|
||||
};
|
||||
m_sProc.eglDebugMessageControlKHR(::eglLog, debugAttrs);
|
||||
}
|
||||
|
||||
RASSERT(eglBindAPI(EGL_OPENGL_ES_API) != EGL_FALSE, "Couldn't bind to EGL's opengl ES API. This means your gpu driver f'd up. This is not a hyprland issue.");
|
||||
|
||||
// if (m_sProc.eglQueryDevicesEXT) {
|
||||
// // TODO:
|
||||
// }
|
||||
|
||||
if (EGLEXTENSIONS.contains("KHR_platform_gbm")) {
|
||||
m_iGBMFD = openRenderNode(m_iDRMFD);
|
||||
if (m_iGBMFD < 0)
|
||||
RASSERT(false, "Couldn't open a gbm fd");
|
||||
|
||||
m_pGbmDevice = gbm_create_device(m_iGBMFD);
|
||||
if (!m_pGbmDevice)
|
||||
RASSERT(false, "Couldn't open a gbm device");
|
||||
|
||||
initEGL(true);
|
||||
} else
|
||||
RASSERT(false, "EGL does not support KHR_platform_gbm, this is an issue with your gpu driver.");
|
||||
|
||||
auto* const EXTENSIONS = (const char*)glGetString(GL_EXTENSIONS);
|
||||
RASSERT(EXTENSIONS, "Couldn't retrieve openGL extensions!");
|
||||
|
||||
m_szExtensions = EXTENSIONS;
|
||||
|
||||
Debug::log(LOG, "Creating the Hypr OpenGL Renderer!");
|
||||
@@ -38,16 +227,7 @@ CHyprOpenGLImpl::CHyprOpenGLImpl() {
|
||||
Debug::log(LOG, "Renderer: {}", (char*)glGetString(GL_RENDERER));
|
||||
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_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");
|
||||
m_sExts.EXT_read_format_bgra = m_szExtensions.contains("GL_EXT_read_format_bgra");
|
||||
|
||||
RASSERT(m_szExtensions.contains("GL_EXT_texture_format_BGRA8888"), "GL_EXT_texture_format_BGRA8888 support by the GPU driver is required");
|
||||
|
||||
@@ -74,7 +254,7 @@ CHyprOpenGLImpl::CHyprOpenGLImpl() {
|
||||
|
||||
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!");
|
||||
RASSERT(eglMakeCurrent(m_pEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT), "Couldn't unset current EGL!");
|
||||
|
||||
m_tGlobalTimer.reset();
|
||||
}
|
||||
@@ -86,7 +266,7 @@ std::optional<std::vector<uint64_t>> CHyprOpenGLImpl::getModsForFormat(EGLint fo
|
||||
return std::nullopt;
|
||||
|
||||
EGLint len = 0;
|
||||
if (!m_sProc.eglQueryDmaBufModifiersEXT(wlr_egl_get_display(g_pCompositor->m_sWLREGL), format, 0, nullptr, nullptr, &len)) {
|
||||
if (!m_sProc.eglQueryDmaBufModifiersEXT(m_pEglDisplay, format, 0, nullptr, nullptr, &len)) {
|
||||
Debug::log(ERR, "EGL: Failed to query mods");
|
||||
return std::nullopt;
|
||||
}
|
||||
@@ -100,7 +280,7 @@ std::optional<std::vector<uint64_t>> CHyprOpenGLImpl::getModsForFormat(EGLint fo
|
||||
mods.resize(len);
|
||||
external.resize(len);
|
||||
|
||||
m_sProc.eglQueryDmaBufModifiersEXT(wlr_egl_get_display(g_pCompositor->m_sWLREGL), format, len, mods.data(), external.data(), &len);
|
||||
m_sProc.eglQueryDmaBufModifiersEXT(m_pEglDisplay, format, len, mods.data(), external.data(), &len);
|
||||
|
||||
std::vector<uint64_t> result;
|
||||
bool linearIsExternal = false;
|
||||
@@ -139,9 +319,9 @@ void CHyprOpenGLImpl::initDRMFormats() {
|
||||
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);
|
||||
m_sProc.eglQueryDmaBufFormatsEXT(m_pEglDisplay, 0, nullptr, &len);
|
||||
formats.resize(len);
|
||||
m_sProc.eglQueryDmaBufFormatsEXT(wlr_egl_get_display(g_pCompositor->m_sWLREGL), len, formats.data(), &len);
|
||||
m_sProc.eglQueryDmaBufFormatsEXT(m_pEglDisplay, len, formats.data(), &len);
|
||||
}
|
||||
|
||||
if (formats.size() == 0) {
|
||||
@@ -149,7 +329,7 @@ void CHyprOpenGLImpl::initDRMFormats() {
|
||||
return;
|
||||
}
|
||||
|
||||
wlr_log(WLR_DEBUG, "Supported DMA-BUF formats:");
|
||||
Debug::log(LOG, "Supported DMA-BUF formats:");
|
||||
|
||||
std::vector<SDRMFormat> dmaFormats;
|
||||
|
||||
@@ -170,8 +350,8 @@ void CHyprOpenGLImpl::initDRMFormats() {
|
||||
mods.push_back(DRM_FORMAT_MOD_INVALID);
|
||||
|
||||
dmaFormats.push_back(SDRMFormat{
|
||||
.format = fmt,
|
||||
.mods = mods,
|
||||
.drmFormat = fmt,
|
||||
.modifiers = mods,
|
||||
});
|
||||
|
||||
std::vector<std::pair<uint64_t, std::string>> modifierData;
|
||||
@@ -209,7 +389,7 @@ void CHyprOpenGLImpl::initDRMFormats() {
|
||||
drmFormats = dmaFormats;
|
||||
}
|
||||
|
||||
EGLImageKHR CHyprOpenGLImpl::createEGLImage(const SDMABUFAttrs& attrs) {
|
||||
EGLImageKHR CHyprOpenGLImpl::createEGLImage(const Aquamarine::SDMABUFAttrs& attrs) {
|
||||
std::vector<uint32_t> attribs;
|
||||
|
||||
attribs.push_back(EGL_WIDTH);
|
||||
@@ -251,7 +431,7 @@ EGLImageKHR CHyprOpenGLImpl::createEGLImage(const SDMABUFAttrs& attrs) {
|
||||
|
||||
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());
|
||||
EGLImageKHR image = m_sProc.eglCreateImageKHR(m_pEglDisplay, 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;
|
||||
@@ -342,7 +522,8 @@ GLuint CHyprOpenGLImpl::compileShader(const GLuint& type, std::string src, bool
|
||||
}
|
||||
|
||||
bool CHyprOpenGLImpl::passRequiresIntrospection(CMonitor* pMonitor) {
|
||||
// passes requiring introspection are the ones that need to render blur.
|
||||
// passes requiring introspection are the ones that need to render blur,
|
||||
// or when we are rendering to a multigpu target
|
||||
|
||||
static auto PBLUR = CConfigValue<Hyprlang::INT>("decoration:blur:enabled");
|
||||
static auto PXRAY = CConfigValue<Hyprlang::INT>("decoration:blur:xray");
|
||||
@@ -446,7 +627,7 @@ bool CHyprOpenGLImpl::passRequiresIntrospection(CMonitor* pMonitor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::beginSimple(CMonitor* pMonitor, const CRegion& damage, CRenderbuffer* rb, CFramebuffer* fb) {
|
||||
void CHyprOpenGLImpl::beginSimple(CMonitor* pMonitor, const CRegion& damage, SP<CRenderbuffer> rb, CFramebuffer* fb) {
|
||||
m_RenderData.pMonitor = pMonitor;
|
||||
|
||||
#ifndef GLES2
|
||||
@@ -472,12 +653,12 @@ void CHyprOpenGLImpl::beginSimple(CMonitor* pMonitor, const CRegion& damage, CRe
|
||||
|
||||
matrixProjection(m_RenderData.projection, pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y, WL_OUTPUT_TRANSFORM_NORMAL);
|
||||
|
||||
wlr_matrix_identity(m_RenderData.monitorProjection.data());
|
||||
matrixIdentity(m_RenderData.monitorProjection.data());
|
||||
if (pMonitor->transform != WL_OUTPUT_TRANSFORM_NORMAL) {
|
||||
const Vector2D tfmd = pMonitor->transform % 2 == 1 ? Vector2D{FBO->m_vSize.y, FBO->m_vSize.x} : FBO->m_vSize;
|
||||
wlr_matrix_translate(m_RenderData.monitorProjection.data(), FBO->m_vSize.x / 2.0, FBO->m_vSize.y / 2.0);
|
||||
wlr_matrix_transform(m_RenderData.monitorProjection.data(), pMonitor->transform);
|
||||
wlr_matrix_translate(m_RenderData.monitorProjection.data(), -tfmd.x / 2.0, -tfmd.y / 2.0);
|
||||
matrixTranslate(m_RenderData.monitorProjection.data(), FBO->m_vSize.x / 2.0, FBO->m_vSize.y / 2.0);
|
||||
matrixTransform(m_RenderData.monitorProjection.data(), wlTransformToHyprutils(pMonitor->transform));
|
||||
matrixTranslate(m_RenderData.monitorProjection.data(), -tfmd.x / 2.0, -tfmd.y / 2.0);
|
||||
}
|
||||
|
||||
m_RenderData.pCurrentMonData = &m_mMonitorRenderResources[pMonitor];
|
||||
@@ -545,10 +726,10 @@ void CHyprOpenGLImpl::begin(CMonitor* pMonitor, const CRegion& damage_, CFramebu
|
||||
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);
|
||||
m_RenderData.pCurrentMonData->mirrorSwapFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y, pMonitor->drmFormat);
|
||||
m_RenderData.pCurrentMonData->offMainFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y, pMonitor->drmFormat);
|
||||
m_RenderData.pCurrentMonData->offloadFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y, pMonitor->output->state->state().drmFormat);
|
||||
m_RenderData.pCurrentMonData->mirrorFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y, pMonitor->output->state->state().drmFormat);
|
||||
m_RenderData.pCurrentMonData->mirrorSwapFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y, pMonitor->output->state->state().drmFormat);
|
||||
m_RenderData.pCurrentMonData->offMainFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y, pMonitor->output->state->state().drmFormat);
|
||||
}
|
||||
|
||||
if (m_RenderData.pCurrentMonData->monitorMirrorFB.isAllocated() && m_RenderData.pMonitor->mirrors.empty())
|
||||
@@ -597,7 +778,7 @@ void CHyprOpenGLImpl::end() {
|
||||
|
||||
TRACY_GPU_ZONE("RenderEnd");
|
||||
|
||||
// end the render, copy the data to the WLR framebuffer
|
||||
// end the render, copy the data to the main framebuffer
|
||||
if (m_bOffloadedFramebuffer) {
|
||||
m_RenderData.damage = m_RenderData.finalDamage;
|
||||
m_bEndFrame = true;
|
||||
@@ -915,11 +1096,8 @@ void CHyprOpenGLImpl::scissor(const CBox* pBox, bool transform) {
|
||||
CBox newBox = *pBox;
|
||||
|
||||
if (transform) {
|
||||
int w, h;
|
||||
wlr_output_transformed_resolution(m_RenderData.pMonitor->output, &w, &h);
|
||||
|
||||
const auto TR = wlTransformToHyprutils(wlr_output_transform_invert(m_RenderData.pMonitor->transform));
|
||||
newBox.transform(TR, w, h);
|
||||
const auto TR = wlTransformToHyprutils(invertTransform(m_RenderData.pMonitor->transform));
|
||||
newBox.transform(TR, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y);
|
||||
}
|
||||
|
||||
glScissor(newBox.x, newBox.y, newBox.width, newBox.height);
|
||||
@@ -1008,18 +1186,18 @@ void CHyprOpenGLImpl::renderRectWithDamage(CBox* box, const CColor& col, CRegion
|
||||
box = &newBox;
|
||||
|
||||
float matrix[9];
|
||||
projectBox(matrix, newBox, wlTransformToHyprutils(wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform)), newBox.rot,
|
||||
m_RenderData.monitorProjection.data()); // TODO: write own, don't use WLR here
|
||||
projectBox(matrix, newBox, wlTransformToHyprutils(invertTransform(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform)), newBox.rot,
|
||||
m_RenderData.monitorProjection.data());
|
||||
|
||||
float glMatrix[9];
|
||||
wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix);
|
||||
matrixMultiply(glMatrix, m_RenderData.projection, matrix);
|
||||
|
||||
glUseProgram(m_RenderData.pCurrentMonData->m_shQUAD.program);
|
||||
|
||||
#ifndef GLES2
|
||||
glUniformMatrix3fv(m_RenderData.pCurrentMonData->m_shQUAD.proj, 1, GL_TRUE, glMatrix);
|
||||
#else
|
||||
wlr_matrix_transpose(glMatrix, glMatrix);
|
||||
matrixTranspose(glMatrix, glMatrix);
|
||||
glUniformMatrix3fv(m_RenderData.pCurrentMonData->m_shQUAD.proj, 1, GL_FALSE, glMatrix);
|
||||
#endif
|
||||
|
||||
@@ -1027,7 +1205,7 @@ void CHyprOpenGLImpl::renderRectWithDamage(CBox* box, const CColor& col, CRegion
|
||||
glUniform4f(m_RenderData.pCurrentMonData->m_shQUAD.color, col.r * col.a, col.g * col.a, col.b * col.a, col.a);
|
||||
|
||||
CBox transformedBox = *box;
|
||||
transformedBox.transform(wlTransformToHyprutils(wlr_output_transform_invert(m_RenderData.pMonitor->transform)), m_RenderData.pMonitor->vecTransformedSize.x,
|
||||
transformedBox.transform(wlTransformToHyprutils(invertTransform(m_RenderData.pMonitor->transform)), m_RenderData.pMonitor->vecTransformedSize.x,
|
||||
m_RenderData.pMonitor->vecTransformedSize.y);
|
||||
|
||||
const auto TOPLEFT = Vector2D(transformedBox.x, transformedBox.y);
|
||||
@@ -1072,16 +1250,17 @@ void CHyprOpenGLImpl::renderTexture(SP<CTexture> tex, CBox* pBox, float alpha, i
|
||||
scissor((CBox*)nullptr);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderTextureWithDamage(SP<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,
|
||||
SP<CSyncTimeline> waitTimeline, uint64_t waitPoint) {
|
||||
RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!");
|
||||
|
||||
renderTextureInternalWithDamage(tex, pBox, alpha, damage, round, discardActive, false, allowCustomUV, true);
|
||||
renderTextureInternalWithDamage(tex, pBox, alpha, damage, round, discardActive, false, allowCustomUV, true, waitTimeline, waitPoint);
|
||||
|
||||
scissor((CBox*)nullptr);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP<CTexture> tex, CBox* pBox, float alpha, CRegion* damage, int round, bool discardActive, bool noAA, bool allowCustomUV,
|
||||
bool allowDim) {
|
||||
bool allowDim, SP<CSyncTimeline> waitTimeline, uint64_t waitPoint) {
|
||||
RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!");
|
||||
RASSERT((tex->m_iTexID > 0), "Attempted to draw NULL texture!");
|
||||
|
||||
@@ -1099,12 +1278,19 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP<CTexture> tex, CBox* pB
|
||||
static auto PDT = CConfigValue<Hyprlang::INT>("debug:damage_tracking");
|
||||
|
||||
// get transform
|
||||
const auto TRANSFORM = wlTransformToHyprutils(wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform));
|
||||
const auto TRANSFORM = wlTransformToHyprutils(invertTransform(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform));
|
||||
float matrix[9];
|
||||
projectBox(matrix, newBox, TRANSFORM, newBox.rot, m_RenderData.monitorProjection.data());
|
||||
|
||||
float glMatrix[9];
|
||||
wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix);
|
||||
matrixMultiply(glMatrix, m_RenderData.projection, matrix);
|
||||
|
||||
if (waitTimeline != nullptr) {
|
||||
if (!waitForTimelinePoint(waitTimeline, waitPoint)) {
|
||||
Debug::log(ERR, "renderTextureInternalWithDamage: failed to wait for explicit sync point {}", waitPoint);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
CShader* shader = nullptr;
|
||||
|
||||
@@ -1151,7 +1337,7 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP<CTexture> tex, CBox* pB
|
||||
#ifndef GLES2
|
||||
glUniformMatrix3fv(shader->proj, 1, GL_TRUE, glMatrix);
|
||||
#else
|
||||
wlr_matrix_transpose(glMatrix, glMatrix);
|
||||
matrixTranspose(glMatrix, glMatrix);
|
||||
glUniformMatrix3fv(shader->proj, 1, GL_FALSE, glMatrix);
|
||||
#endif
|
||||
glUniform1i(shader->tex, 0);
|
||||
@@ -1187,7 +1373,7 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP<CTexture> tex, CBox* pB
|
||||
}
|
||||
|
||||
CBox transformedBox = newBox;
|
||||
transformedBox.transform(wlTransformToHyprutils(wlr_output_transform_invert(m_RenderData.pMonitor->transform)), m_RenderData.pMonitor->vecTransformedSize.x,
|
||||
transformedBox.transform(wlTransformToHyprutils(invertTransform(m_RenderData.pMonitor->transform)), m_RenderData.pMonitor->vecTransformedSize.x,
|
||||
m_RenderData.pMonitor->vecTransformedSize.y);
|
||||
|
||||
const auto TOPLEFT = Vector2D(transformedBox.x, transformedBox.y);
|
||||
@@ -1262,12 +1448,12 @@ void CHyprOpenGLImpl::renderTexturePrimitive(SP<CTexture> tex, CBox* pBox) {
|
||||
m_RenderData.renderModif.applyToBox(newBox);
|
||||
|
||||
// get transform
|
||||
const auto TRANSFORM = wlTransformToHyprutils(wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform));
|
||||
const auto TRANSFORM = wlTransformToHyprutils(invertTransform(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform));
|
||||
float matrix[9];
|
||||
projectBox(matrix, newBox, TRANSFORM, newBox.rot, m_RenderData.monitorProjection.data());
|
||||
|
||||
float glMatrix[9];
|
||||
wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix);
|
||||
matrixMultiply(glMatrix, m_RenderData.projection, matrix);
|
||||
|
||||
CShader* shader = &m_RenderData.pCurrentMonData->m_shPASSTHRURGBA;
|
||||
|
||||
@@ -1279,7 +1465,7 @@ void CHyprOpenGLImpl::renderTexturePrimitive(SP<CTexture> tex, CBox* pBox) {
|
||||
#ifndef GLES2
|
||||
glUniformMatrix3fv(shader->proj, 1, GL_TRUE, glMatrix);
|
||||
#else
|
||||
wlr_matrix_transpose(glMatrix, glMatrix);
|
||||
matrixTranspose(glMatrix, glMatrix);
|
||||
glUniformMatrix3fv(shader->proj, 1, GL_FALSE, glMatrix);
|
||||
#endif
|
||||
glUniform1i(shader->tex, 0);
|
||||
@@ -1316,12 +1502,12 @@ void CHyprOpenGLImpl::renderTextureMatte(SP<CTexture> tex, CBox* pBox, CFramebuf
|
||||
m_RenderData.renderModif.applyToBox(newBox);
|
||||
|
||||
// get transform
|
||||
const auto TRANSFORM = wlTransformToHyprutils(wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform));
|
||||
const auto TRANSFORM = wlTransformToHyprutils(invertTransform(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform));
|
||||
float matrix[9];
|
||||
projectBox(matrix, newBox, TRANSFORM, newBox.rot, m_RenderData.monitorProjection.data());
|
||||
|
||||
float glMatrix[9];
|
||||
wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix);
|
||||
matrixMultiply(glMatrix, m_RenderData.projection, matrix);
|
||||
|
||||
CShader* shader = &m_RenderData.pCurrentMonData->m_shMATTE;
|
||||
|
||||
@@ -1330,7 +1516,7 @@ void CHyprOpenGLImpl::renderTextureMatte(SP<CTexture> tex, CBox* pBox, CFramebuf
|
||||
#ifndef GLES2
|
||||
glUniformMatrix3fv(shader->proj, 1, GL_TRUE, glMatrix);
|
||||
#else
|
||||
wlr_matrix_transpose(glMatrix, glMatrix);
|
||||
matrixTranspose(glMatrix, glMatrix);
|
||||
glUniformMatrix3fv(shader->proj, 1, GL_FALSE, glMatrix);
|
||||
#endif
|
||||
glUniform1i(shader->tex, 0);
|
||||
@@ -1374,13 +1560,13 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
|
||||
// get transforms for the full monitor
|
||||
const auto TRANSFORM = wlTransformToHyprutils(wlr_output_transform_invert(m_RenderData.pMonitor->transform));
|
||||
const auto TRANSFORM = wlTransformToHyprutils(invertTransform(m_RenderData.pMonitor->transform));
|
||||
float matrix[9];
|
||||
CBox MONITORBOX = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y};
|
||||
projectBox(matrix, MONITORBOX, TRANSFORM, 0, m_RenderData.monitorProjection.data());
|
||||
|
||||
float glMatrix[9];
|
||||
wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix);
|
||||
matrixMultiply(glMatrix, m_RenderData.projection, matrix);
|
||||
|
||||
// get the config settings
|
||||
static auto PBLURSIZE = CConfigValue<Hyprlang::INT>("decoration:blur:size");
|
||||
@@ -1390,9 +1576,9 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o
|
||||
|
||||
// prep damage
|
||||
CRegion damage{*originalDamage};
|
||||
wlr_region_transform(damage.pixman(), damage.pixman(), wlr_output_transform_invert(m_RenderData.pMonitor->transform), m_RenderData.pMonitor->vecTransformedSize.x,
|
||||
m_RenderData.pMonitor->vecTransformedSize.y);
|
||||
wlr_region_expand(damage.pixman(), damage.pixman(), *PBLURPASSES > 10 ? pow(2, 15) : std::clamp(*PBLURSIZE, (int64_t)1, (int64_t)40) * pow(2, *PBLURPASSES));
|
||||
damage.transform(wlTransformToHyprutils(invertTransform(m_RenderData.pMonitor->transform)), m_RenderData.pMonitor->vecTransformedSize.x,
|
||||
m_RenderData.pMonitor->vecTransformedSize.y);
|
||||
damage.expand(*PBLURPASSES > 10 ? pow(2, 15) : std::clamp(*PBLURSIZE, (int64_t)1, (int64_t)40) * pow(2, *PBLURPASSES));
|
||||
|
||||
// helper
|
||||
const auto PMIRRORFB = &m_RenderData.pCurrentMonData->mirrorFB;
|
||||
@@ -1419,7 +1605,7 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o
|
||||
#ifndef GLES2
|
||||
glUniformMatrix3fv(m_RenderData.pCurrentMonData->m_shBLURPREPARE.proj, 1, GL_TRUE, glMatrix);
|
||||
#else
|
||||
wlr_matrix_transpose(glMatrix, glMatrix);
|
||||
matrixTranspose(glMatrix, glMatrix);
|
||||
glUniformMatrix3fv(m_RenderData.pCurrentMonData->m_shBLURPREPARE.proj, 1, GL_FALSE, glMatrix);
|
||||
#endif
|
||||
glUniform1f(m_RenderData.pCurrentMonData->m_shBLURPREPARE.contrast, *PBLURCONTRAST);
|
||||
@@ -1464,7 +1650,7 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o
|
||||
#ifndef GLES2
|
||||
glUniformMatrix3fv(pShader->proj, 1, GL_TRUE, glMatrix);
|
||||
#else
|
||||
wlr_matrix_transpose(glMatrix, glMatrix);
|
||||
matrixTranspose(glMatrix, glMatrix);
|
||||
glUniformMatrix3fv(pShader->proj, 1, GL_FALSE, glMatrix);
|
||||
#endif
|
||||
glUniform1f(pShader->radius, *PBLURSIZE * a); // this makes the blursize change with a
|
||||
@@ -1511,13 +1697,13 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o
|
||||
|
||||
// and draw
|
||||
for (int i = 1; i <= *PBLURPASSES; ++i) {
|
||||
wlr_region_scale(tempDamage.pixman(), damage.pixman(), 1.f / (1 << i));
|
||||
tempDamage = damage.copy().scale(1.f / (1 << i));
|
||||
drawPass(&m_RenderData.pCurrentMonData->m_shBLUR1, &tempDamage); // down
|
||||
}
|
||||
|
||||
for (int i = *PBLURPASSES - 1; i >= 0; --i) {
|
||||
wlr_region_scale(tempDamage.pixman(), damage.pixman(), 1.f / (1 << i)); // when upsampling we make the region twice as big
|
||||
drawPass(&m_RenderData.pCurrentMonData->m_shBLUR2, &tempDamage); // up
|
||||
tempDamage = damage.copy().scale(1.f / (1 << i)); // when upsampling we make the region twice as big
|
||||
drawPass(&m_RenderData.pCurrentMonData->m_shBLUR2, &tempDamage); // up
|
||||
}
|
||||
|
||||
// finalize the image
|
||||
@@ -1541,7 +1727,7 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o
|
||||
#ifndef GLES2
|
||||
glUniformMatrix3fv(m_RenderData.pCurrentMonData->m_shBLURFINISH.proj, 1, GL_TRUE, glMatrix);
|
||||
#else
|
||||
wlr_matrix_transpose(glMatrix, glMatrix);
|
||||
matrixTranspose(glMatrix, glMatrix);
|
||||
glUniformMatrix3fv(m_RenderData.pCurrentMonData->m_shBLURFINISH.proj, 1, GL_FALSE, glMatrix);
|
||||
#endif
|
||||
glUniform1f(m_RenderData.pCurrentMonData->m_shBLURFINISH.noise, *PBLURNOISE);
|
||||
@@ -1679,7 +1865,8 @@ void CHyprOpenGLImpl::preBlurForCurrentMonitor() {
|
||||
const auto POUTFB = blurMainFramebufferWithDamage(1, &fakeDamage);
|
||||
|
||||
// render onto blurFB
|
||||
m_RenderData.pCurrentMonData->blurFB.alloc(m_RenderData.pMonitor->vecPixelSize.x, m_RenderData.pMonitor->vecPixelSize.y, m_RenderData.pMonitor->drmFormat);
|
||||
m_RenderData.pCurrentMonData->blurFB.alloc(m_RenderData.pMonitor->vecPixelSize.x, m_RenderData.pMonitor->vecPixelSize.y,
|
||||
m_RenderData.pMonitor->output->state->state().drmFormat);
|
||||
m_RenderData.pCurrentMonData->blurFB.bind();
|
||||
|
||||
clear(CColor(0, 0, 0, 0));
|
||||
@@ -1773,7 +1960,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP<CTexture> tex, CBox* pBox, float
|
||||
inverseOpaque = {0, 0, pBox->width, pBox->height};
|
||||
}
|
||||
|
||||
wlr_region_scale(inverseOpaque.pixman(), inverseOpaque.pixman(), m_RenderData.pMonitor->scale);
|
||||
inverseOpaque.scale(m_RenderData.pMonitor->scale);
|
||||
|
||||
// vvv TODO: layered blur fbs?
|
||||
const bool USENEWOPTIMIZE = shouldUseNewBlurOptimizations(m_pCurrentLayer, m_pCurrentWindow.lock()) && !blockBlurOptimization;
|
||||
@@ -1872,11 +2059,11 @@ void CHyprOpenGLImpl::renderBorder(CBox* box, const CGradientValueData& grad, in
|
||||
round += round == 0 ? 0 : scaledBorderSize;
|
||||
|
||||
float matrix[9];
|
||||
projectBox(matrix, newBox, wlTransformToHyprutils(wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform)), newBox.rot,
|
||||
m_RenderData.monitorProjection.data()); // TODO: write own, don't use WLR here
|
||||
projectBox(matrix, newBox, wlTransformToHyprutils(invertTransform(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform)), newBox.rot,
|
||||
m_RenderData.monitorProjection.data());
|
||||
|
||||
float glMatrix[9];
|
||||
wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix);
|
||||
matrixMultiply(glMatrix, m_RenderData.projection, matrix);
|
||||
|
||||
const auto BLEND = m_bBlend;
|
||||
blend(true);
|
||||
@@ -1886,7 +2073,7 @@ void CHyprOpenGLImpl::renderBorder(CBox* box, const CGradientValueData& grad, in
|
||||
#ifndef GLES2
|
||||
glUniformMatrix3fv(m_RenderData.pCurrentMonData->m_shBORDER1.proj, 1, GL_TRUE, glMatrix);
|
||||
#else
|
||||
wlr_matrix_transpose(glMatrix, glMatrix);
|
||||
matrixTranspose(glMatrix, glMatrix);
|
||||
glUniformMatrix3fv(m_RenderData.pCurrentMonData->m_shBORDER1.proj, 1, GL_FALSE, glMatrix);
|
||||
#endif
|
||||
|
||||
@@ -1898,7 +2085,7 @@ void CHyprOpenGLImpl::renderBorder(CBox* box, const CGradientValueData& grad, in
|
||||
glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.alpha, a);
|
||||
|
||||
CBox transformedBox = *box;
|
||||
transformedBox.transform(wlTransformToHyprutils(wlr_output_transform_invert(m_RenderData.pMonitor->transform)), m_RenderData.pMonitor->vecTransformedSize.x,
|
||||
transformedBox.transform(wlTransformToHyprutils(invertTransform(m_RenderData.pMonitor->transform)), m_RenderData.pMonitor->vecTransformedSize.x,
|
||||
m_RenderData.pMonitor->vecTransformedSize.y);
|
||||
|
||||
const auto TOPLEFT = Vector2D(transformedBox.x, transformedBox.y);
|
||||
@@ -1949,14 +2136,14 @@ void CHyprOpenGLImpl::makeRawWindowSnapshot(PHLWINDOW pWindow, CFramebuffer* pFr
|
||||
|
||||
// we need to "damage" the entire monitor
|
||||
// so that we render the entire window
|
||||
// this is temporary, doesnt mess with the actual wlr damage
|
||||
// this is temporary, doesnt mess with the actual damage
|
||||
CRegion fakeDamage{0, 0, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y};
|
||||
|
||||
g_pHyprRenderer->makeEGLCurrent();
|
||||
|
||||
pFramebuffer->m_pStencilTex = m_RenderData.pCurrentMonData->stencilTex;
|
||||
|
||||
pFramebuffer->alloc(PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y, PMONITOR->drmFormat);
|
||||
pFramebuffer->alloc(PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y, PMONITOR->output->state->state().drmFormat);
|
||||
|
||||
g_pHyprRenderer->beginRender(PMONITOR, fakeDamage, RENDER_MODE_FULL_FAKE, nullptr, pFramebuffer);
|
||||
|
||||
@@ -2000,7 +2187,7 @@ void CHyprOpenGLImpl::makeWindowSnapshot(PHLWINDOW pWindow) {
|
||||
|
||||
// we need to "damage" the entire monitor
|
||||
// so that we render the entire window
|
||||
// this is temporary, doesnt mess with the actual wlr damage
|
||||
// this is temporary, doesnt mess with the actual damage
|
||||
CRegion fakeDamage{0, 0, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y};
|
||||
|
||||
PHLWINDOWREF ref{pWindow};
|
||||
@@ -2009,7 +2196,7 @@ void CHyprOpenGLImpl::makeWindowSnapshot(PHLWINDOW pWindow) {
|
||||
|
||||
const auto PFRAMEBUFFER = &m_mWindowFramebuffers[ref];
|
||||
|
||||
PFRAMEBUFFER->alloc(PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y, PMONITOR->drmFormat);
|
||||
PFRAMEBUFFER->alloc(PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y, PMONITOR->output->state->state().drmFormat);
|
||||
|
||||
g_pHyprRenderer->beginRender(PMONITOR, fakeDamage, RENDER_MODE_FULL_FAKE, nullptr, PFRAMEBUFFER);
|
||||
|
||||
@@ -2049,14 +2236,14 @@ void CHyprOpenGLImpl::makeLayerSnapshot(PHLLS pLayer) {
|
||||
|
||||
// we need to "damage" the entire monitor
|
||||
// so that we render the entire window
|
||||
// this is temporary, doesnt mess with the actual wlr damage
|
||||
// this is temporary, doesnt mess with the actual damage
|
||||
CRegion fakeDamage{0, 0, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y};
|
||||
|
||||
g_pHyprRenderer->makeEGLCurrent();
|
||||
|
||||
const auto PFRAMEBUFFER = &m_mLayerFramebuffers[pLayer];
|
||||
|
||||
PFRAMEBUFFER->alloc(PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y, PMONITOR->drmFormat);
|
||||
PFRAMEBUFFER->alloc(PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y, PMONITOR->output->state->state().drmFormat);
|
||||
|
||||
g_pHyprRenderer->beginRender(PMONITOR, fakeDamage, RENDER_MODE_FULL_FAKE, nullptr, PFRAMEBUFFER);
|
||||
|
||||
@@ -2178,11 +2365,11 @@ void CHyprOpenGLImpl::renderRoundedShadow(CBox* box, int round, int range, const
|
||||
const auto col = color;
|
||||
|
||||
float matrix[9];
|
||||
projectBox(matrix, newBox, wlTransformToHyprutils(wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform)), newBox.rot,
|
||||
m_RenderData.monitorProjection.data()); // TODO: write own, don't use WLR here
|
||||
projectBox(matrix, newBox, wlTransformToHyprutils(invertTransform(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform)), newBox.rot,
|
||||
m_RenderData.monitorProjection.data());
|
||||
|
||||
float glMatrix[9];
|
||||
wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix);
|
||||
matrixMultiply(glMatrix, m_RenderData.projection, matrix);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
@@ -2191,7 +2378,7 @@ void CHyprOpenGLImpl::renderRoundedShadow(CBox* box, int round, int range, const
|
||||
#ifndef GLES2
|
||||
glUniformMatrix3fv(m_RenderData.pCurrentMonData->m_shSHADOW.proj, 1, GL_TRUE, glMatrix);
|
||||
#else
|
||||
wlr_matrix_transpose(glMatrix, glMatrix);
|
||||
matrixTranspose(glMatrix, glMatrix);
|
||||
glUniformMatrix3fv(m_RenderData.pCurrentMonData->m_shSHADOW.proj, 1, GL_FALSE, glMatrix);
|
||||
#endif
|
||||
glUniform4f(m_RenderData.pCurrentMonData->m_shSHADOW.color, col.r, col.g, col.b, col.a * a);
|
||||
@@ -2238,7 +2425,8 @@ void CHyprOpenGLImpl::renderRoundedShadow(CBox* box, int round, int range, const
|
||||
void CHyprOpenGLImpl::saveBufferForMirror(CBox* box) {
|
||||
|
||||
if (!m_RenderData.pCurrentMonData->monitorMirrorFB.isAllocated())
|
||||
m_RenderData.pCurrentMonData->monitorMirrorFB.alloc(m_RenderData.pMonitor->vecPixelSize.x, m_RenderData.pMonitor->vecPixelSize.y, m_RenderData.pMonitor->drmFormat);
|
||||
m_RenderData.pCurrentMonData->monitorMirrorFB.alloc(m_RenderData.pMonitor->vecPixelSize.x, m_RenderData.pMonitor->vecPixelSize.y,
|
||||
m_RenderData.pMonitor->output->state->state().drmFormat);
|
||||
|
||||
m_RenderData.pCurrentMonData->monitorMirrorFB.bind();
|
||||
|
||||
@@ -2270,11 +2458,11 @@ void CHyprOpenGLImpl::renderMirrored() {
|
||||
return;
|
||||
|
||||
// replace monitor projection to undo the mirrored monitor's projection
|
||||
wlr_matrix_identity(monitor->projMatrix.data());
|
||||
wlr_matrix_translate(monitor->projMatrix.data(), monitor->vecPixelSize.x / 2.0, monitor->vecPixelSize.y / 2.0);
|
||||
wlr_matrix_transform(monitor->projMatrix.data(), monitor->transform);
|
||||
wlr_matrix_transform(monitor->projMatrix.data(), wlr_output_transform_invert(mirrored->transform));
|
||||
wlr_matrix_translate(monitor->projMatrix.data(), -monitor->vecTransformedSize.x / 2.0, -monitor->vecTransformedSize.y / 2.0);
|
||||
matrixIdentity(m_RenderData.monitorProjection.data());
|
||||
matrixTranslate(m_RenderData.monitorProjection.data(), monitor->vecPixelSize.x / 2.0, monitor->vecPixelSize.y / 2.0);
|
||||
matrixTransform(m_RenderData.monitorProjection.data(), wlTransformToHyprutils(monitor->transform));
|
||||
matrixTransform(m_RenderData.monitorProjection.data(), wlTransformToHyprutils(invertTransform(mirrored->transform)));
|
||||
matrixTranslate(m_RenderData.monitorProjection.data(), -monitor->vecTransformedSize.x / 2.0, -monitor->vecTransformedSize.y / 2.0);
|
||||
|
||||
// clear stuff outside of mirrored area (e.g. when changing to mirrored)
|
||||
clear(CColor(0, 0, 0, 0));
|
||||
@@ -2282,7 +2470,7 @@ void CHyprOpenGLImpl::renderMirrored() {
|
||||
renderTexture(PFB->m_cTex, &monbox, 1.f, 0, false, false);
|
||||
|
||||
// reset matrix for further drawing
|
||||
monitor->updateMatrix();
|
||||
m_RenderData.monitorProjection = monitor->projMatrix;
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderSplash(cairo_t* const CAIRO, cairo_surface_t* const CAIROSURFACE, double offsetY, const Vector2D& size) {
|
||||
@@ -2338,7 +2526,7 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(CMonitor* pMonitor) {
|
||||
const auto PFB = &m_mMonitorBGFBs[pMonitor];
|
||||
PFB->release();
|
||||
|
||||
PFB->alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y, pMonitor->drmFormat);
|
||||
PFB->alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y, pMonitor->output->state->state().drmFormat);
|
||||
Debug::log(LOG, "Allocated texture for BGTex");
|
||||
|
||||
// TODO: use relative paths to the installation
|
||||
@@ -2474,6 +2662,9 @@ void CHyprOpenGLImpl::clearWithTex() {
|
||||
void CHyprOpenGLImpl::destroyMonitorResources(CMonitor* pMonitor) {
|
||||
g_pHyprRenderer->makeEGLCurrent();
|
||||
|
||||
if (!g_pHyprOpenGL)
|
||||
return;
|
||||
|
||||
auto RESIT = g_pHyprOpenGL->m_mMonitorRenderResources.find(pMonitor);
|
||||
if (RESIT != g_pHyprOpenGL->m_mMonitorRenderResources.end()) {
|
||||
RESIT->second.mirrorFB.release();
|
||||
@@ -2500,8 +2691,8 @@ void CHyprOpenGLImpl::saveMatrix() {
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::setMatrixScaleTranslate(const Vector2D& translate, const float& scale) {
|
||||
wlr_matrix_scale(m_RenderData.projection, scale, scale);
|
||||
wlr_matrix_translate(m_RenderData.projection, translate.x, translate.y);
|
||||
matrixScale(m_RenderData.projection, scale, scale);
|
||||
matrixTranslate(m_RenderData.projection, translate.x, translate.y);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::restoreMatrix() {
|
||||
@@ -2533,29 +2724,63 @@ void CHyprOpenGLImpl::setRenderModifEnabled(bool enabled) {
|
||||
}
|
||||
|
||||
uint32_t CHyprOpenGLImpl::getPreferredReadFormat(CMonitor* pMonitor) {
|
||||
GLint glf = -1, glt = -1, as = 0;
|
||||
/*glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &glf);
|
||||
glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &glt);
|
||||
glGetIntegerv(GL_ALPHA_BITS, &as);*/
|
||||
|
||||
if (glf == 0 || glt == 0) {
|
||||
glf = FormatUtils::drmFormatToGL(pMonitor->drmFormat);
|
||||
glt = FormatUtils::glFormatToType(glf);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
return DRM_FORMAT_XBGR8888;
|
||||
return pMonitor->output->state->state().drmFormat;
|
||||
}
|
||||
|
||||
std::vector<SDRMFormat> CHyprOpenGLImpl::getDRMFormats() {
|
||||
return drmFormats;
|
||||
}
|
||||
|
||||
SP<CEGLSync> CHyprOpenGLImpl::createEGLSync(int fenceFD) {
|
||||
std::vector<EGLint> attribs;
|
||||
int dupFd = -1;
|
||||
if (fenceFD > 0) {
|
||||
int dupFd = fcntl(fenceFD, F_DUPFD_CLOEXEC, 0);
|
||||
if (dupFd < 0) {
|
||||
Debug::log(ERR, "createEGLSync: dup failed");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
attribs.push_back(EGL_SYNC_NATIVE_FENCE_FD_ANDROID);
|
||||
attribs.push_back(dupFd);
|
||||
attribs.push_back(EGL_NONE);
|
||||
}
|
||||
|
||||
EGLSyncKHR sync = m_sProc.eglCreateSyncKHR(m_pEglDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, attribs.data());
|
||||
if (sync == EGL_NO_SYNC_KHR) {
|
||||
Debug::log(ERR, "eglCreateSyncKHR failed");
|
||||
if (dupFd >= 0)
|
||||
close(dupFd);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto eglsync = SP<CEGLSync>(new CEGLSync);
|
||||
eglsync->sync = sync;
|
||||
return eglsync;
|
||||
}
|
||||
|
||||
bool CHyprOpenGLImpl::waitForTimelinePoint(SP<CSyncTimeline> timeline, uint64_t point) {
|
||||
int fd = timeline->exportAsSyncFileFD(point);
|
||||
if (fd < 0) {
|
||||
Debug::log(ERR, "waitForTimelinePoint: failed to get a fd from explicit timeline");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto sync = g_pHyprOpenGL->createEGLSync(fd);
|
||||
close(fd);
|
||||
if (!sync) {
|
||||
Debug::log(ERR, "waitForTimelinePoint: failed to get an eglsync from explicit timeline");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!sync->wait()) {
|
||||
Debug::log(ERR, "waitForTimelinePoint: failed to wait on an eglsync from explicit timeline");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SRenderModifData::applyToBox(CBox& box) {
|
||||
if (!enabled)
|
||||
return;
|
||||
@@ -2616,3 +2841,35 @@ float SRenderModifData::combinedScale() {
|
||||
}
|
||||
return scale;
|
||||
}
|
||||
|
||||
CEGLSync::~CEGLSync() {
|
||||
if (sync == EGL_NO_SYNC_KHR)
|
||||
return;
|
||||
|
||||
if (g_pHyprOpenGL->m_sProc.eglDestroySyncKHR(g_pHyprOpenGL->m_pEglDisplay, sync) != EGL_TRUE)
|
||||
Debug::log(ERR, "eglDestroySyncKHR failed");
|
||||
}
|
||||
|
||||
int CEGLSync::dupFenceFD() {
|
||||
if (sync == EGL_NO_SYNC_KHR)
|
||||
return -1;
|
||||
|
||||
int fd = g_pHyprOpenGL->m_sProc.eglDupNativeFenceFDANDROID(g_pHyprOpenGL->m_pEglDisplay, sync);
|
||||
if (fd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
|
||||
Debug::log(ERR, "eglDupNativeFenceFDANDROID failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
bool CEGLSync::wait() {
|
||||
if (sync == EGL_NO_SYNC_KHR)
|
||||
return false;
|
||||
|
||||
if (g_pHyprOpenGL->m_sProc.eglWaitSyncKHR(g_pHyprOpenGL->m_pEglDisplay, sync, 0) != EGL_TRUE) {
|
||||
Debug::log(ERR, "eglWaitSyncKHR failed");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
Reference in New Issue
Block a user