]> git.ipfire.org Git - thirdparty/plymouth.git/commitdiff
[x11] Draw to back pixmap instead of on exposes
authorRay Strode <rstrode@redhat.com>
Sat, 3 Oct 2009 04:26:14 +0000 (00:26 -0400)
committerRay Strode <rstrode@redhat.com>
Sun, 4 Oct 2009 14:45:37 +0000 (10:45 -0400)
It's a little more efficient.

src/plugins/renderers/x11/plugin.c

index 2fbe5fc79dbb529a0ed9efe18d98ee6d30ab9015..87ad8bb4de179821915b1fa222174002f81968d3 100644 (file)
@@ -67,6 +67,7 @@ struct _ply_renderer_head
   ply_pixel_buffer_t     *pixel_buffer;
   ply_rectangle_t         area;
   GtkWidget              *window;
+  GdkPixmap              *pixmap;
   cairo_surface_t        *image;
 };
 
@@ -182,6 +183,10 @@ query_device (ply_renderer_backend_t *backend)
       head->area.y = 0;
       head->area.width = 800;         /* FIXME hardcoded */
       head->area.height = 600;
+      head->pixmap = gdk_pixmap_new (NULL,
+                                     head->area.width,
+                                     head->area.height,
+                                     24);
 
       ply_list_append_data (backend->heads, head);
 
@@ -192,6 +197,10 @@ query_device (ply_renderer_backend_t *backend)
       head->area.y = 0;
       head->area.width = 640;         /* FIXME hardcoded */
       head->area.height = 480;
+      head->pixmap = gdk_pixmap_new (NULL,
+                                     head->area.width,
+                                     head->area.height,
+                                     24);
 
       ply_list_append_data (backend->heads, head);
     }
@@ -199,41 +208,6 @@ query_device (ply_renderer_backend_t *backend)
   return true;
 }
 
-static void
-screen_refresh (GtkWidget       *widget,
-                cairo_surface_t *image,
-                int              x,
-                int              y,
-                int              width,
-                int              height)
-{
-  cairo_t *cr;
-  cr = gdk_cairo_create (gtk_widget_get_window (widget));
-  cairo_rectangle (cr, x, y, width, height);
-  cairo_clip (cr);
-
-  cairo_set_source_surface (cr, image, 0, 0);
-  cairo_paint (cr);
-
-  cairo_destroy (cr);
-  return;
-}
-
-static gboolean
-on_expose_event (GtkWidget       *widget,
-                 GdkEventExpose  *event,
-                 gpointer         user_data)
-{
-  cairo_surface_t *image = user_data;
-  screen_refresh (widget,
-                  image,
-                  event->area.x,
-                  event->area.y,
-                  event->area.width,
-                  event->area.height);
-  return FALSE;
-}
-
 static gboolean
 on_window_destroy (GtkWidget *widget,
                    GdkEvent  *event,
@@ -270,10 +244,8 @@ map_to_device (ply_renderer_backend_t *backend)
                                                          head->area.width * 4);
       gtk_widget_set_app_paintable (head->window, TRUE);
       gtk_widget_show_all (head->window);
+      gdk_window_set_back_pixmap (head->window->window, head->pixmap, FALSE);
 
-      g_signal_connect (head->window, "expose-event",
-                        G_CALLBACK (on_expose_event),
-                       head->image);
       g_signal_connect (head->window, "key-press-event",
                         G_CALLBACK (on_key_event),
                         &backend->input_source);
@@ -316,14 +288,20 @@ unmap_from_device (ply_renderer_backend_t *backend)
 static void
 flush_area_to_device (ply_renderer_backend_t *backend,
                       ply_renderer_head_t    *head,
-                      ply_rectangle_t        *area_to_flush)
+                      ply_rectangle_t        *area_to_flush,
+                      cairo_t                *cr)
 {
-  screen_refresh (head->window,
-                  head->image,
-                  area_to_flush->x,
-                  area_to_flush->y,
-                  area_to_flush->width,
-                  area_to_flush->height);
+  cairo_save (cr);
+  cairo_rectangle (cr,
+                   area_to_flush->x,
+                   area_to_flush->y,
+                   area_to_flush->width,
+                   area_to_flush->height);
+  cairo_clip (cr);
+
+  cairo_set_source_surface (cr, head->image, 0, 0);
+  cairo_paint (cr);
+  cairo_restore (cr);
 }
 
 static void
@@ -334,6 +312,7 @@ flush_head (ply_renderer_backend_t *backend,
   ply_list_t *areas_to_flush;
   ply_list_node_t *node;
   ply_pixel_buffer_t *pixel_buffer;
+  cairo_t *cr;
 
   assert (backend != NULL);
 
@@ -341,6 +320,8 @@ flush_head (ply_renderer_backend_t *backend,
   updated_region = ply_pixel_buffer_get_updated_areas (pixel_buffer);
   areas_to_flush = ply_region_get_rectangle_list (updated_region);
 
+  cr = gdk_cairo_create (head->pixmap);
+
   node = ply_list_get_first_node (areas_to_flush);
   while (node != NULL)
     {
@@ -351,11 +332,17 @@ flush_head (ply_renderer_backend_t *backend,
 
       next_node = ply_list_get_next_node (areas_to_flush, node);
 
-      flush_area_to_device (backend, head, area_to_flush);
-
+      flush_area_to_device (backend, head, area_to_flush, cr);
+      gdk_window_clear_area (head->window->window,
+                             area_to_flush->x,
+                             area_to_flush->y,
+                             area_to_flush->width,
+                             area_to_flush->height);
       node = next_node;
     }
   ply_region_clear (updated_region);
+
+  cairo_destroy (cr);
 }
 
 static void