summaryrefslogtreecommitdiff
path: root/src/protocols/SinglePixel.cpp
diff options
context:
space:
mode:
authorVaxry <vaxry@vaxry.net>2024-09-30 00:57:51 +0100
committerVaxry <vaxry@vaxry.net>2024-09-30 00:58:16 +0100
commit488efab63654a643d76df4997cd932d6fddd8faf (patch)
tree4e330456e26e6ba5e208424f292fc1d03e89f10b /src/protocols/SinglePixel.cpp
parent6649255d54f45a7e2fedd9b4be85fe5d11229c04 (diff)
single-pixel-buffer: new protocol impl
fixes #6624
Diffstat (limited to 'src/protocols/SinglePixel.cpp')
-rw-r--r--src/protocols/SinglePixel.cpp125
1 files changed, 125 insertions, 0 deletions
diff --git a/src/protocols/SinglePixel.cpp b/src/protocols/SinglePixel.cpp
new file mode 100644
index 00000000..7dd3748f
--- /dev/null
+++ b/src/protocols/SinglePixel.cpp
@@ -0,0 +1,125 @@
+#include "SinglePixel.hpp"
+#include <limits>
+
+CSinglePixelBuffer::CSinglePixelBuffer(uint32_t id, wl_client* client, CColor col_) {
+ LOGM(LOG, "New single-pixel buffer with color 0x{:x}", col_.getAsHex());
+
+ color = col_.getAsHex();
+
+ g_pHyprRenderer->makeEGLCurrent();
+
+ opaque = col_.a >= 1.F;
+
+ texture = makeShared<CTexture>(DRM_FORMAT_ARGB8888, (uint8_t*)&color, 4, Vector2D{1, 1});
+
+ resource = CWLBufferResource::create(makeShared<CWlBuffer>(client, 1, id));
+
+ success = texture->m_iTexID;
+
+ if (!success)
+ Debug::log(ERR, "Failed creating a single pixel texture: null texture id");
+}
+
+CSinglePixelBuffer::~CSinglePixelBuffer() {
+ ;
+}
+
+Aquamarine::eBufferCapability CSinglePixelBuffer::caps() {
+ return Aquamarine::eBufferCapability::BUFFER_CAPABILITY_DATAPTR;
+}
+
+Aquamarine::eBufferType CSinglePixelBuffer::type() {
+ return Aquamarine::eBufferType::BUFFER_TYPE_SHM;
+}
+
+bool CSinglePixelBuffer::isSynchronous() {
+ return true;
+}
+
+void CSinglePixelBuffer::update(const CRegion& damage) {
+ ;
+}
+
+Aquamarine::SDMABUFAttrs CSinglePixelBuffer::dmabuf() {
+ return {.success = false};
+}
+
+std::tuple<uint8_t*, uint32_t, size_t> CSinglePixelBuffer::beginDataPtr(uint32_t flags) {
+ return {(uint8_t*)&color, DRM_FORMAT_ARGB8888, 4};
+}
+
+void CSinglePixelBuffer::endDataPtr() {
+ ;
+}
+
+bool CSinglePixelBuffer::good() {
+ return resource->good();
+}
+
+CSinglePixelBufferResource::CSinglePixelBufferResource(uint32_t id, wl_client* client, CColor color) {
+ buffer = makeShared<CSinglePixelBuffer>(id, client, color);
+
+ if (!buffer->good())
+ return;
+
+ buffer->resource->buffer = buffer;
+
+ listeners.bufferResourceDestroy = buffer->events.destroy.registerListener([this](std::any d) {
+ listeners.bufferResourceDestroy.reset();
+ PROTO::singlePixel->destroyResource(this);
+ });
+}
+
+CSinglePixelBufferResource::~CSinglePixelBufferResource() {
+ ;
+}
+
+bool CSinglePixelBufferResource::good() {
+ return buffer->good();
+}
+
+CSinglePixelBufferManagerResource::CSinglePixelBufferManagerResource(SP<CWpSinglePixelBufferManagerV1> resource_) : resource(resource_) {
+ if (!good())
+ return;
+
+ resource->setDestroy([this](CWpSinglePixelBufferManagerV1* r) { PROTO::singlePixel->destroyResource(this); });
+ resource->setOnDestroy([this](CWpSinglePixelBufferManagerV1* r) { PROTO::singlePixel->destroyResource(this); });
+
+ resource->setCreateU32RgbaBuffer([this](CWpSinglePixelBufferManagerV1* res, uint32_t id, uint32_t r, uint32_t g, uint32_t b, uint32_t a) {
+ CColor color{r / (float)std::numeric_limits<uint32_t>::max(), g / (float)std::numeric_limits<uint32_t>::max(), b / (float)std::numeric_limits<uint32_t>::max(),
+ a / (float)std::numeric_limits<uint32_t>::max()};
+ const auto RESOURCE = PROTO::singlePixel->m_vBuffers.emplace_back(makeShared<CSinglePixelBufferResource>(id, resource->client(), color));
+
+ if (!RESOURCE->good()) {
+ res->noMemory();
+ PROTO::singlePixel->m_vBuffers.pop_back();
+ return;
+ }
+ });
+}
+
+bool CSinglePixelBufferManagerResource::good() {
+ return resource->resource();
+}
+
+CSinglePixelProtocol::CSinglePixelProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
+ ;
+}
+
+void CSinglePixelProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
+ const auto RESOURCE = m_vManagers.emplace_back(makeShared<CSinglePixelBufferManagerResource>(makeShared<CWpSinglePixelBufferManagerV1>(client, ver, id)));
+
+ if (!RESOURCE->good()) {
+ wl_client_post_no_memory(client);
+ m_vManagers.pop_back();
+ return;
+ }
+}
+
+void CSinglePixelProtocol::destroyResource(CSinglePixelBufferManagerResource* res) {
+ std::erase_if(m_vManagers, [&](const auto& other) { return other.get() == res; });
+}
+
+void CSinglePixelProtocol::destroyResource(CSinglePixelBufferResource* surf) {
+ std::erase_if(m_vBuffers, [&](const auto& other) { return other.get() == surf; });
+}