mirror of
https://gitlab.freedesktop.org/xorg/xserver.git
synced 2025-12-31 07:50:13 +01:00
Asynchronous reply processing using XCB and more efficient
sync batch processing.
This commit is contained in:
parent
e92aa7be90
commit
e43b271db3
9 changed files with 295 additions and 140 deletions
23
hw/dmx/dmx.h
23
hw/dmx/dmx.h
|
|
@ -71,6 +71,9 @@
|
|||
#include <GL/glxint.h>
|
||||
#endif
|
||||
|
||||
#include <xcb/xcb.h>
|
||||
#include <xcb/xcbext.h>
|
||||
|
||||
#include <X11/Xlib-xcb.h>
|
||||
|
||||
#include "dmxxlibio.h"
|
||||
|
|
@ -85,10 +88,15 @@ typedef enum {
|
|||
PosRelative
|
||||
} PositionType;
|
||||
|
||||
typedef struct _DMXIgnore {
|
||||
struct _DMXIgnore *next;
|
||||
unsigned long sequence;
|
||||
} DMXIgnore;
|
||||
typedef struct _DMXSequence {
|
||||
struct _DMXSequence *next;
|
||||
unsigned long sequence;
|
||||
} DMXSequence;
|
||||
|
||||
typedef struct _DMXQueue {
|
||||
DMXSequence *head;
|
||||
DMXSequence **tail;
|
||||
} DMXQueue;
|
||||
|
||||
typedef struct _DMXPropTrans {
|
||||
const char *name;
|
||||
|
|
@ -113,9 +121,10 @@ typedef struct _DMXScreenInfo {
|
|||
/*---------- Back-end X server information ----------*/
|
||||
|
||||
int fd;
|
||||
int inDispatch;
|
||||
|
||||
xcb_connection_t *connection;
|
||||
xcb_get_input_focus_cookie_t syncCookie;
|
||||
xcb_get_input_focus_cookie_t sync;
|
||||
|
||||
Display *beDisplay; /**< Back-end X server's display */
|
||||
int beWidth; /**< Width of BE display */
|
||||
|
|
@ -217,8 +226,8 @@ typedef struct _DMXScreenInfo {
|
|||
DMXStatInfo *stat; /**< Statistics about XSync */
|
||||
Bool needsSync; /**< True if an XSync is pending */
|
||||
|
||||
DMXIgnore *ignoreHead;
|
||||
DMXIgnore **ignoreTail;
|
||||
DMXQueue ignore;
|
||||
DMXQueue request;
|
||||
|
||||
#ifdef GLXEXT
|
||||
/** Visual information for glxProxy */
|
||||
|
|
|
|||
|
|
@ -1192,7 +1192,7 @@ static void dmxBECreateWindowTree(int idx)
|
|||
#endif
|
||||
|
||||
XLIB_PROLOGUE (dmxScreen);
|
||||
dmxSetIgnore (dmxScreen, NextRequest (dmxScreen->beDisplay));
|
||||
dmxAddSequence (&dmxScreen->ignore, NextRequest (dmxScreen->beDisplay));
|
||||
XMapWindow(dmxScreen->beDisplay, dmxScreen->rootWin);
|
||||
XLIB_EPILOGUE (dmxScreen);
|
||||
|
||||
|
|
@ -2547,7 +2547,5 @@ int dmxDetachScreen(int idx)
|
|||
RRGetInfo (screenInfo.screens[0]);
|
||||
#endif
|
||||
|
||||
dmxDiscardIgnore (dmxScreen, ~0);
|
||||
|
||||
return 0; /* Success */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -295,12 +295,13 @@ Bool dmxOpenDisplay(DMXScreenInfo *dmxScreen)
|
|||
return FALSE;
|
||||
|
||||
dmxScreen->alive = 1;
|
||||
dmxScreen->inDispatch = FALSE;
|
||||
dmxScreen->fd = XConnectionNumber (dmxScreen->beDisplay);
|
||||
dmxScreen->connection = XGetXCBConnection (dmxScreen->beDisplay);
|
||||
|
||||
XSetEventQueueOwner (dmxScreen->beDisplay, XCBOwnsEventQueue);
|
||||
|
||||
dmxScreen->syncCookie.sequence = 0;
|
||||
dmxScreen->sync.sequence = 0;
|
||||
|
||||
AddEnabledDevice (dmxScreen->fd);
|
||||
|
||||
|
|
|
|||
|
|
@ -68,8 +68,6 @@ static jmp_buf jumpbuf;
|
|||
static char **xbeArgv = 0;
|
||||
static int nXbeArgv = 0;
|
||||
|
||||
static int xbePriority = 0;
|
||||
|
||||
static int
|
||||
dmxAddXbeArguments (char **argv,
|
||||
int n)
|
||||
|
|
|
|||
|
|
@ -315,6 +315,39 @@ dmxSetWindowPixmap (WindowPtr pWin, PixmapPtr pPixmap)
|
|||
DMX_WRAP(SetWindowPixmap, dmxSetWindowPixmap, dmxScreen, pScreen);
|
||||
}
|
||||
|
||||
static void
|
||||
dmxDiscardIgnore (DMXScreenInfo *dmxScreen,
|
||||
unsigned long sequence)
|
||||
{
|
||||
while (dmxScreen->ignore.head)
|
||||
{
|
||||
if ((long) (sequence - dmxScreen->ignore.head->sequence) > 0)
|
||||
{
|
||||
DMXSequence *next = dmxScreen->ignore.head->next;
|
||||
|
||||
free (dmxScreen->ignore.head);
|
||||
|
||||
dmxScreen->ignore.head = next;
|
||||
if (!dmxScreen->ignore.head)
|
||||
dmxScreen->ignore.tail = &dmxScreen->ignore.head;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static Bool
|
||||
dmxShouldIgnore (DMXScreenInfo *dmxScreen,
|
||||
unsigned long sequence)
|
||||
{
|
||||
dmxDiscardIgnore (dmxScreen, sequence);
|
||||
|
||||
if (!dmxScreen->ignore.head)
|
||||
return FALSE;
|
||||
|
||||
return dmxScreen->ignore.head->sequence == sequence;
|
||||
}
|
||||
|
||||
static Bool
|
||||
dmxScreenEventCheckExpose (ScreenPtr pScreen,
|
||||
xcb_generic_event_t *event)
|
||||
|
|
@ -712,8 +745,15 @@ dmxScreenEventCheckIgnore (ScreenPtr pScreen,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
dmxScreenReplyCheckIgnore (ScreenPtr pScreen,
|
||||
xcb_generic_reply_t *reply)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
dmxScreenCheckForError (ScreenPtr pScreen)
|
||||
dmxScreenCheckForIOError (ScreenPtr pScreen)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
|
||||
|
|
@ -723,7 +763,7 @@ dmxScreenCheckForError (ScreenPtr pScreen)
|
|||
|
||||
dmxScreen->alive = FALSE;
|
||||
|
||||
dmxLogOutput (dmxScreen, "Detect broken connection\n");
|
||||
dmxLogOutput (dmxScreen, "Detected broken connection\n");
|
||||
dmxDetachScreen (pScreen->myNum);
|
||||
|
||||
for (i = 0; i < dmxNumScreens; i++)
|
||||
|
|
@ -736,6 +776,69 @@ dmxScreenCheckForError (ScreenPtr pScreen)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
dmxBEDispatch (ScreenPtr pScreen)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
xcb_generic_event_t *event;
|
||||
xcb_generic_reply_t *reply;
|
||||
|
||||
dmxScreen->inDispatch = TRUE;
|
||||
|
||||
while ((event = xcb_poll_for_event (dmxScreen->connection)))
|
||||
{
|
||||
if (!dmxScreenEventCheckInput (pScreen, event) &&
|
||||
!dmxScreenEventCheckManageWindow (pScreen, event) &&
|
||||
!dmxScreenEventCheckExpose (pScreen, event) &&
|
||||
|
||||
#ifdef RANDR
|
||||
!dmxScreenEventCheckRR (pScreen, event) &&
|
||||
#endif
|
||||
|
||||
!dmxScreenEventCheckIgnore (pScreen, event))
|
||||
{
|
||||
dmxLogOutput (dmxScreen, "unhandled event type %d\n",
|
||||
event->response_type);
|
||||
}
|
||||
|
||||
free (event);
|
||||
}
|
||||
|
||||
while (dmxScreen->request.head &&
|
||||
xcb_poll_for_reply (dmxScreen->connection,
|
||||
dmxScreen->request.head->sequence,
|
||||
(void *) &reply,
|
||||
NULL))
|
||||
{
|
||||
DMXSequence *head = dmxScreen->request.head;
|
||||
|
||||
if (reply)
|
||||
{
|
||||
if (!dmxScreenReplyCheckSync (pScreen, reply) &&
|
||||
!dmxScreenReplyCheckIgnore (pScreen, reply))
|
||||
{
|
||||
dmxLogOutput (dmxScreen,
|
||||
"unhandled reply sequence %d\n",
|
||||
reply->sequence);
|
||||
}
|
||||
|
||||
free (reply);
|
||||
}
|
||||
else
|
||||
{
|
||||
dmxLogOutput (dmxScreen, "error sequence %d\n", head->sequence);
|
||||
}
|
||||
|
||||
dmxScreen->request.head = head->next;
|
||||
if (!dmxScreen->request.head)
|
||||
dmxScreen->request.tail = &dmxScreen->request.head;
|
||||
|
||||
free (head);
|
||||
}
|
||||
|
||||
dmxScreen->inDispatch = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
dmxScreenBlockHandler (pointer blockData,
|
||||
OSTimePtr pTimeout,
|
||||
|
|
@ -747,7 +850,7 @@ dmxScreenBlockHandler (pointer blockData,
|
|||
if (dmxScreen->beDisplay)
|
||||
{
|
||||
xcb_flush (dmxScreen->connection);
|
||||
dmxScreenCheckForError (pScreen);
|
||||
dmxScreenCheckForIOError (pScreen);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -760,28 +863,7 @@ dmxScreenWakeupHandler (pointer blockData,
|
|||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
|
||||
if (dmxScreen->beDisplay)
|
||||
{
|
||||
xcb_generic_event_t *event;
|
||||
|
||||
while ((event = xcb_poll_for_event (dmxScreen->connection)))
|
||||
{
|
||||
if (!dmxScreenEventCheckInput (pScreen, event) &&
|
||||
!dmxScreenEventCheckManageWindow (pScreen, event) &&
|
||||
!dmxScreenEventCheckExpose (pScreen, event) &&
|
||||
|
||||
#ifdef RANDR
|
||||
!dmxScreenEventCheckRR (pScreen, event) &&
|
||||
#endif
|
||||
|
||||
!dmxScreenEventCheckIgnore (pScreen, event))
|
||||
{
|
||||
dmxLogOutput (dmxScreen, "unhandled event type %d\n",
|
||||
event->response_type);
|
||||
}
|
||||
|
||||
free (event);
|
||||
}
|
||||
}
|
||||
dmxBEDispatch (pScreen);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -834,8 +916,11 @@ Bool dmxScreenInit(int idx, ScreenPtr pScreen, int argc, char *argv[])
|
|||
dmxGeneration = serverGeneration;
|
||||
}
|
||||
|
||||
dmxScreen->ignoreHead = NULL;
|
||||
dmxScreen->ignoreTail = &dmxScreen->ignoreHead;
|
||||
dmxScreen->ignore.head = NULL;
|
||||
dmxScreen->ignore.tail = &dmxScreen->ignore.head;
|
||||
|
||||
dmxScreen->request.head = NULL;
|
||||
dmxScreen->request.tail = &dmxScreen->request.head;
|
||||
|
||||
#ifdef RANDR
|
||||
dmxScreen->beRandr = FALSE;
|
||||
|
|
@ -1170,6 +1255,9 @@ void dmxBECloseScreen(ScreenPtr pScreen)
|
|||
/* Close display */
|
||||
dmxCloseDisplay (dmxScreen);
|
||||
dmxScreen->beDisplay = NULL;
|
||||
|
||||
dmxClearQueue (&dmxScreen->request);
|
||||
dmxClearQueue (&dmxScreen->ignore);
|
||||
}
|
||||
|
||||
/** Close screen number \a idx. */
|
||||
|
|
@ -1290,52 +1378,35 @@ static Bool dmxSaveScreen(ScreenPtr pScreen, int what)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
dmxDiscardIgnore (DMXScreenInfo *dmxScreen,
|
||||
unsigned long sequence)
|
||||
{
|
||||
while (dmxScreen->ignoreHead)
|
||||
{
|
||||
if ((long) (sequence - dmxScreen->ignoreHead->sequence) > 0)
|
||||
{
|
||||
DMXIgnore *next = dmxScreen->ignoreHead->next;
|
||||
|
||||
free (dmxScreen->ignoreHead);
|
||||
|
||||
dmxScreen->ignoreHead = next;
|
||||
if (!dmxScreen->ignoreHead)
|
||||
dmxScreen->ignoreTail = &dmxScreen->ignoreHead;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dmxSetIgnore (DMXScreenInfo *dmxScreen,
|
||||
unsigned long sequence)
|
||||
{
|
||||
DMXIgnore *i;
|
||||
|
||||
i = malloc (sizeof (DMXIgnore));
|
||||
if (!i)
|
||||
return;
|
||||
|
||||
i->sequence = sequence;
|
||||
i->next = 0;
|
||||
|
||||
*(dmxScreen->ignoreTail) = i;
|
||||
dmxScreen->ignoreTail = &i->next;
|
||||
}
|
||||
|
||||
Bool
|
||||
dmxShouldIgnore (DMXScreenInfo *dmxScreen,
|
||||
unsigned long sequence)
|
||||
dmxAddSequence (DMXQueue *q,
|
||||
unsigned long sequence)
|
||||
{
|
||||
dmxDiscardIgnore (dmxScreen, sequence);
|
||||
DMXSequence *s;
|
||||
|
||||
if (!dmxScreen->ignoreHead)
|
||||
s = malloc (sizeof (DMXSequence));
|
||||
if (!s)
|
||||
return FALSE;
|
||||
|
||||
return dmxScreen->ignoreHead->sequence == sequence;
|
||||
s->sequence = sequence;
|
||||
s->next = 0;
|
||||
|
||||
*(q->tail) = s;
|
||||
q->tail = &s->next;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
dmxClearQueue (DMXQueue *q)
|
||||
{
|
||||
while (q->head)
|
||||
{
|
||||
DMXSequence *head = q->head;
|
||||
|
||||
q->head = head->next;
|
||||
free (head);
|
||||
}
|
||||
|
||||
q->tail = &q->head;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,9 +47,9 @@ extern Bool dmxScreenInit(int idx, ScreenPtr pScreen, int argc, char *argv[]);
|
|||
|
||||
extern void dmxBEScreenInit(int idx, ScreenPtr pScreen);
|
||||
extern void dmxBECloseScreen(ScreenPtr pScreen);
|
||||
extern void dmxBEDispatch (ScreenPtr pScreen);
|
||||
|
||||
extern void dmxDiscardIgnore (DMXScreenInfo *dmxScreen, unsigned long sequence);
|
||||
extern void dmxSetIgnore (DMXScreenInfo *dmxScreen, unsigned long sequence);
|
||||
extern Bool dmxShouldIgnore (DMXScreenInfo *dmxScreen, unsigned long sequence);
|
||||
extern Bool dmxAddSequence (DMXQueue *q, unsigned long sequence);
|
||||
extern void dmxClearQueue (DMXQueue *q);
|
||||
|
||||
#endif /* DMXSCRINIT_H */
|
||||
|
|
|
|||
179
hw/dmx/dmxsync.c
179
hw/dmx/dmxsync.c
|
|
@ -55,42 +55,13 @@
|
|||
#include "dmxstat.h"
|
||||
#include "dmxlog.h"
|
||||
#include "dmxextension.h"
|
||||
#include "dmxscrinit.h"
|
||||
#include <sys/time.h>
|
||||
|
||||
static int dmxSyncInterval = 100; /* Default interval in milliseconds */
|
||||
static OsTimerPtr dmxSyncTimer;
|
||||
static int dmxSyncPending = 0;
|
||||
static int dmxSyncCookie = 0;
|
||||
|
||||
static void dmxWaitSync(DMXScreenInfo *dmxScreen)
|
||||
{
|
||||
if (dmxScreen->syncCookie.sequence)
|
||||
{
|
||||
if (dmxScreen->beDisplay)
|
||||
{
|
||||
if (!dmxStatInterval) {
|
||||
XLIB_PROLOGUE (dmxScreen);
|
||||
free (xcb_get_input_focus_reply (dmxScreen->connection,
|
||||
dmxScreen->syncCookie,
|
||||
NULL));
|
||||
XLIB_EPILOGUE (dmxScreen);
|
||||
} else {
|
||||
struct timeval start, stop;
|
||||
|
||||
gettimeofday(&start, 0);
|
||||
XLIB_PROLOGUE (dmxScreen);
|
||||
free (xcb_get_input_focus_reply (dmxScreen->connection,
|
||||
dmxScreen->syncCookie,
|
||||
NULL));
|
||||
XLIB_EPILOGUE (dmxScreen);
|
||||
gettimeofday(&stop, 0);
|
||||
dmxStatSync(dmxScreen, &stop, &start, dmxSyncPending);
|
||||
}
|
||||
}
|
||||
|
||||
dmxScreen->syncCookie.sequence = 0;
|
||||
}
|
||||
}
|
||||
static int dmxSyncRequest = 0;
|
||||
|
||||
static void dmxDoSync(DMXScreenInfo *dmxScreen)
|
||||
{
|
||||
|
|
@ -98,33 +69,86 @@ static void dmxDoSync(DMXScreenInfo *dmxScreen)
|
|||
|
||||
if (!dmxScreen->beDisplay)
|
||||
{
|
||||
dmxScreen->syncCookie.sequence = 0;
|
||||
dmxScreen->sync.sequence = 0;
|
||||
return; /* FIXME: Is this correct behavior for sync stats? */
|
||||
}
|
||||
|
||||
dmxScreen->syncCookie =
|
||||
xcb_get_input_focus_unchecked (dmxScreen->connection);
|
||||
if (dmxScreen->sync.sequence)
|
||||
return;
|
||||
|
||||
dmxSyncCookie++;
|
||||
dmxScreen->sync = xcb_get_input_focus_unchecked (dmxScreen->connection);
|
||||
dmxAddSequence (&dmxScreen->request, dmxScreen->sync.sequence);
|
||||
dmxSyncRequest++;
|
||||
}
|
||||
|
||||
static CARD32 dmxSyncCallback(OsTimerPtr timer, CARD32 time, pointer arg)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (dmxSyncCookie) {
|
||||
while (dmxSyncRequest)
|
||||
{
|
||||
fd_set rfds;
|
||||
int ret, fd = 0;
|
||||
|
||||
/* timer expired and there is pending sync replies that need
|
||||
to be waited for before we can allow further processing
|
||||
of client requests */
|
||||
|
||||
FD_ZERO (&rfds);
|
||||
|
||||
for (i = 0; i < dmxNumScreens; i++)
|
||||
if (dmxScreens[i].syncCookie.sequence) dmxWaitSync(&dmxScreens[i]);
|
||||
dmxSyncCookie = 0;
|
||||
{
|
||||
if (dmxScreens[i].beDisplay)
|
||||
{
|
||||
xcb_flush (dmxScreens[i].connection);
|
||||
if (xcb_connection_has_error (dmxScreens[i].connection))
|
||||
{
|
||||
if (dmxScreens[i].sync.sequence)
|
||||
{
|
||||
dmxScreens[i].sync.sequence = 0;
|
||||
dmxSyncRequest--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FD_SET (dmxScreens[i].fd, &rfds);
|
||||
|
||||
if (dmxScreens[i].fd > fd)
|
||||
fd = dmxScreens[i].fd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fd)
|
||||
{
|
||||
do {
|
||||
ret = select (fd + 1, &rfds, 0, 0, 0);
|
||||
} while (ret == -1 && errno == EINTR);
|
||||
}
|
||||
|
||||
dmxSyncPending++;
|
||||
|
||||
for (i = 0; i < dmxNumScreens; i++)
|
||||
if (dmxScreens[i].beDisplay)
|
||||
dmxBEDispatch (screenInfo.screens[i]);
|
||||
|
||||
dmxSyncPending--;
|
||||
}
|
||||
|
||||
if (dmxSyncPending) {
|
||||
if (dmxSyncPending)
|
||||
{
|
||||
for (i = 0; i < dmxNumScreens; i++)
|
||||
if (dmxScreens[i].needsSync) dmxDoSync(&dmxScreens[i]);
|
||||
if (dmxScreens[i].needsSync)
|
||||
dmxDoSync (&dmxScreens[i]);
|
||||
|
||||
dmxSyncPending = 0;
|
||||
if (dmxSyncCookie)
|
||||
|
||||
if (dmxSyncRequest)
|
||||
return dmxSyncInterval;
|
||||
}
|
||||
|
||||
dmxSyncTimer = NULL;
|
||||
|
||||
return 0; /* Do not place on queue again */
|
||||
}
|
||||
|
||||
|
|
@ -185,34 +209,81 @@ void dmxSync(DMXScreenInfo *dmxScreen, Bool now)
|
|||
now = TRUE;
|
||||
dmxGeneration = serverGeneration;
|
||||
}
|
||||
/* Queue sync */
|
||||
|
||||
/* Queue sync */
|
||||
if (dmxScreen) {
|
||||
if (now && dmxScreen->inDispatch)
|
||||
{
|
||||
dmxLog (dmxWarning,
|
||||
"Immediate sync from within back-end dispatch\n");
|
||||
free (xcb_get_input_focus_reply
|
||||
(dmxScreen->connection,
|
||||
xcb_get_input_focus_unchecked (dmxScreen->connection),
|
||||
NULL));
|
||||
return;
|
||||
}
|
||||
dmxScreen->needsSync = TRUE;
|
||||
++dmxSyncPending;
|
||||
}
|
||||
|
||||
/* Do sync or set time for later */
|
||||
if (now || !dmxScreen) {
|
||||
if (!TimerForce(dmxSyncTimer)) dmxSyncCallback(NULL, 0, NULL);
|
||||
/* Do sync or set time for later */
|
||||
if (now || !dmxScreen)
|
||||
{
|
||||
if (dmxSyncTimer)
|
||||
{
|
||||
TimerFree (dmxSyncTimer);
|
||||
dmxSyncTimer = NULL;
|
||||
}
|
||||
|
||||
while (dmxSyncRequest || dmxSyncPending)
|
||||
dmxSyncCallback (NULL, 0, NULL);
|
||||
|
||||
/* At this point, dmxSyncPending == 0 because
|
||||
* dmxSyncCallback must have been called. */
|
||||
if (dmxSyncPending)
|
||||
dmxLog(dmxFatal, "dmxSync(%s,%d): dmxSyncPending = %d\n",
|
||||
dmxScreen ? dmxScreen->display : "", now, dmxSyncPending);
|
||||
} else {
|
||||
if (dmxSyncCookie == 0 && dmxSyncPending == 1)
|
||||
dmxSyncTimer = TimerSet(dmxSyncTimer, 0, dmxSyncInterval,
|
||||
dmxSyncCallback, NULL);
|
||||
}
|
||||
} else {
|
||||
/* If dmxSyncInterval is not being used,
|
||||
* then all the backends are already
|
||||
* up-to-date. */
|
||||
else if (!dmxSyncTimer)
|
||||
{
|
||||
dmxSyncTimer = TimerSet(dmxSyncTimer, 0, dmxSyncInterval,
|
||||
dmxSyncCallback, NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If dmxSyncInterval is not being used,
|
||||
* then all the backends are already
|
||||
* up-to-date. */
|
||||
if (dmxScreen)
|
||||
{
|
||||
dmxDoSync(dmxScreen);
|
||||
dmxWaitSync(dmxScreen);
|
||||
dmxSyncCallback(NULL, 0, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Bool
|
||||
dmxScreenReplyCheckSync (ScreenPtr pScreen,
|
||||
xcb_generic_reply_t *reply)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
|
||||
if (reply->sequence != dmxScreen->sync.sequence)
|
||||
return FALSE;
|
||||
|
||||
dmxScreen->sync.sequence = 0;
|
||||
|
||||
dmxSyncRequest--;
|
||||
if (dmxSyncRequest == 0)
|
||||
{
|
||||
if (dmxSyncPending == 0)
|
||||
{
|
||||
TimerFree (dmxSyncTimer);
|
||||
dmxSyncTimer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,4 +40,6 @@
|
|||
extern void dmxSyncActivate(const char *interval);
|
||||
extern void dmxSyncInit(void);
|
||||
extern void dmxSync(DMXScreenInfo *dmxScreen, Bool now);
|
||||
extern Bool dmxScreenReplyCheckSync (ScreenPtr pScreen,
|
||||
xcb_generic_reply_t *reply);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -179,6 +179,11 @@ void dmxResizeScreenWindow(ScreenPtr pScreen,
|
|||
dmxSync(dmxScreen, False);
|
||||
}
|
||||
|
||||
static void dmxSetIgnore (DMXScreenInfo *dmxScreen, unsigned int sequence)
|
||||
{
|
||||
dmxAddSequence (&dmxScreen->ignore, sequence);
|
||||
}
|
||||
|
||||
/** Change the location and size of the "root" window. Called from
|
||||
* #dmxReconfigureRootWindow(). */
|
||||
void dmxResizeRootWindow(WindowPtr pRoot,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue