summaryrefslogtreecommitdiff
path: root/src/protocols/SinglePixel.cpp
blob: 9abde68ab0e0e61b060dea98714019f61a3245f8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include "SinglePixel.hpp"
#include "../desktop/LayerSurface.hpp"
#include <limits>
#include "render/Renderer.hpp"

CSinglePixelBuffer::CSinglePixelBuffer(uint32_t id, wl_client* client, CHyprColor col_) {
    LOGM(LOG, "New single-pixel buffer with color 0x{:x}", col_.getAsHex());

    m_color = col_.getAsHex();

    g_pHyprRenderer->makeEGLCurrent();

    m_opaque = col_.a >= 1.F;

    m_resource = CWLBufferResource::create(makeShared<CWlBuffer>(client, 1, id));

    size = {1, 1};
}

CSinglePixelBuffer::~CSinglePixelBuffer() {
    if (m_resource)
        m_resource->sendRelease();
}

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 {rc<uint8_t*>(&m_color), DRM_FORMAT_ARGB8888, 4};
}

void CSinglePixelBuffer::endDataPtr() {
    ;
}

SP<CTexture> CSinglePixelBuffer::createTexture() {
    auto tex = makeShared<CTexture>(DRM_FORMAT_ARGB8888, rc<uint8_t*>(&m_color), 4, Vector2D{1, 1});

    if (!tex->m_texID) {
        Debug::log(ERR, "Failed creating a single pixel texture: null texture id");
        return nullptr;
    }

    return tex;
}

bool CSinglePixelBuffer::good() {
    return m_resource->good();
}

CSinglePixelBufferResource::CSinglePixelBufferResource(uint32_t id, wl_client* client, CHyprColor color) {
    m_buffer = makeShared<CSinglePixelBuffer>(id, client, color);

    if UNLIKELY (!m_buffer->good())
        return;

    m_buffer->m_resource->m_buffer = m_buffer;

    m_listeners.bufferResourceDestroy = m_buffer->events.destroy.listen([this] {
        m_listeners.bufferResourceDestroy.reset();
        PROTO::singlePixel->destroyResource(this);
    });
}

bool CSinglePixelBufferResource::good() {
    return m_buffer->good();
}

CSinglePixelBufferManagerResource::CSinglePixelBufferManagerResource(UP<CWpSinglePixelBufferManagerV1>&& resource_) : m_resource(std::move(resource_)) {
    if UNLIKELY (!good())
        return;

    m_resource->setDestroy([this](CWpSinglePixelBufferManagerV1* r) { PROTO::singlePixel->destroyResource(this); });
    m_resource->setOnDestroy([this](CWpSinglePixelBufferManagerV1* r) { PROTO::singlePixel->destroyResource(this); });

    m_resource->setCreateU32RgbaBuffer([this](CWpSinglePixelBufferManagerV1* res, uint32_t id, uint32_t r, uint32_t g, uint32_t b, uint32_t a) {
        CHyprColor  color{r / sc<float>(std::numeric_limits<uint32_t>::max()), g / sc<float>(std::numeric_limits<uint32_t>::max()),
                         b / sc<float>(std::numeric_limits<uint32_t>::max()), a / sc<float>(std::numeric_limits<uint32_t>::max())};
        const auto& RESOURCE = PROTO::singlePixel->m_buffers.emplace_back(makeUnique<CSinglePixelBufferResource>(id, m_resource->client(), color));

        if UNLIKELY (!RESOURCE->good()) {
            res->noMemory();
            PROTO::singlePixel->m_buffers.pop_back();
            return;
        }
    });
}

bool CSinglePixelBufferManagerResource::good() {
    return m_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_managers.emplace_back(makeUnique<CSinglePixelBufferManagerResource>(makeUnique<CWpSinglePixelBufferManagerV1>(client, ver, id)));

    if UNLIKELY (!RESOURCE->good()) {
        wl_client_post_no_memory(client);
        m_managers.pop_back();
        return;
    }
}

void CSinglePixelProtocol::destroyResource(CSinglePixelBufferManagerResource* res) {
    std::erase_if(m_managers, [&](const auto& other) { return other.get() == res; });
}

void CSinglePixelProtocol::destroyResource(CSinglePixelBufferResource* surf) {
    std::erase_if(m_buffers, [&](const auto& other) { return other.get() == surf; });
}