Hi,
This code extends the CairoSurface optimization I submitted a few days
ago, adding fallback code for VMs that copy JNI arrays rather than
pinning them.
Also included is some cleanup, removing various un-used CairoSurface methods.
Cheers,
Francis
2007-02-21 Francis Kung <[EMAIL PROTECTED]>
* gnu/java/awt/peer/gtk/BufferedImageGraphcs.java
(constructor): Add pre-multiplied colour model to types available for
optimization.
(updateBufferedImage): Change surface.getPixels() call to
surface.getData().
* gnu/java/awt/peer/gtk/CairoGraphics2D.java
(drawImage): Add checks before using CairoSurface optimization.
* gnu/java/awt/peer/gtk/CairoSurface.java
(bufferPointer): Removed field.
(sharedBuffer): New field.
(CairoSurface(GtkImage)): Copy array rather than using setPixels() call.
(CairoSurface(int,int,int)): Use getData() convenience method.
(CairoSurface(SampleModel,CairoSurface,Rectangle,Point)): Remove
reference
to deleted bufferPointer field.
(copyAreaNative): Update documentation, remove reference to
bufferPointer.
(copyAreaNative2): Remove reference to deleted bufferPointer field.
(destroy): Remove reference to deleted bufferPointer field.
(dispose): Updated to reflect new method signature for destroy().
(drawSurface): Added documentation.
(getData): New convience method.
(getFlippedBuffer): Removed method parameters.
(getGtkImage): Updated to reflect new method signature.
(getPixels): Removed method.
(nativeGetElem): Removed method.
(netiveGetPixels): Removed method.
(nativeSetElem): Removed method.
(nativeSetPixels): Removed method.
(setPixels): Removed method.
(syncJavaToNative): New method.
(syncNativeToJava): New method.
* gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java
(draw): Sync buffers if necessary.
(drawGlyphVector): Likewise.
(drawImage): Likewise.
(drawRenderedImage): Likewise,
(fill): Likewise.
* include/gnu_java_awt_peer_gtk_CairoSurface.h: Regenerated.
* native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c
(Java_gnu_java_awt_peer_gtk_CairoSurface_copyAreaNative2): Use pointer
to
surface rather than pointer to buffer.
(Java_gnu_java_awt_peer_gtk_CairoSurface_create): Provide fall-back for
copied arrays.
(Java_gnu_java_awt_peer_gtk_CairoSurface_destroy): Handle copied arrays.
(Java_gnu_java_awt_peer_gtk_CairoSurface_getFlippedBuffer): Retrieve
information on size using JNI calls.
(Java_gnu_java_awt_peer_gtk_CairoSurface_getElem): Removed.
(Java_gnu_java_awt_peer_gtk_CairoSurface_getPixels): Removed.
(Java_gnu_java_awt_peer_gtk_CairoSurface_setElem): Removed.
(Java_gnu_java_awt_peer_gtk_CairoSurface_setPixels): Removed.
(Java_gnu_java_awt_peer_gtk_CairoSurface_syncJavaToNative): New
function.
(Java_gnu_java_awt_peer_gtk_CairoSurface_syncNativeToJava): New
function.
(BUFFER): Removed constant.
(SHARED): New constant.
Index: gnu/java/awt/peer/gtk/CairoSurface.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/CairoSurface.java,v
retrieving revision 1.24
diff -u -r1.24 CairoSurface.java
--- gnu/java/awt/peer/gtk/CairoSurface.java 16 Feb 2007 20:28:45 -0000 1.24
+++ gnu/java/awt/peer/gtk/CairoSurface.java 21 Feb 2007 21:26:54 -0000
@@ -1,5 +1,5 @@
/* CairoSurface.java
- Copyright (C) 2006 Free Software Foundation, Inc.
+ Copyright (C) 2006, 2007 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -73,9 +73,9 @@
long surfacePointer;
/**
- * The native pointer to the image's data buffer
+ * Whether the data buffer is shared between java and cairo.
*/
- long bufferPointer;
+ boolean sharedBuffer;
// FIXME: use only the cairoCM_pre colormodel
// since that's what Cairo really uses (is there a way to do this cheaply?
@@ -108,17 +108,7 @@
/**
* Destroys the cairo surface and frees the buffer.
*/
- private native void destroy(long surfacePointer, long bufferPointer, int[] buf);
-
- /**
- * Gets buffer elements
- */
- private native int nativeGetElem(long bufferPointer, int i);
-
- /**
- * Sets buffer elements.
- */
- private native void nativeSetElem(long bufferPointer, int i, int val);
+ private native void destroy(long surfacePointer, int[] buf);
/**
* Draws this image to a given CairoGraphics context,
@@ -128,6 +118,30 @@
double[] i2u, double alpha,
int interpolation);
+ /**
+ * Synchronizes the image's data buffers, copying any changes made in the
+ * Java array into the native array.
+ *
+ * This method should only be called if (sharedBuffers == false).
+ */
+ native void syncNativeToJava(long surfacePointer, int[] buffer);
+
+ /**
+ * Synchronizes the image's data buffers, copying any changes made in the
+ * native array into the Java array.
+ *
+ * This method should only be called if (sharedBuffers == false).
+ */
+ native void syncJavaToNative(long surfacePointer, int[] buffer);
+
+ /**
+ * Draw this CairoSurface image onto a given Cairo context.
+ *
+ * @param contextPointer A pointer to the context to draw onto.
+ * @param i2u The transformation matrix (cannot be null).
+ * @param alpha The alpha value to paint with ( 0 <= alpha <= 1).
+ * @param interpolation The interpolation type, as defined in CairoGraphcs2D.
+ */
public void drawSurface(long contextPointer, double[] i2u, double alpha,
int interpolation)
{
@@ -135,26 +149,13 @@
}
/**
- * getPixels -return the pixels as a java array.
- */
- native int[] nativeGetPixels(long bufferPointer, int size);
-
- public int[] getPixels(int size)
- {
- return nativeGetPixels(bufferPointer, size);
- }
-
- /**
- * getPixels -return the pixels as a java array.
+ * Return the buffer, with the sample values of each pixel reversed
+ * (ie, in ABGR instead of ARGB).
+ *
+ * @return A pointer to a flipped buffer. The memory is allocated in native
+ * code, and must be explicitly freed when it is no longer needed.
*/
- native void nativeSetPixels(long bufferPointer, int[] pixels);
-
- public void setPixels(int[] pixels)
- {
- nativeSetPixels(bufferPointer, pixels);
- }
-
- native long getFlippedBuffer(long bufferPointer, int size);
+ native long getFlippedBuffer();
/**
* Create a cairo_surface_t with specified width and height.
@@ -168,8 +169,7 @@
public CairoSurface(int x, int y, int width, int height)
{
- super(createCairoSampleModel(width, height),
- null, new Point(x, y));
+ super(createCairoSampleModel(width, height), null, new Point(x, y));
if(width <= 0 || height <= 0)
throw new IllegalArgumentException("Image must be at least 1x1 pixels.");
@@ -177,11 +177,10 @@
this.width = width;
this.height = height;
dataBuffer = new DataBufferInt(width * height);
- create(width, height, width, ((DataBufferInt)dataBuffer).getData());
+ create(width, height, width, getData());
- if(surfacePointer == 0 || bufferPointer == 0)
+ if(surfacePointer == 0)
throw new Error("Could not allocate bitmap.");
-
}
/**
@@ -194,7 +193,6 @@
this.width = parent.width;
this.height = parent.height;
- this.bufferPointer = parent.bufferPointer;
this.surfacePointer = parent.surfacePointer;
this.dataBuffer = parent.dataBuffer;
}
@@ -245,7 +243,7 @@
}
}
- setPixels( data );
+ System.arraycopy(data, 0, getData(), 0, data.length);
}
/**
@@ -254,8 +252,7 @@
public void dispose()
{
if(surfacePointer != 0 && parent == null)
- destroy(surfacePointer, bufferPointer,
- ((DataBufferInt)dataBuffer).getData());
+ destroy(surfacePointer, getData());
}
/**
@@ -271,8 +268,17 @@
*/
public GtkImage getGtkImage()
{
- return new GtkImage( width, height,
- getFlippedBuffer(bufferPointer, width * height ));
+ return new GtkImage(width, height, getFlippedBuffer());
+ }
+
+ /**
+ * Convenience method to quickly grab the data array backing this Raster.
+ *
+ * @return The array behind the databuffer.
+ */
+ public int[] getData()
+ {
+ return ((DataBufferInt)dataBuffer).getData();
}
/**
@@ -323,16 +329,24 @@
}
/**
- * Copy an area of the surface. Expects parameters must be within bounds.
- * Count on a segfault otherwise.
+ * Copy a portion of this surface to another area on the surface. The given
+ * parameters must be within bounds - count on a segfault otherwise.
+ *
+ * @param x The x coordinate of the area to be copied from.
+ * @param y The y coordinate of the area to be copied from.
+ * @param width The width of the area to be copied.
+ * @param height The height of the area to be copied.
+ * @param dx The destination x coordinate.
+ * @param dy The destination y coordinate.
+ * @param stride The scanline stride.
*/
- native void copyAreaNative2(long bufferPointer, int x, int y, int width,
- int height, int dx, int dy, int stride);
public void copyAreaNative(int x, int y, int width,
int height, int dx, int dy, int stride)
{
- copyAreaNative2(bufferPointer, x, y, width, height, dx, dy, stride);
+ copyAreaNative2(x, y, width, height, dx, dy, stride);
}
+ native void copyAreaNative2(int x, int y, int width, int height,
+ int dx, int dy, int stride);
/**
* Creates a SampleModel that matches Cairo's native format
Index: gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java,v
retrieving revision 1.9
diff -u -r1.9 CairoSurfaceGraphics.java
--- gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java 16 Feb 2007 20:28:45 -0000 1.9
+++ gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java 21 Feb 2007 21:26:54 -0000
@@ -116,6 +116,9 @@
*/
public void draw(Shape s)
{
+ if (!surface.sharedBuffer)
+ surface.syncJavaToNative(surface.surfacePointer, surface.getData());
+
// Find total bounds of shape
Rectangle r = findStrokedBounds(s);
if (shiftDrawCalls)
@@ -140,10 +143,16 @@
drawComposite(r.getBounds2D(), null);
}
+
+ if (!surface.sharedBuffer)
+ surface.syncNativeToJava(surface.surfacePointer, surface.getData());
}
public void fill(Shape s)
{
+ if (!surface.sharedBuffer)
+ surface.syncJavaToNative(surface.surfacePointer, surface.getData());
+
if (comp == null || comp instanceof AlphaComposite)
super.fill(s);
@@ -159,10 +168,16 @@
drawComposite(s.getBounds2D(), null);
}
+
+ if (!surface.sharedBuffer)
+ surface.syncNativeToJava(surface.surfacePointer, surface.getData());
}
public void drawRenderedImage(RenderedImage image, AffineTransform xform)
{
+ if (!surface.sharedBuffer)
+ surface.syncJavaToNative(surface.surfacePointer, surface.getData());
+
if (comp == null || comp instanceof AlphaComposite)
super.drawRenderedImage(image, xform);
@@ -177,14 +192,20 @@
drawComposite(buffer.getRaster().getBounds(), null);
}
-
+
+ if (!surface.sharedBuffer)
+ surface.syncNativeToJava(surface.surfacePointer, surface.getData());
}
protected boolean drawImage(Image img, AffineTransform xform,
Color bgcolor, ImageObserver obs)
{
+ if (!surface.sharedBuffer)
+ surface.syncJavaToNative(surface.surfacePointer, surface.getData());
+
+ boolean ret;
if (comp == null || comp instanceof AlphaComposite)
- return super.drawImage(img, xform, bgcolor, obs);
+ ret = super.drawImage(img, xform, bgcolor, obs);
else
{
@@ -212,12 +233,20 @@
g2d.drawImage(img, xform, obs);
// Perform compositing
- return drawComposite(bounds, obs);
+ ret = drawComposite(bounds, obs);
}
+
+ if (!surface.sharedBuffer)
+ surface.syncNativeToJava(surface.surfacePointer, surface.getData());
+
+ return ret;
}
public void drawGlyphVector(GlyphVector gv, float x, float y)
{
+ if (!surface.sharedBuffer)
+ surface.syncJavaToNative(surface.surfacePointer, surface.getData());
+
if (comp == null || comp instanceof AlphaComposite)
super.drawGlyphVector(gv, x, y);
@@ -235,6 +264,9 @@
bounds.getWidth(), bounds.getHeight());
drawComposite(bounds, null);
}
+
+ if (!surface.sharedBuffer)
+ surface.syncNativeToJava(surface.surfacePointer, surface.getData());
}
private boolean drawComposite(Rectangle2D bounds, ImageObserver observer)
Index: gnu/java/awt/peer/gtk/CairoGraphics2D.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/CairoGraphics2D.java,v
retrieving revision 1.63
diff -u -r1.63 CairoGraphics2D.java
--- gnu/java/awt/peer/gtk/CairoGraphics2D.java 12 Feb 2007 21:39:20 -0000 1.63
+++ gnu/java/awt/peer/gtk/CairoGraphics2D.java 21 Feb 2007 21:26:53 -0000
@@ -1520,7 +1520,9 @@
if (comp instanceof AlphaComposite)
alpha = ((AlphaComposite) comp).getAlpha();
- if(raster instanceof CairoSurface)
+ if(raster instanceof CairoSurface
+ && ((CairoSurface)raster).getParent() == null
+ && ((CairoSurface)raster).sharedBuffer == true)
{
((CairoSurface)raster).drawSurface(nativePointer, i2u, alpha,
getInterpolation());
Index: gnu/java/awt/peer/gtk/BufferedImageGraphics.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/BufferedImageGraphics.java,v
retrieving revision 1.24
diff -u -r1.24 BufferedImageGraphics.java
--- gnu/java/awt/peer/gtk/BufferedImageGraphics.java 12 Feb 2007 21:39:20 -0000 1.24
+++ gnu/java/awt/peer/gtk/BufferedImageGraphics.java 21 Feb 2007 21:26:52 -0000
@@ -112,7 +112,8 @@
hasFastCM = true;
hasAlpha = false;
}
- else if(bi.getColorModel().equals(CairoSurface.cairoColorModel))
+ else if(bi.getColorModel().equals(CairoSurface.cairoColorModel)
+ || bi.getColorModel().equals(CairoSurface.cairoCM_pre))
{
hasFastCM = true;
hasAlpha = true;
@@ -142,10 +143,7 @@
int minY = image.getRaster().getSampleModelTranslateY();
// Pull pixels directly out of data buffer
- if(raster instanceof CairoSurface)
- pixels = ((CairoSurface)raster).getPixels(raster.getWidth() * raster.getHeight());
- else
- pixels = ((DataBufferInt)raster.getDataBuffer()).getData();
+ pixels = ((DataBufferInt)raster.getDataBuffer()).getData();
// Discard pixels that fall outside of the image's bounds
// (ie, this image is actually a subimage of a different image)
@@ -170,10 +168,11 @@
{
pixels = CairoGraphics2D.findSimpleIntegerArray(image.getColorModel(),
image.getData());
+ if (pixels != null)
+ System.arraycopy(pixels, 0, surface.getData(),
+ 0, pixels.length);
}
- surface.setPixels( pixels );
-
setup( cairo_t );
setClip(0, 0, imageWidth, imageHeight);
}
@@ -204,7 +203,7 @@
width = bounds.width;
height = bounds.height;
- int[] pixels = surface.getPixels(imageWidth * imageHeight);
+ int[] pixels = surface.getData();
if( x > imageWidth || y > imageHeight )
return;
Index: native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c
===================================================================
RCS file: /cvsroot/classpath/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c,v
retrieving revision 1.22
diff -u -r1.22 gnu_java_awt_peer_gtk_CairoSurface.c
--- native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c 16 Feb 2007 20:28:46 -0000 1.22
+++ native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c 21 Feb 2007 21:26:54 -0000
@@ -47,7 +47,7 @@
* Field names in CairoSurface.java
*/
#define SURFACE "surfacePointer"
-#define BUFFER "bufferPointer"
+#define SHARED "sharedBuffer"
/* prototypes */
static void setNativeObject( JNIEnv *env, jobject obj, void *ptr, const char *pointer );
@@ -62,10 +62,29 @@
{
cairo_surface_t* surface;
jboolean isCopy;
+
+ /* Retrieve java-created data array */
void *data = (*env)->GetIntArrayElements (env, buf, &isCopy);
-/* FIXME: provide fallback if (isCopy == true) */
- setNativeObject(env, obj, data, BUFFER);
+
+ /* Set sharedBuffer variable */
+ jclass cls = (*env)->GetObjectClass (env, obj);
+ jfieldID field = (*env)->GetFieldID (env, cls, SHARED, "Z");
+ g_assert (field != 0);
+
+ isCopy = JNI_TRUE;
+
+ if (isCopy == JNI_TRUE)
+ {
+ (*env)->SetBooleanField (env, obj, field, JNI_FALSE);
+ void* temp = g_malloc(stride * height * 4);
+ memcpy(temp, data, stride * height * 4);
+ (*env)->ReleaseIntArrayElements (env, buf, data, 0);
+ data = temp;
+ }
+ else
+ (*env)->SetBooleanField (env, obj, field, JNI_TRUE);
+ /* Create the cairo surface and set the java pointer */
surface = cairo_image_surface_create_for_data
(data, CAIRO_FORMAT_ARGB32, width, height, stride * 4);
@@ -78,109 +97,28 @@
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_CairoSurface_destroy
(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
- jlong surfacePointer, jlong bufferPointer, jintArray buf)
+ jlong surfacePointer, jintArray buf)
{
- void *buffer;
cairo_surface_t* surface = JLONG_TO_PTR(void, surfacePointer);
- buffer = JLONG_TO_PTR(void, bufferPointer);
+ void *data = cairo_image_surface_get_data(surface);
if( surface != NULL )
{
- (*env)->ReleaseIntArrayElements (env, buf, buffer, 0);
+ /* Release or free the data buffer as appropriate */
+ jclass cls = (*env)->GetObjectClass (env, obj);
+ jfieldID field = (*env)->GetFieldID (env, cls, SHARED, "Z");
+ g_assert (field != 0);
+ jboolean sharedBuffer = (*env)->GetBooleanField (env, obj, field);
+
+ if (sharedBuffer == JNI_TRUE)
+ (*env)->ReleaseIntArrayElements (env, buf, data, 0);
+ else
+ g_free(data);
+
+ /* Destroy the cairo surface itself */
cairo_surface_destroy(surface);
}
}
-/**
- * Gets a pixel
- */
-JNIEXPORT jint JNICALL
-Java_gnu_java_awt_peer_gtk_CairoSurface_nativeGetElem
-(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
- jlong bufferPointer, jint i)
-{
- jint *pixeldata = JLONG_TO_PTR(void, bufferPointer);
-
- if( pixeldata == NULL )
- return 0;
-
- return pixeldata[i];
-}
-
-/**
- * Sets a pixel
- */
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_CairoSurface_nativeSetElem
-(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
- jlong bufferPointer, jint i, jint val)
-{
- jint *pixeldata = JLONG_TO_PTR(void, bufferPointer);
-
- if( pixeldata == NULL )
- return;
-
- pixeldata[i] = val;
-}
-
-/**
- * Gets all pixels in an array
- */
-JNIEXPORT jintArray JNICALL
-Java_gnu_java_awt_peer_gtk_CairoSurface_nativeGetPixels
-(JNIEnv *env __attribute((unused)), jobject obj __attribute((unused)),
- jlong bufferPointer, int size)
-{
- jint *pixeldata, *jpixdata;
- jintArray jpixels;
-
- pixeldata = JLONG_TO_PTR(void, bufferPointer);
- g_assert(pixeldata != NULL);
-
- jpixels = (*env)->NewIntArray (env, size);
- jpixdata = (*env)->GetIntArrayElements (env, jpixels, NULL);
- memcpy (jpixdata, pixeldata, size * sizeof( jint ));
-
- (*env)->ReleaseIntArrayElements (env, jpixels, jpixdata, 0);
- return jpixels;
-}
-
-/**
- * Sets all pixels by an array.
- */
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_CairoSurface_nativeSetPixels
-(JNIEnv *env, jobject obj, jlong bufferPointer, jintArray jpixels)
-{
- jint *pixeldata, *jpixdata;
- int size;
- int width, height;
- jclass cls;
- jfieldID field;
-
- if( jpixels == NULL )
- return;
-
- cls = (*env)->GetObjectClass (env, obj);
- field = (*env)->GetFieldID (env, cls, "width", "I");
- g_assert (field != 0);
- width = (*env)->GetIntField (env, obj, field);
-
- field = (*env)->GetFieldID (env, cls, "height", "I");
- g_assert (field != 0);
- height = (*env)->GetIntField (env, obj, field);
-
- pixeldata = JLONG_TO_PTR(void, bufferPointer);
- g_assert(pixeldata != NULL);
-
- jpixdata = (*env)->GetIntArrayElements (env, jpixels, NULL);
- size = (*env)->GetArrayLength( env, jpixels );
- if( size > width * height ) size = width * height; /* stop overflows. */
-
- memcpy (pixeldata, jpixdata, size * sizeof( jint ));
-
- (*env)->ReleaseIntArrayElements (env, jpixels, jpixdata, 0);
-}
-
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_CairoSurface_nativeDrawSurface
(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
@@ -246,17 +184,35 @@
JNIEXPORT jlong JNICALL
Java_gnu_java_awt_peer_gtk_CairoSurface_getFlippedBuffer
(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
- jlong bufferPointer, jint size)
+ jlong surfacePointer)
{
+ cairo_surface_t* surface;
+ jint *src;
jint *dst;
- jint *src = JLONG_TO_PTR(void, bufferPointer);
- int i;
- int t;
+ int i, t, width, height;
+ jclass cls;
+ jfieldID field;
+ /* Retrieve pointer to cairo data buffer */
+ surface = JLONG_TO_PTR(void, surfacePointer);
+ src = (jint*)cairo_image_surface_get_data(surface);
+
+ /* Retrieve dimensions of surface, from java fields */
+ cls = (*env)->GetObjectClass (env, obj);
+ field = (*env)->GetFieldID (env, cls, "width", "I");
+ g_assert (field != 0);
+ width = (*env)->GetIntField (env, obj, field);
+
+ field = (*env)->GetFieldID (env, cls, "height", "I");
+ g_assert (field != 0);
+ height = (*env)->GetIntField (env, obj, field);
+
+ /* Create destination array */
g_assert( src != NULL );
- dst = g_malloc( size * sizeof( jint ) );
+ dst = g_malloc( width * height * sizeof( jint ) );
- for(i = 0; i < size; i++ )
+ /* Copy data into destination array, reversing sample order of each pixel */
+ for(i = 0; i < (height * width); i++ )
{
t = (src[i] & 0x0000FF) << 16;
dst[i] = (src[i] & 0x00FF0000) >> 16;
@@ -290,24 +246,30 @@
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_CairoSurface_copyAreaNative2
(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
- jlong bufferPointer,
+ jlong surfacePointer,
jint x, jint y, jint w, jint h, jint dx, jint dy, jint stride)
{
int row;
int srcOffset, dstOffset;
jint *temp;
- jint *pixeldata = JLONG_TO_PTR(jint, bufferPointer);
+
+ /* Retrieve pointer to cairo data buffer */
+ cairo_surface_t* surface = JLONG_TO_PTR(void, surfacePointer);
+ jint *pixeldata = (jint*)cairo_image_surface_get_data(surface);
g_assert( pixeldata != NULL );
+ /* Create temporary buffer and calculate offsets */
temp = g_malloc( h * w * 4 );
g_assert( temp != NULL );
srcOffset = x + (y * stride);
dstOffset = (x + dx) + ((y + dy) * stride);
+ /* Copy desired region into temporary buffer */
for( row = 0; row < h; row++ )
memcpy( temp + (w * row), pixeldata + srcOffset + (stride * row), w * 4 );
+ /* Copy out of buffer and to destination */
for( row = 0; row < h; row++ )
memcpy( pixeldata + dstOffset + (stride * row), temp + (w * row), w * 4 );
@@ -315,6 +277,50 @@
}
/*
+ * Synchronizes the java and native data buffers, copying any changes made in
+ * the java array into the native array.
+ * This method should only be called if (sharedBuffer == false).
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoSurface_syncJavaToNative
+(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
+ jlong surfacePointer, jintArray buffer)
+{
+ /* Get size of java array */
+ int size = (*env)->GetArrayLength(env, buffer);
+
+ /* Get native data buffer */
+ cairo_surface_t* surface = JLONG_TO_PTR(void, surfacePointer);
+ g_assert(surface != NULL);
+ void* nativeBuffer = cairo_image_surface_get_data(surface);
+
+ /* Sync buffers */
+ (*env)->GetIntArrayRegion(env, buffer, 0, size, nativeBuffer);
+}
+
+/*
+ * Synchronizes the java and native data buffers, copying any changes made in
+ * the native array into the java array.
+ * This method should only be called if (sharedBuffer == false).
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoSurface_syncNativeToJava
+(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
+ jlong surfacePointer, jintArray buffer)
+{
+ /* Get size of java array */
+ int size = (*env)->GetArrayLength(env, buffer);
+
+ /* Get native data buffer */
+ cairo_surface_t* surface = JLONG_TO_PTR(void, surfacePointer);
+ g_assert(surface != NULL);
+ void* nativeBuffer = cairo_image_surface_get_data(surface);
+
+ /* Sync buffers */
+ (*env)->SetIntArrayRegion(env, buffer, 0, size, nativeBuffer);
+}
+
+/*
* Sets the native object field.
*/
static void
Index: include/gnu_java_awt_peer_gtk_CairoSurface.h
===================================================================
RCS file: /cvsroot/classpath/classpath/include/gnu_java_awt_peer_gtk_CairoSurface.h,v
retrieving revision 1.8
diff -u -r1.8 gnu_java_awt_peer_gtk_CairoSurface.h
--- include/gnu_java_awt_peer_gtk_CairoSurface.h 16 Feb 2007 20:28:46 -0000 1.8
+++ include/gnu_java_awt_peer_gtk_CairoSurface.h 21 Feb 2007 21:26:54 -0000
@@ -11,15 +11,13 @@
#endif
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoSurface_create (JNIEnv *env, jobject, jint, jint, jint, jintArray);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoSurface_destroy (JNIEnv *env, jobject, jlong, jlong, jintArray);
-JNIEXPORT jint JNICALL Java_gnu_java_awt_peer_gtk_CairoSurface_nativeGetElem (JNIEnv *env, jobject, jlong, jint);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoSurface_nativeSetElem (JNIEnv *env, jobject, jlong, jint, jint);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoSurface_destroy (JNIEnv *env, jobject, jlong, jintArray);
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoSurface_nativeDrawSurface (JNIEnv *env, jobject, jlong, jlong, jdoubleArray, jdouble, jint);
-JNIEXPORT jintArray JNICALL Java_gnu_java_awt_peer_gtk_CairoSurface_nativeGetPixels (JNIEnv *env, jobject, jlong, jint);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoSurface_nativeSetPixels (JNIEnv *env, jobject, jlong, jintArray);
-JNIEXPORT jlong JNICALL Java_gnu_java_awt_peer_gtk_CairoSurface_getFlippedBuffer (JNIEnv *env, jobject, jlong, jint);
+JNIEXPORT jlong JNICALL Java_gnu_java_awt_peer_gtk_CairoSurface_getFlippedBuffer (JNIEnv *env, jobject, jlong);
JNIEXPORT jlong JNICALL Java_gnu_java_awt_peer_gtk_CairoSurface_nativeNewCairoContext (JNIEnv *env, jobject, jlong);
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoSurface_copyAreaNative2 (JNIEnv *env, jobject, jlong, jint, jint, jint, jint, jint, jint, jint);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoSurface_syncJavaToNative (JNIEnv *env, jobject, jlong, jintArray);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoSurface_syncNativeToJava (JNIEnv *env, jobject, jlong, jintArray);
#ifdef __cplusplus
}