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);