VIGS: Moved context operations and glFinish to batch_start/batch_end
authorStanislav Vorobiov <s.vorobiov@samsung.com>
Fri, 5 Jul 2013 07:42:23 +0000 (11:42 +0400)
committerStanislav Vorobiov <s.vorobiov@samsung.com>
Fri, 5 Jul 2013 07:42:23 +0000 (11:42 +0400)
It's quite frequent for X server to group several blits
into one batch, so we should call glFinish once for
whole batch instead of for every operation

hw/vigs_backend.h
hw/vigs_gl_backend.c
hw/vigs_server.c
hw/vigs_server.h
hw/vigs_sw_backend.c

index 8b940c1629ee7649271ae2552ea05a050b198a16..9d3bc7e61b8f1313af88e0a0319678b95de1f44e 100644 (file)
@@ -10,6 +10,8 @@ struct vigs_backend
 {
     struct winsys_info *ws_info;
 
+    void (*batch_start)(struct vigs_backend */*backend*/);
+
     struct vigs_surface *(*create_surface)(struct vigs_backend */*backend*/,
                                            uint32_t /*width*/,
                                            uint32_t /*height*/,
@@ -17,6 +19,8 @@ struct vigs_backend
                                            vigsp_surface_format /*format*/,
                                            vigsp_surface_id /*id*/);
 
+    void (*batch_end)(struct vigs_backend */*backend*/);
+
     void (*destroy)(struct vigs_backend */*backend*/);
 };
 
index 61988d718765139474ad6046276c08c71199b460..527965ab35c395969b47dbc22391a2d6175b27fc 100644 (file)
@@ -281,6 +281,15 @@ static void vigs_winsys_gl_surface_orphan(struct vigs_winsys_gl_surface *sfc)
  * @}
  */
 
+static void vigs_gl_backend_batch_start(struct vigs_backend *backend)
+{
+    struct vigs_gl_backend *gl_backend = (struct vigs_gl_backend*)backend;
+
+    if (!gl_backend->make_current(gl_backend, true)) {
+        VIGS_LOG_CRITICAL("make_current failed");
+    }
+}
+
 /*
  * vigs_gl_surface.
  * @{
@@ -303,10 +312,6 @@ static void vigs_gl_surface_read_pixels(struct vigs_surface *sfc,
     VIGS_LOG_TRACE("x = %u, y = %u, width = %u, height = %u",
                    x, y, width, height);
 
-    if (!gl_backend->make_current(gl_backend, true)) {
-        return;
-    }
-
     if (!ws_sfc->tex) {
         VIGS_LOG_TRACE("skipping blank read");
         goto out;
@@ -384,8 +389,6 @@ static void vigs_gl_surface_read_pixels(struct vigs_surface *sfc,
 
 out:
     gl_backend->BindFramebuffer(GL_FRAMEBUFFER, 0);
-
-    gl_backend->make_current(gl_backend, false);
 }
 
 static void vigs_gl_surface_draw_pixels(struct vigs_surface *sfc,
@@ -398,10 +401,6 @@ static void vigs_gl_surface_draw_pixels(struct vigs_surface *sfc,
     struct vigs_winsys_gl_surface *ws_sfc = get_ws_sfc(gl_sfc);
     uint32_t i;
 
-    if (!gl_backend->make_current(gl_backend, true)) {
-        return;
-    }
-
     if (!vigs_winsys_gl_surface_create_texture(ws_sfc, &ws_sfc->tex)) {
         goto out;
     }
@@ -441,12 +440,8 @@ static void vigs_gl_surface_draw_pixels(struct vigs_surface *sfc,
                                pixels);
     }
 
-    gl_backend->Finish();
-
 out:
     gl_backend->BindFramebuffer(GL_FRAMEBUFFER, 0);
-
-    gl_backend->make_current(gl_backend, false);
 }
 
 static void vigs_gl_surface_copy(struct vigs_surface *dst,
@@ -465,10 +460,6 @@ static void vigs_gl_surface_copy(struct vigs_surface *dst,
     GLfloat *vert_coords;
     GLfloat *tex_coords;
 
-    if (!gl_backend->make_current(gl_backend, true)) {
-        return;
-    }
-
     if (!vigs_winsys_gl_surface_create_texture(ws_dst, &ws_dst->tex)) {
         goto out;
     }
@@ -624,12 +615,8 @@ static void vigs_gl_surface_copy(struct vigs_surface *dst,
     gl_backend->DisableClientState(GL_TEXTURE_COORD_ARRAY);
     gl_backend->DisableClientState(GL_VERTEX_ARRAY);
 
-    gl_backend->Finish();
-
 out:
     gl_backend->BindFramebuffer(GL_FRAMEBUFFER, 0);
-
-    gl_backend->make_current(gl_backend, false);
 }
 
 static void vigs_gl_surface_solid_fill(struct vigs_surface *sfc,
@@ -644,10 +631,6 @@ static void vigs_gl_surface_solid_fill(struct vigs_surface *sfc,
     GLubyte red, green, blue, alpha;
     GLfloat sfc_h;
 
-    if (!gl_backend->make_current(gl_backend, true)) {
-        return;
-    }
-
     if (!vigs_winsys_gl_surface_create_texture(ws_sfc, &ws_sfc->tex)) {
         goto out;
     }
@@ -700,12 +683,8 @@ static void vigs_gl_surface_solid_fill(struct vigs_surface *sfc,
 
     gl_backend->DisableClientState(GL_VERTEX_ARRAY);
 
-    gl_backend->Finish();
-
 out:
     gl_backend->BindFramebuffer(GL_FRAMEBUFFER, 0);
-
-    gl_backend->make_current(gl_backend, false);
 }
 
 static void vigs_gl_surface_destroy(struct vigs_surface *sfc)
@@ -716,15 +695,11 @@ static void vigs_gl_surface_destroy(struct vigs_surface *sfc)
 
     vigs_winsys_gl_surface_orphan(ws_sfc);
 
-    if (gl_backend->make_current(gl_backend, true)) {
-        if (gl_sfc->fb) {
-            gl_backend->DeleteFramebuffers(1, &gl_sfc->fb);
-        }
-        if (gl_sfc->tmp_tex) {
-            gl_backend->DeleteTextures(1, &gl_sfc->tmp_tex);
-        }
-
-        gl_backend->make_current(gl_backend, false);
+    if (gl_sfc->fb) {
+        gl_backend->DeleteFramebuffers(1, &gl_sfc->fb);
+    }
+    if (gl_sfc->tmp_tex) {
+        gl_backend->DeleteTextures(1, &gl_sfc->tmp_tex);
     }
 
     vigs_surface_cleanup(&gl_sfc->base);
@@ -811,6 +786,14 @@ fail:
     return NULL;
 }
 
+static void vigs_gl_backend_batch_end(struct vigs_backend *backend)
+{
+    struct vigs_gl_backend *gl_backend = (struct vigs_gl_backend*)backend;
+
+    gl_backend->Finish();
+    gl_backend->make_current(gl_backend, false);
+}
+
 bool vigs_gl_backend_init(struct vigs_gl_backend *gl_backend)
 {
     const char *extensions;
@@ -865,7 +848,9 @@ bool vigs_gl_backend_init(struct vigs_gl_backend *gl_backend)
      * @}
      */
 
+    gl_backend->base.batch_start = &vigs_gl_backend_batch_start;
     gl_backend->base.create_surface = &vigs_gl_backend_create_surface;
+    gl_backend->base.batch_end = &vigs_gl_backend_batch_end;
 
     gl_backend->make_current(gl_backend, false);
 
index 1bee4bfe8d9e1ed862b4a4dae95af1cc9065fa06..e02c39a5d83a24336a668c5dc411a64dd70b25b6 100644 (file)
@@ -47,8 +47,26 @@ static struct winsys_surface
     return res->ws_sfc;
 }
 
+static void vigs_server_end_batch(struct vigs_server *server)
+{
+    if (server->in_batch) {
+        server->backend->batch_end(server->backend);
+
+        server->in_batch = false;
+    }
+}
+
 static void vigs_server_dispatch_batch_start(void *user_data)
 {
+    struct vigs_server *server = user_data;
+
+    server->in_batch = false;
+
+    if (server->initialized) {
+        server->backend->batch_start(server->backend);
+
+        server->in_batch = true;
+    }
 }
 
 static bool vigs_server_dispatch_init(void *user_data)
@@ -96,6 +114,8 @@ static void vigs_server_dispatch_exit(void *user_data)
         return;
     }
 
+    vigs_server_end_batch(server);
+
     vigs_server_reset(server);
 }
 
@@ -318,6 +338,9 @@ static void vigs_server_dispatch_solid_fill(void *user_data,
 
 static void vigs_server_dispatch_batch_end(void *user_data)
 {
+    struct vigs_server *server = user_data;
+
+    vigs_server_end_batch(server);
 }
 
 static struct vigs_comm_ops vigs_server_dispatch_ops =
@@ -393,6 +416,8 @@ void vigs_server_reset(struct vigs_server *server)
     GHashTableIter iter;
     gpointer key, value;
 
+    server->backend->batch_start(server->backend);
+
     g_hash_table_iter_init(&iter, server->surfaces);
     while (g_hash_table_iter_next(&iter, &key, &value)) {
         struct vigs_surface *sfc = value;
@@ -402,6 +427,8 @@ void vigs_server_reset(struct vigs_server *server)
         g_hash_table_iter_remove(&iter);
     }
 
+    server->backend->batch_end(server->backend);
+
     server->root_sfc = NULL;
     server->root_sfc_data = NULL;
 
@@ -428,12 +455,14 @@ void vigs_server_update_display(struct vigs_server *server)
     }
 
     if (root_sfc->is_dirty) {
+        server->backend->batch_start(server->backend);
         root_sfc->read_pixels(root_sfc,
                               0,
                               0,
                               root_sfc->ws_sfc->width,
                               root_sfc->ws_sfc->height,
                               sfc_data);
+        server->backend->batch_end(server->backend);
         root_sfc->is_dirty = false;
     }
 
index e34b0bad2097945eb9955fe8c10715008f422672..d7046396dda6c5dba76f9af9cb343297bbeaa658 100644 (file)
@@ -60,6 +60,8 @@ struct vigs_server
     struct vigs_surface *root_sfc;
     uint8_t *root_sfc_data;
 
+    bool in_batch;
+
     /*
      * General purpose vectors.
      * @{
index 12808710bd10d1f4cd8d995ac1c7c600d96831f8..51f705495713f7b7c753bd2d16abf2d1ebbe549c 100644 (file)
@@ -68,6 +68,10 @@ static struct vigs_winsys_sw_surface
  * @}
  */
 
+static void vigs_sw_backend_batch_start(struct vigs_backend *backend)
+{
+}
+
 /*
  * vigs_sw_surface.
  * @{
@@ -296,6 +300,10 @@ static struct vigs_surface *vigs_sw_backend_create_surface(struct vigs_backend *
     return &sw_sfc->base;
 }
 
+static void vigs_sw_backend_batch_end(struct vigs_backend *backend)
+{
+}
+
 static void vigs_sw_backend_destroy(struct vigs_backend *backend)
 {
     vigs_backend_cleanup(backend);
@@ -310,7 +318,9 @@ struct vigs_backend *vigs_sw_backend_create(void)
 
     vigs_backend_init(backend, NULL);
 
+    backend->batch_start = &vigs_sw_backend_batch_start;
     backend->create_surface = &vigs_sw_backend_create_surface;
+    backend->batch_end = &vigs_sw_backend_batch_end;
     backend->destroy = &vigs_sw_backend_destroy;
 
     return backend;