mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-01-23 19:50:21 +01:00
xlib/shm: Rate-limit events and only use as necessary
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
parent
21db1c9910
commit
0c84a5474d
2 changed files with 79 additions and 35 deletions
|
|
@ -1485,12 +1485,12 @@ check_composite_glyphs (const cairo_composite_rectangles_t *extents,
|
|||
cairo_glyph_t *glyphs,
|
||||
int *num_glyphs)
|
||||
{
|
||||
TRACE ((stderr, "%s\n", __FUNCTION__));
|
||||
|
||||
cairo_xlib_surface_t *dst = (cairo_xlib_surface_t *)extents->surface;
|
||||
cairo_xlib_display_t *display = dst->display;
|
||||
int max_request_size, size;
|
||||
|
||||
TRACE ((stderr, "%s\n", __FUNCTION__));
|
||||
|
||||
if (! CAIRO_RENDER_SUPPORTS_OPERATOR (display, extents->op))
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
|
|
|
|||
|
|
@ -206,6 +206,8 @@ struct _cairo_xlib_shm_display {
|
|||
int event;
|
||||
|
||||
Window window;
|
||||
unsigned long last_request;
|
||||
unsigned long last_event;
|
||||
|
||||
cairo_list_t surfaces;
|
||||
|
||||
|
|
@ -216,7 +218,7 @@ struct _cairo_xlib_shm_display {
|
|||
static inline cairo_bool_t
|
||||
seqno_passed (unsigned long a, unsigned long b)
|
||||
{
|
||||
return (long)(b - a) > 0;
|
||||
return (long)(b - a) >= 0;
|
||||
}
|
||||
|
||||
static inline cairo_status_t
|
||||
|
|
@ -421,6 +423,43 @@ _cairo_xlib_display_shm_pool_destroy (cairo_xlib_display_t *display,
|
|||
free (pool);
|
||||
}
|
||||
|
||||
static void send_event(cairo_xlib_display_t *display,
|
||||
cairo_xlib_shm_info_t *info,
|
||||
unsigned long seqno)
|
||||
{
|
||||
XShmCompletionEvent ev;
|
||||
|
||||
if (seqno_passed (seqno, display->shm->last_event))
|
||||
return;
|
||||
|
||||
ev.type = display->shm->event;
|
||||
ev.send_event = 1; /* XXX or lie? */
|
||||
ev.serial = NextRequest (display->display);
|
||||
ev.drawable = display->shm->window;
|
||||
ev.major_code = display->shm->opcode;
|
||||
ev.minor_code = X_ShmPutImage;
|
||||
ev.shmseg = info->pool->shm.shmid;
|
||||
ev.offset = (char *)info->mem - (char *)info->pool->shm.shmaddr;
|
||||
|
||||
XSendEvent (display->display, ev.drawable, False, 0, (XEvent *)&ev);
|
||||
|
||||
display->shm->last_event = ev.serial;
|
||||
}
|
||||
|
||||
static void sync (cairo_xlib_display_t *display)
|
||||
{
|
||||
cairo_xlib_shm_info_t *info;
|
||||
struct pqueue *pq = &display->shm->info;
|
||||
|
||||
XSync (display->display, False);
|
||||
|
||||
while ((info = PQ_TOP(pq))) {
|
||||
_cairo_mempool_free (&info->pool->mem, info->mem);
|
||||
_pqueue_pop (&display->shm->info);
|
||||
free (info);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_xlib_shm_info_cleanup (cairo_xlib_display_t *display)
|
||||
{
|
||||
|
|
@ -437,8 +476,10 @@ _cairo_xlib_shm_info_cleanup (cairo_xlib_display_t *display)
|
|||
|
||||
info = PQ_TOP(pq);
|
||||
do {
|
||||
if (! seqno_passed (info->last_request, processed))
|
||||
break;
|
||||
if (! seqno_passed (info->last_request, processed)) {
|
||||
send_event (display, info, display->shm->last_request);
|
||||
return;
|
||||
}
|
||||
|
||||
_cairo_mempool_free (&info->pool->mem, info->mem);
|
||||
_pqueue_pop (&display->shm->info);
|
||||
|
|
@ -446,9 +487,9 @@ _cairo_xlib_shm_info_cleanup (cairo_xlib_display_t *display)
|
|||
} while ((info = PQ_TOP(pq)));
|
||||
}
|
||||
|
||||
static cairo_xlib_shm_info_t *
|
||||
_cairo_xlib_shm_info_find (cairo_xlib_display_t *display,
|
||||
size_t size, unsigned long *last_request)
|
||||
static cairo_xlib_shm_t *
|
||||
_cairo_xlib_shm_info_find (cairo_xlib_display_t *display, size_t size,
|
||||
void **ptr, unsigned long *last_request)
|
||||
{
|
||||
cairo_xlib_shm_info_t *info;
|
||||
struct pqueue *pq = &display->shm->info;
|
||||
|
|
@ -458,14 +499,21 @@ _cairo_xlib_shm_info_find (cairo_xlib_display_t *display,
|
|||
|
||||
info = PQ_TOP(pq);
|
||||
do {
|
||||
_pqueue_pop (&display->shm->info);
|
||||
|
||||
if (info->size >= size && size <= 2*info->size)
|
||||
return info;
|
||||
cairo_xlib_shm_t *pool = info->pool;
|
||||
|
||||
*last_request = info->last_request;
|
||||
|
||||
_pqueue_pop (&display->shm->info);
|
||||
_cairo_mempool_free (&info->pool->mem, info->mem);
|
||||
free (info);
|
||||
|
||||
if (pool->mem.free_bytes >= size) {
|
||||
void *mem = _cairo_mempool_alloc (&pool->mem, size);
|
||||
if (mem != NULL) {
|
||||
*ptr = mem;
|
||||
return pool;
|
||||
}
|
||||
}
|
||||
} while ((info = PQ_TOP(pq)));
|
||||
|
||||
return NULL;
|
||||
|
|
@ -582,15 +630,12 @@ _cairo_xlib_shm_info_create (cairo_xlib_display_t *display,
|
|||
unsigned long last_request = 0;
|
||||
void *mem = NULL;
|
||||
|
||||
if (will_sync) {
|
||||
info = _cairo_xlib_shm_info_find (display, size, &last_request);
|
||||
if (info)
|
||||
return info;
|
||||
}
|
||||
|
||||
_cairo_xlib_shm_info_cleanup (display);
|
||||
pool = _cairo_xlib_shm_pool_find (display, size, &mem);
|
||||
_cairo_xlib_shm_pool_cleanup (display);
|
||||
|
||||
if (pool == NULL && will_sync)
|
||||
pool = _cairo_xlib_shm_info_find (display, size, &mem, &last_request);
|
||||
if (pool == NULL)
|
||||
pool = _cairo_xlib_shm_pool_create (display, size, &mem);
|
||||
if (pool == NULL)
|
||||
|
|
@ -617,6 +662,7 @@ _cairo_xlib_shm_surface_flush (void *abstract_surface, unsigned flags)
|
|||
{
|
||||
cairo_xlib_shm_surface_t *shm = abstract_surface;
|
||||
cairo_xlib_display_t *display;
|
||||
Display *dpy;
|
||||
cairo_status_t status;
|
||||
|
||||
if (shm->active == 0)
|
||||
|
|
@ -634,10 +680,15 @@ _cairo_xlib_shm_surface_flush (void *abstract_surface, unsigned flags)
|
|||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
XEventsQueued (display->display, QueuedAfterReading);
|
||||
if (!seqno_passed (shm->active,
|
||||
LastKnownRequestProcessed (display->display)))
|
||||
XSync (display->display, False);
|
||||
send_event (display, shm->info, shm->active);
|
||||
|
||||
dpy = display->display;
|
||||
XEventsQueued (dpy, QueuedAfterReading);
|
||||
while (! seqno_passed (shm->active, LastKnownRequestProcessed (dpy))) {
|
||||
LockDisplay(dpy);
|
||||
_XReadEvents(dpy);
|
||||
UnlockDisplay(dpy);
|
||||
}
|
||||
|
||||
cairo_device_release (&display->base);
|
||||
shm->active = 0;
|
||||
|
|
@ -649,7 +700,7 @@ static inline cairo_bool_t
|
|||
active (cairo_xlib_shm_surface_t *shm, Display *dpy)
|
||||
{
|
||||
return (shm->active &&
|
||||
!seqno_passed (shm->active, LastKnownRequestProcessed (dpy)));
|
||||
! seqno_passed (shm->active, LastKnownRequestProcessed (dpy)));
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
|
|
@ -669,6 +720,8 @@ _cairo_xlib_shm_surface_finish (void *abstract_surface)
|
|||
if (active (shm, display->display)) {
|
||||
shm->info->last_request = shm->active;
|
||||
_pqueue_push (&display->shm->info, shm->info);
|
||||
if (! seqno_passed (display->shm->last_request, shm->active))
|
||||
display->shm->last_request = shm->active;
|
||||
} else {
|
||||
_cairo_mempool_free (&shm->info->pool->mem, shm->info->mem);
|
||||
free (shm->info);
|
||||
|
|
@ -884,7 +937,7 @@ _cairo_xlib_surface_update_shm (cairo_xlib_surface_t *surface)
|
|||
XChangeGC (display->display, gc, GCSubwindowMode, &gcv);
|
||||
}
|
||||
|
||||
XSync (display->display, False);
|
||||
sync (display);
|
||||
shm->active = 0;
|
||||
shm->idle--;
|
||||
|
||||
|
|
@ -1130,19 +1183,8 @@ _cairo_xlib_shm_surface_mark_active (cairo_surface_t *_shm)
|
|||
{
|
||||
cairo_xlib_shm_surface_t *shm = (cairo_xlib_shm_surface_t *) _shm;
|
||||
cairo_xlib_display_t *display = (cairo_xlib_display_t *) _shm->device;
|
||||
XShmCompletionEvent ev;
|
||||
|
||||
ev.type = display->shm->event;
|
||||
ev.send_event = 1; /* XXX or lie? */
|
||||
ev.serial = NextRequest (display->display) - 1;
|
||||
ev.drawable = display->shm->window;
|
||||
ev.major_code = display->shm->opcode;
|
||||
ev.minor_code = X_ShmPutImage;
|
||||
ev.shmseg = shm->info->pool->shm.shmid;
|
||||
ev.offset = (char *)shm->info->mem - (char *)shm->info->pool->shm.shmaddr;
|
||||
|
||||
shm->active = NextRequest (display->display);
|
||||
XSendEvent (display->display, ev.drawable, False, 0, (XEvent *)&ev);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -1356,6 +1398,8 @@ _cairo_xlib_display_init_shm (cairo_xlib_display_t *display)
|
|||
InputOutput,
|
||||
DefaultVisual (display->display, scr),
|
||||
CWOverrideRedirect, &attr);
|
||||
shm->last_event = 0;
|
||||
shm->last_request = 0;
|
||||
|
||||
if (xorg_has_buggy_send_shm_completion_event(display, shm))
|
||||
has_pixmap = 0;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue