7#include <QtWaylandCompositor/QWaylandCompositor>
8#include <QtWaylandCompositor/private/qwltextureorphanage_p.h>
10#include <drm_fourcc.h>
17 : zwp_linux_dmabuf_v1(
display, 3 )
18 , m_clientBufferIntegration(clientBufferIntegration)
36 for (
const auto &modifier : std::as_const(
modifiers)) {
37 if (resource->version() >= ZWP_LINUX_DMABUF_V1_MODIFIER_SINCE_VERSION) {
38 const uint32_t modifier_lo = modifier & 0xFFFFFFFF;
39 const uint32_t modifier_hi = modifier >> 32;
40 send_modifier(resource->handle,
format, modifier_hi, modifier_lo);
42 send_format(resource->handle,
format);
50 wl_resource *
r = wl_resource_create(resource->client(), &zwp_linux_buffer_params_v1_interface,
51 wl_resource_get_version(resource->handle), params_id);
56 : zwp_linux_buffer_params_v1(resource)
57 , m_clientBufferIntegration(clientBufferIntegration)
64 if (
it.value().fd != -1)
73 wl_resource_post_error(resource->handle,
74 ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_ALREADY_USED,
75 "Params already used");
80 wl_resource_post_error(resource->handle,
81 ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INVALID_DIMENSIONS,
82 "Invalid dimensions in create request");
87 wl_resource_post_error(resource->handle,
88 ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INCOMPLETE,
89 "Cannot create a buffer with no planes");
94 auto planeIds = m_planes.
keys();
95 std::sort(planeIds.begin(), planeIds.end());
96 for (
int i = 0;
i < planeIds.size(); ++
i) {
97 if (
uint(
i) != planeIds[
i]) {
98 wl_resource_post_error(resource->handle,
99 ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INCOMPLETE,
100 "No dmabuf parameters provided for plane %i",
i);
107 const auto planeId =
it.key();
108 const auto plane =
it.value();
109 if (
static_cast<int64_t
>(plane.offset) + plane.stride > UINT32_MAX) {
110 wl_resource_post_error(resource->handle,
111 ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_OUT_OF_BOUNDS,
112 "Size overflow for plane %i",
116 if (planeId == 0 &&
static_cast<int64_t
>(plane.offset) + plane.stride *
static_cast<int64_t
>(
height) > UINT32_MAX) {
117 wl_resource_post_error(resource->handle,
118 ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_OUT_OF_BOUNDS,
119 "Size overflow for plane %i",
125 off_t
size = lseek(plane.fd, 0, SEEK_END);
127 qCDebug(qLcWaylandCompositorHardwareIntegration) <<
"Seeking is not supported";
131 if (
static_cast<int64_t
>(plane.offset) >=
size) {
132 wl_resource_post_error(resource->handle,
133 ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_OUT_OF_BOUNDS,
134 "Invalid offset %i for plane %i",
135 plane.offset, planeId);
139 if (
static_cast<int64_t
>(plane.offset) +
static_cast<int64_t
>(plane.stride) >
size) {
140 wl_resource_post_error(resource->handle,
141 ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_OUT_OF_BOUNDS,
142 "Invalid stride %i for plane %i",
143 plane.stride, planeId);
148 if (planeId == 0 && plane.offset +
static_cast<int64_t
>(plane.stride) *
height >
size) {
149 wl_resource_post_error(resource->handle,
150 ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_OUT_OF_BOUNDS,
151 "Invalid buffer stride or height for plane %i", planeId);
166 wl_resource_destroy(resource->handle);
177 const uint64_t
modifiers = (
static_cast<uint64_t
>(modifier_hi) << 32) | modifier_lo;
179 wl_resource_post_error(resource->handle,
180 ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_PLANE_IDX,
181 "Plane index %i is out of bounds", plane_idx);
185 wl_resource_post_error(resource->handle,
186 ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_PLANE_SET,
187 "Plane already set");
195 m_planes.
insert(plane_idx, plane);
205 buffer->m_flags = m_flags;
206 buffer->m_drmFormat = m_drmFormat;
214 send_failed(resource->handle);
216 send_created(resource->handle,
buffer->resource()->handle);
227 buffer->m_flags = m_flags;
228 buffer->m_drmFormat = m_drmFormat;
239 wl_resource_post_error(resource->handle,
240 ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INVALID_WL_BUFFER,
241 "Import of the provided DMA buffer failed");
247 : wl_buffer(client,
id, 1 )
248 , m_clientBufferIntegration(clientBufferIntegration)
264 for (uint32_t
i = 0;
i < m_planesNumber; ++
i) {
265 if (m_textures[
i] !=
nullptr) {
267 m_texturesContext[
i]);
268 m_textures[
i] =
nullptr;
269 m_texturesContext[
i] =
nullptr;
273 if (m_eglImages[
i] != EGL_NO_IMAGE_KHR) {
275 m_eglImages[
i] = EGL_NO_IMAGE_KHR;
277 if (m_planes[
i].
fd != -1)
278 close(m_planes[
i].
fd);
301 m_texturesAboutToBeDestroyedConnection[
plane] =
309 if (this->m_textures[
plane] ==
nullptr)
312 delete this->m_textures[
plane];
314 qCDebug(qLcWaylandCompositorHardwareIntegration)
316 <<
"texture deleted due to QOpenGLContext::aboutToBeDestroyed!"
317 <<
"Pointer (now dead) was:" << (
void*)(this->m_textures[
plane])
318 <<
" Associated context (about to die too) is: " << (
void*)(this->m_texturesContext[
plane]);
320 this->m_textures[
plane] =
nullptr;
321 this->m_texturesContext[
plane] =
nullptr;
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,...
static QWaylandTextureOrphanage * instance()
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