dumb allocator
This commit is contained in:
parent
493f2c8cd4
commit
95d6c8ac0e
|
|
@ -0,0 +1,70 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Allocator.hpp"
|
||||||
|
|
||||||
|
struct gbm_device;
|
||||||
|
|
||||||
|
namespace Aquamarine {
|
||||||
|
class CDumbAllocator;
|
||||||
|
class CBackend;
|
||||||
|
class CSwapchain;
|
||||||
|
|
||||||
|
class CDumbBuffer : public IBuffer {
|
||||||
|
public:
|
||||||
|
virtual ~CDumbBuffer();
|
||||||
|
|
||||||
|
virtual eBufferCapability caps();
|
||||||
|
virtual eBufferType type();
|
||||||
|
virtual void update(const Hyprutils::Math::CRegion& damage);
|
||||||
|
virtual bool isSynchronous();
|
||||||
|
virtual bool good();
|
||||||
|
virtual SSHMAttrs shm();
|
||||||
|
virtual std::tuple<uint8_t*, uint32_t, size_t> beginDataPtr(uint32_t flags);
|
||||||
|
virtual void endDataPtr();
|
||||||
|
|
||||||
|
private:
|
||||||
|
CDumbBuffer(const SAllocatorBufferParams& params, Hyprutils::Memory::CWeakPointer<CDumbAllocator> allocator_, Hyprutils::Memory::CSharedPointer<CSwapchain> swapchain);
|
||||||
|
|
||||||
|
Hyprutils::Memory::CWeakPointer<CDumbAllocator> allocator;
|
||||||
|
|
||||||
|
// dumb stuff
|
||||||
|
int drmFd;
|
||||||
|
uint32_t handle;
|
||||||
|
void* data = nullptr;
|
||||||
|
size_t length = 0;
|
||||||
|
|
||||||
|
SSHMAttrs attrs{.success = false};
|
||||||
|
|
||||||
|
friend class CDumbAllocator;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CDumbAllocator : public IAllocator {
|
||||||
|
public:
|
||||||
|
~CDumbAllocator();
|
||||||
|
static Hyprutils::Memory::CSharedPointer<CDumbAllocator> create(int drmfd_, Hyprutils::Memory::CWeakPointer<CBackend> backend_);
|
||||||
|
|
||||||
|
virtual Hyprutils::Memory::CSharedPointer<IBuffer> acquire(const SAllocatorBufferParams& params, Hyprutils::Memory::CSharedPointer<CSwapchain> swapchain_);
|
||||||
|
virtual Hyprutils::Memory::CSharedPointer<CBackend> getBackend();
|
||||||
|
virtual int drmFD();
|
||||||
|
|
||||||
|
//
|
||||||
|
Hyprutils::Memory::CWeakPointer<CDumbAllocator> self;
|
||||||
|
|
||||||
|
private:
|
||||||
|
CDumbAllocator(int fd_, Hyprutils::Memory::CWeakPointer<CBackend> backend_);
|
||||||
|
|
||||||
|
// a vector purely for tracking (debugging) the buffers and nothing more
|
||||||
|
std::vector<Hyprutils::Memory::CWeakPointer<CDumbBuffer>> buffers;
|
||||||
|
|
||||||
|
int fd = -1;
|
||||||
|
Hyprutils::Memory::CWeakPointer<CBackend> backend;
|
||||||
|
|
||||||
|
// gbm stuff
|
||||||
|
gbm_device* gbmDevice = nullptr;
|
||||||
|
std::string gbmDeviceBackendName = "";
|
||||||
|
std::string drmName = "";
|
||||||
|
|
||||||
|
friend class CDumbBuffer;
|
||||||
|
friend class CDRMRenderer;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
@ -37,35 +37,6 @@ namespace Aquamarine {
|
||||||
friend class CGBMAllocator;
|
friend class CGBMAllocator;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CGBMDumbBuffer : public IBuffer {
|
|
||||||
public:
|
|
||||||
virtual ~CGBMDumbBuffer();
|
|
||||||
|
|
||||||
virtual eBufferCapability caps();
|
|
||||||
virtual eBufferType type();
|
|
||||||
virtual void update(const Hyprutils::Math::CRegion& damage);
|
|
||||||
virtual bool isSynchronous();
|
|
||||||
virtual bool good();
|
|
||||||
virtual SDMABUFAttrs dmabuf();
|
|
||||||
virtual std::tuple<uint8_t*, uint32_t, size_t> beginDataPtr(uint32_t flags);
|
|
||||||
virtual void endDataPtr();
|
|
||||||
|
|
||||||
private:
|
|
||||||
CGBMDumbBuffer(const SAllocatorBufferParams& params, Hyprutils::Memory::CWeakPointer<CGBMAllocator> allocator_, Hyprutils::Memory::CSharedPointer<CSwapchain> swapchain);
|
|
||||||
|
|
||||||
Hyprutils::Memory::CWeakPointer<CGBMAllocator> allocator;
|
|
||||||
|
|
||||||
// dumb stuff
|
|
||||||
int m_drmFd;
|
|
||||||
uint32_t m_handle;
|
|
||||||
void* m_data = nullptr;
|
|
||||||
size_t m_size = 0;
|
|
||||||
|
|
||||||
SDMABUFAttrs attrs{.success = false};
|
|
||||||
|
|
||||||
friend class CGBMAllocator;
|
|
||||||
};
|
|
||||||
|
|
||||||
class CGBMAllocator : public IAllocator {
|
class CGBMAllocator : public IAllocator {
|
||||||
public:
|
public:
|
||||||
~CGBMAllocator();
|
~CGBMAllocator();
|
||||||
|
|
@ -82,10 +53,10 @@ namespace Aquamarine {
|
||||||
CGBMAllocator(int fd_, Hyprutils::Memory::CWeakPointer<CBackend> backend_);
|
CGBMAllocator(int fd_, Hyprutils::Memory::CWeakPointer<CBackend> backend_);
|
||||||
|
|
||||||
// a vector purely for tracking (debugging) the buffers and nothing more
|
// a vector purely for tracking (debugging) the buffers and nothing more
|
||||||
std::vector<Hyprutils::Memory::CWeakPointer<IBuffer>> buffers;
|
std::vector<Hyprutils::Memory::CWeakPointer<CGBMBuffer>> buffers;
|
||||||
|
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
Hyprutils::Memory::CWeakPointer<CBackend> backend;
|
Hyprutils::Memory::CWeakPointer<CBackend> backend;
|
||||||
|
|
||||||
// gbm stuff
|
// gbm stuff
|
||||||
gbm_device* gbmDevice = nullptr;
|
gbm_device* gbmDevice = nullptr;
|
||||||
|
|
@ -93,7 +64,6 @@ namespace Aquamarine {
|
||||||
std::string drmName = "";
|
std::string drmName = "";
|
||||||
|
|
||||||
friend class CGBMBuffer;
|
friend class CGBMBuffer;
|
||||||
friend class CGBMDumbBuffer;
|
|
||||||
friend class CDRMRenderer;
|
friend class CDRMRenderer;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,6 @@ namespace Aquamarine {
|
||||||
int lastAcquired = 0;
|
int lastAcquired = 0;
|
||||||
|
|
||||||
friend class CGBMBuffer;
|
friend class CGBMBuffer;
|
||||||
friend class CGBMDumbBuffer;
|
friend class CDumbBuffer;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,10 @@ namespace Aquamarine {
|
||||||
virtual std::vector<SDRMFormat> getCursorFormats() = 0;
|
virtual std::vector<SDRMFormat> getCursorFormats() = 0;
|
||||||
virtual bool createOutput(const std::string& name = "") = 0; // "" means auto
|
virtual bool createOutput(const std::string& name = "") = 0; // "" means auto
|
||||||
virtual Hyprutils::Memory::CSharedPointer<IAllocator> preferredAllocator() = 0;
|
virtual Hyprutils::Memory::CSharedPointer<IAllocator> preferredAllocator() = 0;
|
||||||
virtual std::vector<SDRMFormat> getRenderableFormats(); // empty = use getRenderFormats
|
virtual Hyprutils::Memory::CSharedPointer<IAllocator> fallbackAllocator() {
|
||||||
|
return nullptr;
|
||||||
|
};
|
||||||
|
virtual std::vector<SDRMFormat> getRenderableFormats(); // empty = use getRenderFormats
|
||||||
};
|
};
|
||||||
|
|
||||||
class CBackend {
|
class CBackend {
|
||||||
|
|
@ -128,6 +131,7 @@ namespace Aquamarine {
|
||||||
} events;
|
} events;
|
||||||
|
|
||||||
Hyprutils::Memory::CSharedPointer<IAllocator> primaryAllocator;
|
Hyprutils::Memory::CSharedPointer<IAllocator> primaryAllocator;
|
||||||
|
Hyprutils::Memory::CSharedPointer<IAllocator> fallbackAllocator;
|
||||||
bool ready = false;
|
bool ready = false;
|
||||||
Hyprutils::Memory::CSharedPointer<CSession> session;
|
Hyprutils::Memory::CSharedPointer<CSession> session;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -342,6 +342,7 @@ namespace Aquamarine {
|
||||||
virtual std::vector<SDRMFormat> getCursorFormats();
|
virtual std::vector<SDRMFormat> getCursorFormats();
|
||||||
virtual bool createOutput(const std::string& name = "");
|
virtual bool createOutput(const std::string& name = "");
|
||||||
virtual Hyprutils::Memory::CSharedPointer<IAllocator> preferredAllocator();
|
virtual Hyprutils::Memory::CSharedPointer<IAllocator> preferredAllocator();
|
||||||
|
virtual Hyprutils::Memory::CSharedPointer<IAllocator> fallbackAllocator();
|
||||||
virtual std::vector<SDRMFormat> getRenderableFormats();
|
virtual std::vector<SDRMFormat> getRenderableFormats();
|
||||||
|
|
||||||
Hyprutils::Memory::CWeakPointer<CDRMBackend> self;
|
Hyprutils::Memory::CWeakPointer<CDRMBackend> self;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,190 @@
|
||||||
|
#include <aquamarine/allocator/Dumb.hpp>
|
||||||
|
#include <aquamarine/backend/Backend.hpp>
|
||||||
|
#include <aquamarine/allocator/Swapchain.hpp>
|
||||||
|
#include "FormatUtils.hpp"
|
||||||
|
#include "Shared.hpp"
|
||||||
|
#include "aquamarine/buffer/Buffer.hpp"
|
||||||
|
#include <cstring>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <xf86drm.h>
|
||||||
|
#include <gbm.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
using namespace Aquamarine;
|
||||||
|
using namespace Hyprutils::Memory;
|
||||||
|
#define SP CSharedPointer
|
||||||
|
|
||||||
|
Aquamarine::CDumbBuffer::CDumbBuffer(const SAllocatorBufferParams& params, Hyprutils::Memory::CWeakPointer<CDumbAllocator> allocator_,
|
||||||
|
Hyprutils::Memory::CSharedPointer<CSwapchain> swapchain) : allocator(allocator_) {
|
||||||
|
if (!allocator)
|
||||||
|
return;
|
||||||
|
|
||||||
|
drm_mode_create_dumb createArgs{
|
||||||
|
.height = uint32_t(params.size.x),
|
||||||
|
.width = uint32_t(params.size.y),
|
||||||
|
.bpp = 32,
|
||||||
|
};
|
||||||
|
|
||||||
|
TRACE(allocator->backend->log(AQ_LOG_TRACE, std::format("DUMB: Allocating a dumb buffer: size {}, format {}", params.size, fourccToName(params.format))));
|
||||||
|
if (drmIoctl(gbm_device_get_fd(allocator->gbmDevice), DRM_IOCTL_MODE_CREATE_DUMB, &createArgs) != 0) {
|
||||||
|
allocator->backend->log(AQ_LOG_ERROR, std::format("DUMB: DRM_IOCTL_MODE_CREATE_DUMB failed {}", strerror(errno)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int primeFd;
|
||||||
|
if (drmPrimeHandleToFD(gbm_device_get_fd(allocator->gbmDevice), createArgs.handle, DRM_CLOEXEC, &primeFd) != 0) {
|
||||||
|
allocator->backend->log(AQ_LOG_ERROR, std::format("DUMB: drmPrimeHandleToFD() failed {}", strerror(errno)));
|
||||||
|
drm_mode_destroy_dumb destroyArgs{
|
||||||
|
.handle = createArgs.handle,
|
||||||
|
};
|
||||||
|
drmIoctl(gbm_device_get_fd(allocator->gbmDevice), DRM_IOCTL_MODE_DESTROY_DUMB, &destroyArgs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
drmFd = gbm_device_get_fd(allocator->gbmDevice);
|
||||||
|
handle = createArgs.handle;
|
||||||
|
length = createArgs.pitch * params.size.y;
|
||||||
|
|
||||||
|
attrs.size = params.size;
|
||||||
|
attrs.format = DRM_FORMAT_ARGB8888;
|
||||||
|
attrs.offset = 0;
|
||||||
|
attrs.fd = primeFd;
|
||||||
|
attrs.stride = createArgs.pitch;
|
||||||
|
|
||||||
|
attrs.success = true;
|
||||||
|
|
||||||
|
allocator->backend->log(AQ_LOG_DEBUG, std::format("DUMB: Allocated a new dumb buffer with size {} and format {}", attrs.size, fourccToName(attrs.format)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Aquamarine::CDumbBuffer::~CDumbBuffer() {
|
||||||
|
events.destroy.emit();
|
||||||
|
|
||||||
|
endDataPtr();
|
||||||
|
|
||||||
|
if (handle) {
|
||||||
|
drm_mode_destroy_dumb destroyArgs{
|
||||||
|
.handle = handle,
|
||||||
|
};
|
||||||
|
drmIoctl(drmFd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroyArgs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
eBufferCapability Aquamarine::CDumbBuffer::caps() {
|
||||||
|
return BUFFER_CAPABILITY_DATAPTR;
|
||||||
|
}
|
||||||
|
|
||||||
|
eBufferType Aquamarine::CDumbBuffer::type() {
|
||||||
|
return Aquamarine::eBufferType::BUFFER_TYPE_DMABUF_DUMB;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Aquamarine::CDumbBuffer::update(const Hyprutils::Math::CRegion& damage) {
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Aquamarine::CDumbBuffer::isSynchronous() {
|
||||||
|
return false; // FIXME is it correct?
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Aquamarine::CDumbBuffer::good() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
SSHMAttrs Aquamarine::CDumbBuffer::shm() {
|
||||||
|
return attrs;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::tuple<uint8_t*, uint32_t, size_t> Aquamarine::CDumbBuffer::beginDataPtr(uint32_t flags) {
|
||||||
|
if (!data) {
|
||||||
|
drm_mode_map_dumb mapArgs{
|
||||||
|
.handle = handle,
|
||||||
|
};
|
||||||
|
if (drmIoctl(drmFd, DRM_IOCTL_MODE_MAP_DUMB, &mapArgs) != 0) {
|
||||||
|
allocator->backend->log(AQ_LOG_ERROR, std::format("DUMB: DRM_IOCTL_MODE_MAP_DUMB failed {}", strerror(errno)));
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
void* address = mmap(nullptr, length, PROT_READ | PROT_WRITE, MAP_SHARED, drmFd, mapArgs.offset);
|
||||||
|
if (address == MAP_FAILED) {
|
||||||
|
allocator->backend->log(AQ_LOG_ERROR, std::format("DUMB: mmap failed {}", strerror(errno)));
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
data = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: assumes a 32-bit pixel format
|
||||||
|
return {(uint8_t*)data, attrs.format, attrs.stride};
|
||||||
|
}
|
||||||
|
|
||||||
|
void Aquamarine::CDumbBuffer::endDataPtr() {
|
||||||
|
if (data) {
|
||||||
|
munmap(data, length);
|
||||||
|
data = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CDumbAllocator::~CDumbAllocator() {
|
||||||
|
if (gbmDevice)
|
||||||
|
gbm_device_destroy(gbmDevice);
|
||||||
|
}
|
||||||
|
|
||||||
|
SP<CDumbAllocator> Aquamarine::CDumbAllocator::create(int drmfd_, Hyprutils::Memory::CWeakPointer<CBackend> backend_) {
|
||||||
|
uint64_t capabilities = 0;
|
||||||
|
if (drmGetCap(drmfd_, DRM_CAP_PRIME, &capabilities) || !(capabilities & DRM_PRIME_CAP_EXPORT)) {
|
||||||
|
backend_->log(AQ_LOG_ERROR, "Cannot create a Dumb Allocator: PRIME export is not supported by the gpu.");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto allocator = SP<CDumbAllocator>(new CDumbAllocator(drmfd_, backend_));
|
||||||
|
|
||||||
|
if (!allocator->gbmDevice) {
|
||||||
|
backend_->log(AQ_LOG_ERROR, "Cannot create a Dumb Allocator: gbm failed to create a device.");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
backend_->log(AQ_LOG_DEBUG, std::format("Created a Dumb Allocator with drm fd {}", drmfd_));
|
||||||
|
|
||||||
|
allocator->self = allocator;
|
||||||
|
|
||||||
|
return allocator;
|
||||||
|
}
|
||||||
|
|
||||||
|
Aquamarine::CDumbAllocator::CDumbAllocator(int fd_, Hyprutils::Memory::CWeakPointer<CBackend> backend_) : fd(fd_), backend(backend_) {
|
||||||
|
gbmDevice = gbm_create_device(fd_);
|
||||||
|
if (!gbmDevice) {
|
||||||
|
backend->log(AQ_LOG_ERROR, std::format("Couldn't open a GBM device at fd {}", fd_));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gbmDeviceBackendName = gbm_device_get_backend_name(gbmDevice);
|
||||||
|
auto drmName_ = drmGetDeviceNameFromFd2(fd_);
|
||||||
|
drmName = drmName_;
|
||||||
|
free(drmName_);
|
||||||
|
}
|
||||||
|
|
||||||
|
SP<IBuffer> Aquamarine::CDumbAllocator::acquire(const SAllocatorBufferParams& params, Hyprutils::Memory::CSharedPointer<CSwapchain> swapchain_) {
|
||||||
|
if (params.size.x < 1 || params.size.y < 1) {
|
||||||
|
backend->log(AQ_LOG_ERROR, std::format("Couldn't allocate a dumb buffer with invalid size {}", params.size));
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto newBuffer = SP<CDumbBuffer>(new CDumbBuffer(params, self, swapchain_));
|
||||||
|
|
||||||
|
if (!newBuffer->good()) {
|
||||||
|
backend->log(AQ_LOG_ERROR, std::format("Couldn't allocate a dumb buffer with size {} and format {}", params.size, fourccToName(params.format)));
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffers.emplace_back(newBuffer);
|
||||||
|
std::erase_if(buffers, [](const auto& b) { return b.expired(); });
|
||||||
|
return newBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
Hyprutils::Memory::CSharedPointer<CBackend> Aquamarine::CDumbAllocator::getBackend() {
|
||||||
|
return backend.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Aquamarine::CDumbAllocator::drmFD() {
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
@ -3,9 +3,6 @@
|
||||||
#include <aquamarine/allocator/Swapchain.hpp>
|
#include <aquamarine/allocator/Swapchain.hpp>
|
||||||
#include "FormatUtils.hpp"
|
#include "FormatUtils.hpp"
|
||||||
#include "Shared.hpp"
|
#include "Shared.hpp"
|
||||||
#include <cstring>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <xf86drm.h>
|
#include <xf86drm.h>
|
||||||
#include <gbm.h>
|
#include <gbm.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
@ -56,8 +53,7 @@ static SDRMFormat guessFormatFrom(std::vector<SDRMFormat> formats, bool cursor)
|
||||||
}
|
}
|
||||||
|
|
||||||
Aquamarine::CGBMBuffer::CGBMBuffer(const SAllocatorBufferParams& params, Hyprutils::Memory::CWeakPointer<CGBMAllocator> allocator_,
|
Aquamarine::CGBMBuffer::CGBMBuffer(const SAllocatorBufferParams& params, Hyprutils::Memory::CWeakPointer<CGBMAllocator> allocator_,
|
||||||
Hyprutils::Memory::CSharedPointer<CSwapchain> swapchain) :
|
Hyprutils::Memory::CSharedPointer<CSwapchain> swapchain) : allocator(allocator_) {
|
||||||
allocator(allocator_) {
|
|
||||||
if (!allocator)
|
if (!allocator)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -145,9 +141,9 @@ Aquamarine::CGBMBuffer::CGBMBuffer(const SAllocatorBufferParams& params, Hypruti
|
||||||
bo = gbm_bo_create_with_modifiers2(allocator->gbmDevice, attrs.size.x, attrs.size.y, attrs.format, explicitModifiers.data(), explicitModifiers.size(), flags);
|
bo = gbm_bo_create_with_modifiers2(allocator->gbmDevice, attrs.size.x, attrs.size.y, attrs.format, explicitModifiers.data(), explicitModifiers.size(), flags);
|
||||||
|
|
||||||
if (!bo && CURSOR) {
|
if (!bo && CURSOR) {
|
||||||
// use dumb buffers for cursors
|
// allow non-renderable cursor buffer for nvidia
|
||||||
allocator->backend->log(AQ_LOG_ERROR, "GBM: Allocating with modifiers and flags failed for cursor plane, falling back to dumb");
|
allocator->backend->log(AQ_LOG_ERROR, "GBM: Allocating with modifiers and flags failed, falling back to modifiers without flags");
|
||||||
return;
|
bo = gbm_bo_create_with_modifiers(allocator->gbmDevice, attrs.size.x, attrs.size.y, attrs.format, explicitModifiers.data(), explicitModifiers.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bo) {
|
if (!bo) {
|
||||||
|
|
@ -243,118 +239,6 @@ void Aquamarine::CGBMBuffer::endDataPtr() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Aquamarine::CGBMDumbBuffer::CGBMDumbBuffer(const SAllocatorBufferParams& params, Hyprutils::Memory::CWeakPointer<CGBMAllocator> allocator_,
|
|
||||||
Hyprutils::Memory::CSharedPointer<CSwapchain> swapchain) :
|
|
||||||
allocator(allocator_) {
|
|
||||||
if (!allocator)
|
|
||||||
return;
|
|
||||||
|
|
||||||
drm_mode_create_dumb createArgs{
|
|
||||||
.height = uint32_t(params.size.x),
|
|
||||||
.width = uint32_t(params.size.y),
|
|
||||||
.bpp = 32,
|
|
||||||
};
|
|
||||||
|
|
||||||
TRACE(allocator->backend->log(AQ_LOG_TRACE, std::format("GBM: Allocating a dumb buffer: size {}, format {}", params.size, fourccToName(params.format))));
|
|
||||||
if (drmIoctl(gbm_device_get_fd(allocator->gbmDevice), DRM_IOCTL_MODE_CREATE_DUMB, &createArgs) != 0) {
|
|
||||||
allocator->backend->log(AQ_LOG_ERROR, std::format("GBM: DRM_IOCTL_MODE_CREATE_DUMB failed {}", strerror(errno)));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int primeFd;
|
|
||||||
if (drmPrimeHandleToFD(gbm_device_get_fd(allocator->gbmDevice), createArgs.handle, DRM_CLOEXEC, &primeFd) != 0) {
|
|
||||||
allocator->backend->log(AQ_LOG_ERROR, std::format("GBM: drmPrimeHandleToFD() failed {}", strerror(errno)));
|
|
||||||
drm_mode_destroy_dumb destroyArgs{
|
|
||||||
.handle = createArgs.handle,
|
|
||||||
};
|
|
||||||
drmIoctl(gbm_device_get_fd(allocator->gbmDevice), DRM_IOCTL_MODE_DESTROY_DUMB, &destroyArgs);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_drmFd = gbm_device_get_fd(allocator->gbmDevice);
|
|
||||||
m_handle = createArgs.handle;
|
|
||||||
m_size = createArgs.pitch * params.size.y;
|
|
||||||
|
|
||||||
attrs.planes = 1;
|
|
||||||
attrs.size = params.size;
|
|
||||||
attrs.format = DRM_FORMAT_ARGB8888;
|
|
||||||
attrs.modifier = DRM_FORMAT_MOD_LINEAR;
|
|
||||||
attrs.offsets = {0, 0, 0, 0};
|
|
||||||
attrs.fds = {primeFd, 0, 0, 0};
|
|
||||||
attrs.strides = {createArgs.pitch, 0, 0, 0};
|
|
||||||
|
|
||||||
attrs.success = true;
|
|
||||||
|
|
||||||
allocator->backend->log(AQ_LOG_DEBUG, std::format("GBM: Allocated a new dumb buffer with size {} and format {}", attrs.size, fourccToName(attrs.format)));
|
|
||||||
}
|
|
||||||
|
|
||||||
Aquamarine::CGBMDumbBuffer::~CGBMDumbBuffer() {
|
|
||||||
events.destroy.emit();
|
|
||||||
|
|
||||||
endDataPtr();
|
|
||||||
|
|
||||||
if (m_handle) {
|
|
||||||
drm_mode_destroy_dumb destroyArgs{
|
|
||||||
.handle = m_handle,
|
|
||||||
};
|
|
||||||
drmIoctl(m_drmFd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroyArgs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
eBufferCapability Aquamarine::CGBMDumbBuffer::caps() {
|
|
||||||
return BUFFER_CAPABILITY_DATAPTR;
|
|
||||||
}
|
|
||||||
|
|
||||||
eBufferType Aquamarine::CGBMDumbBuffer::type() {
|
|
||||||
return Aquamarine::eBufferType::BUFFER_TYPE_DMABUF_DUMB;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Aquamarine::CGBMDumbBuffer::update(const Hyprutils::Math::CRegion& damage) {
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Aquamarine::CGBMDumbBuffer::isSynchronous() {
|
|
||||||
return false; // FIXME is it correct?
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Aquamarine::CGBMDumbBuffer::good() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
SDMABUFAttrs Aquamarine::CGBMDumbBuffer::dmabuf() {
|
|
||||||
return attrs;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::tuple<uint8_t*, uint32_t, size_t> Aquamarine::CGBMDumbBuffer::beginDataPtr(uint32_t flags) {
|
|
||||||
if (!m_data) {
|
|
||||||
drm_mode_map_dumb mapArgs{
|
|
||||||
.handle = m_handle,
|
|
||||||
};
|
|
||||||
if (drmIoctl(m_drmFd, DRM_IOCTL_MODE_MAP_DUMB, &mapArgs) != 0) {
|
|
||||||
allocator->backend->log(AQ_LOG_ERROR, std::format("GBM: DRM_IOCTL_MODE_MAP_DUMB failed {}", strerror(errno)));
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
void* address = mmap(nullptr, m_size, PROT_READ | PROT_WRITE, MAP_SHARED, m_drmFd, mapArgs.offset);
|
|
||||||
if (address == MAP_FAILED) {
|
|
||||||
allocator->backend->log(AQ_LOG_ERROR, std::format("GBM: mmap failed {}", strerror(errno)));
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
m_data = address;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: assumes a 32-bit pixel format
|
|
||||||
return {(uint8_t*)m_data, attrs.format, attrs.strides[0]};
|
|
||||||
}
|
|
||||||
|
|
||||||
void Aquamarine::CGBMDumbBuffer::endDataPtr() {
|
|
||||||
if (m_data) {
|
|
||||||
munmap(m_data, m_size);
|
|
||||||
m_data = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CGBMAllocator::~CGBMAllocator() {
|
CGBMAllocator::~CGBMAllocator() {
|
||||||
if (gbmDevice)
|
if (gbmDevice)
|
||||||
gbm_device_destroy(gbmDevice);
|
gbm_device_destroy(gbmDevice);
|
||||||
|
|
@ -400,17 +284,11 @@ SP<IBuffer> Aquamarine::CGBMAllocator::acquire(const SAllocatorBufferParams& par
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
SP<IBuffer> newBuffer = SP<CGBMBuffer>(new CGBMBuffer(params, self, swapchain_));
|
auto newBuffer = SP<CGBMBuffer>(new CGBMBuffer(params, self, swapchain_));
|
||||||
|
|
||||||
if (!newBuffer->good()) {
|
if (!newBuffer->good()) {
|
||||||
backend->log(AQ_LOG_ERROR, std::format("Couldn't allocate a gbm buffer with size {} and format {}", params.size, fourccToName(params.format)));
|
backend->log(AQ_LOG_ERROR, std::format("Couldn't allocate a gbm buffer with size {} and format {}", params.size, fourccToName(params.format)));
|
||||||
|
return nullptr;
|
||||||
newBuffer = SP<CGBMDumbBuffer>(new CGBMDumbBuffer(params, self, swapchain_));
|
|
||||||
|
|
||||||
if (!newBuffer->good()) {
|
|
||||||
backend->log(AQ_LOG_ERROR, std::format("Couldn't allocate a dumb gbm buffer with size {} and format {}", params.size, fourccToName(params.format)));
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buffers.emplace_back(newBuffer);
|
buffers.emplace_back(newBuffer);
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
#include <aquamarine/backend/Headless.hpp>
|
#include <aquamarine/backend/Headless.hpp>
|
||||||
#include <aquamarine/backend/DRM.hpp>
|
#include <aquamarine/backend/DRM.hpp>
|
||||||
#include <aquamarine/allocator/GBM.hpp>
|
#include <aquamarine/allocator/GBM.hpp>
|
||||||
|
#include <aquamarine/allocator/Dumb.hpp>
|
||||||
#include <sys/poll.h>
|
#include <sys/poll.h>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
@ -153,7 +154,8 @@ bool Aquamarine::CBackend::start() {
|
||||||
log(AQ_LOG_CRITICAL, "Failed to create an allocator (reopenDRMNode failed)");
|
log(AQ_LOG_CRITICAL, "Failed to create an allocator (reopenDRMNode failed)");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
primaryAllocator = CGBMAllocator::create(fd, self);
|
primaryAllocator = CGBMAllocator::create(fd, self);
|
||||||
|
fallbackAllocator = CDumbAllocator::create(fd, self);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -932,6 +932,10 @@ SP<IAllocator> Aquamarine::CDRMBackend::preferredAllocator() {
|
||||||
return backend->primaryAllocator;
|
return backend->primaryAllocator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SP<IAllocator> Aquamarine::CDRMBackend::fallbackAllocator() {
|
||||||
|
return backend->fallbackAllocator;
|
||||||
|
}
|
||||||
|
|
||||||
bool Aquamarine::SDRMPlane::init(drmModePlane* plane) {
|
bool Aquamarine::SDRMPlane::init(drmModePlane* plane) {
|
||||||
id = plane->plane_id;
|
id = plane->plane_id;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue