19#include <QOpenGLContext>
20#include <drm_fourcc.h>
27 auto handle = createContext(display,
config, sharedContext);
31 if (!eglMakeCurrent(display->
handle(), EGL_NO_SURFACE, EGL_NO_SURFACE,
handle)) {
35 auto ret = std::make_unique<EglContext>(display,
config,
handle);
36 if (!ret->checkSupported()) {
51 glGenVertexArrays(1, &m_vao);
52 glBindVertexArray(m_vao);
60 glDeleteVertexArrays(1, &m_vao);
62 m_shaderManager.reset();
64 eglDestroyContext(m_display->
handle(), m_handle);
69 return eglMakeCurrent(m_display->
handle(), surface, surface, m_handle) == EGL_TRUE;
74 eglMakeCurrent(m_display->
handle(), EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
94 return m_display !=
nullptr && m_handle != EGL_NO_CONTEXT;
97::EGLContext EglContext::createContext(
EglDisplay *display, EGLConfig config, ::EGLContext sharedContext)
99 const bool haveRobustness = display->
hasExtension(QByteArrayLiteral(
"EGL_EXT_create_context_robustness"));
100 const bool haveCreateContext = display->
hasExtension(QByteArrayLiteral(
"EGL_KHR_create_context"));
101 const bool haveContextPriority = display->
hasExtension(QByteArrayLiteral(
"EGL_IMG_context_priority"));
102 const bool haveResetOnVideoMemoryPurge = display->
hasExtension(QByteArrayLiteral(
"EGL_NV_robustness_video_memory_purge"));
104 std::vector<std::unique_ptr<AbstractOpenGLContextAttributeBuilder>> candidates;
106 if (haveCreateContext && haveRobustness && haveContextPriority && haveResetOnVideoMemoryPurge) {
107 auto glesRobustPriority = std::make_unique<EglOpenGLESContextAttributeBuilder>();
108 glesRobustPriority->setResetOnVideoMemoryPurge(
true);
109 glesRobustPriority->setVersion(2);
110 glesRobustPriority->setRobust(
true);
111 glesRobustPriority->setHighPriority(
true);
112 candidates.push_back(std::move(glesRobustPriority));
115 if (haveCreateContext && haveRobustness && haveContextPriority) {
116 auto glesRobustPriority = std::make_unique<EglOpenGLESContextAttributeBuilder>();
117 glesRobustPriority->setVersion(2);
118 glesRobustPriority->setRobust(
true);
119 glesRobustPriority->setHighPriority(
true);
120 candidates.push_back(std::move(glesRobustPriority));
122 if (haveCreateContext && haveRobustness) {
123 auto glesRobust = std::make_unique<EglOpenGLESContextAttributeBuilder>();
124 glesRobust->setVersion(2);
125 glesRobust->setRobust(
true);
126 candidates.push_back(std::move(glesRobust));
128 if (haveContextPriority) {
129 auto glesPriority = std::make_unique<EglOpenGLESContextAttributeBuilder>();
130 glesPriority->setVersion(2);
131 glesPriority->setHighPriority(
true);
132 candidates.push_back(std::move(glesPriority));
134 auto gles = std::make_unique<EglOpenGLESContextAttributeBuilder>();
136 candidates.push_back(std::move(gles));
138 if (haveCreateContext) {
139 if (haveRobustness && haveContextPriority && haveResetOnVideoMemoryPurge) {
140 auto robustCorePriority = std::make_unique<EglContextAttributeBuilder>();
141 robustCorePriority->setResetOnVideoMemoryPurge(
true);
142 robustCorePriority->setVersion(3, 1);
143 robustCorePriority->setRobust(
true);
144 robustCorePriority->setHighPriority(
true);
145 candidates.push_back(std::move(robustCorePriority));
147 if (haveRobustness && haveContextPriority) {
148 auto robustCorePriority = std::make_unique<EglContextAttributeBuilder>();
149 robustCorePriority->setVersion(3, 1);
150 robustCorePriority->setRobust(
true);
151 robustCorePriority->setHighPriority(
true);
152 candidates.push_back(std::move(robustCorePriority));
154 if (haveRobustness) {
155 auto robustCore = std::make_unique<EglContextAttributeBuilder>();
156 robustCore->setVersion(3, 1);
157 robustCore->setRobust(
true);
158 candidates.push_back(std::move(robustCore));
160 if (haveContextPriority) {
161 auto corePriority = std::make_unique<EglContextAttributeBuilder>();
162 corePriority->setVersion(3, 1);
163 corePriority->setHighPriority(
true);
164 candidates.push_back(std::move(corePriority));
166 auto core = std::make_unique<EglContextAttributeBuilder>();
167 core->setVersion(3, 1);
168 candidates.push_back(std::move(core));
170 if (haveRobustness && haveCreateContext && haveContextPriority) {
171 auto robustPriority = std::make_unique<EglContextAttributeBuilder>();
172 robustPriority->setRobust(
true);
173 robustPriority->setHighPriority(
true);
174 candidates.push_back(std::move(robustPriority));
176 if (haveRobustness && haveCreateContext) {
177 auto robust = std::make_unique<EglContextAttributeBuilder>();
178 robust->setRobust(
true);
179 candidates.push_back(std::move(robust));
181 candidates.emplace_back(
new EglContextAttributeBuilder);
184 for (
const auto &candidate : candidates) {
185 const auto attribs = candidate->build();
186 ::EGLContext ctx = eglCreateContext(display->
handle(),
config, sharedContext, attribs.data());
187 if (ctx != EGL_NO_CONTEXT) {
188 qCDebug(KWIN_OPENGL) <<
"Created EGL context with attributes:" << candidate.get();
192 qCCritical(KWIN_OPENGL) <<
"Create Context failed" << getEglErrorString();
193 return EGL_NO_CONTEXT;
199 if (image != EGL_NO_IMAGE_KHR) {
203 qCWarning(KWIN_OPENGL) <<
"Error creating EGLImageKHR: " << getEglErrorString();
210 return m_shaderManager.get();
bool makeCurrent(EGLSurface surface=EGL_NO_SURFACE) const
::EGLContext handle() const
EglDisplay * displayObject() const
EglContext(EglDisplay *display, EGLConfig config, ::EGLContext context)
std::shared_ptr< GLTexture > importDmaBufAsTexture(const DmaBufAttributes &attributes) const
ShaderManager * shaderManager() const
static std::unique_ptr< EglContext > create(EglDisplay *display, EGLConfig config, ::EGLContext sharedContext)
bool hasExtension(const QByteArray &name) const
EGLImageKHR importDmaBufAsImage(const DmaBufAttributes &dmabuf) const
bool isExternalOnly(uint32_t format, uint64_t modifier) const
::EGLDisplay handle() const
bool hasOpenglExtension(QByteArrayView name) const