summaryrefslogtreecommitdiff
path: root/src/render/OpenGL.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/render/OpenGL.cpp')
-rw-r--r--src/render/OpenGL.cpp154
1 files changed, 135 insertions, 19 deletions
diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp
index 3c30c4a1..436ba26c 100644
--- a/src/render/OpenGL.cpp
+++ b/src/render/OpenGL.cpp
@@ -9,6 +9,7 @@
#include "Renderer.hpp"
#include "../Compositor.hpp"
#include "../helpers/MiscFunctions.hpp"
+#include "../helpers/CursorShapes.hpp"
#include "../config/ConfigValue.hpp"
#include "../config/ConfigManager.hpp"
#include "../managers/PointerManager.hpp"
@@ -20,6 +21,7 @@
#include "../managers/HookSystemManager.hpp"
#include "../managers/input/InputManager.hpp"
#include "../managers/eventLoop/EventLoopManager.hpp"
+#include "../managers/CursorManager.hpp"
#include "../helpers/fs/FsUtils.hpp"
#include "../helpers/MainLoopExecutor.hpp"
#include "debug/HyprNotificationOverlay.hpp"
@@ -30,6 +32,8 @@
#include "pass/ClearPassElement.hpp"
#include "render/Shader.hpp"
#include "AsyncResourceGatherer.hpp"
+#include <ranges>
+#include <algorithm>
#include <string>
#include <xf86drm.h>
#include <fcntl.h>
@@ -381,6 +385,50 @@ CHyprOpenGLImpl::CHyprOpenGLImpl() : m_drmFD(g_pCompositor->m_drmRenderNode.fd >
m_globalTimer.reset();
pushMonitorTransformEnabled(false);
+
+ static auto addLastPressToHistory = [this](const Vector2D& pos, bool killing, bool touch) {
+ // shift the new pos and time in
+ std::ranges::rotate(m_pressedHistoryPositions, m_pressedHistoryPositions.end() - 1);
+ m_pressedHistoryPositions[0] = pos;
+
+ std::ranges::rotate(m_pressedHistoryTimers, m_pressedHistoryTimers.end() - 1);
+ m_pressedHistoryTimers[0].reset();
+
+ // shift killed flag in
+ m_pressedHistoryKilled <<= 1;
+ m_pressedHistoryKilled |= killing ? 1 : 0;
+#if POINTER_PRESSED_HISTORY_LENGTH < 32
+ m_pressedHistoryKilled &= (1 >> POINTER_PRESSED_HISTORY_LENGTH) - 1;
+#endif
+
+ // shift touch flag in
+ m_pressedHistoryTouched <<= 1;
+ m_pressedHistoryTouched |= touch ? 1 : 0;
+#if POINTER_PRESSED_HISTORY_LENGTH < 32
+ m_pressedHistoryTouched &= (1 >> POINTER_PRESSED_HISTORY_LENGTH) - 1;
+#endif
+ };
+
+ static auto P2 = g_pHookSystem->hookDynamic("mouseButton", [](void* self, SCallbackInfo& info, std::any e) {
+ auto E = std::any_cast<IPointer::SButtonEvent>(e);
+
+ if (E.state != WL_POINTER_BUTTON_STATE_PRESSED)
+ return;
+
+ addLastPressToHistory(g_pInputManager->getMouseCoordsInternal(), g_pInputManager->getClickMode() == CLICKMODE_KILL, false);
+ });
+
+ static auto P3 = g_pHookSystem->hookDynamic("touchDown", [](void* self, SCallbackInfo& info, std::any e) {
+ auto E = std::any_cast<ITouch::SDownEvent>(e);
+
+ auto PMONITOR = g_pCompositor->getMonitorFromName(!E.device->m_boundOutput.empty() ? E.device->m_boundOutput : "");
+
+ PMONITOR = PMONITOR ? PMONITOR : g_pCompositor->m_lastMonitor.lock();
+
+ const auto TOUCH_COORDS = PMONITOR->m_position + (E.pos * PMONITOR->m_size);
+
+ addLastPressToHistory(TOUCH_COORDS, g_pInputManager->getClickMode() == CLICKMODE_KILL, true);
+ });
}
CHyprOpenGLImpl::~CHyprOpenGLImpl() {
@@ -1240,30 +1288,59 @@ void CHyprOpenGLImpl::applyScreenShader(const std::string& path) {
return;
}
- m_finalScreenShader.uniformLocations[SHADER_POINTER] = glGetUniformLocation(m_finalScreenShader.program, "pointer_position");
- m_finalScreenShader.uniformLocations[SHADER_PROJ] = glGetUniformLocation(m_finalScreenShader.program, "proj");
- m_finalScreenShader.uniformLocations[SHADER_TEX] = glGetUniformLocation(m_finalScreenShader.program, "tex");
- m_finalScreenShader.uniformLocations[SHADER_TIME] = glGetUniformLocation(m_finalScreenShader.program, "time");
+ m_finalScreenShader.uniformLocations[SHADER_POINTER_HIDDEN] = glGetUniformLocation(m_finalScreenShader.program, "pointer_hidden");
+ m_finalScreenShader.uniformLocations[SHADER_POINTER_KILLING] = glGetUniformLocation(m_finalScreenShader.program, "pointer_killing");
+ m_finalScreenShader.uniformLocations[SHADER_POINTER_SHAPE] = glGetUniformLocation(m_finalScreenShader.program, "pointer_shape");
+ m_finalScreenShader.uniformLocations[SHADER_POINTER_SHAPE_PREVIOUS] = glGetUniformLocation(m_finalScreenShader.program, "pointer_shape_previous");
+ m_finalScreenShader.uniformLocations[SHADER_POINTER_SWITCH_TIME] = glGetUniformLocation(m_finalScreenShader.program, "pointer_switch_time");
+ m_finalScreenShader.uniformLocations[SHADER_POINTER_PRESSED_POSITIONS] = glGetUniformLocation(m_finalScreenShader.program, "pointer_pressed_positions");
+ m_finalScreenShader.uniformLocations[SHADER_POINTER_PRESSED_TIMES] = glGetUniformLocation(m_finalScreenShader.program, "pointer_pressed_times");
+ m_finalScreenShader.uniformLocations[SHADER_POINTER_PRESSED_KILLED] = glGetUniformLocation(m_finalScreenShader.program, "pointer_pressed_killed");
+ m_finalScreenShader.uniformLocations[SHADER_POINTER_PRESSED_TOUCHED] = glGetUniformLocation(m_finalScreenShader.program, "pointer_pressed_touched");
+ m_finalScreenShader.uniformLocations[SHADER_POINTER_INACTIVE_TIMEOUT] = glGetUniformLocation(m_finalScreenShader.program, "pointer_inactive_timeout");
+ m_finalScreenShader.uniformLocations[SHADER_POINTER_LAST_ACTIVE] = glGetUniformLocation(m_finalScreenShader.program, "pointer_last_active");
+ m_finalScreenShader.uniformLocations[SHADER_POINTER_SIZE] = glGetUniformLocation(m_finalScreenShader.program, "pointer_size");
+ m_finalScreenShader.uniformLocations[SHADER_POINTER] = glGetUniformLocation(m_finalScreenShader.program, "pointer_position");
+ m_finalScreenShader.uniformLocations[SHADER_PROJ] = glGetUniformLocation(m_finalScreenShader.program, "proj");
+ m_finalScreenShader.uniformLocations[SHADER_TEX] = glGetUniformLocation(m_finalScreenShader.program, "tex");
+ m_finalScreenShader.uniformLocations[SHADER_TIME] = glGetUniformLocation(m_finalScreenShader.program, "time");
if (m_finalScreenShader.uniformLocations[SHADER_TIME] != -1)
m_finalScreenShader.initialTime = m_globalTimer.getSeconds();
m_finalScreenShader.uniformLocations[SHADER_WL_OUTPUT] = glGetUniformLocation(m_finalScreenShader.program, "wl_output");
m_finalScreenShader.uniformLocations[SHADER_FULL_SIZE] = glGetUniformLocation(m_finalScreenShader.program, "screen_size");
if (m_finalScreenShader.uniformLocations[SHADER_FULL_SIZE] == -1)
m_finalScreenShader.uniformLocations[SHADER_FULL_SIZE] = glGetUniformLocation(m_finalScreenShader.program, "screenSize");
- if (m_finalScreenShader.uniformLocations[SHADER_TIME] != -1 && *PDT != 0 && !g_pHyprRenderer->m_crashingInProgress) {
- // The screen shader uses the "time" uniform
- // Since the screen shader could change every frame, damage tracking *needs* to be disabled
- g_pConfigManager->addParseError("Screen shader: Screen shader uses uniform 'time', which requires debug:damage_tracking to be switched off.\n"
- "WARNING: Disabling damage tracking will *massively* increase GPU utilization!");
- }
m_finalScreenShader.uniformLocations[SHADER_TEX_ATTRIB] = glGetAttribLocation(m_finalScreenShader.program, "texcoord");
m_finalScreenShader.uniformLocations[SHADER_POS_ATTRIB] = glGetAttribLocation(m_finalScreenShader.program, "pos");
- if (m_finalScreenShader.uniformLocations[SHADER_POINTER] != -1 && *PDT != 0 && !g_pHyprRenderer->m_crashingInProgress) {
- // The screen shader uses the "pointer_position" uniform
+
+ static auto uniformRequireNoDamage = [this](eShaderUniform uniform, const std::string& name) {
+ if (*PDT == 0)
+ return;
+ if (m_finalScreenShader.uniformLocations[uniform] == -1)
+ return;
+
+ // The screen shader uses the uniform
// Since the screen shader could change every frame, damage tracking *needs* to be disabled
- g_pConfigManager->addParseError("Screen shader: Screen shader uses uniform 'pointerPosition', which requires debug:damage_tracking to be switched off.\n"
- "WARNING: Disabling damage tracking will *massively* increase GPU utilization!");
- }
+ g_pConfigManager->addParseError(std::format("Screen shader: Screen shader uses uniform '{}', which requires debug:damage_tracking to be switched off.\n"
+ "WARNING:(Disabling damage tracking will *massively* increase GPU utilization!",
+ name));
+ };
+
+ // Allow glitch shader to use time uniform whighout damage tracking
+ if (!g_pHyprRenderer->m_crashingInProgress)
+ uniformRequireNoDamage(SHADER_TIME, "time");
+
+ uniformRequireNoDamage(SHADER_POINTER, "pointer_position");
+ uniformRequireNoDamage(SHADER_POINTER_PRESSED_POSITIONS, "pointer_pressed_positions");
+ uniformRequireNoDamage(SHADER_POINTER_PRESSED_TIMES, "pointer_pressed_times");
+ uniformRequireNoDamage(SHADER_POINTER_PRESSED_KILLED, "pointer_pressed_killed");
+ uniformRequireNoDamage(SHADER_POINTER_PRESSED_TOUCHED, "pointer_pressed_touched");
+ uniformRequireNoDamage(SHADER_POINTER_LAST_ACTIVE, "pointer_last_active");
+ uniformRequireNoDamage(SHADER_POINTER_HIDDEN, "pointer_hidden");
+ uniformRequireNoDamage(SHADER_POINTER_KILLING, "pointer_killing");
+ uniformRequireNoDamage(SHADER_POINTER_SHAPE, "pointer_shape");
+ uniformRequireNoDamage(SHADER_POINTER_SHAPE_PREVIOUS, "pointer_shape_previous");
+
m_finalScreenShader.createVao();
}
@@ -1539,9 +1616,10 @@ void CHyprOpenGLImpl::renderTextureInternal(SP<CTexture> tex, const CBox& box, c
CBox newBox = box;
m_renderData.renderModif.applyToBox(newBox);
- static const auto PDT = CConfigValue<Hyprlang::INT>("debug:damage_tracking");
- static const auto PPASS = CConfigValue<Hyprlang::INT>("render:cm_fs_passthrough");
- static const auto PENABLECM = CConfigValue<Hyprlang::INT>("render:cm_enabled");
+ static const auto PDT = CConfigValue<Hyprlang::INT>("debug:damage_tracking");
+ static const auto PPASS = CConfigValue<Hyprlang::INT>("render:cm_fs_passthrough");
+ static const auto PENABLECM = CConfigValue<Hyprlang::INT>("render:cm_enabled");
+ static const auto PCURSORTIMEOUT = CConfigValue<Hyprlang::FLOAT>("cursor:inactive_timeout");
// get the needed transform for this texture
const bool TRANSFORMS_MATCH = wlTransformToHyprutils(m_renderData.pMonitor->m_transform) == tex->m_transform; // FIXME: combine them properly!!!
@@ -1639,6 +1717,12 @@ void CHyprOpenGLImpl::renderTextureInternal(SP<CTexture> tex, const CBox& box, c
if (usingFinalShader) {
shader->setUniformInt(SHADER_WL_OUTPUT, m_renderData.pMonitor->m_id);
shader->setUniformFloat2(SHADER_FULL_SIZE, m_renderData.pMonitor->m_pixelSize.x, m_renderData.pMonitor->m_pixelSize.y);
+ shader->setUniformFloat(SHADER_POINTER_INACTIVE_TIMEOUT, *PCURSORTIMEOUT);
+ shader->setUniformInt(SHADER_POINTER_HIDDEN, g_pHyprRenderer->m_cursorHiddenByCondition);
+ shader->setUniformInt(SHADER_POINTER_KILLING, g_pInputManager->getClickMode() == CLICKMODE_KILL);
+ shader->setUniformInt(SHADER_POINTER_SHAPE, g_pHyprRenderer->m_lastCursorData.shape);
+ shader->setUniformInt(SHADER_POINTER_SHAPE_PREVIOUS, g_pHyprRenderer->m_lastCursorData.shapePrevious);
+ shader->setUniformFloat(SHADER_POINTER_SIZE, g_pCursorManager->getScaledSize());
}
if (usingFinalShader && *PDT == 0) {
@@ -1646,9 +1730,41 @@ void CHyprOpenGLImpl::renderTextureInternal(SP<CTexture> tex, const CBox& box, c
Vector2D p = ((g_pInputManager->getMouseCoordsInternal() - pMonitor->m_position) * pMonitor->m_scale);
p = p.transform(wlTransformToHyprutils(pMonitor->m_transform), pMonitor->m_pixelSize);
shader->setUniformFloat2(SHADER_POINTER, p.x / pMonitor->m_pixelSize.x, p.y / pMonitor->m_pixelSize.y);
- } else if (usingFinalShader)
+
+ std::vector<float> pressedPos = m_pressedHistoryPositions | std::views::transform([&](const Vector2D& vec) {
+ Vector2D pPressed = ((vec - pMonitor->m_position) * pMonitor->m_scale);
+ pPressed = pPressed.transform(wlTransformToHyprutils(pMonitor->m_transform), pMonitor->m_pixelSize);
+ return std::array<float, 2>{pPressed.x / pMonitor->m_pixelSize.x, pPressed.y / pMonitor->m_pixelSize.y};
+ }) |
+ std::views::join | std::ranges::to<std::vector<float>>();
+
+ shader->setUniform2fv(SHADER_POINTER_PRESSED_POSITIONS, pressedPos.size(), pressedPos);
+
+ std::vector<float> pressedTime =
+ m_pressedHistoryTimers | std::views::transform([](const CTimer& timer) { return timer.getSeconds(); }) | std::ranges::to<std::vector<float>>();
+
+ shader->setUniform1fv(SHADER_POINTER_PRESSED_TIMES, pressedTime.size(), pressedTime);
+
+ shader->setUniformInt(SHADER_POINTER_PRESSED_KILLED, m_pressedHistoryKilled);
+ shader->setUniformInt(SHADER_POINTER_PRESSED_TOUCHED, m_pressedHistoryTouched);
+
+ shader->setUniformFloat(SHADER_POINTER_LAST_ACTIVE, g_pInputManager->m_lastCursorMovement.getSeconds());
+ shader->setUniformFloat(SHADER_POINTER_SWITCH_TIME, g_pHyprRenderer->m_lastCursorData.switchedTimer.getSeconds());
+
+ } else if (usingFinalShader) {
shader->setUniformFloat2(SHADER_POINTER, 0.f, 0.f);
+ static const std::vector<float> pressedPosDefault(POINTER_PRESSED_HISTORY_LENGTH * 2uz, 0.f);
+ static const std::vector<float> pressedTimeDefault(POINTER_PRESSED_HISTORY_LENGTH, 0.f);
+
+ shader->setUniform2fv(SHADER_POINTER_PRESSED_POSITIONS, pressedPosDefault.size(), pressedPosDefault);
+ shader->setUniform1fv(SHADER_POINTER_PRESSED_TIMES, pressedTimeDefault.size(), pressedTimeDefault);
+ shader->setUniformInt(SHADER_POINTER_PRESSED_KILLED, 0);
+
+ shader->setUniformFloat(SHADER_POINTER_LAST_ACTIVE, 0.f);
+ shader->setUniformFloat(SHADER_POINTER_SWITCH_TIME, 0.f);
+ }
+
if (CRASHING) {
shader->setUniformFloat(SHADER_DISTORT, g_pHyprRenderer->m_crashingDistort);
shader->setUniformFloat2(SHADER_FULL_SIZE, m_renderData.pMonitor->m_pixelSize.x, m_renderData.pMonitor->m_pixelSize.y);