24#include <QOpenGLContext>
26#include <private/qopenglcontext_p.h>
36 , texture(std::move(texture))
47 : m_eglDisplay(display)
49 create(context->format(), kwinApp()->outputBackend()->sceneEglGlobalShareContext());
54 if (!m_renderTargets.empty() || !m_zombieRenderTargets.empty()) {
55 m_eglContext->makeCurrent();
56 m_renderTargets.clear();
57 m_zombieRenderTargets.clear();
63 const bool ok = m_eglContext->makeCurrent();
65 qCWarning(KWIN_QPA,
"eglMakeCurrent failed: %x", eglGetError());
69 m_zombieRenderTargets.clear();
71 if (surface->surface()->surfaceClass() == QSurface::Window) {
75 QOpenGLContextPrivate::setCurrentContext(context());
85 auto it = m_renderTargets.find(buffer);
86 if (it != m_renderTargets.end()) {
87 m_current = it->second;
89 std::shared_ptr<GLTexture> texture = m_eglContext->importDmaBufAsTexture(*buffer->
dmabufAttributes());
99 auto target = std::make_shared<EGLRenderTarget>(buffer, std::move(fbo), std::move(texture));
100 m_renderTargets[buffer] = target;
101 QObject::connect(buffer, &QObject::destroyed,
this, [
this, buffer]() {
102 if (
auto it = m_renderTargets.find(buffer); it != m_renderTargets.end()) {
103 m_zombieRenderTargets.push_back(std::move(it->second));
104 m_renderTargets.erase(it);
111 glBindFramebuffer(GL_FRAMEBUFFER, m_current->fbo->handle());
119 m_eglContext->doneCurrent();
124 return m_eglContext !=
nullptr;
139 return eglGetProcAddress(procName);
144 if (surface->surface()->surfaceClass() == QSurface::Window) {
147 if (!internalWindow) {
154 .
buffer = m_current->buffer,
155 .bufferDamage = QRect(QPoint(0, 0), m_current->buffer->size()),
165 if (surface->surface()->surfaceClass() == QSurface::Window) {
167 return m_current->fbo->handle();
169 qCDebug(KWIN_QPA) <<
"No default framebuffer object for internal window";
175void EGLPlatformContext::create(
const QSurfaceFormat &
format, ::EGLContext shareContext)
177 if (!eglBindAPI(
isOpenGLES() ? EGL_OPENGL_ES_API : EGL_OPENGL_API)) {
178 qCWarning(KWIN_QPA,
"eglBindAPI failed: 0x%x", eglGetError());
183 if (m_config == EGL_NO_CONFIG_KHR) {
184 qCWarning(KWIN_QPA) <<
"Could not find suitable EGLConfig for" <<
format;
191 qCWarning(KWIN_QPA) <<
"Failed to create EGL context";
194 updateFormatFromContext();
197void EGLPlatformContext::updateFormatFromContext()
199 const EGLSurface oldDrawSurface = eglGetCurrentSurface(EGL_DRAW);
200 const EGLSurface oldReadSurface = eglGetCurrentSurface(EGL_READ);
201 const ::EGLContext oldContext = eglGetCurrentContext();
203 m_eglContext->makeCurrent();
205 const char *
version =
reinterpret_cast<const char *
>(glGetString(GL_VERSION));
207 if (parseOpenGLVersion(
version, major, minor)) {
208 m_format.setMajorVersion(major);
209 m_format.setMinorVersion(minor);
211 qCWarning(KWIN_QPA) <<
"Unrecognized OpenGL version:" <<
version;
216 if (m_format.version() >= qMakePair(3, 0)) {
217 glGetIntegerv(GL_CONTEXT_FLAGS, &value);
218 if (value & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT) {
219 m_format.setOption(QSurfaceFormat::DeprecatedFunctions);
221 if (value & GL_CONTEXT_FLAG_DEBUG_BIT) {
222 m_format.setOption(QSurfaceFormat::DebugContext);
225 m_format.setOption(QSurfaceFormat::DeprecatedFunctions);
228 if (m_format.version() >= qMakePair(3, 2)) {
229 glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &value);
230 if (value & GL_CONTEXT_CORE_PROFILE_BIT) {
231 m_format.setProfile(QSurfaceFormat::CoreProfile);
232 }
else if (value & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) {
233 m_format.setProfile(QSurfaceFormat::CompatibilityProfile);
235 m_format.setProfile(QSurfaceFormat::NoProfile);
238 m_format.setProfile(QSurfaceFormat::NoProfile);
241 eglMakeCurrent(m_eglDisplay->
handle(), oldDrawSurface, oldReadSurface, oldContext);
static std::unique_ptr< EglContext > create(EglDisplay *display, EGLConfig config, ::EGLContext sharedContext)
QHash< uint32_t, QList< uint64_t > > nonExternalOnlySupportedDrmFormats() const
::EGLDisplay handle() const
virtual const DmaBufAttributes * dmabufAttributes() const
void present(const InternalWindowFrame &frame)
bool isValid() const override
~EGLPlatformContext() override
GLuint defaultFramebufferObject(QPlatformSurface *surface) const override
EGLPlatformContext(QOpenGLContext *context, EglDisplay *display)
void doneCurrent() override
QFunctionPointer getProcAddress(const char *procName) override
bool isSharing() const override
void swapBuffers(QPlatformSurface *surface) override
bool makeCurrent(QPlatformSurface *surface) override
QSurfaceFormat format() const override
std::unique_ptr< GLFramebuffer > fbo
EGLRenderTarget(GraphicsBuffer *buffer, std::unique_ptr< GLFramebuffer > fbo, std::shared_ptr< GLTexture > texture)
std::shared_ptr< GLTexture > texture
GraphicsBuffer * acquire()
InternalWindow * internalWindow() const
Swapchain * swapchain(const QHash< uint32_t, QList< uint64_t > > &formats)
QSurfaceFormat formatFromConfig(EglDisplay *display, EGLConfig config)
EGLConfig configFromFormat(EglDisplay *display, const QSurfaceFormat &surfaceFormat, EGLint surfaceType)