VIGS: add synchronous glReadPixels fallback
authorVasiliy Ulyanov <v.ulyanov@samsung.com>
Thu, 14 May 2015 10:47:50 +0000 (13:47 +0300)
committerVasiliy Ulyanov <v.ulyanov@samsung.com>
Thu, 14 May 2015 13:04:05 +0000 (16:04 +0300)
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 <v.ulyanov@samsung.com>
hw/vigs/vigs_offscreen_server.c
hw/vigs/vigs_offscreen_server.h

index 3f961a7..1f54a70 100644 (file)
@@ -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;
index f0e715f..287b015 100644 (file)
@@ -36,6 +36,7 @@ struct vigs_offscreen_server
 {
     struct vigs_server base;
 
+    bool display_sync;
     struct work_queue *display_queue;
 };