glx: Fix the swap event filter for DRI3 drivers
The drawable field is set to the X drawable ID when the swap event is synthesized by DRI2WireToEvent(), and the GLX drawable ID when the event is received over the wire. The latter being the case with DRI3. __glXWireToEvent() fixes this for Xlib clients by changing the field to the X drawable ID. This doesn't work for xcb clients however, so we have to expect the field to be set to either the X or the GLX drawable ID. BUG: 342582
This commit is contained in:
parent
9fe660ac5c
commit
301a996563
2 changed files with 11 additions and 6 deletions
|
@ -41,7 +41,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#include <QOpenGLContext>
|
#include <QOpenGLContext>
|
||||||
// system
|
// system
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <xcb/glx.h>
|
|
||||||
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
@ -79,9 +78,10 @@ namespace std {
|
||||||
namespace KWin
|
namespace KWin
|
||||||
{
|
{
|
||||||
|
|
||||||
SwapEventFilter::SwapEventFilter(xcb_drawable_t drawable)
|
SwapEventFilter::SwapEventFilter(xcb_drawable_t drawable, xcb_glx_drawable_t glxDrawable)
|
||||||
: X11EventFilter(Xcb::Extensions::self()->glxEventBase() + XCB_GLX_BUFFER_SWAP_COMPLETE),
|
: X11EventFilter(Xcb::Extensions::self()->glxEventBase() + XCB_GLX_BUFFER_SWAP_COMPLETE),
|
||||||
m_drawable(drawable)
|
m_drawable(drawable),
|
||||||
|
m_glxDrawable(glxDrawable)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +90,10 @@ bool SwapEventFilter::event(xcb_generic_event_t *event)
|
||||||
xcb_glx_buffer_swap_complete_event_t *ev =
|
xcb_glx_buffer_swap_complete_event_t *ev =
|
||||||
reinterpret_cast<xcb_glx_buffer_swap_complete_event_t *>(event);
|
reinterpret_cast<xcb_glx_buffer_swap_complete_event_t *>(event);
|
||||||
|
|
||||||
if (ev->drawable == m_drawable) {
|
// The drawable field is the X drawable when the event was synthesized
|
||||||
|
// by a WireToEvent handler, and the GLX drawable when the event was
|
||||||
|
// received over the wire
|
||||||
|
if (ev->drawable == m_drawable || ev->drawable == m_glxDrawable) {
|
||||||
Compositor::self()->bufferSwapComplete();
|
Compositor::self()->bufferSwapComplete();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -192,7 +195,7 @@ void GlxBackend::init()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_haveINTELSwapEvent) {
|
if (m_haveINTELSwapEvent) {
|
||||||
m_swapEventFilter = std::make_unique<SwapEventFilter>(window);
|
m_swapEventFilter = std::make_unique<SwapEventFilter>(window, glxWindow);
|
||||||
glXSelectEvent(display(), glxWindow, GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK);
|
glXSelectEvent(display(), glxWindow, GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#include "scene_opengl.h"
|
#include "scene_opengl.h"
|
||||||
#include "x11eventfilter.h"
|
#include "x11eventfilter.h"
|
||||||
|
|
||||||
|
#include <xcb/glx.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace KWin
|
namespace KWin
|
||||||
|
@ -44,11 +45,12 @@ public:
|
||||||
class SwapEventFilter : public X11EventFilter
|
class SwapEventFilter : public X11EventFilter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SwapEventFilter(xcb_drawable_t drawable);
|
SwapEventFilter(xcb_drawable_t drawable, xcb_glx_drawable_t glxDrawable);
|
||||||
bool event(xcb_generic_event_t *event) override;
|
bool event(xcb_generic_event_t *event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
xcb_drawable_t m_drawable;
|
xcb_drawable_t m_drawable;
|
||||||
|
xcb_glx_drawable_t m_glxDrawable;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue