mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-05-19 08:30:22 -07:00
Compare commits
29 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
eb3b38d40b | ||
|
d9c8a37811 | ||
|
158c0f2911 | ||
|
44cb8f769e | ||
|
705b97c4ac | ||
|
c19f383685 | ||
|
bb5cd5b2dd | ||
|
bb9aa79b21 | ||
|
dfa4836216 | ||
|
18377d221d | ||
|
2aa21625bd | ||
|
2946009006 | ||
|
b0cc49218d | ||
|
a5c9b3e490 | ||
|
dfb841c303 | ||
|
5ceb0ec15d | ||
|
f707d86912 | ||
|
75f2cb5f65 | ||
|
a51e639d81 | ||
|
59b2340680 | ||
|
da3583fd5e | ||
|
04124988e8 | ||
|
390a357859 | ||
|
9a87498bb1 | ||
|
f58bb72d3a | ||
|
60cd5b7a48 | ||
|
25cf06f6cf | ||
|
e44aae0c20 | ||
|
fcb6f936ea |
@ -99,18 +99,14 @@ message(STATUS "Checking deps...")
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
if(LEGACY_RENDERER)
|
||||
set(GLES_VERSION "GLES2")
|
||||
else()
|
||||
set(GLES_VERSION "GLES3")
|
||||
endif()
|
||||
set(GLES_VERSION "GLES3")
|
||||
find_package(OpenGL REQUIRED COMPONENTS ${GLES_VERSION})
|
||||
|
||||
pkg_check_modules(aquamarine_dep REQUIRED IMPORTED_TARGET aquamarine>=0.8.0)
|
||||
pkg_check_modules(hyprlang_dep REQUIRED IMPORTED_TARGET hyprlang>=0.3.2)
|
||||
pkg_check_modules(hyprcursor_dep REQUIRED IMPORTED_TARGET hyprcursor>=0.1.7)
|
||||
pkg_check_modules(hyprutils_dep REQUIRED IMPORTED_TARGET hyprutils>=0.7.0)
|
||||
pkg_check_modules(hyprgraphics_dep REQUIRED IMPORTED_TARGET hyprgraphics>=0.1.1)
|
||||
pkg_check_modules(hyprgraphics_dep REQUIRED IMPORTED_TARGET hyprgraphics>=0.1.3)
|
||||
|
||||
string(REPLACE "." ";" AQ_VERSION_LIST ${aquamarine_dep_VERSION})
|
||||
list(GET AQ_VERSION_LIST 0 AQ_VERSION_MAJOR)
|
||||
@ -216,11 +212,6 @@ if(NOT HAS_INOTIFY AND inotify_FOUND)
|
||||
target_link_libraries(Hyprland PkgConfig::inotify)
|
||||
endif()
|
||||
|
||||
if(LEGACY_RENDERER)
|
||||
message(STATUS "Using the legacy GLES2 renderer!")
|
||||
add_compile_definitions(LEGACY_RENDERER)
|
||||
endif()
|
||||
|
||||
if(NO_XWAYLAND)
|
||||
message(STATUS "Using the NO_XWAYLAND flag, disabling XWayland!")
|
||||
add_compile_definitions(NO_XWAYLAND)
|
||||
|
8
Makefile
8
Makefile
@ -3,14 +3,6 @@ PREFIX = /usr/local
|
||||
stub:
|
||||
@echo "Do not run $(MAKE) directly without any arguments. Please refer to the wiki on how to compile Hyprland."
|
||||
|
||||
legacyrenderer:
|
||||
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -DLEGACY_RENDERER:BOOL=true -S . -B ./build
|
||||
cmake --build ./build --config Release --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
|
||||
|
||||
legacyrendererdebug:
|
||||
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -DLEGACY_RENDERER:BOOL=true -S . -B ./build
|
||||
cmake --build ./build --config Debug --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
|
||||
|
||||
release:
|
||||
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -S . -B ./build
|
||||
cmake --build ./build --config Release --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
|
||||
|
12
flake.lock
generated
12
flake.lock
generated
@ -276,11 +276,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1746461020,
|
||||
"narHash": "sha256-7+pG1I9jvxNlmln4YgnlW4o+w0TZX24k688mibiFDUE=",
|
||||
"lastModified": 1747327360,
|
||||
"narHash": "sha256-LSmTbiq/nqZR9B2t4MRnWG7cb0KVNU70dB7RT4+wYK4=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "3730d8a308f94996a9ba7c7138ede69c1b9ac4ae",
|
||||
"rev": "e06158e58f3adee28b139e9c2bcfcc41f8625b46",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -299,11 +299,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1746537231,
|
||||
"narHash": "sha256-Wb2xeSyOsCoTCTj7LOoD6cdKLEROyFAArnYoS+noCWo=",
|
||||
"lastModified": 1747372754,
|
||||
"narHash": "sha256-2Y53NGIX2vxfie1rOW0Qb86vjRZ7ngizoo+bnXU9D9k=",
|
||||
"owner": "cachix",
|
||||
"repo": "git-hooks.nix",
|
||||
"rev": "fa466640195d38ec97cf0493d6d6882bc4d14969",
|
||||
"rev": "80479b6ec16fefd9c1db3ea13aeb038c60530f46",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -132,7 +132,6 @@
|
||||
# hyprland-packages
|
||||
hyprland
|
||||
hyprland-debug
|
||||
hyprland-legacy-renderer
|
||||
hyprland-unwrapped
|
||||
# hyprland-extras
|
||||
xdg-desktop-portal-hyprland
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <print>
|
||||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
|
||||
static int getUID() {
|
||||
const auto UID = getuid();
|
||||
|
@ -566,7 +566,7 @@ bool CPluginManager::updateHeaders(bool force) {
|
||||
|
||||
ret = execAndGet(cmd);
|
||||
|
||||
cmd = std::format("make -C '{}' installheaders && chmod -R 644 '{}' && find '{}' -type d -exec chmod o+x {{}} \\;", WORKINGDIR, DataState::getHeadersPath(),
|
||||
cmd = std::format("make -C '{}' installheaders && chmod -R 644 '{}' && find '{}' -type d -exec chmod a+x {{}} \\;", WORKINGDIR, DataState::getHeadersPath(),
|
||||
DataState::getHeadersPath());
|
||||
|
||||
if (m_bVerbose)
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include <pwd.h>
|
||||
#include <unistd.h>
|
||||
#include <sstream>
|
||||
#include <print>
|
||||
#include <filesystem>
|
||||
#include <algorithm>
|
||||
@ -152,7 +153,7 @@ bool NSys::root::install(const std::string& what, const std::string& where, cons
|
||||
if (!std::ranges::all_of(mode, [](const char& c) { return c >= '0' && c <= '9'; }))
|
||||
return false;
|
||||
|
||||
CProcess proc(subin(), {"install", "-m" + mode, "-o", "root", "-g", "root", what, where});
|
||||
CProcess proc(subin(), {"install", "-m" + mode, "-o", "0", "-g", "0", what, where});
|
||||
|
||||
return proc.runSync() && proc.exitCode() == 0;
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ int main(int argc, char** argv, char** envp) {
|
||||
|
||||
return g_pPluginManager->addNewPluginRepo(command[1], rev) ? 0 : 1;
|
||||
} else if (command[0] == "remove") {
|
||||
if (ARGS.size() < 2) {
|
||||
if (command.size() < 2) {
|
||||
std::println(stderr, "{}", failureString("Not enough args for remove."));
|
||||
return 1;
|
||||
}
|
||||
@ -142,7 +142,7 @@ int main(int argc, char** argv, char** envp) {
|
||||
} else if (notify)
|
||||
g_pPluginManager->notify(ICON_ERROR, 0, 10000, "[hyprpm] Couldn't update headers");
|
||||
} else if (command[0] == "enable") {
|
||||
if (ARGS.size() < 2) {
|
||||
if (command.size() < 2) {
|
||||
std::println(stderr, "{}", failureString("Not enough args for enable."));
|
||||
return 1;
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ endif
|
||||
|
||||
aquamarine = dependency('aquamarine', version: '>=0.8.0')
|
||||
hyprcursor = dependency('hyprcursor', version: '>=0.1.7')
|
||||
hyprgraphics = dependency('hyprgraphics', version: '>= 0.1.1')
|
||||
hyprgraphics = dependency('hyprgraphics', version: '>= 0.1.3')
|
||||
hyprlang = dependency('hyprlang', version: '>= 0.3.2')
|
||||
hyprutils = dependency('hyprutils', version: '>= 0.7.0')
|
||||
aquamarine_version_list = aquamarine.version().split('.')
|
||||
@ -77,10 +77,6 @@ if (systemd_option.enabled())
|
||||
subdir('systemd')
|
||||
endif
|
||||
|
||||
if get_option('legacy_renderer').enabled()
|
||||
add_project_arguments('-DLEGACY_RENDERER', language: 'cpp')
|
||||
endif
|
||||
|
||||
if get_option('buildtype') == 'debug'
|
||||
add_project_arguments('-DHYPRLAND_DEBUG', language: 'cpp')
|
||||
endif
|
||||
|
@ -1,6 +1,5 @@
|
||||
option('xwayland', type: 'feature', value: 'auto', description: 'Enable support for X11 applications')
|
||||
option('systemd', type: 'feature', value: 'auto', description: 'Enable systemd integration')
|
||||
option('uwsm', type: 'feature', value: 'enabled', description: 'Enable uwsm integration (only if systemd is enabled)')
|
||||
option('legacy_renderer', type: 'feature', value: 'disabled', description: 'Enable legacy renderer')
|
||||
option('hyprpm', type: 'feature', value: 'enabled', description: 'Enable hyprpm')
|
||||
option('tracy_enable', type: 'boolean', value: false , description: 'Enable profiling')
|
||||
|
@ -41,7 +41,6 @@
|
||||
xwayland,
|
||||
debug ? false,
|
||||
enableXWayland ? true,
|
||||
legacyRenderer ? false,
|
||||
withSystemd ? lib.meta.availableOn stdenv.hostPlatform systemd,
|
||||
wrapRuntimeDeps ? true,
|
||||
version ? "git",
|
||||
@ -52,6 +51,7 @@
|
||||
enableNvidiaPatches ? false,
|
||||
nvidiaPatches ? false,
|
||||
hidpiXWayland ? false,
|
||||
legacyRenderer ? false,
|
||||
}: let
|
||||
inherit (builtins) baseNameOf foldl' readFile;
|
||||
inherit (lib.asserts) assertMsg;
|
||||
@ -70,6 +70,7 @@ in
|
||||
assert assertMsg (!nvidiaPatches) "The option `nvidiaPatches` has been removed.";
|
||||
assert assertMsg (!enableNvidiaPatches) "The option `enableNvidiaPatches` has been removed.";
|
||||
assert assertMsg (!hidpiXWayland) "The option `hidpiXWayland` has been removed. Please refer https://wiki.hyprland.org/Configuring/XWayland";
|
||||
assert assertMsg (!legacyRenderer) "The option `legacyRenderer` has been removed. Legacy renderer is no longer supported.";
|
||||
customStdenv.mkDerivation (finalAttrs: {
|
||||
pname = "hyprland${optionalString debug "-debug"}";
|
||||
inherit version;
|
||||
@ -142,7 +143,7 @@ in
|
||||
wayland-scanner
|
||||
xorg.libXcursor
|
||||
]
|
||||
(optionals customStdenv.hostPlatform.isBSD [ epoll-shim ])
|
||||
(optionals customStdenv.hostPlatform.isBSD [epoll-shim])
|
||||
(optionals customStdenv.hostPlatform.isMusl [libexecinfo])
|
||||
(optionals enableXWayland [
|
||||
xorg.libxcb
|
||||
@ -165,7 +166,6 @@ in
|
||||
mesonFlags = flatten [
|
||||
(mapAttrsToList mesonEnable {
|
||||
"xwayland" = enableXWayland;
|
||||
"legacy_renderer" = legacyRenderer;
|
||||
"systemd" = withSystemd;
|
||||
"uwsm" = false;
|
||||
"hyprpm" = false;
|
||||
|
@ -50,9 +50,15 @@ in {
|
||||
hyprutils = final.hyprutils.override {debug = true;};
|
||||
debug = true;
|
||||
};
|
||||
hyprland-legacy-renderer = final.hyprland.override {legacyRenderer = true;};
|
||||
|
||||
# deprecated packages
|
||||
hyprland-legacy-renderer =
|
||||
builtins.trace ''
|
||||
hyprland-legacy-renderer was removed. Please use the hyprland package.
|
||||
Legacy renderer is no longer supported.
|
||||
''
|
||||
final.hyprland;
|
||||
|
||||
hyprland-nvidia =
|
||||
builtins.trace ''
|
||||
hyprland-nvidia was removed. Please use the hyprland package.
|
||||
|
@ -870,10 +870,14 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper
|
||||
static auto PBORDERGRABEXTEND = CConfigValue<Hyprlang::INT>("general:extend_border_grab_area");
|
||||
static auto PSPECIALFALLTHRU = CConfigValue<Hyprlang::INT>("input:special_fallthrough");
|
||||
const auto BORDER_GRAB_AREA = *PRESIZEONBORDER ? *PBORDERSIZE + *PBORDERGRABEXTEND : 0;
|
||||
const bool ONLY_PRIORITY = properties & FOCUS_PRIORITY;
|
||||
|
||||
// pinned windows on top of floating regardless
|
||||
if (properties & ALLOW_FLOATING) {
|
||||
for (auto const& w : m_windows | std::views::reverse) {
|
||||
if (ONLY_PRIORITY && !w->priorityFocus())
|
||||
continue;
|
||||
|
||||
if (w->m_isFloating && w->m_isMapped && !w->isHidden() && !w->m_X11ShouldntFocus && w->m_pinned && !w->m_windowData.noFocus.valueOrDefault() && w != pIgnoreWindow) {
|
||||
const auto BB = w->getWindowBoxUnified(properties);
|
||||
CBox box = BB.copy().expand(!w->isX11OverrideRedirect() ? BORDER_GRAB_AREA : 0);
|
||||
@ -898,6 +902,9 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper
|
||||
if (!w->m_workspace)
|
||||
continue;
|
||||
|
||||
if (ONLY_PRIORITY && !w->priorityFocus())
|
||||
continue;
|
||||
|
||||
const auto PWINDOWMONITOR = w->m_monitor.lock();
|
||||
|
||||
// to avoid focusing windows behind special workspaces from other monitors
|
||||
@ -950,7 +957,7 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper
|
||||
const WORKSPACEID WSPID = special ? PMONITOR->activeSpecialWorkspaceID() : PMONITOR->activeWorkspaceID();
|
||||
const auto PWORKSPACE = getWorkspaceByID(WSPID);
|
||||
|
||||
if (PWORKSPACE->m_hasFullscreenWindow && !(properties & SKIP_FULLSCREEN_PRIORITY))
|
||||
if (PWORKSPACE->m_hasFullscreenWindow && !(properties & SKIP_FULLSCREEN_PRIORITY) && !ONLY_PRIORITY)
|
||||
return PWORKSPACE->getFullscreenWindow();
|
||||
|
||||
auto found = floating(false);
|
||||
@ -959,6 +966,9 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper
|
||||
|
||||
// for windows, we need to check their extensions too, first.
|
||||
for (auto const& w : m_windows) {
|
||||
if (ONLY_PRIORITY && !w->priorityFocus())
|
||||
continue;
|
||||
|
||||
if (special != w->onSpecialWorkspace())
|
||||
continue;
|
||||
|
||||
@ -973,6 +983,9 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper
|
||||
}
|
||||
|
||||
for (auto const& w : m_windows) {
|
||||
if (ONLY_PRIORITY && !w->priorityFocus())
|
||||
continue;
|
||||
|
||||
if (special != w->onSpecialWorkspace())
|
||||
continue;
|
||||
|
||||
@ -1083,6 +1096,7 @@ void CCompositor::focusWindow(PHLWINDOW pWindow, SP<CWLSurfaceResource> pSurface
|
||||
static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse");
|
||||
static auto PSPECIALFALLTHROUGH = CConfigValue<Hyprlang::INT>("input:special_fallthrough");
|
||||
|
||||
if (!pWindow || !pWindow->priorityFocus()) {
|
||||
if (g_pSessionLockManager->isSessionLocked()) {
|
||||
Debug::log(LOG, "Refusing a keyboard focus to a window because of a sessionlock");
|
||||
return;
|
||||
@ -1092,6 +1106,7 @@ void CCompositor::focusWindow(PHLWINDOW pWindow, SP<CWLSurfaceResource> pSurface
|
||||
Debug::log(LOG, "Refusing a keyboard focus to a window because of an exclusive ls");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (pWindow && pWindow->m_isX11 && pWindow->isX11OverrideRedirect() && !pWindow->m_xwaylandSurface->wantsFocus())
|
||||
return;
|
||||
@ -1487,7 +1502,6 @@ void CCompositor::cleanupFadingOut(const MONITORID& monid) {
|
||||
|
||||
Debug::log(LOG, "Cleanup: destroyed a layersurface");
|
||||
|
||||
glFlush(); // to free mem NOW.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -2900,6 +2900,8 @@ std::optional<std::string> CConfigManager::handlePermission(const std::string& c
|
||||
type = PERMISSION_TYPE_SCREENCOPY;
|
||||
else if (data[1] == "plugin")
|
||||
type = PERMISSION_TYPE_PLUGIN;
|
||||
else if (data[1] == "keyboard" || data[1] == "keeb")
|
||||
type = PERMISSION_TYPE_KEYBOARD;
|
||||
|
||||
if (data[2] == "ask")
|
||||
mode = PERMISSION_RULE_ALLOW_MODE_ASK;
|
||||
|
@ -109,9 +109,6 @@ void NCrashReporter::createAndSaveCrash(int sig) {
|
||||
finalCrashReport += "\nDate: ";
|
||||
finalCrashReport += GIT_COMMIT_DATE;
|
||||
finalCrashReport += "\nFlags:\n";
|
||||
#ifdef LEGACY_RENDERER
|
||||
finalCrashReport += "legacyrenderer\n";
|
||||
#endif
|
||||
#if ISDEBUG
|
||||
finalCrashReport += "debug\n";
|
||||
#endif
|
||||
|
@ -931,13 +931,10 @@ std::string versionRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
HYPRLAND_VERSION, GIT_BRANCH, GIT_COMMIT_HASH, GIT_DIRTY, commitMsg, GIT_COMMIT_DATE, GIT_TAG, GIT_COMMITS, AQUAMARINE_VERSION,
|
||||
HYPRLANG_VERSION, HYPRUTILS_VERSION, HYPRCURSOR_VERSION, HYPRGRAPHICS_VERSION);
|
||||
|
||||
#if (!defined(LEGACY_RENDERER) && !ISDEBUG && !defined(NO_XWAYLAND))
|
||||
#if (!ISDEBUG && !defined(NO_XWAYLAND))
|
||||
result += "no flags were set\n";
|
||||
#else
|
||||
result += "flags set:\n";
|
||||
#ifdef LEGACY_RENDERER
|
||||
result += "legacyrenderer\n";
|
||||
#endif
|
||||
#if ISDEBUG
|
||||
result += "debug\n";
|
||||
#endif
|
||||
@ -966,9 +963,6 @@ std::string versionRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
GIT_BRANCH, GIT_COMMIT_HASH, HYPRLAND_VERSION, (strcmp(GIT_DIRTY, "dirty") == 0 ? "true" : "false"), escapeJSONStrings(commitMsg), GIT_COMMIT_DATE, GIT_TAG,
|
||||
GIT_COMMITS, AQUAMARINE_VERSION, HYPRLANG_VERSION, HYPRUTILS_VERSION, HYPRCURSOR_VERSION, HYPRGRAPHICS_VERSION);
|
||||
|
||||
#ifdef LEGACY_RENDERER
|
||||
result += "\"legacyrenderer\",";
|
||||
#endif
|
||||
#if ISDEBUG
|
||||
result += "\"debug\",";
|
||||
#endif
|
||||
|
@ -263,11 +263,8 @@ void CHyprDebugOverlay::draw() {
|
||||
glBindTexture(GL_TEXTURE_2D, m_texture->m_texID);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
|
||||
#ifndef GLES2
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
|
||||
#endif
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, PMONITOR->m_pixelSize.x, PMONITOR->m_pixelSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA);
|
||||
|
||||
|
@ -238,11 +238,8 @@ void CHyprNotificationOverlay::draw(PHLMONITOR pMonitor) {
|
||||
glBindTexture(GL_TEXTURE_2D, m_texture->m_texID);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
|
||||
#ifndef GLES2
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
|
||||
#endif
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, MONSIZE.x, MONSIZE.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA);
|
||||
|
||||
|
@ -167,7 +167,9 @@ void CLayerSurface::onMap() {
|
||||
|
||||
if (GRABSFOCUS) {
|
||||
// TODO: use the new superb really very cool grab
|
||||
if (g_pSeatManager->m_seatGrab && !g_pSeatManager->m_seatGrab->accepts(m_surface->resource()))
|
||||
g_pSeatManager->setGrab(nullptr);
|
||||
|
||||
g_pInputManager->releaseAllMouseButtons();
|
||||
g_pCompositor->focusSurface(m_surface->resource());
|
||||
|
||||
|
@ -1149,7 +1149,7 @@ bool CWindow::opaque() {
|
||||
if (m_wlSurface->small() && !m_wlSurface->m_fillIgnoreSmall)
|
||||
return false;
|
||||
|
||||
if (PWORKSPACE->m_alpha->value() != 1.f)
|
||||
if (PWORKSPACE && PWORKSPACE->m_alpha->value() != 1.f)
|
||||
return false;
|
||||
|
||||
if (m_isX11 && m_xwaylandSurface && m_xwaylandSurface->m_surface && m_xwaylandSurface->m_surface->m_current.texture)
|
||||
@ -1836,3 +1836,7 @@ PHLWINDOW CWindow::parent() {
|
||||
|
||||
return m_xdgSurface->m_toplevel->m_parent->m_window.lock();
|
||||
}
|
||||
|
||||
bool CWindow::priorityFocus() {
|
||||
return !m_isX11 && CAsyncDialogBox::isPriorityDialogBox(getPID());
|
||||
}
|
||||
|
@ -51,6 +51,7 @@ enum eGetWindowProperties : uint8_t {
|
||||
ALLOW_FLOATING = 1 << 4,
|
||||
USE_PROP_TILED = 1 << 5,
|
||||
SKIP_FULLSCREEN_PRIORITY = 1 << 6,
|
||||
FOCUS_PRIORITY = 1 << 7,
|
||||
};
|
||||
|
||||
enum eSuppressEvents : uint8_t {
|
||||
@ -408,6 +409,7 @@ class CWindow {
|
||||
std::optional<std::string> xdgTag();
|
||||
std::optional<std::string> xdgDescription();
|
||||
PHLWINDOW parent();
|
||||
bool priorityFocus();
|
||||
|
||||
CBox getWindowMainSurfaceBox() const {
|
||||
return {m_realPosition->value().x, m_realPosition->value().y, m_realSize->value().x, m_realSize->value().y};
|
||||
|
@ -78,6 +78,9 @@ class IKeyboard : public IHID {
|
||||
bool m_enabled = true;
|
||||
bool m_allowBinds = true;
|
||||
|
||||
// permission flag: whether this keyboard is allowed to be processed
|
||||
bool m_allowed = true;
|
||||
|
||||
// if the keymap is overridden by the implementation,
|
||||
// don't try to set keyboard rules anymore, to avoid overwriting the requested one.
|
||||
// e.g. Virtual keyboards with custom maps.
|
||||
|
@ -754,6 +754,7 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
||||
g_pCompositor->setWindowFullscreenInternal(PWINDOW, FSMODE_NONE);
|
||||
|
||||
// Allow the renderer to catch the last frame.
|
||||
if (g_pHyprRenderer->shouldRenderWindow(PWINDOW))
|
||||
g_pHyprRenderer->makeWindowSnapshot(PWINDOW);
|
||||
|
||||
// swallowing
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
using namespace Hyprutils::OS;
|
||||
|
||||
static std::vector<pid_t> asyncDialogBoxes;
|
||||
static std::vector<std::pair<pid_t, WP<CAsyncDialogBox>>> asyncDialogBoxes;
|
||||
|
||||
//
|
||||
SP<CAsyncDialogBox> CAsyncDialogBox::create(const std::string& title, const std::string& description, std::vector<std::string> buttons) {
|
||||
@ -24,7 +24,18 @@ SP<CAsyncDialogBox> CAsyncDialogBox::create(const std::string& title, const std:
|
||||
}
|
||||
|
||||
bool CAsyncDialogBox::isAsyncDialogBox(pid_t pid) {
|
||||
return std::ranges::contains(asyncDialogBoxes, pid);
|
||||
return std::ranges::find_if(asyncDialogBoxes, [pid](const auto& e) { return e.first == pid; }) != asyncDialogBoxes.end();
|
||||
}
|
||||
|
||||
bool CAsyncDialogBox::isPriorityDialogBox(pid_t pid) {
|
||||
for (const auto& [p, db] : asyncDialogBoxes) {
|
||||
if (p != pid)
|
||||
continue;
|
||||
|
||||
return db && db->m_priority;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
CAsyncDialogBox::CAsyncDialogBox(const std::string& title, const std::string& description, std::vector<std::string> buttons) :
|
||||
@ -68,7 +79,7 @@ void CAsyncDialogBox::onWrite(int fd, uint32_t mask) {
|
||||
Debug::log(LOG, "CAsyncDialogBox: dialog {:x} hung up, closed.");
|
||||
|
||||
m_promiseResolver->resolve(m_stdout);
|
||||
std::erase(asyncDialogBoxes, m_dialogPid);
|
||||
std::erase_if(asyncDialogBoxes, [this](const auto& e) { return e.first == m_dialogPid; });
|
||||
|
||||
wl_event_source_remove(m_readEventSource);
|
||||
m_selfReference.reset();
|
||||
@ -112,7 +123,7 @@ SP<CPromise<std::string>> CAsyncDialogBox::open() {
|
||||
}
|
||||
|
||||
m_dialogPid = proc.pid();
|
||||
asyncDialogBoxes.emplace_back(m_dialogPid);
|
||||
asyncDialogBoxes.emplace_back(std::make_pair<>(m_dialogPid, m_selfWeakReference));
|
||||
|
||||
// close the write fd, only the dialog owns it now
|
||||
close(outPipe[1]);
|
||||
|
@ -16,6 +16,7 @@ class CAsyncDialogBox {
|
||||
public:
|
||||
static SP<CAsyncDialogBox> create(const std::string& title, const std::string& description, std::vector<std::string> buttons);
|
||||
static bool isAsyncDialogBox(pid_t pid);
|
||||
static bool isPriorityDialogBox(pid_t pid);
|
||||
|
||||
CAsyncDialogBox(const CAsyncDialogBox&) = delete;
|
||||
CAsyncDialogBox(CAsyncDialogBox&&) = delete;
|
||||
@ -26,6 +27,9 @@ class CAsyncDialogBox {
|
||||
void kill();
|
||||
bool isRunning() const;
|
||||
|
||||
// focus priority, only permission popups
|
||||
bool m_priority = false;
|
||||
|
||||
void onWrite(int fd, uint32_t mask);
|
||||
|
||||
private:
|
||||
|
@ -16,11 +16,7 @@ inline const std::vector<SPixelFormat> GLES3_FORMATS = {
|
||||
{
|
||||
.drmFormat = DRM_FORMAT_ARGB8888,
|
||||
.flipRB = true,
|
||||
#ifndef GLES2
|
||||
.glFormat = GL_RGBA,
|
||||
#else
|
||||
.glFormat = GL_BGRA_EXT,
|
||||
#endif
|
||||
.glType = GL_UNSIGNED_BYTE,
|
||||
.withAlpha = true,
|
||||
.alphaStripped = DRM_FORMAT_XRGB8888,
|
||||
@ -29,11 +25,7 @@ inline const std::vector<SPixelFormat> GLES3_FORMATS = {
|
||||
{
|
||||
.drmFormat = DRM_FORMAT_XRGB8888,
|
||||
.flipRB = true,
|
||||
#ifndef GLES2
|
||||
.glFormat = GL_RGBA,
|
||||
#else
|
||||
.glFormat = GL_BGRA_EXT,
|
||||
#endif
|
||||
.glType = GL_UNSIGNED_BYTE,
|
||||
.withAlpha = false,
|
||||
.alphaStripped = DRM_FORMAT_XRGB8888,
|
||||
@ -106,11 +98,7 @@ inline const std::vector<SPixelFormat> GLES3_FORMATS = {
|
||||
{
|
||||
.drmFormat = DRM_FORMAT_XBGR2101010,
|
||||
.glFormat = GL_RGBA,
|
||||
#ifndef GLES2
|
||||
.glType = GL_UNSIGNED_INT_2_10_10_10_REV,
|
||||
#else
|
||||
.glType = GL_UNSIGNED_INT_2_10_10_10_REV_EXT,
|
||||
#endif
|
||||
.withAlpha = false,
|
||||
.alphaStripped = DRM_FORMAT_XBGR2101010,
|
||||
.bytesPerBlock = 4,
|
||||
@ -118,11 +106,7 @@ inline const std::vector<SPixelFormat> GLES3_FORMATS = {
|
||||
{
|
||||
.drmFormat = DRM_FORMAT_ABGR2101010,
|
||||
.glFormat = GL_RGBA,
|
||||
#ifndef GLES2
|
||||
.glType = GL_UNSIGNED_INT_2_10_10_10_REV,
|
||||
#else
|
||||
.glType = GL_UNSIGNED_INT_2_10_10_10_REV_EXT,
|
||||
#endif
|
||||
.withAlpha = true,
|
||||
.alphaStripped = DRM_FORMAT_XBGR2101010,
|
||||
.bytesPerBlock = 4,
|
||||
@ -130,11 +114,7 @@ inline const std::vector<SPixelFormat> GLES3_FORMATS = {
|
||||
{
|
||||
.drmFormat = DRM_FORMAT_XRGB2101010,
|
||||
.glFormat = GL_RGBA,
|
||||
#ifndef GLES2
|
||||
.glType = GL_UNSIGNED_INT_2_10_10_10_REV,
|
||||
#else
|
||||
.glType = GL_UNSIGNED_INT_2_10_10_10_REV_EXT,
|
||||
#endif
|
||||
.withAlpha = false,
|
||||
.alphaStripped = DRM_FORMAT_XRGB2101010,
|
||||
.bytesPerBlock = 4,
|
||||
@ -142,11 +122,7 @@ inline const std::vector<SPixelFormat> GLES3_FORMATS = {
|
||||
{
|
||||
.drmFormat = DRM_FORMAT_ARGB2101010,
|
||||
.glFormat = GL_RGBA,
|
||||
#ifndef GLES2
|
||||
.glType = GL_UNSIGNED_INT_2_10_10_10_REV,
|
||||
#else
|
||||
.glType = GL_UNSIGNED_INT_2_10_10_10_REV_EXT,
|
||||
#endif
|
||||
.withAlpha = true,
|
||||
.alphaStripped = DRM_FORMAT_XRGB2101010,
|
||||
.bytesPerBlock = 4,
|
||||
@ -154,11 +130,7 @@ inline const std::vector<SPixelFormat> GLES3_FORMATS = {
|
||||
{
|
||||
.drmFormat = DRM_FORMAT_XBGR16161616F,
|
||||
.glFormat = GL_RGBA,
|
||||
#ifndef GLES2
|
||||
.glType = GL_HALF_FLOAT,
|
||||
#else
|
||||
.glType = GL_HALF_FLOAT_OES,
|
||||
#endif
|
||||
.withAlpha = false,
|
||||
.alphaStripped = DRM_FORMAT_XBGR16161616F,
|
||||
.bytesPerBlock = 8,
|
||||
@ -166,22 +138,14 @@ inline const std::vector<SPixelFormat> GLES3_FORMATS = {
|
||||
{
|
||||
.drmFormat = DRM_FORMAT_ABGR16161616F,
|
||||
.glFormat = GL_RGBA,
|
||||
#ifndef GLES2
|
||||
.glType = GL_HALF_FLOAT,
|
||||
#else
|
||||
.glType = GL_HALF_FLOAT_OES,
|
||||
#endif
|
||||
.withAlpha = true,
|
||||
.alphaStripped = DRM_FORMAT_XBGR16161616F,
|
||||
.bytesPerBlock = 8,
|
||||
},
|
||||
{
|
||||
.drmFormat = DRM_FORMAT_XBGR16161616,
|
||||
#ifndef GLES2
|
||||
.glFormat = GL_RGBA16UI,
|
||||
#else
|
||||
.glFormat = GL_RGBA16_EXT,
|
||||
#endif
|
||||
.glType = GL_UNSIGNED_SHORT,
|
||||
.withAlpha = false,
|
||||
.alphaStripped = DRM_FORMAT_XBGR16161616,
|
||||
@ -189,11 +153,7 @@ inline const std::vector<SPixelFormat> GLES3_FORMATS = {
|
||||
},
|
||||
{
|
||||
.drmFormat = DRM_FORMAT_ABGR16161616,
|
||||
#ifndef GLES2
|
||||
.glFormat = GL_RGBA16UI,
|
||||
#else
|
||||
.glFormat = GL_RGBA16_EXT,
|
||||
#endif
|
||||
.glType = GL_UNSIGNED_SHORT,
|
||||
.withAlpha = true,
|
||||
.alphaStripped = DRM_FORMAT_XBGR16161616,
|
||||
@ -290,12 +250,7 @@ uint32_t NFormatUtils::drmFormatToGL(DRMFormat drm) {
|
||||
case DRM_FORMAT_XRGB8888:
|
||||
case DRM_FORMAT_XBGR8888: return GL_RGBA; // doesn't matter, opengl is gucci in this case.
|
||||
case DRM_FORMAT_XRGB2101010:
|
||||
case DRM_FORMAT_XBGR2101010:
|
||||
#ifdef GLES2
|
||||
return GL_RGB10_A2_EXT;
|
||||
#else
|
||||
return GL_RGB10_A2;
|
||||
#endif
|
||||
case DRM_FORMAT_XBGR2101010: return GL_RGB10_A2;
|
||||
default: return GL_RGBA;
|
||||
}
|
||||
UNREACHABLE();
|
||||
@ -303,13 +258,7 @@ uint32_t NFormatUtils::drmFormatToGL(DRMFormat drm) {
|
||||
}
|
||||
|
||||
uint32_t NFormatUtils::glFormatToType(uint32_t gl) {
|
||||
return gl != GL_RGBA ?
|
||||
#ifdef GLES2
|
||||
GL_UNSIGNED_INT_2_10_10_10_REV_EXT :
|
||||
#else
|
||||
GL_UNSIGNED_INT_2_10_10_10_REV :
|
||||
#endif
|
||||
GL_UNSIGNED_BYTE;
|
||||
return gl != GL_RGBA ? GL_UNSIGNED_INT_2_10_10_10_REV : GL_UNSIGNED_BYTE;
|
||||
}
|
||||
|
||||
std::string NFormatUtils::drmFormatName(DRMFormat drm) {
|
||||
|
@ -146,11 +146,8 @@ void CHyprError::createQueued() {
|
||||
glBindTexture(GL_TEXTURE_2D, m_texture->m_texID);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
|
||||
#ifndef GLES2
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
|
||||
#endif
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, PMONITOR->m_pixelSize.x, PMONITOR->m_pixelSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA);
|
||||
|
||||
|
@ -17,15 +17,9 @@
|
||||
#include <unistd.h>
|
||||
#include <wayland-server-core.h>
|
||||
|
||||
#ifdef LEGACY_RENDERER
|
||||
#include <GLES2/gl2.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
#define GLES2
|
||||
#else
|
||||
#define GLES32
|
||||
#include <GLES3/gl32.h>
|
||||
#include <GLES3/gl3ext.h>
|
||||
#endif
|
||||
|
||||
#ifdef NO_XWAYLAND
|
||||
#define XWAYLAND false
|
||||
|
@ -584,7 +584,6 @@ SP<Aquamarine::IBuffer> CPointerManager::renderHWCursorBuffer(SP<CPointerManager
|
||||
g_pHyprOpenGL->renderTexture(texture, xbox, 1.F);
|
||||
|
||||
g_pHyprOpenGL->end();
|
||||
glFlush();
|
||||
g_pHyprOpenGL->m_renderData.pMonitor.reset();
|
||||
|
||||
g_pHyprRenderer->onRenderbufferDestroy(RBO.get());
|
||||
|
@ -70,16 +70,20 @@ static int handleWaiterFD(int fd, uint32_t mask, void* data) {
|
||||
void CEventLoopManager::onFdReadable(SReadableWaiter* waiter) {
|
||||
auto it = std::ranges::find_if(m_readableWaiters, [waiter](const UP<SReadableWaiter>& w) { return waiter == w.get() && w->fd == waiter->fd && w->source == waiter->source; });
|
||||
|
||||
if (waiter->source) {
|
||||
wl_event_source_remove(waiter->source);
|
||||
waiter->source = nullptr;
|
||||
// ???
|
||||
if (it == m_readableWaiters.end())
|
||||
return;
|
||||
|
||||
UP<SReadableWaiter> taken = std::move(*it);
|
||||
m_readableWaiters.erase(it);
|
||||
|
||||
if (taken->source) {
|
||||
wl_event_source_remove(taken->source);
|
||||
taken->source = nullptr;
|
||||
}
|
||||
|
||||
if (waiter->fn)
|
||||
waiter->fn();
|
||||
|
||||
if (it != m_readableWaiters.end())
|
||||
m_readableWaiters.erase(it);
|
||||
if (taken->fn)
|
||||
taken->fn();
|
||||
}
|
||||
|
||||
void CEventLoopManager::enterLoop() {
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "../../managers/HookSystemManager.hpp"
|
||||
#include "../../managers/EventManager.hpp"
|
||||
#include "../../managers/LayoutManager.hpp"
|
||||
#include "../../managers/permissions/DynamicPermissionManager.hpp"
|
||||
|
||||
#include "../../helpers/time/Time.hpp"
|
||||
|
||||
@ -249,7 +250,12 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse) {
|
||||
if (PMONITOR != g_pCompositor->m_lastMonitor && (*PMOUSEFOCUSMON || refocus) && m_forcedFocus.expired())
|
||||
g_pCompositor->setActiveMonitor(PMONITOR);
|
||||
|
||||
if (g_pSessionLockManager->isSessionLocked()) {
|
||||
// check for windows that have focus priority like our permission popups
|
||||
pFoundWindow = g_pCompositor->vectorToWindowUnified(mouseCoords, FOCUS_PRIORITY);
|
||||
if (pFoundWindow)
|
||||
foundSurface = g_pCompositor->vectorWindowToSurface(mouseCoords, pFoundWindow, surfaceCoords);
|
||||
|
||||
if (!foundSurface && g_pSessionLockManager->isSessionLocked()) {
|
||||
|
||||
// set keyboard focus on session lock surface regardless of layers
|
||||
const auto PSESSIONLOCKSURFACE = g_pSessionLockManager->getSessionLockSurfaceForMonitor(PMONITOR->m_id);
|
||||
@ -287,7 +293,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse) {
|
||||
if (!forcedFocus)
|
||||
forcedFocus = g_pCompositor->getForceFocus();
|
||||
|
||||
if (forcedFocus) {
|
||||
if (forcedFocus && !foundSurface) {
|
||||
pFoundWindow = forcedFocus;
|
||||
surfacePos = pFoundWindow->m_realPosition->value();
|
||||
foundSurface = pFoundWindow->m_wlSurface->resource();
|
||||
@ -1054,6 +1060,27 @@ void CInputManager::applyConfigToKeyboard(SP<IKeyboard> pKeyboard) {
|
||||
pKeyboard->m_resolveBindsBySym = RESOLVEBINDSBYSYM;
|
||||
pKeyboard->m_allowBinds = ALLOWBINDS;
|
||||
|
||||
const auto PERM = g_pDynamicPermissionManager->clientPermissionModeWithString(-1, pKeyboard->m_hlName, PERMISSION_TYPE_KEYBOARD);
|
||||
if (PERM == PERMISSION_RULE_ALLOW_MODE_PENDING) {
|
||||
const auto PROMISE = g_pDynamicPermissionManager->promiseFor(-1, pKeyboard->m_hlName, PERMISSION_TYPE_KEYBOARD);
|
||||
if (!PROMISE)
|
||||
Debug::log(ERR, "BUG THIS: No promise for client permission for keyboard");
|
||||
else {
|
||||
PROMISE->then([k = WP<IKeyboard>{pKeyboard}](SP<CPromiseResult<eDynamicPermissionAllowMode>> r) {
|
||||
if (r->hasError()) {
|
||||
Debug::log(ERR, "BUG THIS: No permission returned for keyboard");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!k)
|
||||
return;
|
||||
|
||||
k->m_allowed = r->result() == PERMISSION_RULE_ALLOW_MODE_ALLOW;
|
||||
});
|
||||
}
|
||||
} else
|
||||
pKeyboard->m_allowed = PERM == PERMISSION_RULE_ALLOW_MODE_ALLOW;
|
||||
|
||||
try {
|
||||
if (NUMLOCKON == pKeyboard->m_numlockOn && REPEATDELAY == pKeyboard->m_repeatDelay && REPEATRATE == pKeyboard->m_repeatRate && RULES != "" &&
|
||||
RULES == pKeyboard->m_currentRules.rules && MODEL == pKeyboard->m_currentRules.model && LAYOUT == pKeyboard->m_currentRules.layout &&
|
||||
@ -1368,7 +1395,7 @@ void CInputManager::destroyTabletPad(SP<CTabletPad> pad) {
|
||||
}
|
||||
|
||||
void CInputManager::updateKeyboardsLeds(SP<IKeyboard> pKeyboard) {
|
||||
if (!pKeyboard)
|
||||
if (!pKeyboard || pKeyboard->isVirtual())
|
||||
return;
|
||||
|
||||
std::optional<uint32_t> leds = pKeyboard->getLEDs();
|
||||
@ -1382,7 +1409,7 @@ void CInputManager::updateKeyboardsLeds(SP<IKeyboard> pKeyboard) {
|
||||
}
|
||||
|
||||
void CInputManager::onKeyboardKey(std::any event, SP<IKeyboard> pKeyboard) {
|
||||
if (!pKeyboard->m_enabled)
|
||||
if (!pKeyboard->m_enabled || !pKeyboard->m_allowed)
|
||||
return;
|
||||
|
||||
const bool DISALLOWACTION = pKeyboard->isVirtual() && shouldIgnoreVirtualKeyboard(pKeyboard);
|
||||
|
@ -52,6 +52,7 @@ static const char* permissionToString(eDynamicPermissionType type) {
|
||||
case PERMISSION_TYPE_UNKNOWN: return "PERMISSION_TYPE_UNKNOWN";
|
||||
case PERMISSION_TYPE_SCREENCOPY: return "PERMISSION_TYPE_SCREENCOPY";
|
||||
case PERMISSION_TYPE_PLUGIN: return "PERMISSION_TYPE_PLUGIN";
|
||||
case PERMISSION_TYPE_KEYBOARD: return "PERMISSION_TYPE_KEYBOARD";
|
||||
}
|
||||
|
||||
return "error";
|
||||
@ -59,9 +60,10 @@ static const char* permissionToString(eDynamicPermissionType type) {
|
||||
|
||||
static const char* permissionToHumanString(eDynamicPermissionType type) {
|
||||
switch (type) {
|
||||
case PERMISSION_TYPE_UNKNOWN: return "requesting an unknown permission";
|
||||
case PERMISSION_TYPE_SCREENCOPY: return "trying to capture your screen";
|
||||
case PERMISSION_TYPE_PLUGIN: return "trying to load a plugin";
|
||||
case PERMISSION_TYPE_UNKNOWN: return "An application <b>{}</b> is requesting an unknown permission.";
|
||||
case PERMISSION_TYPE_SCREENCOPY: return "An application <b>{}</b> is trying to capture your screen.<br/><br/>Do you want to allow it to do so?";
|
||||
case PERMISSION_TYPE_PLUGIN: return "An application <b>{}</b> is trying to load a plugin: <b>{}</b>.<br/><br/>Do you want to load it?";
|
||||
case PERMISSION_TYPE_KEYBOARD: return "A new keyboard has been plugged in: {}.<br/><br/>Do you want to allow it to operate?";
|
||||
}
|
||||
|
||||
return "error";
|
||||
@ -184,7 +186,7 @@ eDynamicPermissionAllowMode CDynamicPermissionManager::clientPermissionMode(wl_c
|
||||
return PERMISSION_RULE_ALLOW_MODE_PENDING;
|
||||
}
|
||||
|
||||
// if we are here, we need to ask.
|
||||
// if we are here, we need to ask, that's the fallback for all these (keyboards wont come here)
|
||||
askForPermission(client, LOOKUP.value_or(""), permission);
|
||||
|
||||
return PERMISSION_RULE_ALLOW_MODE_PENDING;
|
||||
@ -232,6 +234,10 @@ eDynamicPermissionAllowMode CDynamicPermissionManager::clientPermissionModeWithS
|
||||
} else if ((*it)->m_allowMode == PERMISSION_RULE_ALLOW_MODE_PENDING) {
|
||||
Debug::log(TRACE, "CDynamicPermissionManager::clientHasPermission: permission pending by config rule");
|
||||
return PERMISSION_RULE_ALLOW_MODE_PENDING;
|
||||
} else if ((*it)->m_allowMode == PERMISSION_RULE_ALLOW_MODE_ASK) {
|
||||
Debug::log(TRACE, "CDynamicPermissionManager::clientHasPermission: permission ask by config rule");
|
||||
askForPermission(nullptr, str, permission, pid);
|
||||
return PERMISSION_RULE_ALLOW_MODE_PENDING;
|
||||
} else
|
||||
Debug::log(TRACE, "CDynamicPermissionManager::clientHasPermission: permission ask by config rule");
|
||||
}
|
||||
@ -247,6 +253,10 @@ eDynamicPermissionAllowMode CDynamicPermissionManager::clientPermissionModeWithS
|
||||
return PERMISSION_RULE_ALLOW_MODE_PENDING;
|
||||
}
|
||||
|
||||
// keyboards are allow default
|
||||
if (permission == PERMISSION_TYPE_KEYBOARD)
|
||||
return PERMISSION_RULE_ALLOW_MODE_ALLOW;
|
||||
|
||||
// if we are here, we need to ask.
|
||||
askForPermission(nullptr, str, permission, pid);
|
||||
|
||||
@ -263,22 +273,20 @@ void CDynamicPermissionManager::askForPermission(wl_client* client, const std::s
|
||||
|
||||
std::string description = "";
|
||||
if (binaryPath.empty())
|
||||
description = std::format("An unknown application (wayland client ID 0x{:x}) is {}.", (uintptr_t)client, permissionToHumanString(type));
|
||||
description = std::format(std::runtime_format(permissionToHumanString(type)), std::format("unknown application (wayland client ID 0x{:x})", (uintptr_t)client));
|
||||
else if (client) {
|
||||
std::string binaryName = binaryPath.contains("/") ? binaryPath.substr(binaryPath.find_last_of('/') + 1) : binaryPath;
|
||||
description = std::format("An application <b>{}</b> ({}) is {}.", binaryName, binaryPath, permissionToHumanString(type));
|
||||
description = std::format(std::runtime_format(permissionToHumanString(type)), std::format("{}</b> ({})", binaryName, binaryPath));
|
||||
} else if (pid >= 0) {
|
||||
if (type == PERMISSION_TYPE_PLUGIN) {
|
||||
const auto LOOKUP = binaryNameForPid(pid);
|
||||
description = std::format("An application <b>{}</b> is {}:<br/><b>{}</b>", LOOKUP.value_or("Unknown"), permissionToHumanString(type), binaryPath);
|
||||
description = std::format(std::runtime_format(permissionToHumanString(type)), LOOKUP.value_or("Unknown"), binaryPath);
|
||||
} else {
|
||||
const auto LOOKUP = binaryNameForPid(pid);
|
||||
description = std::format("An application <b>{}</b> ({}) is {}.", LOOKUP.value_or("Unknown"), binaryPath, permissionToHumanString(type));
|
||||
description = std::format(std::runtime_format(permissionToHumanString(type)), LOOKUP.value_or("Unknown"), binaryPath);
|
||||
}
|
||||
} else
|
||||
description = std::format("An application is {}:<br/><b>{}</b>", permissionToHumanString(type), binaryPath);
|
||||
|
||||
description += "<br/><br/>Do you want to allow this?";
|
||||
description = std::format(std::runtime_format(permissionToHumanString(type)), binaryPath);
|
||||
|
||||
std::vector<std::string> options;
|
||||
|
||||
@ -289,6 +297,7 @@ void CDynamicPermissionManager::askForPermission(wl_client* client, const std::s
|
||||
options = {"Deny", "Allow"};
|
||||
|
||||
rule->m_dialogBox = CAsyncDialogBox::create("Permission request", description, options);
|
||||
rule->m_dialogBox->m_priority = true;
|
||||
|
||||
if (!rule->m_dialogBox) {
|
||||
Debug::log(ERR, "CDynamicPermissionManager::askForPermission: hyprland-qtutils likely missing, cannot ask! Disabling permission control...");
|
||||
|
@ -17,6 +17,7 @@ enum eDynamicPermissionType : uint8_t {
|
||||
PERMISSION_TYPE_UNKNOWN = 0,
|
||||
PERMISSION_TYPE_SCREENCOPY,
|
||||
PERMISSION_TYPE_PLUGIN,
|
||||
PERMISSION_TYPE_KEYBOARD,
|
||||
};
|
||||
|
||||
enum eDynamicPermissionRuleSource : uint8_t {
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "ForeignToplevelWlr.hpp"
|
||||
#include <algorithm>
|
||||
#include "../Compositor.hpp"
|
||||
#include "managers/input/InputManager.hpp"
|
||||
#include "protocols/core/Output.hpp"
|
||||
#include "render/Renderer.hpp"
|
||||
#include "../managers/HookSystemManager.hpp"
|
||||
@ -24,6 +25,7 @@ CForeignToplevelHandleWlr::CForeignToplevelHandleWlr(SP<CZwlrForeignToplevelHand
|
||||
// these requests bypass the config'd stuff cuz it's usually like
|
||||
// window switchers and shit
|
||||
PWINDOW->activate(true);
|
||||
g_pInputManager->simulateMouseMovement();
|
||||
});
|
||||
|
||||
m_resource->setSetFullscreen([this](CZwlrForeignToplevelHandleV1* p, wl_resource* output) {
|
||||
|
@ -187,19 +187,11 @@ void CScreencopyFrame::share() {
|
||||
callback(copyShm());
|
||||
}
|
||||
|
||||
void CScreencopyFrame::copyDmabuf(std::function<void(bool)> callback) {
|
||||
const auto PERM = g_pDynamicPermissionManager->clientPermissionMode(m_resource->client(), PERMISSION_TYPE_SCREENCOPY);
|
||||
void CScreencopyFrame::renderMon() {
|
||||
auto TEXTURE = makeShared<CTexture>(m_monitor->m_output->state->state().buffer);
|
||||
|
||||
CRegion fakeDamage = {0, 0, INT16_MAX, INT16_MAX};
|
||||
|
||||
if (!g_pHyprRenderer->beginRender(m_monitor.lock(), fakeDamage, RENDER_MODE_TO_BUFFER, m_buffer.m_buffer, nullptr, true)) {
|
||||
LOGM(ERR, "Can't copy: failed to begin rendering to dma frame");
|
||||
callback(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (PERM == PERMISSION_RULE_ALLOW_MODE_ALLOW) {
|
||||
CBox monbox = CBox{0, 0, m_monitor->m_pixelSize.x, m_monitor->m_pixelSize.y}
|
||||
.translate({-m_box.x, -m_box.y}) // vvvv kinda ass-backwards but that's how I designed the renderer... sigh.
|
||||
.transform(wlTransformToHyprutils(invertTransform(m_monitor->m_transform)), m_monitor->m_pixelSize.x, m_monitor->m_pixelSize.y);
|
||||
@ -211,6 +203,43 @@ void CScreencopyFrame::copyDmabuf(std::function<void(bool)> callback) {
|
||||
if (m_overlayCursor)
|
||||
g_pPointerManager->renderSoftwareCursorsFor(m_monitor.lock(), Time::steadyNow(), fakeDamage,
|
||||
g_pInputManager->getMouseCoordsInternal() - m_monitor->m_position - m_box.pos(), true);
|
||||
}
|
||||
|
||||
void CScreencopyFrame::storeTempFB() {
|
||||
g_pHyprRenderer->makeEGLCurrent();
|
||||
|
||||
m_tempFb.alloc(m_box.w, m_box.h);
|
||||
|
||||
CRegion fakeDamage = {0, 0, INT16_MAX, INT16_MAX};
|
||||
|
||||
if (!g_pHyprRenderer->beginRender(m_monitor.lock(), fakeDamage, RENDER_MODE_FULL_FAKE, nullptr, &m_tempFb, true)) {
|
||||
LOGM(ERR, "Can't copy: failed to begin rendering to temp fb");
|
||||
return;
|
||||
}
|
||||
|
||||
renderMon();
|
||||
|
||||
g_pHyprRenderer->endRender();
|
||||
}
|
||||
|
||||
void CScreencopyFrame::copyDmabuf(std::function<void(bool)> callback) {
|
||||
const auto PERM = g_pDynamicPermissionManager->clientPermissionMode(m_resource->client(), PERMISSION_TYPE_SCREENCOPY);
|
||||
|
||||
CRegion fakeDamage = {0, 0, INT16_MAX, INT16_MAX};
|
||||
|
||||
if (!g_pHyprRenderer->beginRender(m_monitor.lock(), fakeDamage, RENDER_MODE_TO_BUFFER, m_buffer.m_buffer, nullptr, true)) {
|
||||
LOGM(ERR, "Can't copy: failed to begin rendering to dma frame");
|
||||
callback(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (PERM == PERMISSION_RULE_ALLOW_MODE_ALLOW) {
|
||||
if (m_tempFb.isAllocated()) {
|
||||
CBox texbox = {{}, m_box.size()};
|
||||
g_pHyprOpenGL->renderTexture(m_tempFb.getTexture(), texbox, 1);
|
||||
m_tempFb.release();
|
||||
} else
|
||||
renderMon();
|
||||
} else if (PERM == PERMISSION_RULE_ALLOW_MODE_PENDING)
|
||||
g_pHyprOpenGL->clear(Colors::BLACK);
|
||||
else {
|
||||
@ -229,7 +258,6 @@ void CScreencopyFrame::copyDmabuf(std::function<void(bool)> callback) {
|
||||
|
||||
bool CScreencopyFrame::copyShm() {
|
||||
const auto PERM = g_pDynamicPermissionManager->clientPermissionMode(m_resource->client(), PERMISSION_TYPE_SCREENCOPY);
|
||||
auto TEXTURE = makeShared<CTexture>(m_monitor->m_output->state->state().buffer);
|
||||
|
||||
auto shm = m_buffer->shm();
|
||||
auto [pixelData, fmt, bufLen] = m_buffer->beginDataPtr(0); // no need for end, cuz it's shm
|
||||
@ -247,15 +275,12 @@ bool CScreencopyFrame::copyShm() {
|
||||
}
|
||||
|
||||
if (PERM == PERMISSION_RULE_ALLOW_MODE_ALLOW) {
|
||||
CBox monbox = CBox{0, 0, m_monitor->m_transformedSize.x, m_monitor->m_transformedSize.y}.translate({-m_box.x, -m_box.y});
|
||||
g_pHyprOpenGL->setMonitorTransformEnabled(true);
|
||||
g_pHyprOpenGL->setRenderModifEnabled(false);
|
||||
g_pHyprOpenGL->renderTexture(TEXTURE, monbox, 1);
|
||||
g_pHyprOpenGL->setRenderModifEnabled(true);
|
||||
g_pHyprOpenGL->setMonitorTransformEnabled(false);
|
||||
if (m_overlayCursor)
|
||||
g_pPointerManager->renderSoftwareCursorsFor(m_monitor.lock(), Time::steadyNow(), fakeDamage,
|
||||
g_pInputManager->getMouseCoordsInternal() - m_monitor->m_position - m_box.pos(), true);
|
||||
if (m_tempFb.isAllocated()) {
|
||||
CBox texbox = {{}, m_box.size()};
|
||||
g_pHyprOpenGL->renderTexture(m_tempFb.getTexture(), texbox, 1);
|
||||
m_tempFb.release();
|
||||
} else
|
||||
renderMon();
|
||||
} else if (PERM == PERMISSION_RULE_ALLOW_MODE_PENDING)
|
||||
g_pHyprOpenGL->clear(Colors::BLACK);
|
||||
else {
|
||||
@ -264,11 +289,7 @@ bool CScreencopyFrame::copyShm() {
|
||||
g_pHyprOpenGL->renderTexture(g_pHyprOpenGL->m_screencopyDeniedTexture, texbox, 1);
|
||||
}
|
||||
|
||||
#ifndef GLES2
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, fb.getFBID());
|
||||
#else
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fb.getFBID());
|
||||
#endif
|
||||
|
||||
const auto PFORMAT = NFormatUtils::getPixelFormatFromDRM(shm.format);
|
||||
if (!PFORMAT) {
|
||||
@ -304,11 +325,7 @@ bool CScreencopyFrame::copyShm() {
|
||||
|
||||
g_pHyprOpenGL->m_renderData.pMonitor.reset();
|
||||
|
||||
#ifndef GLES2
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||
#else
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
#endif
|
||||
|
||||
LOGM(TRACE, "Copied frame via shm");
|
||||
|
||||
@ -428,8 +445,12 @@ void CScreencopyProtocol::onOutputCommit(PHLMONITOR pMonitor) {
|
||||
// check permissions
|
||||
const auto PERM = g_pDynamicPermissionManager->clientPermissionMode(f->m_resource->client(), PERMISSION_TYPE_SCREENCOPY);
|
||||
|
||||
if (PERM == PERMISSION_RULE_ALLOW_MODE_PENDING)
|
||||
if (PERM == PERMISSION_RULE_ALLOW_MODE_PENDING) {
|
||||
if (!f->m_tempFb.isAllocated())
|
||||
f->storeTempFB(); // make a snapshot before the popup
|
||||
|
||||
continue; // pending an answer, don't do anything yet.
|
||||
}
|
||||
|
||||
// otherwise share. If it's denied, it will be black.
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "../managers/HookSystemManager.hpp"
|
||||
#include "../helpers/time/Timer.hpp"
|
||||
#include "../helpers/time/Time.hpp"
|
||||
#include "../render/Framebuffer.hpp"
|
||||
#include "../managers/eventLoop/EventLoopTimer.hpp"
|
||||
#include <aquamarine/buffer/Buffer.hpp>
|
||||
|
||||
@ -72,9 +73,14 @@ class CScreencopyFrame {
|
||||
int m_shmStride = 0;
|
||||
CBox m_box = {};
|
||||
|
||||
// if we have a pending perm, hold the buffer.
|
||||
CFramebuffer m_tempFb;
|
||||
|
||||
void copy(CZwlrScreencopyFrameV1* pFrame, wl_resource* buffer);
|
||||
void copyDmabuf(std::function<void(bool)> callback);
|
||||
bool copyShm();
|
||||
void renderMon();
|
||||
void storeTempFB();
|
||||
void share();
|
||||
|
||||
friend class CScreencopyProtocol;
|
||||
|
@ -281,10 +281,7 @@ bool CToplevelExportFrame::copyShm(const Time::steady_tp& now) {
|
||||
g_pHyprOpenGL->m_renderData.pMonitor = PMONITOR;
|
||||
outFB.bind();
|
||||
|
||||
#ifndef GLES2
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, outFB.getFBID());
|
||||
#endif
|
||||
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
|
||||
auto glFormat = PFORMAT->flipRB ? GL_BGRA_EXT : GL_RGBA;
|
||||
@ -318,10 +315,7 @@ bool CToplevelExportFrame::copyShm(const Time::steady_tp& now) {
|
||||
}
|
||||
|
||||
outFB.unbind();
|
||||
|
||||
#ifndef GLES2
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -12,6 +12,11 @@ bool CFramebuffer::alloc(int w, int h, uint32_t drmFormat) {
|
||||
uint32_t glFormat = NFormatUtils::drmFormatToGL(drmFormat);
|
||||
uint32_t glType = NFormatUtils::glFormatToType(glFormat);
|
||||
|
||||
if (drmFormat != m_drmFormat || m_size != Vector2D{w, h})
|
||||
release();
|
||||
|
||||
m_drmFormat = drmFormat;
|
||||
|
||||
if (!m_tex) {
|
||||
m_tex = makeShared<CTexture>();
|
||||
m_tex->allocate();
|
||||
@ -35,14 +40,11 @@ bool CFramebuffer::alloc(int w, int h, uint32_t drmFormat) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_fb);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_tex->m_texID, 0);
|
||||
|
||||
// TODO: Allow this with gles2
|
||||
#ifndef GLES2
|
||||
if (m_stencilTex) {
|
||||
glBindTexture(GL_TEXTURE_2D, m_stencilTex->m_texID);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, w, h, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_stencilTex->m_texID, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
auto status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
RASSERT((status == GL_FRAMEBUFFER_COMPLETE), "Framebuffer incomplete, couldn't create! (FB status: {}, GL Error: 0x{:x})", status, (int)glGetError());
|
||||
@ -59,8 +61,6 @@ bool CFramebuffer::alloc(int w, int h, uint32_t drmFormat) {
|
||||
}
|
||||
|
||||
void CFramebuffer::addStencil(SP<CTexture> tex) {
|
||||
// TODO: Allow this with gles2
|
||||
#ifndef GLES2
|
||||
m_stencilTex = tex;
|
||||
glBindTexture(GL_TEXTURE_2D, m_stencilTex->m_texID);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, m_size.x, m_size.y, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr);
|
||||
@ -74,15 +74,10 @@ void CFramebuffer::addStencil(SP<CTexture> tex) {
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CFramebuffer::bind() {
|
||||
#ifndef GLES2
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fb);
|
||||
#else
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_iFb);
|
||||
#endif
|
||||
|
||||
if (g_pHyprOpenGL)
|
||||
glViewport(0, 0, g_pHyprOpenGL->m_renderData.pMonitor->m_pixelSize.x, g_pHyprOpenGL->m_renderData.pMonitor->m_pixelSize.y);
|
||||
@ -91,11 +86,7 @@ void CFramebuffer::bind() {
|
||||
}
|
||||
|
||||
void CFramebuffer::unbind() {
|
||||
#ifndef GLES2
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
#else
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CFramebuffer::release() {
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "../defines.hpp"
|
||||
#include "../helpers/Format.hpp"
|
||||
#include "Texture.hpp"
|
||||
|
||||
class CFramebuffer {
|
||||
@ -20,6 +21,7 @@ class CFramebuffer {
|
||||
GLuint getFBID();
|
||||
|
||||
Vector2D m_size;
|
||||
DRMFormat m_drmFormat = 0 /* DRM_FORMAT_INVALID */;
|
||||
|
||||
private:
|
||||
SP<CTexture> m_tex;
|
||||
|
@ -162,24 +162,14 @@ void CHyprOpenGLImpl::initEGL(bool gbm) {
|
||||
|
||||
auto attrsNoVer = attrs;
|
||||
|
||||
#ifndef GLES2
|
||||
attrs.push_back(EGL_CONTEXT_MAJOR_VERSION);
|
||||
attrs.push_back(3);
|
||||
attrs.push_back(EGL_CONTEXT_MINOR_VERSION);
|
||||
attrs.push_back(2);
|
||||
#else
|
||||
attrs.push_back(EGL_CONTEXT_CLIENT_VERSION);
|
||||
attrs.push_back(2);
|
||||
m_eglContextVersion = EGL_CONTEXT_GLES_2_0;
|
||||
#endif
|
||||
|
||||
attrs.push_back(EGL_NONE);
|
||||
|
||||
m_eglContext = eglCreateContext(m_eglDisplay, EGL_NO_CONFIG_KHR, EGL_NO_CONTEXT, attrs.data());
|
||||
if (m_eglContext == EGL_NO_CONTEXT) {
|
||||
#ifdef GLES2
|
||||
RASSERT(false, "EGL: failed to create a context with GLES2.0");
|
||||
#endif
|
||||
Debug::log(WARN, "EGL: Failed to create a context with GLES3.2, retrying 3.0");
|
||||
|
||||
attrs = attrsNoVer;
|
||||
@ -362,10 +352,6 @@ CHyprOpenGLImpl::CHyprOpenGLImpl() : m_drmFD(g_pCompositor->m_drmFD) {
|
||||
|
||||
TRACY_GPU_CONTEXT;
|
||||
|
||||
#ifdef GLES2
|
||||
Debug::log(WARN, "!RENDERER: Using the legacy GLES2 renderer!");
|
||||
#endif
|
||||
|
||||
initDRMFormats();
|
||||
|
||||
initAssets();
|
||||
@ -669,7 +655,6 @@ GLuint CHyprOpenGLImpl::compileShader(const GLuint& type, std::string src, bool
|
||||
void CHyprOpenGLImpl::beginSimple(PHLMONITOR pMonitor, const CRegion& damage, SP<CRenderbuffer> rb, CFramebuffer* fb) {
|
||||
m_renderData.pMonitor = pMonitor;
|
||||
|
||||
#ifndef GLES2
|
||||
const GLenum RESETSTATUS = glGetGraphicsResetStatus();
|
||||
if (RESETSTATUS != GL_NO_ERROR) {
|
||||
std::string errStr = "";
|
||||
@ -682,7 +667,6 @@ void CHyprOpenGLImpl::beginSimple(PHLMONITOR pMonitor, const CRegion& damage, SP
|
||||
RASSERT(false, "Aborting, glGetGraphicsResetStatus returned {}. Cannot continue until proper GPU reset handling is implemented.", errStr);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
TRACY_GPU_ZONE("RenderBeginSimple");
|
||||
|
||||
@ -721,7 +705,6 @@ void CHyprOpenGLImpl::beginSimple(PHLMONITOR pMonitor, const CRegion& damage, SP
|
||||
void CHyprOpenGLImpl::begin(PHLMONITOR pMonitor, const CRegion& damage_, CFramebuffer* fb, std::optional<CRegion> finalDamage) {
|
||||
m_renderData.pMonitor = pMonitor;
|
||||
|
||||
#ifndef GLES2
|
||||
const GLenum RESETSTATUS = glGetGraphicsResetStatus();
|
||||
if (RESETSTATUS != GL_NO_ERROR) {
|
||||
std::string errStr = "";
|
||||
@ -734,7 +717,6 @@ void CHyprOpenGLImpl::begin(PHLMONITOR pMonitor, const CRegion& damage_, CFrameb
|
||||
RASSERT(false, "Aborting, glGetGraphicsResetStatus returned {}. Cannot continue until proper GPU reset handling is implemented.", errStr);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
TRACY_GPU_ZONE("RenderBegin");
|
||||
|
||||
@ -752,13 +734,15 @@ void CHyprOpenGLImpl::begin(PHLMONITOR pMonitor, const CRegion& damage_, CFrameb
|
||||
if (!m_shadersInitialized)
|
||||
initShaders();
|
||||
|
||||
const auto DRM_FORMAT = fb ? fb->m_drmFormat : pMonitor->m_output->state->state().drmFormat;
|
||||
|
||||
// ensure a framebuffer for the monitor exists
|
||||
if (m_renderData.pCurrentMonData->offloadFB.m_size != pMonitor->m_pixelSize) {
|
||||
if (m_renderData.pCurrentMonData->offloadFB.m_size != pMonitor->m_pixelSize || DRM_FORMAT != m_renderData.pCurrentMonData->offloadFB.m_drmFormat) {
|
||||
m_renderData.pCurrentMonData->stencilTex->allocate();
|
||||
|
||||
m_renderData.pCurrentMonData->offloadFB.alloc(pMonitor->m_pixelSize.x, pMonitor->m_pixelSize.y, pMonitor->m_output->state->state().drmFormat);
|
||||
m_renderData.pCurrentMonData->mirrorFB.alloc(pMonitor->m_pixelSize.x, pMonitor->m_pixelSize.y, pMonitor->m_output->state->state().drmFormat);
|
||||
m_renderData.pCurrentMonData->mirrorSwapFB.alloc(pMonitor->m_pixelSize.x, pMonitor->m_pixelSize.y, pMonitor->m_output->state->state().drmFormat);
|
||||
m_renderData.pCurrentMonData->offloadFB.alloc(pMonitor->m_pixelSize.x, pMonitor->m_pixelSize.y, DRM_FORMAT);
|
||||
m_renderData.pCurrentMonData->mirrorFB.alloc(pMonitor->m_pixelSize.x, pMonitor->m_pixelSize.y, DRM_FORMAT);
|
||||
m_renderData.pCurrentMonData->mirrorSwapFB.alloc(pMonitor->m_pixelSize.x, pMonitor->m_pixelSize.y, DRM_FORMAT);
|
||||
|
||||
m_renderData.pCurrentMonData->offloadFB.addStencil(m_renderData.pCurrentMonData->stencilTex);
|
||||
m_renderData.pCurrentMonData->mirrorFB.addStencil(m_renderData.pCurrentMonData->stencilTex);
|
||||
@ -858,11 +842,7 @@ void CHyprOpenGLImpl::end() {
|
||||
// check for gl errors
|
||||
const GLenum ERR = glGetError();
|
||||
|
||||
#ifdef GLES2
|
||||
if (ERR == GL_CONTEXT_LOST_KHR) /* We don't have infra to recover from this */
|
||||
#else
|
||||
if (ERR == GL_CONTEXT_LOST) /* We don't have infra to recover from this */
|
||||
#endif
|
||||
RASSERT(false, "glGetError at Opengl::end() returned GL_CONTEXT_LOST. Cannot continue until proper GPU reset handling is implemented.");
|
||||
}
|
||||
|
||||
@ -944,9 +924,7 @@ bool CHyprOpenGLImpl::initShaders() {
|
||||
shaders->TEXVERTSRC320 = processShader("tex320.vert", includes);
|
||||
|
||||
GLuint prog;
|
||||
#ifdef GLES2
|
||||
m_cmSupported = false;
|
||||
#else
|
||||
|
||||
if (!*PCM)
|
||||
m_cmSupported = false;
|
||||
else {
|
||||
@ -975,12 +953,12 @@ bool CHyprOpenGLImpl::initShaders() {
|
||||
shaders->m_shCM.applyTint = glGetUniformLocation(prog, "applyTint");
|
||||
shaders->m_shCM.tint = glGetUniformLocation(prog, "tint");
|
||||
shaders->m_shCM.useAlphaMatte = glGetUniformLocation(prog, "useAlphaMatte");
|
||||
shaders->m_shCM.createVao();
|
||||
} else
|
||||
Debug::log(ERR,
|
||||
"WARNING: CM Shader failed compiling, color management will not work. It's likely because your GPU is an old piece of garbage, don't file bug reports "
|
||||
"about this!");
|
||||
}
|
||||
#endif
|
||||
|
||||
const auto FRAGSHADOW = processShader(m_cmSupported ? "shadow.frag" : "shadow_legacy.frag", includes);
|
||||
const auto FRAGBORDER1 = processShader(m_cmSupported ? "border.frag" : "border_legacy.frag", includes);
|
||||
@ -1004,6 +982,7 @@ bool CHyprOpenGLImpl::initShaders() {
|
||||
shaders->m_shQUAD.proj = glGetUniformLocation(prog, "proj");
|
||||
shaders->m_shQUAD.color = glGetUniformLocation(prog, "color");
|
||||
shaders->m_shQUAD.posAttrib = glGetAttribLocation(prog, "pos");
|
||||
shaders->m_shQUAD.createVao();
|
||||
|
||||
prog = createProgram(shaders->TEXVERTSRC, TEXFRAGSRCRGBA, isDynamic);
|
||||
if (!prog)
|
||||
@ -1023,6 +1002,7 @@ bool CHyprOpenGLImpl::initShaders() {
|
||||
shaders->m_shRGBA.applyTint = glGetUniformLocation(prog, "applyTint");
|
||||
shaders->m_shRGBA.tint = glGetUniformLocation(prog, "tint");
|
||||
shaders->m_shRGBA.useAlphaMatte = glGetUniformLocation(prog, "useAlphaMatte");
|
||||
shaders->m_shRGBA.createVao();
|
||||
|
||||
prog = createProgram(shaders->TEXVERTSRC, TEXFRAGSRCRGBAPASSTHRU, isDynamic);
|
||||
if (!prog)
|
||||
@ -1032,6 +1012,7 @@ bool CHyprOpenGLImpl::initShaders() {
|
||||
shaders->m_shPASSTHRURGBA.tex = glGetUniformLocation(prog, "tex");
|
||||
shaders->m_shPASSTHRURGBA.texAttrib = glGetAttribLocation(prog, "texcoord");
|
||||
shaders->m_shPASSTHRURGBA.posAttrib = glGetAttribLocation(prog, "pos");
|
||||
shaders->m_shPASSTHRURGBA.createVao();
|
||||
|
||||
prog = createProgram(shaders->TEXVERTSRC, TEXFRAGSRCRGBAMATTE, isDynamic);
|
||||
if (!prog)
|
||||
@ -1042,6 +1023,7 @@ bool CHyprOpenGLImpl::initShaders() {
|
||||
shaders->m_shMATTE.alphaMatte = glGetUniformLocation(prog, "texMatte");
|
||||
shaders->m_shMATTE.texAttrib = glGetAttribLocation(prog, "texcoord");
|
||||
shaders->m_shMATTE.posAttrib = glGetAttribLocation(prog, "pos");
|
||||
shaders->m_shMATTE.createVao();
|
||||
|
||||
prog = createProgram(shaders->TEXVERTSRC, FRAGGLITCH, isDynamic);
|
||||
if (!prog)
|
||||
@ -1054,6 +1036,7 @@ bool CHyprOpenGLImpl::initShaders() {
|
||||
shaders->m_shGLITCH.distort = glGetUniformLocation(prog, "distort");
|
||||
shaders->m_shGLITCH.time = glGetUniformLocation(prog, "time");
|
||||
shaders->m_shGLITCH.fullSize = glGetUniformLocation(prog, "screenSize");
|
||||
shaders->m_shGLITCH.createVao();
|
||||
|
||||
prog = createProgram(shaders->TEXVERTSRC, TEXFRAGSRCRGBX, isDynamic);
|
||||
if (!prog)
|
||||
@ -1070,6 +1053,7 @@ bool CHyprOpenGLImpl::initShaders() {
|
||||
shaders->m_shRGBX.discardAlphaValue = glGetUniformLocation(prog, "discardAlphaValue");
|
||||
shaders->m_shRGBX.applyTint = glGetUniformLocation(prog, "applyTint");
|
||||
shaders->m_shRGBX.tint = glGetUniformLocation(prog, "tint");
|
||||
shaders->m_shRGBX.createVao();
|
||||
|
||||
prog = createProgram(shaders->TEXVERTSRC, TEXFRAGSRCEXT, isDynamic);
|
||||
if (!prog)
|
||||
@ -1086,6 +1070,7 @@ bool CHyprOpenGLImpl::initShaders() {
|
||||
shaders->m_shEXT.discardAlphaValue = glGetUniformLocation(prog, "discardAlphaValue");
|
||||
shaders->m_shEXT.applyTint = glGetUniformLocation(prog, "applyTint");
|
||||
shaders->m_shEXT.tint = glGetUniformLocation(prog, "tint");
|
||||
shaders->m_shEXT.createVao();
|
||||
|
||||
prog = createProgram(shaders->TEXVERTSRC, FRAGBLUR1, isDynamic);
|
||||
if (!prog)
|
||||
@ -1101,6 +1086,7 @@ bool CHyprOpenGLImpl::initShaders() {
|
||||
shaders->m_shBLUR1.passes = glGetUniformLocation(prog, "passes");
|
||||
shaders->m_shBLUR1.vibrancy = glGetUniformLocation(prog, "vibrancy");
|
||||
shaders->m_shBLUR1.vibrancy_darkness = glGetUniformLocation(prog, "vibrancy_darkness");
|
||||
shaders->m_shBLUR1.createVao();
|
||||
|
||||
prog = createProgram(shaders->TEXVERTSRC, FRAGBLUR2, isDynamic);
|
||||
if (!prog)
|
||||
@ -1113,6 +1099,7 @@ bool CHyprOpenGLImpl::initShaders() {
|
||||
shaders->m_shBLUR2.texAttrib = glGetAttribLocation(prog, "texcoord");
|
||||
shaders->m_shBLUR2.radius = glGetUniformLocation(prog, "radius");
|
||||
shaders->m_shBLUR2.halfpixel = glGetUniformLocation(prog, "halfpixel");
|
||||
shaders->m_shBLUR2.createVao();
|
||||
|
||||
prog = createProgram(m_cmSupported ? shaders->TEXVERTSRC300 : shaders->TEXVERTSRC, FRAGBLURPREPARE, isDynamic);
|
||||
if (!prog)
|
||||
@ -1127,6 +1114,7 @@ bool CHyprOpenGLImpl::initShaders() {
|
||||
shaders->m_shBLURPREPARE.texAttrib = glGetAttribLocation(prog, "texcoord");
|
||||
shaders->m_shBLURPREPARE.contrast = glGetUniformLocation(prog, "contrast");
|
||||
shaders->m_shBLURPREPARE.brightness = glGetUniformLocation(prog, "brightness");
|
||||
shaders->m_shBLURPREPARE.createVao();
|
||||
|
||||
prog = createProgram(m_cmSupported ? shaders->TEXVERTSRC300 : shaders->TEXVERTSRC, FRAGBLURFINISH, isDynamic);
|
||||
if (!prog)
|
||||
@ -1140,6 +1128,7 @@ bool CHyprOpenGLImpl::initShaders() {
|
||||
shaders->m_shBLURFINISH.texAttrib = glGetAttribLocation(prog, "texcoord");
|
||||
shaders->m_shBLURFINISH.brightness = glGetUniformLocation(prog, "brightness");
|
||||
shaders->m_shBLURFINISH.noise = glGetUniformLocation(prog, "noise");
|
||||
shaders->m_shBLURFINISH.createVao();
|
||||
|
||||
prog = createProgram(m_cmSupported ? shaders->TEXVERTSRC300 : shaders->TEXVERTSRC, FRAGSHADOW, isDynamic);
|
||||
if (!prog)
|
||||
@ -1155,6 +1144,7 @@ bool CHyprOpenGLImpl::initShaders() {
|
||||
shaders->m_shSHADOW.range = glGetUniformLocation(prog, "range");
|
||||
shaders->m_shSHADOW.shadowPower = glGetUniformLocation(prog, "shadowPower");
|
||||
shaders->m_shSHADOW.color = glGetUniformLocation(prog, "color");
|
||||
shaders->m_shSHADOW.createVao();
|
||||
|
||||
prog = createProgram(m_cmSupported ? shaders->TEXVERTSRC300 : shaders->TEXVERTSRC, FRAGBORDER1, isDynamic);
|
||||
if (!prog)
|
||||
@ -1179,6 +1169,8 @@ bool CHyprOpenGLImpl::initShaders() {
|
||||
shaders->m_shBORDER1.angle2 = glGetUniformLocation(prog, "angle2");
|
||||
shaders->m_shBORDER1.gradientLerp = glGetUniformLocation(prog, "gradientLerp");
|
||||
shaders->m_shBORDER1.alpha = glGetUniformLocation(prog, "alpha");
|
||||
shaders->m_shBORDER1.createVao();
|
||||
|
||||
} catch (const std::exception& e) {
|
||||
if (!m_shadersInitialized)
|
||||
throw e;
|
||||
@ -1245,6 +1237,7 @@ void CHyprOpenGLImpl::applyScreenShader(const std::string& path) {
|
||||
}
|
||||
m_finalScreenShader.texAttrib = glGetAttribLocation(m_finalScreenShader.program, "texcoord");
|
||||
m_finalScreenShader.posAttrib = glGetAttribLocation(m_finalScreenShader.program, "pos");
|
||||
m_finalScreenShader.createVao();
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::clear(const CHyprColor& color) {
|
||||
@ -1373,14 +1366,8 @@ void CHyprOpenGLImpl::renderRectWithDamage(const CBox& box, const CHyprColor& co
|
||||
newBox, wlTransformToHyprutils(invertTransform(!m_endFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_renderData.pMonitor->m_transform)), newBox.rot);
|
||||
Mat3x3 glMatrix = m_renderData.projection.copy().multiply(matrix);
|
||||
|
||||
glUseProgram(m_shaders->m_shQUAD.program);
|
||||
|
||||
#ifndef GLES2
|
||||
useProgram(m_shaders->m_shQUAD.program);
|
||||
glUniformMatrix3fv(m_shaders->m_shQUAD.proj, 1, GL_TRUE, glMatrix.getMatrix().data());
|
||||
#else
|
||||
glMatrix.transpose();
|
||||
glUniformMatrix3fv(m_renderData.pCurrentMonData->m_shQUAD.proj, 1, GL_FALSE, glMatrix.getMatrix().data());
|
||||
#endif
|
||||
|
||||
// premultiply the color as well as we don't work with straight alpha
|
||||
glUniform4f(m_shaders->m_shQUAD.color, col.r * col.a, col.g * col.a, col.b * col.a, col.a);
|
||||
@ -1398,9 +1385,7 @@ void CHyprOpenGLImpl::renderRectWithDamage(const CBox& box, const CHyprColor& co
|
||||
glUniform1f(m_shaders->m_shQUAD.radius, round);
|
||||
glUniform1f(m_shaders->m_shQUAD.roundingPower, roundingPower);
|
||||
|
||||
glVertexAttribPointer(m_shaders->m_shQUAD.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
|
||||
glEnableVertexAttribArray(m_shaders->m_shQUAD.posAttrib);
|
||||
glBindVertexArray(m_shaders->m_shQUAD.shaderVao);
|
||||
|
||||
if (m_renderData.clipBox.width != 0 && m_renderData.clipBox.height != 0) {
|
||||
CRegion damageClip{m_renderData.clipBox.x, m_renderData.clipBox.y, m_renderData.clipBox.width, m_renderData.clipBox.height};
|
||||
@ -1419,7 +1404,7 @@ void CHyprOpenGLImpl::renderRectWithDamage(const CBox& box, const CHyprColor& co
|
||||
}
|
||||
}
|
||||
|
||||
glDisableVertexAttribArray(m_shaders->m_shQUAD.posAttrib);
|
||||
glBindVertexArray(0);
|
||||
|
||||
scissor(nullptr);
|
||||
}
|
||||
@ -1579,19 +1564,14 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP<CTexture> tex, const CB
|
||||
if (!skipCM && !usingFinalShader && (texType == TEXTURE_RGBA || texType == TEXTURE_RGBX))
|
||||
shader = &m_shaders->m_shCM;
|
||||
|
||||
glUseProgram(shader->program);
|
||||
useProgram(shader->program);
|
||||
|
||||
if (shader == &m_shaders->m_shCM) {
|
||||
glUniform1i(shader->texType, texType);
|
||||
passCMUniforms(*shader, imageDescription);
|
||||
}
|
||||
|
||||
#ifndef GLES2
|
||||
glUniformMatrix3fv(shader->proj, 1, GL_TRUE, glMatrix.getMatrix().data());
|
||||
#else
|
||||
glMatrix.transpose();
|
||||
glUniformMatrix3fv(shader->proj, 1, GL_FALSE, glMatrix.getMatrix().data());
|
||||
#endif
|
||||
glUniform1i(shader->tex, 0);
|
||||
|
||||
if ((usingFinalShader && *PDT == 0) || CRASHING) {
|
||||
@ -1653,22 +1633,20 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP<CTexture> tex, const CB
|
||||
glUniform1i(shader->applyTint, 0);
|
||||
}
|
||||
|
||||
const float verts[] = {
|
||||
m_renderData.primarySurfaceUVBottomRight.x, m_renderData.primarySurfaceUVTopLeft.y, // top right
|
||||
m_renderData.primarySurfaceUVTopLeft.x, m_renderData.primarySurfaceUVTopLeft.y, // top left
|
||||
m_renderData.primarySurfaceUVBottomRight.x, m_renderData.primarySurfaceUVBottomRight.y, // bottom right
|
||||
m_renderData.primarySurfaceUVTopLeft.x, m_renderData.primarySurfaceUVBottomRight.y, // bottom left
|
||||
glBindVertexArray(shader->shaderVao);
|
||||
if (allowCustomUV && m_renderData.primarySurfaceUVTopLeft != Vector2D(-1, -1)) {
|
||||
const float customUVs[] = {
|
||||
m_renderData.primarySurfaceUVBottomRight.x, m_renderData.primarySurfaceUVTopLeft.y, m_renderData.primarySurfaceUVTopLeft.x,
|
||||
m_renderData.primarySurfaceUVTopLeft.y, m_renderData.primarySurfaceUVBottomRight.x, m_renderData.primarySurfaceUVBottomRight.y,
|
||||
m_renderData.primarySurfaceUVTopLeft.x, m_renderData.primarySurfaceUVBottomRight.y,
|
||||
};
|
||||
|
||||
glVertexAttribPointer(shader->posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
|
||||
if (allowCustomUV && m_renderData.primarySurfaceUVTopLeft != Vector2D(-1, -1))
|
||||
glVertexAttribPointer(shader->texAttrib, 2, GL_FLOAT, GL_FALSE, 0, verts);
|
||||
else
|
||||
glVertexAttribPointer(shader->texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
|
||||
glEnableVertexAttribArray(shader->posAttrib);
|
||||
glEnableVertexAttribArray(shader->texAttrib);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, shader->shaderVboUv);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(customUVs), customUVs);
|
||||
} else {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, shader->shaderVboUv);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(fullVerts), fullVerts);
|
||||
}
|
||||
|
||||
if (!m_renderData.clipBox.empty() || !m_renderData.clipRegion.empty()) {
|
||||
CRegion damageClip = m_renderData.clipBox;
|
||||
@ -1693,9 +1671,8 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP<CTexture> tex, const CB
|
||||
}
|
||||
}
|
||||
|
||||
glDisableVertexAttribArray(shader->posAttrib);
|
||||
glDisableVertexAttribArray(shader->texAttrib);
|
||||
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindTexture(tex->m_target, 0);
|
||||
}
|
||||
|
||||
@ -1721,21 +1698,10 @@ void CHyprOpenGLImpl::renderTexturePrimitive(SP<CTexture> tex, const CBox& box)
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(tex->m_target, tex->m_texID);
|
||||
|
||||
glUseProgram(shader->program);
|
||||
|
||||
#ifndef GLES2
|
||||
useProgram(shader->program);
|
||||
glUniformMatrix3fv(shader->proj, 1, GL_TRUE, glMatrix.getMatrix().data());
|
||||
#else
|
||||
glMatrix.transpose();
|
||||
glUniformMatrix3fv(shader->proj, 1, GL_FALSE, glMatrix.getMatrix().data());
|
||||
#endif
|
||||
glUniform1i(shader->tex, 0);
|
||||
|
||||
glVertexAttribPointer(shader->posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
glVertexAttribPointer(shader->texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
|
||||
glEnableVertexAttribArray(shader->posAttrib);
|
||||
glEnableVertexAttribArray(shader->texAttrib);
|
||||
glBindVertexArray(shader->shaderVao);
|
||||
|
||||
for (auto const& RECT : m_renderData.damage.getRects()) {
|
||||
scissor(&RECT);
|
||||
@ -1744,9 +1710,7 @@ void CHyprOpenGLImpl::renderTexturePrimitive(SP<CTexture> tex, const CBox& box)
|
||||
|
||||
scissor(nullptr);
|
||||
|
||||
glDisableVertexAttribArray(shader->posAttrib);
|
||||
glDisableVertexAttribArray(shader->texAttrib);
|
||||
|
||||
glBindVertexArray(0);
|
||||
glBindTexture(tex->m_target, 0);
|
||||
}
|
||||
|
||||
@ -1769,14 +1733,8 @@ void CHyprOpenGLImpl::renderTextureMatte(SP<CTexture> tex, const CBox& box, CFra
|
||||
|
||||
SShader* shader = &m_shaders->m_shMATTE;
|
||||
|
||||
glUseProgram(shader->program);
|
||||
|
||||
#ifndef GLES2
|
||||
useProgram(shader->program);
|
||||
glUniformMatrix3fv(shader->proj, 1, GL_TRUE, glMatrix.getMatrix().data());
|
||||
#else
|
||||
glMatrix.transpose();
|
||||
glUniformMatrix3fv(shader->proj, 1, GL_FALSE, glMatrix.getMatrix().data());
|
||||
#endif
|
||||
glUniform1i(shader->tex, 0);
|
||||
glUniform1i(shader->alphaMatte, 1);
|
||||
|
||||
@ -1787,11 +1745,7 @@ void CHyprOpenGLImpl::renderTextureMatte(SP<CTexture> tex, const CBox& box, CFra
|
||||
auto matteTex = matte.getTexture();
|
||||
glBindTexture(matteTex->m_target, matteTex->m_texID);
|
||||
|
||||
glVertexAttribPointer(shader->posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
glVertexAttribPointer(shader->texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
|
||||
glEnableVertexAttribArray(shader->posAttrib);
|
||||
glEnableVertexAttribArray(shader->texAttrib);
|
||||
glBindVertexArray(shader->shaderVao);
|
||||
|
||||
for (auto const& RECT : m_renderData.damage.getRects()) {
|
||||
scissor(&RECT);
|
||||
@ -1800,9 +1754,7 @@ void CHyprOpenGLImpl::renderTextureMatte(SP<CTexture> tex, const CBox& box, CFra
|
||||
|
||||
scissor(nullptr);
|
||||
|
||||
glDisableVertexAttribArray(shader->posAttrib);
|
||||
glDisableVertexAttribArray(shader->texAttrib);
|
||||
|
||||
glBindVertexArray(0);
|
||||
glBindTexture(tex->m_target, 0);
|
||||
}
|
||||
|
||||
@ -1811,13 +1763,16 @@ void CHyprOpenGLImpl::renderTextureMatte(SP<CTexture> tex, const CBox& box, CFra
|
||||
//
|
||||
// Dual (or more) kawase blur
|
||||
CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* originalDamage) {
|
||||
|
||||
if (!m_renderData.currentFB->getTexture()) {
|
||||
Debug::log(ERR, "BUG THIS: null fb texture while attempting to blur main fb?! (introspection off?!)");
|
||||
return &m_renderData.pCurrentMonData->mirrorFB; // return something to sample from at least
|
||||
}
|
||||
|
||||
TRACY_GPU_ZONE("RenderBlurMainFramebufferWithDamage");
|
||||
return blurFramebufferWithDamage(a, originalDamage, *m_renderData.currentFB);
|
||||
}
|
||||
|
||||
CFramebuffer* CHyprOpenGLImpl::blurFramebufferWithDamage(float a, CRegion* originalDamage, CFramebuffer& source) {
|
||||
TRACY_GPU_ZONE("RenderBlurFramebufferWithDamage");
|
||||
|
||||
const auto BLENDBEFORE = m_blend;
|
||||
blend(false);
|
||||
@ -1857,13 +1812,13 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
auto currentTex = m_renderData.currentFB->getTexture();
|
||||
auto currentTex = source.getTexture();
|
||||
|
||||
glBindTexture(currentTex->m_target, currentTex->m_texID);
|
||||
|
||||
glTexParameteri(currentTex->m_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
glUseProgram(m_shaders->m_shBLURPREPARE.program);
|
||||
useProgram(m_shaders->m_shBLURPREPARE.program);
|
||||
|
||||
// From FB to sRGB
|
||||
const bool skipCM = !m_cmSupported || m_renderData.pMonitor->m_imageDescription == SImageDescription{};
|
||||
@ -1882,21 +1837,12 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o
|
||||
1.0f);
|
||||
}
|
||||
|
||||
#ifndef GLES2
|
||||
glUniformMatrix3fv(m_shaders->m_shBLURPREPARE.proj, 1, GL_TRUE, glMatrix.getMatrix().data());
|
||||
#else
|
||||
glMatrix.transpose();
|
||||
glUniformMatrix3fv(m_shaders->m_shBLURPREPARE.proj, 1, GL_FALSE, glMatrix.getMatrix().data());
|
||||
#endif
|
||||
glUniform1f(m_shaders->m_shBLURPREPARE.contrast, *PBLURCONTRAST);
|
||||
glUniform1f(m_shaders->m_shBLURPREPARE.brightness, *PBLURBRIGHTNESS);
|
||||
glUniform1i(m_shaders->m_shBLURPREPARE.tex, 0);
|
||||
|
||||
glVertexAttribPointer(m_shaders->m_shBLURPREPARE.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
glVertexAttribPointer(m_shaders->m_shBLURPREPARE.texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
|
||||
glEnableVertexAttribArray(m_shaders->m_shBLURPREPARE.posAttrib);
|
||||
glEnableVertexAttribArray(m_shaders->m_shBLURPREPARE.texAttrib);
|
||||
glBindVertexArray(m_shaders->m_shBLURPREPARE.shaderVao);
|
||||
|
||||
if (!damage.empty()) {
|
||||
for (auto const& RECT : damage.getRects()) {
|
||||
@ -1905,9 +1851,7 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o
|
||||
}
|
||||
}
|
||||
|
||||
glDisableVertexAttribArray(m_shaders->m_shBLURPREPARE.posAttrib);
|
||||
glDisableVertexAttribArray(m_shaders->m_shBLURPREPARE.texAttrib);
|
||||
|
||||
glBindVertexArray(0);
|
||||
currentRenderToFB = PMIRRORSWAPFB;
|
||||
}
|
||||
|
||||
@ -1926,15 +1870,10 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o
|
||||
|
||||
glTexParameteri(currentTex->m_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
glUseProgram(pShader->program);
|
||||
useProgram(pShader->program);
|
||||
|
||||
// prep two shaders
|
||||
#ifndef GLES2
|
||||
glUniformMatrix3fv(pShader->proj, 1, GL_TRUE, glMatrix.getMatrix().data());
|
||||
#else
|
||||
glMatrix.transpose();
|
||||
glUniformMatrix3fv(pShader->proj, 1, GL_FALSE, glMatrix.getMatrix().data());
|
||||
#endif
|
||||
glUniform1f(pShader->radius, *PBLURSIZE * a); // this makes the blursize change with a
|
||||
if (pShader == &m_shaders->m_shBLUR1) {
|
||||
glUniform2f(m_shaders->m_shBLUR1.halfpixel, 0.5f / (m_renderData.pMonitor->m_pixelSize.x / 2.f), 0.5f / (m_renderData.pMonitor->m_pixelSize.y / 2.f));
|
||||
@ -1945,12 +1884,7 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o
|
||||
glUniform2f(m_shaders->m_shBLUR2.halfpixel, 0.5f / (m_renderData.pMonitor->m_pixelSize.x * 2.f), 0.5f / (m_renderData.pMonitor->m_pixelSize.y * 2.f));
|
||||
glUniform1i(pShader->tex, 0);
|
||||
|
||||
glVertexAttribPointer(pShader->posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
glVertexAttribPointer(pShader->texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
|
||||
glEnableVertexAttribArray(pShader->posAttrib);
|
||||
glEnableVertexAttribArray(pShader->texAttrib);
|
||||
|
||||
glBindVertexArray(pShader->shaderVao);
|
||||
if (!pDamage->empty()) {
|
||||
for (auto const& RECT : pDamage->getRects()) {
|
||||
scissor(&RECT, false /* this region is already transformed */);
|
||||
@ -1958,8 +1892,7 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o
|
||||
}
|
||||
}
|
||||
|
||||
glDisableVertexAttribArray(pShader->posAttrib);
|
||||
glDisableVertexAttribArray(pShader->texAttrib);
|
||||
glBindVertexArray(0);
|
||||
|
||||
if (currentRenderToFB != PMIRRORFB)
|
||||
currentRenderToFB = PMIRRORFB;
|
||||
@ -2004,24 +1937,14 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o
|
||||
|
||||
glTexParameteri(currentTex->m_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
glUseProgram(m_shaders->m_shBLURFINISH.program);
|
||||
|
||||
#ifndef GLES2
|
||||
useProgram(m_shaders->m_shBLURFINISH.program);
|
||||
glUniformMatrix3fv(m_shaders->m_shBLURFINISH.proj, 1, GL_TRUE, glMatrix.getMatrix().data());
|
||||
#else
|
||||
glMatrix.transpose();
|
||||
glUniformMatrix3fv(m_shaders->m_shBLURFINISH.proj, 1, GL_FALSE, glMatrix.getMatrix().data());
|
||||
#endif
|
||||
glUniform1f(m_shaders->m_shBLURFINISH.noise, *PBLURNOISE);
|
||||
glUniform1f(m_shaders->m_shBLURFINISH.brightness, *PBLURBRIGHTNESS);
|
||||
|
||||
glUniform1i(m_shaders->m_shBLURFINISH.tex, 0);
|
||||
|
||||
glVertexAttribPointer(m_shaders->m_shBLURFINISH.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
glVertexAttribPointer(m_shaders->m_shBLURFINISH.texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
|
||||
glEnableVertexAttribArray(m_shaders->m_shBLURFINISH.posAttrib);
|
||||
glEnableVertexAttribArray(m_shaders->m_shBLURFINISH.texAttrib);
|
||||
glBindVertexArray(m_shaders->m_shBLURFINISH.shaderVao);
|
||||
|
||||
if (!damage.empty()) {
|
||||
for (auto const& RECT : damage.getRects()) {
|
||||
@ -2030,8 +1953,7 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o
|
||||
}
|
||||
}
|
||||
|
||||
glDisableVertexAttribArray(m_shaders->m_shBLURFINISH.posAttrib);
|
||||
glDisableVertexAttribArray(m_shaders->m_shBLURFINISH.texAttrib);
|
||||
glBindVertexArray(0);
|
||||
|
||||
if (currentRenderToFB != PMIRRORFB)
|
||||
currentRenderToFB = PMIRRORFB;
|
||||
@ -2224,7 +2146,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP<CTexture> tex, const CBox& box, f
|
||||
|
||||
// amazing hack: the surface has an opaque region!
|
||||
CRegion inverseOpaque;
|
||||
if (a >= 1.f && std::round(pSurface->m_current.size.x * m_renderData.pMonitor->m_scale) == box.w &&
|
||||
if (a >= 1.f && pSurface && std::round(pSurface->m_current.size.x * m_renderData.pMonitor->m_scale) == box.w &&
|
||||
std::round(pSurface->m_current.size.y * m_renderData.pMonitor->m_scale) == box.h) {
|
||||
pixman_box32_t surfbox = {0, 0, pSurface->m_current.size.x * pSurface->m_current.scale, pSurface->m_current.size.y * pSurface->m_current.scale};
|
||||
inverseOpaque = pSurface->m_current.opaque;
|
||||
@ -2247,7 +2169,6 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP<CTexture> tex, const CBox& box, f
|
||||
inverseOpaque.translate(box.pos());
|
||||
m_renderData.renderModif.applyToRegion(inverseOpaque);
|
||||
inverseOpaque.intersect(texDamage);
|
||||
|
||||
POUTFB = blurMainFramebufferWithDamage(a, &inverseOpaque);
|
||||
} else
|
||||
POUTFB = &m_renderData.pCurrentMonData->blurFB;
|
||||
@ -2348,20 +2269,14 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& gr
|
||||
const auto BLEND = m_blend;
|
||||
blend(true);
|
||||
|
||||
glUseProgram(m_shaders->m_shBORDER1.program);
|
||||
useProgram(m_shaders->m_shBORDER1.program);
|
||||
|
||||
const bool skipCM = !m_cmSupported || m_renderData.pMonitor->m_imageDescription == SImageDescription{};
|
||||
glUniform1i(m_shaders->m_shBORDER1.skipCM, skipCM);
|
||||
if (!skipCM)
|
||||
passCMUniforms(m_shaders->m_shBORDER1, SImageDescription{});
|
||||
|
||||
#ifndef GLES2
|
||||
glUniformMatrix3fv(m_shaders->m_shBORDER1.proj, 1, GL_TRUE, glMatrix.getMatrix().data());
|
||||
#else
|
||||
glMatrix.transpose();
|
||||
glUniformMatrix3fv(m_shaders->m_shBORDER1.proj, 1, GL_FALSE, glMatrix.getMatrix().data());
|
||||
#endif
|
||||
|
||||
glUniform4fv(m_shaders->m_shBORDER1.gradient, grad.m_colorsOkLabA.size() / 4, (float*)grad.m_colorsOkLabA.data());
|
||||
glUniform1i(m_shaders->m_shBORDER1.gradientLength, grad.m_colorsOkLabA.size() / 4);
|
||||
glUniform1f(m_shaders->m_shBORDER1.angle, (int)(grad.m_angle / (PI / 180.0)) % 360 * (PI / 180.0));
|
||||
@ -2383,11 +2298,7 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& gr
|
||||
glUniform1f(m_shaders->m_shBORDER1.roundingPower, roundingPower);
|
||||
glUniform1f(m_shaders->m_shBORDER1.thick, scaledBorderSize);
|
||||
|
||||
glVertexAttribPointer(m_shaders->m_shBORDER1.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
glVertexAttribPointer(m_shaders->m_shBORDER1.texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
|
||||
glEnableVertexAttribArray(m_shaders->m_shBORDER1.posAttrib);
|
||||
glEnableVertexAttribArray(m_shaders->m_shBORDER1.texAttrib);
|
||||
glBindVertexArray(m_shaders->m_shBORDER1.shaderVao);
|
||||
|
||||
if (m_renderData.clipBox.width != 0 && m_renderData.clipBox.height != 0) {
|
||||
CRegion damageClip{m_renderData.clipBox.x, m_renderData.clipBox.y, m_renderData.clipBox.width, m_renderData.clipBox.height};
|
||||
@ -2406,8 +2317,7 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& gr
|
||||
}
|
||||
}
|
||||
|
||||
glDisableVertexAttribArray(m_shaders->m_shBORDER1.posAttrib);
|
||||
glDisableVertexAttribArray(m_shaders->m_shBORDER1.texAttrib);
|
||||
glBindVertexArray(0);
|
||||
|
||||
blend(BLEND);
|
||||
}
|
||||
@ -2446,15 +2356,8 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& gr
|
||||
const auto BLEND = m_blend;
|
||||
blend(true);
|
||||
|
||||
glUseProgram(m_shaders->m_shBORDER1.program);
|
||||
|
||||
#ifndef GLES2
|
||||
useProgram(m_shaders->m_shBORDER1.program);
|
||||
glUniformMatrix3fv(m_shaders->m_shBORDER1.proj, 1, GL_TRUE, glMatrix.getMatrix().data());
|
||||
#else
|
||||
glMatrix.transpose();
|
||||
glUniformMatrix3fv(m_shaders->m_shBORDER1.proj, 1, GL_FALSE, glMatrix.getMatrix().data());
|
||||
#endif
|
||||
|
||||
glUniform4fv(m_shaders->m_shBORDER1.gradient, grad1.m_colorsOkLabA.size() / 4, (float*)grad1.m_colorsOkLabA.data());
|
||||
glUniform1i(m_shaders->m_shBORDER1.gradientLength, grad1.m_colorsOkLabA.size() / 4);
|
||||
glUniform1f(m_shaders->m_shBORDER1.angle, (int)(grad1.m_angle / (PI / 180.0)) % 360 * (PI / 180.0));
|
||||
@ -2480,11 +2383,7 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& gr
|
||||
glUniform1f(m_shaders->m_shBORDER1.roundingPower, roundingPower);
|
||||
glUniform1f(m_shaders->m_shBORDER1.thick, scaledBorderSize);
|
||||
|
||||
glVertexAttribPointer(m_shaders->m_shBORDER1.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
glVertexAttribPointer(m_shaders->m_shBORDER1.texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
|
||||
glEnableVertexAttribArray(m_shaders->m_shBORDER1.posAttrib);
|
||||
glEnableVertexAttribArray(m_shaders->m_shBORDER1.texAttrib);
|
||||
glBindVertexArray(m_shaders->m_shBORDER1.shaderVao);
|
||||
|
||||
if (m_renderData.clipBox.width != 0 && m_renderData.clipBox.height != 0) {
|
||||
CRegion damageClip{m_renderData.clipBox.x, m_renderData.clipBox.y, m_renderData.clipBox.width, m_renderData.clipBox.height};
|
||||
@ -2503,9 +2402,7 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& gr
|
||||
}
|
||||
}
|
||||
|
||||
glDisableVertexAttribArray(m_shaders->m_shBORDER1.posAttrib);
|
||||
glDisableVertexAttribArray(m_shaders->m_shBORDER1.texAttrib);
|
||||
|
||||
glBindVertexArray(0);
|
||||
blend(BLEND);
|
||||
}
|
||||
|
||||
@ -2534,18 +2431,13 @@ void CHyprOpenGLImpl::renderRoundedShadow(const CBox& box, int round, float roun
|
||||
|
||||
blend(true);
|
||||
|
||||
glUseProgram(m_shaders->m_shSHADOW.program);
|
||||
useProgram(m_shaders->m_shSHADOW.program);
|
||||
const bool skipCM = !m_cmSupported || m_renderData.pMonitor->m_imageDescription == SImageDescription{};
|
||||
glUniform1i(m_shaders->m_shSHADOW.skipCM, skipCM);
|
||||
if (!skipCM)
|
||||
passCMUniforms(m_shaders->m_shSHADOW, SImageDescription{});
|
||||
|
||||
#ifndef GLES2
|
||||
glUniformMatrix3fv(m_shaders->m_shSHADOW.proj, 1, GL_TRUE, glMatrix.getMatrix().data());
|
||||
#else
|
||||
glMatrix.transpose();
|
||||
glUniformMatrix3fv(m_shaders->m_shSHADOW.proj, 1, GL_FALSE, glMatrix.getMatrix().data());
|
||||
#endif
|
||||
glUniform4f(m_shaders->m_shSHADOW.color, col.r, col.g, col.b, col.a * a);
|
||||
|
||||
const auto TOPLEFT = Vector2D(range + round, range + round);
|
||||
@ -2561,11 +2453,7 @@ void CHyprOpenGLImpl::renderRoundedShadow(const CBox& box, int round, float roun
|
||||
glUniform1f(m_shaders->m_shSHADOW.range, range);
|
||||
glUniform1f(m_shaders->m_shSHADOW.shadowPower, SHADOWPOWER);
|
||||
|
||||
glVertexAttribPointer(m_shaders->m_shSHADOW.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
glVertexAttribPointer(m_shaders->m_shSHADOW.texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
|
||||
glEnableVertexAttribArray(m_shaders->m_shSHADOW.posAttrib);
|
||||
glEnableVertexAttribArray(m_shaders->m_shSHADOW.texAttrib);
|
||||
glBindVertexArray(m_shaders->m_shSHADOW.shaderVao);
|
||||
|
||||
if (m_renderData.clipBox.width != 0 && m_renderData.clipBox.height != 0) {
|
||||
CRegion damageClip{m_renderData.clipBox.x, m_renderData.clipBox.y, m_renderData.clipBox.width, m_renderData.clipBox.height};
|
||||
@ -2584,8 +2472,7 @@ void CHyprOpenGLImpl::renderRoundedShadow(const CBox& box, int round, float roun
|
||||
}
|
||||
}
|
||||
|
||||
glDisableVertexAttribArray(m_shaders->m_shSHADOW.posAttrib);
|
||||
glDisableVertexAttribArray(m_shaders->m_shSHADOW.texAttrib);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::saveBufferForMirror(const CBox& box) {
|
||||
@ -2705,13 +2592,7 @@ SP<CTexture> CHyprOpenGLImpl::loadAsset(const std::string& filename) {
|
||||
tex->allocate();
|
||||
tex->m_size = {cairo_image_surface_get_width(CAIROSURFACE), cairo_image_surface_get_height(CAIROSURFACE)};
|
||||
|
||||
const GLint glIFormat = CAIROFORMAT == CAIRO_FORMAT_RGB96F ?
|
||||
#ifdef GLES2
|
||||
GL_RGB32F_EXT :
|
||||
#else
|
||||
GL_RGB32F :
|
||||
#endif
|
||||
GL_RGBA;
|
||||
const GLint glIFormat = CAIROFORMAT == CAIRO_FORMAT_RGB96F ? GL_RGB32F : GL_RGBA;
|
||||
const GLint glFormat = CAIROFORMAT == CAIRO_FORMAT_RGB96F ? GL_RGB : GL_RGBA;
|
||||
const GLint glType = CAIROFORMAT == CAIRO_FORMAT_RGB96F ? GL_FLOAT : GL_UNSIGNED_BYTE;
|
||||
|
||||
@ -2719,12 +2600,12 @@ SP<CTexture> CHyprOpenGLImpl::loadAsset(const std::string& filename) {
|
||||
glBindTexture(GL_TEXTURE_2D, tex->m_texID);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
#ifndef GLES2
|
||||
|
||||
if (CAIROFORMAT != CAIRO_FORMAT_RGB96F) {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
|
||||
}
|
||||
#endif
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, glIFormat, tex->m_size.x, tex->m_size.y, 0, glFormat, glType, DATA);
|
||||
|
||||
cairo_surface_destroy(CAIROSURFACE);
|
||||
@ -2802,10 +2683,8 @@ SP<CTexture> CHyprOpenGLImpl::renderText(const std::string& text, CHyprColor col
|
||||
glBindTexture(GL_TEXTURE_2D, tex->m_texID);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
#ifndef GLES2
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
|
||||
#endif
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex->m_size.x, tex->m_size.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA);
|
||||
|
||||
cairo_destroy(CAIRO);
|
||||
@ -2845,10 +2724,8 @@ void CHyprOpenGLImpl::initMissingAssetTexture() {
|
||||
glBindTexture(GL_TEXTURE_2D, tex->m_texID);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
#ifndef GLES2
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
|
||||
#endif
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, glFormat, tex->m_size.x, tex->m_size.y, 0, glFormat, glType, DATA);
|
||||
|
||||
cairo_surface_destroy(CAIROSURFACE);
|
||||
@ -2857,6 +2734,14 @@ void CHyprOpenGLImpl::initMissingAssetTexture() {
|
||||
m_missingAssetTexture = tex;
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::useProgram(GLuint prog) {
|
||||
if (m_currentProgram == prog)
|
||||
return;
|
||||
|
||||
glUseProgram(prog);
|
||||
m_currentProgram = prog;
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::initAssets() {
|
||||
initMissingAssetTexture();
|
||||
|
||||
@ -2950,10 +2835,8 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(PHLMONITOR pMonitor) {
|
||||
glBindTexture(GL_TEXTURE_2D, tex->m_texID);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
#ifndef GLES2
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
|
||||
#endif
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, glFormat, tex->m_size.x, tex->m_size.y, 0, glFormat, glType, DATA);
|
||||
|
||||
cairo_surface_destroy(CAIROSURFACE);
|
||||
|
@ -119,6 +119,7 @@ struct SCurrentRenderData {
|
||||
Mat3x3 savedProjection;
|
||||
Mat3x3 monitorProjection;
|
||||
|
||||
// FIXME: raw pointer galore!
|
||||
SMonitorRenderData* pCurrentMonData = nullptr;
|
||||
CFramebuffer* currentFB = nullptr; // current rendering to
|
||||
CFramebuffer* mainFB = nullptr; // main to render to
|
||||
@ -239,6 +240,11 @@ class CHyprOpenGLImpl {
|
||||
EGLImageKHR createEGLImage(const Aquamarine::SDMABUFAttrs& attrs);
|
||||
|
||||
bool initShaders();
|
||||
|
||||
GLuint createProgram(const std::string&, const std::string&, bool dynamic = false, bool silent = false);
|
||||
GLuint compileShader(const GLuint&, std::string, bool dynamic = false, bool silent = false);
|
||||
void useProgram(GLuint prog);
|
||||
|
||||
bool m_shadersInitialized = false;
|
||||
SP<SPreparedShaders> m_shaders;
|
||||
|
||||
@ -311,6 +317,7 @@ class CHyprOpenGLImpl {
|
||||
|
||||
SShader m_finalScreenShader;
|
||||
CTimer m_globalTimer;
|
||||
GLuint m_currentProgram;
|
||||
|
||||
SP<CTexture> m_missingAssetTexture;
|
||||
SP<CTexture> m_backgroundTexture;
|
||||
@ -319,8 +326,6 @@ class CHyprOpenGLImpl {
|
||||
SP<CTexture> m_lockTtyTextTexture; // TODO: don't always load lock
|
||||
|
||||
void logShaderError(const GLuint&, bool program = false, bool silent = false);
|
||||
GLuint createProgram(const std::string&, const std::string&, bool dynamic = false, bool silent = false);
|
||||
GLuint compileShader(const GLuint&, std::string, bool dynamic = false, bool silent = false);
|
||||
void createBGTextureForMonitor(PHLMONITOR);
|
||||
void initDRMFormats();
|
||||
void initEGL(bool gbm);
|
||||
@ -333,6 +338,7 @@ class CHyprOpenGLImpl {
|
||||
|
||||
// returns the out FB, can be either Mirror or MirrorSwap
|
||||
CFramebuffer* blurMainFramebufferWithDamage(float a, CRegion* damage);
|
||||
CFramebuffer* blurFramebufferWithDamage(float a, CRegion* damage, CFramebuffer& source);
|
||||
|
||||
void passCMUniforms(const SShader&, const NColorManagement::SImageDescription& imageDescription, const NColorManagement::SImageDescription& targetImageDescription,
|
||||
bool modifySDR = false);
|
||||
|
@ -175,7 +175,7 @@ bool CHyprRenderer::shouldRenderWindow(PHLWINDOW pWindow, PHLMONITOR pMonitor) {
|
||||
return false;
|
||||
|
||||
if (!pWindow->m_workspace && pWindow->m_fadingOut)
|
||||
return pWindow->workspaceID() == pMonitor->activeWorkspaceID();
|
||||
return pWindow->workspaceID() == pMonitor->activeWorkspaceID() || pWindow->workspaceID() == pMonitor->activeSpecialWorkspaceID();
|
||||
|
||||
if (pWindow->m_pinned)
|
||||
return true;
|
||||
@ -493,7 +493,6 @@ void CHyprRenderer::renderWindow(PHLWINDOW pWindow, PHLMONITOR pMonitor, const T
|
||||
|
||||
// whether to use m_fMovingToWorkspaceAlpha, only if fading out into an invisible ws
|
||||
const bool USE_WORKSPACE_FADE_ALPHA = pWindow->m_monitorMovedFrom != -1 && (!PWORKSPACE || !PWORKSPACE->isVisible());
|
||||
const bool DONT_BLUR = pWindow->m_windowData.noBlur.valueOrDefault() || pWindow->m_windowData.RGBX.valueOrDefault() || pWindow->opaque();
|
||||
|
||||
renderdata.surface = pWindow->m_wlSurface->resource();
|
||||
renderdata.dontRound = pWindow->isEffectiveInternalFSMode(FSMODE_FULLSCREEN) || pWindow->m_windowData.noRounding.valueOrDefault();
|
||||
@ -503,7 +502,7 @@ void CHyprRenderer::renderWindow(PHLWINDOW pWindow, PHLMONITOR pMonitor, const T
|
||||
renderdata.decorate = decorate && !pWindow->m_X11DoesntWantBorders && !pWindow->isEffectiveInternalFSMode(FSMODE_FULLSCREEN);
|
||||
renderdata.rounding = standalone || renderdata.dontRound ? 0 : pWindow->rounding() * pMonitor->m_scale;
|
||||
renderdata.roundingPower = standalone || renderdata.dontRound ? 2.0f : pWindow->roundingPower();
|
||||
renderdata.blur = !standalone && *PBLUR && !DONT_BLUR;
|
||||
renderdata.blur = !standalone && shouldBlur(pWindow);
|
||||
renderdata.pWindow = pWindow;
|
||||
|
||||
if (standalone) {
|
||||
@ -572,7 +571,7 @@ void CHyprRenderer::renderWindow(PHLWINDOW pWindow, PHLMONITOR pMonitor, const T
|
||||
if ((pWindow->m_isX11 && *PXWLUSENN) || pWindow->m_windowData.nearestNeighbor.valueOrDefault())
|
||||
renderdata.useNearestNeighbor = true;
|
||||
|
||||
if (!pWindow->m_windowData.noBlur.valueOrDefault() && pWindow->m_wlSurface->small() && !pWindow->m_wlSurface->m_fillIgnoreSmall && renderdata.blur && *PBLUR) {
|
||||
if (pWindow->m_wlSurface->small() && !pWindow->m_wlSurface->m_fillIgnoreSmall && renderdata.blur) {
|
||||
CBox wb = {renderdata.pos.x - pMonitor->m_position.x, renderdata.pos.y - pMonitor->m_position.y, renderdata.w, renderdata.h};
|
||||
wb.scale(pMonitor->m_scale).round();
|
||||
CRectPassElement::SRectData data;
|
||||
@ -712,8 +711,6 @@ void CHyprRenderer::renderLayer(PHLLS pLayer, PHLMONITOR pMonitor, const Time::s
|
||||
return;
|
||||
}
|
||||
|
||||
static auto PBLUR = CConfigValue<Hyprlang::INT>("decoration:blur:enabled");
|
||||
|
||||
TRACY_GPU_ZONE("RenderLayer");
|
||||
|
||||
const auto REALPOS = pLayer->m_realPosition->value();
|
||||
@ -721,7 +718,7 @@ void CHyprRenderer::renderLayer(PHLLS pLayer, PHLMONITOR pMonitor, const Time::s
|
||||
|
||||
CSurfacePassElement::SRenderData renderdata = {pMonitor, time, REALPOS};
|
||||
renderdata.fadeAlpha = pLayer->m_alpha->value();
|
||||
renderdata.blur = pLayer->m_forceBlur && *PBLUR;
|
||||
renderdata.blur = shouldBlur(pLayer);
|
||||
renderdata.surface = pLayer->m_surface->resource();
|
||||
renderdata.decorate = false;
|
||||
renderdata.w = REALSIZ.x;
|
||||
@ -874,12 +871,15 @@ void CHyprRenderer::renderAllClientsForWorkspace(PHLMONITOR pMonitor, PHLWORKSPA
|
||||
for (auto const& ls : pMonitor->m_layerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]) {
|
||||
renderLayer(ls.lock(), pMonitor, time);
|
||||
}
|
||||
|
||||
for (auto const& ls : pMonitor->m_layerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]) {
|
||||
renderLayer(ls.lock(), pMonitor, time);
|
||||
}
|
||||
|
||||
for (auto const& ls : pMonitor->m_layerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]) {
|
||||
renderLayer(ls.lock(), pMonitor, time);
|
||||
}
|
||||
|
||||
for (auto const& ls : pMonitor->m_layerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]) {
|
||||
renderLayer(ls.lock(), pMonitor, time);
|
||||
}
|
||||
@ -896,6 +896,7 @@ void CHyprRenderer::renderAllClientsForWorkspace(PHLMONITOR pMonitor, PHLWORKSPA
|
||||
for (auto const& ls : pMonitor->m_layerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]) {
|
||||
renderLayer(ls.lock(), pMonitor, time);
|
||||
}
|
||||
|
||||
for (auto const& ls : pMonitor->m_layerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]) {
|
||||
renderLayer(ls.lock(), pMonitor, time);
|
||||
}
|
||||
@ -940,9 +941,9 @@ void CHyprRenderer::renderAllClientsForWorkspace(PHLMONITOR pMonitor, PHLWORKSPA
|
||||
// special
|
||||
for (auto const& ws : g_pCompositor->m_workspaces) {
|
||||
if (ws->m_alpha->value() > 0.f && ws->m_isSpecialWorkspace) {
|
||||
if (ws->m_hasFullscreenWindow)
|
||||
if (ws->m_hasFullscreenWindow) {
|
||||
renderWorkspaceWindowsFullscreen(pMonitor, ws, time);
|
||||
else
|
||||
} else
|
||||
renderWorkspaceWindows(pMonitor, ws, time);
|
||||
}
|
||||
}
|
||||
@ -1036,7 +1037,7 @@ void CHyprRenderer::renderSessionLockMissing(PHLMONITOR pMonitor) {
|
||||
// also render text for the tty number
|
||||
if (g_pHyprOpenGL->m_lockTtyTextTexture) {
|
||||
CBox texbox = {{}, g_pHyprOpenGL->m_lockTtyTextTexture->m_size};
|
||||
g_pHyprOpenGL->renderTexture(g_pHyprOpenGL->m_lockTtyTextTexture, texbox, 1.F);
|
||||
g_pHyprOpenGL->renderTexture(g_pHyprOpenGL->m_lockTtyTextTexture, texbox, ALPHA);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2279,9 +2280,6 @@ void CHyprRenderer::endRender(const std::function<void()>& renderingDoneCallback
|
||||
g_pHyprOpenGL->m_renderData.mouseZoomUseMouse = true;
|
||||
}
|
||||
|
||||
// send all queued opengl commands so rendering starts happening immediately
|
||||
glFlush();
|
||||
|
||||
if (m_renderMode == RENDER_MODE_FULL_FAKE)
|
||||
return;
|
||||
|
||||
@ -2389,7 +2387,7 @@ void CHyprRenderer::makeRawWindowSnapshot(PHLWINDOW pWindow, CFramebuffer* pFram
|
||||
|
||||
makeEGLCurrent();
|
||||
|
||||
pFramebuffer->alloc(PMONITOR->m_pixelSize.x, PMONITOR->m_pixelSize.y, PMONITOR->m_output->state->state().drmFormat);
|
||||
pFramebuffer->alloc(PMONITOR->m_pixelSize.x, PMONITOR->m_pixelSize.y, DRM_FORMAT_ABGR8888);
|
||||
pFramebuffer->addStencil(g_pHyprOpenGL->m_renderData.pCurrentMonData->stencilTex);
|
||||
|
||||
beginRender(PMONITOR, fakeDamage, RENDER_MODE_FULL_FAKE, nullptr, pFramebuffer);
|
||||
@ -2440,7 +2438,7 @@ void CHyprRenderer::makeWindowSnapshot(PHLWINDOW pWindow) {
|
||||
|
||||
const auto PFRAMEBUFFER = &g_pHyprOpenGL->m_windowFramebuffers[ref];
|
||||
|
||||
PFRAMEBUFFER->alloc(PMONITOR->m_pixelSize.x, PMONITOR->m_pixelSize.y, PMONITOR->m_output->state->state().drmFormat);
|
||||
PFRAMEBUFFER->alloc(PMONITOR->m_pixelSize.x, PMONITOR->m_pixelSize.y, DRM_FORMAT_ABGR8888);
|
||||
|
||||
beginRender(PMONITOR, fakeDamage, RENDER_MODE_FULL_FAKE, nullptr, PFRAMEBUFFER);
|
||||
|
||||
@ -2448,21 +2446,8 @@ void CHyprRenderer::makeWindowSnapshot(PHLWINDOW pWindow) {
|
||||
|
||||
g_pHyprOpenGL->clear(CHyprColor(0, 0, 0, 0)); // JIC
|
||||
|
||||
// this is a hack but it works :P
|
||||
// we need to disable blur or else we will get a black background, as the shader
|
||||
// will try to copy the bg to apply blur.
|
||||
// this isn't entirely correct, but like, oh well.
|
||||
// small todo: maybe make this correct? :P
|
||||
static auto* const PBLUR = (Hyprlang::INT* const*)(g_pConfigManager->getConfigValuePtr("decoration:blur:enabled"));
|
||||
const auto BLURVAL = **PBLUR;
|
||||
**PBLUR = 0;
|
||||
|
||||
g_pHyprOpenGL->clear(CHyprColor(0, 0, 0, 0)); // JIC
|
||||
|
||||
renderWindow(pWindow, PMONITOR, Time::steadyNow(), !pWindow->m_X11DoesntWantBorders, RENDER_PASS_ALL);
|
||||
|
||||
**PBLUR = BLURVAL;
|
||||
|
||||
endRender();
|
||||
|
||||
m_bRenderingSnapshot = false;
|
||||
@ -2484,7 +2469,7 @@ void CHyprRenderer::makeLayerSnapshot(PHLLS pLayer) {
|
||||
|
||||
const auto PFRAMEBUFFER = &g_pHyprOpenGL->m_layerFramebuffers[pLayer];
|
||||
|
||||
PFRAMEBUFFER->alloc(PMONITOR->m_pixelSize.x, PMONITOR->m_pixelSize.y, PMONITOR->m_output->state->state().drmFormat);
|
||||
PFRAMEBUFFER->alloc(PMONITOR->m_pixelSize.x, PMONITOR->m_pixelSize.y, DRM_FORMAT_ABGR8888);
|
||||
|
||||
beginRender(PMONITOR, fakeDamage, RENDER_MODE_FULL_FAKE, nullptr, PFRAMEBUFFER);
|
||||
|
||||
@ -2492,14 +2477,9 @@ void CHyprRenderer::makeLayerSnapshot(PHLLS pLayer) {
|
||||
|
||||
g_pHyprOpenGL->clear(CHyprColor(0, 0, 0, 0)); // JIC
|
||||
|
||||
const auto BLURLSSTATUS = pLayer->m_forceBlur;
|
||||
pLayer->m_forceBlur = false;
|
||||
|
||||
// draw the layer
|
||||
renderLayer(pLayer, PMONITOR, Time::steadyNow());
|
||||
|
||||
pLayer->m_forceBlur = BLURLSSTATUS;
|
||||
|
||||
endRender();
|
||||
|
||||
m_bRenderingSnapshot = false;
|
||||
@ -2534,14 +2514,25 @@ void CHyprRenderer::renderSnapshot(PHLWINDOW pWindow) {
|
||||
CRegion fakeDamage{0, 0, PMONITOR->m_transformedSize.x, PMONITOR->m_transformedSize.y};
|
||||
|
||||
if (*PDIMAROUND && pWindow->m_windowData.dimAround.valueOrDefault()) {
|
||||
|
||||
CRectPassElement::SRectData data;
|
||||
|
||||
data.box = {0, 0, g_pHyprOpenGL->m_renderData.pMonitor->m_pixelSize.x, g_pHyprOpenGL->m_renderData.pMonitor->m_pixelSize.y};
|
||||
data.color = CHyprColor(0, 0, 0, *PDIMAROUND * pWindow->m_alpha->value());
|
||||
|
||||
m_renderPass.add(makeShared<CRectPassElement>(data));
|
||||
damageMonitor(PMONITOR);
|
||||
}
|
||||
|
||||
if (shouldBlur(pWindow)) {
|
||||
CRectPassElement::SRectData data;
|
||||
data.box = CBox{pWindow->m_realPosition->value(), pWindow->m_realSize->value()}.translate(-PMONITOR->m_position).scale(PMONITOR->m_scale).round();
|
||||
data.color = CHyprColor{0, 0, 0, 0};
|
||||
data.blur = true;
|
||||
data.blurA = sqrt(pWindow->m_alpha->value()); // sqrt makes the blur fadeout more realistic.
|
||||
data.round = pWindow->rounding();
|
||||
data.roundingPower = pWindow->roundingPower();
|
||||
data.xray = pWindow->m_windowData.xray.valueOr(false);
|
||||
|
||||
m_renderPass.add(makeShared<CRectPassElement>(data));
|
||||
}
|
||||
|
||||
CTexPassElement::SRenderData data;
|
||||
@ -2580,12 +2571,35 @@ void CHyprRenderer::renderSnapshot(PHLLS pLayer) {
|
||||
|
||||
CRegion fakeDamage{0, 0, PMONITOR->m_transformedSize.x, PMONITOR->m_transformedSize.y};
|
||||
|
||||
const bool SHOULD_BLUR = shouldBlur(pLayer);
|
||||
|
||||
CTexPassElement::SRenderData data;
|
||||
data.flipEndFrame = true;
|
||||
data.tex = FBDATA->getTexture();
|
||||
data.box = layerBox;
|
||||
data.a = pLayer->m_alpha->value();
|
||||
data.damage = fakeDamage;
|
||||
data.blur = SHOULD_BLUR;
|
||||
data.blurA = sqrt(pLayer->m_alpha->value()); // sqrt makes the blur fadeout more realistic.
|
||||
if (SHOULD_BLUR)
|
||||
data.ignoreAlpha = pLayer->m_ignoreAlpha ? pLayer->m_ignoreAlphaValue : 0.01F /* ignore the alpha 0 regions */;
|
||||
|
||||
m_renderPass.add(makeShared<CTexPassElement>(data));
|
||||
}
|
||||
|
||||
bool CHyprRenderer::shouldBlur(PHLLS ls) {
|
||||
if (m_bRenderingSnapshot)
|
||||
return false;
|
||||
|
||||
static auto PBLUR = CConfigValue<Hyprlang::INT>("decoration:blur:enabled");
|
||||
return *PBLUR && ls->m_forceBlur;
|
||||
}
|
||||
|
||||
bool CHyprRenderer::shouldBlur(PHLWINDOW w) {
|
||||
if (m_bRenderingSnapshot)
|
||||
return false;
|
||||
|
||||
static auto PBLUR = CConfigValue<Hyprlang::INT>("decoration:blur:enabled");
|
||||
const bool DONT_BLUR = w->m_windowData.noBlur.valueOrDefault() || w->m_windowData.RGBX.valueOrDefault() || w->opaque();
|
||||
return *PBLUR && !DONT_BLUR;
|
||||
}
|
||||
|
@ -45,6 +45,11 @@ struct SExplicitSyncSettings {
|
||||
bool explicitEnabled = false, explicitKMSEnabled = false;
|
||||
};
|
||||
|
||||
struct SRenderWorkspaceUntilData {
|
||||
PHLLS ls;
|
||||
PHLWINDOW w;
|
||||
};
|
||||
|
||||
class CHyprRenderer {
|
||||
public:
|
||||
CHyprRenderer();
|
||||
@ -117,20 +122,23 @@ class CHyprRenderer {
|
||||
|
||||
private:
|
||||
void arrangeLayerArray(PHLMONITOR, const std::vector<PHLLSREF>&, bool, CBox*);
|
||||
void renderWorkspace(PHLMONITOR pMonitor, PHLWORKSPACE pWorkspace, const Time::steady_tp& now, const CBox& geometry);
|
||||
void renderWorkspaceWindowsFullscreen(PHLMONITOR, PHLWORKSPACE, const Time::steady_tp&); // renders workspace windows (fullscreen) (tiled, floating, pinned, but no special)
|
||||
void renderWorkspaceWindows(PHLMONITOR, PHLWORKSPACE, const Time::steady_tp&); // renders workspace windows (no fullscreen) (tiled, floating, pinned, but no special)
|
||||
void renderAllClientsForWorkspace(PHLMONITOR pMonitor, PHLWORKSPACE pWorkspace, const Time::steady_tp& now, const Vector2D& translate = {0, 0}, const float& scale = 1.f);
|
||||
void renderWindow(PHLWINDOW, PHLMONITOR, const Time::steady_tp&, bool, eRenderPassMode, bool ignorePosition = false, bool standalone = false);
|
||||
void renderLayer(PHLLS, PHLMONITOR, const Time::steady_tp&, bool popups = false, bool lockscreen = false);
|
||||
void renderSessionLockSurface(WP<SSessionLockSurface>, PHLMONITOR, const Time::steady_tp&);
|
||||
void renderDragIcon(PHLMONITOR, const Time::steady_tp&);
|
||||
void renderIMEPopup(CInputPopup*, PHLMONITOR, const Time::steady_tp&);
|
||||
void renderWorkspace(PHLMONITOR pMonitor, PHLWORKSPACE pWorkspace, const Time::steady_tp& now, const CBox& geometry);
|
||||
void sendFrameEventsToWorkspace(PHLMONITOR pMonitor, PHLWORKSPACE pWorkspace, const Time::steady_tp& now); // sends frame displayed events but doesn't actually render anything
|
||||
void renderAllClientsForWorkspace(PHLMONITOR pMonitor, PHLWORKSPACE pWorkspace, const Time::steady_tp& now, const Vector2D& translate = {0, 0}, const float& scale = 1.f);
|
||||
void renderSessionLockMissing(PHLMONITOR pMonitor);
|
||||
|
||||
bool commitPendingAndDoExplicitSync(PHLMONITOR pMonitor);
|
||||
|
||||
bool shouldBlur(PHLLS ls);
|
||||
bool shouldBlur(PHLWINDOW w);
|
||||
|
||||
bool m_cursorHidden = false;
|
||||
bool m_cursorHasSurface = false;
|
||||
SP<CRenderbuffer> m_currentRenderbuffer = nullptr;
|
||||
|
@ -1,14 +1,48 @@
|
||||
#include "Shader.hpp"
|
||||
#include "render/OpenGL.hpp"
|
||||
|
||||
SShader::~SShader() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
void SShader::createVao() {
|
||||
glGenVertexArrays(1, &shaderVao);
|
||||
glBindVertexArray(shaderVao);
|
||||
|
||||
if (posAttrib != -1) {
|
||||
glGenBuffers(1, &shaderVboPos);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, shaderVboPos);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(fullVerts), fullVerts, GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(posAttrib);
|
||||
glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);
|
||||
}
|
||||
|
||||
// UV VBO (dynamic, may be updated per frame)
|
||||
if (texAttrib != -1) {
|
||||
glGenBuffers(1, &shaderVboUv);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, shaderVboUv);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(fullVerts), fullVerts, GL_DYNAMIC_DRAW); // Initial dummy UVs
|
||||
glEnableVertexAttribArray(texAttrib);
|
||||
glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);
|
||||
}
|
||||
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
void SShader::destroy() {
|
||||
if (program == 0)
|
||||
return;
|
||||
|
||||
glDeleteProgram(program);
|
||||
if (shaderVao)
|
||||
glDeleteVertexArrays(1, &shaderVao);
|
||||
|
||||
if (shaderVboPos)
|
||||
glDeleteBuffers(1, &shaderVboPos);
|
||||
|
||||
if (shaderVboUv)
|
||||
glDeleteBuffers(1, &shaderVboUv);
|
||||
|
||||
glDeleteProgram(program);
|
||||
program = 0;
|
||||
}
|
||||
|
@ -32,6 +32,10 @@ struct SShader {
|
||||
GLint discardAlpha = -1;
|
||||
GLfloat discardAlphaValue = -1;
|
||||
|
||||
GLuint shaderVao = 0;
|
||||
GLuint shaderVboPos = 0;
|
||||
GLuint shaderVboUv = 0;
|
||||
|
||||
GLint topLeft = -1;
|
||||
GLint bottomRight = -1;
|
||||
GLint fullSize = -1;
|
||||
@ -76,5 +80,6 @@ struct SShader {
|
||||
GLint brightness = -1;
|
||||
GLint noise = -1;
|
||||
|
||||
void createVao();
|
||||
void destroy();
|
||||
};
|
||||
|
@ -72,12 +72,12 @@ void CTexture::createFromShm(uint32_t drmFormat, uint8_t* pixels, uint32_t strid
|
||||
GLCALL(glBindTexture(GL_TEXTURE_2D, m_texID));
|
||||
GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
|
||||
GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
|
||||
#ifndef GLES2
|
||||
|
||||
if (format->flipRB) {
|
||||
GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE));
|
||||
GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED));
|
||||
}
|
||||
#endif
|
||||
|
||||
GLCALL(glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, stride / format->bytesPerBlock));
|
||||
GLCALL(glTexImage2D(GL_TEXTURE_2D, 0, format->glInternalFormat ? format->glInternalFormat : format->glFormat, size_.x, size_.y, 0, format->glFormat, format->glType, pixels));
|
||||
GLCALL(glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, 0));
|
||||
@ -120,12 +120,10 @@ void CTexture::update(uint32_t drmFormat, uint8_t* pixels, uint32_t stride, cons
|
||||
|
||||
auto rects = damage.copy().intersect(CBox{{}, m_size}).getRects();
|
||||
|
||||
#ifndef GLES2
|
||||
if (format->flipRB) {
|
||||
GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE));
|
||||
GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED));
|
||||
}
|
||||
#endif
|
||||
|
||||
for (auto const& rect : rects) {
|
||||
GLCALL(glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, stride / format->bytesPerBlock));
|
||||
|
@ -332,11 +332,8 @@ static void renderGradientTo(SP<CTexture> tex, CGradientValueData* grad) {
|
||||
glBindTexture(GL_TEXTURE_2D, tex->m_texID);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
|
||||
#ifndef GLES2
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
|
||||
#endif
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bufferSize.x, bufferSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA);
|
||||
|
||||
|
@ -42,7 +42,6 @@ Vector2D CDecorationPositioner::getEdgeDefinedPoint(uint32_t edges, PHLWINDOW pW
|
||||
return wb.pos() + Vector2D{0.0, wb.size().y / 2.0};
|
||||
else if (RIGHT)
|
||||
return wb.pos() + Vector2D{wb.size().x, wb.size().y / 2.0};
|
||||
UNREACHABLE();
|
||||
} else {
|
||||
if (TOP && LEFT)
|
||||
return wb.pos();
|
||||
@ -52,9 +51,8 @@ Vector2D CDecorationPositioner::getEdgeDefinedPoint(uint32_t edges, PHLWINDOW pW
|
||||
return wb.pos() + wb.size();
|
||||
if (BOTTOM && LEFT)
|
||||
return wb.pos() + Vector2D{0.0, wb.size().y};
|
||||
UNREACHABLE();
|
||||
}
|
||||
UNREACHABLE();
|
||||
Debug::log(ERR, "getEdgeDefinedPoint: invalid configuration of edges");
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -273,7 +273,7 @@ CRegion CSurfacePassElement::visibleRegion(bool& cancel) {
|
||||
texBox.round();
|
||||
|
||||
visibleRegion.scale((Vector2D(1, 1) / (uvBR - uvTL)) * (texBox.size() / bufferSize));
|
||||
visibleRegion.translate((m_data.pos + m_data.localPos) * m_data.pMonitor->m_scale - m_data.pMonitor->m_position);
|
||||
visibleRegion.translate((m_data.pos + m_data.localPos - m_data.pMonitor->m_position) * m_data.pMonitor->m_scale);
|
||||
|
||||
return visibleRegion;
|
||||
}
|
||||
|
@ -11,10 +11,14 @@ CTexPassElement::CTexPassElement(const CTexPassElement::SRenderData& data_) : m_
|
||||
void CTexPassElement::draw(const CRegion& damage) {
|
||||
g_pHyprOpenGL->m_endFrame = m_data.flipEndFrame;
|
||||
|
||||
CScopeGuard x = {[]() {
|
||||
CScopeGuard x = {[this]() {
|
||||
//
|
||||
g_pHyprOpenGL->m_endFrame = false;
|
||||
g_pHyprOpenGL->m_renderData.clipBox = {};
|
||||
if (m_data.replaceProjection)
|
||||
g_pHyprOpenGL->m_renderData.monitorProjection = g_pHyprOpenGL->m_renderData.pMonitor->m_projMatrix;
|
||||
if (m_data.ignoreAlpha.has_value())
|
||||
g_pHyprOpenGL->m_renderData.discardMode = 0;
|
||||
}};
|
||||
|
||||
if (!m_data.clipBox.empty())
|
||||
@ -22,9 +26,16 @@ void CTexPassElement::draw(const CRegion& damage) {
|
||||
|
||||
if (m_data.replaceProjection)
|
||||
g_pHyprOpenGL->m_renderData.monitorProjection = *m_data.replaceProjection;
|
||||
|
||||
if (m_data.ignoreAlpha.has_value()) {
|
||||
g_pHyprOpenGL->m_renderData.discardMode = DISCARD_ALPHA;
|
||||
g_pHyprOpenGL->m_renderData.discardOpacity = *m_data.ignoreAlpha;
|
||||
}
|
||||
|
||||
if (m_data.blur)
|
||||
g_pHyprOpenGL->renderTextureWithBlur(m_data.tex, m_data.box, m_data.a, nullptr, m_data.round, m_data.roundingPower, false, m_data.blurA, 1.F);
|
||||
else
|
||||
g_pHyprOpenGL->renderTextureInternalWithDamage(m_data.tex, m_data.box, m_data.a, m_data.damage.empty() ? damage : m_data.damage, m_data.round, m_data.roundingPower);
|
||||
if (m_data.replaceProjection)
|
||||
g_pHyprOpenGL->m_renderData.monitorProjection = g_pHyprOpenGL->m_renderData.pMonitor->m_projMatrix;
|
||||
}
|
||||
|
||||
bool CTexPassElement::needsLiveBlur() {
|
||||
|
@ -12,12 +12,15 @@ class CTexPassElement : public IPassElement {
|
||||
SP<CTexture> tex;
|
||||
CBox box;
|
||||
float a = 1.F;
|
||||
float blurA = 1.F;
|
||||
CRegion damage;
|
||||
int round = 0;
|
||||
float roundingPower = 2.0f;
|
||||
bool flipEndFrame = false;
|
||||
std::optional<Mat3x3> replaceProjection;
|
||||
CBox clipBox;
|
||||
bool blur = false;
|
||||
std::optional<float> ignoreAlpha;
|
||||
};
|
||||
|
||||
CTexPassElement(const SRenderData& data);
|
||||
|
@ -5,7 +5,9 @@
|
||||
#include "../managers/input/InputManager.hpp"
|
||||
#include <wayland-server-protocol.h>
|
||||
#include <hyprutils/os/FileDescriptor.hpp>
|
||||
#ifndef NO_XWAYLAND
|
||||
#include <xcb/xcb.h>
|
||||
#endif
|
||||
|
||||
#define XDND_VERSION 5
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user