Core: Move to aquamarine (#6608)
Moves Hyprland from wlroots to aquamarine for the backend. --------- Signed-off-by: Vaxry <vaxry@vaxry.net> Co-authored-by: Mihai Fufezan <mihai@fufexan.net> Co-authored-by: Jan Beich <jbeich@FreeBSD.org> Co-authored-by: vaxerski <vaxerski@users.noreply.github.com> Co-authored-by: UjinT34 <41110182+UjinT34@users.noreply.github.com> Co-authored-by: Tom Englund <tomenglund26@gmail.com> Co-authored-by: Ikalco <73481042+ikalco@users.noreply.github.com> Co-authored-by: diniamo <diniamo53@gmail.com>
This commit is contained in:
parent
f642fb97df
commit
016da234d0
131 changed files with 4755 additions and 3460 deletions
|
|
@ -6,6 +6,9 @@
|
|||
#include "Subcompositor.hpp"
|
||||
#include "../Viewporter.hpp"
|
||||
#include "../../helpers/Monitor.hpp"
|
||||
#include "../PresentationTime.hpp"
|
||||
#include "../DRMSyncobj.hpp"
|
||||
#include "../../render/Renderer.hpp"
|
||||
|
||||
#define LOGM PROTO::compositor->protoLog
|
||||
|
||||
|
|
@ -102,58 +105,14 @@ CWLSurfaceResource::CWLSurfaceResource(SP<CWlSurface> resource_) : resource(reso
|
|||
pending.size = tfs / pending.scale;
|
||||
}
|
||||
|
||||
if (viewportResource)
|
||||
viewportResource->verify();
|
||||
|
||||
pending.damage.intersect(CBox{{}, pending.size});
|
||||
|
||||
auto previousBuffer = current.buffer;
|
||||
CRegion previousBufferDamage = accumulateCurrentBufferDamage();
|
||||
events.precommit.emit();
|
||||
if (pending.rejected)
|
||||
return;
|
||||
|
||||
current = pending;
|
||||
pending.damage.clear();
|
||||
pending.bufferDamage.clear();
|
||||
|
||||
if (current.buffer && !bufferReleased) {
|
||||
// without previous dolphin et al are weird vvv
|
||||
//CRegion surfaceDamage =
|
||||
// current.damage.copy().scale(current.scale).transform(current.transform, current.size.x, current.size.y).add(current.bufferDamage).add(previousBufferDamage);
|
||||
current.buffer->update(CBox{{}, {INT32_MAX, INT32_MAX}}); // FIXME: figure this out to not use this hack. QT apps are wonky without this.
|
||||
|
||||
// release the buffer if it's synchronous as update() has done everything thats needed
|
||||
// so we can let the app know we're done.
|
||||
if (current.buffer->isSynchronous()) {
|
||||
current.buffer->sendRelease();
|
||||
bufferReleased = true;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: we should _accumulate_ and not replace above if sync
|
||||
if (role->role() == SURFACE_ROLE_SUBSURFACE) {
|
||||
auto subsurface = (CWLSubsurfaceResource*)role.get();
|
||||
if (subsurface->sync)
|
||||
return;
|
||||
|
||||
events.commit.emit();
|
||||
} else {
|
||||
// send commit to all synced surfaces in this tree.
|
||||
breadthfirst(
|
||||
[](SP<CWLSurfaceResource> surf, const Vector2D& offset, void* data) {
|
||||
if (surf->role->role() == SURFACE_ROLE_SUBSURFACE) {
|
||||
auto subsurface = (CWLSubsurfaceResource*)surf->role.get();
|
||||
if (!subsurface->sync)
|
||||
return;
|
||||
}
|
||||
surf->events.commit.emit();
|
||||
},
|
||||
nullptr);
|
||||
}
|
||||
|
||||
// for async buffers, we can only release the buffer once we are unrefing it from current.
|
||||
if (previousBuffer && !previousBuffer->isSynchronous() && !bufferReleased) {
|
||||
previousBuffer->sendRelease();
|
||||
bufferReleased = true;
|
||||
}
|
||||
if (stateLocks <= 0)
|
||||
commitPendingState();
|
||||
});
|
||||
|
||||
resource->setDamage([this](CWlSurface* r, int32_t x, int32_t y, int32_t w, int32_t h) { pending.damage.add(CBox{x, y, w, h}); });
|
||||
|
|
@ -426,7 +385,97 @@ CRegion CWLSurfaceResource::accumulateCurrentBufferDamage() {
|
|||
|
||||
Vector2D trc = current.transform % 2 == 1 ? Vector2D{current.buffer->size.y, current.buffer->size.x} : current.buffer->size;
|
||||
|
||||
return surfaceDamage.scale(current.scale).transform(wlTransformToHyprutils(wlr_output_transform_invert(current.transform)), trc.x, trc.y).add(current.bufferDamage);
|
||||
return surfaceDamage.scale(current.scale).transform(wlTransformToHyprutils(invertTransform(current.transform)), trc.x, trc.y).add(current.bufferDamage);
|
||||
}
|
||||
|
||||
void CWLSurfaceResource::lockPendingState() {
|
||||
stateLocks++;
|
||||
}
|
||||
|
||||
void CWLSurfaceResource::unlockPendingState() {
|
||||
stateLocks--;
|
||||
if (stateLocks <= 0)
|
||||
commitPendingState();
|
||||
}
|
||||
|
||||
void CWLSurfaceResource::commitPendingState() {
|
||||
auto previousBuffer = current.buffer;
|
||||
CRegion previousBufferDamage = accumulateCurrentBufferDamage();
|
||||
|
||||
current = pending;
|
||||
pending.damage.clear();
|
||||
pending.bufferDamage.clear();
|
||||
|
||||
if (current.buffer && !bufferReleased) {
|
||||
// without previous dolphin et al are weird vvv
|
||||
//CRegion surfaceDamage =
|
||||
// current.damage.copy().scale(current.scale).transform(current.transform, current.size.x, current.size.y).add(current.bufferDamage).add(previousBufferDamage);
|
||||
current.buffer->update(CBox{{}, {INT32_MAX, INT32_MAX}}); // FIXME: figure this out to not use this hack. QT apps are wonky without this.
|
||||
|
||||
// release the buffer if it's synchronous as update() has done everything thats needed
|
||||
// so we can let the app know we're done.
|
||||
if (current.buffer->isSynchronous()) {
|
||||
current.buffer->sendReleaseWithSurface(self.lock());
|
||||
bufferReleased = true;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: we should _accumulate_ and not replace above if sync
|
||||
if (role->role() == SURFACE_ROLE_SUBSURFACE) {
|
||||
auto subsurface = (CWLSubsurfaceResource*)role.get();
|
||||
if (subsurface->sync)
|
||||
return;
|
||||
|
||||
events.commit.emit();
|
||||
} else {
|
||||
// send commit to all synced surfaces in this tree.
|
||||
breadthfirst(
|
||||
[](SP<CWLSurfaceResource> surf, const Vector2D& offset, void* data) {
|
||||
if (surf->role->role() == SURFACE_ROLE_SUBSURFACE) {
|
||||
auto subsurface = (CWLSubsurfaceResource*)surf->role.get();
|
||||
if (!subsurface->sync)
|
||||
return;
|
||||
}
|
||||
surf->events.commit.emit();
|
||||
},
|
||||
nullptr);
|
||||
}
|
||||
|
||||
// for async buffers, we can only release the buffer once we are unrefing it from current.
|
||||
if (previousBuffer && !previousBuffer->isSynchronous() && !bufferReleased) {
|
||||
if (previousBuffer->lockedByBackend) {
|
||||
previousBuffer->hlEvents.backendRelease = previousBuffer->events.backendRelease.registerListener([this, previousBuffer](std::any data) {
|
||||
if (!self.expired()) // could be dead in the dtor
|
||||
previousBuffer->sendReleaseWithSurface(self.lock());
|
||||
else
|
||||
previousBuffer->sendRelease();
|
||||
previousBuffer->hlEvents.backendRelease.reset();
|
||||
bufferReleased = true;
|
||||
});
|
||||
} else
|
||||
previousBuffer->sendReleaseWithSurface(self.lock());
|
||||
|
||||
bufferReleased = true;
|
||||
}
|
||||
}
|
||||
|
||||
void CWLSurfaceResource::presentFeedback(timespec* when, CMonitor* pMonitor, bool needsExplicitSync) {
|
||||
frame(when);
|
||||
auto FEEDBACK = makeShared<CQueuedPresentationData>(self.lock());
|
||||
FEEDBACK->attachMonitor(pMonitor);
|
||||
FEEDBACK->discarded();
|
||||
PROTO::presentation->queueData(FEEDBACK);
|
||||
|
||||
if (!pMonitor || !pMonitor->outTimeline || !syncobj || !needsExplicitSync)
|
||||
return;
|
||||
|
||||
// attach explicit sync
|
||||
g_pHyprRenderer->explicitPresented.emplace_back(self.lock());
|
||||
|
||||
if (syncobj->acquirePoint > pMonitor->lastWaitPoint) {
|
||||
Debug::log(TRACE, "presentFeedback lastWaitPoint {} -> {}", pMonitor->lastWaitPoint, syncobj->acquirePoint);
|
||||
pMonitor->lastWaitPoint = syncobj->acquirePoint;
|
||||
}
|
||||
}
|
||||
|
||||
CWLCompositorResource::CWLCompositorResource(SP<CWlCompositor> resource_) : resource(resource_) {
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ class CWLSurface;
|
|||
class CWLSurfaceResource;
|
||||
class CWLSubsurfaceResource;
|
||||
class CViewportResource;
|
||||
class CDRMSyncobjSurfaceResource;
|
||||
|
||||
class CWLCallbackResource {
|
||||
public:
|
||||
|
|
@ -74,6 +75,7 @@ class CWLSurfaceResource {
|
|||
Vector2D sourceSize();
|
||||
|
||||
struct {
|
||||
CSignal precommit;
|
||||
CSignal commit;
|
||||
CSignal map;
|
||||
CSignal unmap;
|
||||
|
|
@ -81,11 +83,11 @@ class CWLSurfaceResource {
|
|||
CSignal destroy;
|
||||
} events;
|
||||
|
||||
struct {
|
||||
struct SState {
|
||||
CRegion opaque, input = CBox{{}, {INT32_MAX, INT32_MAX}}, damage, bufferDamage = CBox{{}, {INT32_MAX, INT32_MAX}} /* initial damage */;
|
||||
wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
int scale = 1;
|
||||
SP<IWLBuffer> buffer;
|
||||
SP<IHLBuffer> buffer;
|
||||
SP<CTexture> texture;
|
||||
Vector2D offset;
|
||||
Vector2D size;
|
||||
|
|
@ -95,6 +97,7 @@ class CWLSurfaceResource {
|
|||
Vector2D destination;
|
||||
CBox source;
|
||||
} viewport;
|
||||
bool rejected = false;
|
||||
|
||||
//
|
||||
void reset() {
|
||||
|
|
@ -115,9 +118,13 @@ class CWLSurfaceResource {
|
|||
std::vector<WP<CWLSubsurfaceResource>> subsurfaces;
|
||||
WP<ISurfaceRole> role;
|
||||
WP<CViewportResource> viewportResource;
|
||||
WP<CDRMSyncobjSurfaceResource> syncobj; // may not be present
|
||||
|
||||
void breadthfirst(std::function<void(SP<CWLSurfaceResource>, const Vector2D&, void*)> fn, void* data);
|
||||
CRegion accumulateCurrentBufferDamage();
|
||||
void presentFeedback(timespec* when, CMonitor* pMonitor, bool needsExplicitSync = false);
|
||||
void lockPendingState();
|
||||
void unlockPendingState();
|
||||
|
||||
// returns a pair: found surface (null if not found) and surface local coords.
|
||||
// localCoords param is relative to 0,0 of this surface
|
||||
|
|
@ -130,7 +137,10 @@ class CWLSurfaceResource {
|
|||
// tracks whether we should release the buffer
|
||||
bool bufferReleased = false;
|
||||
|
||||
int stateLocks = 0;
|
||||
|
||||
void destroy();
|
||||
void commitPendingState();
|
||||
void bfHelper(std::vector<SP<CWLSurfaceResource>> nodes, std::function<void(SP<CWLSurfaceResource>, const Vector2D&, void*)> fn, void* data);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ CWLOutputResource::CWLOutputResource(SP<CWlOutput> resource_, SP<CMonitor> pMoni
|
|||
PROTO::outputs.at(monitor->szName)->destroyResource(this);
|
||||
});
|
||||
|
||||
resource->sendGeometry(0, 0, monitor->output->phys_width, monitor->output->phys_height, monitor->output->subpixel, monitor->output->make ? monitor->output->make : "null",
|
||||
monitor->output->model ? monitor->output->model : "null", monitor->transform);
|
||||
resource->sendGeometry(0, 0, monitor->output->physicalSize.x, monitor->output->physicalSize.y, (wl_output_subpixel)monitor->output->subpixel, monitor->output->make.c_str(),
|
||||
monitor->output->model.c_str(), monitor->transform);
|
||||
if (resource->version() >= 4) {
|
||||
resource->sendName(monitor->szName.c_str());
|
||||
resource->sendDescription(monitor->szDescription.c_str());
|
||||
|
|
@ -115,3 +115,9 @@ void CWLOutputProtocol::remove() {
|
|||
bool CWLOutputProtocol::isDefunct() {
|
||||
return defunct;
|
||||
}
|
||||
|
||||
void CWLOutputProtocol::sendDone() {
|
||||
for (auto& r : m_vOutputs) {
|
||||
r->resource->sendDone();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ class CWLOutputResource {
|
|||
private:
|
||||
SP<CWlOutput> resource;
|
||||
wl_client* pClient = nullptr;
|
||||
|
||||
friend class CWLOutputProtocol;
|
||||
};
|
||||
|
||||
class CWLOutputProtocol : public IWaylandProtocol {
|
||||
|
|
@ -35,6 +37,7 @@ class CWLOutputProtocol : public IWaylandProtocol {
|
|||
virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id);
|
||||
|
||||
SP<CWLOutputResource> outputResourceFrom(wl_client* client);
|
||||
void sendDone();
|
||||
|
||||
WP<CMonitor> monitor;
|
||||
|
||||
|
|
|
|||
|
|
@ -254,8 +254,8 @@ void CWLKeyboardResource::sendKeymap(SP<IKeyboard> keyboard) {
|
|||
int fd;
|
||||
uint32_t size;
|
||||
if (keyboard) {
|
||||
fd = keyboard->wlr()->keymap_fd;
|
||||
size = keyboard->wlr()->keymap_size;
|
||||
fd = keyboard->xkbKeymapFD;
|
||||
size = keyboard->xkbKeymapString.length() + 1;
|
||||
} else {
|
||||
fd = open("/dev/null", O_RDONLY | O_CLOEXEC);
|
||||
if (fd < 0) {
|
||||
|
|
|
|||
|
|
@ -41,20 +41,20 @@ CWLSHMBuffer::~CWLSHMBuffer() {
|
|||
;
|
||||
}
|
||||
|
||||
eBufferCapability CWLSHMBuffer::caps() {
|
||||
return BUFFER_CAPABILITY_DATAPTR;
|
||||
Aquamarine::eBufferCapability CWLSHMBuffer::caps() {
|
||||
return Aquamarine::eBufferCapability::BUFFER_CAPABILITY_DATAPTR;
|
||||
}
|
||||
|
||||
eBufferType CWLSHMBuffer::type() {
|
||||
return BUFFER_TYPE_SHM;
|
||||
Aquamarine::eBufferType CWLSHMBuffer::type() {
|
||||
return Aquamarine::eBufferType::BUFFER_TYPE_SHM;
|
||||
}
|
||||
|
||||
bool CWLSHMBuffer::isSynchronous() {
|
||||
return true;
|
||||
}
|
||||
|
||||
SSHMAttrs CWLSHMBuffer::shm() {
|
||||
SSHMAttrs attrs;
|
||||
Aquamarine::SSHMAttrs CWLSHMBuffer::shm() {
|
||||
Aquamarine::SSHMAttrs attrs;
|
||||
attrs.success = true;
|
||||
attrs.fd = pool->fd;
|
||||
attrs.format = FormatUtils::shmToDRM(fmt);
|
||||
|
|
@ -188,11 +188,18 @@ CWLSHMProtocol::CWLSHMProtocol(const wl_interface* iface, const int& ver, const
|
|||
|
||||
void CWLSHMProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
|
||||
if (shmFormats.empty()) {
|
||||
size_t len = 0;
|
||||
const uint32_t* formats = wlr_renderer_get_shm_texture_formats(g_pCompositor->m_sWLRRenderer, &len);
|
||||
shmFormats.push_back(WL_SHM_FORMAT_ARGB8888);
|
||||
shmFormats.push_back(WL_SHM_FORMAT_XRGB8888);
|
||||
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
shmFormats.push_back(FormatUtils::drmToShm(formats[i]));
|
||||
static const std::array<DRMFormat, 6> supportedShmFourccFormats = {
|
||||
DRM_FORMAT_XBGR8888, DRM_FORMAT_ABGR8888, DRM_FORMAT_XRGB2101010, DRM_FORMAT_ARGB2101010, DRM_FORMAT_XBGR2101010, DRM_FORMAT_ABGR2101010,
|
||||
};
|
||||
|
||||
for (auto& fmt : g_pHyprOpenGL->getDRMFormats()) {
|
||||
if (std::find(supportedShmFourccFormats.begin(), supportedShmFourccFormats.end(), fmt.drmFormat) == supportedShmFourccFormats.end())
|
||||
continue;
|
||||
|
||||
shmFormats.push_back(fmt.drmFormat);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,16 +29,16 @@ class CSHMPool {
|
|||
void resize(size_t size);
|
||||
};
|
||||
|
||||
class CWLSHMBuffer : public IWLBuffer {
|
||||
class CWLSHMBuffer : public IHLBuffer {
|
||||
public:
|
||||
CWLSHMBuffer(SP<CWLSHMPoolResource> pool, uint32_t id, int32_t offset, const Vector2D& size, int32_t stride, uint32_t fmt);
|
||||
virtual ~CWLSHMBuffer();
|
||||
|
||||
virtual eBufferCapability caps();
|
||||
virtual eBufferType type();
|
||||
virtual Aquamarine::eBufferCapability caps();
|
||||
virtual Aquamarine::eBufferType type();
|
||||
virtual void update(const CRegion& damage);
|
||||
virtual bool isSynchronous();
|
||||
virtual SSHMAttrs shm();
|
||||
virtual Aquamarine::SSHMAttrs shm();
|
||||
virtual std::tuple<uint8_t*, uint32_t, size_t> beginDataPtr(uint32_t flags);
|
||||
virtual void endDataPtr();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue