1 /********************************************************************
2 Copyright © 2018 Fredrik Höglund <fredrik@kde.org>
3 Copyright © 2019-2020 Roman Gilg <subdiff@gmail.com>
4 
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) version 3, or any
9 later version accepted by the membership of KDE e.V. (or its
10 successor approved by the membership of KDE e.V.), which shall
11 act as a proxy defined in Section 6 of version 3 of the license.
12 
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 Lesser General Public License for more details.
17 
18 You should have received a copy of the GNU Lesser General Public
19 License along with this library.  If not, see <http://www.gnu.org/licenses/>.
20 *********************************************************************/
21 #pragma once
22 
23 #include "linux_dmabuf_v1.h"
24 
25 #include "wayland/global.h"
26 #include "wayland/resource.h"
27 
28 #include "wayland-linux-dmabuf-unstable-v1-server-protocol.h"
29 
30 #include <array>
31 
32 namespace Wrapland::Server
33 {
34 class BufferV1;
35 
36 constexpr uint32_t LinuxDmabufV1Version = 3;
37 using LinuxDmabufV1Global = Wayland::Global<LinuxDmabufV1, LinuxDmabufV1Version>;
38 using LinuxDmabufV1Bind = Wayland::Bind<LinuxDmabufV1Global>;
39 
40 class LinuxDmabufV1::Private : public LinuxDmabufV1Global
41 {
42 public:
43     Private(LinuxDmabufV1* q, Display* display);
44     ~Private() override;
45 
46     void bindInit(LinuxDmabufV1Bind* bind) final;
47 
48     static const struct wl_buffer_interface* bufferInterface();
49     static void createParamsCallback(LinuxDmabufV1Bind* bind, uint32_t id);
50 
51     LinuxDmabufV1::Impl* impl;
52     QHash<uint32_t, QSet<uint64_t>> supportedFormatsWithModifiers;
53 
54 private:
55     static const struct zwp_linux_dmabuf_v1_interface s_interface;
56 };
57 
58 class LinuxDmabufBufferV1::Private
59 {
60 public:
61     Private(uint32_t format, const QSize& size, LinuxDmabufBufferV1* q);
62     ~Private() = default;
63 
64     uint32_t format;
65     QSize size;
66 
67     BufferV1* buffer;
68 };
69 
70 class BufferV1 : public Wayland::Resource<LinuxDmabufBufferV1>
71 {
72 public:
73     BufferV1(Client* client, uint32_t version, uint32_t id, LinuxDmabufBufferV1* q);
74     ~BufferV1() override = default;
75 
76     static const struct wl_buffer_interface* interface();
77 
78 private:
79     static const struct wl_buffer_interface s_interface;
80 };
81 
82 class ParamsWrapperV1;
83 class ParamsV1 : public Wayland::Resource<ParamsWrapperV1>
84 {
85 public:
86     ParamsV1(Client* client,
87              uint32_t version,
88              uint32_t id,
89              LinuxDmabufV1::Private* dmabuf,
90              ParamsWrapperV1* q);
91     ~ParamsV1() override;
92 
93     void add(int fd, uint32_t plane_idx, uint32_t offset, uint32_t stride, uint64_t modifier);
94     void create(uint32_t bufferId, const QSize& size, uint32_t format, uint32_t flags);
95 
96 private:
97     static void addCallback(wl_client* wlClient,
98                             wl_resource* wlResource,
99                             int fd,
100                             uint32_t plane_idx,
101                             uint32_t offset,
102                             uint32_t stride,
103                             uint32_t modifier_hi,
104                             uint32_t modifier_lo);
105 
106     static void createCallback(wl_client* wlClient,
107                                wl_resource* wlResource,
108                                int width,
109                                int height,
110                                uint32_t format,
111                                uint32_t flags);
112 
113     static void createImmedCallback(wl_client* wlClient,
114                                     wl_resource* wlResource,
115                                     uint32_t new_id,
116                                     int width,
117                                     int height,
118                                     uint32_t format,
119                                     uint32_t flags);
120 
121     bool validate_params(QSize const& size);
122 
123     static struct zwp_linux_buffer_params_v1_interface const s_interface;
124 
125     LinuxDmabufV1::Private* m_dmabuf;
126     std::array<LinuxDmabufV1::Plane, 4> m_planes;
127     size_t m_planeCount = 0;
128     bool m_createRequested = false;
129 };
130 
131 // TODO(romangg): Make this wrapper go away! For that Wayland::Resource can't depend any longer on
132 //                the resourceDestroy signal being available.
133 class ParamsWrapperV1 : public QObject
134 {
135     Q_OBJECT
136 public:
137     ParamsWrapperV1(Client* client, uint32_t version, uint32_t id, LinuxDmabufV1::Private* dmabuf);
138     ParamsV1* d_ptr;
139 
140 Q_SIGNALS:
141     void resourceDestroyed();
142 };
143 
144 }
145