Hi,

I ported my rate-limited flushing patch to GdkGraphics2D. For an explanation, see my original post:

http://developer.classpath.org/pipermail/classpath-patches/2006-March/001051.html

The patch makes animations less choppy and painting more efficient.

Tom

2006-05-25  Thomas Fitzsimmons  <[EMAIL PROTECTED]>

        * native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c
        (schedule_flush): New function.
        (end_drawing_operation): Call schedule_flush.
Index: native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c
===================================================================
RCS file: /sources/classpath/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c,v
retrieving revision 1.39
diff -u -r1.39 gnu_java_awt_peer_gtk_GdkGraphics2D.c
--- native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c	25 May 2006 15:29:36 -0000	1.39
+++ native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c	25 May 2006 20:59:05 -0000
@@ -54,6 +54,49 @@
 
 struct state_table *cp_gtk_native_graphics2d_state_table;
 
+/*
+ * AWT applications may call Graphics methods from threads other than
+ * the GDK main thread, so we must call XFlush after each batch of
+ * drawing operations, otherwise animations flicker.  Flushing after
+ * every graphics operation is excessive and negatively affects
+ * performance (PR 26486).  We set the maximum frequency to 50 times
+ * per second, or a minimum period of 20 milliseconds between calls to
+ * XFlush.  See gnu.classpath.examples.awt.AnimationApplet for an
+ * example applet that requires these XFlush calls.
+ */
+
+static short flush_scheduled = 0;
+
+static gboolean flush (gpointer data __attribute__((unused)))
+{
+  gdk_threads_enter ();
+
+  cp_gtk_print_current_thread ();
+  g_print ("flush\n");
+
+  XFlush (GDK_DISPLAY ());
+  flush_scheduled = 0;
+
+  gdk_threads_leave ();
+
+  return FALSE;
+}
+
+/* The minimum time period between calls to XFlush, in
+   milliseconds. */
+#define MINIMUM_FLUSH_PERIOD 20
+
+/* schedule_flush must be called with the GDK lock held. */
+static void
+schedule_flush ()
+{
+  if (!flush_scheduled)
+    {
+      g_timeout_add (MINIMUM_FLUSH_PERIOD, flush, NULL);
+      flush_scheduled = 1;
+    }
+}
+
 JNIEXPORT void JNICALL
 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initStaticState 
   (JNIEnv *env, jclass clazz)
@@ -331,6 +374,8 @@
 	memcpy (gr->javabuf, gr->javabuf_copy, gr->width * gr->height * 4);
       (*env)->ReleasePrimitiveArrayCritical (env, gr->jarray, gr->javabuf, JNI_COMMIT);
     }
+
+  schedule_flush ();
 }
 
 
@@ -567,8 +612,6 @@
   if (src->pattern)
     cairo_pattern_set_matrix (src->pattern, &matrix);
 
-  gdk_flush();
-
   end_drawing_operation(env, dst);
 
   if (src->debug) printf ("copied %d x %d pixels from offscreen drawable\n", width, height);

Reply via email to