KWaylandServer

drmclientbuffer.cpp
1 /*
2  SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5 */
6 
7 #include "drmclientbuffer.h"
8 #include "clientbuffer_p.h"
9 #include "display.h"
10 
11 #include <EGL/egl.h>
12 #include <QtGui/qopengl.h>
13 
14 #ifndef EGL_WL_bind_wayland_display
15 #define EGL_WAYLAND_Y_INVERTED_WL 0x31DB
16 #endif
17 
18 namespace KWaylandServer
19 {
20 typedef EGLBoolean (*eglQueryWaylandBufferWL_func)(EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value);
21 static eglQueryWaylandBufferWL_func eglQueryWaylandBufferWL = nullptr;
22 
23 class DrmClientBufferPrivate : public ClientBufferPrivate
24 {
25 public:
26  int textureFormat = 0;
27  int width = 0;
28  int height = 0;
29  int yInverted = 0;
30  bool hasAlphaChannel = false;
31 };
32 
33 DrmClientBuffer::DrmClientBuffer(wl_resource *resource, DrmClientBufferIntegration *integration)
34  : ClientBuffer(resource, *new DrmClientBufferPrivate)
35 {
36  Q_D(DrmClientBuffer);
37 
38  EGLDisplay eglDisplay = integration->display()->eglDisplay();
39  if (!eglQueryWaylandBufferWL(eglDisplay, resource, EGL_TEXTURE_FORMAT, &d->textureFormat)) {
40  // The proprietary Nvidia driver doesn't support querying the EGL_TEXTURE_FORMAT.
41  // We must assume that the buffer has an alpha channel for transparency to work.
42  d->textureFormat = EGL_TEXTURE_RGBA;
43  }
44 
45  eglQueryWaylandBufferWL(eglDisplay, resource, EGL_WIDTH, &d->width);
46  eglQueryWaylandBufferWL(eglDisplay, resource, EGL_HEIGHT, &d->height);
47 
48  if (!eglQueryWaylandBufferWL(eglDisplay, resource, EGL_WAYLAND_Y_INVERTED_WL, &d->yInverted)) {
49  // If EGL_WAYLAND_Y_INVERTED_WL is unsupported, we must assume that the buffer is inverted.
50  d->yInverted = true;
51  }
52 }
53 
54 int DrmClientBuffer::textureFormat() const
55 {
56  Q_D(const DrmClientBuffer);
57  return d->textureFormat;
58 }
59 
61 {
62  Q_D(const DrmClientBuffer);
63  return QSize(d->width, d->height);
64 }
65 
66 bool DrmClientBuffer::hasAlphaChannel() const
67 {
68  Q_D(const DrmClientBuffer);
69  return d->textureFormat == EGL_TEXTURE_RGBA;
70 }
71 
72 ClientBuffer::Origin DrmClientBuffer::origin() const
73 {
74  Q_D(const DrmClientBuffer);
75  return d->yInverted ? Origin::TopLeft : Origin::BottomLeft;
76 }
77 
78 DrmClientBufferIntegration::DrmClientBufferIntegration(Display *display)
79  : ClientBufferIntegration(display)
80 {
81 }
82 
83 ClientBuffer *DrmClientBufferIntegration::createBuffer(::wl_resource *resource)
84 {
85  EGLDisplay eglDisplay = display()->eglDisplay();
86  static bool resolved = false;
87  if (!resolved && eglDisplay != EGL_NO_DISPLAY) {
88  eglQueryWaylandBufferWL = (eglQueryWaylandBufferWL_func)eglGetProcAddress("eglQueryWaylandBufferWL");
89  resolved = true;
90  }
91 
92  EGLint height;
93  if (eglQueryWaylandBufferWL(eglDisplay, resource, EGL_HEIGHT, &height)) {
94  return new DrmClientBuffer(resource, this);
95  }
96  return nullptr;
97 }
98 
99 } // namespace KWaylandServer
void * eglDisplay() const
Definition: display.cpp:231
Class holding the Wayland server display loop.
Definition: display.h:47
Origin
This enum type is used to specify the corner where the origin is.
Definition: clientbuffer.h:41
The DrmClientBuffer class represents a wl_drm client buffer.
The ClientBuffer class represents a client buffer.
Definition: clientbuffer.h:29
QSize size() const override
Returns the size in the native pixels.
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Sat Oct 23 2021 23:08:27 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.