]> Pileus Git - ~andy/gtk/commitdiff
GC caching, bug #125645 (based on patch by Brian Cameron)
authorSoeren Sandmann <sandmann@daimi.au.dk>
Wed, 18 Feb 2004 00:59:14 +0000 (00:59 +0000)
committerSøren Sandmann Pedersen <ssp@src.gnome.org>
Wed, 18 Feb 2004 00:59:14 +0000 (00:59 +0000)
Wed Feb 18 01:44:59 2004  Soeren Sandmann  <sandmann@daimi.au.dk>

GC caching, bug #125645 (based on patch by Brian Cameron)

* gdk/gdkscreen.h (struct _GdkScreen): Add GC cache
* gdk/gdkscreen.c (gdk_screen_dispose): New function. Unref the
cached GC's here.
* gdk/gdkdraw.c (_gdk_drawable_get_scratch_gc): New function to
get a scratch gc.
* gdk/gdkinternals.h: Declare the function here

* gdk/gdkdraw.c (gdk_drawable_real_draw_pixbuf): Use
_gdk_drawable_get_scratch_gc() instead of creating a new GC.
* gdk/x11/gdkgeometry-x11.c (gdk_window_copy_area_scroll): same
* gdk/x11/gdkdrawable-x11.c (draw_with_images): same
* gdk/gdkwindow.c (gdk_window_get_composite_drawable): same
* gdk/gdkwindow.c (gdk_window_end_paint): same
* gdk/gdkpixmap.c (gdk_pixmap_colormap_new_from_pixbuf): same
* gdk/gdkpixbuf-render.c (gdk_pixbuf_render_threshold_alpha): same
* gdk/gdkpixbuf-render.c (gdk_pixbuf_render_pixmap_and_mask_for_colormap): same

14 files changed:
ChangeLog
ChangeLog.pre-2-10
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gdk/gdkdraw.c
gdk/gdkinternals.h
gdk/gdkpixbuf-render.c
gdk/gdkpixmap.c
gdk/gdkscreen.c
gdk/gdkscreen.h
gdk/gdkwindow.c
gdk/x11/gdkdrawable-x11.c
gdk/x11/gdkgeometry-x11.c

index 46e1aadfd669790d9d5ee8bb4922b771e30ea6a8..aeb654b37fdbf9ce2578da1f35c2401116a6605e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+Wed Feb 18 01:44:59 2004  Soeren Sandmann  <sandmann@daimi.au.dk>
+
+       GC caching, bug #125645 (based on patch by Brian Cameron)
+       
+       * gdk/gdkscreen.h (struct _GdkScreen): Add GC cache
+       * gdk/gdkscreen.c (gdk_screen_dispose): New function. Unref the
+       cached GC's here.
+       * gdk/gdkdraw.c (_gdk_drawable_get_scratch_gc): New function to
+       get a scratch gc.
+       * gdk/gdkinternals.h: Declare the function here
+
+       * gdk/gdkdraw.c (gdk_drawable_real_draw_pixbuf): Use
+       _gdk_drawable_get_scratch_gc() instead of creating a new GC.
+       * gdk/x11/gdkgeometry-x11.c (gdk_window_copy_area_scroll): same
+       * gdk/x11/gdkdrawable-x11.c (draw_with_images): same
+       * gdk/gdkwindow.c (gdk_window_get_composite_drawable): same
+       * gdk/gdkwindow.c (gdk_window_end_paint): same
+       * gdk/gdkpixmap.c (gdk_pixmap_colormap_new_from_pixbuf): same
+       * gdk/gdkpixbuf-render.c (gdk_pixbuf_render_threshold_alpha): same
+       * gdk/gdkpixbuf-render.c (gdk_pixbuf_render_pixmap_and_mask_for_colormap): same
+
 Tue Feb 17 23:28:33 2004  Matthias Clasen  <maclas@gmx.de>
 
        * gtk/gtkmenu.c (gtk_menu_init): ...and don't forget to initalize
index 46e1aadfd669790d9d5ee8bb4922b771e30ea6a8..aeb654b37fdbf9ce2578da1f35c2401116a6605e 100644 (file)
@@ -1,3 +1,24 @@
+Wed Feb 18 01:44:59 2004  Soeren Sandmann  <sandmann@daimi.au.dk>
+
+       GC caching, bug #125645 (based on patch by Brian Cameron)
+       
+       * gdk/gdkscreen.h (struct _GdkScreen): Add GC cache
+       * gdk/gdkscreen.c (gdk_screen_dispose): New function. Unref the
+       cached GC's here.
+       * gdk/gdkdraw.c (_gdk_drawable_get_scratch_gc): New function to
+       get a scratch gc.
+       * gdk/gdkinternals.h: Declare the function here
+
+       * gdk/gdkdraw.c (gdk_drawable_real_draw_pixbuf): Use
+       _gdk_drawable_get_scratch_gc() instead of creating a new GC.
+       * gdk/x11/gdkgeometry-x11.c (gdk_window_copy_area_scroll): same
+       * gdk/x11/gdkdrawable-x11.c (draw_with_images): same
+       * gdk/gdkwindow.c (gdk_window_get_composite_drawable): same
+       * gdk/gdkwindow.c (gdk_window_end_paint): same
+       * gdk/gdkpixmap.c (gdk_pixmap_colormap_new_from_pixbuf): same
+       * gdk/gdkpixbuf-render.c (gdk_pixbuf_render_threshold_alpha): same
+       * gdk/gdkpixbuf-render.c (gdk_pixbuf_render_pixmap_and_mask_for_colormap): same
+
 Tue Feb 17 23:28:33 2004  Matthias Clasen  <maclas@gmx.de>
 
        * gtk/gtkmenu.c (gtk_menu_init): ...and don't forget to initalize
index 46e1aadfd669790d9d5ee8bb4922b771e30ea6a8..aeb654b37fdbf9ce2578da1f35c2401116a6605e 100644 (file)
@@ -1,3 +1,24 @@
+Wed Feb 18 01:44:59 2004  Soeren Sandmann  <sandmann@daimi.au.dk>
+
+       GC caching, bug #125645 (based on patch by Brian Cameron)
+       
+       * gdk/gdkscreen.h (struct _GdkScreen): Add GC cache
+       * gdk/gdkscreen.c (gdk_screen_dispose): New function. Unref the
+       cached GC's here.
+       * gdk/gdkdraw.c (_gdk_drawable_get_scratch_gc): New function to
+       get a scratch gc.
+       * gdk/gdkinternals.h: Declare the function here
+
+       * gdk/gdkdraw.c (gdk_drawable_real_draw_pixbuf): Use
+       _gdk_drawable_get_scratch_gc() instead of creating a new GC.
+       * gdk/x11/gdkgeometry-x11.c (gdk_window_copy_area_scroll): same
+       * gdk/x11/gdkdrawable-x11.c (draw_with_images): same
+       * gdk/gdkwindow.c (gdk_window_get_composite_drawable): same
+       * gdk/gdkwindow.c (gdk_window_end_paint): same
+       * gdk/gdkpixmap.c (gdk_pixmap_colormap_new_from_pixbuf): same
+       * gdk/gdkpixbuf-render.c (gdk_pixbuf_render_threshold_alpha): same
+       * gdk/gdkpixbuf-render.c (gdk_pixbuf_render_pixmap_and_mask_for_colormap): same
+
 Tue Feb 17 23:28:33 2004  Matthias Clasen  <maclas@gmx.de>
 
        * gtk/gtkmenu.c (gtk_menu_init): ...and don't forget to initalize
index 46e1aadfd669790d9d5ee8bb4922b771e30ea6a8..aeb654b37fdbf9ce2578da1f35c2401116a6605e 100644 (file)
@@ -1,3 +1,24 @@
+Wed Feb 18 01:44:59 2004  Soeren Sandmann  <sandmann@daimi.au.dk>
+
+       GC caching, bug #125645 (based on patch by Brian Cameron)
+       
+       * gdk/gdkscreen.h (struct _GdkScreen): Add GC cache
+       * gdk/gdkscreen.c (gdk_screen_dispose): New function. Unref the
+       cached GC's here.
+       * gdk/gdkdraw.c (_gdk_drawable_get_scratch_gc): New function to
+       get a scratch gc.
+       * gdk/gdkinternals.h: Declare the function here
+
+       * gdk/gdkdraw.c (gdk_drawable_real_draw_pixbuf): Use
+       _gdk_drawable_get_scratch_gc() instead of creating a new GC.
+       * gdk/x11/gdkgeometry-x11.c (gdk_window_copy_area_scroll): same
+       * gdk/x11/gdkdrawable-x11.c (draw_with_images): same
+       * gdk/gdkwindow.c (gdk_window_get_composite_drawable): same
+       * gdk/gdkwindow.c (gdk_window_end_paint): same
+       * gdk/gdkpixmap.c (gdk_pixmap_colormap_new_from_pixbuf): same
+       * gdk/gdkpixbuf-render.c (gdk_pixbuf_render_threshold_alpha): same
+       * gdk/gdkpixbuf-render.c (gdk_pixbuf_render_pixmap_and_mask_for_colormap): same
+
 Tue Feb 17 23:28:33 2004  Matthias Clasen  <maclas@gmx.de>
 
        * gtk/gtkmenu.c (gtk_menu_init): ...and don't forget to initalize
index 46e1aadfd669790d9d5ee8bb4922b771e30ea6a8..aeb654b37fdbf9ce2578da1f35c2401116a6605e 100644 (file)
@@ -1,3 +1,24 @@
+Wed Feb 18 01:44:59 2004  Soeren Sandmann  <sandmann@daimi.au.dk>
+
+       GC caching, bug #125645 (based on patch by Brian Cameron)
+       
+       * gdk/gdkscreen.h (struct _GdkScreen): Add GC cache
+       * gdk/gdkscreen.c (gdk_screen_dispose): New function. Unref the
+       cached GC's here.
+       * gdk/gdkdraw.c (_gdk_drawable_get_scratch_gc): New function to
+       get a scratch gc.
+       * gdk/gdkinternals.h: Declare the function here
+
+       * gdk/gdkdraw.c (gdk_drawable_real_draw_pixbuf): Use
+       _gdk_drawable_get_scratch_gc() instead of creating a new GC.
+       * gdk/x11/gdkgeometry-x11.c (gdk_window_copy_area_scroll): same
+       * gdk/x11/gdkdrawable-x11.c (draw_with_images): same
+       * gdk/gdkwindow.c (gdk_window_get_composite_drawable): same
+       * gdk/gdkwindow.c (gdk_window_end_paint): same
+       * gdk/gdkpixmap.c (gdk_pixmap_colormap_new_from_pixbuf): same
+       * gdk/gdkpixbuf-render.c (gdk_pixbuf_render_threshold_alpha): same
+       * gdk/gdkpixbuf-render.c (gdk_pixbuf_render_pixmap_and_mask_for_colormap): same
+
 Tue Feb 17 23:28:33 2004  Matthias Clasen  <maclas@gmx.de>
 
        * gtk/gtkmenu.c (gtk_menu_init): ...and don't forget to initalize
index 97905bf5662b782cb39f27b274b857174dca122c..79fa0966586a50c0e4509218b26d628537c96ddf 100644 (file)
@@ -1329,7 +1329,6 @@ gdk_drawable_real_draw_pixbuf (GdkDrawable  *drawable,
                               gint          x_dither,
                               gint          y_dither)
 {
-  gboolean free_gc = FALSE;
   GdkPixbuf *composited = NULL;
   gint dwidth, dheight;
   GdkRegion *clip;
@@ -1405,12 +1404,7 @@ gdk_drawable_real_draw_pixbuf (GdkDrawable  *drawable,
     return;
   
   /* Actually draw */
-
-  if (!gc)
-    {
-      gc = gdk_gc_new (drawable);
-      free_gc = TRUE;
-    }
+  gc = _gdk_drawable_get_scratch_gc (drawable, FALSE);
   
   if (pixbuf->has_alpha)
     {
@@ -1535,7 +1529,62 @@ gdk_drawable_real_draw_pixbuf (GdkDrawable  *drawable,
  out:
   if (composited)
     g_object_unref (composited);
+}
+
+/**
+ * _gdk_drawable_get_scratch_gc:
+ * @drawable: A #GdkDrawable
+ * @graphics_exposures: Whether the reutrned #GdkGC should generate graphics exposures 
+ * 
+ * Returns a #GdkGC suitable for drawing on @drawable. The #GdkGC has
+ * the standard values for @drawable, except for the graphics_exposures
+ * field which is determined by the @graphics_exposures parameter.
+ *
+ * The returned #GdkGC must not be altered in any way and must not
+ * be freed.
+ * 
+ * Return value: A #GdkGC suitable for drawing on @drawable
+ * 
+ * Since: 2.4
+ **/
+GdkGC *
+_gdk_drawable_get_scratch_gc (GdkDrawable *drawable,
+                             gboolean     graphics_exposures)
+{
+  GdkScreen *screen;
+  gint depth;
+
+  g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
 
-  if (free_gc)
-    g_object_unref (gc);
+  screen = gdk_drawable_get_screen (drawable);
+
+  g_return_val_if_fail (!screen->closed, NULL);
+
+  depth = gdk_drawable_get_depth (drawable);
+  
+  if (graphics_exposures)
+    {
+      if (!screen->exposure_gcs[depth])
+       {
+         GdkGCValues values;
+         GdkGCValuesMask mask;
+
+         values.graphics_exposures = TRUE;
+         mask = GDK_GC_EXPOSURES;
+         screen->exposure_gcs[depth] =
+           gdk_gc_new_with_values (drawable, &values, mask);
+       }
+
+      return screen->exposure_gcs[depth];
+    }
+  else
+    {
+      if (!screen->normal_gcs[depth])
+       {
+         screen->normal_gcs[depth] =
+           gdk_gc_new (drawable);
+       }
+
+      return screen->normal_gcs[depth];
+    }
 }
index 45c6e1c32726bf8a59886d008d8abd7ffdaa85ae..6f4c5394243862a6546d2952b813263065a45231 100644 (file)
@@ -210,6 +210,10 @@ GdkImage *_gdk_drawable_copy_to_image (GdkDrawable  *drawable,
                                       gint          width,
                                       gint          height);
 
+/* GC caching */
+GdkGC *_gdk_drawable_get_scratch_gc (GdkDrawable *drawable,
+                                    gboolean     graphics_exposures);
+
 /*************************************
  * Interfaces used by windowing code *
  *************************************/
index 8095188d953b79f14b1ffa793a22e2b7af79638b..b93fac33cca428b8880d78dddc9fb7992e8c80d1 100644 (file)
@@ -25,6 +25,7 @@
 #include "gdk-pixbuf-private.h"
 #include "gdkpixbuf.h"
 #include "gdkscreen.h"
+#include "gdkinternals.h"
 
 \f
 
@@ -82,6 +83,7 @@ gdk_pixbuf_render_threshold_alpha (GdkPixbuf *pixbuf,
     return;
 
   gc = gdk_gc_new (bitmap);
+  gc = _gdk_drawable_get_scratch_gc (GDK_DRAWABLE (bitmap), FALSE);
 
   if (!pixbuf->has_alpha)
     {
@@ -130,8 +132,6 @@ gdk_pixbuf_render_threshold_alpha (GdkPixbuf *pixbuf,
                       start + dest_x, y + dest_y,
                       x - 1 + dest_x, y + dest_y);
     }
-       
-  g_object_unref (gc);
 }
 
 \f
@@ -305,13 +305,12 @@ gdk_pixbuf_render_pixmap_and_mask_for_colormap (GdkPixbuf   *pixbuf,
                                       gdk_colormap_get_visual (colormap)->depth);
 
       gdk_drawable_set_colormap (GDK_DRAWABLE (*pixmap_return), colormap);
-      gc = gdk_gc_new (*pixmap_return);
+      gc = _gdk_drawable_get_scratch_gc (*pixmap_return, FALSE);
       gdk_draw_pixbuf (*pixmap_return, gc, pixbuf, 
                       0, 0, 0, 0,
                       gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf),
                       GDK_RGB_DITHER_NORMAL,
                       0, 0);
-      g_object_unref (gc);
     }
   
   if (mask_return)
index efc9763086e9767f2ac8ad2d6adfd43024304bc5..23927763509f4b8af182201550ed7171b8646251 100644 (file)
@@ -529,12 +529,11 @@ gdk_pixmap_colormap_new_from_pixbuf (GdkColormap    *colormap,
   else
     render_pixbuf = pixbuf;
 
-  tmp_gc = gdk_gc_new (pixmap);
+  tmp_gc = _gdk_drawable_get_scratch_gc (pixmap, FALSE);
   gdk_draw_pixbuf (pixmap, tmp_gc, render_pixbuf, 0, 0, 0, 0,
                   gdk_pixbuf_get_width (render_pixbuf),
                   gdk_pixbuf_get_height (render_pixbuf),
                   GDK_RGB_DITHER_NORMAL, 0, 0);
-  g_object_unref (tmp_gc);
 
   if (render_pixbuf != pixbuf)
     g_object_unref (render_pixbuf);
index 0492ab2095a075817689c865d693abac457154b3..329eab9540e87570d5657f6b0a9a501de60d20c2 100644 (file)
 
 #include "gdk.h"               /* For gdk_rectangle_intersect() */
 #include "gdkcolor.h"
-#include "gdkinternals.h"
 #include "gdkwindow.h"
 #include "gdkscreen.h"
 
-static void         gdk_screen_class_init  (GdkScreenClass *klass);
+static void gdk_screen_class_init  (GdkScreenClass *klass);
+static void gdk_screen_dispose     (GObject        *object);
 
 enum
 {
@@ -37,6 +37,8 @@ enum
 
 static guint signals[LAST_SIGNAL] = { 0 };
 
+static gpointer parent_class = NULL;
+
 GType
 gdk_screen_get_type (void)
 {
@@ -67,6 +69,12 @@ gdk_screen_get_type (void)
 static void
 gdk_screen_class_init (GdkScreenClass *klass)
 {
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  parent_class = g_type_class_peek_parent (klass);
+  
+  object_class->dispose = gdk_screen_dispose;
+  
   /**
    * GdkScreen::size-changed:
    * @screen: the object on which the signal is emitted
@@ -87,6 +95,24 @@ gdk_screen_class_init (GdkScreenClass *klass)
                   0);
 }
 
+static void
+gdk_screen_dispose (GObject *object)
+{
+  GdkScreen *screen = GDK_SCREEN (object);
+  gint i;
+
+  for (i = 0; i < 32; ++i)
+    {
+      if (screen->exposure_gcs[i])
+       g_object_unref (screen->exposure_gcs[i]);
+
+      if (screen->normal_gcs[i])
+       g_object_unref (screen->normal_gcs[i]);
+    }
+
+  G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
 void 
 _gdk_screen_close (GdkScreen *screen)
 {
index 6e2241aa5ba993f61ead49e0a198e838a6931ad8..87a7ae0974c7c4a8c9153f9de4172e291c098414 100644 (file)
@@ -43,6 +43,9 @@ struct _GdkScreen
   GObject parent_instance;
 
   guint closed : 1;
+
+  GdkGC *normal_gcs[32];
+  GdkGC *exposure_gcs[32];
 };
 
 struct _GdkScreenClass
index e06881e5cf199fb874d359210db2145a8b10dfec..4d278dcc245b995c2759ae025ba5394c529043b2 100644 (file)
@@ -1020,7 +1020,7 @@ gdk_window_end_paint (GdkWindow *window)
 
   gdk_region_get_clipbox (paint->region, &clip_box);
 
-  tmp_gc = gdk_gc_new (window);
+  tmp_gc = _gdk_drawable_get_scratch_gc (window, FALSE);
 
   _gdk_windowing_window_get_offsets (window, &x_offset, &y_offset);
 
@@ -1033,7 +1033,6 @@ gdk_window_end_paint (GdkWindow *window)
                      clip_box.x - x_offset, clip_box.y - y_offset,
                      clip_box.width, clip_box.height);
 
-  g_object_unref (tmp_gc);
   g_object_unref (paint->pixmap);
   gdk_region_destroy (paint->region);
   g_free (paint);
@@ -1398,7 +1397,7 @@ gdk_window_get_composite_drawable (GdkDrawable *drawable,
     return g_object_ref (drawable);
 
   tmp_pixmap = gdk_pixmap_new (drawable, width, height, -1);
-  tmp_gc = gdk_gc_new (tmp_pixmap);
+  tmp_gc = _gdk_drawable_get_scratch_gc (tmp_pixmap, FALSE);
 
   /* Copy the current window contents */
   gdk_draw_drawable (tmp_pixmap,
@@ -1427,8 +1426,6 @@ gdk_window_get_composite_drawable (GdkDrawable *drawable,
   *composite_x_offset = x;
   *composite_y_offset = y;
 
-  g_object_unref (tmp_gc);
-  
   return tmp_pixmap;
 }
 
index e5d4b30e0d227f6da1a8b2aa7f80417d9164ef9c..d18e9502ebc1bb66ed0bd8515b5dbed433f46936 100644 (file)
@@ -1260,7 +1260,7 @@ draw_with_images (GdkDrawable       *drawable,
 
   dest_pict = gdk_x11_drawable_get_picture (drawable);  
   
-  pix_gc = gdk_gc_new (pix);
+  pix_gc = _gdk_drawable_get_scratch_gc (pix, FALSE);
 
   for (y0 = 0; y0 < height; y0 += GDK_SCRATCH_IMAGE_HEIGHT)
     {
@@ -1291,7 +1291,6 @@ draw_with_images (GdkDrawable       *drawable,
     XRenderFreePicture (xdisplay, mask);
   
   g_object_unref (pix);
-  g_object_unref (pix_gc);
 }
 
 typedef struct _ShmPixmapInfo ShmPixmapInfo;
index 0ad1b5d64ad72982591a415582916b4d734c3dd5..976b1aa98752c360ed6a67c8b3936172bfd337e6 100644 (file)
@@ -226,25 +226,19 @@ gdk_window_copy_area_scroll (GdkWindow    *window,
 
   if (dest_rect->width > 0 && dest_rect->height > 0)
     {
-      GC gc;
-      XGCValues values;
-
-      values.graphics_exposures = True;
-      gc = XCreateGC (GDK_WINDOW_XDISPLAY (window),
-                     GDK_WINDOW_XID (window),
-                     GCGraphicsExposures, &values);
+      GdkGC *gc;
 
+      gc = _gdk_drawable_get_scratch_gc (window, TRUE);
+      
       gdk_window_queue_translation (window, dx, dy);
 
       XCopyArea (GDK_WINDOW_XDISPLAY (window),
                 GDK_WINDOW_XID (window),
                 GDK_WINDOW_XID (window),
-                gc,
+                gdk_x11_gc_get_xgc (gc),
                 dest_rect->x - dx, dest_rect->y - dy,
                 dest_rect->width, dest_rect->height,
                 dest_rect->x, dest_rect->y);
-
-      XFreeGC (GDK_WINDOW_XDISPLAY (window), gc);
     }
 
   tmp_list = obj->children;