mirror of
https://github.com/gnif/LookingGlass.git
synced 2025-04-26 00:26:32 +00:00
[client] x11: make use of the x11 present extension for jitRender
This implementation is a bit dodgy and needs some work but is currently functional. Consider this feature highly experiemental under X11.
This commit is contained in:
parent
037788f562
commit
891ee3e789
@ -9,6 +9,7 @@ pkg_check_modules(DISPLAYSERVER_X11 REQUIRED IMPORTED_TARGET
|
|||||||
xscrnsaver
|
xscrnsaver
|
||||||
xinerama
|
xinerama
|
||||||
xcursor
|
xcursor
|
||||||
|
xpresent
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(displayserver_X11 STATIC
|
add_library(displayserver_X11 STATIC
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include <X11/extensions/XInput2.h>
|
#include <X11/extensions/XInput2.h>
|
||||||
#include <X11/extensions/scrnsaver.h>
|
#include <X11/extensions/scrnsaver.h>
|
||||||
#include <X11/extensions/Xinerama.h>
|
#include <X11/extensions/Xinerama.h>
|
||||||
|
#include <X11/extensions/Xpresent.h>
|
||||||
#include <X11/Xcursor/Xcursor.h>
|
#include <X11/Xcursor/Xcursor.h>
|
||||||
|
|
||||||
#include <GL/glx.h>
|
#include <GL/glx.h>
|
||||||
@ -45,6 +46,7 @@
|
|||||||
#include "app.h"
|
#include "app.h"
|
||||||
#include "common/debug.h"
|
#include "common/debug.h"
|
||||||
#include "common/time.h"
|
#include "common/time.h"
|
||||||
|
#include "common/event.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
#define _NET_WM_STATE_REMOVE 0
|
#define _NET_WM_STATE_REMOVE 0
|
||||||
@ -77,7 +79,32 @@ enum {
|
|||||||
// forwards
|
// forwards
|
||||||
static void x11SetFullscreen(bool fs);
|
static void x11SetFullscreen(bool fs);
|
||||||
static int x11EventThread(void * unused);
|
static int x11EventThread(void * unused);
|
||||||
static void x11GenericEvent(XGenericEventCookie *cookie);
|
static void x11XInputEvent(XGenericEventCookie *cookie);
|
||||||
|
static void x11XPresentEvent(XGenericEventCookie *cookie);
|
||||||
|
|
||||||
|
static void x11DoPresent(void)
|
||||||
|
{
|
||||||
|
XPresentPixmap(
|
||||||
|
x11.display,
|
||||||
|
x11.window,
|
||||||
|
x11.presentPixmap,
|
||||||
|
x11.presentSerial++,
|
||||||
|
0, // valid
|
||||||
|
0, // update
|
||||||
|
-1, // x_off,
|
||||||
|
-1, // y_off,
|
||||||
|
0, // target_crtc
|
||||||
|
None, // wait_fence
|
||||||
|
None, // idle_fence
|
||||||
|
0, // options
|
||||||
|
0, // target_msc,
|
||||||
|
0, // divisor,
|
||||||
|
0, // remainder,
|
||||||
|
NULL, // notifies
|
||||||
|
0 // nnotifies
|
||||||
|
);
|
||||||
|
XFlush(x11.display);
|
||||||
|
}
|
||||||
|
|
||||||
static void x11Setup(void)
|
static void x11Setup(void)
|
||||||
{
|
{
|
||||||
@ -487,15 +514,24 @@ static bool x11Init(const LG_DSInitParams params)
|
|||||||
/* default to the square cursor */
|
/* default to the square cursor */
|
||||||
XDefineCursor(x11.display, x11.window, x11.cursors[LG_POINTER_SQUARE]);
|
XDefineCursor(x11.display, x11.window, x11.cursors[LG_POINTER_SQUARE]);
|
||||||
|
|
||||||
|
x11.frameEvent = lgCreateEvent(true, 0);
|
||||||
|
|
||||||
|
x11.presentAvg = runningavg_new(1000);
|
||||||
|
XPresentQueryExtension(x11.display, &x11.xpresentOp, &event, &error);
|
||||||
|
x11.presentPixmap = XCreatePixmap(x11.display, x11.window, 1, 1, 24);
|
||||||
|
XPresentSelectInput(x11.display, x11.window,
|
||||||
|
PresentCompleteNotifyMask | PresentIdleNotifyMask);
|
||||||
XMapWindow(x11.display, x11.window);
|
XMapWindow(x11.display, x11.window);
|
||||||
XFlush(x11.display);
|
XFlush(x11.display);
|
||||||
|
|
||||||
if (!lgCreateThread("X11EventThread", x11EventThread, NULL, &x11.eventThread))
|
if (!lgCreateThread("X11EventThread", x11EventThread, NULL, &x11.eventThread))
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("Failed to create the x11 event thread");
|
DEBUG_ERROR("Failed to create the x11 event thread");
|
||||||
return false;
|
goto fail_window;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
x11DoPresent();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
fail_window:
|
fail_window:
|
||||||
@ -513,11 +549,13 @@ static void x11Startup(void)
|
|||||||
|
|
||||||
static void x11Shutdown(void)
|
static void x11Shutdown(void)
|
||||||
{
|
{
|
||||||
|
lgSignalEvent(x11.frameEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void x11Free(void)
|
static void x11Free(void)
|
||||||
{
|
{
|
||||||
lgJoinThread(x11.eventThread, NULL);
|
lgJoinThread(x11.eventThread, NULL);
|
||||||
|
lgFreeEvent(x11.frameEvent);
|
||||||
|
|
||||||
if (x11.window)
|
if (x11.window)
|
||||||
XDestroyWindow(x11.display, x11.window);
|
XDestroyWindow(x11.display, x11.window);
|
||||||
@ -667,9 +705,18 @@ static int x11EventThread(void * unused)
|
|||||||
case GenericEvent:
|
case GenericEvent:
|
||||||
{
|
{
|
||||||
XGenericEventCookie *cookie = (XGenericEventCookie*)&xe.xcookie;
|
XGenericEventCookie *cookie = (XGenericEventCookie*)&xe.xcookie;
|
||||||
|
if (cookie->extension == x11.xinputOp)
|
||||||
|
{
|
||||||
XGetEventData(x11.display, cookie);
|
XGetEventData(x11.display, cookie);
|
||||||
x11GenericEvent(cookie);
|
x11XInputEvent(cookie);
|
||||||
XFreeEventData(x11.display, cookie);
|
XFreeEventData(x11.display, cookie);
|
||||||
|
}
|
||||||
|
else if (cookie->extension == x11.xpresentOp)
|
||||||
|
{
|
||||||
|
XGetEventData(x11.display, cookie);
|
||||||
|
x11XPresentEvent(cookie);
|
||||||
|
XFreeEventData(x11.display, cookie);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -737,13 +784,10 @@ static int x11EventThread(void * unused)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void x11GenericEvent(XGenericEventCookie *cookie)
|
static void x11XInputEvent(XGenericEventCookie *cookie)
|
||||||
{
|
{
|
||||||
static int button_state = 0;
|
static int button_state = 0;
|
||||||
|
|
||||||
if (cookie->extension != x11.xinputOp)
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch(cookie->evtype)
|
switch(cookie->evtype)
|
||||||
{
|
{
|
||||||
case XI_FocusIn:
|
case XI_FocusIn:
|
||||||
@ -983,6 +1027,51 @@ static void x11GenericEvent(XGenericEventCookie *cookie)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
static void x11XPresentEvent(XGenericEventCookie *cookie)
|
||||||
|
{
|
||||||
|
switch(cookie->evtype)
|
||||||
|
{
|
||||||
|
case PresentCompleteNotify:
|
||||||
|
{
|
||||||
|
lgSignalEvent(x11.frameEvent);
|
||||||
|
x11DoPresent();
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
static uint64_t last = 0;
|
||||||
|
static uint64_t predict = 0;
|
||||||
|
|
||||||
|
XPresentCompleteNotifyEvent * ev =
|
||||||
|
(XPresentCompleteNotifyEvent *)cookie->data;
|
||||||
|
|
||||||
|
const int64_t err = (int64_t)predict - ev->ust;
|
||||||
|
if (last)
|
||||||
|
{
|
||||||
|
const uint64_t delta = ev->ust - last;
|
||||||
|
runningavg_push(x11.presentAvg, delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG_WARN("predict err %f", err / 1000.0f);
|
||||||
|
|
||||||
|
predict = (ev->ust + round(runningavg_calc(x11.presentAvg)));
|
||||||
|
last = ev->ust;
|
||||||
|
XFlush(x11.display);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PresentIdleNotify:
|
||||||
|
{
|
||||||
|
XPresentIdleNotifyEvent * ev =
|
||||||
|
(XPresentIdleNotifyEvent *)cookie->data;
|
||||||
|
(void)ev;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_EGL
|
#ifdef ENABLE_EGL
|
||||||
static EGLDisplay x11GetEGLDisplay(void)
|
static EGLDisplay x11GetEGLDisplay(void)
|
||||||
{
|
{
|
||||||
@ -1056,6 +1145,16 @@ static void x11GLSwapBuffers(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void x11WaitFrame(void)
|
||||||
|
{
|
||||||
|
lgWaitEvent(x11.frameEvent, TIMEOUT_INFINITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void x11StopWaitFrame(void)
|
||||||
|
{
|
||||||
|
lgSignalEvent(x11.frameEvent);
|
||||||
|
}
|
||||||
|
|
||||||
static void x11GuestPointerUpdated(double x, double y, double localX, double localY)
|
static void x11GuestPointerUpdated(double x, double y, double localX, double localY)
|
||||||
{
|
{
|
||||||
if (app_isCaptureMode() || !x11.entered)
|
if (app_isCaptureMode() || !x11.entered)
|
||||||
@ -1332,6 +1431,8 @@ struct LG_DisplayServerOps LGDS_X11 =
|
|||||||
.glSetSwapInterval = x11GLSetSwapInterval,
|
.glSetSwapInterval = x11GLSetSwapInterval,
|
||||||
.glSwapBuffers = x11GLSwapBuffers,
|
.glSwapBuffers = x11GLSwapBuffers,
|
||||||
#endif
|
#endif
|
||||||
|
.waitFrame = x11WaitFrame,
|
||||||
|
.stopWaitFrame = x11StopWaitFrame,
|
||||||
.guestPointerUpdated = x11GuestPointerUpdated,
|
.guestPointerUpdated = x11GuestPointerUpdated,
|
||||||
.setPointer = x11SetPointer,
|
.setPointer = x11SetPointer,
|
||||||
.grabPointer = x11GrabPointer,
|
.grabPointer = x11GrabPointer,
|
||||||
|
@ -21,20 +21,30 @@
|
|||||||
#ifndef _H_X11DS_X11_
|
#ifndef _H_X11DS_X11_
|
||||||
#define _H_X11DS_X11_
|
#define _H_X11DS_X11_
|
||||||
|
|
||||||
|
#include <stdatomic.h>
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
|
|
||||||
|
#include <GL/glx.h>
|
||||||
|
|
||||||
#include "interface/displayserver.h"
|
#include "interface/displayserver.h"
|
||||||
#include "common/thread.h"
|
#include "common/thread.h"
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
|
#include "common/runningavg.h"
|
||||||
|
|
||||||
struct X11DSState
|
struct X11DSState
|
||||||
{
|
{
|
||||||
Display * display;
|
Display * display;
|
||||||
Window window;
|
Window window;
|
||||||
XVisualInfo * visual;
|
XVisualInfo * visual;
|
||||||
int xinputOp;
|
int xinputOp, xpresentOp;
|
||||||
|
|
||||||
|
uint32_t presentSerial;
|
||||||
|
Pixmap presentPixmap;
|
||||||
|
RunningAvg presentAvg;
|
||||||
|
LGEvent * frameEvent;
|
||||||
|
|
||||||
LGThread * eventThread;
|
LGThread * eventThread;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user