From bc57086d98295f99645be07f01519e52b1632af4 Mon Sep 17 00:00:00 2001 From: Vasiliy Ulyanov Date: Thu, 14 May 2015 13:47:50 +0300 Subject: [PATCH] VIGS: add synchronous glReadPixels fallback On some GPUs accessing OpenGL objects from different threads may lead to a deadlock inside the host video driver (e.g. AMD Radeon FGLRX). To workaround this problem new env var has been introduced: VIGS_SYNC_READ_PIXELS. It makes VIGS use a single work_queue for both rendering and pixels reading. Change-Id: Ib929fb41333233e928659dd7829875fb96a4370e Signed-off-by: Vasiliy Ulyanov --- hw/vigs/vigs_offscreen_server.c | 13 +++++++++++-- hw/vigs/vigs_offscreen_server.h | 1 + 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/hw/vigs/vigs_offscreen_server.c b/hw/vigs/vigs_offscreen_server.c index 3f961a7..1f54a70 100644 --- a/hw/vigs/vigs_offscreen_server.c +++ b/hw/vigs/vigs_offscreen_server.c @@ -29,6 +29,7 @@ #include "vigs_offscreen_server.h" #include "vigs_backend.h" +#include "vigs_log.h" #include "work_queue.h" struct vigs_display_work_item @@ -109,7 +110,9 @@ static void vigs_offscreen_server_destroy(struct vigs_server *server) struct vigs_offscreen_server *offscreen_server = (struct vigs_offscreen_server*)server; - work_queue_destroy(offscreen_server->display_queue); + if (!offscreen_server->display_sync) { + work_queue_destroy(offscreen_server->display_queue); + } vigs_server_cleanup(server); @@ -124,6 +127,7 @@ struct vigs_server *vigs_offscreen_server_create(uint8_t *vram_ptr, struct vigs_backend *backend, struct work_queue *render_queue) { + const char *sync = getenv("VIGS_SYNC_READ_PIXELS"); struct vigs_offscreen_server *server = NULL; server = g_malloc0(sizeof(*server)); @@ -135,7 +139,12 @@ struct vigs_server *vigs_offscreen_server_create(uint8_t *vram_ptr, return NULL; } - server->display_queue = work_queue_create("display_queue"); + server->display_sync = sync ? !!atoi(sync) : false; + server->display_queue = server->display_sync ? + render_queue : + work_queue_create("display_queue"); + + VIGS_LOG_INFO("VIGS_SYNC_READ_PIXELS: %d", server->display_sync); server->base.begin_update = &vigs_offscreen_server_begin_update; server->base.finish_update = &vigs_offscreen_server_finish_update; diff --git a/hw/vigs/vigs_offscreen_server.h b/hw/vigs/vigs_offscreen_server.h index f0e715f..287b015 100644 --- a/hw/vigs/vigs_offscreen_server.h +++ b/hw/vigs/vigs_offscreen_server.h @@ -36,6 +36,7 @@ struct vigs_offscreen_server { struct vigs_server base; + bool display_sync; struct work_queue *display_queue; }; -- 2.7.4