[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [kwin] /: Add support for GLX_INTEL_swap_event
From: Fredrik_Höglund <fredrik () kde ! org>
Date: 2014-09-18 18:26:33
Message-ID: E1XUgPZ-0006Cb-8I () scm ! kde ! org
[Download RAW message or body]
Git commit ad0abdc81286ce6db94f735935e304c65afdf17d by Fredrik Höglund.
Committed on 07/08/2014 at 12:16.
Pushed by fredrik into branch 'master'.
Add support for GLX_INTEL_swap_event
Enable swap events and use them to defer rendering of the next frame
until the last glXSwapBuffers() call has completed.
M +57 -0 glxbackend.cpp
M +20 -0 glxbackend.h
http://commits.kde.org/kwin/ad0abdc81286ce6db94f735935e304c65afdf17d
diff --git a/glxbackend.cpp b/glxbackend.cpp
index d2b5af0..def6e9f 100644
--- a/glxbackend.cpp
+++ b/glxbackend.cpp
@@ -30,6 +30,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "options.h"
#include "utils.h"
#include "overlaywindow.h"
+#include "composite.h"
+#include "xcbutils.h"
// kwin libs
#include <kwinglplatform.h>
#include <kwinxrenderutils.h>
@@ -38,11 +40,48 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <QOpenGLContext>
// system
#include <unistd.h>
+#include <xcb/glx.h>
#include <tuple>
+#if __cplusplus <= 201103L
+namespace std {
+ // C++-14
+ template<class T, class... Args>
+ unique_ptr<T> make_unique(Args&&... args) {
+ return unique_ptr<T>(new T(std::forward<Args>(args)...));
+ }
+}
+#endif
+
+
namespace KWin
{
+
+SwapEventFilter::SwapEventFilter(xcb_drawable_t drawable)
+ : X11EventFilter(Xcb::Extensions::self()->glxEventBase() + XCB_GLX_BUFFER_SWAP_COMPLETE),
+ m_drawable(drawable)
+{
+}
+
+bool SwapEventFilter::event(xcb_generic_event_t *event)
+{
+ xcb_glx_buffer_swap_complete_event_t *ev =
+ reinterpret_cast<xcb_glx_buffer_swap_complete_event_t *>(event);
+
+ if (ev->drawable == m_drawable) {
+ Compositor::self()->bufferSwapComplete();
+ return true;
+ }
+
+ return false;
+}
+
+
+// -----------------------------------------------------------------------
+
+
+
GlxBackend::GlxBackend()
: OpenGLBackend()
, m_overlayWindow(new OverlayWindow())
@@ -116,6 +155,21 @@ void GlxBackend::init()
m_haveMESASwapControl = hasGLExtension(QByteArrayLiteral("GLX_MESA_swap_control"));
m_haveEXTSwapControl = hasGLExtension(QByteArrayLiteral("GLX_EXT_swap_control"));
m_haveSGISwapControl = hasGLExtension(QByteArrayLiteral("GLX_SGI_swap_control"));
+ m_haveINTELSwapEvent = hasGLExtension(QByteArrayLiteral("GLX_INTEL_swap_event"));
+
+ if (m_haveINTELSwapEvent) {
+ const QList<QByteArray> tokens = QByteArray(qVersion()).split('.');
+ uint32_t version = tokens[0].toInt() << 16 | tokens[1].toInt() << 8 | tokens[2].toInt();
+
+ // Qt 5.3 doesn't forward swap events to the native event filter
+ if (version < 0x00050400)
+ m_haveINTELSwapEvent = false;
+ }
+
+ if (m_haveINTELSwapEvent) {
+ m_swapEventFilter = std::make_unique<SwapEventFilter>(window);
+ glXSelectEvent(display(), glxWindow, GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK);
+ }
haveSwapInterval = m_haveMESASwapControl || m_haveEXTSwapControl || m_haveSGISwapControl;
@@ -473,6 +527,9 @@ void GlxBackend::present()
const bool fullRepaint = supportsBufferAge() || (lastDamage() == displayRegion);
if (fullRepaint) {
+ if (m_haveINTELSwapEvent)
+ Compositor::self()->aboutToSwapBuffers();
+
if (haveSwapInterval) {
if (gs_tripleBufferNeedsDetection) {
glXWaitGL();
diff --git a/glxbackend.h b/glxbackend.h
index 4b49ae8..fba0a34 100644
--- a/glxbackend.h
+++ b/glxbackend.h
@@ -20,6 +20,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef KWIN_GLX_BACKEND_H
#define KWIN_GLX_BACKEND_H
#include "scene_opengl.h"
+#include "x11eventfilter.h"
+
+#include <memory>
namespace KWin
{
@@ -34,6 +37,21 @@ public:
int mipmap;
};
+
+// ------------------------------------------------------------------
+
+
+class SwapEventFilter : public X11EventFilter
+{
+public:
+ SwapEventFilter(xcb_drawable_t drawable);
+ bool event(xcb_generic_event_t *event) override;
+
+private:
+ xcb_drawable_t m_drawable;
+};
+
+
/**
* @brief OpenGL Backend using GLX over an X overlay window.
**/
@@ -76,11 +94,13 @@ private:
GLXContext ctx;
QHash<xcb_visualid_t, FBConfigInfo *> m_fbconfigHash;
QHash<xcb_visualid_t, int> m_visualDepthHash;
+ std::unique_ptr<SwapEventFilter> m_swapEventFilter;
int m_bufferAge;
bool m_haveMESACopySubBuffer;
bool m_haveMESASwapControl;
bool m_haveEXTSwapControl;
bool m_haveSGISwapControl;
+ bool m_haveINTELSwapEvent;
bool haveSwapInterval, haveWaitSync;
friend class GlxTexture;
};
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic