Compare commits

..

No commits in common. "main" and "v0.49.0" have entirely different histories.

52 changed files with 509 additions and 477 deletions

View File

@ -99,14 +99,18 @@ message(STATUS "Checking deps...")
find_package(Threads REQUIRED)
set(GLES_VERSION "GLES3")
if(LEGACY_RENDERER)
set(GLES_VERSION "GLES2")
else()
set(GLES_VERSION "GLES3")
endif()
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.3)
pkg_check_modules(hyprgraphics_dep REQUIRED IMPORTED_TARGET hyprgraphics>=0.1.1)
string(REPLACE "." ";" AQ_VERSION_LIST ${aquamarine_dep_VERSION})
list(GET AQ_VERSION_LIST 0 AQ_VERSION_MAJOR)
@ -212,6 +216,11 @@ 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)

View File

@ -3,6 +3,14 @@ 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
View File

@ -276,11 +276,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1747327360,
"narHash": "sha256-LSmTbiq/nqZR9B2t4MRnWG7cb0KVNU70dB7RT4+wYK4=",
"lastModified": 1746461020,
"narHash": "sha256-7+pG1I9jvxNlmln4YgnlW4o+w0TZX24k688mibiFDUE=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e06158e58f3adee28b139e9c2bcfcc41f8625b46",
"rev": "3730d8a308f94996a9ba7c7138ede69c1b9ac4ae",
"type": "github"
},
"original": {
@ -299,11 +299,11 @@
]
},
"locked": {
"lastModified": 1747372754,
"narHash": "sha256-2Y53NGIX2vxfie1rOW0Qb86vjRZ7ngizoo+bnXU9D9k=",
"lastModified": 1746537231,
"narHash": "sha256-Wb2xeSyOsCoTCTj7LOoD6cdKLEROyFAArnYoS+noCWo=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "80479b6ec16fefd9c1db3ea13aeb038c60530f46",
"rev": "fa466640195d38ec97cf0493d6d6882bc4d14969",
"type": "github"
},
"original": {

View File

@ -132,6 +132,7 @@
# hyprland-packages
hyprland
hyprland-debug
hyprland-legacy-renderer
hyprland-unwrapped
# hyprland-extras
xdg-desktop-portal-hyprland

View File

@ -5,7 +5,6 @@
#include <print>
#include <sys/un.h>
#include <unistd.h>
#include <cstring>
static int getUID() {
const auto UID = getuid();

View File

@ -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 a+x {{}} \\;", WORKINGDIR, DataState::getHeadersPath(),
cmd = std::format("make -C '{}' installheaders && chmod -R 644 '{}' && find '{}' -type d -exec chmod o+x {{}} \\;", WORKINGDIR, DataState::getHeadersPath(),
DataState::getHeadersPath());
if (m_bVerbose)

View File

@ -4,7 +4,6 @@
#include <pwd.h>
#include <unistd.h>
#include <sstream>
#include <print>
#include <filesystem>
#include <algorithm>
@ -153,7 +152,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", "0", "-g", "0", what, where});
CProcess proc(subin(), {"install", "-m" + mode, "-o", "root", "-g", "root", what, where});
return proc.runSync() && proc.exitCode() == 0;
}

View File

@ -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 (command.size() < 2) {
if (ARGS.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 (command.size() < 2) {
if (ARGS.size() < 2) {
std::println(stderr, "{}", failureString("Not enough args for enable."));
return 1;
}

View File

@ -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.3')
hyprgraphics = dependency('hyprgraphics', version: '>= 0.1.1')
hyprlang = dependency('hyprlang', version: '>= 0.3.2')
hyprutils = dependency('hyprutils', version: '>= 0.7.0')
aquamarine_version_list = aquamarine.version().split('.')
@ -77,6 +77,10 @@ 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

View File

@ -1,5 +1,6 @@
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')

View File

@ -41,6 +41,7 @@
xwayland,
debug ? false,
enableXWayland ? true,
legacyRenderer ? false,
withSystemd ? lib.meta.availableOn stdenv.hostPlatform systemd,
wrapRuntimeDeps ? true,
version ? "git",
@ -51,7 +52,6 @@
enableNvidiaPatches ? false,
nvidiaPatches ? false,
hidpiXWayland ? false,
legacyRenderer ? false,
}: let
inherit (builtins) baseNameOf foldl' readFile;
inherit (lib.asserts) assertMsg;
@ -70,7 +70,6 @@ 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;
@ -143,7 +142,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
@ -166,6 +165,7 @@ in
mesonFlags = flatten [
(mapAttrsToList mesonEnable {
"xwayland" = enableXWayland;
"legacy_renderer" = legacyRenderer;
"systemd" = withSystemd;
"uwsm" = false;
"hyprpm" = false;

View File

@ -50,15 +50,9 @@ 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.

View File

@ -870,14 +870,10 @@ 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);
@ -902,9 +898,6 @@ 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
@ -957,7 +950,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) && !ONLY_PRIORITY)
if (PWORKSPACE->m_hasFullscreenWindow && !(properties & SKIP_FULLSCREEN_PRIORITY))
return PWORKSPACE->getFullscreenWindow();
auto found = floating(false);
@ -966,9 +959,6 @@ 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;
@ -983,9 +973,6 @@ 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;
@ -1096,16 +1083,14 @@ 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;
}
if (g_pSessionLockManager->isSessionLocked()) {
Debug::log(LOG, "Refusing a keyboard focus to a window because of a sessionlock");
return;
}
if (!g_pInputManager->m_exclusiveLSes.empty()) {
Debug::log(LOG, "Refusing a keyboard focus to a window because of an exclusive ls");
return;
}
if (!g_pInputManager->m_exclusiveLSes.empty()) {
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())
@ -1502,6 +1487,7 @@ void CCompositor::cleanupFadingOut(const MONITORID& monid) {
Debug::log(LOG, "Cleanup: destroyed a layersurface");
glFlush(); // to free mem NOW.
return;
}
}

View File

@ -2900,8 +2900,6 @@ 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;

View File

@ -109,6 +109,9 @@ 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

View File

@ -931,10 +931,13 @@ 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 (!ISDEBUG && !defined(NO_XWAYLAND))
#if (!defined(LEGACY_RENDERER) && !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
@ -963,6 +966,9 @@ 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

View File

@ -263,8 +263,11 @@ 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);

View File

@ -238,8 +238,11 @@ 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);

View File

@ -167,9 +167,7 @@ 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_pSeatManager->setGrab(nullptr);
g_pInputManager->releaseAllMouseButtons();
g_pCompositor->focusSurface(m_surface->resource());

View File

@ -1149,7 +1149,7 @@ bool CWindow::opaque() {
if (m_wlSurface->small() && !m_wlSurface->m_fillIgnoreSmall)
return false;
if (PWORKSPACE && PWORKSPACE->m_alpha->value() != 1.f)
if (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,7 +1836,3 @@ PHLWINDOW CWindow::parent() {
return m_xdgSurface->m_toplevel->m_parent->m_window.lock();
}
bool CWindow::priorityFocus() {
return !m_isX11 && CAsyncDialogBox::isPriorityDialogBox(getPID());
}

View File

@ -51,7 +51,6 @@ 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 {
@ -409,7 +408,6 @@ 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};

View File

@ -78,9 +78,6 @@ 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.

View File

@ -754,8 +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);
g_pHyprRenderer->makeWindowSnapshot(PWINDOW);
// swallowing
if (valid(PWINDOW->m_swallowed)) {

View File

@ -7,7 +7,7 @@
using namespace Hyprutils::OS;
static std::vector<std::pair<pid_t, WP<CAsyncDialogBox>>> asyncDialogBoxes;
static std::vector<pid_t> asyncDialogBoxes;
//
SP<CAsyncDialogBox> CAsyncDialogBox::create(const std::string& title, const std::string& description, std::vector<std::string> buttons) {
@ -24,18 +24,7 @@ SP<CAsyncDialogBox> CAsyncDialogBox::create(const std::string& title, const std:
}
bool CAsyncDialogBox::isAsyncDialogBox(pid_t 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;
return std::ranges::contains(asyncDialogBoxes, pid);
}
CAsyncDialogBox::CAsyncDialogBox(const std::string& title, const std::string& description, std::vector<std::string> buttons) :
@ -79,7 +68,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_if(asyncDialogBoxes, [this](const auto& e) { return e.first == m_dialogPid; });
std::erase(asyncDialogBoxes, m_dialogPid);
wl_event_source_remove(m_readEventSource);
m_selfReference.reset();
@ -123,7 +112,7 @@ SP<CPromise<std::string>> CAsyncDialogBox::open() {
}
m_dialogPid = proc.pid();
asyncDialogBoxes.emplace_back(std::make_pair<>(m_dialogPid, m_selfWeakReference));
asyncDialogBoxes.emplace_back(m_dialogPid);
// close the write fd, only the dialog owns it now
close(outPipe[1]);

View File

@ -16,7 +16,6 @@ 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;
@ -27,10 +26,7 @@ class CAsyncDialogBox {
void kill();
bool isRunning() const;
// focus priority, only permission popups
bool m_priority = false;
void onWrite(int fd, uint32_t mask);
void onWrite(int fd, uint32_t mask);
private:
CAsyncDialogBox(const std::string& title, const std::string& description, std::vector<std::string> buttons);

View File

@ -14,18 +14,26 @@
*/
inline const std::vector<SPixelFormat> GLES3_FORMATS = {
{
.drmFormat = DRM_FORMAT_ARGB8888,
.flipRB = true,
.glFormat = GL_RGBA,
.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,
.bytesPerBlock = 4,
},
{
.drmFormat = DRM_FORMAT_XRGB8888,
.flipRB = true,
.glFormat = GL_RGBA,
.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,
@ -96,64 +104,96 @@ inline const std::vector<SPixelFormat> GLES3_FORMATS = {
.bytesPerBlock = 2,
},
{
.drmFormat = DRM_FORMAT_XBGR2101010,
.glFormat = GL_RGBA,
.glType = GL_UNSIGNED_INT_2_10_10_10_REV,
.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,
},
{
.drmFormat = DRM_FORMAT_ABGR2101010,
.glFormat = GL_RGBA,
.glType = GL_UNSIGNED_INT_2_10_10_10_REV,
.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,
},
{
.drmFormat = DRM_FORMAT_XRGB2101010,
.glFormat = GL_RGBA,
.glType = GL_UNSIGNED_INT_2_10_10_10_REV,
.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,
},
{
.drmFormat = DRM_FORMAT_ARGB2101010,
.glFormat = GL_RGBA,
.glType = GL_UNSIGNED_INT_2_10_10_10_REV,
.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,
},
{
.drmFormat = DRM_FORMAT_XBGR16161616F,
.glFormat = GL_RGBA,
.glType = GL_HALF_FLOAT,
.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,
},
{
.drmFormat = DRM_FORMAT_ABGR16161616F,
.glFormat = GL_RGBA,
.glType = GL_HALF_FLOAT,
.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,
.glFormat = GL_RGBA16UI,
.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,
.bytesPerBlock = 8,
},
{
.drmFormat = DRM_FORMAT_ABGR16161616,
.glFormat = GL_RGBA16UI,
.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,
@ -250,7 +290,12 @@ 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: return GL_RGB10_A2;
case DRM_FORMAT_XBGR2101010:
#ifdef GLES2
return GL_RGB10_A2_EXT;
#else
return GL_RGB10_A2;
#endif
default: return GL_RGBA;
}
UNREACHABLE();
@ -258,7 +303,13 @@ uint32_t NFormatUtils::drmFormatToGL(DRMFormat drm) {
}
uint32_t NFormatUtils::glFormatToType(uint32_t gl) {
return gl != GL_RGBA ? GL_UNSIGNED_INT_2_10_10_10_REV : GL_UNSIGNED_BYTE;
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;
}
std::string NFormatUtils::drmFormatName(DRMFormat drm) {

View File

@ -146,8 +146,11 @@ 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);

View File

@ -17,9 +17,15 @@
#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

View File

@ -584,6 +584,7 @@ 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());

View File

@ -70,20 +70,16 @@ 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 (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->source) {
wl_event_source_remove(waiter->source);
waiter->source = nullptr;
}
if (taken->fn)
taken->fn();
if (waiter->fn)
waiter->fn();
if (it != m_readableWaiters.end())
m_readableWaiters.erase(it);
}
void CEventLoopManager::enterLoop() {

View File

@ -36,7 +36,6 @@
#include "../../managers/HookSystemManager.hpp"
#include "../../managers/EventManager.hpp"
#include "../../managers/LayoutManager.hpp"
#include "../../managers/permissions/DynamicPermissionManager.hpp"
#include "../../helpers/time/Time.hpp"
@ -250,12 +249,7 @@ 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);
// 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()) {
if (g_pSessionLockManager->isSessionLocked()) {
// set keyboard focus on session lock surface regardless of layers
const auto PSESSIONLOCKSURFACE = g_pSessionLockManager->getSessionLockSurfaceForMonitor(PMONITOR->m_id);
@ -293,7 +287,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse) {
if (!forcedFocus)
forcedFocus = g_pCompositor->getForceFocus();
if (forcedFocus && !foundSurface) {
if (forcedFocus) {
pFoundWindow = forcedFocus;
surfacePos = pFoundWindow->m_realPosition->value();
foundSurface = pFoundWindow->m_wlSurface->resource();
@ -1060,27 +1054,6 @@ 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 &&
@ -1395,7 +1368,7 @@ void CInputManager::destroyTabletPad(SP<CTabletPad> pad) {
}
void CInputManager::updateKeyboardsLeds(SP<IKeyboard> pKeyboard) {
if (!pKeyboard || pKeyboard->isVirtual())
if (!pKeyboard)
return;
std::optional<uint32_t> leds = pKeyboard->getLEDs();
@ -1409,7 +1382,7 @@ void CInputManager::updateKeyboardsLeds(SP<IKeyboard> pKeyboard) {
}
void CInputManager::onKeyboardKey(std::any event, SP<IKeyboard> pKeyboard) {
if (!pKeyboard->m_enabled || !pKeyboard->m_allowed)
if (!pKeyboard->m_enabled)
return;
const bool DISALLOWACTION = pKeyboard->isVirtual() && shouldIgnoreVirtualKeyboard(pKeyboard);

View File

@ -52,7 +52,6 @@ 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";
@ -60,10 +59,9 @@ static const char* permissionToString(eDynamicPermissionType type) {
static const char* permissionToHumanString(eDynamicPermissionType type) {
switch (type) {
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?";
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";
}
return "error";
@ -186,7 +184,7 @@ eDynamicPermissionAllowMode CDynamicPermissionManager::clientPermissionMode(wl_c
return PERMISSION_RULE_ALLOW_MODE_PENDING;
}
// if we are here, we need to ask, that's the fallback for all these (keyboards wont come here)
// if we are here, we need to ask.
askForPermission(client, LOOKUP.value_or(""), permission);
return PERMISSION_RULE_ALLOW_MODE_PENDING;
@ -234,10 +232,6 @@ 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");
}
@ -253,10 +247,6 @@ 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);
@ -273,20 +263,22 @@ void CDynamicPermissionManager::askForPermission(wl_client* client, const std::s
std::string description = "";
if (binaryPath.empty())
description = std::format(std::runtime_format(permissionToHumanString(type)), std::format("unknown application (wayland client ID 0x{:x})", (uintptr_t)client));
description = std::format("An unknown application (wayland client ID 0x{:x}) is {}.", (uintptr_t)client, permissionToHumanString(type));
else if (client) {
std::string binaryName = binaryPath.contains("/") ? binaryPath.substr(binaryPath.find_last_of('/') + 1) : binaryPath;
description = std::format(std::runtime_format(permissionToHumanString(type)), std::format("{}</b> ({})", binaryName, binaryPath));
description = std::format("An application <b>{}</b> ({}) is {}.", binaryName, binaryPath, permissionToHumanString(type));
} else if (pid >= 0) {
if (type == PERMISSION_TYPE_PLUGIN) {
const auto LOOKUP = binaryNameForPid(pid);
description = std::format(std::runtime_format(permissionToHumanString(type)), LOOKUP.value_or("Unknown"), binaryPath);
description = std::format("An application <b>{}</b> is {}:<br/><b>{}</b>", LOOKUP.value_or("Unknown"), permissionToHumanString(type), binaryPath);
} else {
const auto LOOKUP = binaryNameForPid(pid);
description = std::format(std::runtime_format(permissionToHumanString(type)), LOOKUP.value_or("Unknown"), binaryPath);
description = std::format("An application <b>{}</b> ({}) is {}.", LOOKUP.value_or("Unknown"), binaryPath, permissionToHumanString(type));
}
} else
description = std::format(std::runtime_format(permissionToHumanString(type)), binaryPath);
description = std::format("An application is {}:<br/><b>{}</b>", permissionToHumanString(type), binaryPath);
description += "<br/><br/>Do you want to allow this?";
std::vector<std::string> options;
@ -296,8 +288,7 @@ void CDynamicPermissionManager::askForPermission(wl_client* client, const std::s
} else
options = {"Deny", "Allow"};
rule->m_dialogBox = CAsyncDialogBox::create("Permission request", description, options);
rule->m_dialogBox->m_priority = true;
rule->m_dialogBox = CAsyncDialogBox::create("Permission request", description, options);
if (!rule->m_dialogBox) {
Debug::log(ERR, "CDynamicPermissionManager::askForPermission: hyprland-qtutils likely missing, cannot ask! Disabling permission control...");

View File

@ -17,7 +17,6 @@ enum eDynamicPermissionType : uint8_t {
PERMISSION_TYPE_UNKNOWN = 0,
PERMISSION_TYPE_SCREENCOPY,
PERMISSION_TYPE_PLUGIN,
PERMISSION_TYPE_KEYBOARD,
};
enum eDynamicPermissionRuleSource : uint8_t {

View File

@ -1,7 +1,6 @@
#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"
@ -25,7 +24,6 @@ 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) {

View File

@ -187,43 +187,9 @@ void CScreencopyFrame::share() {
callback(copyShm());
}
void CScreencopyFrame::renderMon() {
auto TEXTURE = makeShared<CTexture>(m_monitor->m_output->state->state().buffer);
CRegion fakeDamage = {0, 0, INT16_MAX, INT16_MAX};
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);
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);
}
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);
const auto PERM = g_pDynamicPermissionManager->clientPermissionMode(m_resource->client(), PERMISSION_TYPE_SCREENCOPY);
auto TEXTURE = makeShared<CTexture>(m_monitor->m_output->state->state().buffer);
CRegion fakeDamage = {0, 0, INT16_MAX, INT16_MAX};
@ -234,12 +200,17 @@ void CScreencopyFrame::copyDmabuf(std::function<void(bool)> callback) {
}
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();
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);
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);
} else if (PERM == PERMISSION_RULE_ALLOW_MODE_PENDING)
g_pHyprOpenGL->clear(Colors::BLACK);
else {
@ -257,7 +228,8 @@ void CScreencopyFrame::copyDmabuf(std::function<void(bool)> callback) {
}
bool CScreencopyFrame::copyShm() {
const auto PERM = g_pDynamicPermissionManager->clientPermissionMode(m_resource->client(), PERMISSION_TYPE_SCREENCOPY);
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
@ -275,12 +247,15 @@ bool CScreencopyFrame::copyShm() {
}
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();
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);
} else if (PERM == PERMISSION_RULE_ALLOW_MODE_PENDING)
g_pHyprOpenGL->clear(Colors::BLACK);
else {
@ -289,7 +264,11 @@ 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) {
@ -325,7 +304,11 @@ 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");
@ -445,12 +428,8 @@ 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 (!f->m_tempFb.isAllocated())
f->storeTempFB(); // make a snapshot before the popup
if (PERM == PERMISSION_RULE_ALLOW_MODE_PENDING)
continue; // pending an answer, don't do anything yet.
}
// otherwise share. If it's denied, it will be black.

View File

@ -10,7 +10,6 @@
#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>
@ -73,15 +72,10 @@ 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();
void copy(CZwlrScreencopyFrameV1* pFrame, wl_resource* buffer);
void copyDmabuf(std::function<void(bool)> callback);
bool copyShm();
void share();
friend class CScreencopyProtocol;
};

View File

@ -281,7 +281,10 @@ 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;
@ -315,7 +318,10 @@ bool CToplevelExportFrame::copyShm(const Time::steady_tp& now) {
}
outFB.unbind();
#ifndef GLES2
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
#endif
return true;
}

View File

@ -12,11 +12,6 @@ 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();
@ -40,11 +35,14 @@ 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());
@ -61,6 +59,8 @@ 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,10 +74,15 @@ 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);
@ -86,7 +91,11 @@ void CFramebuffer::bind() {
}
void CFramebuffer::unbind() {
#ifndef GLES2
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
#else
glBindFramebuffer(GL_FRAMEBUFFER, 0);
#endif
}
void CFramebuffer::release() {

View File

@ -1,7 +1,6 @@
#pragma once
#include "../defines.hpp"
#include "../helpers/Format.hpp"
#include "Texture.hpp"
class CFramebuffer {
@ -21,7 +20,6 @@ class CFramebuffer {
GLuint getFBID();
Vector2D m_size;
DRMFormat m_drmFormat = 0 /* DRM_FORMAT_INVALID */;
private:
SP<CTexture> m_tex;

View File

@ -162,14 +162,24 @@ 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;
@ -352,6 +362,10 @@ 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();
@ -655,6 +669,7 @@ 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 = "";
@ -667,6 +682,7 @@ 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");
@ -705,6 +721,7 @@ 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 = "";
@ -717,6 +734,7 @@ 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");
@ -734,15 +752,13 @@ 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 || DRM_FORMAT != m_renderData.pCurrentMonData->offloadFB.m_drmFormat) {
if (m_renderData.pCurrentMonData->offloadFB.m_size != pMonitor->m_pixelSize) {
m_renderData.pCurrentMonData->stencilTex->allocate();
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.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.addStencil(m_renderData.pCurrentMonData->stencilTex);
m_renderData.pCurrentMonData->mirrorFB.addStencil(m_renderData.pCurrentMonData->stencilTex);
@ -842,7 +858,11 @@ 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.");
}
@ -924,7 +944,9 @@ bool CHyprOpenGLImpl::initShaders() {
shaders->TEXVERTSRC320 = processShader("tex320.vert", includes);
GLuint prog;
#ifdef GLES2
m_cmSupported = false;
#else
if (!*PCM)
m_cmSupported = false;
else {
@ -953,12 +975,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);
@ -982,7 +1004,6 @@ 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)
@ -1002,7 +1023,6 @@ 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)
@ -1012,7 +1032,6 @@ 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)
@ -1023,7 +1042,6 @@ 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)
@ -1036,7 +1054,6 @@ 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)
@ -1053,7 +1070,6 @@ 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)
@ -1070,7 +1086,6 @@ 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)
@ -1086,7 +1101,6 @@ 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)
@ -1099,7 +1113,6 @@ 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)
@ -1114,7 +1127,6 @@ 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)
@ -1128,7 +1140,6 @@ 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)
@ -1144,7 +1155,6 @@ 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)
@ -1169,8 +1179,6 @@ 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;
@ -1237,7 +1245,6 @@ 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) {
@ -1366,8 +1373,14 @@ 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);
useProgram(m_shaders->m_shQUAD.program);
glUseProgram(m_shaders->m_shQUAD.program);
#ifndef GLES2
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);
@ -1385,7 +1398,9 @@ void CHyprOpenGLImpl::renderRectWithDamage(const CBox& box, const CHyprColor& co
glUniform1f(m_shaders->m_shQUAD.radius, round);
glUniform1f(m_shaders->m_shQUAD.roundingPower, roundingPower);
glBindVertexArray(m_shaders->m_shQUAD.shaderVao);
glVertexAttribPointer(m_shaders->m_shQUAD.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
glEnableVertexAttribArray(m_shaders->m_shQUAD.posAttrib);
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};
@ -1404,7 +1419,7 @@ void CHyprOpenGLImpl::renderRectWithDamage(const CBox& box, const CHyprColor& co
}
}
glBindVertexArray(0);
glDisableVertexAttribArray(m_shaders->m_shQUAD.posAttrib);
scissor(nullptr);
}
@ -1564,14 +1579,19 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP<CTexture> tex, const CB
if (!skipCM && !usingFinalShader && (texType == TEXTURE_RGBA || texType == TEXTURE_RGBX))
shader = &m_shaders->m_shCM;
useProgram(shader->program);
glUseProgram(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) {
@ -1633,20 +1653,22 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP<CTexture> tex, const CB
glUniform1i(shader->applyTint, 0);
}
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,
};
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
};
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);
}
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);
if (!m_renderData.clipBox.empty() || !m_renderData.clipRegion.empty()) {
CRegion damageClip = m_renderData.clipBox;
@ -1671,8 +1693,9 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP<CTexture> tex, const CB
}
}
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDisableVertexAttribArray(shader->posAttrib);
glDisableVertexAttribArray(shader->texAttrib);
glBindTexture(tex->m_target, 0);
}
@ -1698,10 +1721,21 @@ void CHyprOpenGLImpl::renderTexturePrimitive(SP<CTexture> tex, const CBox& box)
glActiveTexture(GL_TEXTURE0);
glBindTexture(tex->m_target, tex->m_texID);
useProgram(shader->program);
glUseProgram(shader->program);
#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);
glBindVertexArray(shader->shaderVao);
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);
for (auto const& RECT : m_renderData.damage.getRects()) {
scissor(&RECT);
@ -1710,7 +1744,9 @@ void CHyprOpenGLImpl::renderTexturePrimitive(SP<CTexture> tex, const CBox& box)
scissor(nullptr);
glBindVertexArray(0);
glDisableVertexAttribArray(shader->posAttrib);
glDisableVertexAttribArray(shader->texAttrib);
glBindTexture(tex->m_target, 0);
}
@ -1733,8 +1769,14 @@ void CHyprOpenGLImpl::renderTextureMatte(SP<CTexture> tex, const CBox& box, CFra
SShader* shader = &m_shaders->m_shMATTE;
useProgram(shader->program);
glUseProgram(shader->program);
#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);
glUniform1i(shader->alphaMatte, 1);
@ -1745,7 +1787,11 @@ void CHyprOpenGLImpl::renderTextureMatte(SP<CTexture> tex, const CBox& box, CFra
auto matteTex = matte.getTexture();
glBindTexture(matteTex->m_target, matteTex->m_texID);
glBindVertexArray(shader->shaderVao);
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);
for (auto const& RECT : m_renderData.damage.getRects()) {
scissor(&RECT);
@ -1754,7 +1800,9 @@ void CHyprOpenGLImpl::renderTextureMatte(SP<CTexture> tex, const CBox& box, CFra
scissor(nullptr);
glBindVertexArray(0);
glDisableVertexAttribArray(shader->posAttrib);
glDisableVertexAttribArray(shader->texAttrib);
glBindTexture(tex->m_target, 0);
}
@ -1763,16 +1811,13 @@ 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
}
return blurFramebufferWithDamage(a, originalDamage, *m_renderData.currentFB);
}
CFramebuffer* CHyprOpenGLImpl::blurFramebufferWithDamage(float a, CRegion* originalDamage, CFramebuffer& source) {
TRACY_GPU_ZONE("RenderBlurFramebufferWithDamage");
TRACY_GPU_ZONE("RenderBlurMainFramebufferWithDamage");
const auto BLENDBEFORE = m_blend;
blend(false);
@ -1812,13 +1857,13 @@ CFramebuffer* CHyprOpenGLImpl::blurFramebufferWithDamage(float a, CRegion* origi
glActiveTexture(GL_TEXTURE0);
auto currentTex = source.getTexture();
auto currentTex = m_renderData.currentFB->getTexture();
glBindTexture(currentTex->m_target, currentTex->m_texID);
glTexParameteri(currentTex->m_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
useProgram(m_shaders->m_shBLURPREPARE.program);
glUseProgram(m_shaders->m_shBLURPREPARE.program);
// From FB to sRGB
const bool skipCM = !m_cmSupported || m_renderData.pMonitor->m_imageDescription == SImageDescription{};
@ -1837,12 +1882,21 @@ CFramebuffer* CHyprOpenGLImpl::blurFramebufferWithDamage(float a, CRegion* origi
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);
glBindVertexArray(m_shaders->m_shBLURPREPARE.shaderVao);
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);
if (!damage.empty()) {
for (auto const& RECT : damage.getRects()) {
@ -1851,7 +1905,9 @@ CFramebuffer* CHyprOpenGLImpl::blurFramebufferWithDamage(float a, CRegion* origi
}
}
glBindVertexArray(0);
glDisableVertexAttribArray(m_shaders->m_shBLURPREPARE.posAttrib);
glDisableVertexAttribArray(m_shaders->m_shBLURPREPARE.texAttrib);
currentRenderToFB = PMIRRORSWAPFB;
}
@ -1870,10 +1926,15 @@ CFramebuffer* CHyprOpenGLImpl::blurFramebufferWithDamage(float a, CRegion* origi
glTexParameteri(currentTex->m_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
useProgram(pShader->program);
glUseProgram(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));
@ -1884,7 +1945,12 @@ CFramebuffer* CHyprOpenGLImpl::blurFramebufferWithDamage(float a, CRegion* origi
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);
glBindVertexArray(pShader->shaderVao);
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);
if (!pDamage->empty()) {
for (auto const& RECT : pDamage->getRects()) {
scissor(&RECT, false /* this region is already transformed */);
@ -1892,7 +1958,8 @@ CFramebuffer* CHyprOpenGLImpl::blurFramebufferWithDamage(float a, CRegion* origi
}
}
glBindVertexArray(0);
glDisableVertexAttribArray(pShader->posAttrib);
glDisableVertexAttribArray(pShader->texAttrib);
if (currentRenderToFB != PMIRRORFB)
currentRenderToFB = PMIRRORFB;
@ -1937,14 +2004,24 @@ CFramebuffer* CHyprOpenGLImpl::blurFramebufferWithDamage(float a, CRegion* origi
glTexParameteri(currentTex->m_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
useProgram(m_shaders->m_shBLURFINISH.program);
glUseProgram(m_shaders->m_shBLURFINISH.program);
#ifndef GLES2
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);
glBindVertexArray(m_shaders->m_shBLURFINISH.shaderVao);
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);
if (!damage.empty()) {
for (auto const& RECT : damage.getRects()) {
@ -1953,7 +2030,8 @@ CFramebuffer* CHyprOpenGLImpl::blurFramebufferWithDamage(float a, CRegion* origi
}
}
glBindVertexArray(0);
glDisableVertexAttribArray(m_shaders->m_shBLURFINISH.posAttrib);
glDisableVertexAttribArray(m_shaders->m_shBLURFINISH.texAttrib);
if (currentRenderToFB != PMIRRORFB)
currentRenderToFB = PMIRRORFB;
@ -2146,7 +2224,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 && pSurface && std::round(pSurface->m_current.size.x * m_renderData.pMonitor->m_scale) == box.w &&
if (a >= 1.f && 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;
@ -2169,6 +2247,7 @@ 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;
@ -2269,14 +2348,20 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& gr
const auto BLEND = m_blend;
blend(true);
useProgram(m_shaders->m_shBORDER1.program);
glUseProgram(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));
@ -2298,7 +2383,11 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& gr
glUniform1f(m_shaders->m_shBORDER1.roundingPower, roundingPower);
glUniform1f(m_shaders->m_shBORDER1.thick, scaledBorderSize);
glBindVertexArray(m_shaders->m_shBORDER1.shaderVao);
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);
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};
@ -2317,7 +2406,8 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& gr
}
}
glBindVertexArray(0);
glDisableVertexAttribArray(m_shaders->m_shBORDER1.posAttrib);
glDisableVertexAttribArray(m_shaders->m_shBORDER1.texAttrib);
blend(BLEND);
}
@ -2356,8 +2446,15 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& gr
const auto BLEND = m_blend;
blend(true);
useProgram(m_shaders->m_shBORDER1.program);
glUseProgram(m_shaders->m_shBORDER1.program);
#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, 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));
@ -2383,7 +2480,11 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& gr
glUniform1f(m_shaders->m_shBORDER1.roundingPower, roundingPower);
glUniform1f(m_shaders->m_shBORDER1.thick, scaledBorderSize);
glBindVertexArray(m_shaders->m_shBORDER1.shaderVao);
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);
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};
@ -2402,7 +2503,9 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& gr
}
}
glBindVertexArray(0);
glDisableVertexAttribArray(m_shaders->m_shBORDER1.posAttrib);
glDisableVertexAttribArray(m_shaders->m_shBORDER1.texAttrib);
blend(BLEND);
}
@ -2431,13 +2534,18 @@ void CHyprOpenGLImpl::renderRoundedShadow(const CBox& box, int round, float roun
blend(true);
useProgram(m_shaders->m_shSHADOW.program);
glUseProgram(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);
@ -2453,7 +2561,11 @@ void CHyprOpenGLImpl::renderRoundedShadow(const CBox& box, int round, float roun
glUniform1f(m_shaders->m_shSHADOW.range, range);
glUniform1f(m_shaders->m_shSHADOW.shadowPower, SHADOWPOWER);
glBindVertexArray(m_shaders->m_shSHADOW.shaderVao);
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);
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};
@ -2472,7 +2584,8 @@ void CHyprOpenGLImpl::renderRoundedShadow(const CBox& box, int round, float roun
}
}
glBindVertexArray(0);
glDisableVertexAttribArray(m_shaders->m_shSHADOW.posAttrib);
glDisableVertexAttribArray(m_shaders->m_shSHADOW.texAttrib);
}
void CHyprOpenGLImpl::saveBufferForMirror(const CBox& box) {
@ -2592,20 +2705,26 @@ 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 ? 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;
const GLint glIFormat = CAIROFORMAT == CAIRO_FORMAT_RGB96F ?
#ifdef GLES2
GL_RGB32F_EXT :
#else
GL_RGB32F :
#endif
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;
const auto DATA = cairo_image_surface_get_data(CAIROSURFACE);
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);
@ -2683,8 +2802,10 @@ 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);
@ -2724,8 +2845,10 @@ 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);
@ -2734,14 +2857,6 @@ 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();
@ -2835,8 +2950,10 @@ 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);

View File

@ -114,12 +114,11 @@ struct SMonitorRenderData {
};
struct SCurrentRenderData {
PHLMONITORREF pMonitor;
Mat3x3 projection;
Mat3x3 savedProjection;
Mat3x3 monitorProjection;
PHLMONITORREF pMonitor;
Mat3x3 projection;
Mat3x3 savedProjection;
Mat3x3 monitorProjection;
// FIXME: raw pointer galore!
SMonitorRenderData* pCurrentMonData = nullptr;
CFramebuffer* currentFB = nullptr; // current rendering to
CFramebuffer* mainFB = nullptr; // main to render to
@ -240,11 +239,6 @@ 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;
@ -317,7 +311,6 @@ class CHyprOpenGLImpl {
SShader m_finalScreenShader;
CTimer m_globalTimer;
GLuint m_currentProgram;
SP<CTexture> m_missingAssetTexture;
SP<CTexture> m_backgroundTexture;
@ -326,6 +319,8 @@ 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);
@ -338,7 +333,6 @@ 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);

View File

@ -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() || pWindow->workspaceID() == pMonitor->activeSpecialWorkspaceID();
return pWindow->workspaceID() == pMonitor->activeWorkspaceID();
if (pWindow->m_pinned)
return true;
@ -493,6 +493,7 @@ 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();
@ -502,7 +503,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 && shouldBlur(pWindow);
renderdata.blur = !standalone && *PBLUR && !DONT_BLUR;
renderdata.pWindow = pWindow;
if (standalone) {
@ -571,7 +572,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_wlSurface->small() && !pWindow->m_wlSurface->m_fillIgnoreSmall && renderdata.blur) {
if (!pWindow->m_windowData.noBlur.valueOrDefault() && pWindow->m_wlSurface->small() && !pWindow->m_wlSurface->m_fillIgnoreSmall && renderdata.blur && *PBLUR) {
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;
@ -711,6 +712,8 @@ 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();
@ -718,7 +721,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 = shouldBlur(pLayer);
renderdata.blur = pLayer->m_forceBlur && *PBLUR;
renderdata.surface = pLayer->m_surface->resource();
renderdata.decorate = false;
renderdata.w = REALSIZ.x;
@ -871,15 +874,12 @@ 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,7 +896,6 @@ 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);
}
@ -941,9 +940,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);
}
}
@ -1037,7 +1036,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, ALPHA);
g_pHyprOpenGL->renderTexture(g_pHyprOpenGL->m_lockTtyTextTexture, texbox, 1.F);
}
}
@ -2280,6 +2279,9 @@ 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;
@ -2387,7 +2389,7 @@ void CHyprRenderer::makeRawWindowSnapshot(PHLWINDOW pWindow, CFramebuffer* pFram
makeEGLCurrent();
pFramebuffer->alloc(PMONITOR->m_pixelSize.x, PMONITOR->m_pixelSize.y, DRM_FORMAT_ABGR8888);
pFramebuffer->alloc(PMONITOR->m_pixelSize.x, PMONITOR->m_pixelSize.y, PMONITOR->m_output->state->state().drmFormat);
pFramebuffer->addStencil(g_pHyprOpenGL->m_renderData.pCurrentMonData->stencilTex);
beginRender(PMONITOR, fakeDamage, RENDER_MODE_FULL_FAKE, nullptr, pFramebuffer);
@ -2438,7 +2440,7 @@ void CHyprRenderer::makeWindowSnapshot(PHLWINDOW pWindow) {
const auto PFRAMEBUFFER = &g_pHyprOpenGL->m_windowFramebuffers[ref];
PFRAMEBUFFER->alloc(PMONITOR->m_pixelSize.x, PMONITOR->m_pixelSize.y, DRM_FORMAT_ABGR8888);
PFRAMEBUFFER->alloc(PMONITOR->m_pixelSize.x, PMONITOR->m_pixelSize.y, PMONITOR->m_output->state->state().drmFormat);
beginRender(PMONITOR, fakeDamage, RENDER_MODE_FULL_FAKE, nullptr, PFRAMEBUFFER);
@ -2446,8 +2448,21 @@ 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;
@ -2469,7 +2484,7 @@ void CHyprRenderer::makeLayerSnapshot(PHLLS pLayer) {
const auto PFRAMEBUFFER = &g_pHyprOpenGL->m_layerFramebuffers[pLayer];
PFRAMEBUFFER->alloc(PMONITOR->m_pixelSize.x, PMONITOR->m_pixelSize.y, DRM_FORMAT_ABGR8888);
PFRAMEBUFFER->alloc(PMONITOR->m_pixelSize.x, PMONITOR->m_pixelSize.y, PMONITOR->m_output->state->state().drmFormat);
beginRender(PMONITOR, fakeDamage, RENDER_MODE_FULL_FAKE, nullptr, PFRAMEBUFFER);
@ -2477,9 +2492,14 @@ 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;
@ -2514,25 +2534,14 @@ 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));
}
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));
damageMonitor(PMONITOR);
}
CTexPassElement::SRenderData data;
@ -2571,35 +2580,12 @@ 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;
}

View File

@ -45,11 +45,6 @@ struct SExplicitSyncSettings {
bool explicitEnabled = false, explicitKMSEnabled = false;
};
struct SRenderWorkspaceUntilData {
PHLLS ls;
PHLWINDOW w;
};
class CHyprRenderer {
public:
CHyprRenderer();
@ -122,23 +117,20 @@ 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;

View File

@ -1,48 +1,14 @@
#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;
if (shaderVao)
glDeleteVertexArrays(1, &shaderVao);
if (shaderVboPos)
glDeleteBuffers(1, &shaderVboPos);
if (shaderVboUv)
glDeleteBuffers(1, &shaderVboUv);
glDeleteProgram(program);
program = 0;
}

View File

@ -32,10 +32,6 @@ 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;
@ -80,6 +76,5 @@ struct SShader {
GLint brightness = -1;
GLint noise = -1;
void createVao();
void destroy();
};

View File

@ -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,10 +120,12 @@ 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));

View File

@ -332,8 +332,11 @@ 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);

View File

@ -42,6 +42,7 @@ 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();
@ -51,8 +52,9 @@ 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();
}
Debug::log(ERR, "getEdgeDefinedPoint: invalid configuration of edges");
UNREACHABLE();
return {};
}

View File

@ -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_position) * m_data.pMonitor->m_scale);
visibleRegion.translate((m_data.pos + m_data.localPos) * m_data.pMonitor->m_scale - m_data.pMonitor->m_position);
return visibleRegion;
}

View File

@ -11,14 +11,10 @@ CTexPassElement::CTexPassElement(const CTexPassElement::SRenderData& data_) : m_
void CTexPassElement::draw(const CRegion& damage) {
g_pHyprOpenGL->m_endFrame = m_data.flipEndFrame;
CScopeGuard x = {[this]() {
CScopeGuard x = {[]() {
//
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())
@ -26,16 +22,9 @@ 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);
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() {

View File

@ -11,16 +11,13 @@ class CTexPassElement : public IPassElement {
struct SRenderData {
SP<CTexture> tex;
CBox box;
float a = 1.F;
float blurA = 1.F;
float a = 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);

View File

@ -5,9 +5,7 @@
#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