mirror of https://github.com/hyprwm/Hyprland
initial tearing stuff, disabled cuz broken for now
This commit is contained in:
parent
5327565b33
commit
2b99f9cae7
22
Makefile
22
Makefile
|
@ -81,6 +81,16 @@ idle-protocol.c:
|
|||
|
||||
idle-protocol.o: idle-protocol.h
|
||||
|
||||
tearing-control-v1-protocol.h:
|
||||
$(WAYLAND_SCANNER) server-header \
|
||||
$(WAYLAND_PROTOCOLS)/staging/tearing-control/tearing-control-v1.xml $@
|
||||
|
||||
tearing-control-v1-protocol.c:
|
||||
$(WAYLAND_SCANNER) private-code \
|
||||
$(WAYLAND_PROTOCOLS)/staging/tearing-control/tearing-control-v1.xml $@
|
||||
|
||||
tearing-control-v1-protocol.o: tearing-control-v1-protocol.h
|
||||
|
||||
wlr-output-power-management-unstable-v1-protocol.h:
|
||||
$(WAYLAND_SCANNER) server-header \
|
||||
protocols/wlr-output-power-management-unstable-v1.xml $@
|
||||
|
@ -179,7 +189,7 @@ uninstall:
|
|||
rm -f ${PREFIX}/share/man/man1/Hyprland.1
|
||||
rm -f ${PREFIX}/share/man/man1/hyprctl.1
|
||||
|
||||
protocols: xdg-shell-protocol.o wlr-layer-shell-unstable-v1-protocol.o wlr-screencopy-unstable-v1-protocol.o idle-protocol.o ext-workspace-unstable-v1-protocol.o pointer-constraints-unstable-v1-protocol.o tablet-unstable-v2-protocol.o wlr-output-power-management-unstable-v1-protocol.o linux-dmabuf-unstable-v1-protocol.o
|
||||
protocols: xdg-shell-protocol.o wlr-layer-shell-unstable-v1-protocol.o wlr-screencopy-unstable-v1-protocol.o idle-protocol.o ext-workspace-unstable-v1-protocol.o pointer-constraints-unstable-v1-protocol.o tablet-unstable-v2-protocol.o wlr-output-power-management-unstable-v1-protocol.o linux-dmabuf-unstable-v1-protocol.o tearing-control-v1-protocol.o
|
||||
|
||||
fixwlr:
|
||||
sed -i -E 's/(soversion = 12)([^032]|$$)/soversion = 12032/g' subprojects/wlroots/meson.build
|
||||
|
@ -196,6 +206,16 @@ config:
|
|||
|
||||
cd subprojects/wlroots && ninja -C build/ install
|
||||
|
||||
configdebug:
|
||||
make protocols
|
||||
|
||||
make fixwlr
|
||||
|
||||
cd subprojects/wlroots && meson ./build --prefix=/usr --buildtype=debug -Dwerror=false -Dexamples=false
|
||||
cd subprojects/wlroots && ninja -C build/
|
||||
|
||||
cd subprojects/wlroots && ninja -C build/ install
|
||||
|
||||
man:
|
||||
pandoc ./docs/Hyprland.1.rst \
|
||||
--standalone \
|
||||
|
|
|
@ -179,6 +179,8 @@ CCompositor::CCompositor() {
|
|||
|
||||
m_sWLRActivation = wlr_xdg_activation_v1_create(m_sWLDisplay);
|
||||
|
||||
m_sWLRTearingMgr = wlr_tearing_control_manager_v1_create(m_sWLDisplay, 1);
|
||||
|
||||
m_sWLRHeadlessBackend = wlr_headless_backend_create(m_sWLDisplay);
|
||||
|
||||
if (!m_sWLRHeadlessBackend) {
|
||||
|
@ -244,6 +246,7 @@ void CCompositor::initAllSignals() {
|
|||
addWLSignal(&m_sWLRIMEMgr->events.input_method, &Events::listen_newIME, m_sWLRIMEMgr, "IMEMgr");
|
||||
addWLSignal(&m_sWLRTextInputMgr->events.text_input, &Events::listen_newTextInput, m_sWLRTextInputMgr, "TextInputMgr");
|
||||
addWLSignal(&m_sWLRActivation->events.request_activate, &Events::listen_activateXDG, m_sWLRActivation, "ActivationV1");
|
||||
addWLSignal(&m_sWLRTearingMgr->events.new_object, &Events::listen_tearingNew, m_sWLRTearingMgr, "TearingMgr");
|
||||
|
||||
if(m_sWRLDRMLeaseMgr)
|
||||
addWLSignal(&m_sWRLDRMLeaseMgr->events.request, &Events::listen_leaseRequest, &m_sWRLDRMLeaseMgr, "DRM");
|
||||
|
@ -1759,6 +1762,8 @@ void CCompositor::setWindowFullscreen(CWindow* pWindow, bool on, eFullscreenMode
|
|||
|
||||
// DMAbuf stuff for direct scanout
|
||||
g_pHyprRenderer->setWindowScanoutMode(pWindow);
|
||||
|
||||
g_pHyprRenderer->damageMonitor(PMONITOR);
|
||||
}
|
||||
|
||||
void CCompositor::moveUnmanagedX11ToWindows(CWindow* pWindow) {
|
||||
|
|
|
@ -72,6 +72,7 @@ public:
|
|||
wlr_xdg_activation_v1* m_sWLRActivation;
|
||||
wlr_linux_dmabuf_v1* m_sWLRLinuxDMABuf;
|
||||
wlr_backend* m_sWLRHeadlessBackend;
|
||||
wlr_tearing_control_manager_v1* m_sWLRTearingMgr;
|
||||
// ------------------------------------------------- //
|
||||
|
||||
|
||||
|
|
|
@ -379,3 +379,8 @@ void CWindow::updateDynamicRules() {
|
|||
applyDynamicRule(r);
|
||||
}
|
||||
}
|
||||
|
||||
bool CWindow::shouldImmediate() {
|
||||
return false; // safeguard. Disabled for now.
|
||||
return m_bTearingHint == 1 || m_sAdditionalConfigData.forceTearing;
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ struct SWindowAdditionalConfigData {
|
|||
bool forceNoBorder = false;
|
||||
bool forceNoShadow = false;
|
||||
bool windowDanceCompat = false;
|
||||
bool forceTearing = false;
|
||||
};
|
||||
|
||||
struct SWindowRule {
|
||||
|
@ -180,6 +181,9 @@ public:
|
|||
// for idle inhibiting windows
|
||||
eIdleInhibitMode m_eIdleInhibitMode = IDLEINHIBIT_NONE;
|
||||
|
||||
// tearing hints
|
||||
bool m_bTearingHint = false;
|
||||
|
||||
// For the list lookup
|
||||
bool operator==(const CWindow& rhs) {
|
||||
return m_uSurface.xdg == rhs.m_uSurface.xdg && m_uSurface.xwayland == rhs.m_uSurface.xwayland && m_vPosition == rhs.m_vPosition && m_vSize == rhs.m_vSize && m_bFadingOut == rhs.m_bFadingOut;
|
||||
|
@ -204,6 +208,7 @@ public:
|
|||
bool isHidden();
|
||||
void applyDynamicRule(const SWindowRule& r);
|
||||
void updateDynamicRules();
|
||||
bool shouldImmediate();
|
||||
|
||||
private:
|
||||
// For hidden windows and stuff
|
||||
|
|
|
@ -681,6 +681,7 @@ bool windowRuleValid(const std::string& RULE) {
|
|||
&& RULE != "pin"
|
||||
&& RULE != "noanim"
|
||||
&& RULE != "windowdance"
|
||||
&& RULE != "immediate"
|
||||
&& RULE.find("animation") != 0
|
||||
&& RULE.find("rounding") != 0
|
||||
&& RULE.find("workspace") != 0
|
||||
|
|
|
@ -23,6 +23,8 @@ void Debug::wlrLog(wlr_log_importance level, const char* fmt, va_list args) {
|
|||
ofs << "[wlr] " << output << "\n";
|
||||
|
||||
ofs.close();
|
||||
|
||||
std::cout << "[wlr] " << output << "\n";
|
||||
}
|
||||
|
||||
void Debug::log(LogLevel level, const char* fmt, ...) {
|
||||
|
|
|
@ -157,4 +157,9 @@ namespace Events {
|
|||
|
||||
LISTENER(holdBegin);
|
||||
LISTENER(holdEnd);
|
||||
|
||||
// Tearing
|
||||
LISTENER(tearingNew);
|
||||
DYNLISTENFUNC(tearingSet);
|
||||
DYNLISTENFUNC(tearingDestroy);
|
||||
};
|
||||
|
|
|
@ -213,3 +213,32 @@ void Events::listener_newTextInput(wl_listener* listener, void* data) {
|
|||
|
||||
g_pInputManager->m_sIMERelay.onNewTextInput((wlr_text_input_v3*)data);
|
||||
}
|
||||
|
||||
void Events::listener_tearingNew(wl_listener* listener, void* data) {
|
||||
Debug::log(LOG, "New tearing object at %x", data);
|
||||
|
||||
const auto foundHint = wlr_tearing_control_manager_v1_surface_hint_from_surface(g_pCompositor->m_sWLRTearingMgr, ((wlr_tearing_control_v1*)data)->surface);
|
||||
|
||||
Debug::log(LOG, "Surface associated: %x, check 2: %i", ((wlr_tearing_control_v1*)data)->surface, foundHint);
|
||||
|
||||
const auto NEWCTRL = &g_pHyprRenderer->m_lTearingControllers.emplace_back();
|
||||
NEWCTRL->pWlrHint = (wlr_tearing_control_v1*)data;
|
||||
|
||||
NEWCTRL->hyprListener_destroy.initCallback(&NEWCTRL->pWlrHint->events.destroy, [&] (void* owner, void* data) {
|
||||
Debug::log(LOG, "Destroyed %x tearing", ((STearingController*)owner)->pWlrHint);
|
||||
|
||||
g_pHyprRenderer->m_lTearingControllers.remove(*((STearingController*)owner));
|
||||
}, NEWCTRL, "TearingController");
|
||||
|
||||
NEWCTRL->hyprListener_set.initCallback(&NEWCTRL->pWlrHint->events.set_hint, [&] (void* owner, void* data) {
|
||||
const auto TEARINGHINT = (STearingController*)owner;
|
||||
|
||||
const auto PWINDOW = g_pCompositor->getWindowFromSurface(TEARINGHINT->pWlrHint->surface);
|
||||
|
||||
if (PWINDOW) {
|
||||
PWINDOW->m_bTearingHint = TEARINGHINT->pWlrHint->hint;
|
||||
|
||||
Debug::log(LOG, "Hint %x (window %x) set tearing hint to %d", TEARINGHINT->pWlrHint, PWINDOW, TEARINGHINT->pWlrHint->hint);
|
||||
}
|
||||
}, NEWCTRL, "TearingController");
|
||||
}
|
|
@ -168,6 +168,10 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
|||
}
|
||||
}
|
||||
|
||||
// check if we have a solitary client. If so, reject any draws not queued by our client (passed in data)
|
||||
if (PMONITOR->solitaryClient && data != PMONITOR->solitaryClient && PMONITOR->solitaryClient->shouldImmediate())
|
||||
return;
|
||||
|
||||
timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
|
||||
|
@ -188,6 +192,12 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (PMONITOR->solitaryClient) {
|
||||
// force damage
|
||||
hasChanged = true;
|
||||
pixman_region32_union_rect(&damage, &damage, 0, 0, (int)PMONITOR->vecTransformedSize.x * 10, (int)PMONITOR->vecTransformedSize.y * 10);
|
||||
}
|
||||
|
||||
// we need to cleanup fading out when rendering the appropriate context
|
||||
g_pCompositor->cleanupFadingOut(PMONITOR->ID);
|
||||
|
||||
|
|
|
@ -183,6 +183,8 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
|||
} else {
|
||||
Debug::log(ERR, "Rule idleinhibit: unknown mode %s", IDLERULE.c_str());
|
||||
}
|
||||
} else if (r.szRule == "immediate") {
|
||||
PWINDOW->m_sAdditionalConfigData.forceTearing = true;
|
||||
}
|
||||
PWINDOW->applyDynamicRule(r);
|
||||
}
|
||||
|
@ -659,12 +661,10 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
|||
void Events::listener_commitWindow(void* owner, void* data) {
|
||||
CWindow* PWINDOW = (CWindow*)owner;
|
||||
|
||||
if (!PWINDOW->m_bMappedX11 || PWINDOW->isHidden() || (PWINDOW->m_bIsX11 && !PWINDOW->m_bMappedX11))
|
||||
if (!PWINDOW->m_bIsMapped || PWINDOW->isHidden())
|
||||
return;
|
||||
|
||||
g_pHyprRenderer->damageSurface(g_pXWaylandManager->getWindowSurface(PWINDOW), PWINDOW->m_vRealPosition.goalv().x, PWINDOW->m_vRealPosition.goalv().y);
|
||||
|
||||
// Debug::log(LOG, "Window %x committed", PWINDOW); // SPAM!
|
||||
}
|
||||
|
||||
void Events::listener_destroyWindow(void* owner, void* data) {
|
||||
|
|
|
@ -229,10 +229,16 @@ void CMonitor::onDisconnect() {
|
|||
}
|
||||
|
||||
void CMonitor::addDamage(pixman_region32_t* rg) {
|
||||
if (solitaryClient) // when there is a solitary client, we adjust to its commits.
|
||||
return;
|
||||
|
||||
wlr_output_damage_add(damage, rg);
|
||||
}
|
||||
|
||||
void CMonitor::addDamage(wlr_box* box) {
|
||||
if (solitaryClient)
|
||||
return;
|
||||
|
||||
wlr_output_damage_add_box(damage, box);
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,9 @@ public:
|
|||
bool enabled10bit = false; // as above, this can be TRUE even if 10 bit failed.
|
||||
bool createdByUser = false;
|
||||
|
||||
// will attempt DS
|
||||
CWindow* solitaryClient = nullptr; // used for stuff like tearing / VRR
|
||||
|
||||
// mirroring
|
||||
CMonitor* pMirrorOf = nullptr;
|
||||
std::vector<CMonitor*> mirrors;
|
||||
|
@ -68,6 +71,7 @@ public:
|
|||
void onDisconnect();
|
||||
void addDamage(pixman_region32_t* rg);
|
||||
void addDamage(wlr_box* box);
|
||||
void forceDamageEntire();
|
||||
void setMirror(const std::string&);
|
||||
bool isMirror();
|
||||
|
||||
|
|
|
@ -224,6 +224,18 @@ void Events::listener_commitSubsurface(void* owner, void* data) {
|
|||
}
|
||||
}
|
||||
|
||||
// check window if X11, we have a special case
|
||||
if (pNode->pWindowOwner) {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(pNode->pWindowOwner->m_iMonitorID);
|
||||
|
||||
if (PMONITOR->solitaryClient == pNode->pWindowOwner && pNode->pWindowOwner->shouldImmediate()) {
|
||||
// TODO: we should do an asynchronous flip here. wlr patch needed.
|
||||
listener_monitorFrame(PMONITOR, pNode->pWindowOwner);
|
||||
|
||||
Debug::log(LOG, "damage commit!");
|
||||
}
|
||||
}
|
||||
|
||||
g_pHyprRenderer->damageSurface(pNode->pSurface, lx, ly);
|
||||
}
|
||||
|
||||
|
|
|
@ -349,3 +349,14 @@ struct SSwitchDevice {
|
|||
return pWlrDevice == other.pWlrDevice;
|
||||
}
|
||||
};
|
||||
|
||||
struct STearingController {
|
||||
wlr_tearing_control_v1* pWlrHint = nullptr;
|
||||
|
||||
DYNLISTENER(set);
|
||||
DYNLISTENER(destroy);
|
||||
|
||||
bool operator==(const STearingController& other) {
|
||||
return pWlrHint == other.pWlrHint;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -103,6 +103,7 @@ extern "C" {
|
|||
#include <wlr/backend/headless.h>
|
||||
#include <wlr/backend/multi.h>
|
||||
#include <wlr/backend/wayland.h>
|
||||
#include <wlr/types/wlr_tearing_control_v1.h>
|
||||
|
||||
#include <drm_fourcc.h>
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ int main(int argc, char** argv) {
|
|||
setenv("_JAVA_AWT_WM_NONREPARENTING", "1", 0);
|
||||
|
||||
// parse some args
|
||||
bool logWlr = false;
|
||||
std::string configPath;
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
if (!strcmp(argv[i], "--i-am-really-stupid"))
|
||||
|
@ -30,6 +31,8 @@ int main(int argc, char** argv) {
|
|||
else if ((!strcmp(argv[i], "-c") || !strcmp(argv[i], "--config")) && argc >= i + 2) {
|
||||
configPath = std::string(argv[++i]);
|
||||
Debug::log(LOG, "Using config location %s.", configPath.c_str());
|
||||
} else if (!strcmp(argv[i], "--log-wlr")) {
|
||||
logWlr = true;
|
||||
} else {
|
||||
std::cout << "Hyprland usage: Hyprland [arg [...]].\n\nArguments:\n" <<
|
||||
"--help -h | Show this help message\n" <<
|
||||
|
@ -53,7 +56,7 @@ int main(int argc, char** argv) {
|
|||
std::cout << "Welcome to Hyprland!\n";
|
||||
|
||||
const auto LOGWLR = getenv("HYPRLAND_LOG_WLR");
|
||||
if (LOGWLR && std::string(LOGWLR) == "1")
|
||||
if ((LOGWLR && std::string(LOGWLR) == "1") || logWlr)
|
||||
wlr_log_init(WLR_DEBUG, Debug::wlrLog);
|
||||
|
||||
// let's init the compositor.
|
||||
|
|
|
@ -556,6 +556,8 @@ void countSubsurfacesIter(wlr_surface* pSurface, int x, int y, void* data) {
|
|||
}
|
||||
|
||||
bool CHyprRenderer::attemptDirectScanout(CMonitor* pMonitor) {
|
||||
pMonitor->solitaryClient = nullptr;
|
||||
|
||||
if (!pMonitor->mirrors.empty())
|
||||
return false; // do not DS if this monitor is being mirrored. Will break the functionality.
|
||||
|
||||
|
@ -609,6 +611,7 @@ bool CHyprRenderer::attemptDirectScanout(CMonitor* pMonitor) {
|
|||
|
||||
// finally, we should be GTG.
|
||||
wlr_output_attach_buffer(pMonitor->output, &PSURFACE->buffer->base);
|
||||
pMonitor->solitaryClient = PCANDIDATE;
|
||||
|
||||
if (!wlr_output_test(pMonitor->output)) {
|
||||
return false;
|
||||
|
@ -620,10 +623,8 @@ bool CHyprRenderer::attemptDirectScanout(CMonitor* pMonitor) {
|
|||
wlr_presentation_surface_sampled_on_output(g_pCompositor->m_sWLRPresentation, PSURFACE, pMonitor->output);
|
||||
|
||||
if (wlr_output_commit(pMonitor->output)) {
|
||||
if (!m_pLastScanout) {
|
||||
if (!m_pLastScanout)
|
||||
m_pLastScanout = PCANDIDATE;
|
||||
Debug::log(LOG, "Entered a direct scanout to %x: \"%s\"", PCANDIDATE, PCANDIDATE->m_szTitle.c_str());
|
||||
}
|
||||
} else {
|
||||
m_pLastScanout = nullptr;
|
||||
return false;
|
||||
|
|
|
@ -51,6 +51,8 @@ public:
|
|||
bool attemptDirectScanout(CMonitor*);
|
||||
void setWindowScanoutMode(CWindow*);
|
||||
|
||||
std::list<STearingController> m_lTearingControllers;
|
||||
|
||||
private:
|
||||
void arrangeLayerArray(CMonitor*, const std::vector<std::unique_ptr<SLayerSurface>>&, bool, wlr_box*);
|
||||
void renderWorkspaceWithFullscreenWindow(CMonitor*, CWorkspace*, timespec*);
|
||||
|
|
Loading…
Reference in New Issue