Index: native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c =================================================================== RCS file: /cvsroot/classpath/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c,v retrieving revision 1.25 diff -u -p -r1.25 gnu_java_awt_peer_gtk_GdkGraphics2D.c --- native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c 10 Jun 2005 03:56:01 -0000 1.25 +++ native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c 19 Jun 2005 15:02:59 -0000 @@ -275,16 +275,18 @@ begin_drawing_operation (JNIEnv *env, st break; case MODE_JAVA_ARRAY: - gr->javabuf = (*env)->GetIntArrayElements (env, gr->jarray, &gr->isCopy); - gr->surface = cairo_image_surface_create_for_data ((unsigned char *) gr->javabuf, - CAIRO_FORMAT_ARGB32, - gr->width, - gr->height, - gr->width * 4); - g_assert(gr->surface != NULL); - g_assert(gr->cr != NULL); - cairo_destroy (gr->cr); - gr->cr = cairo_create (gr->surface); + { + jboolean isCopy; + gr->javabuf = (*env)->GetPrimitiveArrayCritical (env, gr->jarray, &isCopy); + gr->isCopy |= isCopy; + if (gr->isCopy) + { + /* Make sure that the pixel buffer copy is already initalized, + i.e. we already failed to get direct access in initState. */ + g_assert (gr->javabuf_copy != NULL); + memcpy (gr->javabuf_copy, gr->javabuf, gr->width * gr->height * 4); + } + } break; } } @@ -323,13 +325,9 @@ end_drawing_operation (JNIEnv *env, stru break; case MODE_JAVA_ARRAY: - /* - * FIXME: Perhaps this should use the isCopy flag to try to avoid - * tearing down the cairo surface. - */ - cairo_surface_destroy (gr->surface); - gr->surface = NULL; - (*env)->ReleaseIntArrayElements (env, gr->jarray, gr->javabuf, JNI_COMMIT); + if (gr->isCopy) + memcpy (gr->javabuf, gr->javabuf_copy, gr->width * gr->height * 4); + (*env)->ReleasePrimitiveArrayCritical (env, gr->jarray, gr->javabuf, JNI_COMMIT); } } @@ -416,6 +414,7 @@ Java_gnu_java_awt_peer_gtk_GdkGraphics2D (JNIEnv *env, jobject obj, jintArray jarr, jint width, jint height) { struct graphics2d *gr; + jint *cairobuf; gdk_threads_enter(); gr = (struct graphics2d *) malloc (sizeof (struct graphics2d)); @@ -426,13 +425,35 @@ Java_gnu_java_awt_peer_gtk_GdkGraphics2D if (gr->debug) printf ("constructing java-backed image of size (%d,%d)\n", width, height); - - gr->cr = gdk_cairo_create (gr->drawable); - g_assert (gr->cr != NULL); gr->width = width; gr->height = height; gr->jarray = (*env)->NewGlobalRef(env, jarr); + gr->javabuf = (*env)->GetPrimitiveArrayCritical (env, gr->jarray, &gr->isCopy); + if (gr->isCopy) + { + /* We didn't get direct access to the pixel buffer, so we'll have to + maintain a separate copy for Cairo. */ + jint size = gr->width * gr->height * 4; + gr->javabuf_copy = (jint *) malloc (size); + memcpy (gr->javabuf_copy, gr->javabuf, size); + cairobuf = gr->javabuf_copy; + } + else + { + /* Have Cairo write directly to the Java array. */ + cairobuf = gr->javabuf; + } + gr->surface = cairo_image_surface_create_for_data ((unsigned char *) cairobuf, + CAIRO_FORMAT_ARGB32, + gr->width, + gr->height, + gr->width * 4); + g_assert (gr->surface != NULL); + gr->cr = cairo_create (gr->surface); + g_assert (gr->cr != NULL); + (*env)->ReleasePrimitiveArrayCritical (env, gr->jarray, gr->javabuf, JNI_COMMIT); + gr->mode = MODE_JAVA_ARRAY; if (gr->debug) printf ("constructed java-backed image of size (%d,%d)\n", @@ -612,7 +633,11 @@ Java_gnu_java_awt_peer_gtk_GdkGraphics2D free (gr->pattern_pixels); if (gr->mode == MODE_JAVA_ARRAY) - (*env)->DeleteGlobalRef(env, gr->jarray); + { + (*env)->DeleteGlobalRef(env, gr->jarray); + if (gr->javabuf_copy) + free (gr->javabuf_copy); + } if (gr->debug) printf ("disposed of graphics2d\n"); Index: native/jni/gtk-peer/gtkcairopeer.h =================================================================== RCS file: /cvsroot/classpath/classpath/native/jni/gtk-peer/gtkcairopeer.h,v retrieving revision 1.3 diff -u -p -r1.3 gtkcairopeer.h --- native/jni/gtk-peer/gtkcairopeer.h 26 Dec 2004 13:35:47 -0000 1.3 +++ native/jni/gtk-peer/gtkcairopeer.h 19 Jun 2005 15:02:59 -0000 @@ -86,6 +86,7 @@ struct graphics2d jintArray jarray; jint width, height; jint *javabuf; + jint *javabuf_copy; jboolean isCopy; };