mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-25 06:47:19 +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
|
||||
xinerama
|
||||
xcursor
|
||||
xpresent
|
||||
)
|
||||
|
||||
add_library(displayserver_X11 STATIC
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <X11/extensions/XInput2.h>
|
||||
#include <X11/extensions/scrnsaver.h>
|
||||
#include <X11/extensions/Xinerama.h>
|
||||
#include <X11/extensions/Xpresent.h>
|
||||
#include <X11/Xcursor/Xcursor.h>
|
||||
|
||||
#include <GL/glx.h>
|
||||
@ -45,6 +46,7 @@
|
||||
#include "app.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/time.h"
|
||||
#include "common/event.h"
|
||||
#include "util.h"
|
||||
|
||||
#define _NET_WM_STATE_REMOVE 0
|
||||
@ -77,7 +79,32 @@ enum {
|
||||
// forwards
|
||||
static void x11SetFullscreen(bool fs);
|
||||
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)
|
||||
{
|
||||
@ -487,15 +514,24 @@ static bool x11Init(const LG_DSInitParams params)
|
||||
/* default to the square cursor */
|
||||
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);
|
||||
XFlush(x11.display);
|
||||
|
||||
if (!lgCreateThread("X11EventThread", x11EventThread, NULL, &x11.eventThread))
|
||||
{
|
||||
DEBUG_ERROR("Failed to create the x11 event thread");
|
||||
return false;
|
||||
goto fail_window;
|
||||
}
|
||||
|
||||
x11DoPresent();
|
||||
|
||||
return true;
|
||||
|
||||
fail_window:
|
||||
@ -513,11 +549,13 @@ static void x11Startup(void)
|
||||
|
||||
static void x11Shutdown(void)
|
||||
{
|
||||
lgSignalEvent(x11.frameEvent);
|
||||
}
|
||||
|
||||
static void x11Free(void)
|
||||
{
|
||||
lgJoinThread(x11.eventThread, NULL);
|
||||
lgFreeEvent(x11.frameEvent);
|
||||
|
||||
if (x11.window)
|
||||
XDestroyWindow(x11.display, x11.window);
|
||||
@ -667,9 +705,18 @@ static int x11EventThread(void * unused)
|
||||
case GenericEvent:
|
||||
{
|
||||
XGenericEventCookie *cookie = (XGenericEventCookie*)&xe.xcookie;
|
||||
XGetEventData(x11.display, cookie);
|
||||
x11GenericEvent(cookie);
|
||||
XFreeEventData(x11.display, cookie);
|
||||
if (cookie->extension == x11.xinputOp)
|
||||
{
|
||||
XGetEventData(x11.display, cookie);
|
||||
x11XInputEvent(cookie);
|
||||
XFreeEventData(x11.display, cookie);
|
||||
}
|
||||
else if (cookie->extension == x11.xpresentOp)
|
||||
{
|
||||
XGetEventData(x11.display, cookie);
|
||||
x11XPresentEvent(cookie);
|
||||
XFreeEventData(x11.display, cookie);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -737,13 +784,10 @@ static int x11EventThread(void * unused)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void x11GenericEvent(XGenericEventCookie *cookie)
|
||||
static void x11XInputEvent(XGenericEventCookie *cookie)
|
||||
{
|
||||
static int button_state = 0;
|
||||
|
||||
if (cookie->extension != x11.xinputOp)
|
||||
return;
|
||||
|
||||
switch(cookie->evtype)
|
||||
{
|
||||
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
|
||||
static EGLDisplay x11GetEGLDisplay(void)
|
||||
{
|
||||
@ -1056,6 +1145,16 @@ static void x11GLSwapBuffers(void)
|
||||
}
|
||||
#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)
|
||||
{
|
||||
if (app_isCaptureMode() || !x11.entered)
|
||||
@ -1332,6 +1431,8 @@ struct LG_DisplayServerOps LGDS_X11 =
|
||||
.glSetSwapInterval = x11GLSetSwapInterval,
|
||||
.glSwapBuffers = x11GLSwapBuffers,
|
||||
#endif
|
||||
.waitFrame = x11WaitFrame,
|
||||
.stopWaitFrame = x11StopWaitFrame,
|
||||
.guestPointerUpdated = x11GuestPointerUpdated,
|
||||
.setPointer = x11SetPointer,
|
||||
.grabPointer = x11GrabPointer,
|
||||
|
@ -21,20 +21,30 @@
|
||||
#ifndef _H_X11DS_X11_
|
||||
#define _H_X11DS_X11_
|
||||
|
||||
#include <stdatomic.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
#include <GL/glx.h>
|
||||
|
||||
#include "interface/displayserver.h"
|
||||
#include "common/thread.h"
|
||||
#include "common/types.h"
|
||||
#include "common/runningavg.h"
|
||||
|
||||
struct X11DSState
|
||||
{
|
||||
Display * display;
|
||||
Window window;
|
||||
XVisualInfo * visual;
|
||||
int xinputOp;
|
||||
int xinputOp, xpresentOp;
|
||||
|
||||
uint32_t presentSerial;
|
||||
Pixmap presentPixmap;
|
||||
RunningAvg presentAvg;
|
||||
LGEvent * frameEvent;
|
||||
|
||||
LGThread * eventThread;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user