initial tearing stuff, disabled cuz broken for now

This commit is contained in:
vaxerski 2022-11-22 21:50:20 +00:00
parent 5327565b33
commit 2b99f9cae7
19 changed files with 131 additions and 8 deletions

View File

@ -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 \

View File

@ -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) {

View File

@ -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;
// ------------------------------------------------- //

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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, ...) {

View File

@ -157,4 +157,9 @@ namespace Events {
LISTENER(holdBegin);
LISTENER(holdEnd);
// Tearing
LISTENER(tearingNew);
DYNLISTENFUNC(tearingSet);
DYNLISTENFUNC(tearingDestroy);
};

View File

@ -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");
}

View File

@ -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);

View File

@ -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) {

View File

@ -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);
}

View File

@ -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();

View File

@ -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);
}

View File

@ -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;
}
};

View File

@ -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>

View File

@ -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.

View File

@ -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;

View File

@ -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*);