mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-26 05:45:59 +01:00
renderer: Move to a full Hyprland GL rendering pipeline (#3920)
Also updates wlroots
This commit is contained in:
parent
e40e486f61
commit
2ebfd0c745
28 changed files with 453 additions and 230 deletions
2
.github/workflows/ci.yaml
vendored
2
.github/workflows/ci.yaml
vendored
|
@ -40,7 +40,7 @@ jobs:
|
||||||
cp ./LICENSE hyprland/
|
cp ./LICENSE hyprland/
|
||||||
cp build/Hyprland hyprland/
|
cp build/Hyprland hyprland/
|
||||||
cp build/hyprctl/hyprctl hyprland/
|
cp build/hyprctl/hyprctl hyprland/
|
||||||
cp subprojects/wlroots/build/libwlroots.so.12032 hyprland/
|
cp subprojects/wlroots/build/libwlroots.so.13032 hyprland/
|
||||||
cp build/Hyprland hyprland/
|
cp build/Hyprland hyprland/
|
||||||
cp -r example/ hyprland/
|
cp -r example/ hyprland/
|
||||||
cp -r assets/ hyprland/
|
cp -r assets/ hyprland/
|
||||||
|
|
|
@ -57,7 +57,7 @@ ExternalProject_Add(
|
||||||
wlroots
|
wlroots
|
||||||
PREFIX ${CMAKE_SOURCE_DIR}/subprojects/wlroots
|
PREFIX ${CMAKE_SOURCE_DIR}/subprojects/wlroots
|
||||||
SOURCE_DIR ${CMAKE_SOURCE_DIR}/subprojects/wlroots
|
SOURCE_DIR ${CMAKE_SOURCE_DIR}/subprojects/wlroots
|
||||||
PATCH_COMMAND sed -E -i -e "s/(soversion = 12)([^032]|$$)/soversion = 12032/g" meson.build
|
PATCH_COMMAND sed -E -i -e "s/(soversion = 13)([^032]|$$)/soversion = 13032/g" meson.build
|
||||||
CONFIGURE_COMMAND meson setup build --buildtype=${BUILDTYPE_LOWER} -Dwerror=false -Dexamples=false -Drenderers=gles2 $<IF:$<BOOL:${WITH_ASAN}>,-Db_sanitize=address,-Db_sanitize=none> && meson setup build --buildtype=${BUILDTYPE_LOWER} -Dwerror=false -Dexamples=false -Drenderers=gles2 $<IF:$<BOOL:${WITH_ASAN}>,-Db_sanitize=address,-Db_sanitize=none> --reconfigure
|
CONFIGURE_COMMAND meson setup build --buildtype=${BUILDTYPE_LOWER} -Dwerror=false -Dexamples=false -Drenderers=gles2 $<IF:$<BOOL:${WITH_ASAN}>,-Db_sanitize=address,-Db_sanitize=none> && meson setup build --buildtype=${BUILDTYPE_LOWER} -Dwerror=false -Dexamples=false -Drenderers=gles2 $<IF:$<BOOL:${WITH_ASAN}>,-Db_sanitize=address,-Db_sanitize=none> --reconfigure
|
||||||
BUILD_COMMAND ninja -C build
|
BUILD_COMMAND ninja -C build
|
||||||
BUILD_ALWAYS true
|
BUILD_ALWAYS true
|
||||||
|
|
|
@ -67,18 +67,18 @@
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"host": "gitlab.freedesktop.org",
|
"host": "gitlab.freedesktop.org",
|
||||||
"lastModified": 1699292815,
|
"lastModified": 1700736101,
|
||||||
"narHash": "sha256-HXu98PyBMKEWLqiTb8viuLDznud/SdkdJsx5A5CWx7I=",
|
"narHash": "sha256-1Fh1xf/JX5zFbGIF9LDaffaleG6JDwwwnKby0LyiXEA=",
|
||||||
"owner": "wlroots",
|
"owner": "wlroots",
|
||||||
"repo": "wlroots",
|
"repo": "wlroots",
|
||||||
"rev": "5de9e1a99d6642c2d09d589aa37ff0a8945dcee1",
|
"rev": "f1762f428b0ef2989c81f57ea9e810403d34d946",
|
||||||
"type": "gitlab"
|
"type": "gitlab"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"host": "gitlab.freedesktop.org",
|
"host": "gitlab.freedesktop.org",
|
||||||
"owner": "wlroots",
|
"owner": "wlroots",
|
||||||
"repo": "wlroots",
|
"repo": "wlroots",
|
||||||
"rev": "5de9e1a99d6642c2d09d589aa37ff0a8945dcee1",
|
"rev": "f1762f428b0ef2989c81f57ea9e810403d34d946",
|
||||||
"type": "gitlab"
|
"type": "gitlab"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
host = "gitlab.freedesktop.org";
|
host = "gitlab.freedesktop.org";
|
||||||
owner = "wlroots";
|
owner = "wlroots";
|
||||||
repo = "wlroots";
|
repo = "wlroots";
|
||||||
rev = "5de9e1a99d6642c2d09d589aa37ff0a8945dcee1";
|
rev = "f1762f428b0ef2989c81f57ea9e810403d34d946";
|
||||||
flake = false;
|
flake = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -225,7 +225,6 @@ void CCompositor::initServer() {
|
||||||
|
|
||||||
m_sWLROutputMgr = wlr_output_manager_v1_create(m_sWLDisplay);
|
m_sWLROutputMgr = wlr_output_manager_v1_create(m_sWLDisplay);
|
||||||
|
|
||||||
m_sWLRInhibitMgr = wlr_input_inhibit_manager_create(m_sWLDisplay);
|
|
||||||
m_sWLRKbShInhibitMgr = wlr_keyboard_shortcuts_inhibit_v1_create(m_sWLDisplay);
|
m_sWLRKbShInhibitMgr = wlr_keyboard_shortcuts_inhibit_v1_create(m_sWLDisplay);
|
||||||
|
|
||||||
m_sWLRPointerConstraints = wlr_pointer_constraints_v1_create(m_sWLDisplay);
|
m_sWLRPointerConstraints = wlr_pointer_constraints_v1_create(m_sWLDisplay);
|
||||||
|
@ -283,7 +282,7 @@ void CCompositor::initServer() {
|
||||||
|
|
||||||
void CCompositor::initAllSignals() {
|
void CCompositor::initAllSignals() {
|
||||||
addWLSignal(&m_sWLRBackend->events.new_output, &Events::listen_newOutput, m_sWLRBackend, "Backend");
|
addWLSignal(&m_sWLRBackend->events.new_output, &Events::listen_newOutput, m_sWLRBackend, "Backend");
|
||||||
addWLSignal(&m_sWLRXDGShell->events.new_surface, &Events::listen_newXDGSurface, m_sWLRXDGShell, "XDG Shell");
|
addWLSignal(&m_sWLRXDGShell->events.new_surface, &Events::listen_newXDGToplevel, m_sWLRXDGShell, "XDG Shell");
|
||||||
addWLSignal(&m_sWLRCursor->events.motion, &Events::listen_mouseMove, m_sWLRCursor, "WLRCursor");
|
addWLSignal(&m_sWLRCursor->events.motion, &Events::listen_mouseMove, m_sWLRCursor, "WLRCursor");
|
||||||
addWLSignal(&m_sWLRCursor->events.motion_absolute, &Events::listen_mouseMoveAbsolute, m_sWLRCursor, "WLRCursor");
|
addWLSignal(&m_sWLRCursor->events.motion_absolute, &Events::listen_mouseMoveAbsolute, m_sWLRCursor, "WLRCursor");
|
||||||
addWLSignal(&m_sWLRCursor->events.button, &Events::listen_mouseButton, m_sWLRCursor, "WLRCursor");
|
addWLSignal(&m_sWLRCursor->events.button, &Events::listen_mouseButton, m_sWLRCursor, "WLRCursor");
|
||||||
|
@ -312,8 +311,6 @@ void CCompositor::initAllSignals() {
|
||||||
addWLSignal(&m_sWLROutputLayout->events.change, &Events::listen_change, m_sWLROutputLayout, "OutputLayout");
|
addWLSignal(&m_sWLROutputLayout->events.change, &Events::listen_change, m_sWLROutputLayout, "OutputLayout");
|
||||||
addWLSignal(&m_sWLROutputMgr->events.apply, &Events::listen_outputMgrApply, m_sWLROutputMgr, "OutputMgr");
|
addWLSignal(&m_sWLROutputMgr->events.apply, &Events::listen_outputMgrApply, m_sWLROutputMgr, "OutputMgr");
|
||||||
addWLSignal(&m_sWLROutputMgr->events.test, &Events::listen_outputMgrTest, m_sWLROutputMgr, "OutputMgr");
|
addWLSignal(&m_sWLROutputMgr->events.test, &Events::listen_outputMgrTest, m_sWLROutputMgr, "OutputMgr");
|
||||||
addWLSignal(&m_sWLRInhibitMgr->events.activate, &Events::listen_InhibitActivate, m_sWLRInhibitMgr, "InhibitMgr");
|
|
||||||
addWLSignal(&m_sWLRInhibitMgr->events.deactivate, &Events::listen_InhibitDeactivate, m_sWLRInhibitMgr, "InhibitMgr");
|
|
||||||
addWLSignal(&m_sWLRPointerConstraints->events.new_constraint, &Events::listen_newConstraint, m_sWLRPointerConstraints, "PointerConstraints");
|
addWLSignal(&m_sWLRPointerConstraints->events.new_constraint, &Events::listen_newConstraint, m_sWLRPointerConstraints, "PointerConstraints");
|
||||||
addWLSignal(&m_sWLRXDGDecoMgr->events.new_toplevel_decoration, &Events::listen_NewXDGDeco, m_sWLRXDGDecoMgr, "XDGDecoMgr");
|
addWLSignal(&m_sWLRXDGDecoMgr->events.new_toplevel_decoration, &Events::listen_NewXDGDeco, m_sWLRXDGDecoMgr, "XDGDecoMgr");
|
||||||
addWLSignal(&m_sWLRVirtPtrMgr->events.new_virtual_pointer, &Events::listen_newVirtPtr, m_sWLRVirtPtrMgr, "VirtPtrMgr");
|
addWLSignal(&m_sWLRVirtPtrMgr->events.new_virtual_pointer, &Events::listen_newVirtPtr, m_sWLRVirtPtrMgr, "VirtPtrMgr");
|
||||||
|
|
|
@ -29,7 +29,8 @@
|
||||||
#include "plugins/PluginSystem.hpp"
|
#include "plugins/PluginSystem.hpp"
|
||||||
#include "helpers/Watchdog.hpp"
|
#include "helpers/Watchdog.hpp"
|
||||||
|
|
||||||
enum eManagersInitStage {
|
enum eManagersInitStage
|
||||||
|
{
|
||||||
STAGE_PRIORITY = 0,
|
STAGE_PRIORITY = 0,
|
||||||
STAGE_LATE
|
STAGE_LATE
|
||||||
};
|
};
|
||||||
|
@ -61,7 +62,6 @@ class CCompositor {
|
||||||
wlr_virtual_keyboard_manager_v1* m_sWLRVKeyboardMgr;
|
wlr_virtual_keyboard_manager_v1* m_sWLRVKeyboardMgr;
|
||||||
wlr_output_manager_v1* m_sWLROutputMgr;
|
wlr_output_manager_v1* m_sWLROutputMgr;
|
||||||
wlr_presentation* m_sWLRPresentation;
|
wlr_presentation* m_sWLRPresentation;
|
||||||
wlr_input_inhibit_manager* m_sWLRInhibitMgr;
|
|
||||||
wlr_keyboard_shortcuts_inhibit_manager_v1* m_sWLRKbShInhibitMgr;
|
wlr_keyboard_shortcuts_inhibit_manager_v1* m_sWLRKbShInhibitMgr;
|
||||||
wlr_egl* m_sWLREGL;
|
wlr_egl* m_sWLREGL;
|
||||||
int m_iDRMFD;
|
int m_iDRMFD;
|
||||||
|
|
|
@ -13,15 +13,6 @@ inline PFNGLGETQUERYOBJECTUI64VEXTPROC glGetQueryObjectui64v;
|
||||||
|
|
||||||
#include "../../subprojects/tracy/public/tracy/TracyOpenGL.hpp"
|
#include "../../subprojects/tracy/public/tracy/TracyOpenGL.hpp"
|
||||||
|
|
||||||
inline void loadGLProc(void* pProc, const char* name) {
|
|
||||||
void* proc = (void*)eglGetProcAddress(name);
|
|
||||||
if (proc == NULL) {
|
|
||||||
Debug::log(CRIT, "[Tracy GPU Profiling] eglGetProcAddress({}) failed", name);
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
*(void**)pProc = proc;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define TRACY_GPU_CONTEXT TracyGpuContext
|
#define TRACY_GPU_CONTEXT TracyGpuContext
|
||||||
#define TRACY_GPU_ZONE(e) TracyGpuZone(e)
|
#define TRACY_GPU_ZONE(e) TracyGpuZone(e)
|
||||||
#define TRACY_GPU_COLLECT TracyGpuCollect
|
#define TRACY_GPU_COLLECT TracyGpuCollect
|
||||||
|
|
|
@ -42,7 +42,7 @@ namespace Events {
|
||||||
DYNLISTENFUNC(repositionPopupXDG);
|
DYNLISTENFUNC(repositionPopupXDG);
|
||||||
|
|
||||||
// Surface XDG (window)
|
// Surface XDG (window)
|
||||||
LISTENER(newXDGSurface);
|
LISTENER(newXDGToplevel);
|
||||||
LISTENER(activateXDG);
|
LISTENER(activateXDG);
|
||||||
|
|
||||||
// Window events
|
// Window events
|
||||||
|
@ -121,10 +121,6 @@ namespace Events {
|
||||||
DYNLISTENFUNC(destroyDragIcon);
|
DYNLISTENFUNC(destroyDragIcon);
|
||||||
DYNLISTENFUNC(commitDragIcon);
|
DYNLISTENFUNC(commitDragIcon);
|
||||||
|
|
||||||
// Inhibit
|
|
||||||
LISTENER(InhibitActivate);
|
|
||||||
LISTENER(InhibitDeactivate);
|
|
||||||
|
|
||||||
// Deco XDG
|
// Deco XDG
|
||||||
LISTENER(NewXDGDeco);
|
LISTENER(NewXDGDeco);
|
||||||
|
|
||||||
|
|
|
@ -156,20 +156,6 @@ void Events::listener_commitDragIcon(void* owner, void* data) {
|
||||||
Debug::log(LOG, "Drag icon committed.");
|
Debug::log(LOG, "Drag icon committed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Events::listener_InhibitActivate(wl_listener* listener, void* data) {
|
|
||||||
Debug::log(LOG, "Activated exclusive for {:x}.", (uintptr_t)g_pCompositor->m_sSeat.exclusiveClient);
|
|
||||||
|
|
||||||
g_pInputManager->refocus();
|
|
||||||
g_pCompositor->m_sSeat.exclusiveClient = g_pCompositor->m_sWLRInhibitMgr->active_client;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Events::listener_InhibitDeactivate(wl_listener* listener, void* data) {
|
|
||||||
Debug::log(LOG, "Deactivated exclusive.");
|
|
||||||
|
|
||||||
g_pCompositor->m_sSeat.exclusiveClient = nullptr;
|
|
||||||
g_pInputManager->refocus();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Events::listener_RendererDestroy(wl_listener* listener, void* data) {
|
void Events::listener_RendererDestroy(wl_listener* listener, void* data) {
|
||||||
Debug::log(LOG, "!!Renderer destroyed!!");
|
Debug::log(LOG, "!!Renderer destroyed!!");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1169,7 +1169,7 @@ void Events::listener_surfaceXWayland(wl_listener* listener, void* data) {
|
||||||
PNEWWINDOW->hyprListener_configureX11.initCallback(&XWSURFACE->events.request_configure, &Events::listener_configureX11, PNEWWINDOW, "XWayland Window");
|
PNEWWINDOW->hyprListener_configureX11.initCallback(&XWSURFACE->events.request_configure, &Events::listener_configureX11, PNEWWINDOW, "XWayland Window");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Events::listener_newXDGSurface(wl_listener* listener, void* data) {
|
void Events::listener_newXDGToplevel(wl_listener* listener, void* data) {
|
||||||
// A window got opened
|
// A window got opened
|
||||||
const auto XDGSURFACE = (wlr_xdg_surface*)data;
|
const auto XDGSURFACE = (wlr_xdg_surface*)data;
|
||||||
|
|
||||||
|
|
|
@ -643,3 +643,12 @@ void CMonitor::moveTo(const Vector2D& pos) {
|
||||||
Vector2D CMonitor::middle() {
|
Vector2D CMonitor::middle() {
|
||||||
return vecPosition + vecSize / 2.f;
|
return vecPosition + vecSize / 2.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CMonitor::updateMatrix() {
|
||||||
|
wlr_matrix_identity(projMatrix.data());
|
||||||
|
if (transform != WL_OUTPUT_TRANSFORM_NORMAL) {
|
||||||
|
wlr_matrix_translate(projMatrix.data(), vecTransformedSize.x / 2.0, vecTransformedSize.y / 2.0);
|
||||||
|
wlr_matrix_transform(projMatrix.data(), transform);
|
||||||
|
wlr_matrix_translate(projMatrix.data(), -vecTransformedSize.x / 2.0, -vecTransformedSize.y / 2.0);
|
||||||
|
}
|
||||||
|
}
|
|
@ -50,32 +50,33 @@ class CMonitor {
|
||||||
drmModeModeInfo customDrmMode = {};
|
drmModeModeInfo customDrmMode = {};
|
||||||
|
|
||||||
// WLR stuff
|
// WLR stuff
|
||||||
wlr_damage_ring damage;
|
wlr_damage_ring damage;
|
||||||
wlr_output* output = nullptr;
|
wlr_output* output = nullptr;
|
||||||
float refreshRate = 60;
|
float refreshRate = 60;
|
||||||
int framesToSkip = 0;
|
int framesToSkip = 0;
|
||||||
int forceFullFrames = 0;
|
int forceFullFrames = 0;
|
||||||
bool noFrameSchedule = false;
|
bool noFrameSchedule = false;
|
||||||
bool scheduledRecalc = false;
|
bool scheduledRecalc = false;
|
||||||
wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||||
bool gammaChanged = false;
|
bool gammaChanged = false;
|
||||||
float xwaylandScale = 1.f;
|
float xwaylandScale = 1.f;
|
||||||
|
std::array<float, 9> projMatrix = {0};
|
||||||
|
|
||||||
bool dpmsStatus = true;
|
bool dpmsStatus = true;
|
||||||
bool vrrActive = false; // this can be TRUE even if VRR is not active in the case that this display does not support it.
|
bool vrrActive = false; // this can be TRUE even if VRR is not active in the case that this display does not support it.
|
||||||
bool enabled10bit = false; // as above, this can be TRUE even if 10 bit failed.
|
bool enabled10bit = false; // as above, this can be TRUE even if 10 bit failed.
|
||||||
bool createdByUser = false;
|
bool createdByUser = false;
|
||||||
uint32_t drmFormat = DRM_FORMAT_INVALID;
|
uint32_t drmFormat = DRM_FORMAT_INVALID;
|
||||||
bool isUnsafeFallback = false;
|
bool isUnsafeFallback = false;
|
||||||
|
|
||||||
bool pendingFrame = false; // if we schedule a frame during rendering, reschedule it after
|
bool pendingFrame = false; // if we schedule a frame during rendering, reschedule it after
|
||||||
bool renderingActive = false;
|
bool renderingActive = false;
|
||||||
|
|
||||||
wl_event_source* renderTimer = nullptr; // for RAT
|
wl_event_source* renderTimer = nullptr; // for RAT
|
||||||
bool RATScheduled = false;
|
bool RATScheduled = false;
|
||||||
CTimer lastPresentationTimer;
|
CTimer lastPresentationTimer;
|
||||||
|
|
||||||
SMonitorRule activeMonitorRule;
|
SMonitorRule activeMonitorRule;
|
||||||
|
|
||||||
// mirroring
|
// mirroring
|
||||||
CMonitor* pMirrorOf = nullptr;
|
CMonitor* pMirrorOf = nullptr;
|
||||||
|
@ -123,6 +124,7 @@ class CMonitor {
|
||||||
void setSpecialWorkspace(const int& id);
|
void setSpecialWorkspace(const int& id);
|
||||||
void moveTo(const Vector2D& pos);
|
void moveTo(const Vector2D& pos);
|
||||||
Vector2D middle();
|
Vector2D middle();
|
||||||
|
void updateMatrix();
|
||||||
|
|
||||||
bool m_bEnabled = false;
|
bool m_bEnabled = false;
|
||||||
bool m_bRenderingInitPassed = false;
|
bool m_bRenderingInitPassed = false;
|
||||||
|
|
|
@ -93,6 +93,15 @@ CRegion& CRegion::translate(const Vector2D& vec) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CRegion& CRegion::transform(const wl_output_transform t, double w, double h) {
|
||||||
|
wlr_region_transform(&m_rRegion, &m_rRegion, t, w, h);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
CRegion CRegion::copy() const {
|
||||||
|
return CRegion(*this);
|
||||||
|
}
|
||||||
|
|
||||||
CRegion& CRegion::scale(float scale) {
|
CRegion& CRegion::scale(float scale) {
|
||||||
wlr_region_scale(&m_rRegion, &m_rRegion, scale);
|
wlr_region_scale(&m_rRegion, &m_rRegion, scale);
|
||||||
return *this;
|
return *this;
|
||||||
|
|
|
@ -45,12 +45,14 @@ class CRegion {
|
||||||
CRegion& intersect(const CRegion& other);
|
CRegion& intersect(const CRegion& other);
|
||||||
CRegion& intersect(double x, double y, double w, double h);
|
CRegion& intersect(double x, double y, double w, double h);
|
||||||
CRegion& translate(const Vector2D& vec);
|
CRegion& translate(const Vector2D& vec);
|
||||||
|
CRegion& transform(const wl_output_transform t, double w, double h);
|
||||||
CRegion& invert(pixman_box32_t* box);
|
CRegion& invert(pixman_box32_t* box);
|
||||||
CRegion& scale(float scale);
|
CRegion& scale(float scale);
|
||||||
CBox getExtents();
|
CBox getExtents();
|
||||||
bool containsPoint(const Vector2D& vec) const;
|
bool containsPoint(const Vector2D& vec) const;
|
||||||
bool empty() const;
|
bool empty() const;
|
||||||
Vector2D closestPoint(const Vector2D& vec) const;
|
Vector2D closestPoint(const Vector2D& vec) const;
|
||||||
|
CRegion copy() const;
|
||||||
|
|
||||||
std::vector<pixman_box32_t> getRects() const;
|
std::vector<pixman_box32_t> getRects() const;
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,6 @@ extern "C" {
|
||||||
#include <wlr/types/wlr_xdg_shell.h>
|
#include <wlr/types/wlr_xdg_shell.h>
|
||||||
#include <wlr/types/wlr_subcompositor.h>
|
#include <wlr/types/wlr_subcompositor.h>
|
||||||
#include <wlr/types/wlr_damage_ring.h>
|
#include <wlr/types/wlr_damage_ring.h>
|
||||||
#include <wlr/types/wlr_input_inhibitor.h>
|
|
||||||
#include <wlr/types/wlr_keyboard_shortcuts_inhibit_v1.h>
|
#include <wlr/types/wlr_keyboard_shortcuts_inhibit_v1.h>
|
||||||
#include <wlr/types/wlr_virtual_pointer_v1.h>
|
#include <wlr/types/wlr_virtual_pointer_v1.h>
|
||||||
#include <wlr/types/wlr_foreign_toplevel_management_v1.h>
|
#include <wlr/types/wlr_foreign_toplevel_management_v1.h>
|
||||||
|
@ -106,6 +105,9 @@ extern "C" {
|
||||||
#include <wlr/types/wlr_cursor_shape_v1.h>
|
#include <wlr/types/wlr_cursor_shape_v1.h>
|
||||||
#include <wlr/types/wlr_tearing_control_v1.h>
|
#include <wlr/types/wlr_tearing_control_v1.h>
|
||||||
#include <wlr/util/box.h>
|
#include <wlr/util/box.h>
|
||||||
|
#include <wlr/util/transform.h>
|
||||||
|
#include <wlr/render/swapchain.h>
|
||||||
|
#include <wlr/render/egl.h>
|
||||||
|
|
||||||
#include <libdrm/drm_fourcc.h>
|
#include <libdrm/drm_fourcc.h>
|
||||||
|
|
||||||
|
|
|
@ -45,10 +45,11 @@ void CHyprXWaylandManager::activateSurface(wlr_surface* pSurface, bool activate)
|
||||||
wlr_xdg_toplevel_set_activated(PSURF->toplevel, activate);
|
wlr_xdg_toplevel_set_activated(PSURF->toplevel, activate);
|
||||||
|
|
||||||
} else if (wlr_xwayland_surface_try_from_wlr_surface(pSurface)) {
|
} else if (wlr_xwayland_surface_try_from_wlr_surface(pSurface)) {
|
||||||
wlr_xwayland_surface_activate(wlr_xwayland_surface_try_from_wlr_surface(pSurface), activate);
|
const auto XSURF = wlr_xwayland_surface_try_from_wlr_surface(pSurface);
|
||||||
|
wlr_xwayland_surface_activate(XSURF, activate);
|
||||||
|
|
||||||
if (activate)
|
if (activate && !XSURF->override_redirect)
|
||||||
wlr_xwayland_surface_restack(wlr_xwayland_surface_try_from_wlr_surface(pSurface), nullptr, XCB_STACK_MODE_ABOVE);
|
wlr_xwayland_surface_restack(XSURF, nullptr, XCB_STACK_MODE_ABOVE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +59,8 @@ void CHyprXWaylandManager::activateWindow(CWindow* pWindow, bool activate) {
|
||||||
|
|
||||||
if (activate) {
|
if (activate) {
|
||||||
wlr_xwayland_surface_set_minimized(pWindow->m_uSurface.xwayland, false);
|
wlr_xwayland_surface_set_minimized(pWindow->m_uSurface.xwayland, false);
|
||||||
wlr_xwayland_surface_restack(pWindow->m_uSurface.xwayland, nullptr, XCB_STACK_MODE_ABOVE);
|
if (!pWindow->m_uSurface.xwayland->override_redirect)
|
||||||
|
wlr_xwayland_surface_restack(pWindow->m_uSurface.xwayland, nullptr, XCB_STACK_MODE_ABOVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_xwayland_surface_activate(pWindow->m_uSurface.xwayland, activate);
|
wlr_xwayland_surface_activate(pWindow->m_uSurface.xwayland, activate);
|
||||||
|
|
|
@ -448,25 +448,19 @@ bool CScreencopyProtocolManager::copyFrameDmabuf(SScreencopyFrame* frame) {
|
||||||
if (!sourceTex)
|
if (!sourceTex)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
float glMatrix[9];
|
CRegion fakeDamage = {0, 0, frame->box.width, frame->box.height};
|
||||||
wlr_matrix_identity(glMatrix);
|
|
||||||
wlr_matrix_translate(glMatrix, -frame->box.x, -frame->box.y);
|
|
||||||
wlr_matrix_scale(glMatrix, frame->pMonitor->vecPixelSize.x, frame->pMonitor->vecPixelSize.y);
|
|
||||||
|
|
||||||
if (!wlr_renderer_begin_with_buffer(g_pCompositor->m_sWLRRenderer, frame->buffer)) {
|
if (!g_pHyprRenderer->beginRender(frame->pMonitor, fakeDamage, RENDER_MODE_TO_BUFFER, frame->buffer))
|
||||||
Debug::log(ERR, "[sc] dmabuf: Client requested a copy to a buffer that failed to pass wlr_renderer_begin_with_buffer");
|
|
||||||
wlr_texture_destroy(sourceTex);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
float color[] = {0, 0, 0, 0};
|
CBox monbox = CBox{0, 0, frame->pMonitor->vecPixelSize.x, frame->pMonitor->vecPixelSize.y}.translate({-frame->box.x, -frame->box.y});
|
||||||
wlr_renderer_clear(g_pCompositor->m_sWLRRenderer, color);
|
g_pHyprOpenGL->setMonitorTransformEnabled(false);
|
||||||
// TODO: use hl render methods to use damage
|
g_pHyprOpenGL->renderTexture(sourceTex, &monbox, 1);
|
||||||
wlr_render_texture_with_matrix(g_pCompositor->m_sWLRRenderer, sourceTex, glMatrix, 1.0f);
|
g_pHyprOpenGL->setMonitorTransformEnabled(true);
|
||||||
|
|
||||||
|
g_pHyprRenderer->endRender();
|
||||||
|
|
||||||
wlr_texture_destroy(sourceTex);
|
wlr_texture_destroy(sourceTex);
|
||||||
|
|
||||||
wlr_renderer_end(g_pCompositor->m_sWLRRenderer);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,7 +134,8 @@ void CToplevelExportProtocolManager::removeFrame(SScreencopyFrame* frame, bool f
|
||||||
std::erase_if(m_vFramesAwaitingWrite, [&](const auto& other) { return other == frame; });
|
std::erase_if(m_vFramesAwaitingWrite, [&](const auto& other) { return other == frame; });
|
||||||
|
|
||||||
wl_resource_set_user_data(frame->resource, nullptr);
|
wl_resource_set_user_data(frame->resource, nullptr);
|
||||||
wlr_buffer_unlock(frame->buffer);
|
if (frame->buffer && frame->buffer->n_locks > 0)
|
||||||
|
wlr_buffer_unlock(frame->buffer);
|
||||||
removeClient(frame->client, force);
|
removeClient(frame->client, force);
|
||||||
m_lFrames.remove(*frame);
|
m_lFrames.remove(*frame);
|
||||||
}
|
}
|
||||||
|
@ -362,18 +363,14 @@ bool CToplevelExportProtocolManager::copyFrameShm(SScreencopyFrame* frame, times
|
||||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(frame->pWindow->m_iMonitorID);
|
const auto PMONITOR = g_pCompositor->getMonitorFromID(frame->pWindow->m_iMonitorID);
|
||||||
CRegion fakeDamage{0, 0, PMONITOR->vecPixelSize.x * 10, PMONITOR->vecPixelSize.y * 10};
|
CRegion fakeDamage{0, 0, PMONITOR->vecPixelSize.x * 10, PMONITOR->vecPixelSize.y * 10};
|
||||||
|
|
||||||
if (frame->overlayCursor)
|
if (!g_pHyprRenderer->beginRender(PMONITOR, fakeDamage, RENDER_MODE_FULL_FAKE)) {
|
||||||
wlr_output_lock_software_cursors(PMONITOR->output, true);
|
|
||||||
|
|
||||||
if (!wlr_output_attach_render(PMONITOR->output, nullptr)) {
|
|
||||||
Debug::log(ERR, "[toplevel_export] Couldn't attach render");
|
|
||||||
wlr_buffer_end_data_ptr_access(frame->buffer);
|
wlr_buffer_end_data_ptr_access(frame->buffer);
|
||||||
if (frame->overlayCursor)
|
|
||||||
wlr_output_lock_software_cursors(PMONITOR->output, false);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_pHyprOpenGL->begin(PMONITOR, &fakeDamage, true);
|
if (frame->overlayCursor)
|
||||||
|
wlr_output_lock_software_cursors(PMONITOR->output, true);
|
||||||
|
|
||||||
g_pHyprOpenGL->clear(CColor(0, 0, 0, 1.0));
|
g_pHyprOpenGL->clear(CColor(0, 0, 0, 1.0));
|
||||||
|
|
||||||
// render client at 0,0
|
// render client at 0,0
|
||||||
|
@ -381,46 +378,25 @@ bool CToplevelExportProtocolManager::copyFrameShm(SScreencopyFrame* frame, times
|
||||||
g_pHyprRenderer->renderWindow(frame->pWindow, PMONITOR, now, false, RENDER_PASS_ALL, true, true);
|
g_pHyprRenderer->renderWindow(frame->pWindow, PMONITOR, now, false, RENDER_PASS_ALL, true, true);
|
||||||
g_pHyprRenderer->m_bBlockSurfaceFeedback = false;
|
g_pHyprRenderer->m_bBlockSurfaceFeedback = false;
|
||||||
|
|
||||||
if (frame->overlayCursor && wlr_renderer_begin(g_pCompositor->m_sWLRRenderer, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y)) {
|
if (frame->overlayCursor)
|
||||||
// hack le massive
|
g_pHyprRenderer->renderSoftwareCursors(PMONITOR, fakeDamage, g_pInputManager->getMouseCoordsInternal() - frame->pWindow->m_vRealPosition.vec());
|
||||||
wlr_output_cursor* cursor;
|
|
||||||
const auto OFFSET = frame->pWindow->m_vRealPosition.vec() - PMONITOR->vecPosition;
|
|
||||||
wl_list_for_each(cursor, &PMONITOR->output->cursors, link) {
|
|
||||||
if (!cursor->enabled || !cursor->visible || PMONITOR->output->hardware_cursor == cursor) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
cursor->x -= OFFSET.x;
|
|
||||||
cursor->y -= OFFSET.y;
|
|
||||||
}
|
|
||||||
wlr_output_render_software_cursors(PMONITOR->output, NULL);
|
|
||||||
wl_list_for_each(cursor, &PMONITOR->output->cursors, link) {
|
|
||||||
if (!cursor->enabled || !cursor->visible || PMONITOR->output->hardware_cursor == cursor) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
cursor->x += OFFSET.x;
|
|
||||||
cursor->y += OFFSET.y;
|
|
||||||
}
|
|
||||||
wlr_renderer_end(g_pCompositor->m_sWLRRenderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy pixels
|
// copy pixels
|
||||||
const auto PFORMAT = gles2FromDRM(format);
|
const auto PFORMAT = gles2FromDRM(format);
|
||||||
if (!PFORMAT) {
|
if (!PFORMAT) {
|
||||||
Debug::log(ERR, "[toplevel_export] Cannot read pixels, unsupported format {:x}", (uintptr_t)PFORMAT);
|
Debug::log(ERR, "[toplevel_export] Cannot read pixels, unsupported format {:x}", (uintptr_t)PFORMAT);
|
||||||
g_pHyprOpenGL->end();
|
g_pHyprRenderer->endRender();
|
||||||
wlr_buffer_end_data_ptr_access(frame->buffer);
|
wlr_buffer_end_data_ptr_access(frame->buffer);
|
||||||
if (frame->overlayCursor)
|
if (frame->overlayCursor)
|
||||||
wlr_output_lock_software_cursors(PMONITOR->output, false);
|
wlr_output_lock_software_cursors(PMONITOR->output, false);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, g_pHyprOpenGL->m_RenderData.pCurrentMonData->primaryFB.m_iFb);
|
g_pHyprOpenGL->m_RenderData.mainFB->bind();
|
||||||
|
|
||||||
glReadPixels(0, 0, frame->box.width, frame->box.height, PFORMAT->gl_format, PFORMAT->gl_type, data);
|
glReadPixels(0, 0, frame->box.width, frame->box.height, PFORMAT->gl_format, PFORMAT->gl_type, data);
|
||||||
|
|
||||||
g_pHyprOpenGL->end();
|
g_pHyprRenderer->endRender();
|
||||||
|
|
||||||
wlr_output_rollback(PMONITOR->output);
|
|
||||||
|
|
||||||
wlr_buffer_end_data_ptr_access(frame->buffer);
|
wlr_buffer_end_data_ptr_access(frame->buffer);
|
||||||
|
|
||||||
|
@ -431,14 +407,12 @@ bool CToplevelExportProtocolManager::copyFrameShm(SScreencopyFrame* frame, times
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CToplevelExportProtocolManager::copyFrameDmabuf(SScreencopyFrame* frame, timespec* now) {
|
bool CToplevelExportProtocolManager::copyFrameDmabuf(SScreencopyFrame* frame, timespec* now) {
|
||||||
if (!wlr_renderer_begin_with_buffer(g_pCompositor->m_sWLRRenderer, frame->buffer))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(frame->pWindow->m_iMonitorID);
|
const auto PMONITOR = g_pCompositor->getMonitorFromID(frame->pWindow->m_iMonitorID);
|
||||||
|
|
||||||
CRegion fakeDamage{0, 0, INT16_MAX, INT16_MAX};
|
CRegion fakeDamage{0, 0, INT16_MAX, INT16_MAX};
|
||||||
|
|
||||||
g_pHyprOpenGL->begin(PMONITOR, &fakeDamage, true);
|
if (!g_pHyprRenderer->beginRender(PMONITOR, fakeDamage, RENDER_MODE_TO_BUFFER, frame->buffer))
|
||||||
|
return false;
|
||||||
|
|
||||||
g_pHyprOpenGL->clear(CColor(0, 0, 0, 1.0));
|
g_pHyprOpenGL->clear(CColor(0, 0, 0, 1.0));
|
||||||
|
|
||||||
|
@ -446,14 +420,10 @@ bool CToplevelExportProtocolManager::copyFrameDmabuf(SScreencopyFrame* frame, ti
|
||||||
g_pHyprRenderer->renderWindow(frame->pWindow, PMONITOR, now, false, RENDER_PASS_ALL, true, true);
|
g_pHyprRenderer->renderWindow(frame->pWindow, PMONITOR, now, false, RENDER_PASS_ALL, true, true);
|
||||||
g_pHyprRenderer->m_bBlockSurfaceFeedback = false;
|
g_pHyprRenderer->m_bBlockSurfaceFeedback = false;
|
||||||
|
|
||||||
g_pHyprOpenGL->bindWlrOutputFb();
|
if (frame->overlayCursor)
|
||||||
|
g_pHyprRenderer->renderSoftwareCursors(PMONITOR, fakeDamage, g_pInputManager->getMouseCoordsInternal() - frame->pWindow->m_vRealPosition.vec());
|
||||||
|
|
||||||
CBox monbox = {0, 0, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y};
|
g_pHyprRenderer->endRender();
|
||||||
g_pHyprOpenGL->renderTexture(g_pHyprOpenGL->m_RenderData.pCurrentMonData->primaryFB.m_cTex, &monbox, 1.f);
|
|
||||||
|
|
||||||
g_pHyprOpenGL->end();
|
|
||||||
|
|
||||||
wlr_renderer_end(g_pCompositor->m_sWLRRenderer);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,21 @@ bool CFramebuffer::alloc(int w, int h, uint32_t drmFormat) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CFramebuffer::addStencil() {
|
||||||
|
glBindTexture(GL_TEXTURE_2D, m_pStencilTex->m_iTexID);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, m_vSize.x, m_vSize.y, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0);
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, m_iFb);
|
||||||
|
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_pStencilTex->m_iTexID, 0);
|
||||||
|
|
||||||
|
auto status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||||
|
RASSERT((status == GL_FRAMEBUFFER_COMPLETE), "Failed adding a stencil to fbo!", status);
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, g_pHyprOpenGL->m_iCurrentOutputFb);
|
||||||
|
}
|
||||||
|
|
||||||
void CFramebuffer::bind() {
|
void CFramebuffer::bind() {
|
||||||
#ifndef GLES2
|
#ifndef GLES2
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_iFb);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_iFb);
|
||||||
|
|
|
@ -8,6 +8,7 @@ class CFramebuffer {
|
||||||
~CFramebuffer();
|
~CFramebuffer();
|
||||||
|
|
||||||
bool alloc(int w, int h, uint32_t format = GL_RGBA);
|
bool alloc(int w, int h, uint32_t format = GL_RGBA);
|
||||||
|
void addStencil();
|
||||||
void bind();
|
void bind();
|
||||||
void release();
|
void release();
|
||||||
void reset();
|
void reset();
|
||||||
|
|
|
@ -5,6 +5,15 @@
|
||||||
#include "Shaders.hpp"
|
#include "Shaders.hpp"
|
||||||
#include <random>
|
#include <random>
|
||||||
|
|
||||||
|
inline void loadGLProc(void* pProc, const char* name) {
|
||||||
|
void* proc = (void*)eglGetProcAddress(name);
|
||||||
|
if (proc == NULL) {
|
||||||
|
Debug::log(CRIT, "[Tracy GPU Profiling] eglGetProcAddress({}) failed", name);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
*(void**)pProc = proc;
|
||||||
|
}
|
||||||
|
|
||||||
CHyprOpenGLImpl::CHyprOpenGLImpl() {
|
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)),
|
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!");
|
"Couldn't unset current EGL!");
|
||||||
|
@ -23,6 +32,9 @@ CHyprOpenGLImpl::CHyprOpenGLImpl() {
|
||||||
Debug::log(LOG, "Renderer: {}", (char*)glGetString(GL_RENDERER));
|
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 size: {}", std::count(m_szExtensions.begin(), m_szExtensions.end(), ' '));
|
||||||
|
|
||||||
|
loadGLProc(&m_sProc.glEGLImageTargetRenderbufferStorageOES, "glEGLImageTargetRenderbufferStorageOES");
|
||||||
|
loadGLProc(&m_sProc.eglDestroyImageKHR, "eglDestroyImageKHR");
|
||||||
|
|
||||||
#ifdef USE_TRACY_GPU
|
#ifdef USE_TRACY_GPU
|
||||||
|
|
||||||
loadGLProc(&glQueryCounter, "glQueryCounterEXT");
|
loadGLProc(&glQueryCounter, "glQueryCounterEXT");
|
||||||
|
@ -106,11 +118,9 @@ GLuint CHyprOpenGLImpl::compileShader(const GLuint& type, std::string src, bool
|
||||||
void CHyprOpenGLImpl::begin(CMonitor* pMonitor, CRegion* pDamage, bool fake) {
|
void CHyprOpenGLImpl::begin(CMonitor* pMonitor, CRegion* pDamage, bool fake) {
|
||||||
m_RenderData.pMonitor = pMonitor;
|
m_RenderData.pMonitor = pMonitor;
|
||||||
|
|
||||||
TRACY_GPU_ZONE("RenderBegin");
|
static auto* const PBLUR = &g_pConfigManager->getConfigValuePtr("decoration:blur:enabled")->intValue;
|
||||||
|
|
||||||
if (eglGetCurrentContext() != wlr_egl_get_context(g_pCompositor->m_sWLREGL)) {
|
TRACY_GPU_ZONE("RenderBegin");
|
||||||
eglMakeCurrent(wlr_egl_get_display(g_pCompositor->m_sWLREGL), EGL_NO_SURFACE, EGL_NO_SURFACE, wlr_egl_get_context(g_pCompositor->m_sWLREGL));
|
|
||||||
}
|
|
||||||
|
|
||||||
glViewport(0, 0, pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y);
|
glViewport(0, 0, pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y);
|
||||||
|
|
||||||
|
@ -118,19 +128,16 @@ void CHyprOpenGLImpl::begin(CMonitor* pMonitor, CRegion* pDamage, bool fake) {
|
||||||
|
|
||||||
m_RenderData.pCurrentMonData = &m_mMonitorRenderResources[pMonitor];
|
m_RenderData.pCurrentMonData = &m_mMonitorRenderResources[pMonitor];
|
||||||
|
|
||||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &m_iCurrentOutputFb);
|
|
||||||
m_iWLROutputFb = m_iCurrentOutputFb;
|
|
||||||
|
|
||||||
// ensure a framebuffer for the monitor exists
|
// ensure a framebuffer for the monitor exists
|
||||||
if (!m_mMonitorRenderResources.contains(pMonitor) || m_RenderData.pCurrentMonData->primaryFB.m_vSize != pMonitor->vecPixelSize) {
|
if (!m_mMonitorRenderResources.contains(pMonitor) || m_RenderData.pCurrentMonData->offloadFB.m_vSize != pMonitor->vecPixelSize) {
|
||||||
m_RenderData.pCurrentMonData->stencilTex.allocate();
|
m_RenderData.pCurrentMonData->stencilTex.allocate();
|
||||||
|
|
||||||
m_RenderData.pCurrentMonData->primaryFB.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->mirrorFB.m_pStencilTex = &m_RenderData.pCurrentMonData->stencilTex;
|
||||||
m_RenderData.pCurrentMonData->mirrorSwapFB.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->offMainFB.m_pStencilTex = &m_RenderData.pCurrentMonData->stencilTex;
|
||||||
|
|
||||||
m_RenderData.pCurrentMonData->primaryFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y, pMonitor->drmFormat);
|
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->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->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->offMainFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y, pMonitor->drmFormat);
|
||||||
|
@ -144,19 +151,37 @@ void CHyprOpenGLImpl::begin(CMonitor* pMonitor, CRegion* pDamage, bool fake) {
|
||||||
if (!m_RenderData.pCurrentMonData->m_bShadersInitialized)
|
if (!m_RenderData.pCurrentMonData->m_bShadersInitialized)
|
||||||
initShaders();
|
initShaders();
|
||||||
|
|
||||||
// bind the primary Hypr Framebuffer
|
|
||||||
m_RenderData.pCurrentMonData->primaryFB.bind();
|
|
||||||
|
|
||||||
m_RenderData.damage.set(*pDamage);
|
m_RenderData.damage.set(*pDamage);
|
||||||
|
|
||||||
m_bFakeFrame = fake;
|
m_bFakeFrame = fake;
|
||||||
|
|
||||||
m_RenderData.currentFB = &m_RenderData.pCurrentMonData->primaryFB;
|
|
||||||
|
|
||||||
if (m_bReloadScreenShader) {
|
if (m_bReloadScreenShader) {
|
||||||
m_bReloadScreenShader = false;
|
m_bReloadScreenShader = false;
|
||||||
applyScreenShader(g_pConfigManager->getString("decoration:screen_shader"));
|
applyScreenShader(g_pConfigManager->getString("decoration:screen_shader"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto PRBO = g_pHyprRenderer->getCurrentRBO();
|
||||||
|
|
||||||
|
if (m_sFinalScreenShader.program > 0 || m_bFakeFrame || m_RenderData.mouseZoomFactor != 1.0 || pMonitor->vecPixelSize != PRBO->getFB()->m_vSize ||
|
||||||
|
(*PBLUR != 0 && !pMonitor->solitaryClient /* TODO: revisit when possible */)) {
|
||||||
|
// we have to offload
|
||||||
|
// bind the primary Hypr Framebuffer
|
||||||
|
m_RenderData.pCurrentMonData->offloadFB.bind();
|
||||||
|
m_RenderData.currentFB = &m_RenderData.pCurrentMonData->offloadFB;
|
||||||
|
m_bOffloadedFramebuffer = true;
|
||||||
|
} else {
|
||||||
|
// we can render to the rbo directly
|
||||||
|
const auto PFBO = PRBO->getFB();
|
||||||
|
m_RenderData.currentFB = PFBO;
|
||||||
|
if (PFBO->m_pStencilTex != &m_RenderData.pCurrentMonData->stencilTex) {
|
||||||
|
PFBO->m_pStencilTex = &m_RenderData.pCurrentMonData->stencilTex;
|
||||||
|
PFBO->addStencil();
|
||||||
|
}
|
||||||
|
PRBO->bindFB();
|
||||||
|
m_bOffloadedFramebuffer = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_RenderData.mainFB = m_RenderData.currentFB;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprOpenGLImpl::end() {
|
void CHyprOpenGLImpl::end() {
|
||||||
|
@ -164,14 +189,15 @@ void CHyprOpenGLImpl::end() {
|
||||||
|
|
||||||
TRACY_GPU_ZONE("RenderEnd");
|
TRACY_GPU_ZONE("RenderEnd");
|
||||||
|
|
||||||
|
if (!m_RenderData.pMonitor->mirrors.empty())
|
||||||
|
saveBufferForMirror(); // save with original damage region
|
||||||
|
|
||||||
// end the render, copy the data to the WLR framebuffer
|
// end the render, copy the data to the WLR framebuffer
|
||||||
if (!m_bFakeFrame) {
|
if (m_bOffloadedFramebuffer && !m_bFakeFrame) {
|
||||||
m_RenderData.damage = m_RenderData.pMonitor->lastFrameDamage;
|
m_RenderData.damage = m_RenderData.pMonitor->lastFrameDamage;
|
||||||
|
|
||||||
if (!m_RenderData.pMonitor->mirrors.empty())
|
g_pHyprRenderer->getCurrentRBO()->bindFB();
|
||||||
saveBufferForMirror(); // save with original damage region
|
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, m_iWLROutputFb);
|
|
||||||
CBox monbox = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y};
|
CBox monbox = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y};
|
||||||
|
|
||||||
if (m_RenderData.mouseZoomFactor != 1.f) {
|
if (m_RenderData.mouseZoomFactor != 1.f) {
|
||||||
|
@ -199,9 +225,9 @@ void CHyprOpenGLImpl::end() {
|
||||||
blend(false);
|
blend(false);
|
||||||
|
|
||||||
if (m_sFinalScreenShader.program < 1)
|
if (m_sFinalScreenShader.program < 1)
|
||||||
renderTexturePrimitive(m_RenderData.pCurrentMonData->primaryFB.m_cTex, &monbox);
|
renderTexturePrimitive(m_RenderData.pCurrentMonData->offloadFB.m_cTex, &monbox);
|
||||||
else
|
else
|
||||||
renderTexture(m_RenderData.pCurrentMonData->primaryFB.m_cTex, &monbox, 1.f);
|
renderTexture(m_RenderData.pCurrentMonData->offloadFB.m_cTex, &monbox, 1.f);
|
||||||
|
|
||||||
blend(true);
|
blend(true);
|
||||||
|
|
||||||
|
@ -212,15 +238,10 @@ void CHyprOpenGLImpl::end() {
|
||||||
|
|
||||||
// reset our data
|
// reset our data
|
||||||
m_RenderData.pMonitor = nullptr;
|
m_RenderData.pMonitor = nullptr;
|
||||||
m_iWLROutputFb = 0;
|
|
||||||
m_RenderData.mouseZoomFactor = 1.f;
|
m_RenderData.mouseZoomFactor = 1.f;
|
||||||
m_RenderData.mouseZoomUseMouse = true;
|
m_RenderData.mouseZoomUseMouse = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprOpenGLImpl::bindWlrOutputFb() {
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, m_iWLROutputFb);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CHyprOpenGLImpl::initShaders() {
|
void CHyprOpenGLImpl::initShaders() {
|
||||||
GLuint prog = createProgram(QUADVERTSRC, QUADFRAGSRC);
|
GLuint prog = createProgram(QUADVERTSRC, QUADFRAGSRC);
|
||||||
m_RenderData.pCurrentMonData->m_shQUAD.program = prog;
|
m_RenderData.pCurrentMonData->m_shQUAD.program = prog;
|
||||||
|
@ -501,8 +522,7 @@ void CHyprOpenGLImpl::renderRectWithBlur(CBox* box, const CColor& col, int round
|
||||||
|
|
||||||
CFramebuffer* POUTFB = blurMainFramebufferWithDamage(blurA, &damage);
|
CFramebuffer* POUTFB = blurMainFramebufferWithDamage(blurA, &damage);
|
||||||
|
|
||||||
// bind primary
|
m_RenderData.currentFB->bind();
|
||||||
m_RenderData.pCurrentMonData->primaryFB.bind();
|
|
||||||
|
|
||||||
// make a stencil for rounded corners to work with blur
|
// make a stencil for rounded corners to work with blur
|
||||||
scissor((CBox*)nullptr); // allow the entire window and stencil to render
|
scissor((CBox*)nullptr); // allow the entire window and stencil to render
|
||||||
|
@ -553,7 +573,7 @@ void CHyprOpenGLImpl::renderRectWithDamage(CBox* box, const CColor& col, CRegion
|
||||||
|
|
||||||
float matrix[9];
|
float matrix[9];
|
||||||
wlr_matrix_project_box(matrix, box->pWlr(), wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform), 0,
|
wlr_matrix_project_box(matrix, box->pWlr(), wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform), 0,
|
||||||
m_RenderData.pMonitor->output->transform_matrix); // TODO: write own, don't use WLR here
|
m_RenderData.pMonitor->projMatrix.data()); // TODO: write own, don't use WLR here
|
||||||
|
|
||||||
float glMatrix[9];
|
float glMatrix[9];
|
||||||
wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix);
|
wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix);
|
||||||
|
@ -640,7 +660,7 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, CBox*
|
||||||
// get transform
|
// get transform
|
||||||
const auto TRANSFORM = wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform);
|
const auto TRANSFORM = wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform);
|
||||||
float matrix[9];
|
float matrix[9];
|
||||||
wlr_matrix_project_box(matrix, newBox.pWlr(), TRANSFORM, 0, m_RenderData.pMonitor->output->transform_matrix);
|
wlr_matrix_project_box(matrix, newBox.pWlr(), TRANSFORM, 0, m_RenderData.pMonitor->projMatrix.data());
|
||||||
|
|
||||||
float glMatrix[9];
|
float glMatrix[9];
|
||||||
wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix);
|
wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix);
|
||||||
|
@ -801,7 +821,7 @@ void CHyprOpenGLImpl::renderTexturePrimitive(const CTexture& tex, CBox* pBox) {
|
||||||
// get transform
|
// get transform
|
||||||
const auto TRANSFORM = wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform);
|
const auto TRANSFORM = wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform);
|
||||||
float matrix[9];
|
float matrix[9];
|
||||||
wlr_matrix_project_box(matrix, newBox.pWlr(), TRANSFORM, 0, m_RenderData.pMonitor->output->transform_matrix);
|
wlr_matrix_project_box(matrix, newBox.pWlr(), TRANSFORM, 0, m_RenderData.pMonitor->projMatrix.data());
|
||||||
|
|
||||||
float glMatrix[9];
|
float glMatrix[9];
|
||||||
wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix);
|
wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix);
|
||||||
|
@ -855,7 +875,7 @@ void CHyprOpenGLImpl::renderTextureMatte(const CTexture& tex, CBox* pBox, CFrame
|
||||||
// get transform
|
// get transform
|
||||||
const auto TRANSFORM = wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform);
|
const auto TRANSFORM = wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform);
|
||||||
float matrix[9];
|
float matrix[9];
|
||||||
wlr_matrix_project_box(matrix, newBox.pWlr(), TRANSFORM, 0, m_RenderData.pMonitor->output->transform_matrix);
|
wlr_matrix_project_box(matrix, newBox.pWlr(), TRANSFORM, 0, m_RenderData.pMonitor->projMatrix.data());
|
||||||
|
|
||||||
float glMatrix[9];
|
float glMatrix[9];
|
||||||
wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix);
|
wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix);
|
||||||
|
@ -914,7 +934,7 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o
|
||||||
const auto TRANSFORM = wlr_output_transform_invert(m_RenderData.pMonitor->transform);
|
const auto TRANSFORM = wlr_output_transform_invert(m_RenderData.pMonitor->transform);
|
||||||
float matrix[9];
|
float matrix[9];
|
||||||
CBox MONITORBOX = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y};
|
CBox MONITORBOX = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y};
|
||||||
wlr_matrix_project_box(matrix, MONITORBOX.pWlr(), TRANSFORM, 0, m_RenderData.pMonitor->output->transform_matrix);
|
wlr_matrix_project_box(matrix, MONITORBOX.pWlr(), TRANSFORM, 0, m_RenderData.pMonitor->projMatrix.data());
|
||||||
|
|
||||||
float glMatrix[9];
|
float glMatrix[9];
|
||||||
wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix);
|
wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix);
|
||||||
|
@ -947,9 +967,9 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
glBindTexture(m_RenderData.pCurrentMonData->primaryFB.m_cTex.m_iTarget, m_RenderData.pCurrentMonData->primaryFB.m_cTex.m_iTexID);
|
glBindTexture(m_RenderData.currentFB->m_cTex.m_iTarget, m_RenderData.currentFB->m_cTex.m_iTexID);
|
||||||
|
|
||||||
glTexParameteri(m_RenderData.pCurrentMonData->primaryFB.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);
|
glUseProgram(m_RenderData.pCurrentMonData->m_shBLURPREPARE.program);
|
||||||
|
|
||||||
|
@ -1225,7 +1245,7 @@ void CHyprOpenGLImpl::preBlurForCurrentMonitor() {
|
||||||
renderTextureInternalWithDamage(POUTFB->m_cTex, &wholeMonitor, 1, &fakeDamage, 0, false, true, false);
|
renderTextureInternalWithDamage(POUTFB->m_cTex, &wholeMonitor, 1, &fakeDamage, 0, false, true, false);
|
||||||
m_bEndFrame = false;
|
m_bEndFrame = false;
|
||||||
|
|
||||||
m_RenderData.pCurrentMonData->primaryFB.bind();
|
m_RenderData.currentFB->bind();
|
||||||
|
|
||||||
m_RenderData.pCurrentMonData->blurFBDirty = false;
|
m_RenderData.pCurrentMonData->blurFBDirty = false;
|
||||||
|
|
||||||
|
@ -1321,8 +1341,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, CBox* pBox, flo
|
||||||
POUTFB = &m_RenderData.pCurrentMonData->blurFB;
|
POUTFB = &m_RenderData.pCurrentMonData->blurFB;
|
||||||
}
|
}
|
||||||
|
|
||||||
// bind primary
|
m_RenderData.currentFB->bind();
|
||||||
m_RenderData.pCurrentMonData->primaryFB.bind();
|
|
||||||
|
|
||||||
// make a stencil for rounded corners to work with blur
|
// make a stencil for rounded corners to work with blur
|
||||||
scissor((CBox*)nullptr); // allow the entire window and stencil to render
|
scissor((CBox*)nullptr); // allow the entire window and stencil to render
|
||||||
|
@ -1404,7 +1423,7 @@ void CHyprOpenGLImpl::renderBorder(CBox* box, const CGradientValueData& grad, in
|
||||||
|
|
||||||
float matrix[9];
|
float matrix[9];
|
||||||
wlr_matrix_project_box(matrix, box->pWlr(), wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform), 0,
|
wlr_matrix_project_box(matrix, box->pWlr(), wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform), 0,
|
||||||
m_RenderData.pMonitor->output->transform_matrix); // TODO: write own, don't use WLR here
|
m_RenderData.pMonitor->projMatrix.data()); // TODO: write own, don't use WLR here
|
||||||
|
|
||||||
float glMatrix[9];
|
float glMatrix[9];
|
||||||
wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix);
|
wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix);
|
||||||
|
@ -1744,7 +1763,7 @@ void CHyprOpenGLImpl::renderRoundedShadow(CBox* box, int round, int range, const
|
||||||
|
|
||||||
float matrix[9];
|
float matrix[9];
|
||||||
wlr_matrix_project_box(matrix, box->pWlr(), wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform), 0,
|
wlr_matrix_project_box(matrix, box->pWlr(), wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform), 0,
|
||||||
m_RenderData.pMonitor->output->transform_matrix); // TODO: write own, don't use WLR here
|
m_RenderData.pMonitor->projMatrix.data()); // TODO: write own, don't use WLR here
|
||||||
|
|
||||||
float glMatrix[9];
|
float glMatrix[9];
|
||||||
wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix);
|
wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix);
|
||||||
|
@ -1811,11 +1830,11 @@ void CHyprOpenGLImpl::saveBufferForMirror() {
|
||||||
|
|
||||||
blend(false);
|
blend(false);
|
||||||
|
|
||||||
renderTexture(m_RenderData.pCurrentMonData->primaryFB.m_cTex, &monbox, 1.f, 0, false, false);
|
renderTexture(m_RenderData.currentFB->m_cTex, &monbox, 1.f, 0, false, false);
|
||||||
|
|
||||||
blend(true);
|
blend(true);
|
||||||
|
|
||||||
m_RenderData.pCurrentMonData->primaryFB.bind();
|
m_RenderData.currentFB->bind();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprOpenGLImpl::renderMirrored() {
|
void CHyprOpenGLImpl::renderMirrored() {
|
||||||
|
@ -1974,7 +1993,7 @@ void CHyprOpenGLImpl::destroyMonitorResources(CMonitor* pMonitor) {
|
||||||
wlr_output_attach_render(pMonitor->output, nullptr);
|
wlr_output_attach_render(pMonitor->output, nullptr);
|
||||||
|
|
||||||
g_pHyprOpenGL->m_mMonitorRenderResources[pMonitor].mirrorFB.release();
|
g_pHyprOpenGL->m_mMonitorRenderResources[pMonitor].mirrorFB.release();
|
||||||
g_pHyprOpenGL->m_mMonitorRenderResources[pMonitor].primaryFB.release();
|
g_pHyprOpenGL->m_mMonitorRenderResources[pMonitor].offloadFB.release();
|
||||||
g_pHyprOpenGL->m_mMonitorRenderResources[pMonitor].mirrorSwapFB.release();
|
g_pHyprOpenGL->m_mMonitorRenderResources[pMonitor].mirrorSwapFB.release();
|
||||||
g_pHyprOpenGL->m_mMonitorRenderResources[pMonitor].monitorMirrorFB.release();
|
g_pHyprOpenGL->m_mMonitorRenderResources[pMonitor].monitorMirrorFB.release();
|
||||||
g_pHyprOpenGL->m_mMonitorRenderResources[pMonitor].blurFB.release();
|
g_pHyprOpenGL->m_mMonitorRenderResources[pMonitor].blurFB.release();
|
||||||
|
@ -2014,8 +2033,8 @@ void CHyprOpenGLImpl::renderOffToMain(CFramebuffer* off) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprOpenGLImpl::bindBackOnMain() {
|
void CHyprOpenGLImpl::bindBackOnMain() {
|
||||||
m_RenderData.pCurrentMonData->primaryFB.bind();
|
m_RenderData.mainFB->bind();
|
||||||
m_RenderData.currentFB = &m_RenderData.pCurrentMonData->primaryFB;
|
m_RenderData.currentFB = m_RenderData.mainFB;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprOpenGLImpl::setMonitorTransformEnabled(bool enabled) {
|
void CHyprOpenGLImpl::setMonitorTransformEnabled(bool enabled) {
|
||||||
|
|
|
@ -14,6 +14,9 @@
|
||||||
#include "Texture.hpp"
|
#include "Texture.hpp"
|
||||||
#include "Framebuffer.hpp"
|
#include "Framebuffer.hpp"
|
||||||
#include "Transformer.hpp"
|
#include "Transformer.hpp"
|
||||||
|
#include "Renderbuffer.hpp"
|
||||||
|
|
||||||
|
#include <GLES2/gl2ext.h>
|
||||||
|
|
||||||
#include "../debug/TracyDefines.hpp"
|
#include "../debug/TracyDefines.hpp"
|
||||||
|
|
||||||
|
@ -39,7 +42,7 @@ struct SRenderModifData {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SMonitorRenderData {
|
struct SMonitorRenderData {
|
||||||
CFramebuffer primaryFB;
|
CFramebuffer offloadFB;
|
||||||
CFramebuffer mirrorFB; // these are used for some effects,
|
CFramebuffer mirrorFB; // these are used for some effects,
|
||||||
CFramebuffer mirrorSwapFB; // etc
|
CFramebuffer mirrorSwapFB; // etc
|
||||||
CFramebuffer offMainFB;
|
CFramebuffer offMainFB;
|
||||||
|
@ -80,6 +83,7 @@ struct SCurrentRenderData {
|
||||||
|
|
||||||
SMonitorRenderData* pCurrentMonData = nullptr;
|
SMonitorRenderData* pCurrentMonData = nullptr;
|
||||||
CFramebuffer* currentFB = nullptr;
|
CFramebuffer* currentFB = nullptr;
|
||||||
|
CFramebuffer* mainFB = nullptr;
|
||||||
|
|
||||||
CRegion damage;
|
CRegion damage;
|
||||||
|
|
||||||
|
@ -105,7 +109,6 @@ class CHyprOpenGLImpl {
|
||||||
|
|
||||||
void begin(CMonitor*, CRegion*, bool fake = false);
|
void begin(CMonitor*, CRegion*, bool fake = false);
|
||||||
void end();
|
void end();
|
||||||
void bindWlrOutputFb();
|
|
||||||
|
|
||||||
void renderRect(CBox*, const CColor&, int round = 0);
|
void renderRect(CBox*, const CColor&, int round = 0);
|
||||||
void renderRectWithBlur(CBox*, const CColor&, int round = 0, float blurA = 1.f);
|
void renderRectWithBlur(CBox*, const CColor&, int round = 0, float blurA = 1.f);
|
||||||
|
@ -157,7 +160,6 @@ class CHyprOpenGLImpl {
|
||||||
SCurrentRenderData m_RenderData;
|
SCurrentRenderData m_RenderData;
|
||||||
|
|
||||||
GLint m_iCurrentOutputFb = 0;
|
GLint m_iCurrentOutputFb = 0;
|
||||||
GLint m_iWLROutputFb = 0;
|
|
||||||
|
|
||||||
bool m_bReloadScreenShader = true; // at launch it can be set
|
bool m_bReloadScreenShader = true; // at launch it can be set
|
||||||
|
|
||||||
|
@ -169,6 +171,11 @@ class CHyprOpenGLImpl {
|
||||||
std::unordered_map<CMonitor*, SMonitorRenderData> m_mMonitorRenderResources;
|
std::unordered_map<CMonitor*, SMonitorRenderData> m_mMonitorRenderResources;
|
||||||
std::unordered_map<CMonitor*, CTexture> m_mMonitorBGTextures;
|
std::unordered_map<CMonitor*, CTexture> m_mMonitorBGTextures;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC glEGLImageTargetRenderbufferStorageOES = nullptr;
|
||||||
|
PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR = nullptr;
|
||||||
|
} m_sProc;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::list<GLuint> m_lBuffers;
|
std::list<GLuint> m_lBuffers;
|
||||||
std::list<GLuint> m_lTextures;
|
std::list<GLuint> m_lTextures;
|
||||||
|
@ -176,10 +183,11 @@ class CHyprOpenGLImpl {
|
||||||
int m_iDRMFD;
|
int m_iDRMFD;
|
||||||
std::string m_szExtensions;
|
std::string m_szExtensions;
|
||||||
|
|
||||||
bool m_bFakeFrame = false;
|
bool m_bFakeFrame = false;
|
||||||
bool m_bEndFrame = false;
|
bool m_bEndFrame = false;
|
||||||
bool m_bApplyFinalShader = false;
|
bool m_bApplyFinalShader = false;
|
||||||
bool m_bBlend = false;
|
bool m_bBlend = false;
|
||||||
|
bool m_bOffloadedFramebuffer = false;
|
||||||
|
|
||||||
CShader m_sFinalScreenShader;
|
CShader m_sFinalScreenShader;
|
||||||
CTimer m_tGlobalTimer;
|
CTimer m_tGlobalTimer;
|
||||||
|
|
81
src/render/Renderbuffer.cpp
Normal file
81
src/render/Renderbuffer.cpp
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
#include "Renderbuffer.hpp"
|
||||||
|
#include "OpenGL.hpp"
|
||||||
|
#include "../Compositor.hpp"
|
||||||
|
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
|
CRenderbuffer::~CRenderbuffer() {
|
||||||
|
if (eglGetCurrentContext() != wlr_egl_get_context(g_pCompositor->m_sWLREGL))
|
||||||
|
eglMakeCurrent(wlr_egl_get_display(g_pCompositor->m_sWLREGL), EGL_NO_SURFACE, EGL_NO_SURFACE, wlr_egl_get_context(g_pCompositor->m_sWLREGL));
|
||||||
|
|
||||||
|
m_sFramebuffer.release();
|
||||||
|
glDeleteRenderbuffers(1, &m_iRBO);
|
||||||
|
|
||||||
|
g_pHyprOpenGL->m_sProc.eglDestroyImageKHR(wlr_egl_get_display(g_pCompositor->m_sWLREGL), m_iImage);
|
||||||
|
}
|
||||||
|
|
||||||
|
CRenderbuffer::CRenderbuffer(wlr_buffer* buffer, uint32_t format) : m_pWlrBuffer(buffer) {
|
||||||
|
|
||||||
|
// EVIL, but we can't include a hidden header because nixos is fucking special
|
||||||
|
static EGLImageKHR (*PWLREGLCREATEIMAGEFROMDMABUF)(wlr_egl*, wlr_dmabuf_attributes*, bool*);
|
||||||
|
static bool symbolFound = false;
|
||||||
|
if (!symbolFound) {
|
||||||
|
PWLREGLCREATEIMAGEFROMDMABUF = reinterpret_cast<EGLImageKHR (*)(wlr_egl*, wlr_dmabuf_attributes*, bool*)>(dlsym(RTLD_DEFAULT, "wlr_egl_create_image_from_dmabuf"));
|
||||||
|
|
||||||
|
symbolFound = true;
|
||||||
|
|
||||||
|
RASSERT(PWLREGLCREATEIMAGEFROMDMABUF, "wlr_egl_create_image_from_dmabuf was not found in wlroots!");
|
||||||
|
|
||||||
|
Debug::log(LOG, "CRenderbuffer: wlr_egl_create_image_from_dmabuf found at {:x}", (uintptr_t)PWLREGLCREATEIMAGEFROMDMABUF);
|
||||||
|
}
|
||||||
|
// end evil hack
|
||||||
|
|
||||||
|
struct wlr_dmabuf_attributes dmabuf = {0};
|
||||||
|
if (!wlr_buffer_get_dmabuf(buffer, &dmabuf))
|
||||||
|
throw std::runtime_error("wlr_buffer_get_dmabuf failed");
|
||||||
|
|
||||||
|
bool externalOnly;
|
||||||
|
m_iImage = PWLREGLCREATEIMAGEFROMDMABUF(g_pCompositor->m_sWLREGL, &dmabuf, &externalOnly);
|
||||||
|
if (m_iImage == EGL_NO_IMAGE_KHR)
|
||||||
|
throw std::runtime_error("wlr_egl_create_image_from_dmabuf failed");
|
||||||
|
|
||||||
|
glGenRenderbuffers(1, &m_iRBO);
|
||||||
|
glBindRenderbuffer(GL_RENDERBUFFER, m_iRBO);
|
||||||
|
g_pHyprOpenGL->m_sProc.glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, (GLeglImageOES)m_iImage);
|
||||||
|
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||||
|
|
||||||
|
glGenFramebuffers(1, &m_sFramebuffer.m_iFb);
|
||||||
|
m_sFramebuffer.m_vSize = {buffer->width, buffer->height};
|
||||||
|
m_sFramebuffer.bind();
|
||||||
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_iRBO);
|
||||||
|
|
||||||
|
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||||
|
throw std::runtime_error("rbo: glCheckFramebufferStatus failed");
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
|
||||||
|
hyprListener_destroyBuffer.initCallback(
|
||||||
|
&buffer->events.destroy, [](void* owner, void* data) { g_pHyprRenderer->onRenderbufferDestroy((CRenderbuffer*)owner); }, this, "CRenderbuffer");
|
||||||
|
}
|
||||||
|
|
||||||
|
void CRenderbuffer::bind() {
|
||||||
|
glBindRenderbuffer(GL_RENDERBUFFER, m_iRBO);
|
||||||
|
bindFB();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CRenderbuffer::bindFB() {
|
||||||
|
m_sFramebuffer.bind();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CRenderbuffer::unbind() {
|
||||||
|
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||||
|
#ifndef GLES2
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||||
|
#else
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CFramebuffer* CRenderbuffer::getFB() {
|
||||||
|
return &m_sFramebuffer;
|
||||||
|
}
|
25
src/render/Renderbuffer.hpp
Normal file
25
src/render/Renderbuffer.hpp
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Framebuffer.hpp"
|
||||||
|
|
||||||
|
class CMonitor;
|
||||||
|
|
||||||
|
class CRenderbuffer {
|
||||||
|
public:
|
||||||
|
CRenderbuffer(wlr_buffer* buffer, uint32_t format);
|
||||||
|
~CRenderbuffer();
|
||||||
|
|
||||||
|
void bind();
|
||||||
|
void bindFB();
|
||||||
|
void unbind();
|
||||||
|
CFramebuffer* getFB();
|
||||||
|
|
||||||
|
wlr_buffer* m_pWlrBuffer = nullptr;
|
||||||
|
|
||||||
|
DYNLISTENER(destroyBuffer);
|
||||||
|
|
||||||
|
private:
|
||||||
|
EGLImageKHR m_iImage = 0;
|
||||||
|
GLuint m_iRBO = 0;
|
||||||
|
CFramebuffer m_sFramebuffer;
|
||||||
|
};
|
|
@ -845,8 +845,8 @@ bool CHyprRenderer::attemptDirectScanout(CMonitor* pMonitor) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprRenderer::renderMonitor(CMonitor* pMonitor) {
|
void CHyprRenderer::renderMonitor(CMonitor* pMonitor) {
|
||||||
static std::chrono::high_resolution_clock::time_point startRender = std::chrono::high_resolution_clock::now();
|
static std::chrono::high_resolution_clock::time_point renderStart = std::chrono::high_resolution_clock::now();
|
||||||
static std::chrono::high_resolution_clock::time_point startRenderOverlay = std::chrono::high_resolution_clock::now();
|
static std::chrono::high_resolution_clock::time_point renderStartOverlay = std::chrono::high_resolution_clock::now();
|
||||||
static std::chrono::high_resolution_clock::time_point endRenderOverlay = std::chrono::high_resolution_clock::now();
|
static std::chrono::high_resolution_clock::time_point endRenderOverlay = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
static auto* const PDEBUGOVERLAY = &g_pConfigManager->getConfigValuePtr("debug:overlay")->intValue;
|
static auto* const PDEBUGOVERLAY = &g_pConfigManager->getConfigValuePtr("debug:overlay")->intValue;
|
||||||
|
@ -887,7 +887,7 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) {
|
||||||
firstLaunchAnimActive = false;
|
firstLaunchAnimActive = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
startRender = std::chrono::high_resolution_clock::now();
|
renderStart = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
if (*PDEBUGOVERLAY == 1) {
|
if (*PDEBUGOVERLAY == 1) {
|
||||||
g_pDebugOverlay->frameData(pMonitor);
|
g_pDebugOverlay->frameData(pMonitor);
|
||||||
|
@ -991,7 +991,6 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) {
|
||||||
// check the damage
|
// check the damage
|
||||||
CRegion damage;
|
CRegion damage;
|
||||||
bool hasChanged = pMonitor->output->needs_frame || pixman_region32_not_empty(&pMonitor->damage.current);
|
bool hasChanged = pMonitor->output->needs_frame || pixman_region32_not_empty(&pMonitor->damage.current);
|
||||||
int bufferAge;
|
|
||||||
|
|
||||||
if (!hasChanged && *PDAMAGETRACKINGMODE != DAMAGE_TRACKING_NONE && pMonitor->forceFullFrames == 0 && damageBlinkCleanup == 0)
|
if (!hasChanged && *PDAMAGETRACKINGMODE != DAMAGE_TRACKING_NONE && pMonitor->forceFullFrames == 0 && damageBlinkCleanup == 0)
|
||||||
return;
|
return;
|
||||||
|
@ -1007,16 +1006,7 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) {
|
||||||
if (UNLOCK_SC)
|
if (UNLOCK_SC)
|
||||||
wlr_output_lock_software_cursors(pMonitor->output, true);
|
wlr_output_lock_software_cursors(pMonitor->output, true);
|
||||||
|
|
||||||
if (!wlr_output_attach_render(pMonitor->output, &bufferAge)) {
|
wlr_damage_ring_get_buffer_damage(&pMonitor->damage, m_iLastBufferAge, damage.pixman());
|
||||||
Debug::log(ERR, "Couldn't attach render to display {} ???", pMonitor->szName);
|
|
||||||
|
|
||||||
if (UNLOCK_SC)
|
|
||||||
wlr_output_lock_software_cursors(pMonitor->output, false);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
wlr_damage_ring_get_buffer_damage(&pMonitor->damage, bufferAge, damage.pixman());
|
|
||||||
|
|
||||||
pMonitor->renderingActive = true;
|
pMonitor->renderingActive = true;
|
||||||
|
|
||||||
|
@ -1062,7 +1052,25 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) {
|
||||||
|
|
||||||
TRACY_GPU_ZONE("Render");
|
TRACY_GPU_ZONE("Render");
|
||||||
|
|
||||||
g_pHyprOpenGL->begin(pMonitor, &damage);
|
if (pMonitor == g_pCompositor->getMonitorFromCursor())
|
||||||
|
g_pHyprOpenGL->m_RenderData.mouseZoomFactor = std::clamp(*PZOOMFACTOR, 1.f, INFINITY);
|
||||||
|
else
|
||||||
|
g_pHyprOpenGL->m_RenderData.mouseZoomFactor = 1.f;
|
||||||
|
|
||||||
|
if (zoomInFactorFirstLaunch > 1.f) {
|
||||||
|
g_pHyprOpenGL->m_RenderData.mouseZoomFactor = zoomInFactorFirstLaunch;
|
||||||
|
g_pHyprOpenGL->m_RenderData.mouseZoomUseMouse = false;
|
||||||
|
g_pHyprOpenGL->m_RenderData.useNearestNeighbor = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!beginRender(pMonitor, damage, RENDER_MODE_NORMAL)) {
|
||||||
|
Debug::log(ERR, "renderer: couldn't beginRender()!");
|
||||||
|
|
||||||
|
if (UNLOCK_SC)
|
||||||
|
wlr_output_lock_software_cursors(pMonitor->output, false);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
EMIT_HOOK_EVENT("render", RENDER_BEGIN);
|
EMIT_HOOK_EVENT("render", RENDER_BEGIN);
|
||||||
|
|
||||||
|
@ -1097,7 +1105,7 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) {
|
||||||
|
|
||||||
// for drawing the debug overlay
|
// for drawing the debug overlay
|
||||||
if (pMonitor == g_pCompositor->m_vMonitors.front().get() && *PDEBUGOVERLAY == 1) {
|
if (pMonitor == g_pCompositor->m_vMonitors.front().get() && *PDEBUGOVERLAY == 1) {
|
||||||
startRenderOverlay = std::chrono::high_resolution_clock::now();
|
renderStartOverlay = std::chrono::high_resolution_clock::now();
|
||||||
g_pDebugOverlay->draw();
|
g_pDebugOverlay->draw();
|
||||||
endRenderOverlay = std::chrono::high_resolution_clock::now();
|
endRenderOverlay = std::chrono::high_resolution_clock::now();
|
||||||
}
|
}
|
||||||
|
@ -1118,35 +1126,22 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) {
|
||||||
|
|
||||||
renderCursor = renderCursor && shouldRenderCursor();
|
renderCursor = renderCursor && shouldRenderCursor();
|
||||||
|
|
||||||
if (renderCursor && wlr_renderer_begin(g_pCompositor->m_sWLRRenderer, pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y)) {
|
if (renderCursor) {
|
||||||
TRACY_GPU_ZONE("RenderCursor");
|
TRACY_GPU_ZONE("RenderCursor");
|
||||||
|
|
||||||
bool lockSoftware = pMonitor == g_pCompositor->getMonitorFromCursor() && *PZOOMFACTOR != 1.f;
|
bool lockSoftware = pMonitor == g_pCompositor->getMonitorFromCursor() && *PZOOMFACTOR != 1.f;
|
||||||
|
|
||||||
if (lockSoftware) {
|
if (lockSoftware) {
|
||||||
wlr_output_lock_software_cursors(pMonitor->output, true);
|
wlr_output_lock_software_cursors(pMonitor->output, true);
|
||||||
wlr_output_render_software_cursors(pMonitor->output, NULL);
|
g_pHyprRenderer->renderSoftwareCursors(pMonitor, g_pHyprOpenGL->m_RenderData.damage);
|
||||||
wlr_output_lock_software_cursors(pMonitor->output, false);
|
wlr_output_lock_software_cursors(pMonitor->output, false);
|
||||||
} else
|
} else
|
||||||
wlr_output_render_software_cursors(pMonitor->output, NULL);
|
g_pHyprRenderer->renderSoftwareCursors(pMonitor, g_pHyprOpenGL->m_RenderData.damage);
|
||||||
|
|
||||||
wlr_renderer_end(g_pCompositor->m_sWLRRenderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pMonitor == g_pCompositor->getMonitorFromCursor())
|
|
||||||
g_pHyprOpenGL->m_RenderData.mouseZoomFactor = std::clamp(*PZOOMFACTOR, 1.f, INFINITY);
|
|
||||||
else
|
|
||||||
g_pHyprOpenGL->m_RenderData.mouseZoomFactor = 1.f;
|
|
||||||
|
|
||||||
if (zoomInFactorFirstLaunch > 1.f) {
|
|
||||||
g_pHyprOpenGL->m_RenderData.mouseZoomFactor = zoomInFactorFirstLaunch;
|
|
||||||
g_pHyprOpenGL->m_RenderData.mouseZoomUseMouse = false;
|
|
||||||
g_pHyprOpenGL->m_RenderData.useNearestNeighbor = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EMIT_HOOK_EVENT("render", RENDER_LAST_MOMENT);
|
EMIT_HOOK_EVENT("render", RENDER_LAST_MOMENT);
|
||||||
|
|
||||||
g_pHyprOpenGL->end();
|
endRender();
|
||||||
|
|
||||||
TRACY_GPU_COLLECT;
|
TRACY_GPU_COLLECT;
|
||||||
|
|
||||||
|
@ -1192,12 +1187,12 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) {
|
||||||
|
|
||||||
pMonitor->pendingFrame = false;
|
pMonitor->pendingFrame = false;
|
||||||
|
|
||||||
const float µs = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now() - startRender).count() / 1000.f;
|
const float µs = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now() - renderStart).count() / 1000.f;
|
||||||
g_pDebugOverlay->renderData(pMonitor, µs);
|
g_pDebugOverlay->renderData(pMonitor, µs);
|
||||||
|
|
||||||
if (*PDEBUGOVERLAY == 1) {
|
if (*PDEBUGOVERLAY == 1) {
|
||||||
if (pMonitor == g_pCompositor->m_vMonitors.front().get()) {
|
if (pMonitor == g_pCompositor->m_vMonitors.front().get()) {
|
||||||
const float µsNoOverlay = µs - std::chrono::duration_cast<std::chrono::nanoseconds>(endRenderOverlay - startRenderOverlay).count() / 1000.f;
|
const float µsNoOverlay = µs - std::chrono::duration_cast<std::chrono::nanoseconds>(endRenderOverlay - renderStartOverlay).count() / 1000.f;
|
||||||
g_pDebugOverlay->renderDataNoOverlay(pMonitor, µsNoOverlay);
|
g_pDebugOverlay->renderDataNoOverlay(pMonitor, µsNoOverlay);
|
||||||
} else {
|
} else {
|
||||||
g_pDebugOverlay->renderDataNoOverlay(pMonitor, µs);
|
g_pDebugOverlay->renderDataNoOverlay(pMonitor, µs);
|
||||||
|
@ -1957,6 +1952,8 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
|
||||||
pMonitor->vecPixelSize = Vector2D(transformedBox.width, transformedBox.height);
|
pMonitor->vecPixelSize = Vector2D(transformedBox.width, transformedBox.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pMonitor->updateMatrix();
|
||||||
|
|
||||||
// update renderer (here because it will call rollback, so we cannot do this before committing)
|
// update renderer (here because it will call rollback, so we cannot do this before committing)
|
||||||
g_pHyprOpenGL->destroyMonitorResources(pMonitor);
|
g_pHyprOpenGL->destroyMonitorResources(pMonitor);
|
||||||
|
|
||||||
|
@ -2191,3 +2188,99 @@ void CHyprRenderer::recheckSolitaryForMonitor(CMonitor* pMonitor) {
|
||||||
// found one!
|
// found one!
|
||||||
pMonitor->solitaryClient = PCANDIDATE;
|
pMonitor->solitaryClient = PCANDIDATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CHyprRenderer::renderSoftwareCursors(CMonitor* pMonitor, const CRegion& damage, std::optional<Vector2D> overridePos) {
|
||||||
|
const auto CURSORPOS = overridePos.value_or(g_pInputManager->getMouseCoordsInternal() - pMonitor->vecPosition);
|
||||||
|
wlr_output_cursor* cursor;
|
||||||
|
wl_list_for_each(cursor, &pMonitor->output->cursors, link) {
|
||||||
|
if (!cursor->enabled || !cursor->visible || pMonitor->output->hardware_cursor == cursor)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!cursor->texture)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
CBox cursorBox = CBox{CURSORPOS.x, CURSORPOS.y, cursor->width, cursor->height}.translate({-cursor->hotspot_x, -cursor->hotspot_y});
|
||||||
|
|
||||||
|
g_pHyprOpenGL->renderTexturePrimitive(cursor->texture, &cursorBox);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CRenderbuffer* CHyprRenderer::getOrCreateRenderbuffer(wlr_buffer* buffer, uint32_t fmt) {
|
||||||
|
auto it = std::find_if(m_vRenderbuffers.begin(), m_vRenderbuffers.end(), [&](const auto& other) { return other->m_pWlrBuffer == buffer; });
|
||||||
|
|
||||||
|
if (it != m_vRenderbuffers.end())
|
||||||
|
return it->get();
|
||||||
|
|
||||||
|
return m_vRenderbuffers.emplace_back(std::make_unique<CRenderbuffer>(buffer, fmt)).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CHyprRenderer::beginRender(CMonitor* pMonitor, CRegion& damage, eRenderMode mode, wlr_buffer* withBuffer) {
|
||||||
|
|
||||||
|
if (eglGetCurrentContext() != wlr_egl_get_context(g_pCompositor->m_sWLREGL))
|
||||||
|
eglMakeCurrent(wlr_egl_get_display(g_pCompositor->m_sWLREGL), EGL_NO_SURFACE, EGL_NO_SURFACE, wlr_egl_get_context(g_pCompositor->m_sWLREGL));
|
||||||
|
|
||||||
|
m_eRenderMode = mode;
|
||||||
|
|
||||||
|
g_pHyprOpenGL->m_RenderData.pMonitor = pMonitor; // has to be set cuz allocs
|
||||||
|
|
||||||
|
if (mode == RENDER_MODE_FULL_FAKE) {
|
||||||
|
wlr_output_attach_render(pMonitor->output, nullptr);
|
||||||
|
g_pHyprOpenGL->begin(pMonitor, &damage, true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!withBuffer) {
|
||||||
|
if (!wlr_output_configure_primary_swapchain(pMonitor->output, &pMonitor->output->pending, &pMonitor->output->swapchain))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_pCurrentWlrBuffer = wlr_swapchain_acquire(pMonitor->output->swapchain, &m_iLastBufferAge);
|
||||||
|
if (!m_pCurrentWlrBuffer)
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
m_pCurrentWlrBuffer = withBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
m_pCurrentRenderbuffer = getOrCreateRenderbuffer(m_pCurrentWlrBuffer, pMonitor->drmFormat);
|
||||||
|
} catch (std::exception& e) {
|
||||||
|
wlr_buffer_unlock(m_pCurrentWlrBuffer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pCurrentRenderbuffer->bind();
|
||||||
|
g_pHyprOpenGL->begin(pMonitor, &damage);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CHyprRenderer::endRender() {
|
||||||
|
const auto PMONITOR = g_pHyprOpenGL->m_RenderData.pMonitor;
|
||||||
|
|
||||||
|
g_pHyprOpenGL->end();
|
||||||
|
|
||||||
|
if (m_eRenderMode == RENDER_MODE_FULL_FAKE) {
|
||||||
|
wlr_output_rollback(PMONITOR->output);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
glFlush();
|
||||||
|
|
||||||
|
if (m_eRenderMode == RENDER_MODE_NORMAL)
|
||||||
|
wlr_output_state_set_buffer(&PMONITOR->output->pending, m_pCurrentWlrBuffer);
|
||||||
|
|
||||||
|
wlr_buffer_unlock(m_pCurrentWlrBuffer);
|
||||||
|
|
||||||
|
m_pCurrentRenderbuffer->unbind();
|
||||||
|
|
||||||
|
m_pCurrentRenderbuffer = nullptr;
|
||||||
|
m_pCurrentWlrBuffer = nullptr;
|
||||||
|
m_iLastBufferAge = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CHyprRenderer::onRenderbufferDestroy(CRenderbuffer* rb) {
|
||||||
|
std::erase_if(m_vRenderbuffers, [&](const auto& rbo) { return rbo.get() == rb; });
|
||||||
|
}
|
||||||
|
|
||||||
|
CRenderbuffer* CHyprRenderer::getCurrentRBO() {
|
||||||
|
return m_pCurrentRenderbuffer;
|
||||||
|
}
|
|
@ -6,6 +6,7 @@
|
||||||
#include "../helpers/Workspace.hpp"
|
#include "../helpers/Workspace.hpp"
|
||||||
#include "../Window.hpp"
|
#include "../Window.hpp"
|
||||||
#include "OpenGL.hpp"
|
#include "OpenGL.hpp"
|
||||||
|
#include "Renderbuffer.hpp"
|
||||||
#include "../helpers/Timer.hpp"
|
#include "../helpers/Timer.hpp"
|
||||||
#include "../helpers/Region.hpp"
|
#include "../helpers/Region.hpp"
|
||||||
|
|
||||||
|
@ -27,6 +28,13 @@ enum eRenderPassMode
|
||||||
RENDER_PASS_POPUP
|
RENDER_PASS_POPUP
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum eRenderMode
|
||||||
|
{
|
||||||
|
RENDER_MODE_NORMAL = 0,
|
||||||
|
RENDER_MODE_FULL_FAKE = 1,
|
||||||
|
RENDER_MODE_TO_BUFFER = 2
|
||||||
|
};
|
||||||
|
|
||||||
class CToplevelExportProtocolManager;
|
class CToplevelExportProtocolManager;
|
||||||
class CInputManager;
|
class CInputManager;
|
||||||
struct SSessionLockSurface;
|
struct SSessionLockSurface;
|
||||||
|
@ -58,6 +66,12 @@ class CHyprRenderer {
|
||||||
void recheckSolitaryForMonitor(CMonitor* pMonitor);
|
void recheckSolitaryForMonitor(CMonitor* pMonitor);
|
||||||
void setCursorSurface(wlr_surface* surf, int hotspotX, int hotspotY);
|
void setCursorSurface(wlr_surface* surf, int hotspotX, int hotspotY);
|
||||||
void setCursorFromName(const std::string& name);
|
void setCursorFromName(const std::string& name);
|
||||||
|
void renderSoftwareCursors(CMonitor* pMonitor, const CRegion& damage, std::optional<Vector2D> overridePos = {});
|
||||||
|
void onRenderbufferDestroy(CRenderbuffer* rb);
|
||||||
|
CRenderbuffer* getCurrentRBO();
|
||||||
|
|
||||||
|
bool beginRender(CMonitor* pMonitor, CRegion& damage, eRenderMode mode = RENDER_MODE_NORMAL, wlr_buffer* withBuffer = nullptr);
|
||||||
|
void endRender();
|
||||||
|
|
||||||
bool m_bWindowRequestedCursorHide = false;
|
bool m_bWindowRequestedCursorHide = false;
|
||||||
bool m_bBlockSurfaceFeedback = false;
|
bool m_bBlockSurfaceFeedback = false;
|
||||||
|
@ -89,19 +103,26 @@ class CHyprRenderer {
|
||||||
} m_sLastCursorData;
|
} m_sLastCursorData;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void arrangeLayerArray(CMonitor*, const std::vector<std::unique_ptr<SLayerSurface>>&, bool, CBox*);
|
void arrangeLayerArray(CMonitor*, const std::vector<std::unique_ptr<SLayerSurface>>&, bool, CBox*);
|
||||||
void renderWorkspaceWindowsFullscreen(CMonitor*, CWorkspace*, timespec*); // renders workspace windows (fullscreen) (tiled, floating, pinned, but no special)
|
void renderWorkspaceWindowsFullscreen(CMonitor*, CWorkspace*, timespec*); // renders workspace windows (fullscreen) (tiled, floating, pinned, but no special)
|
||||||
void renderWorkspaceWindows(CMonitor*, CWorkspace*, timespec*); // renders workspace windows (no fullscreen) (tiled, floating, pinned, but no special)
|
void renderWorkspaceWindows(CMonitor*, CWorkspace*, timespec*); // renders workspace windows (no fullscreen) (tiled, floating, pinned, but no special)
|
||||||
void renderWindow(CWindow*, CMonitor*, timespec*, bool, eRenderPassMode, bool ignorePosition = false, bool ignoreAllGeometry = false);
|
void renderWindow(CWindow*, CMonitor*, timespec*, bool, eRenderPassMode, bool ignorePosition = false, bool ignoreAllGeometry = false);
|
||||||
void renderLayer(SLayerSurface*, CMonitor*, timespec*);
|
void renderLayer(SLayerSurface*, CMonitor*, timespec*);
|
||||||
void renderSessionLockSurface(SSessionLockSurface*, CMonitor*, timespec*);
|
void renderSessionLockSurface(SSessionLockSurface*, CMonitor*, timespec*);
|
||||||
void renderDragIcon(CMonitor*, timespec*);
|
void renderDragIcon(CMonitor*, timespec*);
|
||||||
void renderIMEPopup(SIMEPopup*, CMonitor*, timespec*);
|
void renderIMEPopup(SIMEPopup*, CMonitor*, timespec*);
|
||||||
void renderWorkspace(CMonitor* pMonitor, CWorkspace* pWorkspace, timespec* now, const CBox& geometry);
|
void renderWorkspace(CMonitor* pMonitor, CWorkspace* pWorkspace, timespec* now, const CBox& geometry);
|
||||||
void renderAllClientsForWorkspace(CMonitor* pMonitor, CWorkspace* pWorkspace, timespec* now, const Vector2D& translate = {0, 0}, const float& scale = 1.f);
|
void renderAllClientsForWorkspace(CMonitor* pMonitor, CWorkspace* pWorkspace, timespec* now, const Vector2D& translate = {0, 0}, const float& scale = 1.f);
|
||||||
|
|
||||||
bool m_bHasARenderedCursor = true;
|
bool m_bHasARenderedCursor = true;
|
||||||
bool m_bCursorHasSurface = false;
|
bool m_bCursorHasSurface = false;
|
||||||
|
CRenderbuffer* m_pCurrentRenderbuffer = nullptr;
|
||||||
|
wlr_buffer* m_pCurrentWlrBuffer = nullptr;
|
||||||
|
eRenderMode m_eRenderMode = RENDER_MODE_NORMAL;
|
||||||
|
int m_iLastBufferAge = 0;
|
||||||
|
|
||||||
|
CRenderbuffer* getOrCreateRenderbuffer(wlr_buffer* buffer, uint32_t fmt);
|
||||||
|
std::vector<std::unique_ptr<CRenderbuffer>> m_vRenderbuffers;
|
||||||
|
|
||||||
friend class CHyprOpenGLImpl;
|
friend class CHyprOpenGLImpl;
|
||||||
friend class CToplevelExportProtocolManager;
|
friend class CToplevelExportProtocolManager;
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 5de9e1a99d6642c2d09d589aa37ff0a8945dcee1
|
Subproject commit f1762f428b0ef2989c81f57ea9e810403d34d946
|
|
@ -1,7 +1,7 @@
|
||||||
[wrap-git]
|
[wrap-git]
|
||||||
directory = wlroots
|
directory = wlroots
|
||||||
url = https://gitlab.freedesktop.org/wlroots/wlroots.git
|
url = https://gitlab.freedesktop.org/wlroots/wlroots.git
|
||||||
revision = 5de9e1a99d6642c2d09d589aa37ff0a8945dcee1
|
revision = f1762f428b0ef2989c81f57ea9e810403d34d946
|
||||||
depth = 1
|
depth = 1
|
||||||
|
|
||||||
diff_files = wlroots-meson-build.patch
|
diff_files = wlroots-meson-build.patch
|
||||||
|
|
Loading…
Reference in a new issue