Compare commits

..

1 Commits

Author SHA1 Message Date
Mihai Fufezan 864f527058
Nix: fix cross-compilation 2024-07-27 20:16:11 +03:00
24 changed files with 206 additions and 503 deletions

View File

@ -59,8 +59,8 @@ target_include_directories(
PUBLIC "./include"
PRIVATE "./src" "./src/include" "./protocols" "${CMAKE_BINARY_DIR}")
set_target_properties(aquamarine PROPERTIES VERSION ${AQUAMARINE_VERSION}
SOVERSION 2)
target_link_libraries(aquamarine OpenGL::EGL OpenGL::OpenGL PkgConfig::deps)
SOVERSION 0)
target_link_libraries(aquamarine OpenGL::EGL OpenGL::GL PkgConfig::deps)
check_include_file("sys/timerfd.h" HAS_TIMERFD)
pkg_check_modules(epoll IMPORTED_TARGET epoll-shim)
@ -71,8 +71,8 @@ endif()
# Protocols
pkg_get_variable(WAYLAND_PROTOCOLS_DIR wayland-protocols pkgdatadir)
message(STATUS "Found wayland-protocols at ${WAYLAND_PROTOCOLS_DIR}")
pkg_get_variable(WAYLAND_SCANNER_PKGDATA_DIR wayland-scanner pkgdatadir)
message(STATUS "Found wayland-scanner pkgdatadir at ${WAYLAND_SCANNER_PKGDATA_DIR}")
pkg_get_variable(WAYLAND_CLIENT_DIR wayland-client pkgdatadir)
message(STATUS "Found wayland-client at ${WAYLAND_CLIENT_DIR}")
function(protocolNew protoPath protoName external)
if(external)
@ -94,7 +94,7 @@ function(protocolWayland)
OUTPUT ${CMAKE_SOURCE_DIR}/protocols/wayland.cpp
${CMAKE_SOURCE_DIR}/protocols/wayland.hpp
COMMAND hyprwayland-scanner --wayland-enums --client
${WAYLAND_SCANNER_PKGDATA_DIR}/wayland.xml ${CMAKE_SOURCE_DIR}/protocols/
${WAYLAND_CLIENT_DIR}/wayland.xml ${CMAKE_SOURCE_DIR}/protocols/
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
target_sources(aquamarine PRIVATE protocols/wayland.cpp protocols/wayland.hpp)
endfunction()

View File

@ -1 +1 @@
0.3.3
0.1.0

View File

@ -4,9 +4,7 @@ Unless specified otherwise, a variable is enabled if and only if it's set to `1`
### DRM
`AQ_DRM_DEVICES` -> Set an explicit list of DRM devices (GPUs) to use. It's a colon-separated list of paths, with the first being the primary. E.g. `/dev/dri/card1:/dev/dri/card0`
`AQ_NO_ATOMIC` -> Disables drm atomic modesetting
`AQ_MGPU_NO_EXPLICIT` -> Disables explicit syncing on mgpu buffers
### Debugging

View File

@ -14,16 +14,11 @@ namespace Aquamarine {
bool scanout = false, cursor = false, multigpu = false;
};
enum eAllocatorType {
AQ_ALLOCATOR_TYPE_GBM = 0,
};
class IAllocator {
public:
virtual ~IAllocator() = default;
virtual Hyprutils::Memory::CSharedPointer<IBuffer> acquire(const SAllocatorBufferParams& params, Hyprutils::Memory::CSharedPointer<CSwapchain> swapchain) = 0;
virtual Hyprutils::Memory::CSharedPointer<CBackend> getBackend() = 0;
virtual int drmFD() = 0;
virtual eAllocatorType type() = 0;
};
};

View File

@ -45,7 +45,6 @@ namespace Aquamarine {
virtual Hyprutils::Memory::CSharedPointer<IBuffer> acquire(const SAllocatorBufferParams& params, Hyprutils::Memory::CSharedPointer<CSwapchain> swapchain_);
virtual Hyprutils::Memory::CSharedPointer<CBackend> getBackend();
virtual int drmFD();
virtual eAllocatorType type();
//
Hyprutils::Memory::CWeakPointer<CGBMAllocator> self;

View File

@ -152,7 +152,7 @@ namespace Aquamarine {
struct SDRMCRTC {
uint32_t id = 0;
std::vector<SDRMLayer> layers;
int32_t refresh = 0; // unused
int32_t refresh = 0;
struct {
int gammaSize = 0;
@ -194,7 +194,7 @@ namespace Aquamarine {
virtual bool test();
virtual Hyprutils::Memory::CSharedPointer<IBackendImplementation> getBackend();
virtual bool setCursor(Hyprutils::Memory::CSharedPointer<IBuffer> buffer, const Hyprutils::Math::Vector2D& hotspot);
virtual void moveCursor(const Hyprutils::Math::Vector2D& coord, bool skipSchedule = false);
virtual void moveCursor(const Hyprutils::Math::Vector2D& coord, bool skipShedule = false);
virtual void scheduleFrame(const scheduleFrameReason reason = AQ_SCHEDULE_UNKNOWN);
virtual void setCursorVisible(bool visible);
virtual Hyprutils::Math::Vector2D cursorPlaneSize();
@ -209,8 +209,6 @@ namespace Aquamarine {
Hyprutils::Math::Vector2D cursorPos; // without hotspot
Hyprutils::Math::Vector2D cursorHotspot;
bool enabledState = true; // actual enabled state. Should be synced with state->state().enabled after a new frame
private:
CDRMOutput(const std::string& name_, Hyprutils::Memory::CWeakPointer<CDRMBackend> backend_, Hyprutils::Memory::CSharedPointer<SDRMConnector> connector_);
@ -267,7 +265,6 @@ namespace Aquamarine {
void applyCommit(const SDRMConnectorCommitData& data);
void rollbackCommit(const SDRMConnectorCommitData& data);
void onPresent();
void recheckCRTCProps();
Hyprutils::Memory::CSharedPointer<CDRMOutput> output;
Hyprutils::Memory::CWeakPointer<CDRMBackend> backend;
@ -323,12 +320,11 @@ namespace Aquamarine {
class IDRMImplementation {
public:
virtual ~IDRMImplementation() = default;
virtual bool commit(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, SDRMConnectorCommitData& data) = 0;
virtual bool reset() = 0;
// moving a cursor IIRC is almost instant on most hardware so we don't have to wait for a commit.
virtual bool moveCursor(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, bool skipSchedule = false) = 0;
virtual bool moveCursor(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, bool skipShedule = false) = 0;
};
class CDRMBackend : public IBackendImplementation {
@ -367,7 +363,7 @@ namespace Aquamarine {
bool initMgpu();
bool grabFormats();
bool shouldBlit();
void scanConnectors(bool allowConnect = true);
void scanConnectors();
void scanLeases();
void restoreAfterVT();
void recheckCRTCs();
@ -377,10 +373,11 @@ namespace Aquamarine {
Hyprutils::Memory::CSharedPointer<IDRMImplementation> impl;
Hyprutils::Memory::CWeakPointer<CDRMBackend> primary;
// multigpu state, only present if this backend is not primary, aka if this->primary != nullptr
struct {
Hyprutils::Memory::CSharedPointer<IAllocator> allocator;
Hyprutils::Memory::CSharedPointer<CDRMRenderer> renderer; // may be null if creation fails
} rendererState;
Hyprutils::Memory::CSharedPointer<CDRMRenderer> renderer;
} mgpu;
Hyprutils::Memory::CWeakPointer<CBackend> backend;
@ -417,6 +414,5 @@ namespace Aquamarine {
friend class CDRMAtomicImpl;
friend class CDRMAtomicRequest;
friend class CDRMLease;
friend class CGBMBuffer;
};
};

View File

@ -45,7 +45,7 @@ namespace Aquamarine {
virtual bool test();
virtual Hyprutils::Memory::CSharedPointer<IBackendImplementation> getBackend();
virtual bool setCursor(Hyprutils::Memory::CSharedPointer<IBuffer> buffer, const Hyprutils::Math::Vector2D& hotspot);
virtual void moveCursor(const Hyprutils::Math::Vector2D& coord, bool skipSchedule = false);
virtual void moveCursor(const Hyprutils::Math::Vector2D& coord, bool skipShedule = false);
virtual void scheduleFrame(const scheduleFrameReason reason = AQ_SCHEDULE_UNKNOWN);
virtual Hyprutils::Math::Vector2D cursorPlaneSize();
virtual bool destroy();

View File

@ -8,7 +8,7 @@ namespace Aquamarine {
CDRMAtomicImpl(Hyprutils::Memory::CSharedPointer<CDRMBackend> backend_);
virtual bool commit(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, SDRMConnectorCommitData& data);
virtual bool reset();
virtual bool moveCursor(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, bool skipSchedule = false);
virtual bool moveCursor(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, bool skipShedule = false);
private:
bool prepareConnector(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, SDRMConnectorCommitData& data);

View File

@ -8,7 +8,7 @@ namespace Aquamarine {
CDRMLegacyImpl(Hyprutils::Memory::CSharedPointer<CDRMBackend> backend_);
virtual bool commit(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, SDRMConnectorCommitData& data);
virtual bool reset();
virtual bool moveCursor(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, bool skipSchedule = false);
virtual bool moveCursor(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, bool skipShedule = false);
private:
bool commitInternal(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, SDRMConnectorCommitData& data);

View File

@ -123,7 +123,7 @@ namespace Aquamarine {
virtual std::vector<SDRMFormat> getRenderFormats() = 0;
virtual Hyprutils::Memory::CSharedPointer<SOutputMode> preferredMode();
virtual bool setCursor(Hyprutils::Memory::CSharedPointer<IBuffer> buffer, const Hyprutils::Math::Vector2D& hotspot);
virtual void moveCursor(const Hyprutils::Math::Vector2D& coord, bool skipSchedule = false); // includes the hotspot
virtual void moveCursor(const Hyprutils::Math::Vector2D& coord, bool skipShedule = false); // includes the hotspot
virtual void setCursorVisible(bool visible); // moving the cursor will make it visible again without this util
virtual Hyprutils::Math::Vector2D cursorPlaneSize(); // -1, -1 means no set size, 0, 0 means error
virtual void scheduleFrame(const scheduleFrameReason reason = AQ_SCHEDULE_UNKNOWN);

View File

@ -17,7 +17,6 @@
udev,
wayland,
wayland-protocols,
# wayland-scanner,
version ? "git",
doCheck ? false,
}:
@ -26,14 +25,10 @@ stdenv.mkDerivation {
inherit version doCheck;
src = ../.;
strictDeps = true;
nativeBuildInputs = [
cmake
hyprwayland-scanner
pkg-config
# re-add after https://github.com/NixOS/nixpkgs/pull/214906 hits nixos-unstable
# wayland-scanner
];
buildInputs = [

View File

@ -1,19 +1,17 @@
#include <aquamarine/allocator/GBM.hpp>
#include <aquamarine/backend/Backend.hpp>
#include <aquamarine/backend/DRM.hpp>
#include <aquamarine/allocator/Swapchain.hpp>
#include "FormatUtils.hpp"
#include "Shared.hpp"
#include <xf86drm.h>
#include <gbm.h>
#include <unistd.h>
#include "../backend/drm/Renderer.hpp"
using namespace Aquamarine;
using namespace Hyprutils::Memory;
#define SP CSharedPointer
static SDRMFormat guessFormatFrom(std::vector<SDRMFormat> formats, bool cursor, bool scanout) {
static SDRMFormat guessFormatFrom(std::vector<SDRMFormat> formats, bool cursor) {
if (formats.empty())
return SDRMFormat{};
@ -22,29 +20,20 @@ static SDRMFormat guessFormatFrom(std::vector<SDRMFormat> formats, bool cursor,
Try to find 10bpp formats first, as they offer better color precision.
For cursors, don't, as these almost never support that.
*/
if (!scanout) {
if (auto it =
std::find_if(formats.begin(), formats.end(), [](const auto& f) { return f.drmFormat == DRM_FORMAT_ARGB2101010 || f.drmFormat == DRM_FORMAT_ABGR2101010; });
it != formats.end())
return *it;
}
if (auto it = std::find_if(formats.begin(), formats.end(), [](const auto& f) { return f.drmFormat == DRM_FORMAT_ARGB2101010; }); it != formats.end())
return *it;
if (auto it = std::find_if(formats.begin(), formats.end(), [](const auto& f) { return f.drmFormat == DRM_FORMAT_XRGB2101010 || f.drmFormat == DRM_FORMAT_XBGR2101010; });
it != formats.end())
if (auto it = std::find_if(formats.begin(), formats.end(), [](const auto& f) { return f.drmFormat == DRM_FORMAT_XRGB2101010; }); it != formats.end())
return *it;
}
if (!scanout) {
if (auto it = std::find_if(formats.begin(), formats.end(), [](const auto& f) { return f.drmFormat == DRM_FORMAT_ARGB8888 || f.drmFormat == DRM_FORMAT_ABGR8888; });
it != formats.end())
return *it;
}
if (auto it = std::find_if(formats.begin(), formats.end(), [](const auto& f) { return f.drmFormat == DRM_FORMAT_XRGB8888 || f.drmFormat == DRM_FORMAT_XBGR8888; });
it != formats.end())
if (auto it = std::find_if(formats.begin(), formats.end(), [](const auto& f) { return f.drmFormat == DRM_FORMAT_ARGB8888; }); it != formats.end())
return *it;
for (auto const& f : formats) {
if (auto it = std::find_if(formats.begin(), formats.end(), [](const auto& f) { return f.drmFormat == DRM_FORMAT_XRGB8888; }); it != formats.end())
return *it;
for (auto& f : formats) {
auto name = fourccToName(f.drmFormat);
/* 10 bpp RGB */
@ -52,7 +41,7 @@ static SDRMFormat guessFormatFrom(std::vector<SDRMFormat> formats, bool cursor,
return f;
}
for (auto const& f : formats) {
for (auto& f : formats) {
auto name = fourccToName(f.drmFormat);
/* 8 bpp RGB */
@ -79,15 +68,13 @@ Aquamarine::CGBMBuffer::CGBMBuffer(const SAllocatorBufferParams& params, Hypruti
std::format("GBM: Allocating a buffer: size {}, format {}, cursor: {}, multigpu: {}, scanout: {}", attrs.size, fourccToName(attrs.format), CURSOR,
MULTIGPU, params.scanout)));
const auto FORMATS = CURSOR ? swapchain->backendImpl->getCursorFormats() : swapchain->backendImpl->getRenderFormats();
const auto RENDERABLE = swapchain->backendImpl->getRenderableFormats();
TRACE(allocator->backend->log(AQ_LOG_TRACE, std::format("GBM: Available formats: {}", FORMATS.size())));
const auto FORMATS = CURSOR ? swapchain->backendImpl->getCursorFormats() : swapchain->backendImpl->getRenderFormats();
const auto RENDERABLE = swapchain->backendImpl->getRenderableFormats();
std::vector<uint64_t> explicitModifiers;
if (attrs.format == DRM_FORMAT_INVALID) {
attrs.format = guessFormatFrom(FORMATS, CURSOR, params.scanout).drmFormat;
attrs.format = guessFormatFrom(FORMATS, CURSOR).drmFormat;
if (attrs.format != DRM_FORMAT_INVALID)
allocator->backend->log(AQ_LOG_DEBUG, std::format("GBM: Automatically selected format {} for new GBM buffer", fourccToName(attrs.format)));
}
@ -99,34 +86,30 @@ Aquamarine::CGBMBuffer::CGBMBuffer(const SAllocatorBufferParams& params, Hypruti
// check if we can use modifiers. If the requested support has any explicit modifier
// supported by the primary backend, we can.
if (!RENDERABLE.empty()) {
TRACE(allocator->backend->log(AQ_LOG_TRACE, std::format("GBM: Renderable has {} formats, clipping", RENDERABLE.size())));
for (auto& f : FORMATS) {
if (f.drmFormat != attrs.format)
continue;
for (auto const& f : FORMATS) {
if (f.drmFormat != attrs.format)
for (auto& m : f.modifiers) {
if (m == DRM_FORMAT_MOD_INVALID)
continue;
for (auto const& m : f.modifiers) {
if (m == DRM_FORMAT_MOD_INVALID)
continue;
if (!RENDERABLE.empty() && params.scanout && !CURSOR && !MULTIGPU) {
// regular scanout plane, check if the format is renderable
auto rformat = std::find_if(RENDERABLE.begin(), RENDERABLE.end(), [f](const auto& e) { return e.drmFormat == f.drmFormat; });
if (params.scanout && !CURSOR && !MULTIGPU) {
// regular scanout plane, check if the format is renderable
auto rformat = std::find_if(RENDERABLE.begin(), RENDERABLE.end(), [f](const auto& e) { return e.drmFormat == f.drmFormat; });
if (rformat == RENDERABLE.end()) {
TRACE(allocator->backend->log(AQ_LOG_TRACE, std::format("GBM: Dropping format {} as it's not renderable", fourccToName(f.drmFormat))));
break;
}
if (std::find(rformat->modifiers.begin(), rformat->modifiers.end(), m) == rformat->modifiers.end()) {
TRACE(allocator->backend->log(AQ_LOG_TRACE, std::format("GBM: Dropping modifier 0x{:x} as it's not renderable", m)));
continue;
}
if (rformat == RENDERABLE.end()) {
TRACE(allocator->backend->log(AQ_LOG_TRACE, std::format("GBM: Dropping format {} as it's not renderable", fourccToName(f.drmFormat))));
break;
}
explicitModifiers.push_back(m);
if (std::find(rformat->modifiers.begin(), rformat->modifiers.end(), m) == rformat->modifiers.end()) {
TRACE(allocator->backend->log(AQ_LOG_TRACE, std::format("GBM: Dropping modifier 0x{:x} as it's not renderable", m)));
continue;
}
}
explicitModifiers.push_back(m);
}
}
@ -150,7 +133,7 @@ Aquamarine::CGBMBuffer::CGBMBuffer(const SAllocatorBufferParams& params, Hypruti
bo = gbm_bo_create(allocator->gbmDevice, attrs.size.x, attrs.size.y, attrs.format, flags);
} else {
TRACE(allocator->backend->log(AQ_LOG_TRACE, std::format("GBM: Using modifier-based allocation, modifiers: {}", explicitModifiers.size())));
for (auto const& mod : explicitModifiers) {
for (auto& mod : explicitModifiers) {
TRACE(allocator->backend->log(AQ_LOG_TRACE, std::format("GBM: | mod 0x{:x}", mod)));
}
bo = gbm_bo_create_with_modifiers2(allocator->gbmDevice, attrs.size.x, attrs.size.y, attrs.format, explicitModifiers.data(), explicitModifiers.size(), flags);
@ -203,13 +186,6 @@ Aquamarine::CGBMBuffer::CGBMBuffer(const SAllocatorBufferParams& params, Hypruti
modName ? modName : "Unknown"));
free(modName);
if (params.scanout && swapchain->backendImpl->type() == AQ_BACKEND_DRM) {
// clear the buffer using the DRM renderer to avoid uninitialized mem
auto impl = (CDRMBackend*)swapchain->backendImpl.get();
if (impl->rendererState.renderer)
impl->rendererState.renderer->clearBuffer(this);
}
}
Aquamarine::CGBMBuffer::~CGBMBuffer() {
@ -240,7 +216,7 @@ bool Aquamarine::CGBMBuffer::isSynchronous() {
}
bool Aquamarine::CGBMBuffer::good() {
return bo;
return true;
}
SDMABUFAttrs Aquamarine::CGBMBuffer::dmabuf() {
@ -248,13 +224,13 @@ SDMABUFAttrs Aquamarine::CGBMBuffer::dmabuf() {
}
std::tuple<uint8_t*, uint32_t, size_t> Aquamarine::CGBMBuffer::beginDataPtr(uint32_t flags) {
uint32_t stride = 0;
uint32_t dst_stride = 0;
if (boBuffer)
allocator->backend->log(AQ_LOG_ERROR, "beginDataPtr is called a second time without calling endDataPtr first. Returning old mapping");
else
boBuffer = gbm_bo_map(bo, 0, 0, attrs.size.x, attrs.size.y, flags, &stride, &gboMapping);
return {(uint8_t*)boBuffer, attrs.format, stride * attrs.size.y};
boBuffer = gbm_bo_map(bo, 0, 0, attrs.size.x, attrs.size.y, flags, &dst_stride, &gboMapping);
// FIXME: assumes a 32-bit pixel format
return {(uint8_t*)boBuffer, attrs.format, attrs.size.x * attrs.size.y * 4};
}
void Aquamarine::CGBMBuffer::endDataPtr() {
@ -329,7 +305,3 @@ Hyprutils::Memory::CSharedPointer<CBackend> Aquamarine::CGBMAllocator::getBacken
int Aquamarine::CGBMAllocator::drmFD() {
return fd;
}
eAllocatorType Aquamarine::CGBMAllocator::type() {
return AQ_ALLOCATOR_TYPE_GBM;
}

View File

@ -17,7 +17,7 @@ using namespace Hyprutils::Memory;
using namespace Aquamarine;
#define SP CSharedPointer
#define TIMESPEC_NSEC_PER_SEC 1000000000LL
#define TIMESPEC_NSEC_PER_SEC 1000000000L
static void timespecAddNs(timespec* pTimespec, int64_t delta) {
int delta_ns_low = delta % TIMESPEC_NSEC_PER_SEC;
@ -67,7 +67,7 @@ Hyprutils::Memory::CSharedPointer<CBackend> Aquamarine::CBackend::create(const s
backend->log(AQ_LOG_DEBUG, "Creating an Aquamarine backend!");
for (auto const& b : backends) {
for (auto& b : backends) {
if (b.backendType == AQ_BACKEND_WAYLAND) {
auto ref = SP<CWaylandBackend>(new CWaylandBackend(backend));
backend->implementations.emplace_back(ref);
@ -79,7 +79,7 @@ Hyprutils::Memory::CSharedPointer<CBackend> Aquamarine::CBackend::create(const s
continue;
}
for (auto const& r : ref) {
for (auto& r : ref) {
backend->implementations.emplace_back(r);
}
} else if (b.backendType == AQ_BACKEND_HEADLESS) {
@ -109,7 +109,7 @@ bool Aquamarine::CBackend::start() {
int started = 0;
auto optionsForType = [this](eBackendType type) -> SBackendImplementationOptions {
for (auto const& o : implementationOptions) {
for (auto& o : implementationOptions) {
if (o.backendType == type)
return o;
}
@ -145,7 +145,7 @@ bool Aquamarine::CBackend::start() {
});
// TODO: obviously change this when (if) we add different allocators.
for (auto const& b : implementations) {
for (auto& b : implementations) {
if (b->drmFD() >= 0) {
auto fd = reopenDRMNode(b->drmFD());
if (fd < 0) {
@ -162,7 +162,7 @@ bool Aquamarine::CBackend::start() {
return false;
ready = true;
for (auto const& b : implementations) {
for (auto& b : implementations) {
b->onReady();
}
@ -180,15 +180,15 @@ void Aquamarine::CBackend::log(eBackendLogLevel level, const std::string& msg) {
std::vector<Hyprutils::Memory::CSharedPointer<SPollFD>> Aquamarine::CBackend::getPollFDs() {
std::vector<Hyprutils::Memory::CSharedPointer<SPollFD>> result;
for (auto const& i : implementations) {
for (auto& i : implementations) {
auto pollfds = i->pollFDs();
for (auto const& p : pollfds) {
for (auto& p : pollfds) {
log(AQ_LOG_DEBUG, std::format("backend: poll fd {} for implementation {}", p->fd, backendTypeToName(i->type())));
result.emplace_back(p);
}
}
for (auto const& sfd : sessionFDs) {
for (auto& sfd : sessionFDs) {
log(AQ_LOG_DEBUG, std::format("backend: poll fd {} for session", sfd->fd));
result.emplace_back(sfd);
}
@ -200,7 +200,7 @@ std::vector<Hyprutils::Memory::CSharedPointer<SPollFD>> Aquamarine::CBackend::ge
}
int Aquamarine::CBackend::drmFD() {
for (auto const& i : implementations) {
for (auto& i : implementations) {
int fd = i->drmFD();
if (fd < 0)
continue;
@ -215,14 +215,14 @@ bool Aquamarine::CBackend::hasSession() {
}
std::vector<SDRMFormat> Aquamarine::CBackend::getPrimaryRenderFormats() {
for (auto const& b : implementations) {
for (auto& b : implementations) {
if (b->type() != AQ_BACKEND_DRM && b->type() != AQ_BACKEND_WAYLAND)
continue;
return b->getRenderFormats();
}
for (auto const& b : implementations) {
for (auto& b : implementations) {
return b->getRenderFormats();
}
@ -260,7 +260,7 @@ void Aquamarine::CBackend::dispatchIdle() {
auto cpy = idle.pending;
idle.pending.clear();
for (auto const& i : cpy) {
for (auto& i : cpy) {
if (i && *i)
(*i)();
}

View File

@ -10,7 +10,7 @@ using namespace Hyprutils::Memory;
using namespace Hyprutils::Math;
#define SP CSharedPointer
#define TIMESPEC_NSEC_PER_SEC 1000000000LL
#define TIMESPEC_NSEC_PER_SEC 1000000000L
static void timespecAddNs(timespec* pTimespec, int64_t delta) {
int delta_ns_low = delta % TIMESPEC_NSEC_PER_SEC;
@ -149,7 +149,7 @@ void Aquamarine::CHeadlessBackend::dispatchTimers() {
}
}
for (auto const& copy : toFire) {
for (auto& copy : toFire) {
if (copy.what)
copy.what();
}
@ -162,7 +162,7 @@ void Aquamarine::CHeadlessBackend::updateTimerFD() {
const auto clocknow = std::chrono::steady_clock::now();
bool any = false;
for (auto const& t : timers.timers) {
for (auto& t : timers.timers) {
auto delta = std::chrono::duration_cast<std::chrono::microseconds>(t.when - clocknow).count() * 1000 /* µs -> ns */;
if (delta < lowestNs)

View File

@ -264,7 +264,7 @@ static bool isDRMCard(const char* sysname) {
}
void Aquamarine::CSession::onReady() {
for (auto const& d : libinputDevices) {
for (auto& d : libinputDevices) {
if (d->keyboard)
backend->events.newKeyboard.emit(SP<IKeyboard>(d->keyboard));
if (d->mouse)
@ -278,7 +278,7 @@ void Aquamarine::CSession::onReady() {
if (d->tabletPad)
backend->events.newTabletPad.emit(SP<ITabletPad>(d->tabletPad));
for (auto const& t : d->tabletTools) {
for (auto& t : d->tabletTools) {
backend->events.newTabletTool.emit(SP<ITabletTool>(t));
}
}
@ -306,7 +306,7 @@ void Aquamarine::CSession::dispatchUdevEvents() {
dev_t deviceNum = udev_device_get_devnum(device);
SP<CSessionDevice> sessionDevice;
for (auto const& sDev : sessionDevices) {
for (auto& sDev : sessionDevices) {
if (sDev->dev == deviceNum) {
sessionDevice = sDev;
break;
@ -498,7 +498,7 @@ void Aquamarine::CSession::handleLibinputEvent(libinput_event* e) {
LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
};
for (auto const& axis : LAXES) {
for (auto& axis : LAXES) {
if (!libinput_event_pointer_has_axis(pe, axis))
continue;
@ -640,7 +640,6 @@ void Aquamarine::CSession::handleLibinputEvent(libinput_event* e) {
if (ENABLED == hlDevice->switchy->state)
return;
hlDevice->switchy->state = ENABLED;
switch (libinput_event_switch_get_switch(se)) {
case LIBINPUT_SWITCH_LID: hlDevice->switchy->type = ISwitch::AQ_SWITCH_TYPE_LID; break;
@ -860,7 +859,7 @@ Aquamarine::CLibinputDevice::~CLibinputDevice() {
}
SP<CLibinputTabletTool> Aquamarine::CLibinputDevice::toolFrom(libinput_tablet_tool* tool) {
for (auto const& t : tabletTools) {
for (auto& t : tabletTools) {
if (t->libinputTool == tool)
return t;
}

View File

@ -168,7 +168,7 @@ bool Aquamarine::CWaylandBackend::dispatchEvents() {
// dispatch frames
if (backend->ready) {
for (auto const& f : idleCallbacks) {
for (auto& f : idleCallbacks) {
f();
}
idleCallbacks.clear();
@ -187,7 +187,7 @@ bool Aquamarine::CWaylandBackend::setCursor(Hyprutils::Memory::CSharedPointer<IB
}
void Aquamarine::CWaylandBackend::onReady() {
for (auto const& o : outputs) {
for (auto& o : outputs) {
o->swapchain = CSwapchain::create(backend->primaryAllocator, self.lock());
if (!o->swapchain) {
backend->log(AQ_LOG_ERROR, std::format("Output {} failed: swapchain creation failed", o->name));
@ -257,7 +257,7 @@ Aquamarine::CWaylandPointer::CWaylandPointer(SP<CCWlPointer> pointer_, Hyprutils
pointer->setEnter([this](CCWlPointer* r, uint32_t serial, wl_proxy* surface, wl_fixed_t x, wl_fixed_t y) {
backend->lastEnterSerial = serial;
for (auto const& o : backend->outputs) {
for (auto& o : backend->outputs) {
if (o->waylandState.surface->resource() != surface)
continue;
@ -269,7 +269,7 @@ Aquamarine::CWaylandPointer::CWaylandPointer(SP<CCWlPointer> pointer_, Hyprutils
});
pointer->setLeave([this](CCWlPointer* r, uint32_t serial, wl_proxy* surface) {
for (auto const& o : backend->outputs) {
for (auto& o : backend->outputs) {
if (o->waylandState.surface->resource() != surface)
continue;
@ -599,7 +599,7 @@ SP<IBackendImplementation> Aquamarine::CWaylandOutput::getBackend() {
SP<CWaylandBuffer> Aquamarine::CWaylandOutput::wlBufferFromBuffer(SP<IBuffer> buffer) {
std::erase_if(backendState.buffers, [this](const auto& el) { return el.first.expired() || !swapchain->contains(el.first.lock()); });
for (auto const& [k, v] : backendState.buffers) {
for (auto& [k, v] : backendState.buffers) {
if (k != buffer)
continue;
@ -655,8 +655,7 @@ bool Aquamarine::CWaylandOutput::setCursor(Hyprutils::Memory::CSharedPointer<IBu
if (!buffer) {
cursorState.cursorBuffer.reset();
cursorState.cursorWlBuffer.reset();
if (!backend->pointers.empty())
backend->pointers.at(0)->pointer->sendSetCursor(cursorState.serial, nullptr, cursorState.hotspot.x, cursorState.hotspot.y);
backend->pointers.at(0)->pointer->sendSetCursor(cursorState.serial, nullptr, cursorState.hotspot.x, cursorState.hotspot.y);
return true;
}
@ -726,7 +725,7 @@ bool Aquamarine::CWaylandOutput::setCursor(Hyprutils::Memory::CSharedPointer<IBu
return true;
}
void Aquamarine::CWaylandOutput::moveCursor(const Hyprutils::Math::Vector2D& coord, bool skipSchedule) {
void Aquamarine::CWaylandOutput::moveCursor(const Hyprutils::Math::Vector2D& coord, bool skipShedule) {
return;
}

View File

@ -139,23 +139,23 @@ static std::vector<SP<CSessionDevice>> scanGPUs(SP<CBackend> backend) {
// Iterate over GPUs and canonicalize the paths
for (auto& d : explicitDevices) {
std::error_code ec;
std::error_code ec;
auto canonicalFilePath = std::filesystem::canonical(d, ec);
// If there is an error, log and continue.
// TODO: Verify that the path is a valid DRM device. (https://gitlab.freedesktop.org/wlroots/wlroots/-/blob/master/backend/session/session.c?ref_type=heads#L369-387)
if (ec) {
backend->log(AQ_LOG_ERROR, std::format("drm: Failed to canonicalize path {}", d));
continue;
}
auto canonicalFilePath = std::filesystem::canonical(d, ec);
// If there is an error, log and continue.
// TODO: Verify that the path is a valid DRM device. (https://gitlab.freedesktop.org/wlroots/wlroots/-/blob/master/backend/session/session.c?ref_type=heads#L369-387)
if (ec) {
backend->log(AQ_LOG_ERROR, std::format("drm: Failed to canonicalize path {}", d));
continue;
}
d = canonicalFilePath.string();
d = canonicalFilePath.string();
}
for (auto const& d : explicitDevices) {
for (auto& d : explicitDevices) {
bool found = false;
for (auto const& vd : devices) {
for (auto& vd : devices) {
if (vd->path == d) {
vecDevices.emplace_back(vd);
found = true;
@ -169,7 +169,7 @@ static std::vector<SP<CSessionDevice>> scanGPUs(SP<CBackend> backend) {
backend->log(AQ_LOG_ERROR, std::format("drm: Explicit device {} not found", d));
}
} else {
for (auto const& d : devices) {
for (auto& d : devices) {
vecDevices.push_back(d);
}
}
@ -219,7 +219,7 @@ std::vector<SP<CDRMBackend>> Aquamarine::CDRMBackend::attempt(SP<CBackend> backe
std::vector<SP<CDRMBackend>> backends;
SP<CDRMBackend> newPrimary;
for (auto const& gpu : gpus) {
for (auto& gpu : gpus) {
auto drmBackend = SP<CDRMBackend>(new CDRMBackend(backend));
drmBackend->self = drmBackend;
@ -246,7 +246,7 @@ std::vector<SP<CDRMBackend>> Aquamarine::CDRMBackend::attempt(SP<CBackend> backe
drmBackend->grabFormats();
drmBackend->scanConnectors(false);
drmBackend->scanConnectors();
drmBackend->recheckCRTCs();
@ -279,7 +279,7 @@ bool Aquamarine::CDRMBackend::sessionActive() {
void Aquamarine::CDRMBackend::restoreAfterVT() {
backend->log(AQ_LOG_DEBUG, "drm: Restoring after VT switch");
scanConnectors(false);
scanConnectors();
recheckCRTCs();
backend->log(AQ_LOG_DEBUG, "drm: Rescanned connectors");
@ -289,7 +289,7 @@ void Aquamarine::CDRMBackend::restoreAfterVT() {
std::vector<SP<SDRMConnector>> noMode;
for (auto const& c : connectors) {
for (auto& c : connectors) {
if (!c->crtc || !c->output)
continue;
@ -302,16 +302,15 @@ void Aquamarine::CDRMBackend::restoreAfterVT() {
};
auto& STATE = c->output->state->state();
auto& MODE = STATE.customMode ? STATE.customMode : STATE.mode;
if (!MODE) {
if (!STATE.customMode && !STATE.mode) {
backend->log(AQ_LOG_WARNING, "drm: Connector {} has output but state has no mode, will send a reset state event later.");
noMode.emplace_back(c);
continue;
}
if (MODE->modeInfo.has_value())
data.modeInfo = *MODE->modeInfo;
if (STATE.mode && STATE.mode->modeInfo.has_value())
data.modeInfo = *STATE.mode->modeInfo;
else
data.calculateMode(c);
@ -342,7 +341,7 @@ void Aquamarine::CDRMBackend::restoreAfterVT() {
backend->log(AQ_LOG_ERROR, std::format("drm: crtc {} failed restore", c->crtc->id));
}
for (auto const& c : noMode) {
for (auto& c : noMode) {
if (!c->output)
continue;
@ -494,30 +493,27 @@ bool Aquamarine::CDRMBackend::shouldBlit() {
}
bool Aquamarine::CDRMBackend::initMgpu() {
SP<CGBMAllocator> newAllocator;
if (primary || backend->primaryAllocator->type() != AQ_ALLOCATOR_TYPE_GBM) {
newAllocator = CGBMAllocator::create(backend->reopenDRMNode(gpu->fd), backend);
rendererState.allocator = newAllocator;
} else {
newAllocator = ((CGBMAllocator*)backend->primaryAllocator.get())->self.lock();
rendererState.allocator = newAllocator;
}
if (!primary)
return true;
if (!rendererState.allocator) {
auto newAllocator = CGBMAllocator::create(backend->reopenDRMNode(gpu->fd), backend);
mgpu.allocator = newAllocator;
if (!mgpu.allocator) {
backend->log(AQ_LOG_ERROR, "drm: initMgpu: no allocator");
return false;
}
rendererState.renderer = CDRMRenderer::attempt(newAllocator, backend.lock());
mgpu.renderer = CDRMRenderer::attempt(newAllocator, backend.lock());
if (!rendererState.renderer) {
if (!mgpu.renderer) {
backend->log(AQ_LOG_ERROR, "drm: initMgpu: no renderer");
return false;
}
rendererState.renderer->self = rendererState.renderer;
mgpu.renderer->self = mgpu.renderer;
buildGlFormats(rendererState.renderer->formats);
buildGlFormats(mgpu.renderer->formats);
return true;
}
@ -525,7 +521,7 @@ bool Aquamarine::CDRMBackend::initMgpu() {
void Aquamarine::CDRMBackend::buildGlFormats(const std::vector<SGLFormat>& fmts) {
std::vector<SDRMFormat> result;
for (auto const& fmt : fmts) {
for (auto& fmt : fmts) {
if (fmt.external)
continue;
@ -550,7 +546,7 @@ void Aquamarine::CDRMBackend::recheckCRTCs() {
backend->log(AQ_LOG_DEBUG, "drm: Rechecking CRTCs");
std::vector<SP<SDRMConnector>> recheck, changed;
for (auto const& c : connectors) {
for (auto& c : connectors) {
if (c->crtc && c->status == DRM_MODE_CONNECTED) {
backend->log(AQ_LOG_DEBUG, std::format("drm: Skipping connector {}, has crtc {} and is connected", c->szName, c->crtc->id));
continue;
@ -562,7 +558,7 @@ void Aquamarine::CDRMBackend::recheckCRTCs() {
for (size_t i = 0; i < crtcs.size(); ++i) {
bool taken = false;
for (auto const& c : connectors) {
for (auto& c : connectors) {
if (c->crtc != crtcs.at(i))
continue;
@ -580,7 +576,7 @@ void Aquamarine::CDRMBackend::recheckCRTCs() {
bool assigned = false;
// try to use a connected connector
for (auto const& c : recheck) {
for (auto& c : recheck) {
if (!(c->possibleCrtcs & (1 << i)))
continue;
@ -606,7 +602,7 @@ void Aquamarine::CDRMBackend::recheckCRTCs() {
backend->log(AQ_LOG_DEBUG, std::format("drm: slot {} crtc {} unassigned", i, crtcs.at(i)->id));
}
for (auto const& c : connectors) {
for (auto& c : connectors) {
if (c->status == DRM_MODE_CONNECTED)
continue;
@ -615,7 +611,7 @@ void Aquamarine::CDRMBackend::recheckCRTCs() {
// if any connectors get a crtc and are connected, we need to rescan to assign them outputs.
bool rescan = false;
for (auto const& c : changed) {
for (auto& c : changed) {
if (!c->output && c->status == DRM_MODE_CONNECTED) {
rescan = true;
continue;
@ -658,7 +654,7 @@ bool Aquamarine::CDRMBackend::registerGPU(SP<CSessionDevice> gpu_, SP<CDRMBacken
auto E = std::any_cast<CSessionDevice::SChangeEvent>(d);
if (E.type == CSessionDevice::AQ_SESSION_EVENT_CHANGE_HOTPLUG) {
backend->log(AQ_LOG_DEBUG, std::format("drm: Got a hotplug event for {}", gpuName));
scanConnectors(false);
scanConnectors();
recheckCRTCs();
} else if (E.type == CSessionDevice::AQ_SESSION_EVENT_CHANGE_LEASE) {
backend->log(AQ_LOG_DEBUG, std::format("drm: Got a lease event for {}", gpuName));
@ -676,7 +672,7 @@ eBackendType Aquamarine::CDRMBackend::type() {
return eBackendType::AQ_BACKEND_DRM;
}
void Aquamarine::CDRMBackend::scanConnectors(bool allowConnect) {
void Aquamarine::CDRMBackend::scanConnectors() {
backend->log(AQ_LOG_DEBUG, std::format("drm: Scanning connectors for {}", gpu->path));
auto resources = drmModeGetResources(gpu->fd);
@ -717,19 +713,19 @@ void Aquamarine::CDRMBackend::scanConnectors(bool allowConnect) {
conn->status = drmConn->connection;
if (conn->crtc)
conn->recheckCRTCProps();
if (!conn->crtc) {
backend->log(AQ_LOG_DEBUG, std::format("drm: Ignoring connector {} because it has no CRTC", connectorID));
continue;
}
backend->log(AQ_LOG_DEBUG, std::format("drm: Connector {} connection state: {}", connectorID, (int)drmConn->connection));
if (allowConnect) {
if (conn->status == DRM_MODE_CONNECTED && !conn->output) {
backend->log(AQ_LOG_DEBUG, std::format("drm: Connector {} connected", conn->szName));
conn->connect(drmConn);
} else if (conn->status != DRM_MODE_CONNECTED && conn->output) {
backend->log(AQ_LOG_DEBUG, std::format("drm: Connector {} disconnected", conn->szName));
conn->disconnect();
}
if (conn->status == DRM_MODE_CONNECTED && !conn->output) {
backend->log(AQ_LOG_DEBUG, std::format("drm: Connector {} connected", conn->szName));
conn->connect(drmConn);
} else if (conn->status != DRM_MODE_CONNECTED && conn->output) {
backend->log(AQ_LOG_DEBUG, std::format("drm: Connector {} disconnected", conn->szName));
conn->disconnect();
}
drmModeFreeConnector(drmConn);
@ -745,7 +741,7 @@ void Aquamarine::CDRMBackend::scanLeases() {
return;
}
for (auto const& c : connectors) {
for (auto& c : connectors) {
if (!c->output || !c->output->lease)
continue;
@ -767,7 +763,7 @@ void Aquamarine::CDRMBackend::scanLeases() {
auto l = c->output->lease;
for (auto const& c2 : connectors) {
for (auto& c2 : connectors) {
if (!c2->output || c2->output->lease != c->output->lease)
continue;
@ -824,7 +820,7 @@ static void handlePF(int fd, unsigned seq, unsigned tv_sec, unsigned tv_usec, un
.flags = flags,
});
if (BACKEND->sessionActive() && !pageFlip->connector->frameEventScheduled && pageFlip->connector->output->enabledState)
if (BACKEND->sessionActive() && !pageFlip->connector->frameEventScheduled)
pageFlip->connector->output->events.frame.emit();
}
@ -841,8 +837,6 @@ bool Aquamarine::CDRMBackend::dispatchEvents() {
}
uint32_t Aquamarine::CDRMBackend::capabilities() {
if (getCursorFormats().empty())
return 0;
return eBackendCapabilities::AQ_BACKEND_CAPABILITY_POINTER;
}
@ -872,7 +866,7 @@ void Aquamarine::CDRMBackend::onReady() {
}
}
for (auto const& c : connectors) {
for (auto& c : connectors) {
backend->log(AQ_LOG_DEBUG, std::format("drm: onReady: connector {}", c->id));
if (!c->output)
continue;
@ -894,7 +888,7 @@ void Aquamarine::CDRMBackend::onReady() {
}
std::vector<SDRMFormat> Aquamarine::CDRMBackend::getRenderFormats() {
for (auto const& p : planes) {
for (auto& p : planes) {
if (p->type != DRM_PLANE_TYPE_PRIMARY)
continue;
@ -909,7 +903,7 @@ std::vector<SDRMFormat> Aquamarine::CDRMBackend::getRenderableFormats() {
}
std::vector<SDRMFormat> Aquamarine::CDRMBackend::getCursorFormats() {
for (auto const& p : planes) {
for (auto& p : planes) {
if (p->type != DRM_PLANE_TYPE_CURSOR)
continue;
@ -1163,30 +1157,13 @@ void Aquamarine::SDRMConnector::parseEDID(std::vector<uint8_t> data) {
di_info_destroy(info);
}
void Aquamarine::SDRMConnector::recheckCRTCProps() {
if (!crtc || !output)
return;
uint64_t prop = 0;
canDoVrr = props.vrr_capable && crtc->props.vrr_enabled && getDRMProp(backend->gpu->fd, id, props.vrr_capable, &prop) && prop;
output->vrrCapable = canDoVrr;
backend->backend->log(AQ_LOG_DEBUG,
std::format("drm: connector {} crtc is {} of vrr: props.vrr_capable -> {}, crtc->props.vrr_enabled -> {}", szName, (canDoVrr ? "capable" : "incapable"),
props.vrr_capable, crtc->props.vrr_enabled));
output->supportsExplicit = backend->drmProps.supportsTimelines && crtc->props.out_fence_ptr && crtc->primary->props.in_fence_fd;
backend->backend->log(AQ_LOG_DEBUG, std::format("drm: Explicit sync {}", output->supportsExplicit ? "supported" : "unsupported"));
}
void Aquamarine::SDRMConnector::connect(drmModeConnector* connector) {
if (output) {
backend->backend->log(AQ_LOG_DEBUG, std::format("drm: Not connecting connector {} because it's already connected", szName));
return;
}
backend->backend->log(AQ_LOG_DEBUG, std::format("drm: Connecting connector {}, {}", szName, crtc ? std::format("CRTC ID {}", crtc->id) : "no CRTC"));
backend->backend->log(AQ_LOG_DEBUG, std::format("drm: Connecting connector {}, CRTC ID {}", szName, crtc ? crtc->id : -1));
output = SP<CDRMOutput>(new CDRMOutput(szName, backend, self.lock()));
output->self = output;
@ -1220,6 +1197,8 @@ void Aquamarine::SDRMConnector::connect(drmModeConnector* connector) {
//uint64_t modeID = 0;
// getDRMProp(backend->gpu->fd, crtc->id, crtc->props.mode_id, &modeID);
crtc->refresh = calculateRefresh(drmMode);
}
backend->backend->log(AQ_LOG_DEBUG,
@ -1227,8 +1206,10 @@ void Aquamarine::SDRMConnector::connect(drmModeConnector* connector) {
aqMode->preferred ? " (preferred)" : ""));
}
if (!currentModeInfo && fallbackMode)
if (!currentModeInfo && fallbackMode) {
output->state->setMode(fallbackMode);
crtc->refresh = calculateRefresh(fallbackMode->modeInfo.value());
}
output->physicalSize = {(double)connector->mmWidth, (double)connector->mmHeight};
@ -1251,6 +1232,13 @@ void Aquamarine::SDRMConnector::connect(drmModeConnector* connector) {
output->nonDesktop = prop;
}
canDoVrr = props.vrr_capable && crtc->props.vrr_enabled && getDRMProp(backend->gpu->fd, id, props.vrr_capable, &prop) && prop;
output->vrrCapable = canDoVrr;
backend->backend->log(AQ_LOG_DEBUG,
std::format("drm: crtc is {} of vrr: props.vrr_capable -> {}, crtc->props.vrr_enabled -> {}", (canDoVrr ? "capable" : "incapable"), props.vrr_capable,
crtc->props.vrr_enabled));
maxBpcBounds.fill(0);
if (props.max_bpc && !introspectDRMPropRange(backend->gpu->fd, props.max_bpc, maxBpcBounds.data(), &maxBpcBounds[1]))
@ -1267,24 +1255,23 @@ void Aquamarine::SDRMConnector::connect(drmModeConnector* connector) {
// TODO: subconnectors
output->make = make;
output->model = model;
output->serial = serial;
output->description = std::format("{} {} {} ({})", make, model, serial, szName);
output->needsFrame = true;
output->make = make;
output->model = model;
output->serial = serial;
output->description = std::format("{} {} {} ({})", make, model, serial, szName);
output->needsFrame = true;
output->supportsExplicit = backend->drmProps.supportsTimelines && crtc->props.out_fence_ptr && crtc->primary->props.in_fence_fd;
backend->backend->log(AQ_LOG_DEBUG, std::format("drm: Explicit sync {}", output->supportsExplicit ? "supported" : "unsupported"));
backend->backend->log(AQ_LOG_DEBUG, std::format("drm: Description {}", output->description));
status = DRM_MODE_CONNECTED;
recheckCRTCProps();
if (!backend->backend->ready)
return;
output->swapchain = CSwapchain::create(backend->backend->primaryAllocator, backend->self.lock());
output->swapchain->reconfigure(SSwapchainOptions{.length = 0, .scanout = true, .multigpu = !!backend->primary}); // mark the swapchain for scanout
output->needsFrame = true;
backend->backend->events.newOutput.emit(SP<IOutput>(output));
output->scheduleFrame(IOutput::AQ_SCHEDULE_NEW_CONNECTOR);
}
@ -1326,16 +1313,10 @@ void Aquamarine::SDRMConnector::applyCommit(const SDRMConnectorCommitData& data)
if (output->state->state().committed & COutputState::AQ_OUTPUT_STATE_MODE)
refresh = calculateRefresh(data.modeInfo);
output->enabledState = output->state->state().enabled;
}
void Aquamarine::SDRMConnector::rollbackCommit(const SDRMConnectorCommitData& data) {
// cursors are applied regardless,
// unless this was a test
if (data.test)
return;
// cursors are applied regardless.
if (crtc->cursor && data.cursorFB)
crtc->cursor->back = data.cursorFB;
@ -1394,33 +1375,12 @@ bool Aquamarine::CDRMOutput::commitState(bool onlyTest) {
const uint32_t COMMITTED = STATE.committed;
if ((COMMITTED & COutputState::eOutputStateProperties::AQ_OUTPUT_STATE_ENABLED) && STATE.enabled) {
if (!STATE.mode && !STATE.customMode) {
if (!STATE.mode && STATE.customMode) {
backend->backend->log(AQ_LOG_ERROR, "drm: No mode on enable commit");
return false;
}
}
if (STATE.drmFormat == DRM_FORMAT_INVALID) {
backend->backend->log(AQ_LOG_ERROR, "drm: No format for output");
return false;
}
if (COMMITTED & COutputState::eOutputStateProperties::AQ_OUTPUT_STATE_FORMAT) {
// verify the format is valid for the primary plane
bool ok = false;
for (auto const& f : getRenderFormats()) {
if (f.drmFormat == STATE.drmFormat) {
ok = true;
break;
}
}
if (!ok) {
backend->backend->log(AQ_LOG_ERROR, "drm: Selected format is not supported by the primary KMS plane");
return false;
}
}
if (STATE.adaptiveSync && !connector->canDoVrr) {
backend->backend->log(AQ_LOG_ERROR, "drm: No Adaptive sync support for output");
return false;
@ -1492,7 +1452,7 @@ bool Aquamarine::CDRMOutput::commitState(bool onlyTest) {
if (!mgpu.swapchain) {
TRACE(backend->backend->log(AQ_LOG_TRACE, "drm: No swapchain for blit, creating"));
mgpu.swapchain = CSwapchain::create(backend->rendererState.allocator, backend.lock());
mgpu.swapchain = CSwapchain::create(backend->mgpu.allocator, backend.lock());
}
auto OPTIONS = swapchain->currentOptions();
@ -1508,22 +1468,12 @@ bool Aquamarine::CDRMOutput::commitState(bool onlyTest) {
return false;
}
auto NEWAQBUF = mgpu.swapchain->next(nullptr);
auto blitResult = backend->rendererState.renderer->blit(
STATE.buffer, NEWAQBUF, (COMMITTED & COutputState::eOutputStateProperties::AQ_OUTPUT_STATE_EXPLICIT_IN_FENCE) ? STATE.explicitInFence : -1);
if (!blitResult.success) {
auto NEWAQBUF = mgpu.swapchain->next(nullptr);
if (!backend->mgpu.renderer->blit(STATE.buffer, NEWAQBUF)) {
backend->backend->log(AQ_LOG_ERROR, "drm: Backend requires blit, but blit failed");
return false;
}
// replace the explicit in fence if the blitting backend returned one, otherwise discard old. Passed fence from the client is wrong.
// if the commit doesn't have an explicit fence, don't use the one we created, just fallback to implicit
static auto NO_EXPLICIT = envEnabled("AQ_MGPU_NO_EXPLICIT");
if (blitResult.syncFD.has_value() && !NO_EXPLICIT && (COMMITTED & COutputState::eOutputStateProperties::AQ_OUTPUT_STATE_EXPLICIT_IN_FENCE))
state->setExplicitInFence(blitResult.syncFD.value());
else
state->setExplicitInFence(-1);
drmFB = CDRMFB::create(NEWAQBUF, backend, nullptr); // will return attachment if present
} else
drmFB = CDRMFB::create(STATE.buffer, backend, nullptr); // will return attachment if present
@ -1551,7 +1501,6 @@ bool Aquamarine::CDRMOutput::commitState(bool onlyTest) {
fourccToName(STATE.drmFormat), fourccToName(params.format)));
state->setFormat(params.format);
formatMismatch = true;
// TODO: reject if tearing? We will miss a frame event!
flags &= ~DRM_MODE_PAGE_FLIP_ASYNC; // we cannot modeset with async pf
}
}
@ -1588,7 +1537,7 @@ bool Aquamarine::CDRMOutput::commitState(bool onlyTest) {
// to avoid doing this over and over.
data.modeset = true;
data.blocking = true;
data.flags = onlyTest ? 0 : DRM_MODE_PAGE_FLIP_EVENT;
data.flags = DRM_MODE_PAGE_FLIP_EVENT;
ok = connector->commitState(data);
if (!ok)
@ -1607,28 +1556,6 @@ bool Aquamarine::CDRMOutput::commitState(bool onlyTest) {
if (ok)
connector->commitTainted = false;
if (data.flags & DRM_MODE_PAGE_FLIP_ASYNC) {
// for tearing commits, we will send presentation feedback instantly, and rotate
// drm framebuffers to properly send backendRelease events.
// the last FB should already be gone from KMS because it's been immediately replaced
// no completion and no vsync, because tearing
uint32_t flags = IOutput::AQ_OUTPUT_PRESENT_HW_CLOCK | IOutput::AQ_OUTPUT_PRESENT_ZEROCOPY;
timespec presented;
clock_gettime(CLOCK_MONOTONIC, &presented);
connector->output->events.present.emit(IOutput::SPresentEvent{
.presented = backend->sessionActive(),
.when = &presented,
.seq = 0, /* unknown sequence for tearing */
.refresh = (int)(connector->refresh ? (1000000000000LL / connector->refresh) : 0),
.flags = flags,
});
connector->onPresent();
}
return ok;
}
@ -1642,9 +1569,6 @@ bool Aquamarine::CDRMOutput::setCursor(SP<IBuffer> buffer, const Vector2D& hotsp
return false;
}
if (!connector->crtc)
return false;
if (!buffer)
setCursorVisible(false);
else {
@ -1655,7 +1579,7 @@ bool Aquamarine::CDRMOutput::setCursor(SP<IBuffer> buffer, const Vector2D& hotsp
if (!mgpu.cursorSwapchain) {
TRACE(backend->backend->log(AQ_LOG_TRACE, "drm: No cursorSwapchain for blit, creating"));
mgpu.cursorSwapchain = CSwapchain::create(backend->rendererState.allocator, backend.lock());
mgpu.cursorSwapchain = CSwapchain::create(backend->mgpu.allocator, backend.lock());
}
auto OPTIONS = mgpu.cursorSwapchain->currentOptions();
@ -1672,7 +1596,7 @@ bool Aquamarine::CDRMOutput::setCursor(SP<IBuffer> buffer, const Vector2D& hotsp
}
auto NEWAQBUF = mgpu.cursorSwapchain->next(nullptr);
if (!backend->rendererState.renderer->blit(buffer, NEWAQBUF).success) {
if (!backend->mgpu.renderer->blit(buffer, NEWAQBUF)) {
backend->backend->log(AQ_LOG_ERROR, "drm: Backend requires blit, but cursor blit failed");
return false;
}
@ -1699,10 +1623,10 @@ bool Aquamarine::CDRMOutput::setCursor(SP<IBuffer> buffer, const Vector2D& hotsp
return true;
}
void Aquamarine::CDRMOutput::moveCursor(const Vector2D& coord, bool skipSchedule) {
void Aquamarine::CDRMOutput::moveCursor(const Vector2D& coord, bool skipShedule) {
cursorPos = coord;
// cursorVisible = true;
backend->impl->moveCursor(connector, skipSchedule);
backend->impl->moveCursor(connector, skipShedule);
}
void Aquamarine::CDRMOutput::scheduleFrame(const scheduleFrameReason reason) {
@ -1711,7 +1635,7 @@ void Aquamarine::CDRMOutput::scheduleFrame(const scheduleFrameReason reason) {
connector->isPageFlipPending, connector->frameEventScheduled)));
needsFrame = true;
if (connector->isPageFlipPending || connector->frameEventScheduled || !enabledState)
if (connector->isPageFlipPending || connector->frameEventScheduled)
return;
connector->frameEventScheduled = true;
@ -1739,10 +1663,6 @@ size_t Aquamarine::CDRMOutput::getGammaSize() {
}
std::vector<SDRMFormat> Aquamarine::CDRMOutput::getRenderFormats() {
if (!connector->crtc || !connector->crtc->primary || connector->crtc->primary->formats.empty()) {
backend->log(AQ_LOG_ERROR, "Can't get formats: no crtc");
return {};
}
return connector->crtc->primary->formats;
}
@ -1962,14 +1882,14 @@ void Aquamarine::SDRMConnectorCommitData::calculateMode(Hyprutils::Memory::CShar
di_cvt_compute(&timing, &options);
uint16_t hsync_start = (int)MODE->pixelSize.x + timing.h_front_porch;
uint16_t hsync_start = (int)MODE->pixelSize.y + timing.h_front_porch;
uint16_t vsync_start = timing.v_lines_rnd + timing.v_front_porch;
uint16_t hsync_end = hsync_start + timing.h_sync;
uint16_t vsync_end = vsync_start + timing.v_sync;
modeInfo = (drmModeModeInfo){
.clock = (uint32_t)std::round(timing.act_pixel_freq * 1000),
.hdisplay = (uint16_t)MODE->pixelSize.x,
.hdisplay = (uint16_t)MODE->pixelSize.y,
.hsync_start = hsync_start,
.hsync_end = hsync_end,
.htotal = (uint16_t)(hsync_end + timing.h_back_porch),
@ -1981,11 +1901,6 @@ void Aquamarine::SDRMConnectorCommitData::calculateMode(Hyprutils::Memory::CShar
.flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC,
};
snprintf(modeInfo.name, sizeof(modeInfo.name), "%dx%d", (int)MODE->pixelSize.x, (int)MODE->pixelSize.y);
TRACE(connector->backend->log(AQ_LOG_TRACE,
std::format("drm: calculateMode: modeline dump: {} {} {} {} {} {} {} {} {} {} {}", modeInfo.clock, modeInfo.hdisplay, modeInfo.hsync_start,
modeInfo.hsync_end, modeInfo.htotal, modeInfo.vdisplay, modeInfo.vsync_start, modeInfo.vsync_end, modeInfo.vtotal, modeInfo.vrefresh,
modeInfo.flags)));
}
Aquamarine::CDRMBufferAttachment::CDRMBufferAttachment(SP<CDRMFB> fb_) : fb(fb_) {
@ -2001,7 +1916,7 @@ SP<CDRMLease> Aquamarine::CDRMLease::create(std::vector<SP<IOutput>> outputs) {
auto backend = ((CDRMBackend*)outputs.at(0)->getBackend().get())->self.lock();
for (auto const& o : outputs) {
for (auto& o : outputs) {
if (o->getBackend() != backend) {
backend->log(AQ_LOG_ERROR, "drm lease: Mismatched backends");
return nullptr;
@ -2012,7 +1927,7 @@ SP<CDRMLease> Aquamarine::CDRMLease::create(std::vector<SP<IOutput>> outputs) {
auto lease = SP<CDRMLease>(new CDRMLease);
for (auto const& o : outputs) {
for (auto& o : outputs) {
auto drmo = ((CDRMOutput*)o.get())->self.lock();
backend->log(AQ_LOG_DEBUG, std::format("drm lease: output {}, connector {}", drmo->name, drmo->connector->id));
@ -2041,7 +1956,7 @@ SP<CDRMLease> Aquamarine::CDRMLease::create(std::vector<SP<IOutput>> outputs) {
return nullptr;
}
for (auto const& o : lease->outputs) {
for (auto& o : lease->outputs) {
o->lease = lease;
}

View File

@ -3,7 +3,6 @@
#include <xf86drmMode.h>
#include <cstring>
#include <fcntl.h>
#include <unistd.h>
#include "Math.hpp"
#include "Shared.hpp"
#include "FormatUtils.hpp"
@ -156,7 +155,7 @@ bool CDRMRenderer::initDRMFormats() {
std::vector<SGLFormat> dmaFormats;
for (auto const& fmt : formats) {
for (auto& fmt : formats) {
std::vector<std::pair<uint64_t, bool>> mods;
auto ret = getModsForFormat(fmt);
@ -170,7 +169,7 @@ bool CDRMRenderer::initDRMFormats() {
// EGL can always do implicit modifiers.
mods.push_back({DRM_FORMAT_MOD_INVALID, true});
for (auto const& [mod, external] : mods) {
for (auto& [mod, external] : mods) {
dmaFormats.push_back(SGLFormat{
.drmFormat = (uint32_t)fmt,
.modifier = mod,
@ -179,7 +178,7 @@ bool CDRMRenderer::initDRMFormats() {
}
TRACE(backend->log(AQ_LOG_TRACE, std::format("EGL: GPU Supports Format {} (0x{:x})", fourccToName((uint32_t)fmt), fmt)));
for (auto const& [mod, external] : mods) {
for (auto& [mod, external] : mods) {
auto modName = drmGetFormatModifierName(mod);
TRACE(backend->log(AQ_LOG_TRACE, std::format("EGL: | {}with modifier 0x{:x}: {}", (external ? "external only " : ""), mod, modName ? modName : "?unknown?")));
free(modName);
@ -224,20 +223,6 @@ SP<CDRMRenderer> CDRMRenderer::attempt(Hyprutils::Memory::CSharedPointer<CGBMAll
loadGLProc(&renderer->egl.glEGLImageTargetRenderbufferStorageOES, "glEGLImageTargetRenderbufferStorageOES");
loadGLProc(&renderer->egl.eglQueryDmaBufFormatsEXT, "eglQueryDmaBufFormatsEXT");
loadGLProc(&renderer->egl.eglQueryDmaBufModifiersEXT, "eglQueryDmaBufModifiersEXT");
loadGLProc(&renderer->egl.eglDestroySyncKHR, "eglDestroySyncKHR");
loadGLProc(&renderer->egl.eglWaitSyncKHR, "eglWaitSyncKHR");
loadGLProc(&renderer->egl.eglCreateSyncKHR, "eglCreateSyncKHR");
loadGLProc(&renderer->egl.eglDupNativeFenceFDANDROID, "eglDupNativeFenceFDANDROID");
if (!renderer->egl.eglCreateSyncKHR) {
backend_->log(AQ_LOG_ERROR, "CDRMRenderer: fail, no eglCreateSyncKHR");
return nullptr;
}
if (!renderer->egl.eglDupNativeFenceFDANDROID) {
backend_->log(AQ_LOG_ERROR, "CDRMRenderer: fail, no eglDupNativeFenceFDANDROID");
return nullptr;
}
if (!renderer->egl.eglGetPlatformDisplayEXT) {
backend_->log(AQ_LOG_ERROR, "CDRMRenderer: fail, no eglGetPlatformDisplayEXT");
@ -455,7 +440,7 @@ SGLTex CDRMRenderer::glTex(Hyprutils::Memory::CSharedPointer<IBuffer> buffa) {
}
bool external = false;
for (auto const& fmt : formats) {
for (auto& fmt : formats) {
if (fmt.drmFormat != dma.format || fmt.modifier != dma.modifier)
continue;
@ -484,140 +469,12 @@ inline const float fullVerts[] = {
0, 1, // bottom left
};
void CDRMRenderer::waitOnSync(int fd) {
TRACE(backend->log(AQ_LOG_TRACE, std::format("EGL (waitOnSync): attempting to wait on fd {}", fd)));
std::vector<EGLint> attribs;
int dupFd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
if (dupFd < 0) {
backend->log(AQ_LOG_TRACE, "EGL (waitOnSync): failed to dup fd for wait");
return;
}
attribs.push_back(EGL_SYNC_NATIVE_FENCE_FD_ANDROID);
attribs.push_back(dupFd);
attribs.push_back(EGL_NONE);
EGLSyncKHR sync = egl.eglCreateSyncKHR(egl.display, EGL_SYNC_NATIVE_FENCE_ANDROID, attribs.data());
if (sync == EGL_NO_SYNC_KHR) {
TRACE(backend->log(AQ_LOG_TRACE, "EGL (waitOnSync): failed to create an egl sync for explicit"));
if (dupFd >= 0)
close(dupFd);
return;
}
// we got a sync, now we just tell egl to wait before sampling
if (egl.eglWaitSyncKHR(egl.display, sync, 0) != EGL_TRUE) {
if (egl.eglDestroySyncKHR(egl.display, sync) != EGL_TRUE)
TRACE(backend->log(AQ_LOG_TRACE, "EGL (waitOnSync): failed to destroy sync"));
TRACE(backend->log(AQ_LOG_TRACE, "EGL (waitOnSync): failed to wait on the sync object"));
return;
}
if (egl.eglDestroySyncKHR(egl.display, sync) != EGL_TRUE)
TRACE(backend->log(AQ_LOG_TRACE, "EGL (waitOnSync): failed to destroy sync"));
}
int CDRMRenderer::recreateBlitSync() {
TRACE(backend->log(AQ_LOG_TRACE, "EGL (recreateBlitSync): recreating blit sync"));
if (egl.lastBlitSync) {
TRACE(backend->log(AQ_LOG_TRACE, std::format("EGL (recreateBlitSync): cleaning up old sync (fd {})", egl.lastBlitSyncFD)));
// cleanup last sync
if (egl.eglDestroySyncKHR(egl.display, egl.lastBlitSync) != EGL_TRUE)
TRACE(backend->log(AQ_LOG_TRACE, "EGL (recreateBlitSync): failed to destroy old sync"));
if (egl.lastBlitSyncFD >= 0)
close(egl.lastBlitSyncFD);
egl.lastBlitSyncFD = -1;
egl.lastBlitSync = nullptr;
}
EGLSyncKHR sync = egl.eglCreateSyncKHR(egl.display, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr);
if (sync == EGL_NO_SYNC_KHR) {
TRACE(backend->log(AQ_LOG_TRACE, "EGL (recreateBlitSync): failed to create an egl sync for explicit"));
return -1;
}
// we need to flush otherwise we might not get a valid fd
glFlush();
int fd = egl.eglDupNativeFenceFDANDROID(egl.display, sync);
if (fd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
TRACE(backend->log(AQ_LOG_TRACE, "EGL (recreateBlitSync): failed to dup egl fence fd"));
if (egl.eglDestroySyncKHR(egl.display, sync) != EGL_TRUE)
TRACE(backend->log(AQ_LOG_TRACE, "EGL (recreateBlitSync): failed to destroy new sync"));
return -1;
}
egl.lastBlitSync = sync;
egl.lastBlitSyncFD = fd;
TRACE(backend->log(AQ_LOG_TRACE, std::format("EGL (recreateBlitSync): success, new fence exported with fd {}", fd)));
return fd;
}
void CDRMRenderer::clearBuffer(IBuffer* buf) {
setEGL();
auto dmabuf = buf->dmabuf();
GLuint rboID = 0, fboID = 0;
if (!dmabuf.success) {
backend->log(AQ_LOG_ERROR, "EGL (clear): cannot clear a non-dmabuf");
return;
}
auto rboImage = createEGLImage(dmabuf);
if (rboImage == EGL_NO_IMAGE_KHR) {
backend->log(AQ_LOG_ERROR, std::format("EGL (clear): createEGLImage failed: {}", eglGetError()));
return;
}
GLCALL(glGenRenderbuffers(1, &rboID));
GLCALL(glBindRenderbuffer(GL_RENDERBUFFER, rboID));
GLCALL(egl.glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, (GLeglImageOES)rboImage));
GLCALL(glBindRenderbuffer(GL_RENDERBUFFER, 0));
GLCALL(glGenFramebuffers(1, &fboID));
GLCALL(glBindFramebuffer(GL_FRAMEBUFFER, fboID));
GLCALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rboID));
GLCALL(glBindRenderbuffer(GL_RENDERBUFFER, rboID));
GLCALL(glBindFramebuffer(GL_FRAMEBUFFER, fboID));
TRACE(backend->log(AQ_LOG_TRACE, std::format("EGL (clear): fbo {} rbo {}", fboID, rboID)));
glClearColor(0.F, 0.F, 0.F, 1.F);
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
GLCALL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
GLCALL(glBindRenderbuffer(GL_RENDERBUFFER, 0));
glDeleteFramebuffers(1, &fboID);
glDeleteRenderbuffers(1, &rboID);
egl.eglDestroyImageKHR(egl.display, rboImage);
restoreEGL();
}
CDRMRenderer::SBlitResult CDRMRenderer::blit(SP<IBuffer> from, SP<IBuffer> to, int waitFD) {
bool CDRMRenderer::blit(SP<IBuffer> from, SP<IBuffer> to) {
setEGL();
if (from->dmabuf().size != to->dmabuf().size) {
backend->log(AQ_LOG_ERROR, "EGL (blit): buffer sizes mismatched");
return {};
}
if (waitFD >= 0) {
// wait on a provided explicit fence
waitOnSync(waitFD);
return false;
}
// firstly, get a texture from the from buffer
@ -657,7 +514,7 @@ CDRMRenderer::SBlitResult CDRMRenderer::blit(SP<IBuffer> from, SP<IBuffer> to, i
if (!verifyDestinationDMABUF(toDma)) {
backend->log(AQ_LOG_ERROR, "EGL (blit): failed to blit: destination dmabuf unsupported");
return {};
return false;
}
{
@ -676,7 +533,7 @@ CDRMRenderer::SBlitResult CDRMRenderer::blit(SP<IBuffer> from, SP<IBuffer> to, i
rboImage = createEGLImage(toDma);
if (rboImage == EGL_NO_IMAGE_KHR) {
backend->log(AQ_LOG_ERROR, std::format("EGL (blit): createEGLImage failed: {}", eglGetError()));
return {};
return false;
}
GLCALL(glGenRenderbuffers(1, &rboID));
@ -690,7 +547,7 @@ CDRMRenderer::SBlitResult CDRMRenderer::blit(SP<IBuffer> from, SP<IBuffer> to, i
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
backend->log(AQ_LOG_ERROR, std::format("EGL (blit): glCheckFramebufferStatus failed: {}", glGetError()));
return {};
return false;
}
// should never remove anything, but JIC. We'll leak an RBO and FBO if this removes anything.
@ -766,19 +623,15 @@ CDRMRenderer::SBlitResult CDRMRenderer::blit(SP<IBuffer> from, SP<IBuffer> to, i
GLCALL(glBindTexture(fromTex.target, 0));
// rendered, cleanup
glFlush();
// get an explicit sync fd for the secondary gpu.
// when we pass buffers between gpus we should always use explicit sync,
// as implicit is not guaranteed at all
int explicitFD = recreateBlitSync();
glFlush();
GLCALL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
GLCALL(glBindRenderbuffer(GL_RENDERBUFFER, 0));
restoreEGL();
return {true, explicitFD == -1 ? std::nullopt : std::optional<int>{explicitFD}};
return true;
}
void CDRMRenderer::onBufferAttachmentDrop(CDRMRendererBufferAttachment* attachment) {
@ -802,7 +655,7 @@ void CDRMRenderer::onBufferAttachmentDrop(CDRMRendererBufferAttachment* attachme
}
bool CDRMRenderer::verifyDestinationDMABUF(const SDMABUFAttrs& attrs) {
for (auto const& fmt : formats) {
for (auto& fmt : formats) {
if (fmt.drmFormat != attrs.format)
continue;

View File

@ -47,19 +47,12 @@ namespace Aquamarine {
int drmFD = -1;
struct SBlitResult {
bool success = false;
std::optional<int> syncFD;
};
bool blit(Hyprutils::Memory::CSharedPointer<IBuffer> from, Hyprutils::Memory::CSharedPointer<IBuffer> to);
SBlitResult blit(Hyprutils::Memory::CSharedPointer<IBuffer> from, Hyprutils::Memory::CSharedPointer<IBuffer> to, int waitFD = -1);
// can't be a SP<> because we call it from buf's ctor...
void clearBuffer(IBuffer* buf);
void setEGL();
void restoreEGL();
void setEGL();
void restoreEGL();
void onBufferAttachmentDrop(CDRMRendererBufferAttachment* attachment);
void onBufferAttachmentDrop(CDRMRendererBufferAttachment* attachment);
struct {
struct SShader {
@ -69,10 +62,8 @@ namespace Aquamarine {
} gl;
struct {
EGLDisplay display = nullptr;
EGLContext context = nullptr;
EGLSync lastBlitSync = nullptr;
int lastBlitSyncFD = -1;
EGLDisplay display = nullptr;
EGLContext context = nullptr;
PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = nullptr;
PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR = nullptr;
@ -81,10 +72,6 @@ namespace Aquamarine {
PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC glEGLImageTargetRenderbufferStorageOES = nullptr;
PFNEGLQUERYDMABUFFORMATSEXTPROC eglQueryDmaBufFormatsEXT = nullptr;
PFNEGLQUERYDMABUFMODIFIERSEXTPROC eglQueryDmaBufModifiersEXT = nullptr;
PFNEGLDESTROYSYNCKHRPROC eglDestroySyncKHR = nullptr;
PFNEGLWAITSYNCKHRPROC eglWaitSyncKHR = nullptr;
PFNEGLCREATESYNCKHRPROC eglCreateSyncKHR = nullptr;
PFNEGLDUPNATIVEFENCEFDANDROIDPROC eglDupNativeFenceFDANDROID = nullptr;
} egl;
struct {
@ -105,8 +92,6 @@ namespace Aquamarine {
std::optional<std::vector<std::pair<uint64_t, bool>>> getModsForFormat(EGLint format);
bool initDRMFormats();
bool verifyDestinationDMABUF(const SDMABUFAttrs& attrs);
void waitOnSync(int fd);
int recreateBlitSync();
bool hasModifiers = false;
Hyprutils::Memory::CWeakPointer<CBackend> backend;

View File

@ -221,7 +221,6 @@ Aquamarine::CDRMAtomicImpl::CDRMAtomicImpl(Hyprutils::Memory::CSharedPointer<CDR
bool Aquamarine::CDRMAtomicImpl::prepareConnector(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, SDRMConnectorCommitData& data) {
const auto& STATE = connector->output->state->state();
const bool enable = STATE.enabled;
const auto& MODE = STATE.mode ? STATE.mode : STATE.customMode;
if (data.modeset) {
if (!enable)
@ -263,12 +262,11 @@ bool Aquamarine::CDRMAtomicImpl::prepareConnector(Hyprutils::Memory::CSharedPoin
}
}
if ((STATE.committed & COutputState::AQ_OUTPUT_STATE_DAMAGE) && connector->crtc->primary->props.fb_damage_clips && MODE) {
if (STATE.committed & COutputState::AQ_OUTPUT_STATE_DAMAGE && connector->crtc->primary->props.fb_damage_clips) {
if (STATE.damage.empty())
data.atomic.fbDamage = 0;
else {
TRACE(connector->backend->backend->log(AQ_LOG_TRACE, std::format("atomic drm: clipping damage to pixel size {}", MODE->pixelSize)));
std::vector<pixman_box32_t> rects = STATE.damage.copy().intersect(CBox{{}, MODE->pixelSize}).getRects();
std::vector<pixman_box32_t> rects = STATE.damage.getRects();
if (drmModeCreatePropertyBlob(connector->backend->gpu->fd, rects.data(), sizeof(pixman_box32_t) * rects.size(), &data.atomic.fbDamage)) {
connector->backend->backend->log(AQ_LOG_ERROR, "atomic drm: failed to create a damage blob");
return false;
@ -310,27 +308,27 @@ bool Aquamarine::CDRMAtomicImpl::commit(Hyprutils::Memory::CSharedPointer<SDRMCo
bool Aquamarine::CDRMAtomicImpl::reset() {
CDRMAtomicRequest request(backend);
for (auto const& crtc : backend->crtcs) {
for (auto& crtc : backend->crtcs) {
request.add(crtc->id, crtc->props.mode_id, 0);
request.add(crtc->id, crtc->props.active, 0);
}
for (auto const& conn : backend->connectors) {
for (auto& conn : backend->connectors) {
request.add(conn->id, conn->props.crtc_id, 0);
}
for (auto const& plane : backend->planes) {
for (auto& plane : backend->planes) {
request.planeProps(plane, nullptr, 0, {});
}
return request.commit(DRM_MODE_ATOMIC_ALLOW_MODESET);
}
bool Aquamarine::CDRMAtomicImpl::moveCursor(SP<SDRMConnector> connector, bool skipSchedule) {
bool Aquamarine::CDRMAtomicImpl::moveCursor(SP<SDRMConnector> connector, bool skipShedule) {
if (!connector->output->cursorVisible || !connector->output->state->state().enabled || !connector->crtc || !connector->crtc->cursor)
return true;
if (!skipSchedule) {
if (!skipShedule) {
TRACE(connector->backend->log(AQ_LOG_TRACE, "atomic moveCursor"));
connector->output->scheduleFrame(IOutput::AQ_SCHEDULE_CURSOR_MOVE);
}

View File

@ -14,11 +14,11 @@ Aquamarine::CDRMLegacyImpl::CDRMLegacyImpl(Hyprutils::Memory::CSharedPointer<CDR
;
}
bool Aquamarine::CDRMLegacyImpl::moveCursor(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, bool skipSchedule) {
bool Aquamarine::CDRMLegacyImpl::moveCursor(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, bool skipShedule) {
if (!connector->output->cursorVisible || !connector->output->state->state().enabled || !connector->crtc || !connector->crtc->cursor)
return true;
if (!skipSchedule)
if (!skipShedule)
connector->output->scheduleFrame(IOutput::AQ_SCHEDULE_CURSOR_MOVE);
return true;
@ -153,7 +153,7 @@ bool Aquamarine::CDRMLegacyImpl::commit(Hyprutils::Memory::CSharedPointer<SDRMCo
bool Aquamarine::CDRMLegacyImpl::reset() {
bool ok = true;
for (auto const& connector : backend->connectors) {
for (auto& connector : backend->connectors) {
if (!connector->crtc)
continue;

View File

@ -5,7 +5,7 @@ using namespace Hyprutils::Memory;
#define SP CSharedPointer
bool Aquamarine::CAttachmentManager::has(eAttachmentType type) {
for (auto const& a : attachments) {
for (auto& a : attachments) {
if (a->type() == type)
return true;
}
@ -13,7 +13,7 @@ bool Aquamarine::CAttachmentManager::has(eAttachmentType type) {
}
SP<IAttachment> Aquamarine::CAttachmentManager::get(eAttachmentType type) {
for (auto const& a : attachments) {
for (auto& a : attachments) {
if (a->type() == type)
return a;
}

View File

@ -3,7 +3,7 @@
using namespace Aquamarine;
Hyprutils::Memory::CSharedPointer<SOutputMode> Aquamarine::IOutput::preferredMode() {
for (auto const& m : modes) {
for (auto& m : modes) {
if (m->preferred)
return m;
}
@ -11,7 +11,7 @@ Hyprutils::Memory::CSharedPointer<SOutputMode> Aquamarine::IOutput::preferredMod
return nullptr;
}
void Aquamarine::IOutput::moveCursor(const Hyprutils::Math::Vector2D& coord, bool skipSchedule) {
void Aquamarine::IOutput::moveCursor(const Hyprutils::Math::Vector2D& coord, bool skipShedule) {
;
}

View File

@ -1,7 +1,6 @@
#include "FormatUtils.hpp"
#include <drm_fourcc.h>
#include <xf86drm.h>
#include <cstdlib>
std::string fourccToName(uint32_t drmFormat) {
auto fmt = drmGetFormatName(drmFormat);