From 52d3a026bbf844de1972ea9777dbcb11c7ac9ccd Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 2 Aug 2016 10:56:30 +0100 Subject: sna: Split SHM and DRI flush tracking Tracking SHM flushes precludes some of the optimisations we can make in future for tracking DRI flushes, so split the two paths. Signed-off-by: Chris Wilson --- src/sna/sna.h | 18 ++++++-- src/sna/sna_accel.c | 128 ++++++++++++++++++++++++++++----------------------- src/sna/sna_dri2.c | 4 +- src/sna/sna_dri3.c | 2 +- src/sna/sna_render.c | 12 +---- 5 files changed, 91 insertions(+), 73 deletions(-) diff --git a/src/sna/sna.h b/src/sna/sna.h index 9adef0eb..eb3489d4 100644 --- a/src/sna/sna.h +++ b/src/sna/sna.h @@ -282,9 +282,11 @@ struct sna { bool ignore_copy_area : 1; - unsigned watch_flush; + unsigned watch_shm_flush; + unsigned watch_dri_flush; unsigned damage_event; - bool needs_flush; + bool needs_shm_flush; + bool needs_dri_flush; struct timeval timer_tv; uint32_t timer_expire[NUM_TIMERS]; @@ -1077,13 +1079,13 @@ static inline uint32_t pixmap_size(PixmapPtr pixmap) bool sna_accel_init(ScreenPtr sreen, struct sna *sna); void sna_accel_create(struct sna *sna); void sna_accel_block(struct sna *sna, struct timeval **tv); -void sna_accel_watch_flush(struct sna *sna, int enable); void sna_accel_flush(struct sna *sna); void sna_accel_enter(struct sna *sna); void sna_accel_leave(struct sna *sna); void sna_accel_close(struct sna *sna); void sna_accel_free(struct sna *sna); +void sna_watch_flush(struct sna *sna, int enable); void sna_copy_fbcon(struct sna *sna); bool sna_composite_create(struct sna *sna); @@ -1349,4 +1351,14 @@ static inline void sigtrap_put(void) extern int getline(char **line, size_t *len, FILE *file); #endif +static inline void add_shm_flush(struct sna *sna, struct sna_pixmap *priv) +{ + if (!priv->shm) + return; + + assert(!priv->flush); + sna_add_flush_pixmap(sna, priv, priv->cpu_bo); + sna->needs_shm_flush = true; +} + #endif /* _SNA_H */ diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index 2f851548..05007bc7 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -222,6 +222,7 @@ static GCOps sna_gc_ops__tmp; static const GCFuncs sna_gc_funcs; static const GCFuncs sna_gc_funcs__cpu; +static void sna_shm_watch_flush(struct sna *sna, int enable); static void sna_poly_fill_rect__gpu(DrawablePtr draw, GCPtr gc, int n, xRectangle *rect); @@ -589,7 +590,7 @@ static void __sna_pixmap_free_cpu(struct sna *sna, struct sna_pixmap *priv) if (priv->cpu_bo->flush) { assert(!priv->cpu_bo->reusable); kgem_bo_sync__cpu(&sna->kgem, priv->cpu_bo); - sna_accel_watch_flush(sna, -1); + sna_shm_watch_flush(sna, -1); } kgem_bo_destroy(&sna->kgem, priv->cpu_bo); } else if (!IS_STATIC_PTR(priv->ptr)) @@ -1001,7 +1002,7 @@ fallback: } priv->cpu_bo->pitch = pitch; kgem_bo_mark_unreusable(priv->cpu_bo); - sna_accel_watch_flush(sna, 1); + sna_shm_watch_flush(sna, 1); #ifdef DEBUG_MEMORY sna->debug_memory.cpu_bo_allocs++; sna->debug_memory.cpu_bo_bytes += kgem_bo_size(priv->cpu_bo); @@ -1440,7 +1441,7 @@ static void __sna_free_pixmap(struct sna *sna, __sna_pixmap_free_cpu(sna, priv); if (priv->flush) - sna_accel_watch_flush(sna, -1); + sna_watch_flush(sna, -1); #if !NDEBUG pixmap->devKind = 0xdeadbeef; @@ -1511,7 +1512,7 @@ static Bool sna_destroy_pixmap(PixmapPtr pixmap) if (priv->shm && kgem_bo_is_busy(priv->cpu_bo)) { DBG(("%s: deferring release of active SHM pixmap=%ld\n", __FUNCTION__, pixmap->drawable.serialNumber)); - sna_add_flush_pixmap(sna, priv, priv->cpu_bo); + add_shm_flush(sna, priv); kgem_bo_submit(&sna->kgem, priv->cpu_bo); /* XXX ShmDetach */ } else __sna_free_pixmap(sna, pixmap, priv); @@ -3460,11 +3461,7 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int fl return priv; } - if (priv->shm) { - assert(!priv->flush); - sna_add_flush_pixmap(sna, priv, priv->cpu_bo); - sna->needs_flush = true; - } + add_shm_flush(sna, priv); assert(priv->cpu_damage); region_set(&r, box); @@ -4072,14 +4069,10 @@ prefer_gpu_bo: } if (priv->shm) { - assert(!priv->flush); - sna_add_flush_pixmap(sna, priv, priv->cpu_bo); - + add_shm_flush(sna, priv); /* As we may have flushed and retired,, recheck for busy bo */ if ((flags & FORCE_GPU) == 0 && !kgem_bo_is_busy(priv->cpu_bo)) return NULL; - - sna->needs_flush = true; } if (priv->flush) { assert(!priv->shm); @@ -4383,11 +4376,7 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags) goto done; } - if (priv->shm) { - assert(!priv->flush); - sna_add_flush_pixmap(sna, priv, priv->cpu_bo); - sna->needs_flush = true; - } + add_shm_flush(sna, priv); n = sna_damage_get_boxes(priv->cpu_damage, &box); assert(n); @@ -5031,10 +5020,7 @@ done: sna_damage_all(&priv->gpu_damage, pixmap); } - if (priv->shm) { - sna_add_flush_pixmap(sna, priv, priv->cpu_bo); - sna->needs_flush = true; - } + add_shm_flush(sna, priv); } assert(!priv->clear); @@ -6637,10 +6623,7 @@ discard_cow: sna_damage_all(&dst_priv->gpu_damage, dst_pixmap); sna_damage_destroy(&dst_priv->cpu_damage); list_del(&dst_priv->flush_list); - if (dst_priv->shm) { - sna_add_flush_pixmap(sna, dst_priv, dst_priv->cpu_bo); - sna->needs_flush = true; - } + add_shm_flush(sna, dst_priv); return; } } @@ -6719,11 +6702,7 @@ discard_cow: if (replaces && UNDO) kgem_bo_pair_undo(&sna->kgem, dst_priv->gpu_bo, dst_priv->cpu_bo); - if (src_priv->shm) { - assert(!src_priv->flush); - sna_add_flush_pixmap(sna, src_priv, src_priv->cpu_bo); - sna->needs_flush = true; - } + add_shm_flush(sna, src_priv); if (!sna->render.copy_boxes(sna, alu, &src_pixmap->drawable, src_priv->cpu_bo, src_dx, src_dy, @@ -17389,32 +17368,43 @@ void sna_accel_flush(struct sna *sna) } static void -sna_accel_flush_callback(CallbackListPtr *list, - pointer user_data, pointer call_data) +sna_shm_flush_callback(CallbackListPtr *list, + pointer user_data, pointer call_data) +{ + struct sna *sna = user_data; + + if (!sna->needs_shm_flush) + return; + + sna_accel_flush(sna); + sna->needs_shm_flush = false; +} + +static void +sna_flush_callback(CallbackListPtr *list, pointer user_data, pointer call_data) { struct sna *sna = user_data; - if (!sna->needs_flush) + if (!sna->needs_dri_flush) return; sna_accel_flush(sna); - sna->needs_flush = false; + sna->needs_dri_flush = false; } static void -sna_accel_event_callback(CallbackListPtr *list, - pointer user_data, pointer call_data) +sna_event_callback(CallbackListPtr *list, pointer user_data, pointer call_data) { EventInfoRec *eventinfo = call_data; struct sna *sna = user_data; int i; - if (sna->needs_flush) + if (sna->needs_dri_flush) return; for (i = 0; i < eventinfo->count; i++) { if (eventinfo->events[i].u.u.type == sna->damage_event) { - sna->needs_flush = true; + sna->needs_dri_flush = true; return; } } @@ -18212,22 +18202,42 @@ fail: no_render_init(sna); } -void sna_accel_watch_flush(struct sna *sna, int enable) +static void sna_shm_watch_flush(struct sna *sna, int enable) { DBG(("%s: enable=%d\n", __FUNCTION__, enable)); assert(enable); - if (sna->watch_flush == 0) { + if (sna->watch_shm_flush == 0) { + DBG(("%s: installing shm watchers\n", __FUNCTION__)); + assert(enable > 0); + + if (!AddCallback(&FlushCallback, sna_shm_flush_callback, sna)) + return; + + sna->watch_shm_flush++; + } + + sna->watch_shm_flush += enable; +} + +void sna_watch_flush(struct sna *sna, int enable) +{ + DBG(("%s: enable=%d\n", __FUNCTION__, enable)); + assert(enable); + + if (sna->watch_dri_flush == 0) { int err = 0; DBG(("%s: installing watchers\n", __FUNCTION__)); assert(enable > 0); - if (sna->damage_event && - !AddCallback(&EventCallback, sna_accel_event_callback, sna)) + if (!sna->damage_event) + return; + + if (!AddCallback(&EventCallback, sna_event_callback, sna)) err = 1; - if (!AddCallback(&FlushCallback, sna_accel_flush_callback, sna)) + if (!AddCallback(&FlushCallback, sna_flush_callback, sna)) err = 1; if (err) { @@ -18235,10 +18245,10 @@ void sna_accel_watch_flush(struct sna *sna, int enable) "Failed to attach ourselves to the flush callbacks, expect missing synchronisation with DRI clients (e.g a compositor)\n"); } - sna->watch_flush++; + sna->watch_dri_flush++; } - sna->watch_flush += enable; + sna->watch_dri_flush += enable; } void sna_accel_leave(struct sna *sna) @@ -18278,8 +18288,9 @@ void sna_accel_close(struct sna *sna) sna_pixmap_expire(sna); - DeleteCallback(&FlushCallback, sna_accel_flush_callback, sna); - DeleteCallback(&EventCallback, sna_accel_event_callback, sna); + DeleteCallback(&FlushCallback, sna_shm_flush_callback, sna); + DeleteCallback(&FlushCallback, sna_flush_callback, sna); + DeleteCallback(&EventCallback, sna_event_callback, sna); RemoveNotifyFd(sna->kgem.fd); kgem_cleanup_cache(&sna->kgem); @@ -18326,14 +18337,17 @@ restart: if (sna_accel_do_debug_memory(sna)) sna_accel_debug_memory(sna); - if (sna->watch_flush == 1) { - DBG(("%s: removing watchers\n", __FUNCTION__)); - DeleteCallback(&FlushCallback, - sna_accel_flush_callback, sna); - if (sna->damage_event) - DeleteCallback(&EventCallback, - sna_accel_event_callback, sna); - sna->watch_flush = 0; + if (sna->watch_shm_flush == 1) { + DBG(("%s: removing shm watchers\n", __FUNCTION__)); + DeleteCallback(&FlushCallback, sna_shm_flush_callback, sna); + sna->watch_shm_flush = 0; + } + + if (sna->watch_dri_flush == 1) { + DBG(("%s: removing dri watchers\n", __FUNCTION__)); + DeleteCallback(&FlushCallback, sna_flush_callback, sna); + DeleteCallback(&EventCallback, sna_event_callback, sna); + sna->watch_dri_flush = 0; } if (sna->timer_active & 1) { diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c index 22667913..47bd2edc 100644 --- a/src/sna/sna_dri2.c +++ b/src/sna/sna_dri2.c @@ -794,7 +794,7 @@ sna_dri2_create_buffer(DrawablePtr draw, priv->flush |= FLUSH_WRITE; } - sna_accel_watch_flush(sna, 1); + sna_watch_flush(sna, 1); } return buffer; @@ -924,7 +924,7 @@ static void _sna_dri2_destroy_buffer(struct sna *sna, priv->gpu_bo->flush = false; priv->flush = false; } - sna_accel_watch_flush(sna, -1); + sna_watch_flush(sna, -1); sna_pixmap_set_buffer(pixmap, NULL); pixmap->drawable.pScreen->DestroyPixmap(pixmap); diff --git a/src/sna/sna_dri3.c b/src/sna/sna_dri3.c index 70b12c60..a10c7fb0 100644 --- a/src/sna/sna_dri3.c +++ b/src/sna/sna_dri3.c @@ -59,7 +59,7 @@ static inline void mark_dri3_pixmap(struct sna *sna, struct sna_pixmap *priv, st else priv->shm = true; - sna_accel_watch_flush(sna, 1); + sna_watch_flush(sna, 1); kgem_bo_unclean(&sna->kgem, bo); } diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c index a5b0935c..3e935d57 100644 --- a/src/sna/sna_render.c +++ b/src/sna/sna_render.c @@ -393,11 +393,7 @@ use_cpu_bo(struct sna *sna, PixmapPtr pixmap, const BoxRec *box, bool blt) } } - if (priv->shm) { - assert(!priv->flush); - sna_add_flush_pixmap(sna, priv, priv->cpu_bo); - sna->needs_flush = true; - } + add_shm_flush(sna, priv); DBG(("%s for box=(%d, %d), (%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2)); @@ -615,11 +611,7 @@ sna_render_pixmap_bo(struct sna *sna, !priv->cpu_bo->snoop && priv->cpu_bo->pitch < 4096) { DBG(("%s: CPU all damaged\n", __FUNCTION__)); channel->bo = priv->cpu_bo; - if (priv->shm) { - assert(!priv->flush); - sna_add_flush_pixmap(sna, priv, priv->cpu_bo); - sna->needs_flush = true; - } + add_shm_flush(sna, priv); goto done; } } -- cgit v1.2.3