Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[aquamarine] try to fix direct scanout #6875

Merged
merged 10 commits into from
Jul 19, 2024
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
Loading