File indexing completed on 2024-05-19 16:35:18
0001 /* 0002 SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 0007 #include "drmclientbuffer.h" 0008 #include "clientbuffer_p.h" 0009 #include "display.h" 0010 0011 #include <EGL/egl.h> 0012 #include <QtGui/qopengl.h> 0013 0014 #ifndef EGL_WL_bind_wayland_display 0015 #define EGL_WAYLAND_Y_INVERTED_WL 0x31DB 0016 #endif 0017 0018 namespace KWaylandServer 0019 { 0020 typedef EGLBoolean (*eglQueryWaylandBufferWL_func)(EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value); 0021 static eglQueryWaylandBufferWL_func eglQueryWaylandBufferWL = nullptr; 0022 0023 class DrmClientBufferPrivate : public ClientBufferPrivate 0024 { 0025 public: 0026 int textureFormat = 0; 0027 int width = 0; 0028 int height = 0; 0029 int yInverted = 0; 0030 bool hasAlphaChannel = false; 0031 }; 0032 0033 DrmClientBuffer::DrmClientBuffer(wl_resource *resource, DrmClientBufferIntegration *integration) 0034 : ClientBuffer(resource, *new DrmClientBufferPrivate) 0035 { 0036 Q_D(DrmClientBuffer); 0037 0038 EGLDisplay eglDisplay = integration->display()->eglDisplay(); 0039 eglQueryWaylandBufferWL(eglDisplay, resource, EGL_TEXTURE_FORMAT, &d->textureFormat); 0040 eglQueryWaylandBufferWL(eglDisplay, resource, EGL_WIDTH, &d->width); 0041 eglQueryWaylandBufferWL(eglDisplay, resource, EGL_HEIGHT, &d->height); 0042 0043 if (!eglQueryWaylandBufferWL(eglDisplay, resource, EGL_WAYLAND_Y_INVERTED_WL, &d->yInverted)) { 0044 // If EGL_WAYLAND_Y_INVERTED_WL is unsupported, we must assume that the buffer is inverted. 0045 d->yInverted = true; 0046 } 0047 } 0048 0049 int DrmClientBuffer::textureFormat() const 0050 { 0051 Q_D(const DrmClientBuffer); 0052 return d->textureFormat; 0053 } 0054 0055 QSize DrmClientBuffer::size() const 0056 { 0057 Q_D(const DrmClientBuffer); 0058 return QSize(d->width, d->height); 0059 } 0060 0061 bool DrmClientBuffer::hasAlphaChannel() const 0062 { 0063 Q_D(const DrmClientBuffer); 0064 return d->textureFormat == EGL_TEXTURE_RGBA; 0065 } 0066 0067 ClientBuffer::Origin DrmClientBuffer::origin() const 0068 { 0069 Q_D(const DrmClientBuffer); 0070 return d->yInverted ? Origin::TopLeft : Origin::BottomLeft; 0071 } 0072 0073 DrmClientBufferIntegration::DrmClientBufferIntegration(Display *display) 0074 : ClientBufferIntegration(display) 0075 { 0076 } 0077 0078 ClientBuffer *DrmClientBufferIntegration::createBuffer(::wl_resource *resource) 0079 { 0080 EGLDisplay eglDisplay = display()->eglDisplay(); 0081 static bool resolved = false; 0082 if (!resolved && eglDisplay != EGL_NO_DISPLAY) { 0083 eglQueryWaylandBufferWL = (eglQueryWaylandBufferWL_func)eglGetProcAddress("eglQueryWaylandBufferWL"); 0084 resolved = true; 0085 } 0086 0087 EGLint format; 0088 if (eglQueryWaylandBufferWL(eglDisplay, resource, EGL_TEXTURE_FORMAT, &format)) { 0089 return new DrmClientBuffer(resource, this); 0090 } 0091 return nullptr; 0092 } 0093 0094 } // namespace KWaylandServer