KWin
Loading...
Searching...
No Matches
eglswapchain.cpp
Go to the documentation of this file.
1/*
2 KWin - the KDE window manager
3 This file is part of the KDE project.
4
5 SPDX-FileCopyrightText: 2017 Martin Flöser <mgraesslin@kde.org>
6 SPDX-FileCopyrightText: 2022 Xaver Hugl <xaver.hugl@gmail.com>
7
8 SPDX-License-Identifier: GPL-2.0-or-later
9*/
10#include "opengl/eglswapchain.h"
11#include "core/graphicsbuffer.h"
13#include "opengl/eglcontext.h"
14#include "opengl/glutils.h"
15#include "utils/common.h"
16
17#include <drm_fourcc.h>
18#include <errno.h>
19
20namespace KWin
21{
22
23EglSwapchainSlot::EglSwapchainSlot(GraphicsBuffer *buffer, std::unique_ptr<GLFramebuffer> &&framebuffer, const std::shared_ptr<GLTexture> &texture)
24 : m_buffer(buffer)
25 , m_framebuffer(std::move(framebuffer))
26 , m_texture(texture)
27{
28}
29
31{
32 m_framebuffer.reset();
33 m_texture.reset();
34 m_buffer->drop();
35}
36
38{
39 return m_buffer;
40}
41
42std::shared_ptr<GLTexture> EglSwapchainSlot::texture() const
43{
44 return m_texture;
45}
46
48{
49 return m_framebuffer.get();
50}
51
53{
54 return m_age;
55}
56
57std::shared_ptr<EglSwapchainSlot> EglSwapchainSlot::create(EglContext *context, GraphicsBuffer *buffer)
58{
60 if (!texture) {
61 buffer->drop();
62 return nullptr;
63 }
64 auto framebuffer = std::make_unique<GLFramebuffer>(texture.get());
65 if (!framebuffer->valid()) {
66 buffer->drop();
67 return nullptr;
68 }
69 return std::make_shared<EglSwapchainSlot>(buffer, std::move(framebuffer), texture);
70}
71
72EglSwapchain::EglSwapchain(GraphicsBufferAllocator *allocator, EglContext *context, const QSize &size, uint32_t format, uint64_t modifier, const std::shared_ptr<EglSwapchainSlot> &seed)
73 : m_allocator(allocator)
74 , m_context(context)
75 , m_size(size)
76 , m_format(format)
77 , m_modifier(modifier)
78 , m_slots({seed})
79{
80}
81
85
86QSize EglSwapchain::size() const
87{
88 return m_size;
89}
90
91uint32_t EglSwapchain::format() const
92{
93 return m_format;
94}
95
96uint64_t EglSwapchain::modifier() const
97{
98 return m_modifier;
99}
100
101std::shared_ptr<EglSwapchainSlot> EglSwapchain::acquire()
102{
103 for (const auto &slot : std::as_const(m_slots)) {
104 if (!slot->buffer()->isReferenced()) {
105 return slot;
106 }
107 }
108
109 GraphicsBuffer *buffer = m_allocator->allocate(GraphicsBufferOptions{
110 .size = m_size,
111 .format = m_format,
112 .modifiers = {m_modifier},
113 });
114 if (!buffer) {
115 qCWarning(KWIN_OPENGL) << "Failed to allocate an egl gbm swapchain graphics buffer";
116 return nullptr;
117 }
118
119 auto slot = EglSwapchainSlot::create(m_context, buffer);
120 if (!slot) {
121 return nullptr;
122 }
123 m_slots.append(slot);
124 return slot;
125}
126
127void EglSwapchain::release(std::shared_ptr<EglSwapchainSlot> slot)
128{
129 for (qsizetype i = 0; i < m_slots.count(); ++i) {
130 if (m_slots[i] == slot) {
131 m_slots[i]->m_age = 1;
132 } else if (m_slots[i]->m_age > 0) {
133 m_slots[i]->m_age++;
134 }
135 }
136}
137
138std::shared_ptr<EglSwapchain> EglSwapchain::create(GraphicsBufferAllocator *allocator, EglContext *context, const QSize &size, uint32_t format, const QList<uint64_t> &modifiers)
139{
140 if (!context->makeCurrent()) {
141 return nullptr;
142 }
143
144 // The seed graphics buffer is used to fixate modifiers.
146 .size = size,
147 .format = format,
148 .modifiers = modifiers,
149 });
150 if (!seed) {
151 return nullptr;
152 }
153 const auto first = EglSwapchainSlot::create(context, seed);
154 if (!first) {
155 return nullptr;
156 }
157 return std::make_shared<EglSwapchain>(std::move(allocator),
158 context,
159 size,
160 format,
161 seed->dmabufAttributes()->modifier,
162 first);
163}
164
165} // namespace KWin
bool makeCurrent(EGLSurface surface=EGL_NO_SURFACE) const
std::shared_ptr< GLTexture > importDmaBufAsTexture(const DmaBufAttributes &attributes) const
uint32_t format() const
void release(std::shared_ptr< EglSwapchainSlot > slot)
QSize size() const
uint64_t modifier() const
EglSwapchain(GraphicsBufferAllocator *allocator, EglContext *context, const QSize &size, uint32_t format, uint64_t modifier, const std::shared_ptr< EglSwapchainSlot > &seed)
static std::shared_ptr< EglSwapchain > create(GraphicsBufferAllocator *allocator, EglContext *context, const QSize &size, uint32_t format, const QList< uint64_t > &modifiers)
std::shared_ptr< EglSwapchainSlot > acquire()
std::shared_ptr< GLTexture > texture() const
EglSwapchainSlot(GraphicsBuffer *buffer, std::unique_ptr< GLFramebuffer > &&framebuffer, const std::shared_ptr< GLTexture > &texture)
GLFramebuffer * framebuffer() const
static std::shared_ptr< EglSwapchainSlot > create(EglContext *context, GraphicsBuffer *buffer)
GraphicsBuffer * buffer() const
OpenGL framebuffer object.
virtual GraphicsBuffer * allocate(const GraphicsBufferOptions &options)=0
virtual const DmaBufAttributes * dmabufAttributes() const
GLenum format
Definition gltexture.cpp:49
QSize size
The size of the buffer, in device pixels.