7#include <QtWaylandCompositor/QWaylandCompositor>
16 : zwp_linux_dmabuf_v1(
display, 3 )
17 , m_clientBufferIntegration(clientBufferIntegration)
35 for (
const auto &modifier : std::as_const(
modifiers)) {
36 if (resource->version() >= ZWP_LINUX_DMABUF_V1_MODIFIER_SINCE_VERSION) {
37 const uint32_t modifier_lo = modifier & 0xFFFFFFFF;
38 const uint32_t modifier_hi = modifier >> 32;
39 send_modifier(resource->handle,
format, modifier_hi, modifier_lo);
41 send_format(resource->handle,
format);
49 wl_resource *
r = wl_resource_create(resource->client(), &zwp_linux_buffer_params_v1_interface,
50 wl_resource_get_version(resource->handle), params_id);
55 : zwp_linux_buffer_params_v1(resource)
56 , m_clientBufferIntegration(clientBufferIntegration)
63 if (
it.value().fd != -1)
72 wl_resource_post_error(resource->handle,
73 ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_ALREADY_USED,
74 "Params already used");
79 wl_resource_post_error(resource->handle,
80 ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INVALID_DIMENSIONS,
81 "Invalid dimensions in create request");
86 wl_resource_post_error(resource->handle,
87 ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INCOMPLETE,
88 "Cannot create a buffer with no planes");
93 auto planeIds = m_planes.
keys();
94 std::sort(planeIds.begin(), planeIds.end());
95 for (
int i = 0;
i < planeIds.size(); ++
i) {
96 if (
uint(
i) != planeIds[
i]) {
97 wl_resource_post_error(resource->handle,
98 ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INCOMPLETE,
99 "No dmabuf parameters provided for plane %i",
i);
106 const auto planeId =
it.key();
107 const auto plane =
it.value();
108 if (
static_cast<int64_t
>(plane.offset) + plane.stride > UINT32_MAX) {
109 wl_resource_post_error(resource->handle,
110 ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_OUT_OF_BOUNDS,
111 "Size overflow for plane %i",
115 if (planeId == 0 &&
static_cast<int64_t
>(plane.offset) + plane.stride *
static_cast<int64_t
>(
height) > UINT32_MAX) {
116 wl_resource_post_error(resource->handle,
117 ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_OUT_OF_BOUNDS,
118 "Size overflow for plane %i",
124 off_t
size = lseek(plane.fd, 0, SEEK_END);
126 qCDebug(qLcWaylandCompositorHardwareIntegration) <<
"Seeking is not supported";
130 if (
static_cast<int64_t
>(plane.offset) >=
size) {
131 wl_resource_post_error(resource->handle,
132 ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_OUT_OF_BOUNDS,
133 "Invalid offset %i for plane %i",
134 plane.offset, planeId);
138 if (
static_cast<int64_t
>(plane.offset) +
static_cast<int64_t
>(plane.stride) >
size) {
139 wl_resource_post_error(resource->handle,
140 ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_OUT_OF_BOUNDS,
141 "Invalid stride %i for plane %i",
142 plane.stride, planeId);
147 if (planeId == 0 && plane.offset +
static_cast<int64_t
>(plane.stride) *
height >
size) {
148 wl_resource_post_error(resource->handle,
149 ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_OUT_OF_BOUNDS,
150 "Invalid buffer stride or height for plane %i", planeId);
165 wl_resource_destroy(resource->handle);
176 const uint64_t
modifiers = (
static_cast<uint64_t
>(modifier_hi) << 32) | modifier_lo;
178 wl_resource_post_error(resource->handle,
179 ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_PLANE_IDX,
180 "Plane index %i is out of bounds", plane_idx);
184 wl_resource_post_error(resource->handle,
185 ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_PLANE_SET,
186 "Plane already set");
194 m_planes.
insert(plane_idx, plane);
204 buffer->m_flags = m_flags;
205 buffer->m_drmFormat = m_drmFormat;
213 send_failed(resource->handle);
215 send_created(resource->handle,
buffer->resource()->handle);
226 buffer->m_flags = m_flags;
227 buffer->m_drmFormat = m_drmFormat;
238 wl_resource_post_error(resource->handle,
239 ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INVALID_WL_BUFFER,
240 "Import of the provided DMA buffer failed");
246 : wl_buffer(client,
id, 1 )
247 , m_clientBufferIntegration(clientBufferIntegration)
263 for (uint32_t
i = 0;
i < m_planesNumber; ++
i) {
264 if (m_textures[
i] !=
nullptr) {
266 m_textures[
i] =
nullptr;
267 m_texturesContext[
i] =
nullptr;
271 if (m_eglImages[
i] != EGL_NO_IMAGE_KHR) {
273 m_eglImages[
i] = EGL_NO_IMAGE_KHR;
275 if (m_planes[
i].
fd != -1)
276 close(m_planes[
i].
fd);
299 m_texturesAboutToBeDestroyedConnection[
plane] =
307 if (this->m_textures[
plane] ==
nullptr)
310 delete this->m_textures[
plane];
312 qCDebug(qLcWaylandCompositorHardwareIntegration)
314 <<
"texture deleted due to QOpenGLContext::aboutToBeDestroyed!"
315 <<
"Pointer (now dead) was:" << (
void*)(this->m_textures[
plane])
316 <<
" Associated context (about to die too) is: " << (
void*)(this->m_texturesContext[
plane]);
318 this->m_textures[
plane] =
nullptr;
319 this->m_texturesContext[
plane] =
nullptr;
void deleteGLTextureWhenPossible(QOpenGLTexture *texture, QOpenGLContext *ctx)
bool importBuffer(wl_resource *resource, LinuxDmabufWlBuffer *linuxDmabufBuffer)
void deleteImage(EGLImageKHR image)
void removeBuffer(wl_resource *resource)
void zwp_linux_buffer_params_v1_create_immed(Resource *resource, uint32_t buffer_id, int32_t width, int32_t height, uint32_t format, uint32_t flags) override
~LinuxDmabufParams() override
LinuxDmabufParams(LinuxDmabufClientBufferIntegration *clientBufferIntegration, wl_resource *resource)
void zwp_linux_buffer_params_v1_create(Resource *resource, int32_t width, int32_t height, uint32_t format, uint32_t flags) override
void zwp_linux_buffer_params_v1_destroy(Resource *resource) override
void zwp_linux_buffer_params_v1_add(Resource *resource, int32_t fd, uint32_t plane_idx, uint32_t offset, uint32_t stride, uint32_t modifier_hi, uint32_t modifier_lo) override
void zwp_linux_buffer_params_v1_destroy_resource(Resource *resource) override
Plane & plane(uint index)
void initTexture(uint32_t plane, QOpenGLTexture *texture)
void initImage(uint32_t plane, EGLImageKHR image)
void buffer_destroy(Resource *resource) override
~LinuxDmabufWlBuffer() override
LinuxDmabufWlBuffer(::wl_client *client, LinuxDmabufClientBufferIntegration *clientBufferIntegration, uint id=0)
static const uint32_t MaxDmabufPlanes
void buffer_destroy_resource(Resource *resource) override
void zwp_linux_dmabuf_v1_bind_resource(Resource *resource) override
LinuxDmabuf(wl_display *display, LinuxDmabufClientBufferIntegration *clientBufferIntegration)
void setSupportedModifiers(const QHash< uint32_t, QList< uint64_t > > &modifiers)
void zwp_linux_dmabuf_v1_create_params(Resource *resource, uint32_t params_id) override
const_iterator constEnd() const noexcept
Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item after the ...
const_iterator constBegin() const noexcept
Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first item in the hash.
iterator insert(const Key &key, const T &value)
bool contains(const Key &key) const
QList< Key > keys() const
const_iterator constBegin() const
const_iterator constEnd() const
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
static bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *member)
\threadsafe
void aboutToBeDestroyed()
This signal is emitted before the underlying native OpenGL context is destroyed, such that users may ...
static QOpenGLContext * currentContext()
Returns the last context which called makeCurrent in the current thread, or \nullptr,...
EGLImageKHR int int EGLuint64KHR * modifiers
QSet< QString >::iterator it
struct wl_display * display
#define DRM_FORMAT_MOD_LINEAR
#define DRM_FORMAT_MOD_INVALID
Combined button and popup list for selecting options.
#define qCDebug(category,...)
GLuint64 GLenum void * handle
GLint GLsizei GLsizei height
GLenum GLuint GLintptr GLsizeiptr size
[1]
const void GLsizei GLsizei stride
GLenum GLuint GLintptr offset
GLint GLsizei GLsizei GLenum format