/**************************************************************************** ** ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:GPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3 or (at your option) any later version ** approved by the KDE Free Qt Foundation. The licenses are as published by ** the Free Software Foundation and appearing in the file LICENSE.GPL3 ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef LINUXDMABUF_H #define LINUXDMABUF_H #include "qwayland-server-linux-dmabuf-unstable-v1.h" #include #include #include #include #include #include #include #include #include // compatibility with libdrm <= 2.4.74 #ifndef DRM_FORMAT_RESERVED #define DRM_FORMAT_RESERVED ((1ULL << 56) - 1) #endif #ifndef DRM_FORMAT_MOD_VENDOR_NONE #define DRM_FORMAT_MOD_VENDOR_NONE 0 #endif #ifndef DRM_FORMAT_MOD_LINEAR #define DRM_FORMAT_MOD_LINEAR fourcc_mod_code(NONE, 0) #endif #ifndef DRM_FORMAT_MOD_INVALID #define DRM_FORMAT_MOD_INVALID fourcc_mod_code(NONE, DRM_FORMAT_RESERVED) #endif // Copied from eglmesaext.h #ifndef EGL_WL_bind_wayland_display typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDWAYLANDDISPLAYWL) (EGLDisplay dpy, struct wl_display *display); typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNBINDWAYLANDDISPLAYWL) (EGLDisplay dpy, struct wl_display *display); #endif QT_BEGIN_NAMESPACE class QWaylandCompositor; class QWaylandResource; class LinuxDmabufParams; class LinuxDmabufClientBufferIntegration; struct Plane { int fd = -1; uint32_t offset = 0; uint32_t stride = 0; uint64_t modifiers = 0; }; class LinuxDmabuf : public QtWaylandServer::zwp_linux_dmabuf_v1 { public: explicit LinuxDmabuf(wl_display *display, LinuxDmabufClientBufferIntegration *clientBufferIntegration); void setSupportedModifiers(const QHash> &modifiers); protected: void zwp_linux_dmabuf_v1_bind_resource(Resource *resource) override; void zwp_linux_dmabuf_v1_create_params(Resource *resource, uint32_t params_id) override; private: QHash> m_modifiers; // key=DRM format, value=supported DRM modifiers for format LinuxDmabufClientBufferIntegration *m_clientBufferIntegration; }; class LinuxDmabufParams : public QtWaylandServer::zwp_linux_buffer_params_v1 { public: explicit LinuxDmabufParams(LinuxDmabufClientBufferIntegration *clientBufferIntegration, wl_resource *resource); ~LinuxDmabufParams() override; private: bool handleCreateParams(Resource *resource, int width, int height, uint format, uint flags); uint m_drmFormat = 0; uint m_flags = 0; QSize m_size; bool m_used = false; QMap m_planes; LinuxDmabufClientBufferIntegration *m_clientBufferIntegration; protected: 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_create(Resource *resource, int32_t width, int32_t height, uint32_t format, uint32_t flags) override; 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; void zwp_linux_buffer_params_v1_destroy_resource(Resource *resource) override; friend class LinuxDmabufClientBufferIntegrationPrivate; }; class LinuxDmabufWlBuffer : public QtWaylandServer::wl_buffer { public: explicit LinuxDmabufWlBuffer(::wl_client *client, LinuxDmabufClientBufferIntegration *clientBufferIntegration, uint id = 0); ~LinuxDmabufWlBuffer() override; void initImage(uint32_t plane, EGLImageKHR image); void initTexture(uint32_t plane, QOpenGLTexture *texture); inline QSize size() const { return m_size; } inline uint32_t flags() const { return m_flags; } inline uint32_t drmFormat() const { return m_drmFormat; } inline Plane& plane(uint index) { return m_planes.at(index); } inline uint32_t planesNumber() const { return m_planesNumber; } inline EGLImageKHR image(uint32_t plane) { return m_eglImages.at(plane); } inline QOpenGLTexture *texture(uint32_t plane) const { return m_textures.at(plane); } void buffer_destroy_resource(Resource *resource) override; static const uint32_t MaxDmabufPlanes = 4; private: QSize m_size; uint32_t m_flags = 0; uint32_t m_drmFormat = EGL_TEXTURE_RGBA; std::array m_planes; uint32_t m_planesNumber = 1; LinuxDmabufClientBufferIntegration *m_clientBufferIntegration = nullptr; std::array m_eglImages = { {EGL_NO_IMAGE_KHR, EGL_NO_IMAGE_KHR, EGL_NO_IMAGE_KHR, EGL_NO_IMAGE_KHR} }; std::array m_textures = { {nullptr, nullptr, nullptr, nullptr} }; void freeResources(); void buffer_destroy(Resource *resource) override; friend class LinuxDmabufParams; }; QT_END_NAMESPACE #endif // LINUXDMABUF_H