Skip to content

Commit

Permalink
[aquamarine] try to fix direct scanout (#6875)
Browse files Browse the repository at this point in the history
* make linux-dmabuf use monitor primary plane formats for ds

* add support for monitor connects/disconnects in linux-dmabuf

* the weird bug was because ds was global, and disabled on one monitor but enabled on the other

* forgot to remove attemptDirectScanout from hyprRenderer

* add renderer fallback tranche on ds and a few other improvements

* use set when making format table

* mitigate ds artifacting and update linux-dmabuf comments
with this commit artifacting now only occurs when the
client's fps is above the refresh rate of the monitor

* use new backend release infra

* revert earlier artifacting mitigation that broke stuff ;)

* ... i should test before push ;-;

---------

Co-authored-by: Vaxry <[email protected]>
  • Loading branch information
ikalco and vaxerski committed Jul 20, 2024
1 parent 2b2e118 commit 8e575f7
Show file tree
Hide file tree
Showing 9 changed files with 281 additions and 177 deletions.
49 changes: 49 additions & 0 deletions src/helpers/Monitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "../protocols/DRMLease.hpp"
#include "../protocols/core/Output.hpp"
#include "../managers/PointerManager.hpp"
#include "../protocols/core/Compositor.hpp"
#include "sync/SyncTimeline.hpp"
#include <aquamarine/output/Output.hpp>
#include <hyprutils/string/String.hpp>
Expand Down Expand Up @@ -786,6 +787,54 @@ void CMonitor::scheduleDone() {
doneSource = wl_event_loop_add_idle(g_pCompositor->m_sWLEventLoop, ::onDoneSource, this);
}

bool CMonitor::attemptDirectScanout() {
if (!mirrors.empty() || isMirror() || g_pHyprRenderer->m_bDirectScanoutBlocked)
return false; // do not DS if this monitor is being mirrored. Will break the functionality.

if (g_pPointerManager->softwareLockedFor(self.lock()))
return false;

const auto PCANDIDATE = solitaryClient.lock();

if (!PCANDIDATE)
return false;

const auto PSURFACE = g_pXWaylandManager->getWindowSurface(PCANDIDATE);

if (!PSURFACE || !PSURFACE->current.buffer || PSURFACE->current.buffer->size != vecPixelSize || PSURFACE->current.transform != transform)
return false;

// we can't scanout shm buffers.
if (!PSURFACE->current.buffer->dmabuf().success)
return false;

// FIXME: make sure the buffer actually follows the available scanout dmabuf formats
// and comes from the appropriate device. This may implode on multi-gpu!!

output->state->setBuffer(PSURFACE->current.buffer);
output->state->setPresentationMode(Aquamarine::eOutputPresentationMode::AQ_OUTPUT_PRESENTATION_VSYNC);

if (!state.test())
return false;

timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
Debug::log(TRACE, "presentFeedback for DS");
PSURFACE->presentFeedback(&now, this, true);

if (state.commit()) {
if (lastScanout.expired()) {
lastScanout = PCANDIDATE;
Debug::log(LOG, "Entered a direct scanout to {:x}: \"{}\"", (uintptr_t)PCANDIDATE.get(), PCANDIDATE->m_szTitle);
}
} else {
lastScanout.reset();
return false;
}

return true;
}

CMonitorState::CMonitorState(CMonitor* owner) {
m_pOwner = owner;
}
Expand Down
4 changes: 4 additions & 0 deletions src/helpers/Monitor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,9 @@ class CMonitor {
// for tearing
PHLWINDOWREF solitaryClient;

// for direct scanout
PHLWINDOWREF lastScanout;

struct {
bool canTear = false;
bool nextRenderTorn = false;
Expand Down Expand Up @@ -174,6 +177,7 @@ class CMonitor {
int64_t activeSpecialWorkspaceID();
CBox logicalBox();
void scheduleDone();
bool attemptDirectScanout();

bool m_bEnabled = false;
bool m_bRenderingInitPassed = false;
Expand Down
Loading

0 comments on commit 8e575f7

Please sign in to comment.