Changeset View
Changeset View
Standalone View
Standalone View
plugins/platforms/x11/standalone/glxbackend.cpp
Show All 19 Lines | |||||
20 | 20 | | |||
21 | You should have received a copy of the GNU General Public License | 21 | You should have received a copy of the GNU General Public License | ||
22 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 22 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
23 | *********************************************************************/ | 23 | *********************************************************************/ | ||
24 | 24 | | |||
25 | // own | 25 | // own | ||
26 | #include "glxbackend.h" | 26 | #include "glxbackend.h" | ||
27 | #include "logging.h" | 27 | #include "logging.h" | ||
28 | #include "glx_context_attribute_builder.h" | ||||
28 | // kwin | 29 | // kwin | ||
29 | #include "options.h" | 30 | #include "options.h" | ||
30 | #include "overlaywindow.h" | 31 | #include "overlaywindow.h" | ||
31 | #include "composite.h" | 32 | #include "composite.h" | ||
32 | #include "screens.h" | 33 | #include "screens.h" | ||
33 | #include "xcbutils.h" | 34 | #include "xcbutils.h" | ||
34 | // kwin libs | 35 | // kwin libs | ||
35 | #include <kwinglplatform.h> | 36 | #include <kwinglplatform.h> | ||
Show All 23 Lines | 53 | typedef struct xcb_glx_buffer_swap_complete_event_t { | |||
59 | uint32_t ust_hi; /**< */ | 60 | uint32_t ust_hi; /**< */ | ||
60 | uint32_t ust_lo; /**< */ | 61 | uint32_t ust_lo; /**< */ | ||
61 | uint32_t msc_hi; /**< */ | 62 | uint32_t msc_hi; /**< */ | ||
62 | uint32_t msc_lo; /**< */ | 63 | uint32_t msc_lo; /**< */ | ||
63 | uint32_t sbc; /**< */ | 64 | uint32_t sbc; /**< */ | ||
64 | } xcb_glx_buffer_swap_complete_event_t; | 65 | } xcb_glx_buffer_swap_complete_event_t; | ||
65 | #endif | 66 | #endif | ||
66 | 67 | | |||
67 | #ifndef GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV | | |||
68 | #define GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x20F7 | | |||
69 | #endif | | |||
70 | | ||||
71 | #include <tuple> | 68 | #include <tuple> | ||
72 | 69 | | |||
73 | #if __cplusplus <= 201103L | 70 | #if __cplusplus <= 201103L | ||
74 | namespace std { | 71 | namespace std { | ||
75 | // C++-14 | 72 | // C++-14 | ||
76 | template<class T, class... Args> | 73 | template<class T, class... Args> | ||
77 | unique_ptr<T> make_unique(Args&&... args) { | 74 | unique_ptr<T> make_unique(Args&&... args) { | ||
78 | return unique_ptr<T>(new T(std::forward<Args>(args)...)); | 75 | return unique_ptr<T>(new T(std::forward<Args>(args)...)); | ||
▲ Show 20 Lines • Show All 213 Lines • ▼ Show 20 Line(s) | |||||
292 | } | 289 | } | ||
293 | 290 | | |||
294 | bool GlxBackend::initRenderingContext() | 291 | bool GlxBackend::initRenderingContext() | ||
295 | { | 292 | { | ||
296 | const bool direct = true; | 293 | const bool direct = true; | ||
297 | 294 | | |||
298 | // Use glXCreateContextAttribsARB() when it's available | 295 | // Use glXCreateContextAttribsARB() when it's available | ||
299 | if (hasExtension(QByteArrayLiteral("GLX_ARB_create_context"))) { | 296 | if (hasExtension(QByteArrayLiteral("GLX_ARB_create_context"))) { | ||
300 | const int attribs_31_core_nv_robustness[] = { | | |||
301 | GLX_CONTEXT_MAJOR_VERSION_ARB, 3, | | |||
302 | GLX_CONTEXT_MINOR_VERSION_ARB, 1, | | |||
303 | GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB, | | |||
304 | GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, GLX_LOSE_CONTEXT_ON_RESET_ARB, | | |||
305 | GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV, GL_TRUE, | | |||
306 | 0 | | |||
307 | }; | | |||
308 | | ||||
309 | const int attribs_31_core_robustness[] = { | | |||
310 | GLX_CONTEXT_MAJOR_VERSION_ARB, 3, | | |||
311 | GLX_CONTEXT_MINOR_VERSION_ARB, 1, | | |||
312 | GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB, | | |||
313 | GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, GLX_LOSE_CONTEXT_ON_RESET_ARB, | | |||
314 | 0 | | |||
315 | }; | | |||
316 | | ||||
317 | const int attribs_31_core[] = { | | |||
318 | GLX_CONTEXT_MAJOR_VERSION_ARB, 3, | | |||
319 | GLX_CONTEXT_MINOR_VERSION_ARB, 1, | | |||
320 | 0 | | |||
321 | }; | | |||
322 | | ||||
323 | const int attribs_legacy_nv_robustness[] = { | | |||
324 | GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB, | | |||
325 | GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, GLX_LOSE_CONTEXT_ON_RESET_ARB, | | |||
326 | GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV, GL_TRUE, | | |||
327 | 0 | | |||
328 | }; | | |||
329 | | ||||
330 | const int attribs_legacy_robustness[] = { | | |||
331 | GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB, | | |||
332 | GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, GLX_LOSE_CONTEXT_ON_RESET_ARB, | | |||
333 | 0 | | |||
334 | }; | | |||
335 | | ||||
336 | const int attribs_legacy[] = { | | |||
337 | GLX_CONTEXT_MAJOR_VERSION_ARB, 2, | | |||
338 | GLX_CONTEXT_MINOR_VERSION_ARB, 1, | | |||
339 | 0 | | |||
340 | }; | | |||
341 | | ||||
342 | const bool have_robustness = hasExtension(QByteArrayLiteral("GLX_ARB_create_context_robustness")); | 297 | const bool have_robustness = hasExtension(QByteArrayLiteral("GLX_ARB_create_context_robustness")); | ||
343 | const bool haveVideoMemoryPurge = hasExtension(QByteArrayLiteral("GLX_NV_robustness_video_memory_purge")); | 298 | const bool haveVideoMemoryPurge = hasExtension(QByteArrayLiteral("GLX_NV_robustness_video_memory_purge")); | ||
344 | 299 | | |||
345 | // Try to create a 3.1 context first | 300 | std::vector<GlxContextAttributeBuilder> candidates; | ||
346 | if (options->glCoreProfile()) { | 301 | if (options->glCoreProfile()) { | ||
347 | if (have_robustness) { | 302 | if (have_robustness) { | ||
348 | if (haveVideoMemoryPurge) { | 303 | if (haveVideoMemoryPurge) { | ||
349 | ctx = glXCreateContextAttribsARB(display(), fbconfig, 0, direct, attribs_31_core_nv_robustness); | 304 | GlxContextAttributeBuilder purgeMemoryCore; | ||
350 | } | 305 | purgeMemoryCore.setVersion(3, 1); | ||
351 | if (!ctx) { | 306 | purgeMemoryCore.setRobust(true); | ||
352 | ctx = glXCreateContextAttribsARB(display(), fbconfig, 0, direct, attribs_31_core_robustness); | 307 | purgeMemoryCore.setResetOnVideoMemoryPurge(true); | ||
353 | } | 308 | candidates.emplace_back(std::move(purgeMemoryCore)); | ||
354 | } | 309 | } | ||
355 | 310 | GlxContextAttributeBuilder robustCore; | |||
356 | if (!ctx) | 311 | robustCore.setVersion(3, 1); | ||
357 | ctx = glXCreateContextAttribsARB(display(), fbconfig, 0, direct, attribs_31_core); | 312 | robustCore.setRobust(true); | ||
358 | } | 313 | candidates.emplace_back(std::move(robustCore)); | ||
359 | 314 | } | |||
360 | if (!ctx && have_robustness) { | 315 | GlxContextAttributeBuilder core; | ||
316 | core.setVersion(3, 1); | ||||
317 | candidates.emplace_back(std::move(core)); | ||||
318 | } else { | ||||
319 | if (have_robustness) { | ||||
361 | if (haveVideoMemoryPurge) { | 320 | if (haveVideoMemoryPurge) { | ||
362 | ctx = glXCreateContextAttribsARB(display(), fbconfig, 0, direct, attribs_legacy_nv_robustness); | 321 | GlxContextAttributeBuilder purgeMemoryLegacy; | ||
363 | } | 322 | purgeMemoryLegacy.setRobust(true); | ||
364 | if (!ctx) { | 323 | purgeMemoryLegacy.setResetOnVideoMemoryPurge(true); | ||
365 | ctx = glXCreateContextAttribsARB(display(), fbconfig, 0, direct, attribs_legacy_robustness); | 324 | candidates.emplace_back(std::move(purgeMemoryLegacy)); | ||
325 | } | ||||
326 | GlxContextAttributeBuilder robustLegacy; | ||||
327 | robustLegacy.setRobust(true); | ||||
328 | candidates.emplace_back(std::move(robustLegacy)); | ||||
329 | } | ||||
330 | GlxContextAttributeBuilder legacy; | ||||
331 | legacy.setVersion(2, 1); | ||||
332 | candidates.emplace_back(std::move(legacy)); | ||||
333 | } | ||||
334 | for (auto it = candidates.begin(); it != candidates.end(); it++) { | ||||
335 | const auto attribs = it->build(); | ||||
336 | ctx = glXCreateContextAttribsARB(display(), fbconfig, 0, true, attribs.data()); | ||||
337 | if (ctx) { | ||||
338 | qCDebug(KWIN_X11STANDALONE) << "Created GLX context with attributes:" << &(*it); | ||||
339 | break; | ||||
366 | } | 340 | } | ||
367 | } | 341 | } | ||
368 | | ||||
369 | if (!ctx) | | |||
370 | ctx = glXCreateContextAttribsARB(display(), fbconfig, 0, direct, attribs_legacy); | | |||
371 | } | 342 | } | ||
372 | 343 | | |||
373 | if (!ctx) | 344 | if (!ctx) | ||
374 | ctx = glXCreateNewContext(display(), fbconfig, GLX_RGBA_TYPE, NULL, direct); | 345 | ctx = glXCreateNewContext(display(), fbconfig, GLX_RGBA_TYPE, NULL, direct); | ||
375 | 346 | | |||
376 | if (!ctx) { | 347 | if (!ctx) { | ||
377 | qCDebug(KWIN_X11STANDALONE) << "Failed to create an OpenGL context."; | 348 | qCDebug(KWIN_X11STANDALONE) << "Failed to create an OpenGL context."; | ||
378 | return false; | 349 | return false; | ||
▲ Show 20 Lines • Show All 575 Lines • Show Last 20 Lines |