24#include <KWayland/Client/surface.h>
27#include <drm_fourcc.h>
36static const bool bufferAgeEnabled = qEnvironmentVariable(
"KWIN_USE_BUFFER_AGE") != QStringLiteral(
"0");
39 : m_waylandOutput(output)
50 return m_buffer->framebuffer();
55 return m_buffer->texture();
61 qCCritical(KWIN_WAYLAND_BACKEND) <<
"Make Context Current failed";
65 const QSize nativeSize = m_waylandOutput->
modeSize();
66 if (!m_swapchain || m_swapchain->size() != nativeSize) {
68 uint32_t
format = DRM_FORMAT_INVALID;
69 QList<uint64_t> modifiers;
70 for (
const uint32_t &candidateFormat : {DRM_FORMAT_XRGB2101010, DRM_FORMAT_XRGB8888}) {
74 modifiers = it.value();
78 if (
format == DRM_FORMAT_INVALID) {
79 qCWarning(KWIN_WAYLAND_BACKEND) <<
"Could not find a suitable render format";
88 m_buffer = m_swapchain->acquire();
95 m_query = std::make_unique<GLRenderTimeQuery>();
110 m_damageJournal.
add(damagedRegion);
116 Q_ASSERT(!m_presentationBuffer);
117 if (surfaceItem->
size() != m_waylandOutput->
modeSize()) {
125 return m_presentationBuffer;
130 if (!m_presentationBuffer) {
132 Q_ASSERT(m_presentationBuffer);
135 KWayland::Client::Surface *surface = m_waylandOutput->
surface();
136 surface->attachBuffer(m_presentationBuffer);
137 surface->damage(m_damageJournal.
lastDamage());
138 surface->setScale(std::ceil(m_waylandOutput->
scale()));
141 m_presentationBuffer =
nullptr;
143 m_swapchain->release(m_buffer);
149 return m_query->result();
166 qCCritical(KWIN_WAYLAND_BACKEND) <<
"Make Context Current failed";
170 const auto tmp =
size().expandedTo(QSize(64, 64));
171 const QSize bufferSize(std::ceil(tmp.width()), std::ceil(tmp.height()));
172 if (!m_swapchain || m_swapchain->size() != bufferSize) {
174 uint32_t
format = DRM_FORMAT_INVALID;
175 QList<uint64_t> modifiers;
176 for (
const uint32_t &candidateFormat : {DRM_FORMAT_ARGB2101010, DRM_FORMAT_ARGB8888}) {
180 modifiers = it.value();
184 if (
format == DRM_FORMAT_INVALID) {
185 qCWarning(KWIN_WAYLAND_BACKEND) <<
"Could not find a suitable render format";
191 m_buffer = m_swapchain->acquire();
193 m_query = std::make_unique<GLRenderTimeQuery>();
213 m_swapchain->release(m_buffer);
220 return m_query->result();
230 m_outputs.erase(output);
248 return m_allocator.get();
251void WaylandEglBackend::cleanupSurfaces()
256bool WaylandEglBackend::createEglWaylandOutput(
Output *waylandOutput)
258 m_outputs[waylandOutput] = Layers{
259 .primaryLayer = std::make_unique<WaylandEglPrimaryLayer>(
static_cast<WaylandOutput *
>(waylandOutput),
this),
260 .cursorLayer = std::make_unique<WaylandEglCursorLayer>(
static_cast<WaylandOutput *
>(waylandOutput),
this),
265bool WaylandEglBackend::initializeEgl()
270 for (
const QByteArray &extension : {QByteArrayLiteral(
"EGL_EXT_platform_base"), QByteArrayLiteral(
"EGL_KHR_platform_gbm")}) {
272 qCWarning(KWIN_WAYLAND_BACKEND) << extension <<
"client extension is not supported by the platform";
290 if (!initializeEgl()) {
294 if (!initRenderingContext()) {
295 setFailed(
"Could not initialize rendering context");
303bool WaylandEglBackend::initRenderingContext()
312 if (waylandOutputs.isEmpty()) {
316 for (
auto *out : waylandOutputs) {
317 if (!createEglWaylandOutput(out)) {
322 if (m_outputs.empty()) {
323 qCCritical(KWIN_WAYLAND_BACKEND) <<
"Create Window Surfaces failed";
337 return std::make_unique<BasicEGLSurfaceTextureWayland>(
this, pixmap);
342 m_outputs[output].primaryLayer->present();
348 return m_outputs[output].primaryLayer.get();
353 return m_outputs[output].cursorLayer.get();
359#include "moc_wayland_egl_backend.cpp"
void initClientExtensions()
bool makeCurrent() override
bool hasClientExtension(const QByteArray &ext) const
void setEglDisplay(EglDisplay *display)
EglContext * contextObject()
bool createContext(EGLConfig config)
static const ColorDescription sRGB
void add(const QRegion ®ion)
QRegion accumulate(int bufferAge, const QRegion &fallback=QRegion()) const
QRegion lastDamage() const
bool makeCurrent(EGLSurface surface=EGL_NO_SURFACE) const
static std::unique_ptr< EglDisplay > create(::EGLDisplay display, bool owning=true)
static std::shared_ptr< EglSwapchain > create(GraphicsBufferAllocator *allocator, EglContext *context, const QSize &size, uint32_t format, const QList< uint64_t > &modifiers)
OpenGL framebuffer object.
void setFailed(const QString &reason)
Sets the backend initialization to failed.
void outputAdded(Output *output)
void outputRemoved(Output *output)
void outputChange(const QRegion &damagedRegion)
OutputTransform bufferTransform() const
GraphicsBuffer * buffer() const
SurfaceInterface * surface() const
Class encapsulating all Wayland data structures needed by the Egl backend.
void setEglDisplay(std::unique_ptr< EglDisplay > &&display)
void setEglBackend(WaylandEglBackend *eglBackend)
WaylandDisplay * display() const
EglDisplay * sceneEglDisplayObject() const override
QList< WaylandOutput * > waylandOutputs() const
wl_buffer * importBuffer(GraphicsBuffer *graphicsBuffer)
gbm_device * gbmDevice() const
void update(wl_buffer *buffer, qreal scale, const QPoint &hotspot)
WaylandLinuxDmabufV1 * linuxDmabuf() const
OpenGL Backend using Egl on a Wayland surface.
GraphicsBufferAllocator * graphicsBufferAllocator() const override
OutputLayer * cursorLayer(Output *output) override
void present(Output *output, const std::shared_ptr< OutputFrame > &frame) override
OutputLayer * primaryLayer(Output *output) override
std::pair< std::shared_ptr< KWin::GLTexture >, ColorDescription > textureForOutput(KWin::Output *output) const override
std::unique_ptr< SurfaceTexture > createSurfaceTextureWayland(SurfacePixmap *pixmap) override
~WaylandEglBackend() override
WaylandBackend * backend() const
WaylandEglBackend(WaylandBackend *b)
std::optional< OutputLayerBeginFrameInfo > beginFrame() override
std::chrono::nanoseconds queryRenderTime() const override
~WaylandEglCursorLayer() override
bool endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override
WaylandEglCursorLayer(WaylandOutput *output, WaylandEglBackend *backend)
WaylandEglPrimaryLayer(WaylandOutput *output, WaylandEglBackend *backend)
~WaylandEglPrimaryLayer() override
std::shared_ptr< GLTexture > texture() const
std::optional< OutputLayerBeginFrameInfo > beginFrame() override
bool scanout(SurfaceItem *surfaceItem) override
std::chrono::nanoseconds queryRenderTime() const override
GLFramebuffer * fbo() const
bool endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override
QHash< uint32_t, QList< uint64_t > > formats() const
WaylandCursor * cursor() const
KWayland::Client::Surface * surface() const
KWIN_EXPORT QRect infiniteRegion()
struct KWin::@10 formatTable[]
RenderTarget renderTarget