view patches/xrender/icedtea-001.patch @ 1836:51313371451a

* patches/xrender/icedtea-001.patch: Initialize X11SurfaceData implicitly, not explicitly.
author Mark Wielaard <mark@klomp.org>
date Mon, 25 May 2009 00:26:26 +0200
parents 9c44278ad34b
children
line wrap: on
line source

diff -Nru openjdk.orig/jdk/make/sun/font/FILES_c.gmk openjdk/jdk/make/sun/font/FILES_c.gmk
--- openjdk.orig/jdk/make/sun/font/FILES_c.gmk	2009-03-30 17:23:03.000000000 +0100
+++ openjdk/jdk/make/sun/font/FILES_c.gmk	2009-05-13 01:02:29.000000000 +0100
@@ -119,6 +119,7 @@
 FILES_cpp_platform =
 else
 FILES_c_platform = X11FontScaler.c \
+                   XRTextRenderer.c \
                    X11TextRenderer.c
 FILES_cpp_platform =
 endif
diff -Nru openjdk.orig/jdk/make/sun/font/Makefile openjdk/jdk/make/sun/font/Makefile
--- openjdk.orig/jdk/make/sun/font/Makefile	2009-05-13 00:07:23.000000000 +0100
+++ openjdk/jdk/make/sun/font/Makefile	2009-05-13 01:02:29.000000000 +0100
@@ -86,6 +86,7 @@
     sun/font/NativeStrike.java \
     sun/font/NativeStrikeDisposer.java \
     sun/font/X11TextRenderer.java \
+    sun/font/XRTextRenderer.java \
     sun/awt/X11GraphicsEnvironment.java 
 
 endif # PLATFORM
diff -Nru openjdk.orig/jdk/make/sun/font/mapfile-vers openjdk/jdk/make/sun/font/mapfile-vers
--- openjdk.orig/jdk/make/sun/font/mapfile-vers	2009-03-30 17:23:03.000000000 +0100
+++ openjdk/jdk/make/sun/font/mapfile-vers	2009-05-13 01:02:29.000000000 +0100
@@ -63,6 +63,7 @@
                 Java_sun_font_NativeFont_getGlyphImage;
                 Java_sun_font_NativeFont_getGlyphImageNoDefault;
                 Java_sun_font_NativeFont_getFontMetrics;
+                Java_sun_font_XRTextRenderer_doDrawGlyphList;
 	local:
 		*;
 };
diff -Nru openjdk.orig/jdk/make/sun/font/mapfile-vers.openjdk openjdk/jdk/make/sun/font/mapfile-vers.openjdk
--- openjdk.orig/jdk/make/sun/font/mapfile-vers.openjdk	2009-03-30 17:23:03.000000000 +0100
+++ openjdk/jdk/make/sun/font/mapfile-vers.openjdk	2009-05-13 01:02:29.000000000 +0100
@@ -82,6 +82,7 @@
                 Java_sun_font_FreetypeFontScaler_getUnitsPerEMNative;
                 Java_sun_font_FreetypeFontScaler_initNativeScaler;
                 Java_sun_font_FreetypeFontScaler_getGlyphPointNative;
+                Java_sun_font_XRTextRenderer_doDrawGlyphList;
 	local:
 		*;
 };
diff -Nru openjdk.orig/jdk/make/sun/xawt/FILES_c_unix.gmk openjdk/jdk/make/sun/xawt/FILES_c_unix.gmk
--- openjdk.orig/jdk/make/sun/xawt/FILES_c_unix.gmk	2009-05-08 16:10:44.000000000 +0100
+++ openjdk/jdk/make/sun/xawt/FILES_c_unix.gmk	2009-05-13 01:03:14.000000000 +0100
@@ -79,4 +79,11 @@
 	gtk2_interface.c \
         swing_GTKEngine.c \
         swing_GTKStyle.c \
-        rect.c
+        rect.c \
+	ArrayList.c \
+ 	MaskBuffer.c \
+ 	XRSurfaceData.c \
+ 	XRGlyphCache.c \
+ 	XRTextRenderer_md.c \
+        XRRenderer.c \
+        XRPMBlitLoops.c
diff -Nru openjdk.orig/jdk/make/sun/xawt/Makefile openjdk/jdk/make/sun/xawt/Makefile
--- openjdk.orig/jdk/make/sun/xawt/Makefile	2009-05-08 16:10:44.000000000 +0100
+++ openjdk/jdk/make/sun/xawt/Makefile	2009-05-13 01:02:29.000000000 +0100
@@ -87,7 +87,7 @@
 vpath %.c   $(PLATFORM_SRC)/native/sun/java2d/opengl
 vpath %.c   $(PLATFORM_SRC)/native/sun/java2d/x11
 
-OTHER_LDLIBS = $(LIBM) -lawt -lXext -lX11 -ldl \
+OTHER_LDLIBS = $(LIBM) -lawt -lXext -lX11 -lXrender -ldl \
                    $(LDFLAGS_COMMON) $(AWT_RUNPATH) $(OTHER_LDFLAGS) -lXtst -lXi
 
 ifeq  ($(PLATFORM), solaris)
diff -Nru openjdk.orig/jdk/make/sun/xawt/mapfile-vers openjdk/jdk/make/sun/xawt/mapfile-vers
--- openjdk.orig/jdk/make/sun/xawt/mapfile-vers	2009-05-08 16:10:44.000000000 +0100
+++ openjdk/jdk/make/sun/xawt/mapfile-vers	2009-05-13 01:02:29.000000000 +0100
@@ -367,6 +367,33 @@
         Java_sun_java2d_x11_X11SurfaceData_XSetForeground;
         Java_sun_java2d_x11_X11SurfaceData_XSetGraphicsExposures;
 
+        Java_sun_java2d_xr_XRSurfaceData_flushNativeSurface;
+        Java_sun_java2d_xr_XRSurfaceData_XRIsDrawableValid;
+        Java_sun_java2d_xr_XRSurfaceData_setInvalid;
+        Java_sun_java2d_xr_XRSurfaceData_XRInitXRender;
+        Java_sun_java2d_xr_XRSurfaceData_initOps;
+        Java_sun_java2d_xr_XRSurfaceData_XRSetForeground;
+        Java_sun_java2d_xr_XRSurfaceData_XRSetComposite;
+        Java_sun_java2d_xr_XRSurfaceData_initIDs;
+        Java_sun_java2d_xr_XRSurfaceData_XRInitSurface;
+	Java_sun_java2d_xr_XRSurfaceData_XRResetClip;
+	Java_sun_java2d_xr_XRSurfaceData_XRSetTransformNative;
+        Java_sun_java2d_xr_XRSurfaceData_XRSetFilter;
+	Java_sun_java2d_xr_XRSurfaceData_XRSetTexturePaint;
+	Java_sun_java2d_xr_XRSurfaceData_XRSetGradientPaint;
+        Java_sun_java2d_xr_XRSurfaceData_XRSetLinearGradientPaint;
+        Java_sun_java2d_xr_XRSurfaceData_XRSetRadialGradientPaint;
+        Java_sun_java2d_xr_XRSurfaceData_XRResetPaint;
+        Java_sun_java2d_xr_XRSurfaceData_XRSetRepeat;
+	Java_sun_java2d_xr_XRPMBlitLoops_nativeRenderBlit;
+	Java_sun_java2d_xr_XRRenderer_XRFillRect;
+	Java_sun_java2d_xr_XRRenderer_XRFillSpans;
+        Java_sun_java2d_xr_XRRenderer_XRDoPath;
+	Java_sun_java2d_xr_XRRenderer_XRDrawLine;
+        Java_sun_java2d_xr_XRMaskFill_maskFill;
+	Java_sun_java2d_xr_XRMaskBlit_maskBlit;
+	XRT_DrawGlyphList;
+
         Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1arrow;
         Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1box;
         Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1box_1gap;
diff -Nru openjdk.orig/jdk/src/share/classes/sun/java2d/pipe/BufferedPaints.java openjdk/jdk/src/share/classes/sun/java2d/pipe/BufferedPaints.java
--- openjdk.orig/jdk/src/share/classes/sun/java2d/pipe/BufferedPaints.java	2009-05-13 00:06:33.000000000 +0100
+++ openjdk/jdk/src/share/classes/sun/java2d/pipe/BufferedPaints.java	2009-05-13 01:02:29.000000000 +0100
@@ -307,7 +307,7 @@
      * linear RGB space.  Copied directly from the
      * MultipleGradientPaintContext class.
      */
-    private static int convertSRGBtoLinearRGB(int color) {
+    public static int convertSRGBtoLinearRGB(int color) {
         float input, output;
 
         input = color / 255.0f;
diff -Nru openjdk.orig/jdk/src/solaris/classes/sun/awt/X11GraphicsDevice.java openjdk/jdk/src/solaris/classes/sun/awt/X11GraphicsDevice.java
--- openjdk.orig/jdk/src/solaris/classes/sun/awt/X11GraphicsDevice.java	2009-05-13 00:06:49.000000000 +0100
+++ openjdk/jdk/src/solaris/classes/sun/awt/X11GraphicsDevice.java	2009-05-13 01:02:29.000000000 +0100
@@ -37,6 +37,7 @@
 import java.util.HashMap;
 
 import sun.java2d.opengl.GLXGraphicsConfig;
+import sun.java2d.xr.*;
 import sun.java2d.loops.SurfaceType;
 
 /**
@@ -150,6 +151,8 @@
             }
 
             boolean glxSupported = X11GraphicsEnvironment.isGLXAvailable();
+            boolean xrender = X11GraphicsEnvironment.isXRenderAvailable();
+            
             boolean dbeSupported = isDBESupported();
             if (dbeSupported && doubleBufferVisuals == null) {
                 doubleBufferVisuals = new HashSet();
@@ -165,9 +168,18 @@
                     boolean doubleBuffer =
                         (dbeSupported &&
                          doubleBufferVisuals.contains(Integer.valueOf(visNum)));
-                    ret[i] = X11GraphicsConfig.getConfig(this, visNum, depth,
-                            getConfigColormap(i, screen),
-                            doubleBuffer);
+                    
+                    if(!xrender)
+                    {
+                        ret[i] = XRGraphicsConfig.getConfig(this, visNum, depth,
+                                getConfigColormap(i, screen),
+                                doubleBuffer);
+                    }else
+                    {
+                        ret[i] = X11GraphicsConfig.getConfig(this, visNum, depth,
+                                getConfigColormap(i, screen),
+                                doubleBuffer);
+                    }
                 }
             }
             configs = ret;
@@ -241,9 +253,19 @@
                     doubleBuffer =
                         doubleBufferVisuals.contains(Integer.valueOf(visNum));
                 }
-                defaultConfig = X11GraphicsConfig.getConfig(this, visNum,
-                                                            depth, getConfigColormap(0, screen),
-                                                            doubleBuffer);
+                
+                if(X11GraphicsEnvironment.isXRenderAvailable())
+                {
+                	System.out.println("XRender pipeline enabled");
+                    defaultConfig = XRGraphicsConfig.getConfig(this, visNum,
+                            depth, getConfigColormap(0, screen),
+                            doubleBuffer);
+                }else
+                {
+                    defaultConfig = X11GraphicsConfig.getConfig(this, visNum,
+                            depth, getConfigColormap(0, screen),
+                            doubleBuffer);
+                }
             }
         }
     }
diff -Nru openjdk.orig/jdk/src/solaris/classes/sun/awt/X11GraphicsEnvironment.java openjdk/jdk/src/solaris/classes/sun/awt/X11GraphicsEnvironment.java
diff -r 827a93c4d06a src/solaris/classes/sun/awt/X11GraphicsEnvironment.java
--- openjdk/jdk/src/solaris/classes/sun/awt/X11GraphicsEnvironment.java	Thu May 14 10:58:07 2009 -0700
+++ openjdk/jdk/src/solaris/classes/sun/awt/X11GraphicsEnvironment.java	Sun May 24 22:35:35 2009 +0200
@@ -48,9 +48,9 @@
 import sun.font.Font2D;
 import sun.font.FontManager;
 import sun.font.NativeFont;
-import sun.java2d.SunGraphicsEnvironment;
-import sun.java2d.SurfaceManagerFactory;
-import sun.java2d.UnixSurfaceManagerFactory;
+import sun.java2d.*;
+import sun.java2d.x11.*;
+import sun.java2d.xr.*;
 
 /**
  * This is an implementation of a GraphicsEnvironment object for the
@@ -175,19 +175,45 @@
                                 "pipeline (GLX 1.3 not available)");
                         }
                     }
+                    
+                    /*CE*/
+                    // Now check for XRender system property
+                    String xProp = System.getProperty("sun.java2d.xrender");
+                        if (xProp != null) {
+                        if (xProp.equals("true") || xProp.equals("t")) {
+                            xRenderAvailable = true;
+                        } else if (xProp.equals("True") || xProp.equals("T")) {
+                            xRenderAvailable = true;
+                            xRenderVerbose = true;
+                        }
+                    }
+                        
+                        if(xRenderAvailable)
+                        {
+                            XRSurfaceData.initXRSurfaceData();
+                        }else
+                        {
+                            // X11SurfaceData.initX11SurfaceData();
+                            // Don't initialize here the X11SurfaceData
+                            // static initializer will do it for us later.
+                        }
                 }
-
+               
+   
                 return null;
             }
          });
-
+        
         // Install the correct surface manager factory.
         SurfaceManagerFactory.setInstance(new UnixSurfaceManagerFactory());
-
     }
-
+    
     private static boolean glxAvailable;
     private static boolean glxVerbose;
+    
+    private static boolean xRenderAvailable; /*CE*/
+    private static boolean xRenderVerbose;
+    private static boolean isX11SurfaceDataInitialized = false;
 
     private static native boolean initGLX();
 
@@ -198,6 +224,15 @@
     public static boolean isGLXVerbose() {
         return glxVerbose;
     }
+    
+    /*CE*/
+    public static boolean isXRenderAvailable() {
+        return xRenderAvailable;
+    }
+
+    public static boolean isXRenderVerbose() {
+        return xRenderVerbose;
+    }
 
     /**
      * Checks if Shared Memory extension can be used.
@@ -1119,4 +1154,14 @@
 
     public void paletteChanged() {
     }
+
+	public static boolean isX11SurfaceDataInitialized()
+	{
+		return isX11SurfaceDataInitialized;
+	}
+
+	public static void setX11SurfaceDataInitialized()
+	{
+		X11GraphicsEnvironment.isX11SurfaceDataInitialized = true;
+	}
 }
diff -Nru openjdk.orig/jdk/src/solaris/classes/sun/font/XRTextRenderer.java openjdk/jdk/src/solaris/classes/sun/font/XRTextRenderer.java
--- openjdk.orig/jdk/src/solaris/classes/sun/font/XRTextRenderer.java	1970-01-01 01:00:00.000000000 +0100
+++ openjdk/jdk/src/solaris/classes/sun/font/XRTextRenderer.java	2009-05-13 01:02:29.000000000 +0100
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.font;
+
+import sun.awt.SunToolkit;
+import sun.java2d.SunGraphics2D;
+import sun.java2d.pipe.GlyphListPipe;
+import sun.java2d.xr.*;
+
+/**
+ * A delegate pipe of SG2D for drawing any text to a XRender surface
+ */
+public class XRTextRenderer extends GlyphListPipe {
+    
+    native void doDrawGlyphList(long dstData, int numGlyphs, boolean subPixPos, boolean rgbOrder, int lcdContrast, boolean usePositions, float xOrigin, float yOrigin, long[] imgArray, float[] posArray);
+    
+    protected void drawGlyphList(SunGraphics2D sg2d, GlyphList gl) 
+    {
+        try 
+        {
+            SunToolkit.awtLock();
+            XRSurfaceData x11sd = (XRSurfaceData)sg2d.surfaceData;
+    		x11sd.validate(sg2d.getCompClip(), sg2d.composite, sg2d.transform, sg2d.paint, sg2d, 0);
+            
+            doDrawGlyphList(x11sd.getNativeOps(), gl.getNumGlyphs(), gl.isSubPixPos(), gl.isRGBOrder(), sg2d.lcdTextContrast, gl.usePositions(), gl.getX(), gl.getY(), gl.getImages(), gl.getPositions());
+        } finally {
+            SunToolkit.awtUnlock();
+        }
+    }
+}
diff -Nru openjdk.orig/jdk/src/solaris/classes/sun/java2d/UnixSurfaceManagerFactory.java openjdk/jdk/src/solaris/classes/sun/java2d/UnixSurfaceManagerFactory.java
--- openjdk.orig/jdk/src/solaris/classes/sun/java2d/UnixSurfaceManagerFactory.java	2009-05-13 00:06:49.000000000 +0100
+++ openjdk/jdk/src/solaris/classes/sun/java2d/UnixSurfaceManagerFactory.java	2009-05-13 01:02:29.000000000 +0100
@@ -33,6 +33,7 @@
 import sun.java2d.opengl.GLXGraphicsConfig;
 import sun.java2d.opengl.GLXVolatileSurfaceManager;
 import sun.java2d.x11.X11VolatileSurfaceManager;
+import sun.java2d.xr.*;
 
 /**
  * The SurfaceManagerFactory that creates VolatileSurfaceManager
@@ -52,11 +53,14 @@
      */
     public VolatileSurfaceManager createVolatileManager(SunVolatileImage vImg,
                                                         Object context)
-    {
+    {    	
         GraphicsConfiguration gc = vImg.getGraphicsConfig();
+        
         if (gc instanceof GLXGraphicsConfig) {
             return new GLXVolatileSurfaceManager(vImg, context);
-        } else {
+        } else if(gc instanceof XRGraphicsConfig) {
+            return new XRVolatileSurfaceManager(vImg, context);
+        }else {
             return new X11VolatileSurfaceManager(vImg, context);
         }
     }
diff -Nru openjdk.orig/jdk/src/solaris/classes/sun/java2d/x11/X11SurfaceData.java openjdk/jdk/src/solaris/classes/sun/java2d/x11/X11SurfaceData.java
--- openjdk/jdk/src/solaris/classes/sun/java2d/x11/X11SurfaceData.java	Thu May 14 10:58:07 2009 -0700
+++ openjdk/jdk/src/solaris/classes/sun/java2d/x11/X11SurfaceData.java	Sun May 24 22:35:22 2009 +0200
@@ -42,10 +42,7 @@
 import java.awt.image.Raster;
 import java.awt.peer.ComponentPeer;
 
-import sun.awt.SunHints;
-import sun.awt.SunToolkit;
-import sun.awt.X11ComponentPeer;
-import sun.awt.X11GraphicsConfig;
+import sun.awt.*;
 import sun.awt.image.PixelConverter;
 import sun.font.X11TextRenderer;
 import sun.java2d.InvalidPipeException;
@@ -71,7 +68,7 @@
 
     protected int depth;
 
-    private static native void initIDs(Class xorComp, boolean tryDGA);
+    private static native void initIDs(Class xorComp, boolean tryDGA);  //OK
     protected native void initSurface(int depth, int width, int height,
                                       long drawable);
     native boolean isDrawableValid();
@@ -200,6 +197,13 @@
     protected static boolean dgaAvailable;
 
     static {
+        initX11SurfaceData();
+    }
+
+    public static void initX11SurfaceData()
+    {
+    	if(!X11GraphicsEnvironment.isX11SurfaceDataInitialized())
+    	{
         if (!GraphicsEnvironment.isHeadless()) {
             // If a screen magnifier is present, don't attempt to use DGA
             String magPresent = (String) java.security.AccessController.doPrivileged
@@ -233,9 +237,12 @@
                 X11PMBlitLoops.register();
                 X11PMBlitBgLoops.register();
             }
-        }
+            
+            X11GraphicsEnvironment.setX11SurfaceDataInitialized();
+        }    	
+    	}
     }
-
+    
     /**
      * Returns true if we can use DGA on any of the screens
      */
@@ -632,7 +639,7 @@
     {
         // assert SunToolkit.isAWTLockHeldByCurrentThread();
 
-        if (!isValid()) {
+    	if (!isValid()) {
             throw new InvalidPipeException("bounds changed");
         }
 
diff -Nru openjdk.orig/jdk/src/solaris/classes/sun/java2d/xr/XRDrawImage.java openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRDrawImage.java
--- openjdk.orig/jdk/src/solaris/classes/sun/java2d/xr/XRDrawImage.java	1970-01-01 01:00:00.000000000 +0100
+++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRDrawImage.java	2009-05-13 01:02:29.000000000 +0100
@@ -0,0 +1,50 @@
+package sun.java2d.xr;
+
+import java.awt.*;
+import java.awt.geom.*;
+
+import sun.java2d.*;
+import sun.java2d.loops.*;
+import sun.java2d.pipe.*;
+
+
+public class XRDrawImage extends DrawImage {
+
+    @Override
+    protected void renderImageXform(SunGraphics2D sg, Image img,
+                                    AffineTransform tx, int interpType,
+                                    int sx1, int sy1, int sx2, int sy2,
+                                    Color bgColor)
+    {    	
+            SurfaceData dstData = sg.surfaceData;
+            SurfaceData srcData =
+                dstData.getSourceSurfaceData(img,
+                                             sg.TRANSFORM_GENERIC,
+                                             sg.imageComp,
+                                             bgColor);
+
+            if (srcData != null && !isBgOperation(srcData, bgColor) && srcData instanceof XRSurfaceData)
+            {
+                SurfaceType srcType = srcData.getSurfaceType();
+                SurfaceType dstType = dstData.getSurfaceType();
+                
+                ((XRSurfaceData) srcData).setPreferredInterpolation(XRUtils.ATransOpToXRQuality(interpType));
+                
+                TransformBlit blit = TransformBlit.getFromCache(srcType,
+                                                                sg.imageComp,
+                                                                dstType);
+
+                if (blit != null) {
+                    blit.Transform(srcData, dstData,
+                                   sg.composite, sg.getCompClip(),
+                                   tx, interpType,
+                                   sx1, sy1, 0, 0, sx2-sx1, sy2-sy1);
+                    return;
+                }
+       
+        }
+
+        super.renderImageXform(sg, img, tx, interpType,  sx1, sy1, sx2, sy2, bgColor);
+    }
+}
+
diff -Nru openjdk.orig/jdk/src/solaris/classes/sun/java2d/xr/XRGraphicsConfig.java openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRGraphicsConfig.java
--- openjdk.orig/jdk/src/solaris/classes/sun/java2d/xr/XRGraphicsConfig.java	1970-01-01 01:00:00.000000000 +0100
+++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRGraphicsConfig.java	2009-05-13 01:02:29.000000000 +0100
@@ -0,0 +1,42 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package sun.java2d.xr;
+
+import sun.awt.*;
+import sun.awt.image.*;
+import sun.java2d.*;
+
+/**
+ *
+ * @author ce
+ */
+public class XRGraphicsConfig extends X11GraphicsConfig
+implements SurfaceManager.ProxiedGraphicsConfig
+{
+	private XRGraphicsConfig(X11GraphicsDevice device, int visualnum, int depth, int colormap, boolean doubleBuffer)
+    {
+		super(device, visualnum, depth, colormap, doubleBuffer);
+    }
+    
+    public SurfaceData createSurfaceData(X11ComponentPeer peer) {
+        return XRSurfaceData.createData(peer);
+    }
+	
+    public static XRGraphicsConfig getConfig(X11GraphicsDevice device,
+            int visualnum, int depth,
+            int colormap, boolean doubleBuffer)
+    {
+        if (!X11GraphicsEnvironment.isXRenderAvailable()) {
+            return null;
+        }
+        
+        return new XRGraphicsConfig(device, visualnum, depth, colormap, doubleBuffer);
+    }
+    
+    public Object getProxyKey() {
+        return this;
+    }
+}
diff -Nru openjdk.orig/jdk/src/solaris/classes/sun/java2d/xr/XRMaskBlit.java openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRMaskBlit.java
--- openjdk.orig/jdk/src/solaris/classes/sun/java2d/xr/XRMaskBlit.java	1970-01-01 01:00:00.000000000 +0100
+++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRMaskBlit.java	2009-05-13 01:02:29.000000000 +0100
@@ -0,0 +1,71 @@
+package sun.java2d.xr;
+
+import static sun.java2d.loops.CompositeType.SrcNoEa;
+import static sun.java2d.loops.CompositeType.SrcOver;
+import static sun.java2d.loops.SurfaceType.IntArgb;
+import static sun.java2d.loops.SurfaceType.IntArgbPre;
+import static sun.java2d.loops.SurfaceType.IntRgb;
+
+import java.awt.AlphaComposite;
+import java.awt.Composite;
+
+import sun.awt.*;
+import sun.java2d.*;
+import sun.java2d.loops.*;
+import sun.java2d.pipe.Region;
+
+public class XRMaskBlit extends MaskBlit
+{
+	static void register()
+	{
+		GraphicsPrimitive[] primitives = 
+		{ 
+				new XRMaskBlit(IntArgbPre, SrcOver, IntArgbPre), 
+				new XRMaskBlit(IntRgb, SrcOver, IntRgb), 
+				new XRMaskBlit(IntArgbPre, SrcNoEa, IntRgb), 
+				new XRMaskBlit(IntRgb, SrcNoEa, IntArgbPre)
+		};
+		GraphicsPrimitiveMgr.register(primitives);
+	}
+
+	public XRMaskBlit(SurfaceType srcType, CompositeType compType, SurfaceType dstType)
+	{
+		super(srcType, CompositeType.AnyAlpha, dstType);
+	}
+
+	protected native void maskBlit(long srcXsdo, long dstxsdo, long alphaXsdo, int srcx, int srcy, int dstx, int dsty, int w, int h, int maskoff, int maskscan, int masklen, byte[] mask);
+
+	
+	static XRSurfaceData alphaPM;
+	static int alphaWidth = 0, alphaHeight = 0;
+	public void MaskBlit(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int srcx, int srcy, int dstx, int dsty, int width, int height, byte[] mask, int maskoff, int maskscan)
+	{
+		if (width <= 0 || height <= 0)
+		{
+			return;
+		}
+
+		try
+		{
+			SunToolkit.awtLock();
+			
+			if (alphaPM == null || alphaWidth < width || alphaHeight < height)
+			{
+				alphaPM = XRSurfaceData.createData(((XRSurfaceData) dst).graphicsConfig, width, height);
+				alphaWidth = width;
+				alphaHeight = height;
+			}
+
+			XRSurfaceData x11sd = (XRSurfaceData) src;
+			x11sd.validateAsSource(null, XRUtils.RepeatNone);
+			
+			XRSurfaceData x11dst = (XRSurfaceData) dst;
+			x11dst.validate(clip, comp, null, null, null, 0);
+			
+			maskBlit(src.getNativeOps(), dst.getNativeOps(), alphaPM.getNativeOps(), srcx, srcy, dstx, dsty, width, height, maskoff, maskscan, mask != null ? mask.length : 0, mask);
+		} finally
+		{
+			SunToolkit.awtUnlock();
+		}
+	}
+}
diff -Nru openjdk.orig/jdk/src/solaris/classes/sun/java2d/xr/XRMaskFill.java openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRMaskFill.java
--- openjdk.orig/jdk/src/solaris/classes/sun/java2d/xr/XRMaskFill.java	1970-01-01 01:00:00.000000000 +0100
+++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRMaskFill.java	2009-05-13 01:02:29.000000000 +0100
@@ -0,0 +1,75 @@
+package sun.java2d.xr;
+
+import static sun.java2d.loops.CompositeType.SrcNoEa;
+import static sun.java2d.loops.CompositeType.SrcOver;
+import static sun.java2d.loops.SurfaceType.AnyColor;
+import static sun.java2d.loops.SurfaceType.GradientPaint;
+import static sun.java2d.loops.SurfaceType.LinearGradientPaint;
+import static sun.java2d.loops.SurfaceType.OpaqueColor;
+import static sun.java2d.loops.SurfaceType.OpaqueGradientPaint;
+import static sun.java2d.loops.SurfaceType.OpaqueLinearGradientPaint;
+import static sun.java2d.loops.SurfaceType.OpaqueRadialGradientPaint;
+import static sun.java2d.loops.SurfaceType.OpaqueTexturePaint;
+import static sun.java2d.loops.SurfaceType.RadialGradientPaint;
+import static sun.java2d.loops.SurfaceType.TexturePaint;
+import static sun.java2d.pipe.BufferedOpCodes.MASK_FILL;
+
+import java.awt.*;
+import java.awt.geom.*;
+import java.awt.geom.Rectangle2D.Float;
+import java.awt.image.*;
+
+import sun.awt.*;
+import sun.java2d.*;
+import sun.java2d.loops.*;
+import sun.java2d.opengl.*;
+import sun.java2d.pipe.*;
+
+public class XRMaskFill extends MaskFill
+{
+	static void register()
+	{
+		GraphicsPrimitive[] primitives = { new XRMaskFill(AnyColor, SrcOver, XRSurfaceData.IntRgbX11), new XRMaskFill(OpaqueColor, SrcNoEa, XRSurfaceData.IntRgbX11), new XRMaskFill(GradientPaint, SrcOver, XRSurfaceData.IntRgbX11), new XRMaskFill(OpaqueGradientPaint, SrcNoEa, XRSurfaceData.IntRgbX11),
+				new XRMaskFill(LinearGradientPaint, SrcOver, XRSurfaceData.IntRgbX11), new XRMaskFill(OpaqueLinearGradientPaint, SrcNoEa, XRSurfaceData.IntRgbX11), new XRMaskFill(RadialGradientPaint, SrcOver, XRSurfaceData.IntRgbX11), new XRMaskFill(OpaqueRadialGradientPaint, SrcNoEa, XRSurfaceData.IntRgbX11),
+				new XRMaskFill(TexturePaint, SrcOver, XRSurfaceData.IntRgbX11), new XRMaskFill(OpaqueTexturePaint, SrcNoEa, XRSurfaceData.IntRgbX11),
+
+				new XRMaskFill(AnyColor, SrcOver, XRSurfaceData.IntArgbX11), new XRMaskFill(OpaqueColor, SrcNoEa, XRSurfaceData.IntArgbX11), new XRMaskFill(GradientPaint, SrcOver, XRSurfaceData.IntArgbX11), new XRMaskFill(OpaqueGradientPaint, SrcNoEa, XRSurfaceData.IntArgbX11),
+				new XRMaskFill(LinearGradientPaint, SrcOver, XRSurfaceData.IntArgbX11), new XRMaskFill(OpaqueLinearGradientPaint, SrcNoEa, XRSurfaceData.IntArgbX11), new XRMaskFill(RadialGradientPaint, SrcOver, XRSurfaceData.IntArgbX11), new XRMaskFill(OpaqueRadialGradientPaint, SrcNoEa, XRSurfaceData.IntArgbX11),
+				new XRMaskFill(TexturePaint, SrcOver, XRSurfaceData.IntArgbX11), new XRMaskFill(OpaqueTexturePaint, SrcNoEa, XRSurfaceData.IntArgbX11) };
+
+		GraphicsPrimitiveMgr.register(primitives);
+	}
+
+	protected XRMaskFill(SurfaceType srcType, CompositeType compType, SurfaceType surfaceType)
+	{
+		super(srcType, compType, surfaceType);
+	}
+
+	protected native void maskFill(long xsdo, long alphaXsdo, int x, int y, int w, int h, int maskoff, int maskscan, int masklen, byte[] mask);
+
+	static XRSurfaceData alphaPM;
+	static int alphaWidth = 0, alphaHeight = 0;
+
+	public void MaskFill(SunGraphics2D sg2d, SurfaceData sData, Composite comp, final int x, final int y, final int w, final int h, final byte[] mask, final int maskoff, final int maskscan)
+	{
+		try
+		{
+			SunToolkit.awtLock();
+
+			XRSurfaceData x11sd = (XRSurfaceData) sData;
+			x11sd.validate(sg2d.getCompClip(), sg2d.getComposite(), sg2d.getTransform(), sg2d.getPaint(), sg2d, 0);
+
+			if (alphaPM == null || alphaWidth < w || alphaHeight < h)
+			{
+				alphaPM = XRSurfaceData.createData(((XRSurfaceData) sData).graphicsConfig, w, h);
+				alphaWidth = w;
+				alphaHeight = h;
+			}
+
+			maskFill(sData.getNativeOps(), alphaPM.getNativeOps(), x, y, w, h, maskoff, maskscan, mask != null ? mask.length : 0, mask);
+		} finally
+		{
+			SunToolkit.awtUnlock();
+		}
+	}
+}
diff -Nru openjdk.orig/jdk/src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java
--- openjdk.orig/jdk/src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java	1970-01-01 01:00:00.000000000 +0100
+++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java	2009-05-13 01:02:29.000000000 +0100
@@ -0,0 +1,206 @@
+/*
+ * Copyright 2000-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.java2d.xr;
+
+import sun.awt.SunToolkit;
+import sun.java2d.loops.*;
+import sun.java2d.opengl.*;
+import sun.java2d.pipe.Region;
+import sun.java2d.SurfaceData;
+import java.awt.*;
+import java.awt.geom.*;
+import java.awt.image.*;
+
+/**
+ * X11PMBlitLoops
+ *
+ * This class accelerates Blits between two surfaces of types *PM.  Since
+ * the onscreen surface is of that type and some of the offscreen surfaces
+ * may be of that type (if they were created via X11OffScreenImage), then
+ * this type of Blit will accelerated double-buffer copies between those
+ * two surfaces.
+*/
+public class XRPMBlitLoops
+{
+
+	public static void register()
+	{
+		GraphicsPrimitive[] primitives = {
+		
+				new X11PMBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntRgbX11), new X11PMBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntArgbX11), new X11PMBlit(XRSurfaceData.IntArgbX11, XRSurfaceData.IntRgbX11), new X11PMBlit(XRSurfaceData.IntArgbX11, XRSurfaceData.IntArgbX11),
+
+				new X11PMScaledBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntRgbX11), new X11PMScaledBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntArgbX11), new X11PMScaledBlit(XRSurfaceData.IntArgbX11, XRSurfaceData.IntRgbX11), new X11PMScaledBlit(XRSurfaceData.IntArgbX11, XRSurfaceData.IntArgbX11),
+
+				new X11PMTransformedBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntRgbX11), new X11PMTransformedBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntArgbX11), new X11PMTransformedBlit(XRSurfaceData.IntArgbX11, XRSurfaceData.IntRgbX11), new X11PMTransformedBlit(XRSurfaceData.IntArgbX11, XRSurfaceData.IntArgbX11),
+
+				/*TODO Allow blits from argb surfaces too*/
+		};
+		GraphicsPrimitiveMgr.register(primitives);
+	}
+
+	/**
+	 * Blit
+	 * This native method is where all of the work happens in the
+	 * accelerated Blit.
+	 */
+	public static native void nativeRenderBlit(long srcData, long dstData, int sx, int sy, int dx, int dy, int w, int h);
+
+	static AffineTransform identityTransform = AffineTransform.getTranslateInstance(0, 0);
+	static double[] tmpCoord = new double[4];
+}
+
+class X11PMBlit extends Blit
+{
+	public X11PMBlit(SurfaceType srcType, SurfaceType dstType)
+	{
+		super(srcType, CompositeType.AnyAlpha, dstType);
+	}
+
+	public void Blit(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int sx, int sy, int dx, int dy, int w, int h)
+	{
+		try
+		{
+			SunToolkit.awtLock();
+
+			XRSurfaceData x11sdDst = (XRSurfaceData) dst;
+			x11sdDst.validate(clip, comp, null, null, null, 0);
+			XRSurfaceData x11sdSrc = (XRSurfaceData) src;
+	
+			x11sdSrc.validateAsSource(null, XRUtils.RepeatNone, XRUtils.FAST);
+
+			XRPMBlitLoops.nativeRenderBlit(src.getNativeOps(), dst.getNativeOps(), sx, sy, dx, dy, w, h);
+		} finally
+		{
+			SunToolkit.awtUnlock();
+		}
+	}
+}
+
+class X11PMScaledBlit extends ScaledBlit
+{
+	public X11PMScaledBlit(SurfaceType srcType, SurfaceType dstType)
+	{
+		super(srcType, CompositeType.AnyAlpha, dstType);
+	}
+
+	public void Scale(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int sx1, int sy1, int sx2, int sy2, double dx1, double dy1, double dx2, double dy2)
+	{
+		try
+		{
+			SunToolkit.awtLock();
+
+			XRSurfaceData x11sdDst = (XRSurfaceData) dst;
+			x11sdDst.validate(clip, comp, null, null, null, 0);
+			XRSurfaceData x11sdSrc = (XRSurfaceData) src;
+
+			double xScale = (dx2 - dx1) / (sx2 - sx1);
+			double yScale = (dy2 - dy1) / (sy2 - sy1);
+
+			sx1 *= xScale;
+			sx2 *= xScale;
+			sy1 *= yScale;
+			sy2 *= yScale;
+
+			AffineTransform xForm = AffineTransform.getScaleInstance(1 / xScale, 1 / yScale);
+
+			x11sdSrc.validateAsSource(xForm, XRUtils.RepeatNone, XRUtils.FAST);
+
+			XRPMBlitLoops.nativeRenderBlit(src.getNativeOps(), dst.getNativeOps(), (int) sx1, (int) sy1, (int) dx1, (int) dy1, (int) (dx2 - dx1), (int) (dy2 - dy1));
+
+		} finally
+		{
+			SunToolkit.awtUnlock();
+		}
+	}
+}
+
+/**
+ * Called also if scale+transform is set
+ * @author Clemens Eisserer
+ */
+class X11PMTransformedBlit extends TransformBlit
+{
+	public X11PMTransformedBlit(SurfaceType srcType, SurfaceType dstType)
+	{
+		super(srcType, CompositeType.AnyAlpha, dstType);
+	}
+
+	public void Transform(SurfaceData src, SurfaceData dst, Composite comp, Region clip, AffineTransform xform, int hint, int srcx, int srcy, int dstx, int dsty, int width, int height)
+	{
+		try
+		{			
+			SunToolkit.awtLock();
+
+			XRSurfaceData x11sdDst = (XRSurfaceData) dst;
+			x11sdDst.validate(clip, comp, null, null, null, 0);
+			XRSurfaceData x11sdSrc = (XRSurfaceData) src;
+
+			boolean needClip =  (xform.getScaleX() != 0.0f) || (xform.getShearY() != 0.0f);
+			try
+			{				
+				/*Calculate area which will be covered by the transform-blit*/
+				Rectangle2D.Float rect = new Rectangle2D.Float(dstx, dsty, width, height);
+				Shape shp = xform.createTransformedShape(rect);
+				Rectangle bounds = shp.getBounds();
+				
+				AffineTransform sourceTrans = (AffineTransform) xform.clone();
+				sourceTrans.translate(-srcx, -srcy);
+			
+//				System.out.println("srcx "+srcx+" srcy:"+srcy+" dstx:"+dstx+" dsty:"+dsty+" width:"+width+" height:"+height);
+//				System.out.println("Dest-Translation: x:"+xform.getTranslateX()+" y:"+xform.getTranslateY());
+				
+				//AffineTransform sourceTransform = new AffineTransform(xform.getScaleX(), xform.getShearY(), xform.getShearX(), xform.getScaleY(), 0, 0);
+				//sourceTransform.translate(-srcx, -srcy);
+				
+				sourceTrans.invert();
+			    
+				
+			    //x11sdSrc.validateAsSource(sourceTrans, XRUtils.RepeatPad); /*Pad avoids smearing, but falls back to software*/
+				x11sdSrc.validateAsSource(sourceTrans, XRUtils.RepeatNone);
+
+				
+				if(needClip)
+				{
+			        x11sdDst.setShapeClip(shp);
+				}
+				
+			    XRPMBlitLoops.nativeRenderBlit(src.getNativeOps(), dst.getNativeOps(), 0, 0, 0, 0, bounds.x + bounds.width, bounds.y + bounds.height);// bounds.x, bounds.y, bounds.width, bounds.height);//(int) (maxX - minX), (int) (maxY - minY));
+		
+			    if(needClip)
+			    {
+			        x11sdDst.resetShapeClip();
+			    }
+			   
+			} catch (Exception ex)
+			{
+				ex.printStackTrace();
+			}
+		} finally
+		{
+			SunToolkit.awtUnlock();
+		}
+	}
+}
\ No newline at end of file
diff -Nru openjdk.orig/jdk/src/solaris/classes/sun/java2d/xr/XRRenderer.java openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRRenderer.java
--- openjdk.orig/jdk/src/solaris/classes/sun/java2d/xr/XRRenderer.java	1970-01-01 01:00:00.000000000 +0100
+++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRRenderer.java	2009-05-13 01:02:29.000000000 +0100
@@ -0,0 +1,255 @@
+package sun.java2d.xr;
+
+import java.awt.*;
+import java.awt.geom.*;
+
+import sun.awt.SunToolkit;
+import sun.java2d.SunGraphics2D;
+import sun.java2d.pipe.Region;
+import sun.java2d.pipe.PixelDrawPipe;
+import sun.java2d.pipe.PixelFillPipe;
+import sun.java2d.pipe.ShapeDrawPipe;
+import sun.java2d.pipe.SpanIterator;
+import sun.java2d.pipe.ShapeSpanIterator;
+import sun.java2d.pipe.LoopPipe;
+
+public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe
+{
+	public XRRenderer()
+	{}
+
+	public static XRRenderer getInstance()
+	{
+		return new XRRenderer();
+		//	return (GraphicsPrimitive.tracingEnabled() ? new X11TracingRenderer() : new X11Renderer());
+	}
+
+	private final void validate(SunGraphics2D sg2d)
+	{
+		// NOTE: getCompClip() will revalidateAll() if the
+		// surfaceData is invalid.  This should ensure that
+		// the clip and pixel that we are validating against
+		// are the most current.
+		//
+		// The assumption is that the pipeline after that
+		// revalidation will either be another X11 pipe
+		// (because the drawable format never changes on X11)
+		// or a null pipeline if the surface is disposed.
+		//
+		// Since we do not get the ops structure of the SurfaceData
+		// until the actual call down to the native level we will
+		// pick up the most recently validated copy.
+		// Note that if the surface is disposed, a NullSurfaceData
+		// (with null native data structure) will be set in
+		// sg2d, so we have to protect against it in native code.
+
+		XRSurfaceData x11sd = (XRSurfaceData) sg2d.surfaceData;
+		x11sd.validate(sg2d.getCompClip(), sg2d.composite, sg2d.transform, sg2d.paint, sg2d, 0);
+	}
+
+	native void XRDrawLine(long pXSData, int x1, int y1, int x2, int y2);
+
+	public void drawLine(SunGraphics2D sg2d, int x1, int y1, int x2, int y2)
+	{
+		try
+		{
+			SunToolkit.awtLock();
+			
+			validate(sg2d);
+			int transx = sg2d.transX;
+			int transy = sg2d.transY;
+			XRDrawLine(sg2d.surfaceData.getNativeOps(), x1 + transx, y1 + transy, x2 + transx, y2 + transy);
+		} finally
+		{
+			SunToolkit.awtUnlock();
+		}
+	}
+
+	public void drawRect(SunGraphics2D sg2d, int x, int y, int width, int height)
+	{
+		draw(sg2d, new Rectangle2D.Float(x, y, width, height));
+	}
+
+	public void drawPolyline(SunGraphics2D sg2d, int xpoints[], int ypoints[], int npoints)
+	{
+		throw new RuntimeException("Not implemented");
+	}
+
+	public void drawPolygon(SunGraphics2D sg2d, int xpoints[], int ypoints[], int npoints)
+	{
+		draw(sg2d, new Polygon(xpoints, ypoints, npoints));
+	}
+
+	native void XRFillRect(long pXSData, int x, int y, int width, int height);
+
+	public void fillRect(SunGraphics2D sg2d, int x, int y, int width, int height)
+	{
+		SunToolkit.awtLock();
+		try
+		{
+			validate(sg2d);
+
+			x += sg2d.transform.getTranslateX();
+			y += sg2d.transform.getTranslateY();
+			XRFillRect(sg2d.surfaceData.getNativeOps(), x, y, width, height);
+		} finally
+		{
+			SunToolkit.awtUnlock();
+		}
+	}
+
+	public void fillPolygon(SunGraphics2D sg2d, int xpoints[], int ypoints[], int npoints)
+	{
+		fill(sg2d, new Polygon(xpoints, ypoints, npoints));
+	}
+
+	public void drawRoundRect(SunGraphics2D sg2d, int x, int y, int width, int height, int arcWidth, int arcHeight)
+	{
+		draw(sg2d, new RoundRectangle2D.Float(x, y, width, height, arcWidth, arcHeight));
+	}
+
+	public void fillRoundRect(SunGraphics2D sg2d, int x, int y, int width, int height, int arcWidth, int arcHeight)
+	{
+		fill(sg2d, new RoundRectangle2D.Float(x, y, width, height, arcWidth, arcHeight));
+	}
+
+	public void drawOval(SunGraphics2D sg2d, int x, int y, int width, int height)
+	{
+		draw(sg2d, new Ellipse2D.Float(x, y, width, height));
+	}
+
+	public void fillOval(SunGraphics2D sg2d, int x, int y, int width, int height)
+	{
+		fill(sg2d, new Ellipse2D.Float(x, y, width, height));
+	}
+
+	public void drawArc(SunGraphics2D sg2d, int x, int y, int width, int height, int startAngle, int arcAngle)
+	{
+		draw(sg2d, new Arc2D.Float(x, y, width, height, startAngle, arcAngle, Arc2D.OPEN));
+	}
+
+	public void fillArc(SunGraphics2D sg2d, int x, int y, int width, int height, int startAngle, int arcAngle)
+	{
+		fill(sg2d, new Arc2D.Float(x, y, width, height, startAngle, arcAngle, Arc2D.PIE));
+	}
+
+	native void XRFillSpans(long pXSData, SpanIterator si, long iterator, int transx, int transy);
+
+	native void XRDoPath(SunGraphics2D sg2d, long pXSData, int transX, int transY, Path2D.Float p2df, boolean isFill);
+
+	private void doPath(SunGraphics2D sg2d, Shape s, boolean isFill)
+	{
+		Path2D.Float p2df;
+		int transx, transy;
+		if (sg2d.transformState <= sg2d.TRANSFORM_INT_TRANSLATE)
+		{
+			if (s instanceof Path2D.Float)
+			{
+				p2df = (Path2D.Float) s;
+			} else
+			{
+				p2df = new Path2D.Float(s);
+			}
+			transx = sg2d.transX;
+			transy = sg2d.transY;
+		} else
+		{
+			p2df = new Path2D.Float(s, sg2d.transform);
+			transx = 0;
+			transy = 0;
+		}
+		
+		try
+		{
+			SunToolkit.awtLock();
+			validate(sg2d);
+			XRDoPath(sg2d, sg2d.surfaceData.getNativeOps(), transx, transy, p2df, isFill);
+		} finally
+		{
+			SunToolkit.awtUnlock();
+		}
+	}
+
+	public void draw(SunGraphics2D sg2d, Shape s)
+	{
+
+		if (sg2d.strokeState == sg2d.STROKE_THIN)
+		{
+			doPath(sg2d, s, false);
+			return;
+		}
+		
+		if (sg2d.strokeState < sg2d.STROKE_CUSTOM)
+		{
+			ShapeSpanIterator si = LoopPipe.getStrokeSpans(sg2d, s);
+			try
+			{
+				try
+				{
+					SunToolkit.awtLock();
+					validate(sg2d);
+					XRFillSpans(sg2d.surfaceData.getNativeOps(), si, si.getNativeIterator(), 0, 0);
+				} finally
+				{
+					SunToolkit.awtUnlock();
+				}
+			} finally
+			{
+				si.dispose();
+			}
+		} else
+		{
+			fill(sg2d, sg2d.stroke.createStrokedShape(s));
+		}
+	}
+
+	public void fill(SunGraphics2D sg2d, Shape s)
+	{
+		if (sg2d.strokeState == sg2d.STROKE_THIN)
+		{
+			doPath(sg2d, s, true);
+			return;
+		}
+
+		AffineTransform at;
+		int transx, transy;
+		if (sg2d.transformState < sg2d.TRANSFORM_TRANSLATESCALE)
+		{
+			// Transform (translation) will be done by XFillSpans
+			at = null;
+			transx = sg2d.transX;
+			transy = sg2d.transY;
+		} else
+		{
+			// Transform will be done by the PathIterator
+			at = sg2d.transform;
+			transx = transy = 0;
+		}
+
+		ShapeSpanIterator ssi = LoopPipe.getFillSSI(sg2d);
+		try
+		{
+			// Subtract transx/y from the SSI clip to match the
+			// (potentially untranslated) geometry fed to it
+			Region clip = sg2d.getCompClip();
+			ssi.setOutputAreaXYXY(clip.getLoX() - transx, clip.getLoY() - transy, clip.getHiX() - transx, clip.getHiY() - transy);
+			ssi.appendPath(s.getPathIterator(at));
+			try
+			{
+				SunToolkit.awtLock();
+				
+				validate(sg2d);
+				XRFillSpans(sg2d.surfaceData.getNativeOps(), ssi, ssi.getNativeIterator(), transx, transy);
+			} finally
+			{
+				SunToolkit.awtUnlock();
+			}
+		} finally
+		{
+			ssi.dispose();
+		}
+	}
+
+	native void devCopyArea(long sdOps, long xgc, int srcx, int srcy, int dstx, int dsty, int w, int h);
+
+}
diff -Nru openjdk.orig/jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceData.java openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceData.java
--- openjdk.orig/jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceData.java	1970-01-01 01:00:00.000000000 +0100
+++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceData.java	2009-05-13 01:02:29.000000000 +0100
@@ -0,0 +1,1017 @@
+/*
+ * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.java2d.xr;
+
+import java.awt.*;
+import java.awt.MultipleGradientPaint.*;
+import java.awt.Transparency;
+import java.awt.geom.*;
+import java.awt.image.*;
+import sun.awt.*;
+import sun.awt.image.PixelConverter;
+import sun.font.*;
+import sun.java2d.InvalidPipeException;
+import sun.java2d.SunGraphics2D;
+import sun.java2d.SurfaceData;
+import sun.java2d.SurfaceDataProxy;
+import sun.java2d.loops.*;
+import sun.java2d.pipe.*;
+import static sun.java2d.xr.XRUtils.XDoubleToFixed;
+
+public abstract class XRSurfaceData extends SurfaceData
+{
+	X11ComponentPeer peer;
+	XRGraphicsConfig graphicsConfig;
+	private RenderLoops solidloops;
+
+	protected int depth;
+
+	private static native void initIDs(boolean gradCache);
+
+	protected native void XRInitSurface(int depth, int width, int height, long drawable, int pictFormat);
+
+	native boolean XRIsDrawableValid();
+
+	protected native void flushNativeSurface();
+
+	native void XRInitXRender(long xsdo, int pictForm);
+
+	public static final String DESC_BYTE_A8_X11 = "Byte A8 Pixmap";
+	public static final String DESC_INT_RGB_X11 = "Integer RGB Pixmap";
+	public static final String DESC_INT_ARGB_X11 = "Integer ARGB-Pre Pixmap";
+
+	public static final SurfaceType ByteA8X11 = SurfaceType.ByteGray.deriveSubType(DESC_BYTE_A8_X11);
+	public static final SurfaceType IntRgbX11 = SurfaceType.IntRgb.deriveSubType(DESC_INT_RGB_X11);
+	public static final SurfaceType IntArgbX11 = SurfaceType.IntArgbPre.deriveSubType(DESC_INT_ARGB_X11);
+
+	public Raster getRaster(int x, int y, int w, int h)
+	{
+		throw new InternalError("not implemented yet");
+	}
+
+	protected XRRenderer x11pipe;
+	protected PixelToShapeConverter x11txpipe;
+	protected TextPipe x11textpipe;
+	protected XRDrawImage xrDrawImage;
+
+	public static void initXRSurfaceData()
+	{
+		if (!X11GraphicsEnvironment.isX11SurfaceDataInitialized())
+		{
+			boolean cacheGradients = true;
+			String xProp = System.getProperty("sun.java2d.xrgradcache");
+			if (xProp != null)
+			{
+				cacheGradients = !(xProp.equalsIgnoreCase("false") || xProp.equalsIgnoreCase("f"));
+			}
+
+			initIDs(cacheGradients);
+
+			XRPMBlitLoops.register();
+			XRMaskFill.register();
+			XRMaskBlit.register();
+
+			X11GraphicsEnvironment.setX11SurfaceDataInitialized();
+		}
+	}
+
+	protected boolean isDrawableValid()
+	{
+		try
+		{
+			SunToolkit.awtLock();
+			return XRIsDrawableValid();
+		} finally
+		{
+			SunToolkit.awtUnlock();
+		}
+	}
+
+	@Override
+	public SurfaceDataProxy makeProxyFor(SurfaceData srcData)
+	{
+		return XRSurfaceDataProxy.createProxy(srcData, graphicsConfig);
+	}
+
+	public void validatePipe(SunGraphics2D sg2d)
+	{
+	        TextPipe textpipe;
+	        boolean validated = false;
+
+	        if (/* CompositeType.SrcNoEa (any color) */
+	            (sg2d.compositeState <= SunGraphics2D.COMP_ISCOPY &&
+	             sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR)        ||
+
+	            /* CompositeType.SrcOver (any color) */
+	            (sg2d.compositeState == SunGraphics2D.COMP_ALPHA    &&
+	             sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR &&
+	             (((AlphaComposite)sg2d.composite).getRule() ==
+	              AlphaComposite.SRC_OVER)))
+	        {
+	            textpipe = x11textpipe;
+	        } else {
+	            // do this to initialize textpipe correctly; we will attempt
+	            // to override the non-text pipes below
+	            super.validatePipe(sg2d);
+	            textpipe = sg2d.textpipe;
+	            validated = true;
+	        }
+
+	        PixelToShapeConverter txPipe = null;
+	        XRRenderer nonTxPipe = null;
+
+	        if (sg2d.antialiasHint != SunHints.INTVAL_ANTIALIAS_ON) 
+	        {
+	            if (sg2d.paintState <= sg2d.PAINT_ALPHACOLOR) {
+	                if (sg2d.compositeState < sg2d.COMP_XOR) {
+	                    txPipe = x11txpipe;
+	                    nonTxPipe = x11pipe;
+	                }
+	            } else if (sg2d.compositeState <= sg2d.COMP_ALPHA) {
+	                if (isPaintValid(sg2d)) {
+	                    txPipe = x11txpipe;
+	                    nonTxPipe = x11pipe;
+	                }
+	                // custom paints handled by super.validatePipe() below
+	            }
+	        }
+
+	        if (txPipe != null) {
+	            if (sg2d.transformState >= sg2d.TRANSFORM_TRANSLATESCALE) {
+	                sg2d.drawpipe = txPipe;
+	                sg2d.fillpipe = txPipe;
+	            } else if (sg2d.strokeState != sg2d.STROKE_THIN) {
+	                sg2d.drawpipe = txPipe;
+	                sg2d.fillpipe = nonTxPipe;
+	            } else {
+	                sg2d.drawpipe = nonTxPipe;
+	                sg2d.fillpipe = nonTxPipe;
+	            }
+	            sg2d.shapepipe = nonTxPipe;
+	        } else {
+	            if (!validated) {
+	                super.validatePipe(sg2d);
+	            }
+	        }
+
+	        // install the text pipe based on our earlier decision
+	        sg2d.textpipe = textpipe;
+
+	        // always override the image pipe with the specialized OGL pipe
+	        sg2d.imagepipe = xrDrawImage;
+		
+//		
+//		if (sg2d.antialiasHint != SunHints.INTVAL_ANTIALIAS_ON && /*sg2d.paintState <= sg2d.PAINT_ALPHACOLOR &&*/(sg2d.compositeState <= sg2d.COMP_ALPHA || sg2d.compositeState == sg2d.COMP_XOR))
+//		{
+//			if (x11txpipe == null)
+//			{
+//				/*
+//				 * Note: this is thread-safe since x11txpipe is the
+//				 * second of the two pipes constructed in makePipes().
+//				 * In the rare case we are racing against another
+//				 * thread making new pipes, setting lazypipe is a
+//				 * safe alternative to waiting for the other thread.
+//				 */
+//				sg2d.drawpipe = lazypipe;
+//				sg2d.fillpipe = lazypipe;
+//				sg2d.shapepipe = lazypipe;
+//				sg2d.imagepipe = lazypipe;
+//				sg2d.textpipe = lazypipe;
+//				return;
+//			}
+//
+//			if (sg2d.transformState >= sg2d.TRANSFORM_TRANSLATESCALE)
+//			{
+//				sg2d.drawpipe = x11txpipe;
+//				sg2d.fillpipe = x11txpipe;
+//			} else if (sg2d.strokeState != sg2d.STROKE_THIN)
+//			{
+//				sg2d.drawpipe = x11txpipe;
+//				sg2d.fillpipe = x11pipe;
+//			} else
+//			{
+//				sg2d.drawpipe = x11pipe;
+//				sg2d.fillpipe = x11pipe;
+//			}
+//			sg2d.shapepipe = x11pipe;
+//			sg2d.imagepipe = new XRDrawImage();
+//		} else
+//		{
+//			super.validatePipe(sg2d);
+//		}
+//
+//		//		 if (sg2d.compositeState <= sg2d.COMP_ALPHA) {
+//		//             if (XRPaints.isValid(sg2d)) {
+//		//                 sg2d.drawpipe = x11pipe;
+//		//                 sg2d.fillpipe = x11pipe;
+//		//             }
+//		//		 }
+//
+//		sg2d.textpipe = x11textpipe;
+
+	}
+	
+
+    @Override
+    protected MaskFill getMaskFill(SunGraphics2D sg2d) {
+        if (sg2d.paintState > sg2d.PAINT_ALPHACOLOR && !isPaintValid(sg2d)) {
+            	return null;
+        }
+        return super.getMaskFill(sg2d);
+    }
+
+	public RenderLoops getRenderLoops(SunGraphics2D sg2d)
+	{
+		if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR && sg2d.compositeState <= sg2d.COMP_ALPHA)
+		{
+			return solidloops;
+		}
+		
+		return super.getRenderLoops(sg2d);
+	}
+
+	public GraphicsConfiguration getDeviceConfiguration()
+	{
+		return graphicsConfig;
+	}
+
+	/**
+	 * Method for instantiating a Window SurfaceData
+	 */
+	public static XRWindowSurfaceData createData(X11ComponentPeer peer)
+	{
+		XRGraphicsConfig gc = getGC(peer);
+		return new XRWindowSurfaceData(peer, gc, gc.getSurfaceType());
+	}
+
+	/**
+	 * Method for instantiating a Pixmap SurfaceData (offscreen)
+	 */
+	public static XRPixmapSurfaceData createData(XRGraphicsConfig gc, int width, int height, ColorModel cm, Image image, long drawable, int transparency)
+	{
+		int depth = transparency > Transparency.OPAQUE ? 32 : 24;
+		if (depth == 24)
+		{
+			cm = new DirectColorModel(depth, 0x00FF0000, 0x0000FF00, 0x000000FF);
+		} else
+		{
+			cm = new DirectColorModel(depth, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
+		}
+
+		return new XRPixmapSurfaceData(gc, width, height, image, getSurfaceType(gc, transparency), cm, drawable, transparency, XRUtils.getPictureFormatForTransparency(transparency), depth);
+	}
+
+	public static XRPixmapSurfaceData createData(XRGraphicsConfig gc, int width, int height)
+	{
+		/*TODO - may I really pass this XRGraphicsConfig down, although depth is different??*/
+		return new XRPixmapSurfaceData(gc, width, height, null, ByteA8X11, new DirectColorModel(8, 0x00000000, 0x00000000, 0x00000000, 0x000000FF), 0, Transparency.OPAQUE, XRUtils.PictStandardA8, 8);
+	}
+
+	//	/**
+	//	 * Initializes the native Ops pointer.
+	//	 */
+	private native void initOps(X11ComponentPeer peer, XRGraphicsConfig gc, int depth);
+
+	protected XRSurfaceData(X11ComponentPeer peer, XRGraphicsConfig gc, SurfaceType sType, ColorModel cm, int depth, int transparency)
+	{
+		super(sType, cm);
+		this.peer = peer;
+		this.graphicsConfig = gc;
+		this.solidloops = graphicsConfig.getSolidLoops(sType);
+		this.depth = depth;
+		initOps(peer, graphicsConfig, depth);
+
+		setBlitProxyKey(gc.getProxyKey());
+	}
+
+	public void initXRender(int pictureFormat)
+	{
+		try
+		{
+			SunToolkit.awtLock();
+			XRInitXRender(getNativeOps(), pictureFormat);
+		} finally
+		{
+			SunToolkit.awtUnlock();
+		}
+	}
+
+	public static XRGraphicsConfig getGC(X11ComponentPeer peer)
+	{
+		if (peer != null)
+		{
+			return (XRGraphicsConfig) peer.getGraphicsConfiguration();
+		} else
+		{
+			GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
+			GraphicsDevice gd = env.getDefaultScreenDevice();
+			return (XRGraphicsConfig) gd.getDefaultConfiguration();
+		}
+	}
+
+	/**
+	 * Returns a boolean indicating whether or not a copyArea from
+	 * the given rectangle source coordinates might be incomplete
+	 * and result in X11 GraphicsExposure events being generated
+	 * from XCopyArea.
+	 * This method allows the SurfaceData copyArea method to determine
+	 * if it needs to set the GraphicsExposures attribute of the X11 GC
+	 * to True or False to receive or avoid the events.
+	 * @return true if there is any chance that an XCopyArea from the
+	 *              given source coordinates could produce any X11
+	 *              Exposure events.
+	 */
+	public abstract boolean canSourceSendExposures(int x, int y, int w, int h);
+	
+	public void validateCopyAreaGC(Region gcClip)
+	{
+		if (validatedGCClip != gcClip)
+		{
+			if (gcClip != null)
+			{
+				//XRSetClip(getNativeOps(), clip.getLoX(), clip.getLoY(), clip.getHiX(), clip.getHiY(), clip.isRectangular() ? null : clip);
+			} else
+			{
+				//XRResetClip(getNativeOps());
+			}
+			validatedGCClip = gcClip;
+		}
+	}
+
+	public boolean copyArea(SunGraphics2D sg2d, int x, int y, int w, int h, int dx, int dy)
+	{
+		if (x11pipe == null)
+		{
+			if (!isDrawableValid())
+			{
+				return true;
+			}
+			makePipes();
+		}
+		CompositeType comptype = sg2d.imageComp;
+		if (sg2d.transformState < sg2d.TRANSFORM_TRANSLATESCALE && (CompositeType.SrcOverNoEa.equals(comptype) || CompositeType.SrcNoEa.equals(comptype)))
+		{
+			x += sg2d.transX;
+			y += sg2d.transY;
+			SunToolkit.awtLock();
+			try
+			{
+				validateCopyAreaGC(sg2d.getCompClip());
+				//validate(sg2d.getCompClip(), sg2d.composite, sg2d.transform, sg2d.paint, sg2d, 0);
+				//						boolean needExposures = canSourceSendExposures(x, y, w, h);
+				//						long xgc = getBlitGC(sg2d.getCompClip(), needExposures);
+				
+				
+				x11pipe.devCopyArea(getNativeOps(), xgc, x, y, x + dx, y + dy, w, h);
+				//X11PMBlitLoops.nativeRenderBlit(getNativeOps(), getNativeOps(), x, y, dx, dy, w, h);
+			} finally
+			{
+				SunToolkit.awtUnlock();
+			}
+			return true;
+		}
+		return false;
+	}
+
+	public static SurfaceType getSurfaceType(XRGraphicsConfig gc, int transparency)
+	{
+		SurfaceType sType = null;
+
+		switch (transparency)
+		{
+			case Transparency.OPAQUE:
+				sType = XRSurfaceData.IntRgbX11;
+				break;
+
+			case Transparency.BITMASK:
+			case Transparency.TRANSLUCENT:
+				sType = XRSurfaceData.IntArgbX11;
+				break;
+		}
+
+		return sType;
+	}
+
+	public native void setInvalid();
+
+	public void invalidate()
+	{
+		if (isValid())
+		{
+			setInvalid();
+			super.invalidate();
+		}
+	}
+
+	/**
+	 * The following methods and variables are used to keep the Java-level
+	 * context state in sync with the native X11 GC associated with this
+	 * X11SurfaceData object.
+	 */
+
+	private static native long XCreateGC(long pXSData);
+
+	private static native void XRSetForeground(int pixel);
+
+	private static native void XRSetComposite(int compRule, float eAlpha);
+
+	private static native void XRSetClip(long xsdo, int lox, int loy, int hix, int hiy, Region complexclip);
+
+	private static native void XRResetClip(long xsdo);
+
+	private static native void XRSetTransformNative(long xsdo, int m00, int m01, int m02, int m10, int m11, int m12);
+
+	private static native void XRSetTexturePaint(long xsdo);
+
+	private static native void XRResetPaint();
+
+	private static native void XRSetRepeat(long xsdo, int repeat);
+
+	private void XRSetTransform(AffineTransform transform)
+	{
+		double[] transformData = new double[6];
+		transform.getMatrix(transformData);
+
+		XRSetTransformNative(getNativeOps(), XDoubleToFixed(transformData[0]), XDoubleToFixed(transformData[2]), XDoubleToFixed(transformData[4]), XDoubleToFixed(transformData[1]), XDoubleToFixed(transformData[3]), XDoubleToFixed(transformData[5]));
+	}
+
+	//private long xgc;
+
+	public static int validatedPixel = -1;
+	public static int validatedPaintState = -1;
+	private static Composite validatedComp;
+	public static Paint validatedPaint;
+	private static int validatedTextureInterpolation = -1;
+
+	private Region validatedClip;
+	private Region validatedGCClip;
+	private boolean validatedExposures = true;
+
+	private int validatedFlags;
+
+	private boolean transformInUse = false;
+	private AffineTransform validatedSourceTransform = new AffineTransform();
+	private int validatedRepeat = XRUtils.RepeatNone;
+	private int validatedInterpolation = -1;
+
+	private int preferredInterpolation = -1;
+
+	public void setPreferredInterpolation(int interpolation)
+	{
+		this.preferredInterpolation = interpolation;
+	}
+
+	public void setShapeClip(Shape shape)
+	{
+		Region shapeClip = Region.getInstance(validatedClip, shape, null);
+		XRSetClip(getNativeOps(), shapeClip.getLoX(), shapeClip.getLoY(), shapeClip.getHiX(), shapeClip.getHiY(), shapeClip.isRectangular() ? null : shapeClip);
+	}
+
+	public void resetShapeClip()
+	{
+		XRSetClip(getNativeOps(), validatedClip.getLoX(), validatedClip.getLoY(), validatedClip.getHiX(), validatedClip.getHiY(), validatedClip.isRectangular() ? null : validatedClip);
+	}
+
+	void validateAsSource(AffineTransform sxForm, int repeat)
+	{
+		validateAsSource(sxForm, repeat, preferredInterpolation);
+	}
+
+	void validateAsSource(AffineTransform sxForm, int repeat, int interpolation)
+	{
+		if (validatedClip != null)
+		{
+			validatedClip = null;
+			XRResetClip(getNativeOps());
+		}
+
+		if (validatedRepeat != repeat)
+		{
+			validatedRepeat = repeat;
+			XRSetRepeat(getNativeOps(), repeat);
+		}
+
+		if (sxForm == null)
+		{
+			if (transformInUse)
+			{
+				validatedSourceTransform.setToIdentity();
+				XRSetTransform(validatedSourceTransform);
+				transformInUse = false;
+			}
+		} else
+		{
+			if (!transformInUse || (transformInUse && !sxForm.equals(validatedSourceTransform)))
+			{
+				validatedSourceTransform.setTransform(sxForm.getScaleX(), sxForm.getShearY(), sxForm.getShearX(), sxForm.getScaleY(), sxForm.getTranslateX(), sxForm.getTranslateY());
+				XRSetTransform(validatedSourceTransform);
+				transformInUse = true;
+			}
+		}
+
+		if (interpolation != validatedInterpolation)
+		{
+			XRSetFilter(getNativeOps(), interpolation);
+			validatedInterpolation = interpolation;
+		}
+	}
+
+	public static native void XRSetFilter(long xsdo, int value);
+
+	private void setComposite(Composite comp)
+	{
+		if (comp instanceof AlphaComposite)
+		{
+			AlphaComposite aComp = (AlphaComposite) comp;
+			float extraAlpha = aComp.getAlpha();
+			//extraAlphaUsed = extraAlpha != 1.0f;
+
+			XRSetComposite(XRUtils.j2dAlphaCompToXR(aComp.getRule()), extraAlpha);
+		} else if (comp instanceof XORComposite)
+		{
+
+		} else
+		{
+			throw new InternalError("Composite accaleration not implemented for: " + comp.getClass().getName());
+		}
+	}
+
+	public static int[] convertToIntArgbPixels(Color[] colors, boolean linear)
+	{
+		int[] pixels = new int[colors.length];
+		for (int i = 0; i < colors.length; i++)
+		{
+			pixels[i] = colorToIntArgbPixel(colors[i], linear);
+		}
+		return pixels;
+	}
+
+	public static int colorToIntArgbPixel(Color c, boolean linear)
+	{
+		int rgb = c.getRGB();
+		if (!linear && ((rgb >> 24) == -1))
+		{
+			return rgb;
+		}
+		int a = rgb >>> 24;
+		int r = (rgb >> 16) & 0xff;
+		int g = (rgb >> 8) & 0xff;
+		int b = (rgb) & 0xff;
+		if (linear)
+		{
+			r = BufferedPaints.convertSRGBtoLinearRGB(r);
+			g = BufferedPaints.convertSRGBtoLinearRGB(g);
+			b = BufferedPaints.convertSRGBtoLinearRGB(b);
+		}
+
+		return ((a << 24) | (r << 16) | (g << 8) | (b));
+	}
+
+	private static void setGradientPaint(SunGraphics2D sg2d, GradientPaint paint, boolean useMask)
+	{
+		int[] pixels = convertToIntArgbPixels(new Color[] { paint.getColor1(), paint.getColor2() }, false);
+
+		float fractions[] = new float[2];
+		fractions[0] = 0;
+		fractions[1] = 1;
+
+		Point2D pt1 = paint.getPoint1();
+		Point2D pt2 = paint.getPoint2();
+
+		AffineTransform at = (AffineTransform) sg2d.transform.clone();
+		try
+		{
+			at.invert();
+		} catch (NoninvertibleTransformException ex)
+		{
+			ex.printStackTrace();
+		}
+
+		double[] transformData = new double[6];
+		at.getMatrix(transformData);
+
+		int repeat = paint.isCyclic() ? XRUtils.RepeatReflect : XRUtils.RepeatPad;
+
+		XRSetLinearGradientPaint(fractions, pixels, XDoubleToFixed(pt1.getX()), XDoubleToFixed(pt1.getY()), XDoubleToFixed(pt2.getX()), XDoubleToFixed(pt2.getY()), 2, repeat, useMask, false, XDoubleToFixed(transformData[0]), XDoubleToFixed(transformData[2]), XDoubleToFixed(transformData[4]), XDoubleToFixed(transformData[1]),
+				XDoubleToFixed(transformData[3]), XDoubleToFixed(transformData[5]));
+	}
+
+	public static boolean isPaintValid(SunGraphics2D sg2d)
+	{
+		if(sg2d.paintState == SunGraphics2D.PAINT_RAD_GRADIENT)
+		{
+			RadialGradientPaint grad = (RadialGradientPaint) sg2d.paint;
+			return grad.getFocusPoint().equals(grad.getCenterPoint());
+		}
+		
+		return true;
+	}
+	
+	public static void setRadialGradientPaint(SunGraphics2D sg2d, RadialGradientPaint paint)
+	{
+		boolean linear = (paint.getColorSpace() == ColorSpaceType.LINEAR_RGB);
+		Color[] colors = paint.getColors();
+		int numStops = colors.length;
+		Point2D center = paint.getCenterPoint();
+		Point2D focus = paint.getFocusPoint();
+
+		int cycleMethod = XRUtils.getRepeatForCycleMethod(paint.getCycleMethod());
+		float[] fractions = paint.getFractions();
+		int[] pixels = convertToIntArgbPixels(colors, linear);
+		float radius = paint.getRadius();
+
+		// save original (untransformed) center and focus points
+		double cx = center.getX();
+		double cy = center.getY();
+		double fx = focus.getX();
+		double fy = focus.getY();
+
+		AffineTransform at = paint.getTransform();
+		at.preConcatenate(sg2d.transform);
+		focus = at.transform(focus, focus);
+
+		// transform unit circle to gradient coords; we start with the
+		// unit circle (center=(0,0), focus on positive x-axis, radius=1)
+		// and then transform into gradient space
+		at.translate(cx, cy);
+		at.rotate(fx - cx, fy - cy);
+		//  at.scale(radius, radius);
+
+		// invert to get mapping from device coords to unit circle
+		try
+		{
+			at.invert();
+		} catch (Exception e)
+		{
+			at.setToScale(0.0, 0.0);
+		}
+		focus = at.transform(focus, focus);
+
+		// clamp the focus point so that it does not rest on, or outside
+		// of, the circumference of the gradient circle
+		fx = Math.min(focus.getX(), 0.99);
+
+		double[] transformData = new double[6];
+		at.getMatrix(transformData);
+
+		XRSetRadialGradientPaint(fractions, pixels, XDoubleToFixed(fx), numStops, cycleMethod, false, linear, XDoubleToFixed(0), XDoubleToFixed(radius), XDoubleToFixed(transformData[0]), XDoubleToFixed(transformData[2]), XDoubleToFixed(transformData[4]), XDoubleToFixed(transformData[1]), XDoubleToFixed(transformData[3]),
+				XDoubleToFixed(transformData[5]));
+	}
+
+	public native static void XRSetRadialGradientPaint(float[] fractions, int[] pixels, int fx, int numStops, int cycleMethod, boolean useMask, boolean linear, int innerRadius, int outerRadius, int m00, int m01, int m02, int m10, int m11, int m12);
+
+	public static void setLinearGradientPaint(SunGraphics2D sg2d, LinearGradientPaint paint, boolean useMask)
+	{
+		boolean linear = (paint.getColorSpace() == ColorSpaceType.LINEAR_RGB);
+		Color[] colors = paint.getColors();
+		int numStops = colors.length;
+		Point2D pt1 = paint.getStartPoint();
+		Point2D pt2 = paint.getEndPoint();
+
+		AffineTransform at = paint.getTransform();
+		at.preConcatenate(sg2d.transform);
+
+		int cycleMethod = XRUtils.getRepeatForCycleMethod(paint.getCycleMethod());
+		float[] fractions = paint.getFractions();
+		int[] pixels = convertToIntArgbPixels(colors, linear);
+
+		try
+		{
+			at.invert();
+		} catch (NoninvertibleTransformException ex)
+		{
+			ex.printStackTrace();
+		}
+
+		double[] transformData = new double[6];
+		at.getMatrix(transformData);
+
+		XRSetLinearGradientPaint(fractions, pixels, XDoubleToFixed(pt1.getX()), XDoubleToFixed(pt1.getY()), XDoubleToFixed(pt2.getX()), XDoubleToFixed(pt2.getY()), numStops, cycleMethod, useMask, linear, XDoubleToFixed(transformData[0]), XDoubleToFixed(transformData[2]), XDoubleToFixed(transformData[4]), XDoubleToFixed(transformData[1]),
+				XDoubleToFixed(transformData[3]), XDoubleToFixed(transformData[5]));
+	}
+
+	private static native void XRSetLinearGradientPaint(float[] fractions, int[] pixels, int x1, int y1, int x2, int y2, int numStops, int cycleMethod, boolean useMask, boolean linear, int m00, int m01, int m02, int m10, int m11, int m12);
+
+	private static TexturePaint setTexturePaint(SunGraphics2D sg2d, TexturePaint paint, boolean useMask)
+	{
+		BufferedImage bi = paint.getImage();
+		SurfaceData dstData = sg2d.surfaceData;
+		SurfaceData srcData = dstData.getSourceSurfaceData(bi, SunGraphics2D.TRANSFORM_ISIDENT, CompositeType.SrcOver, null);
+
+		// REMIND: this hack tries to ensure that we have a cached texture
+		if (!(srcData instanceof XRSurfaceData))
+		{
+			srcData = dstData.getSourceSurfaceData(paint.getImage(), SunGraphics2D.TRANSFORM_ISIDENT, CompositeType.SrcOver, null);
+			if (!(srcData instanceof XRSurfaceData))
+			{
+				return null;
+			}
+		}
+
+		XRSurfaceData x11SrcData = (XRSurfaceData) srcData;
+
+		validatedTextureInterpolation = sg2d.interpolationType;
+		XRSetFilter(x11SrcData.getNativeOps(), XRUtils.ATransOpToXRQuality(sg2d.interpolationType));
+
+		AffineTransform at = (AffineTransform) sg2d.transform.clone();
+		Rectangle2D anchor = paint.getAnchorRect();
+		at.translate(anchor.getX(), anchor.getY());
+		at.scale(anchor.getWidth() / ((double) bi.getWidth()), anchor.getHeight() / ((double) bi.getHeight()));
+		try
+		{
+			at.invert();
+		} catch (NoninvertibleTransformException ex)
+		{
+			ex.printStackTrace();
+		}
+
+		x11SrcData.validateAsSource(at, XRUtils.RepeatNormal, XRUtils.ATransOpToXRQuality(sg2d.interpolationType)); /*Todo - doesn't work if interpolation value is changed after texturepaint is "realized"*/
+
+		XRSetTexturePaint(srcData.getNativeOps());
+
+		return paint;
+	}
+
+	public void setPaint(SunGraphics2D sg2d, Paint paint)
+	{
+		if (sg2d != null)
+		{
+			if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR)
+			{
+				XRResetPaint();
+			} else
+			{
+				switch (sg2d.paintState)
+				{
+					case SunGraphics2D.PAINT_GRADIENT:
+						setGradientPaint(sg2d, (GradientPaint) paint, false);
+						validatedPaint = paint;
+						break;
+
+					case SunGraphics2D.PAINT_LIN_GRADIENT:
+						setLinearGradientPaint(sg2d, (LinearGradientPaint) paint, false);
+						validatedPaint = paint;
+						break;
+
+					case SunGraphics2D.PAINT_RAD_GRADIENT:
+						setRadialGradientPaint(sg2d, (RadialGradientPaint) paint);
+						validatedPaint = paint;
+						break;
+
+					case SunGraphics2D.PAINT_TEXTURE:
+						validatedPaint = setTexturePaint(sg2d, (TexturePaint) paint, false);
+						break;
+
+					default:
+						throw new InternalError("should not reach");
+				}
+			}
+		}
+	}
+
+	public void validate(Region clip, Composite comp, AffineTransform xform, Paint paint, SunGraphics2D sg2d, int flags)
+	{
+		boolean updateClip = (clip != validatedClip);
+		boolean updatePaint = (paint != validatedPaint) || paint == null;
+
+		if (!isValid())
+		{
+			throw new InvalidPipeException("bounds changed");
+		}
+
+		// validate clip
+		if (updateClip)
+		{
+			if (clip != null)
+			{
+				XRSetClip(getNativeOps(), clip.getLoX(), clip.getLoY(), clip.getHiX(), clip.getHiY(), clip.isRectangular() ? null : clip);
+			} else
+			{
+				XRResetClip(getNativeOps());
+			}
+			validatedClip = clip;
+		}
+
+		// validate composite (note that a change in the context flags
+		// may require us to update the composite state, even if the
+		// composite has not changed)
+		if ((comp != validatedComp) || (flags != validatedFlags))
+		{
+			if (comp != null)
+			{
+				setComposite(comp);
+			} else
+			{
+				comp = AlphaComposite.getInstance(AlphaComposite.SRC_OVER);
+				setComposite(comp);
+			}
+			// the paint state is dependent on the composite state, so make
+			// sure we update the color below
+			updatePaint = true;
+			validatedComp = comp;
+			validatedFlags = flags;
+		}
+
+		if (sg2d != null && validatedPixel != sg2d.pixel)
+		{
+			validatedPixel = sg2d.pixel;
+			XRSetForeground(validatedPixel);
+		}
+
+		// validate paint
+		if (updatePaint)
+		{
+			if (paint != null)
+			{
+				setPaint(sg2d, paint);
+			} else
+			{
+				XRResetPaint();
+			}
+			validatedPaint = paint;
+		}
+	}
+
+	long xgc;
+
+	public void makePipes()
+	{
+		if (x11pipe == null)
+		{
+			try
+			{
+				SunToolkit.awtLock();
+				xgc = XCreateGC(getNativeOps());
+
+				x11pipe = XRRenderer.getInstance();
+				x11txpipe = new PixelToShapeConverter(x11pipe);
+				x11textpipe = new XRTextRenderer();
+				xrDrawImage = new XRDrawImage();
+			} finally
+			{
+				SunToolkit.awtUnlock();
+			}
+		}
+	}
+
+	public static class XRWindowSurfaceData extends XRSurfaceData
+	{
+		public XRWindowSurfaceData(X11ComponentPeer peer, XRGraphicsConfig gc, SurfaceType sType)
+		{
+			super(peer, gc, sType, peer.getColorModel(), peer.getColorModel().getPixelSize(), Transparency.OPAQUE);
+
+			if (isDrawableValid())
+			{
+				initXRender(XRUtils.getPictureFormatForTransparency(Transparency.OPAQUE));
+				makePipes();
+			}
+		}
+
+		public SurfaceData getReplacement()
+		{
+			return peer.getSurfaceData();
+		}
+
+		public Rectangle getBounds()
+		{
+			Rectangle r = peer.getBounds();
+			r.x = r.y = 0;
+			return r;
+		}
+
+		@Override
+		public boolean canSourceSendExposures(int x, int y, int w, int h)
+		{
+			return true;
+		}
+
+		/**
+		 * Returns destination Component associated with this SurfaceData.
+		 */
+		public Object getDestination()
+		{
+			return peer.getTarget();
+		}
+	}
+
+	public static class XRPixmapSurfaceData extends XRSurfaceData
+	{
+		Image offscreenImage;
+		int width;
+		int height;
+		int transparency;
+
+		public XRPixmapSurfaceData(XRGraphicsConfig gc, int width, int height, Image image, SurfaceType sType, ColorModel cm, long drawable, int transparency, int pictFormat, int depth)
+		{
+			super(null, gc, sType, cm, depth, transparency);
+			this.width = width;
+			this.height = height;
+			offscreenImage = image;
+			this.transparency = transparency;
+			initSurface(depth, width, height, drawable, pictFormat);
+			makePipes();
+		}
+
+		public void initSurface(int depth, int width, int height, long drawable, int pictFormat)
+		{
+			try
+			{
+				SunToolkit.awtLock();
+				XRInitSurface(depth, width, height, drawable, pictFormat);
+			} finally
+			{
+				SunToolkit.awtUnlock();
+			}
+		}
+
+		public SurfaceData getReplacement()
+		{
+			return restoreContents(offscreenImage);
+		}
+
+		/**
+		 * Need this since the surface data is created with
+		 * the color model of the target GC, which is always
+		 * opaque. But in SunGraphics2D.blitSD we choose loops
+		 * based on the transparency on the source SD, so
+		 * it could choose wrong loop (blit instead of blitbg,
+		 * for example).
+		 */
+		public int getTransparency()
+		{
+			return transparency;
+		}
+
+		public Rectangle getBounds()
+		{
+			return new Rectangle(width, height);
+		}
+
+		@Override
+		public boolean canSourceSendExposures(int x, int y, int w, int h)
+		{
+			return (x < 0 || y < 0 || (x + w) > width || (y + h) > height);
+		}
+
+		public void flush()
+		{
+			/*
+			 * We need to invalidate the surface before disposing the
+			 * native Drawable and GC.  This way if an application tries
+			 * to render to an already flushed X11SurfaceData, we will notice
+			 * in the validate() method above that it has been invalidated,
+			 * and we will avoid using those native resources that have
+			 * already been disposed.
+			 */
+			invalidate();
+			flushNativeSurface();
+		}
+
+		/**
+		 * Returns destination Image associated with this SurfaceData.
+		 */
+		public Object getDestination()
+		{
+			return offscreenImage;
+		}
+	}
+
+	private static LazyPipe lazypipe = new LazyPipe();
+
+	public static class LazyPipe extends ValidatePipe
+	{
+		public boolean validate(SunGraphics2D sg2d)
+		{
+			XRSurfaceData xsd = (XRSurfaceData) sg2d.surfaceData;
+			if (!xsd.isDrawableValid())
+			{
+				return false;
+			}
+			xsd.makePipes();
+			return super.validate(sg2d);
+		}
+	}
+}
diff -Nru openjdk.orig/jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceDataProxy.java openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceDataProxy.java
--- openjdk.orig/jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceDataProxy.java	1970-01-01 01:00:00.000000000 +0100
+++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceDataProxy.java	2009-05-13 01:02:29.000000000 +0100
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.java2d.xr;
+
+import java.awt.Color;
+import java.awt.AlphaComposite;
+import java.awt.GraphicsConfiguration;
+import java.awt.Transparency;
+import java.awt.image.ColorModel;
+import java.awt.image.IndexColorModel;
+import java.awt.image.DirectColorModel;
+
+import sun.awt.X11GraphicsConfig;
+import sun.java2d.SurfaceData;
+import sun.java2d.SurfaceDataProxy;
+import sun.java2d.SunGraphics2D;
+import sun.java2d.loops.SurfaceType;
+import sun.java2d.loops.CompositeType;
+import sun.java2d.opengl.*;
+
+/**
+ * The proxy class contains the logic for when to replace a
+ * SurfaceData with a cached X11 Pixmap and the code to create
+ * the accelerated surfaces.
+ */
+public class XRSurfaceDataProxy extends SurfaceDataProxy
+    implements Transparency
+{
+    public static SurfaceDataProxy createProxy(SurfaceData srcData,
+                                               XRGraphicsConfig dstConfig)
+    {
+        if (srcData instanceof XRSurfaceData) {
+            // srcData must be a VolatileImage which either matches
+            // our visual or not - either way we do not cache it...
+            return UNCACHED;
+        }
+        
+        return new XRSurfaceDataProxy(dstConfig, srcData.getTransparency());
+    }
+
+    XRGraphicsConfig xrgc;
+    int transparency;
+
+    public XRSurfaceDataProxy(XRGraphicsConfig x11gc) {
+        this.xrgc = x11gc;
+    }
+
+    @Override
+    public SurfaceData validateSurfaceData(SurfaceData srcData,
+                                           SurfaceData cachedData,
+                                           int w, int h)
+    {
+        if (cachedData == null) {
+            // Bitmask will be created lazily during the blit phase
+            cachedData = XRSurfaceData.createData(xrgc, w, h,
+                                                   xrgc.getColorModel(),
+                                                   null, 0, getTransparency());
+        }
+        return cachedData;
+    }
+    
+    public XRSurfaceDataProxy(XRGraphicsConfig x11gc, int transparency) {
+        this.xrgc = x11gc;
+        this.transparency = transparency;
+    }
+
+    @Override
+    public boolean isSupportedOperation(SurfaceData srcData,
+                                        int txtype,
+                                        CompositeType comp,
+                                        Color bgColor)
+    {
+        return (bgColor == null || transparency == Transparency.OPAQUE);
+    }
+
+	public int getTransparency()
+	{
+		return transparency;
+	}
+}
diff -Nru openjdk.orig/jdk/src/solaris/classes/sun/java2d/xr/XRUtils.java openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRUtils.java
--- openjdk.orig/jdk/src/solaris/classes/sun/java2d/xr/XRUtils.java	1970-01-01 01:00:00.000000000 +0100
+++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRUtils.java	2009-05-13 01:02:29.000000000 +0100
@@ -0,0 +1,142 @@
+package sun.java2d.xr;
+
+import static java.awt.AlphaComposite.*;
+
+import java.awt.*;
+import java.awt.MultipleGradientPaint.*;
+import java.awt.image.*;
+
+public class XRUtils
+{
+	/*Composition Operators*/
+	public static final int PictOpClear = 0;
+	public static final int PictOpSrc = 1;
+	public static final int PictOpDst = 2;
+	public static final int PictOpOver = 3;
+	public static final int PictOpOverReverse = 4;
+	public static final int PictOpIn = 5;
+	public static final int PictOpInReverse = 6;
+	public static final int PictOpOut = 7;
+	public static final int PictOpOutReverse = 8;
+	public static final int PictOpAtop = 9;
+	public static final int PictOpAtopReverse = 10;
+	public static final int PictOpXor = 11;
+	public static final int PictOpAdd = 12;
+	public static final int PictOpSaturate = 13;
+
+	/*Repeats*/
+	public static final int RepeatNone = 0;
+	public static final int RepeatNormal = 1;
+	public static final int RepeatPad = 2;
+	public static final int RepeatReflect = 3;
+	
+	/*Interpolation qualities*/
+	public static final int FAST = 0;
+	public static final int GOOD = 1;
+	public static final int BEST = 2;
+	
+	/*PictFormats*/
+	public static final int PictStandardARGB32 = 0;
+	public static final int PictStandardRGB24 = 1;
+	public static final int PictStandardA8 = 2;
+	public static final int PictStandardA4 = 3;
+	public static final int PictStandardA1 = 4;
+	
+	public static int ATransOpToXRQuality(int affineTranformOp)
+	{
+		switch(affineTranformOp)
+		{
+			case AffineTransformOp.TYPE_NEAREST_NEIGHBOR:
+				return FAST;
+				
+			case AffineTransformOp.TYPE_BILINEAR:
+				return GOOD;
+				
+			case AffineTransformOp.TYPE_BICUBIC:
+				return BEST;
+		}
+		
+		return -1;
+	}
+	
+	public static int getPictureFormatForTransparency(int transparency)
+	{ 
+		switch(transparency)
+		{
+			case Transparency.OPAQUE:
+				return PictStandardRGB24;
+				
+			case Transparency.BITMASK:
+			case Transparency.TRANSLUCENT:
+				return PictStandardARGB32;
+		}
+		
+		return -1;
+	}
+
+	public static int getRepeatForCycleMethod(CycleMethod cycleMethod)
+	{
+		if (cycleMethod.equals(CycleMethod.NO_CYCLE))
+		{
+			return RepeatPad;
+		} else if (cycleMethod.equals(CycleMethod.REFLECT))
+		{
+			return RepeatReflect;
+		} else if (cycleMethod.equals(CycleMethod.REPEAT))
+		{
+			return RepeatNormal;
+		}
+
+		return RepeatNone;
+	}
+
+	public static int XDoubleToFixed(double dbl)
+	{
+		return (int) (dbl * 65536);
+	}
+
+	public static int j2dAlphaCompToXR(int j2dRule)
+	{
+		switch (j2dRule)
+		{
+			case CLEAR:
+				return PictOpClear;
+
+			case SRC:
+				//return PictOpOver;
+				return PictOpSrc;
+
+			case DST:
+				return PictOpDst;
+
+			case SRC_OVER:
+				return PictOpOver;
+
+			case DST_OVER:
+				return PictOpOverReverse;
+
+			case SRC_IN:
+				return PictOpIn;
+
+			case DST_IN:
+				return PictOpInReverse;
+
+			case SRC_OUT:
+				return PictOpOut;
+
+			case DST_OUT:
+				return PictOpOutReverse;
+
+			case SRC_ATOP:
+				return PictOpAtop;
+
+			case DST_ATOP:
+				return PictOpAtopReverse;
+
+			case XOR:
+				return PictOpXor;
+		}
+
+		throw new InternalError("No XRender equivalent available for requested java2d composition rule");
+	}
+}
diff -Nru openjdk.orig/jdk/src/solaris/classes/sun/java2d/xr/XRVolatileSurfaceManager.java openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRVolatileSurfaceManager.java
--- openjdk.orig/jdk/src/solaris/classes/sun/java2d/xr/XRVolatileSurfaceManager.java	1970-01-01 01:00:00.000000000 +0100
+++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRVolatileSurfaceManager.java	2009-05-13 01:02:29.000000000 +0100
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2000-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.java2d.xr;
+
+import java.awt.GraphicsConfiguration;
+import java.awt.ImageCapabilities;
+import java.awt.Transparency;
+import java.awt.image.ColorModel;
+import sun.awt.X11GraphicsConfig;
+import sun.awt.image.SunVolatileImage;
+import sun.awt.image.VolatileSurfaceManager;
+import sun.java2d.SurfaceData;
+
+/**
+ * X11 platform implementation of the VolatileSurfaceManager class.
+ * The class attempts to create and use a pixmap-based SurfaceData
+ * object (X11PixmapSurfaceData).
+ * If this object cannot be created or re-created as necessary, the
+ * class falls back to a system memory based SurfaceData object
+ * (BufImgSurfaceData) that will be used until the accelerated
+ * SurfaceData can be restored.
+ */
+public class XRVolatileSurfaceManager extends VolatileSurfaceManager {
+
+    public XRVolatileSurfaceManager(SunVolatileImage vImg, Object context) {
+        super(vImg, context);
+    }
+
+    protected boolean isAccelerationEnabled() {
+        return true;
+    }
+
+    /**
+     * Create a pixmap-based SurfaceData object
+     */
+    protected SurfaceData initAcceleratedSurface() {
+        SurfaceData sData;
+
+        try {
+            XRGraphicsConfig gc = (XRGraphicsConfig) vImg.getGraphicsConfig();
+            ColorModel cm = gc.getColorModel();
+            long drawable = 0;
+            if (context instanceof Long) {
+                drawable = ((Long)context).longValue();
+            }
+            sData = XRSurfaceData.createData(gc,
+                                              vImg.getWidth(),
+                                              vImg.getHeight(),
+                                              cm, vImg, drawable,
+                                              vImg.getTransparency());
+        } catch (NullPointerException ex) {
+            sData = null;
+        } catch (OutOfMemoryError er) {
+            sData = null;
+        }
+
+        return sData;
+    }
+
+    protected boolean isConfigValid(GraphicsConfiguration gc) {
+        // REMIND: we might be too paranoid here, requiring that
+        // the GC be exactly the same as the original one.  The
+        // real answer is one that guarantees that pixmap copies
+        // will be correct (which requires like bit depths and
+        // formats).
+        return ((gc == null) || (gc == vImg.getGraphicsConfig()));
+    }
+
+    /**
+     * Need to override the default behavior because Pixmaps-based
+     * images are accelerated but not volatile.
+     */
+    @Override
+    public ImageCapabilities getCapabilities(GraphicsConfiguration gc) {
+        if (isConfigValid(gc) && isAccelerationEnabled()) {
+            // accelerated but not volatile
+            return new ImageCapabilities(true);
+        }
+        // neither accelerated nor volatile
+        return new ImageCapabilities(false);
+    }
+}
diff -Nru openjdk.orig/jdk/src/solaris/native/sun/font/XRTextRenderer.c openjdk/jdk/src/solaris/native/sun/font/XRTextRenderer.c
--- openjdk.orig/jdk/src/solaris/native/sun/font/XRTextRenderer.c	1970-01-01 01:00:00.000000000 +0100
+++ openjdk/jdk/src/solaris/native/sun/font/XRTextRenderer.c	2009-05-13 01:02:29.000000000 +0100
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2000-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * Important note : All AWTxxx functions are defined in font.h.
+ * These were added to remove the dependency of this file on X11.
+ * These functions are used to perform X11 operations and should
+ * be "stubbed out" in environments that do not support X11.
+ * The implementation of these functions has been moved from this file
+ * into X11TextRenderer_md.c, which is compiled into another library.
+ */
+
+#include "sun_font_X11TextRenderer.h"
+
+#include "Region.h"
+#include "SurfaceData.h"
+#include "GraphicsPrimitiveMgr.h"
+#include "glyphblitting.h"
+#include <malloc.h>
+#include "Trace.h"
+
+
+JNIEXPORT void JNICALL XRT_DrawGlyphList(JNIEnv *env, jobject xtr,
+                 jlong dstData, jint numGlyphs, jboolean subPixPos, jboolean rgbOrder, jint lcdContrast,
+                 jboolean usePositions, jfloat xOrigin, jfloat yOrigin, jlong *images, jfloat *positions);
+
+
+
+JNIEXPORT void JNICALL Java_sun_font_XRTextRenderer_doDrawGlyphList (JNIEnv *env, jobject xtr,
+     jlong dstData, jint numGlyphs, jboolean subPixPos, jboolean rgbOrder, jint lcdContrast,
+     jboolean usePositions, jfloat xOrigin, jfloat yOrigin, jlongArray imgArray, jfloatArray posArray)
+{
+    jlong *images;
+
+    J2dTraceLn(J2D_TRACE_INFO, "XRTextRenderer_drawGlyphList");
+
+    images = (jlong *) (*env)->GetPrimitiveArrayCritical(env, imgArray, NULL);
+    if (images != NULL) {
+
+        if (usePositions == JNI_TRUE) {
+            jfloat *positions = (jfloat *) (*env)->GetPrimitiveArrayCritical(env, posArray, NULL);
+
+            if (positions != NULL) {
+                XRT_DrawGlyphList(env, xtr, dstData, numGlyphs, subPixPos, rgbOrder, lcdContrast, usePositions, xOrigin, yOrigin, images, positions);
+                (*env)->ReleasePrimitiveArrayCritical(env, posArray,
+                                                      positions, JNI_ABORT);
+            }
+        } else {
+            XRT_DrawGlyphList(env, xtr, dstData, numGlyphs, subPixPos, rgbOrder, lcdContrast, usePositions, xOrigin, yOrigin, images, NULL);
+        }
+
+        (*env)->ReleasePrimitiveArrayCritical(env, imgArray,
+                                              images, JNI_ABORT);
+    }
+}
diff -Nru openjdk.orig/jdk/src/solaris/native/sun/java2d/x11/ArrayList.c openjdk/jdk/src/solaris/native/sun/java2d/x11/ArrayList.c
--- openjdk.orig/jdk/src/solaris/native/sun/java2d/x11/ArrayList.c	1970-01-01 01:00:00.000000000 +0100
+++ openjdk/jdk/src/solaris/native/sun/java2d/x11/ArrayList.c	2009-05-13 01:02:29.000000000 +0100
@@ -0,0 +1,39 @@
+#include <malloc.h>
+#include <string.h>
+#include "ArrayList.h"
+
+void initXRList(XrArrayList *list, jint capacity, size_t blkSize)
+{
+  //printf("Init XR LIst!\n");fflush(stdout);
+  list->used = 0;
+  list->capacity = capacity;
+
+  if(capacity != 0) {
+    list->elements = calloc(capacity, blkSize);
+  }else {
+    list->elements = NULL;
+  }
+}
+
+void* getNewXR(XrArrayList *list, size_t blkSize)
+{
+  if((list->used+1) >= list->capacity)
+  {
+    int newCapacity = list->capacity*2 + 10;
+    if(list->capacity > 0) {
+      list->elements = realloc(list->elements, newCapacity * blkSize);
+    }else {
+      list->elements = calloc(newCapacity, blkSize);
+    }
+    list->capacity = newCapacity;
+  }
+
+  return list->elements + (list->used++ * blkSize);
+}
+
+void clearXRList(XrArrayList *list)
+{
+  list->used = 0;
+  //memset(list->elements, 0, list->used);
+}
+
diff -Nru openjdk.orig/jdk/src/solaris/native/sun/java2d/x11/ArrayList.h openjdk/jdk/src/solaris/native/sun/java2d/x11/ArrayList.h
--- openjdk.orig/jdk/src/solaris/native/sun/java2d/x11/ArrayList.h	1970-01-01 01:00:00.000000000 +0100
+++ openjdk/jdk/src/solaris/native/sun/java2d/x11/ArrayList.h	2009-05-13 01:02:29.000000000 +0100
@@ -0,0 +1,18 @@
+#ifndef ArrayList_h_Included
+#define ArrayList_h_Included
+
+#include "jni.h"
+
+typedef struct {
+   void *elements;
+   jint capacity;
+   jint used;
+} XrArrayList;
+
+void initXRList(XrArrayList *list, jint capacity, size_t blkSize);
+
+void* getNewXR(XrArrayList *list, size_t blkSize);
+
+void clearXRList(XrArrayList *list);
+
+#endif /* ArrayList_h_Included */
diff -Nru openjdk.orig/jdk/src/solaris/native/sun/java2d/x11/MaskBuffer.c openjdk/jdk/src/solaris/native/sun/java2d/x11/MaskBuffer.c
--- openjdk.orig/jdk/src/solaris/native/sun/java2d/x11/MaskBuffer.c	1970-01-01 01:00:00.000000000 +0100
+++ openjdk/jdk/src/solaris/native/sun/java2d/x11/MaskBuffer.c	2009-05-13 01:02:29.000000000 +0100
@@ -0,0 +1,576 @@
+#include "MaskBuffer.h"
+#include "XRSurfaceData.h"
+#include "X11SurfaceData.h"
+
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+
+#define GET_DIRTY_LINE_REGION(X1, Y1, X2, Y2, RX1, RY1, RX2, RY2)        \
+  {                                                                      \
+    if(X1 < X2) {                                                        \
+      RX1 = X1;                                                          \
+      RX2 = X2;                                                          \
+    }else {                                                              \
+      RX1 = X2;                                                          \
+      RX2 = X1;                                                          \
+    }                                                                    \
+                                                                         \
+    if(Y1 < Y2) {                                                        \
+      RY1 = Y1;                                                          \
+      RY2 = Y2;                                                          \
+    }else {                                                              \
+      RY1 = Y2;                                                          \
+      RY2 = Y1;                                                          \
+    }                                                                    \
+  }
+
+#ifndef HEADLESS
+MaskBuffer* initMaskBuffer(Window window)
+{
+  MaskBuffer *buffer = malloc(sizeof(MaskBuffer));
+  initRegion(&buffer->region);
+ 
+  initXRList(&buffer->rects, sizeof(XRectangle), 512);
+  initXRList(&buffer->lines, sizeof(XSegment), 512);
+
+  buffer->xTiles = 0;
+  buffer->yTiles = 0;
+  buffer->xTileCap = 0;
+  buffer->yTileCap = 0;
+  buffer->tiles = NULL;
+
+  XRenderPictFormat *fmt = XRenderFindStandardFormat(awt_display, PictStandardA8);
+  XRenderPictFormat *fmt32 = XRenderFindStandardFormat(awt_display, PictStandardARGB32);
+
+  buffer->maskPixmap = XCreatePixmap(awt_display, window, MASK_TILE_SIZE, MASK_TILE_SIZE, 8);
+  buffer->lineMaskPixmap = XCreatePixmap(awt_display, window, MASK_TILE_SIZE, MASK_TILE_SIZE, 8);
+  buffer->gradPixmap = XCreatePixmap(awt_display, window, MASK_TILE_SIZE, MASK_TILE_SIZE, 32);
+ 
+  XRenderPictureAttributes pict_attr;
+  buffer->maskPicture = XRenderCreatePicture(awt_display, buffer->maskPixmap, fmt, 0, &pict_attr);
+  buffer->lineMaskPicture = XRenderCreatePicture(awt_display, buffer->lineMaskPixmap, fmt, 0, &pict_attr);
+  buffer->gradPict = XRenderCreatePicture(awt_display, buffer->gradPixmap, fmt32, 0, &pict_attr);
+
+  XRenderColor color_black={.red=0, .green=0, .blue=0, .alpha=0xffff};
+  XRenderFillRectangle (awt_display, PictOpClear, buffer->maskPicture, &color_black, 0, 0, MASK_TILE_SIZE, MASK_TILE_SIZE);
+  XRenderFillRectangle (awt_display, PictOpClear, buffer->lineMaskPicture, &color_black, 0, 0, MASK_TILE_SIZE, MASK_TILE_SIZE);
+  XRenderFillRectangle (awt_display, PictOpClear, buffer->gradPict, &color_black, 0, 0, MASK_TILE_SIZE, MASK_TILE_SIZE);
+
+  buffer->validatedGCAlpha = 1.0f;
+  XGCValues values;
+  values.foreground = 255;
+  buffer->drawLineGC = XCreateGC(awt_display, buffer->lineMaskPixmap, GCForeground, &values);
+  /*Invisible GC for readback assistance*/
+  values.foreground = 0;
+  buffer->clearLineGC = XCreateGC(awt_display, buffer->lineMaskPixmap, GCForeground, &values);
+
+  return buffer;
+}
+
+static void allocTileBuffer(MaskBuffer* buf)
+{
+  buf->xTiles = ((buf->region.x2 - buf->region.x) / MASK_TILE_SIZE) + 1;
+  buf->yTiles = ((buf->region.y2 - buf->region.y) / MASK_TILE_SIZE) + 1;
+
+  //If current tile-array is too small, allocate a larger one
+  if(buf->tiles == NULL || buf->xTileCap < buf->xTiles || buf->yTileCap < buf->yTiles) {
+    buf->xTileCap = MAX((buf->xTiles * 2), buf->xTileCap);
+    buf->yTileCap = MAX((buf->yTiles * 2), buf->yTileCap);
+    if(buf->tiles != NULL) {
+      free(buf->tiles);
+    }
+    buf->tiles = calloc(buf->xTileCap * buf->yTileCap, sizeof(XrTile));
+  }
+
+  //Init/Reset the tiles that will be used later
+  int x,y;
+  for(y=0; y < buf->yTiles; y++) {
+    for(x=0; x < buf->xTiles; x++) {
+      initXrTile(&buf->tiles[y*buf->xTileCap + x]);
+    }
+ }
+}
+
+static void cleanMaskBuffer(MaskBuffer *buf)
+{
+  initRegion(&buf->region); //TODO: eigentlich nicht noetig
+  buf->xTiles = 0;
+  buf->yTiles = 0;
+  clearXRList(&buf->rects);
+  clearXRList(&buf->lines);
+}
+
+static void getTileDirtyArea(MaskRegion *dirtyRectArea, MaskRegion *dirtyLineArea, MaskRegion *totalDirtyArea)
+{
+  totalDirtyArea->x = MIN(dirtyRectArea->x, dirtyLineArea->x);
+  totalDirtyArea->y = MIN(dirtyRectArea->y, dirtyLineArea->y);
+  totalDirtyArea->x2 = MAX(dirtyRectArea->x2, dirtyLineArea->x2);
+  totalDirtyArea->y2 = MAX(dirtyRectArea->y2, dirtyLineArea->y2);
+}
+
+/**
+* Grows the dirty region of the tile.
+* This allows to log which areas of the mask are used, and only do Composition
+* with the parts that are really occupied.
+*/
+static void growDirtyRegion(MaskRegion *region, jint x, jint y, jint x2, jint y2)
+{
+  if(x < region->x){
+    region->x = x;
+  }
+  if(y < region->y) {
+    region->y = y;
+  }
+  if(x2 > region->x2){ 
+    region->x2 = x2;
+  }
+  if(y2 > region->y2){
+    region->y2 = y2;
+  }
+}
+
+static void growDirtyRegionTileLimit(MaskRegion *region, jint x, jint y, jint x2, jint y2)
+{
+  if(x < region->x){
+    region->x = MAX(x, 0);
+  }
+  if(y < region->y) {
+    region->y = MAX(y, 0);
+  }
+  if(x2 > region->x2){ 
+    region->x2 = MIN(x2, MASK_TILE_SIZE);
+  }
+  if(y2 > region->y2){
+    region->y2 = MIN(y2, MASK_TILE_SIZE);
+  }
+}
+
+/**
+* Limits the rect's coordinates to the mask coordinates.
+* The result is used by growDirtyRegion.
+*/
+static void limitRetcCoords(XRectangle *rect) 
+{
+   if((rect->x + rect->width) > MASK_TILE_SIZE) {
+      rect->width = MASK_TILE_SIZE - rect->x;
+   }
+   if((rect->y + rect->height) > MASK_TILE_SIZE) {
+      rect->height = MASK_TILE_SIZE - rect->y;
+   }
+
+  if(rect->x < 0){
+    rect->width += rect->x;
+    rect->x = 0;
+  }
+  if(rect->y < 0) {
+     rect->height += rect->y;
+     rect->y = 0;
+  }
+}
+
+static void initRegion(MaskRegion *region)
+{
+  region->x = 99999;
+  region->y = 99999;
+  region->x2 = -99999;
+  region->y2 = -99999;
+}
+
+void addRect(MaskBuffer* buf, short x, short y, unsigned short w, unsigned short h)
+{
+  XRectangle *rect = (XRectangle*) getNewXR(&buf->rects, sizeof(XRectangle));
+  rect->x = x;
+  rect->y = y;
+  rect->width = w;
+  rect->height = h;
+
+  growDirtyRegion(&buf->region, x, y, x+w, y+h);
+}
+
+void addLine(MaskBuffer* buf, int x1, int y1, int x2, int y2)
+{
+  /* EXA tries to accalerate lines which can be rendered with a single fillRect.
+   * Unfourtunatly EXA is a bit dumb because our image is held in sysmem all the time anyway.
+   * So although it would be pretty cheap in sysmem, it migrates the mask to vram just to do a single accalerated fillRect.
+   * This should really be fixed in EXA, I hope I get it done sometimes.
+   *
+   * We seperate rect/line rendering to not cause exzessive migration, therefor we simple add that "line" to our rects.
+   */
+
+  int minX, minY, maxX, maxY;
+  GET_DIRTY_LINE_REGION(x1, y1, x2, y2, minX, minY, maxX, maxY); 
+  int xDiff = maxX - minX;
+  int yDiff = maxY - minY;
+
+   if(xDiff == 0 || yDiff == 0)
+   {
+     addRect(buf, minX, minY, maxX - minX + 1, maxY - minY + 1);
+   }else
+   if(xDiff == 1 && yDiff == 1)
+   {
+     addRect(buf, x1, y1, 1, 1);
+     addRect(buf, x2, y2, 1, 1);
+   } else 
+   {
+     XSegment *line = (XSegment*) getNewXR(&buf->lines, sizeof(XSegment));
+     line->x1 = x1;
+     line->y1 = y1;
+     line->x2 = x2;
+     line->y2 = y2;
+ 
+     growDirtyRegion(&buf->region, minX, minY, maxX + 1, maxY + 1);
+  }
+}
+
+static void initXrTile(XrTile *tile)
+{
+  initRegion(&tile->dirtyLineArea);
+  initRegion(&tile->dirtyRectArea);
+  clearXRList(&tile->rects);
+  clearXRList(&tile->lines);
+}
+
+static void storeLinesInTiles(MaskBuffer *buf)
+{
+  int i,n,m;
+
+  for(i=0; i < buf->lines.used; i++) {
+     XSegment *line = ((XSegment*) buf->lines.elements) + i; 
+
+     line->x1 -= buf->region.x;
+     line->y1 -= buf->region.y;
+     line->x2 -= buf->region.x;
+     line->y2 -= buf->region.y;
+
+    int minX, minY, maxX, maxY;
+    GET_DIRTY_LINE_REGION(line->x1, line->y1, line->x2, line->y2, minX, minY, maxX, maxY);
+
+     int tileXStartIndex = minX / MASK_TILE_SIZE;
+     int tileYStartIndex = minY / MASK_TILE_SIZE;
+     int tileXLenght = (maxX / MASK_TILE_SIZE + 1) - tileXStartIndex;
+     int tileYLenght = (maxY / MASK_TILE_SIZE + 1) - tileYStartIndex;
+
+      /*TODO: Better coverage analysis should really pay off for lines!*/
+      for(n=0; n < tileYLenght; n++) {
+        for(m=0; m < tileXLenght; m++) { /*Coverage indicator: Simply do not add to not covered tiles*/
+          int tileIndex = (buf->xTileCap * (tileYStartIndex + n)) + tileXStartIndex + m;
+          assert(tileIndex >= 0 && tileIndex < (buf->xTileCap*buf->yTileCap));
+          XrTile *tile = &buf->tiles[tileIndex];
+          XSegment *tileLine = (XSegment*) getNewXR(&tile->lines, sizeof(XSegment));
+
+          int tileStartPosX = (tileXStartIndex + m) * MASK_TILE_SIZE;
+          int tileStartPosY = (tileYStartIndex + n) * MASK_TILE_SIZE;
+
+          tileLine->x1 = line->x1 - tileStartPosX; //Translate coordinates relative to the mask-location
+          tileLine->y1 = line->y1 - tileStartPosY;
+          tileLine->x2 = line->x2 - tileStartPosX;
+          tileLine->y2 = line->y2 - tileStartPosY; 
+
+          int transminX = minX - tileStartPosX;
+          int transminY = minY - tileStartPosY;
+          int transmaxX = maxX - tileStartPosX;
+          int transmaxY = maxY - tileStartPosY;
+
+          growDirtyRegionTileLimit(&tile->dirtyLineArea, transminX,  transminY, transmaxX + 1, transmaxY + 1);
+       }
+     }
+  }
+}
+
+static void storeRectsInTiles(MaskBuffer *buf)
+{
+  int i,n,m;
+
+  for(i=0; i < buf->rects.used; i++) {
+     XRectangle *rect = ((XRectangle*) buf->rects.elements) + i; 
+
+     rect->x -= buf->region.x;
+     rect->y -= buf->region.y;
+
+     int tileXStartIndex = rect->x / MASK_TILE_SIZE;
+     int tileYStartIndex = rect->y / MASK_TILE_SIZE;
+     int tileXLenght = ((rect->x + rect->width) / MASK_TILE_SIZE + 1) - tileXStartIndex;
+     int tileYLenght = ((rect->y + rect->height) / MASK_TILE_SIZE + 1) - tileYStartIndex;
+
+      for(n=0; n < tileYLenght; n++) {
+        for(m=0; m < tileXLenght; m++) {
+          int tileIndex = (buf->xTileCap * (tileYStartIndex + n)) + tileXStartIndex + m;
+          assert(tileIndex >= 0 && tileIndex < (buf->xTileCap*buf->yTileCap));
+          //printf("Index: %d - tileX:%d, tileY:%d, tilesx:%d, tilesy:%d, capx:%d capy:%d\n",tileIndex,  (m + tileXLenght), (n + tileYStartIndex), buf->xTiles, buf->yTiles, buf->xTileCap, buf->yTileCap);fflush(stdout);
+          XrTile *tile = &buf->tiles[tileIndex];
+          XRectangle *tileRect = (XRectangle*) getNewXR(&tile->rects, sizeof(XRectangle));
+
+          int tileStartPosX = (tileXStartIndex + m) * MASK_TILE_SIZE;
+          int tileStartPosY = (tileYStartIndex + n) * MASK_TILE_SIZE;
+
+          tileRect->x = rect->x - tileStartPosX; //Translate coordinates relative to the mask-location
+          tileRect->y = rect->y - tileStartPosY;
+          tileRect->width = rect->width;
+          tileRect->height = rect->height; 
+
+          limitRetcCoords(tileRect);
+          growDirtyRegion(&tile->dirtyRectArea, tileRect->x, tileRect->y, tileRect->x + tileRect->width, tileRect->y + tileRect->height);
+       }
+     }
+  }
+}
+
+static void translateRects(XrArrayList *rectList, int x, int y)
+{
+  int i;
+  for(i = 0; i < rectList->used; i++) {
+      XRectangle *rect = ((XRectangle *) rectList->elements) + i;
+      rect->x += x;
+      rect->y += y;
+   }
+}
+
+void fillMask(MaskBuffer* buf, Picture dest)
+{
+  XRenderColor color_black={.red=0, .green=0, .blue=0, .alpha=0xffff};
+  int i, m, n;
+
+  jboolean maskRequired = (xrSrcData.src != xrSrcData.solid) || (xrSrcData.solidColor.alpha != 0xffff) || (xrSrcData.extraAlpha != 1.0f);
+  /*Extra Alpha is already storen in solid-colo*/
+  jdouble maskAlpha = (xrSrcData.src == xrSrcData.solid) ? 1.0f : xrSrcData.extraAlpha;
+
+  unsigned short alphaValueFixed = XDoubleToUShort(maskAlpha);
+  XRenderColor maskColor;
+  maskColor.alpha = alphaValueFixed;
+
+  /* If we don't have to use a mask and there are no lines, 
+   * we can draw the rects directly and omit tile partitioning */
+  if(maskRequired || buf->lines.used > 0) {
+  allocTileBuffer(buf);
+  storeRectsInTiles(buf);
+  storeLinesInTiles(buf);
+
+  if(buf->lines.used > 0 && buf->validatedGCAlpha != maskAlpha) {
+     buf->validatedGCAlpha = maskAlpha;
+     XSetForeground(awt_display, buf->drawLineGC, (int) (buf->validatedGCAlpha*255));
+  }
+
+  for(i=0; i < buf->yTiles; i++) {
+   for(m=0; m < buf->xTiles; m++) {
+       XrTile *tile = &buf->tiles[i*buf->xTileCap + m];
+       XrArrayList *rectList = &tile->rects;
+       XrArrayList *lineList = &tile->lines;
+
+       if(rectList->used != 0 || lineList->used != 0) {
+	  MaskRegion tileDirtyArea;
+          getTileDirtyArea(&tile->dirtyRectArea, &tile->dirtyLineArea, &tileDirtyArea);
+
+          int tileStartX = m * MASK_TILE_SIZE;
+          int tileStartY = i * MASK_TILE_SIZE;
+          int x = tileDirtyArea.x + tileStartX + buf->region.x;
+          int y = tileDirtyArea.y + tileStartY + buf->region.y;
+          int width = tileDirtyArea.x2 - tileDirtyArea.x;
+          int height = tileDirtyArea.y2 - tileDirtyArea.y;
+          width = MIN(width, MASK_TILE_SIZE);
+          height = MIN(height, MASK_TILE_SIZE);
+
+	  if(maskRequired || lineList->used  > 0) /*Again, only composite _current_tile_ if required, otherwise just fill rects*/
+          {
+            Picture mask = None;
+            if(lineList->used != 0) {
+              XDrawSegments(awt_display, buf->lineMaskPixmap, buf->drawLineGC, (XSegment *) lineList->elements, lineList->used);
+              mask = buf->lineMaskPicture;
+            }
+
+            if(rectList->used != 0) {
+               XRenderComposite (awt_display, PictOpSrc, buf->lineMaskPicture, None, buf->maskPicture, tile->dirtyLineArea.x, tile->dirtyLineArea.y, 0, 0, tile->dirtyLineArea.x, tile->dirtyLineArea.y, (tile->dirtyLineArea.x2 - tile->dirtyLineArea.x), (tile->dirtyLineArea.y2 - tile->dirtyLineArea.y)); 
+               XRenderFillRectangles (awt_display, PictOpSrc, buf->maskPicture, &maskColor, (XRectangle*) rectList->elements, rectList->used);
+               mask = buf->maskPicture;
+               clearXRList(rectList);
+            }
+
+             XRComposite(mask, dest, x, y, tileDirtyArea.x, tileDirtyArea.y, x, y, width, height);
+
+             /*Clear dirty rectangle of the rect-mask*/
+             XRenderFillRectangle (awt_display, PictOpClear, buf->maskPicture, &color_black, tileDirtyArea.x, tileDirtyArea.y, width, height);
+
+             if(lineList->used != 0) {
+               XDrawSegments(awt_display, buf->lineMaskPixmap, buf->clearLineGC, (XSegment *) lineList->elements, lineList->used);
+               clearXRList(lineList);
+	     }
+          }else
+          if(rectList->used != 0)
+          {
+             translateRects(rectList, (tileStartX + buf->region.x), (tileStartY + buf->region.y));
+             XRenderFillRectangles (awt_display, xrSrcData.compRule, dest, &xrSrcData.solidColor, (XRectangle*) rectList->elements, rectList->used);
+             clearXRList(rectList);
+          }
+        }
+      }
+     }
+ } else 
+ {
+   XRenderFillRectangles (awt_display, xrSrcData.compRule, dest, &xrSrcData.solidColor, (XRectangle*) buf->rects.elements, buf->rects.used);
+ }
+
+  cleanMaskBuffer(buf);
+}
+
+#endif
+
+
+	   /*printf("Composition: x:%d y:%d width:%d height:%d, dx:%d, dy:%d\n", x, y, width, height, tileDirtyArea.x, tileDirtyArea.y);
+           XRenderFillRectangle (awt_display, PictOpSrc, buf->maskPicture, &color_black, 0, 0, MASK_TILE_SIZE, 1);
+           XRenderFillRectangle (awt_display, PictOpSrc, buf->maskPicture, &color_black, 0, MASK_TILE_SIZE-1, MASK_TILE_SIZE, 1);
+           XRenderFillRectangle (awt_display, PictOpSrc, buf->maskPicture, &color_black, 0, 0, 1, MASK_TILE_SIZE);
+           XRenderFillRectangle (awt_display, PictOpSrc, buf->maskPicture, &color_black, MASK_TILE_SIZE-1, 0, 1, MASK_TILE_SIZE);*/
+
+
+
+           /* if(xrSrcData.src == xrSrcData.gradient)
+             { 
+               XRenderComposite (awt_display, PictOpSrc, xrSrcData.gradient, None, buf->gradPict, x, y, 0, 0, 0, 0, width, height);
+               XRenderComposite (awt_display, xrSrcData.compRule, buf->gradPict, mask, dest, 0, 0, tileDirtyArea.x, tileDirtyArea.y, x, y, width, height);
+             }else 
+             {
+               XRenderComposite (awt_display, xrSrcData.compRule, xrSrcData.src, mask, dest, x, y, tileDirtyArea.x, tileDirtyArea.y, x, y, width, height);
+             }*/
+
+/*
+void addTrap(MaskBuffer* buf, XTrapezoid *xt)
+{
+  XTrapezoid *trap = (XTrapezoid*) getNewXR(&buf->traps, sizeof(XTrapezoid));
+  memcpy(trap, xt, sizeof(XTrapezoid));
+
+  int leftMin = XFixedToDouble(MIN(trap->left.p1.x, trap->left.p2.x)) - 1;
+  int rightMax = XFixedToDouble(MAX(trap->right.p2.x, trap->right.p1.x)) + 1;
+  int top = XFixedToDouble(trap->top) - 1;
+  int bottom = XFixedToDouble(trap->bottom) + 1;
+
+  growDirtyRegion(&buf->region, leftMin, top, rightMax, bottom);
+}
+*/
+
+/*void translateTrap(XTrapezoid *trap, int x, int y)
+{
+   XFixed xTrans = XDoubleToFixed(x);     
+   XFixed yTrans = XDoubleToFixed(y);
+
+   trap->left.p1.x  += xTrans;
+   trap->left.p2.x  += xTrans;
+   trap->right.p1.x += xTrans;    
+   trap->right.p2.x += xTrans;
+   trap->left.p1.y  += yTrans;
+   trap->left.p2.y  += yTrans;
+   trap->right.p1.y += yTrans;
+   trap->right.p2.y += yTrans;
+   trap->top += yTrans;
+   trap->bottom += yTrans;
+}*/
+
+/*
+void storeTrapsInTiles(MaskBuffer *buf)
+{
+  int i,n,m;
+
+  for(i=0; i < buf->traps.used; i++) {
+     XTrapezoid *trap = ((XTrapezoid*) buf->traps.elements) + i;
+     translateTrap(trap, -buf->region.x, -buf->region.y);
+
+     int leftMin = XFixedToDouble(MIN(trap->left.p1.x, trap->left.p2.x));
+     int rightMax = XFixedToDouble(MAX(trap->right.p2.x, trap->right.p1.x));
+     int top = XFixedToDouble(trap->top) - 1;
+     int bottom = XFixedToDouble(trap->bottom) + 1;
+
+     int tileXStartIndex = leftMin / MASK_TILE_SIZE;
+     int tileYStartIndex = top / MASK_TILE_SIZE;
+     int tileXLenght = ((rightMax / MASK_TILE_SIZE) + 1) - tileXStartIndex;
+     int tileYLenght = ((bottom / MASK_TILE_SIZE) + 1) - tileYStartIndex;
+
+      for(n=0; n < tileYLenght; n++) {
+        for(m=0; m < tileXLenght; m++) {
+          int tileIndex = (buf->xTileCap * (tileYStartIndex + n)) + tileXStartIndex + m;
+          assert(tileIndex >= 0);
+          XrTile *tile = &buf->tiles[tileIndex];
+
+          XTrapezoid *tileTrap = (XTrapezoid*) getNewXR(&tile->traps, sizeof(XTrapezoid));
+          memcpy(tileTrap, trap, sizeof(XTrapezoid));
+
+          int tileStartPosX = (tileXStartIndex + m) * MASK_TILE_SIZE;
+          int tileStartPosY = (tileYStartIndex + n) * MASK_TILE_SIZE;
+          translateTrap(tileTrap, -tileStartPosX, -tileStartPosY);
+
+          leftMin = XFixedToDouble(MIN(tileTrap->left.p1.x, tileTrap->left.p2.x)) - 1;
+          rightMax = XFixedToDouble(MAX(tileTrap->right.p2.x, tileTrap->right.p1.x)) + 1;
+          top = XFixedToDouble(tileTrap->top) - 1;
+          bottom = XFixedToDouble(tileTrap->bottom) + 1;
+
+         // limitRetcCoords(tileRect);
+          //TODO: Better dirty array handling
+          growDirtyRegionTileLimit(&tile->dirtyArea, leftMin, top, rightMax, bottom);
+        }
+      }
+  }
+}*/
+
+//   XrArrayList tileRectList;
+//   initXRList(&tileRectList, sizeof(XRectangle), 64); //Todo memory leak!
+// 
+//   int i, tileStartX, tileStartY;
+//   MaskRegion ditryRegion;
+// 
+//   for(tileStartX = buf->region.x; tileStartX <= buf->region.x2; tileStartX += MASK_TILE_SIZE) {
+//    int tileEndX = tileStartX + MASK_TILE_SIZE;
+// 
+//     for(tileStartY = buf->region.y; tileStartY <= buf->region.y2; tileStartY += MASK_TILE_SIZE) {
+//       int tileEndY = tileStartY + MASK_TILE_SIZE;
+//       initRegion(&ditryRegion);
+// 
+//       for(i=0; i < buf->rects.used; i++) {
+//         XRectangle *rect = ((XRectangle*) buf->rects.elements) + i;
+// 
+//         if((rect->x <= tileEndX) && ((rect->x + rect->width) > tileStartX) &&
+//            (rect->y <= tileEndY) && ((rect->y + rect->height) > tileStartY)) {
+// 	  XRectangle *ptr = (XRectangle *) getNewXR(&tileRectList);
+//           ptr->x = rect->x - tileStartX; /*Translate coordinates relative to the mask-location*/
+//           ptr->y = rect->y - tileStartY;
+//           ptr->width = rect->width;
+//           ptr->height = rect->height;
+// 
+//           limitRetcCoords(ptr);
+//           growDirtyRegion(&ditryRegion, ptr->x, ptr->y, ptr->x + ptr->width, ptr->y + ptr->height);
+//         }
+//       }
+// 
+//         if(tileRectList.used > 0) { 
+//            XRenderFillRectangles (display, PictOpSrc, mask, alphaColor, (XRectangle*) tileRectList.elements, tileRectList.used);
+//            clearXRList(&tileRectList);
+// 
+//            int x = ditryRegion.x + tileStartX;
+//            int y = ditryRegion.y + tileStartY;
+//            int width = ditryRegion.x2 - ditryRegion.x;
+//            int height = ditryRegion.y2 - ditryRegion.y;
+// 
+//            XRenderComposite (display, PictOpOver, src, mask, dest, x, y, ditryRegion.x, ditryRegion.y, x, y, width, height);
+//            XRenderFillRectangle (display, PictOpClear, mask, alphaColor, ditryRegion.x, ditryRegion.y, width, height);
+//         }
+//     } 
+//   }
+
+
+/*
+          XRenderFillRectangle (display, PictOpSrc, mask, &color_black, 0, 0, MASK_TILE_SIZE, 1);
+          XRenderFillRectangle (display, PictOpSrc, mask, &color_black, 0, MASK_TILE_SIZE-1, MASK_TILE_SIZE, 1);
+          XRenderFillRectangle (display, PictOpSrc, mask, &color_black, 0, 0, 1, MASK_TILE_SIZE);
+          XRenderFillRectangle (display, PictOpSrc, mask, &color_black, MASK_TILE_SIZE-1, 0, 1, MASK_TILE_SIZE);
+*/
+
+//         int z;
+//         for(z=0; z < tileRectList.used; z++)
+//  {
+//      XRectangle *rect = ((XRectangle*) tileRectList.elements) + z;
+//      printf("Rechteck %d - %d %d %d %d %d\n", z, rect->x, rect->y, rect->width, rect->height, tileRectList.used);
+// }
+
+//printf("Composition rect: %d %d %d %d\n", x, y, ditryRegion.x2 - ditryRegion.x, ditryRegion.y2 - ditryRegion.y);fflush(stdout);
+          //XRenderFillRectangle (display, PictOpSrc, mask, &color_black, 0, 0, MASK_TILE_SIZE, 1);
+          //XRenderFillRectangle (display, PictOpSrc, mask, &color_black, 0, MASK_TILE_SIZE-1, MASK_TILE_SIZE, 1);
+          //XRenderFillRectangle (display, PictOpSrc, mask, &color_black, 0, 0, 1, MASK_TILE_SIZE);
+          //XRenderFillRectangle (display, PictOpSrc, mask, &color_black, MASK_TILE_SIZE-1, 0, 1, MASK_TILE_SIZE);
+
+// printf("Rendering region: %d %d %d %d\n", buf->region.x, buf->region.y, buf->region.x2 - buf->region.x, buf->region.y2 - buf->region.y);fflush(stdout);
diff -Nru openjdk.orig/jdk/src/solaris/native/sun/java2d/x11/MaskBuffer.h openjdk/jdk/src/solaris/native/sun/java2d/x11/MaskBuffer.h
--- openjdk.orig/jdk/src/solaris/native/sun/java2d/x11/MaskBuffer.h	1970-01-01 01:00:00.000000000 +0100
+++ openjdk/jdk/src/solaris/native/sun/java2d/x11/MaskBuffer.h	2009-05-13 01:02:29.000000000 +0100
@@ -0,0 +1,80 @@
+#ifndef MaskBuffer_h_Included
+#define MaskBuffer_h_Included
+
+#include "jni.h"
+#include <X11/Xlib.h>
+#include "ArrayList.h"
+#include "ArrayList.h"
+#include <malloc.h>
+#include <string.h>
+#include <X11/extensions/Xrender.h>
+#include <assert.h>
+
+#define MASK_TILE_SIZE 256
+
+typedef struct {
+  jint x;
+  jint y;
+  jint x2;
+  jint y2;
+}MaskRegion;
+
+typedef struct {
+  XrArrayList rects;
+  XrArrayList lines;
+
+  MaskRegion dirtyRectArea;
+  MaskRegion dirtyLineArea;
+} XrTile;
+
+typedef struct {
+  Pixmap lineMaskPixmap;
+  Picture lineMaskPicture;
+  GC drawLineGC;
+  GC clearLineGC;
+
+  Pixmap maskPixmap;
+  Picture maskPicture;
+  jfloat validatedGCAlpha;
+
+  XrArrayList rects;
+  XrArrayList lines;
+  MaskRegion region;
+
+  int xTiles;
+  int yTiles;
+  int xTileCap;
+  int yTileCap;
+  XrTile *tiles;
+
+  Pixmap gradPixmap;
+  Picture gradPict;
+}MaskBuffer;
+
+MaskBuffer* initMaskBuffer(Window window);
+
+void addRect(MaskBuffer* buf, short x, short y, unsigned short w, unsigned short h);
+
+void addLine(MaskBuffer* buf, int x1, int y1, int x2, int y2);
+
+void fillMask(MaskBuffer* buf, Picture dest);
+
+static void storeRectsInTiles(MaskBuffer *buf);
+
+static void cleanMaskBuffer(MaskBuffer *buf);
+
+static void limitRetcCoords(XRectangle *rect);
+
+static void initRegion(MaskRegion *region);
+
+static void growDirtyRegion(MaskRegion *region, jint x, jint y, jint x2, jint y2);
+
+static void growDirtyRegionTileLimit(MaskRegion *region, jint x, jint y, jint x2, jint y2);
+
+static void initXrTile(XrTile *tile);
+
+static void getTileDirtyArea(MaskRegion *dirtyRectArea, MaskRegion *dirtyLineArea, MaskRegion *totalDirtyArea);
+
+static void translateRects(XrArrayList *rectList, int x, int y);
+
+#endif /* MaskBuffer_h_Included */
diff -Nru openjdk.orig/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.c openjdk/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.c
--- openjdk.orig/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.c	2009-03-30 17:23:08.000000000 +0100
+++ openjdk/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.c	2009-05-13 01:02:29.000000000 +0100
@@ -71,7 +71,7 @@
 extern AwtGraphicsConfigDataPtr
     getGraphicsConfigFromComponentPeer(JNIEnv *env, jobject this);
 extern struct X11GraphicsConfigIDs x11GraphicsConfigIDs;
-static jint X11SD_InitWindow(JNIEnv *env, X11SDOps *xsdo);
+
 static int X11SD_FindClip(SurfaceDataBounds *b, SurfaceDataBounds *bounds,
                           X11SDOps *xsdo);
 static int X11SD_ClipToRoot(SurfaceDataBounds *b, SurfaceDataBounds *bounds,
@@ -97,19 +97,10 @@
 
 #endif /* !HEADLESS */
 
-/*
- * Class:     sun_java2d_x11_X11SurfaceData
- * Method:    initIDs
- * Signature: (Ljava/lang/Class;Z)V
- */
-JNIEXPORT void JNICALL
-Java_sun_java2d_x11_X11SurfaceData_initIDs(JNIEnv *env, jclass xsd,
-                                           jclass XORComp, jboolean tryDGA)
+jboolean XShared_initIDs(JNIEnv *env)
 {
 #ifndef HEADLESS
-    void *lib = 0;
-
-    union {
+   union {
         char c[4];
         int i;
     } endian;
@@ -117,20 +108,59 @@
     endian.i = 0xff000000;
     nativeByteOrder = (endian.c[0]) ? MSBFirst : LSBFirst;
 
+    dgaAvailable = JNI_FALSE;
+
     cachedXImage = NULL;
 
     if (sizeof(X11RIPrivate) > SD_RASINFO_PRIVATE_SIZE) {
         JNU_ThrowInternalError(env, "Private RasInfo structure too large!");
-        return;
+        return JNI_FALSE;
+    }
+
+#ifdef MITSHM
+    if (getenv("NO_AWT_MITSHM") == NULL &&
+        getenv("NO_J2D_MITSHM") == NULL) {
+        char * force;
+        TryInitMITShm(env, &useMitShmExt, &useMitShmPixmaps);
+        useMitShmPixmaps = (useMitShmPixmaps == CAN_USE_MITSHM);
+        force = getenv("J2D_PIXMAPS");
+        if (force != NULL) {
+            if (useMitShmPixmaps && (strcmp(force, "shared") == 0)) {
+                forceSharedPixmaps = JNI_TRUE;
+            } else if (strcmp(force, "server") == 0) {
+                useMitShmPixmaps = JNI_FALSE;
+            }
+        }
     }
 
+    return JNI_TRUE;
+#endif /* MITSHM */
+
+#endif /* !HEADLESS */
+}
+
+
+/*
+ * Class:     sun_java2d_x11_X11SurfaceData
+ * Method:    initIDs
+ * Signature: (Ljava/lang/Class;Z)V
+ */
+JNIEXPORT void JNICALL
+Java_sun_java2d_x11_X11SurfaceData_initIDs(JNIEnv *env, jclass xsd,
+                                           jclass XORComp, jboolean tryDGA)
+{
+#ifndef HEADLESS
+  if(XShared_initIDs(env))
+  {
+    void *lib = 0;
+
     xorCompClass = (*env)->NewGlobalRef(env, XORComp);
 
     if (tryDGA && (getenv("NO_J2D_DGA") == NULL)) {
     /* we use RTLD_NOW because of bug 4032715 */
         lib = dlopen("libsunwjdga.so", RTLD_NOW);
     }
-    dgaAvailable = JNI_FALSE;
+
     if (lib != NULL) {
         JDgaStatus ret = JDGA_FAILED;
         void *sym = dlsym(lib, "JDgaLibInit");
@@ -149,24 +179,7 @@
             lib = NULL;
         }
     }
-
-#ifdef MITSHM
-    if (getenv("NO_AWT_MITSHM") == NULL &&
-        getenv("NO_J2D_MITSHM") == NULL) {
-        char * force;
-        TryInitMITShm(env, &useMitShmExt, &useMitShmPixmaps);
-        useMitShmPixmaps = (useMitShmPixmaps == CAN_USE_MITSHM);
-        force = getenv("J2D_PIXMAPS");
-        if (force != NULL) {
-            if (useMitShmPixmaps && (strcmp(force, "shared") == 0)) {
-                forceSharedPixmaps = JNI_TRUE;
-            } else if (strcmp(force, "server") == 0) {
-                useMitShmPixmaps = JNI_FALSE;
-            }
-        }
-    }
-#endif /* MITSHM */
-
+  }
 #endif /* !HEADLESS */
 }
 
@@ -304,6 +317,8 @@
     } else {
         xsdo->pixelmask = 0xff;
     }
+
+    xsdo->xrPic = None;
 #endif /* !HEADLESS */
 }
 
@@ -384,6 +399,10 @@
         XFreeGC(awt_display, xsdo->cachedGC);
         xsdo->cachedGC = NULL;
     }
+    if(xsdo->xrPic != None) {
+      XRenderFreePicture(awt_display, xsdo->xrPic);
+    }
+
     AWT_UNLOCK();
 #endif /* !HEADLESS */
 }
@@ -404,29 +423,10 @@
 #endif /* !HEADLESS */
 }
 
-/*
- * Class:     sun_java2d_x11_X11SurfaceData
- * Method:    initSurface
- * Signature: ()V
- */
-JNIEXPORT void JNICALL
-Java_sun_java2d_x11_X11SurfaceData_initSurface(JNIEnv *env, jclass xsd,
-                                               jint depth,
-                                               jint width, jint height,
-                                               jlong drawable)
+
+jboolean XShared_initSurface(JNIEnv *env, X11SDOps *xsdo, jint depth, jint width, jint height, jlong drawable)
 {
 #ifndef HEADLESS
-    X11SDOps *xsdo = X11SurfaceData_GetOps(env, xsd);
-    if (xsdo == NULL) {
-        return;
-    }
-
-    if (xsdo->configData->awt_cmap == (Colormap)NULL) {
-        awtJNI_CreateColorData(env, xsdo->configData, 1);
-    }
-    /* color_data will be initialized in awtJNI_CreateColorData for
-       8-bit visuals */
-    xsdo->cData = xsdo->configData->color_data;
 
     if (drawable != (jlong)0) {
         /* Double-buffering */
@@ -452,7 +452,7 @@
             if (xsdo->drawable) {
                 xsdo->shmPMData.usingShmPixmap = JNI_TRUE;
                 xsdo->shmPMData.shmPixmap = xsdo->drawable;
-                return;
+                return JNI_TRUE;
             }
         }
 #endif /* MITSHM */
@@ -472,7 +472,40 @@
     if (xsdo->drawable == 0) {
         JNU_ThrowOutOfMemoryError(env,
                                   "Can't create offscreen surface");
+        return JNI_FALSE;
     }
+
+    return JNI_TRUE;
+#endif /* !HEADLESS */
+}
+
+
+/*
+ * Class:     sun_java2d_x11_X11SurfaceData
+ * Method:    initSurface
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_sun_java2d_x11_X11SurfaceData_initSurface(JNIEnv *env, jclass xsd,
+                                               jint depth,
+                                               jint width, jint height,
+                                               jlong drawable)
+{
+#ifndef HEADLESS
+    X11SDOps *xsdo = X11SurfaceData_GetOps(env, xsd);
+    if (xsdo == NULL) {
+        return;
+    }
+
+    if (xsdo->configData->awt_cmap == (Colormap)NULL) {
+        awtJNI_CreateColorData(env, xsdo->configData, 1);
+    }
+    /* color_data will be initialized in awtJNI_CreateColorData for
+       8-bit visuals */
+    xsdo->cData = xsdo->configData->color_data;
+
+    XShared_initSurface(env, xsdo, depth, width, height, drawable);
+    xsdo->xrPic = NULL;
 #endif /* !HEADLESS */
 }
 
@@ -718,7 +751,7 @@
 }
 #endif /* MITSHM */
 
-static jint X11SD_InitWindow(JNIEnv *env, X11SDOps *xsdo)
+jint X11SD_InitWindow(JNIEnv *env, X11SDOps *xsdo)
 {
     if (xsdo->isPixmap == JNI_TRUE) {
         return SD_FAILURE;
diff -Nru openjdk.orig/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.h openjdk/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.h
--- openjdk.orig/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.h	2009-03-30 17:23:08.000000000 +0100
+++ openjdk/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.h	2009-05-13 01:02:29.000000000 +0100
@@ -30,6 +30,10 @@
 
 #include <jdga.h>
 
+#include <X11/extensions/Xrender.h>
+#include "MaskBuffer.h"
+#include "XRSurfaceData.h"
+
 /**
  * This include file contains support declarations for loops using the
  * X11 extended SurfaceData interface to talk to an X11 drawable from
@@ -87,6 +91,7 @@
 } ShmPixmapData;
 #endif /* MITSHM */
 
+
 struct _X11SDOps {
     SurfaceDataOps      sdOps;
     GetPixmapBgFunc     *GetPixmapWithBg;
@@ -110,6 +115,7 @@
     jboolean            isBgInitialized; /* whether the bg pixel is valid */
     jint                pmWidth;       /* width, height of the */
     jint                pmHeight;      /* pixmap */
+    Picture             xrPic;
 #ifdef MITSHM
     ShmPixmapData       shmPMData;     /* data for switching between shm/nonshm pixmaps*/
 #endif /* MITSHM */
@@ -156,3 +162,21 @@
  */
 JNIEXPORT X11SDOps * JNICALL
 X11SurfaceData_GetOps(JNIEnv *env, jobject sData);
+
+/*Prototypes for shared functions used by XRSurfaceData*/
+jboolean XShared_initSurface(JNIEnv *env, X11SDOps *xsdo, jint depth, jint width, jint height, jlong drawable);
+
+jboolean XShared_initIDs(JNIEnv *env);
+
+JNIEXPORT void JNICALL
+Java_sun_java2d_x11_X11SurfaceData_initOps(JNIEnv *env, jobject xsd,
+                                           jobject peer,
+                                           jobject graphicsConfig, jint depth);
+
+JNIEXPORT jlong JNICALL Java_sun_java2d_x11_X11SurfaceData_XCreateGC (JNIEnv *env, jclass xsd, jlong pXSData);
+
+jint X11SD_InitWindow(JNIEnv *env, X11SDOps *xsdo);
+
+JNIEXPORT void JNICALL
+Java_sun_java2d_x11_X11SurfaceData_flushNativeSurface(JNIEnv *env, jobject xsd);
+
diff -Nru openjdk.orig/jdk/src/solaris/native/sun/java2d/x11/XRGlyphCache.c openjdk/jdk/src/solaris/native/sun/java2d/x11/XRGlyphCache.c
--- openjdk.orig/jdk/src/solaris/native/sun/java2d/x11/XRGlyphCache.c	1970-01-01 01:00:00.000000000 +0100
+++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRGlyphCache.c	2009-05-13 01:02:29.000000000 +0100
@@ -0,0 +1,313 @@
+#include <malloc.h>
+#include "jni.h"
+#include "XRGlyphCache.h"
+#include "ArrayList.h"
+#include "Trace.h"
+#include <X11/extensions/Xrender.h>
+
+#define DEFAULT_CACHE_SIZE 1024
+#define CACHED_PIXELS 100000
+#define TIMES_RENDERED_THRESHOLD 5
+
+#ifndef HEADLESS
+XRGlyphCacheInfo* XRGlyphCache_Init(XRenderPictFormat* glyphSetPictFormat)
+{
+    XRGlyphCacheInfo *cache;
+    J2dTraceLn(J2D_TRACE_INFO, "XRGlyphCache_Init");
+
+    cache = (XRGlyphCacheInfo *) malloc(sizeof(XRGlyphCacheInfo));
+    if (cache == NULL) {
+        J2dRlsTraceLn(J2D_TRACE_ERROR, "XRGlyphCache_Init: could not allocate GlyphCacheInfo");
+        return NULL;
+    }
+
+    cache->cells = (XRCacheCellInfo *) calloc(DEFAULT_CACHE_SIZE, sizeof(XRCacheCellInfo));
+    if(cache->cells == NULL) {
+        J2dRlsTraceLn(J2D_TRACE_ERROR, "XRGlyphCache_Init: could not allocate cell space");
+        return NULL;
+    }
+
+    cache->glyphSet = XRenderCreateGlyphSet (awt_display, glyphSetPictFormat);
+    cache->cellCapacity = DEFAULT_CACHE_SIZE;
+    cache->usedCells = 0;
+    cache->searchPosition = 0;
+    cache->pixelsUsed = 0;
+
+    return cache;
+}
+
+static jboolean cleanCache(XRGlyphCacheInfo *cache)
+{
+  J2dTraceLn(J2D_TRACE_INFO, "XRGlyphCache_cleanCache");
+
+  jint i;
+
+  /*First set cold cache entries free*/
+  for(i=0; i < cache->cellCapacity; i++) {
+    XRCacheCellInfo *cacheCell = &cache->cells[i];
+    if(cacheCell->pinned == JNI_FALSE) {
+      if(cacheCell->glyphID != 0 && cacheCell->timesRendered < TIMES_RENDERED_THRESHOLD) {
+        J2dTraceLn1(J2D_TRACE_INFO, "Removing glyph from cache. ID:", cacheCell->glyphID);
+        XRenderFreeGlyphs (awt_display, cache->glyphSet, (Glyph *) &cacheCell->glyphID, 1);
+        cacheCell->glyphID = 0;
+        cache->pixelsUsed -= (cacheCell->width * cacheCell->height);
+        cache->usedCells--;
+
+        if(cacheCell->glyphInfo != NULL) {
+	   cacheCell->glyphInfo->cellInfo = NULL;
+	}	
+      }
+    }
+     cacheCell->timesRendered = 0;
+  }
+
+  cache->searchPosition = 0;
+   
+  /*If more than 70% are occupied, we enlarge our cache-size by 1.5*/
+  jint oldCapacity = cache->cellCapacity;
+  XRCacheCellInfo *oldCache = cache->cells;
+  jfloat relUsed = ((jfloat) cache->usedCells) / cache->cellCapacity;
+  if(relUsed > 0.7)
+  {
+     cache->cellCapacity = (jint) cache->cellCapacity*1.5;
+     J2dTraceLn1(J2D_TRACE_INFO, "Extensing glyph-cache capacity to", cache->cellCapacity);
+     
+     cache->cells = (XRCacheCellInfo *) realloc(cache->cells, sizeof(XRCacheCellInfo) * (cache->cellCapacity));
+     if(cache->cells == NULL) {
+        J2dRlsTraceLn(J2D_TRACE_ERROR, "XRGlyphCache_cleanCache: Could not enlarge cell space");
+        return JNI_FALSE;
+      }
+     memset(&cache->cells[oldCapacity], 0, sizeof(XRCacheCellInfo) * (cache->cellCapacity - oldCapacity));
+
+   //If realloc gave us a different location, update pointers in GlyphInfo
+   if(oldCache != cache->cells) {
+       int cnt;
+       for(cnt = 0; cnt < oldCapacity; cnt++) {
+           XRCacheCellInfo *cacheCell = &cache->cells[cnt];
+           if(cacheCell->glyphID != 0 && cacheCell->glyphInfo != NULL) {
+              cacheCell->glyphInfo->cellInfo = cacheCell; /*TODO: we currently mis-use the pointer for our own type*/
+           }
+        }
+    }
+  } 
+
+  return JNI_TRUE;
+}
+
+static jboolean uploadGlyph(XRGlyphCacheInfo *cache, GlyphInfo *jginfo, XRCacheCellInfo *cacheCell)
+{
+     J2dTraceLn(J2D_TRACE_INFO, "XRGlyphCache_uploadGlyph");
+
+     unsigned char* glyphBuf = (unsigned char*) jginfo->image; 
+     jboolean grayscale = (jginfo->rowBytes == jginfo->width);
+     jint dstBytesPerPixel = grayscale ? 1 : 4;
+     jint srcBytesPerPixel = grayscale ? 1 : 3;
+     jint dstStrideWidth = dstBytesPerPixel * jginfo->width;
+     jint srcStrideWidth = srcBytesPerPixel * jginfo->width;
+     jint bufLen = dstStrideWidth * jginfo->height;
+     jint width = jginfo->width, height = jginfo->height;
+     jboolean bufferAllocated = JNI_FALSE;
+
+        if(jginfo->image != NULL) {
+          if(grayscale == JNI_TRUE) {
+
+                 /*XRender expects glyph images to be padded to 4-byte boundaries*/
+                 if(jginfo->width%4 != 0 || jginfo->image == NULL) { 
+                 int pad = 4 - (jginfo->width % 4);
+	         dstBytesPerPixel = jginfo->width + pad;
+                 bufLen =  dstBytesPerPixel * jginfo->height;
+                 glyphBuf = calloc(1, bufLen);
+                 bufferAllocated = JNI_TRUE;
+
+                 if(jginfo->image != NULL)  {
+	           int line, pix;
+	           for(line = 0; line < jginfo->height; line++) {
+		     for(pix = 0; pix < jginfo->width; pix++) {
+		        glyphBuf[line*jginfo->width + pad*line + pix] = jginfo->image[line*jginfo->width + pix];
+		     }
+	           }	
+                 }
+             }
+
+          }else {
+            bufLen =  dstStrideWidth * height;
+            glyphBuf = calloc(1, bufLen);
+            bufferAllocated = JNI_TRUE;
+
+	    int line, srcpix, dstpix;
+	    for(line = 0; line < height; line++) {
+		srcpix = 0;
+		dstpix = 0;
+		while(dstpix < dstStrideWidth) {
+             /*B*/glyphBuf[line*dstStrideWidth + dstpix + 0] = /*B*/jginfo->image[(line*jginfo->rowBytes + srcpix + 2)];
+             /*G*/glyphBuf[line*dstStrideWidth + dstpix + 1] = /*G*/jginfo->image[(line*jginfo->rowBytes + srcpix + 1)];
+             /*R*/glyphBuf[line*dstStrideWidth + dstpix + 2] = /*R*/jginfo->image[(line*jginfo->rowBytes + srcpix + 0)];
+             /*A*/glyphBuf[line*dstStrideWidth + dstpix + 3] = 255;		
+                  srcpix += 3;
+                  dstpix += 4;
+		}
+	    }
+	 }
+      }else {
+         bufLen = 4; //Work arround for bug in older servers
+	 glyphBuf = calloc(1, bufLen);
+         bufferAllocated = JNI_TRUE;
+	 width = 1;
+	 height = 1;
+      }
+     
+
+     Glyph gid = (Glyph) cacheCell->glyphID;
+     XGlyphInfo xginfo={.x=(jginfo->topLeftX*-1),.y=(jginfo->topLeftY*-1),.width=width,.height=height, .xOff = cacheCell->xOff,.yOff = cacheCell->yOff};
+
+     XRenderAddGlyphs(awt_display, cache->glyphSet, &gid, &xginfo, 1, glyphBuf, bufLen);
+     
+     if(bufferAllocated == JNI_TRUE) {
+       free(glyphBuf);
+     }
+
+     return JNI_TRUE;
+}
+
+jboolean XRGlyphCache_CacheGlyphs(XRGlyphCacheInfo *cache, jlong *glyphPtrs, jint glyphCount, jint *ids)
+{ 
+   jint glyphsStored = 0;
+   
+   do {
+    /**
+     * Search for free cache-cells to store glyphs which have not been cached already.
+     * The outer loop iterates over all cache-zells, as long as either all have been walked over or all glyphs are stored.
+     * The inner loop loops over all non-processed glyphs (if the current zell is free), 
+     * and stores it in the free cache-zell if not already cached, and pins it.
+     * If the outer-loop finishes before all glyphs are cached, not enough free zells were available and a cache-cleanup is triggered.
+     */
+      while((cache->searchPosition < cache->cellCapacity) && (glyphsStored < glyphCount)) {
+       XRCacheCellInfo *cacheCell = &cache->cells[cache->searchPosition];
+       
+       while(glyphsStored < glyphCount) {  //loop over unprocessed glyphs
+	 GlyphInfo *currGlyph = (GlyphInfo *)jlong_to_ptr(glyphPtrs[glyphsStored]);// &glyphs[glyphsStored];
+
+         if(currGlyph->cellInfo == NULL) { //If the current glyph is not cached, add it to cache if current cacheZell is a free one
+           //Evaluate not in loop-head, otherwise we would have to iterate until a free cell
+           //even if all glyphs are already cached (common case)
+           if(cacheCell->glyphID != 0)
+           {
+             cache->searchPosition++;
+             break;
+           }
+
+           currGlyph->cellInfo = cacheCell;
+           cacheCell->glyphInfo = currGlyph;
+           cacheCell->glyphID = (unsigned short) cache->searchPosition + 1;
+           cacheCell->xOff = round(currGlyph->advanceX);
+	   cacheCell->yOff = round(currGlyph->advanceY);
+           cacheCell->width = currGlyph->width;
+           cacheCell->height = currGlyph->height;
+
+           jboolean uploadError = uploadGlyph(cache, currGlyph, cacheCell);
+           if(uploadError == JNI_FALSE) {
+             return JNI_FALSE;
+           }
+
+           cache->pixelsUsed += (currGlyph->width * currGlyph->height);
+           cache->usedCells++;
+         }
+
+	  //Work that has to be done independently wether the cell was cached or not
+          XRCacheCellInfo *usedCell = (XRCacheCellInfo *) currGlyph->cellInfo;
+          usedCell->pinned = JNI_TRUE;
+          usedCell->timesRendered++;
+          glyphsStored++;
+        }
+     }
+       
+     //TODO: If we were not able to store all uncached glyphs we free the cache and try again
+     if(glyphsStored < glyphCount || cache->pixelsUsed > CACHED_PIXELS) { 
+       J2dTraceLn(J2D_TRACE_INFO, "XRGlyphCache: Glyph-cache too small, cleanup triggered");
+       if(cleanCache(cache) == JNI_FALSE) {
+	  return JNI_FALSE;
+       }
+     }
+   }while(glyphsStored < glyphCount);
+ 
+   /* Remove pin-property from the cache-entries,
+    * pass IDs to the caller                     */
+   int i;
+   for(i=0; i < glyphCount; i++) {
+     XRCacheCellInfo *cell = (XRCacheCellInfo*) (((GlyphInfo *)jlong_to_ptr(glyphPtrs[i]))->cellInfo);
+     cell->pinned = JNI_FALSE;
+     ids[i] = cell->glyphID;
+   }
+
+   return JNI_TRUE;
+}
+
+#if 0
+void dumpCache(XRGlyphCacheInfo *cache)
+{
+  int i;
+  for(i=0; i < cache->cellCapacity; i++)
+  {
+    XRCacheCellInfo *cell = &cache->cells[i];
+    if(cell->glyphID != 0)
+    {
+      printf("Cache-Position: %d enthaelt glyph: %d mit counter:%d\n", i, cell->glyphID, cell->timesRendered);
+      fflush(stdout);
+    }
+  }
+}
+#endif
+
+#endif /*!Headless*/
+
+
+// 	  int line_, pix_;
+// 	  for(line_ = 0; line_ < jginfo->height; line_++)
+// 	  {
+// 		for(pix_ = 0; pix_ < jginfo->rowBytes; pix_+=3)
+// 		{
+// 		  int r = jginfo->image[line_*jginfo->rowBytes + pix_ + 0];
+//                   int g = jginfo->image[line_*jginfo->rowBytes + pix_ + 1];
+// 	          int b = jginfo->image[line_*jginfo->rowBytes + pix_ + 2];
+//   
+//                 if(r > 99)
+// 	{
+// 	printf("%d,", r);
+// 	}else	
+//         if(r > 9)
+// {
+// 	printf(" %d,", r);
+// }else
+// {
+// 	printf("  %d,", r);
+// }
+// 
+//                 if(g > 99)
+// 	{
+// 	printf("%d,", g);
+// 	}else	
+//         if(g > 9)
+// {
+// 	printf(" %d,", g);
+// }else
+// {
+// 	printf("  %d,", g);
+// }
+// 
+//                 if(b > 99)
+// 	{
+// 	printf("%d,", b);
+// 	}else	
+//         if(b > 9)
+// {
+// 	printf(" %d,", b);
+// }else
+// {
+// 	printf("  %d,", b);
+// }
+// 
+// 	printf(" 255, ");
+// }
+//             printf("\n");
+// 	  }	
+//         fflush(stdout);
diff -Nru openjdk.orig/jdk/src/solaris/native/sun/java2d/x11/XRGlyphCache.h openjdk/jdk/src/solaris/native/sun/java2d/x11/XRGlyphCache.h
--- openjdk.orig/jdk/src/solaris/native/sun/java2d/x11/XRGlyphCache.h	1970-01-01 01:00:00.000000000 +0100
+++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRGlyphCache.h	2009-05-13 01:02:29.000000000 +0100
@@ -0,0 +1,41 @@
+#ifndef XRGlyphCache_h_Included
+#define XRGlyphCache_h_Included
+
+#include "awt_p.h"
+#include "awt_GraphicsEnv.h"
+
+#include <X11/extensions/Xrender.h>
+#include "jni.h"
+#include "fontscalerdefs.h"
+
+typedef struct _XRGlyphCacheInfo XRGlyphCacheInfo;
+typedef struct _XRCacheCellInfo XRCacheCellInfo;
+
+struct _XRGlyphCacheInfo {
+    XRCacheCellInfo *cells;
+    jint searchPosition;
+    jint usedCells;
+    jint cellCapacity;
+    jint pixelsUsed;
+    GlyphSet glyphSet;
+};
+
+struct _XRCacheCellInfo {
+    XRGlyphCacheInfo *cacheInfo;
+    GlyphInfo *glyphInfo;
+    unsigned short glyphID;
+    jint timesRendered;
+    jint width;
+    jint height;
+    jint xOff;
+    jint yOff;
+    jboolean pinned;
+};
+
+#ifndef HEADLESS
+XRGlyphCacheInfo* XRGlyphCache_Init(XRenderPictFormat* glyphSetPictFormat);
+jboolean XRGlyphCache_CacheGlyphs(XRGlyphCacheInfo *cache, jlong *glyphPtrs, jint glyphCount, jint *ids);
+void dumpCache(XRGlyphCacheInfo *cache);
+#endif
+
+#endif /* XRGlyphCache_h_Included */
diff -Nru openjdk.orig/jdk/src/solaris/native/sun/java2d/x11/XRPMBlitLoops.c openjdk/jdk/src/solaris/native/sun/java2d/x11/XRPMBlitLoops.c
--- openjdk.orig/jdk/src/solaris/native/sun/java2d/x11/XRPMBlitLoops.c	1970-01-01 01:00:00.000000000 +0100
+++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRPMBlitLoops.c	2009-05-13 01:02:29.000000000 +0100
@@ -0,0 +1,223 @@
+/*
+ * Copyright 2000-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+#include <stdlib.h>
+#include <jni.h>
+#include <jlong.h>
+#include "X11SurfaceData.h"
+#include "XRSurfaceData.h"
+#include "Region.h"
+#include "MaskBuffer.h"
+#include "Trace.h"
+
+JNIEXPORT void JNICALL
+Java_sun_java2d_xr_XRPMBlitLoops_nativeRenderBlit
+    (JNIEnv *env, jclass xsd,
+     jlong srcData, jlong dstData,
+     jint srcx, jint srcy,
+     jint dstx, jint dsty,
+     jint width, jint height)
+{
+#ifndef HEADLESS
+    J2dTraceLn(J2D_TRACE_INFO, "in XRPBMBlitLoops_nativeRenderBlit");
+
+    X11SDOps *srcXsdo, *dstXsdo;
+    SurfaceDataBounds span, srcBounds;
+
+    if (width <= 0 || height <= 0) {
+        return;
+    }
+
+    srcXsdo = (X11SDOps *)jlong_to_ptr(srcData);
+    if (srcXsdo == NULL) {
+        return;
+    }
+    dstXsdo = (X11SDOps *)jlong_to_ptr(dstData);
+    if (dstXsdo == NULL) {
+        return;
+    }
+
+#ifdef MITSHM
+    if (srcXsdo->isPixmap) {
+        X11SD_UnPuntPixmap(srcXsdo);
+    }
+#endif /* MITSHM */
+
+/*   printf("src: %d, dst: %d", srcXsdo->xrData.xrPic, dstXsdo->xrData.xrPic);
+   fflush(stdout);*/
+
+/*XTransform xf = {{{XDoubleToFixed (0.5), 0, 0 },
+{0, XDoubleToFixed (0.5), 0 },
+{XDoubleToFixed (0), XDoubleToFixed (0), XDoubleToFixed (1.0)}}};
+
+XRenderSetPictureTransform(awt_display, dstXsdo->xrData.xrPic, &xf);
+XRenderSetPictureFilter(awt_display, dstXsdo->xrData.xrPic, "good", NULL, 0);*/
+
+   XRenderComposite (awt_display, xrSrcData.compRule, srcXsdo->xrPic, xrSrcData.alphaMask, dstXsdo->xrPic, srcx, srcy, 0, 0, dstx, dsty, width, height); 
+
+#ifdef MITSHM
+    if (srcXsdo->shmPMData.usingShmPixmap) {
+        srcXsdo->shmPMData.xRequestSent = JNI_TRUE;
+    }
+#endif /* MITSHM */
+    X11SD_DirectRenderNotify(env, dstXsdo);
+#endif /* !HEADLESS */
+}
+
+#ifndef HEADLESS
+static Picture prepareMaskPM(JNIEnv *env, X11SDOps *alphaXsdo, jbyteArray maskArray, jint maskoff, jint maskscan, jint w, jint h)
+{
+    int line, pix;
+    unsigned char *mask;
+    SurfaceDataOps *alphaOps = &alphaXsdo->sdOps;
+
+    jboolean useEA = (xrSrcData.src != xrSrcData.solid && xrSrcData.extraAlpha != 1.0f);
+
+    if (maskArray != NULL) {
+    		SurfaceDataRasInfo alphaInfo;
+    		alphaInfo.bounds.x1 = 0;
+    		alphaInfo.bounds.y1 = 0;
+    		alphaInfo.bounds.x2 = w;
+    		alphaInfo.bounds.y2 = h;
+
+		if (alphaOps->Lock(env, alphaOps, &alphaInfo, SD_LOCK_WRITE) != SD_SUCCESS) {
+			SurfaceData_InvokeUnlock(env, alphaOps, &alphaInfo);
+			return None;
+		}
+                mask = (unsigned char *) (*env)->GetPrimitiveArrayCritical(env, maskArray, NULL);
+
+		alphaOps->GetRasInfo(env, alphaOps, &alphaInfo);
+
+              if(useEA && (w > MASK_TILE_SIZE || h > MASK_TILE_SIZE))
+              {
+		for(line=0; line < h; line++) {
+		  for(pix=0; pix < w; pix++) {
+  		     ((unsigned char*)alphaInfo.rasBase)[line*alphaInfo.scanStride + pix] = (unsigned char) (mask[maskscan*line + pix + maskoff] * xrSrcData.extraAlpha);  
+		  }
+		}
+             }else
+             {
+		for(line=0; line < h; line++) {
+		  for(pix=0; pix < w; pix++) {
+  		     ((unsigned char*)alphaInfo.rasBase)[line*alphaInfo.scanStride + pix] = (unsigned char) (mask[maskscan*line + pix + maskoff]);  
+		  }
+		}
+             }
+
+                SurfaceData_InvokeRelease(env, alphaOps, &alphaInfo);
+                SurfaceData_InvokeUnlock(env, alphaOps, &alphaInfo);
+                (*env)->ReleasePrimitiveArrayCritical(env, maskArray, mask, JNI_ABORT);
+
+	if(useEA) {
+                XRenderComposite (awt_display, PictOpOver, alphaXsdo->xrPic, xrSrcData.alphaMask, maskBuffer->maskPicture, 0, 0, 0, 0, 0, 0, w, h); 
+                return maskBuffer->maskPicture;
+          }else
+          {
+             return alphaXsdo->xrPic;
+          }
+    }else
+    {
+      if(useEA) {
+        return xrSrcData.alphaMask;
+      }
+    }
+
+    return None;
+}
+
+static void cleanMask(Picture mask, int w, int h)
+{
+  if(mask == maskBuffer->maskPicture)
+  {
+     XRenderColor color_black={.red=0, .green=0, .blue=0, .alpha=0xffff};
+     XRenderFillRectangle (awt_display, PictOpClear, maskBuffer->maskPicture, &color_black, 0, 0, w, h);
+  }
+}
+#endif
+
+JNIEXPORT void JNICALL
+Java_sun_java2d_xr_XRMaskFill_maskFill
+     (JNIEnv *env, jobject joSelf, 
+      jlong dstData, jlong alphaData,
+      jint x, jint y, jint w, jint h,
+      jint maskoff, jint maskscan, 
+      jint masklen, jbyteArray maskArray)
+{
+#ifndef HEADLESS
+    J2dTraceLn(J2D_TRACE_INFO, "in XRPBMBlitLoops_maskFill");
+
+    Picture maskPic;
+    X11SDOps *dstXsdo, *alphaXsdo;
+    dstXsdo = (X11SDOps *)jlong_to_ptr(dstData);
+    alphaXsdo = (X11SDOps *)jlong_to_ptr(alphaData);
+    if (dstXsdo == NULL || alphaXsdo == NULL) {
+        return;
+    }
+
+    maskPic = prepareMaskPM(env, alphaXsdo, maskArray, maskoff, maskscan, w, h);
+
+    XRComposite(maskPic, dstXsdo->xrPic, x, y, 0, 0, x, y, w, h);
+
+    cleanMask(maskPic, w, h);
+
+    X11SD_DirectRenderNotify(env, dstXsdo);
+#endif
+}
+
+
+JNIEXPORT void JNICALL
+Java_sun_java2d_xr_XRMaskBlit_maskBlit
+     (JNIEnv *env, jobject joSelf, 
+      jlong srcData, jlong dstData, jlong alphaData,
+      jint srcx, jint srcy,
+      jint dstx, jint dsty, jint w, jint h,
+      jint maskoff, jint maskscan, 
+      jint masklen, jbyteArray maskArray)
+{
+#ifndef HEADLESS
+    J2dTraceLn(J2D_TRACE_INFO, "in XRPBMBlitLoops_maskBlit");
+
+    Picture maskPic;
+    X11SDOps *srcXsdo, *dstXsdo, *alphaXsdo;
+    srcXsdo = (X11SDOps *)jlong_to_ptr(srcData);
+    dstXsdo = (X11SDOps *)jlong_to_ptr(dstData);
+    alphaXsdo = (X11SDOps *)jlong_to_ptr(alphaData);
+    if (srcXsdo == NULL || dstXsdo == NULL || alphaXsdo == NULL) {
+        return;
+    }
+
+    maskPic = prepareMaskPM(env, alphaXsdo, maskArray, maskoff, maskscan, w, h);
+    XRenderComposite (awt_display, xrSrcData.compRule, srcXsdo->xrPic, maskPic, dstXsdo->xrPic, srcx, srcy, 0, 0, dstx, dsty, w, h); 
+    cleanMask(maskPic, w, h);
+
+    X11SD_DirectRenderNotify(env, dstXsdo);
+
+    #ifdef MITSHM
+    if (srcXsdo->isPixmap) {
+        X11SD_UnPuntPixmap(srcXsdo);
+    }
+    #endif /* MITSHM */
+#endif
+}
diff -Nru openjdk.orig/jdk/src/solaris/native/sun/java2d/x11/XRRenderer.c openjdk/jdk/src/solaris/native/sun/java2d/x11/XRRenderer.c
--- openjdk.orig/jdk/src/solaris/native/sun/java2d/x11/XRRenderer.c	1970-01-01 01:00:00.000000000 +0100
+++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRRenderer.c	2009-05-13 01:02:29.000000000 +0100
@@ -0,0 +1,318 @@
+/*
+ * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+#include "X11SurfaceData.h"
+#include "XRSurfaceData.h"
+#include "SpanIterator.h"
+#include "Trace.h"
+#include "ProcessPath.h"
+#include "GraphicsPrimitiveMgr.h"
+#include <math.h>
+#include <stdint.h>
+
+#include <jlong.h>
+
+#define POLYTEMPSIZE    (int)(256 / sizeof(XPoint))
+#define ABS(n)          (((n) < 0) ? -(n) : (n))
+
+#define MAX_SHORT 32767
+#define MIN_SHORT (-32768)
+
+#define CLAMP_TO_SHORT(x) (((x) > MAX_SHORT)                            \
+                           ? MAX_SHORT                                  \
+                           : ((x) < MIN_SHORT)                          \
+                               ? MIN_SHORT                              \
+                               : (x))
+
+#define CLAMP_TO_USHORT(x)  (((x) > 65535) ? 65535 : ((x) < 0) ? 0 : (x))
+
+
+JNIEXPORT void JNICALL XRDrawLines(Picture dst, XPoint * points, int npoints)
+{
+#ifndef HEADLESS
+    J2dTraceLn(J2D_TRACE_INFO, "in XRRenderer_XRDrawLines");
+
+    int i;
+    XPoint *start = &points[0], *end;
+    for(i=1; i < npoints; i++)
+    {
+      end = &points[i];
+      addLine(maskBuffer, start->x, start->y, end->x, end->y);
+      start = end;
+    }
+#endif
+}
+
+/*
+ * Class:     sun_java2d_xr_XRRenderer
+ * Method:    XDrawLine
+ * Signature: (IJIIII)V
+ */
+JNIEXPORT void JNICALL Java_sun_java2d_xr_XRRenderer_XRDrawLine
+    (JNIEnv *env, jobject xr, jlong pXSData, jint x1, jint y1, jint x2, jint y2)
+{
+#ifndef HEADLESS
+    J2dTraceLn(J2D_TRACE_INFO, "in XRRenderer_XRDrawLine");
+    X11SDOps *xsdo = (X11SDOps *) jlong_to_ptr(pXSData);
+
+    if (xsdo == NULL) {
+        return;
+    }
+
+    addLine(maskBuffer, x1, y1, x2, y2);
+    fillMask(maskBuffer, xsdo->xrPic);
+
+    X11SD_DirectRenderNotify(env, xsdo);
+#endif /* !HEADLESS */
+}
+
+static void storeLine(DrawHandler* hnd,
+                      jint x0, jint y0, jint x1, jint y1)
+{
+#ifndef HEADLESS
+   addLine(maskBuffer, x0, y0, x1, y1);
+#endif /* !HEADLESS */
+}
+
+static void storePoint(DrawHandler* hnd, jint x0, jint y0) {
+#ifndef HEADLESS
+    addRect(maskBuffer, x0, y0, 1, 1);
+#endif /* !HEADLESS */
+}
+
+static void drawSubPath(ProcessHandler* hnd) {
+#ifndef HEADLESS
+#endif /* !HEADLESS */
+}
+
+static void drawScanline(DrawHandler* hnd, jint x0, jint x1, jint y0)
+{
+#ifndef HEADLESS
+   addRect(maskBuffer, x0, y0, x1-x0 + 1, 1);
+#endif /* !HEADLESS */
+}
+
+/*
+ * Class:     sun_java2d_xr_XRRenderer
+ * Method:    XDoPath
+ * Signature: (Lsun/java2d/SunGraphics2D;JJIILjava/awt/geom/Path2D/Float;Z)V
+ */
+JNIEXPORT void JNICALL
+Java_sun_java2d_xr_XRRenderer_XRDoPath
+    (JNIEnv *env, jobject self, jobject sg2d, jlong pXSData,
+     jint transX, jint transY, jobject p2df, jboolean isFill)
+{
+#ifndef HEADLESS
+    J2dTraceLn(J2D_TRACE_INFO, "in XRRenderer_XRDoPath");
+
+    X11SDOps *xsdo = (X11SDOps *) jlong_to_ptr(pXSData);
+    jarray typesArray;
+    jobject pointArray;
+    jarray coordsArray;
+    jint numTypes;
+    jint fillRule;
+    jint maxCoords;
+    jbyte *types;
+    jfloat *coords;
+
+    DrawHandler drawHandler = {
+        NULL, NULL, NULL,
+        MIN_SHORT, MIN_SHORT, MAX_SHORT, MAX_SHORT,
+        0, 0, 0, 0,
+        NULL
+    };
+    PHStroke stroke;
+
+    if (xsdo == NULL) {
+        return;
+    }
+
+    if (isFill) {
+        fillRule = (*env)->GetIntField(env, p2df, path2DWindingRuleID);
+    }
+
+    typesArray = (jarray)(*env)->GetObjectField(env, p2df, path2DTypesID);
+    coordsArray = (jarray)(*env)->GetObjectField(env, p2df,
+                                                 path2DFloatCoordsID);
+    if (coordsArray == NULL) {
+        JNU_ThrowNullPointerException(env, "coordinates array");
+        return;
+    }
+    numTypes = (*env)->GetIntField(env, p2df, path2DNumTypesID);
+    if ((*env)->GetArrayLength(env, typesArray) < numTypes) {
+        JNU_ThrowArrayIndexOutOfBoundsException(env, "types array");
+        return;
+    }
+
+
+    drawHandler.pData = NULL;
+
+    stroke = (((*env)->GetIntField(env, sg2d, sg2dStrokeHintID) ==
+               sunHints_INTVAL_STROKE_PURE)
+              ? PH_STROKE_PURE
+              : PH_STROKE_DEFAULT);
+
+    maxCoords = (*env)->GetArrayLength(env, coordsArray);
+    coords = (jfloat*)
+        (*env)->GetPrimitiveArrayCritical(env, coordsArray, NULL);
+    if (coords != NULL) {
+        types = (jbyte*)
+            (*env)->GetPrimitiveArrayCritical(env, typesArray, NULL);
+        if (types != NULL) {
+            jboolean ok;
+
+            if (isFill) {
+                drawHandler.pDrawScanline = &drawScanline;
+                ok = doFillPath(&drawHandler,
+                                transX, transY,
+                                coords, maxCoords,
+                                types, numTypes,
+                                stroke, fillRule);
+            } else {
+                drawHandler.pDrawLine = &storeLine;
+                drawHandler.pDrawPixel = &storePoint;
+                ok = doDrawPath(&drawHandler, &drawSubPath,
+                                transX, transY,
+                                coords, maxCoords,
+                                types, numTypes,
+                                stroke);
+            }
+            if (!ok) {
+                JNU_ThrowArrayIndexOutOfBoundsException(env, "coords array");
+            }
+            (*env)->ReleasePrimitiveArrayCritical(env, typesArray, types,
+                                                  JNI_ABORT);
+        }
+        (*env)->ReleasePrimitiveArrayCritical(env, coordsArray, coords,
+                                              JNI_ABORT);
+    }
+
+
+    fillMask(maskBuffer, xsdo->xrPic);
+
+    X11SD_DirectRenderNotify(env, xsdo);
+#endif /* !HEADLESS */
+}
+
+JNIEXPORT void JNICALL Java_sun_java2d_xr_XRRenderer_XRFillRect
+    (JNIEnv *env, jobject xr,
+     jlong pXSData,
+     jint x, jint y, jint w, jint h)
+{
+#ifndef HEADLESS
+    J2dTraceLn(J2D_TRACE_INFO, "in XRRenderer_XRFillRect");
+    X11SDOps *xsdo = (X11SDOps *) jlong_to_ptr(pXSData);
+
+    if (xsdo == NULL) {
+        return;
+    }
+ 
+    addRect(maskBuffer, x, y, w, h);
+    fillMask(maskBuffer, xsdo->xrPic);
+
+    X11SD_DirectRenderNotify(env, xsdo);
+#endif /* !HEADLESS */
+}
+
+JNIEXPORT void JNICALL Java_sun_java2d_xr_XRRenderer_XRFillSpans
+    (JNIEnv *env, jobject xr,
+     jlong pXSData,
+     jobject si, jlong pIterator,
+     jint transx, jint transy)
+{
+#ifndef HEADLESS
+    J2dTraceLn(J2D_TRACE_INFO, "in XRRenderer_XRFillSpans");
+
+    SpanIteratorFuncs *pFuncs = (SpanIteratorFuncs *) jlong_to_ptr(pIterator);
+    void *srData;
+    jint x, y, w, h;
+    jint spanbox[4];
+    X11SDOps *xsdo = (X11SDOps *) jlong_to_ptr(pXSData);
+
+    if (xsdo == NULL) {
+        return;
+    }
+
+    if (JNU_IsNull(env, si)) {
+        JNU_ThrowNullPointerException(env, "span iterator");
+        return;
+    }
+    if (pFuncs == NULL) {
+        JNU_ThrowNullPointerException(env, "native iterator not supplied");
+        return;
+    }
+
+    srData = (*pFuncs->open)(env, si);
+    while ((*pFuncs->nextSpan)(srData, spanbox)) {
+        x = spanbox[0] + transx;
+        y = spanbox[1] + transy;
+        w = spanbox[2] - spanbox[0];
+        h = spanbox[3] - spanbox[1];
+
+        addRect(maskBuffer, x, y, w, h);
+    }
+
+    fillMask(maskBuffer, xsdo->xrPic);
+
+    (*pFuncs->close)(env, srData);
+    X11SD_DirectRenderNotify(env, xsdo);
+#endif /* !HEADLESS */
+}
+
+/*
+ * Class:     sun_java2d_xr_XRRenderer
+ * Method:    devCopyArea
+ * Signature: (Lsun/java2d/SurfaceData;IIIIII)V
+ */
+JNIEXPORT void JNICALL
+Java_sun_java2d_xr_XRRenderer_devCopyArea
+    (JNIEnv *env, jobject xr,
+     jlong xsd, jlong gc,
+     jint srcx, jint srcy,
+     jint dstx, jint dsty,
+     jint width, jint height)
+{
+#ifndef HEADLESS
+    J2dTraceLn(J2D_TRACE_INFO, "in XRRenderer_devCopyArea");
+
+    X11SDOps *xsdo;
+    GC xgc;
+
+    xsdo = (X11SDOps *) jlong_to_ptr(xsd);
+    if (xsdo == NULL) {
+        return;
+    }
+
+    xgc = (GC) jlong_to_ptr(gc);
+    if (xgc == NULL) {
+        return;
+    }
+
+    XCopyArea(awt_display, xsdo->drawable, xsdo->drawable, xgc,
+              srcx, srcy, width, height, dstx, dsty);
+
+    X11SD_DirectRenderNotify(env, xsdo);
+#endif /* !HEADLESS */
+}
diff -Nru openjdk.orig/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.c openjdk/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.c
--- openjdk.orig/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.c	1970-01-01 01:00:00.000000000 +0100
+++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.c	2009-05-13 01:02:29.000000000 +0100
@@ -0,0 +1,519 @@
+#include "GraphicsPrimitiveMgr.h"
+#include "Region.h"
+#include "Trace.h"
+#include "X11SurfaceData.h"
+
+#ifndef HEADLESS
+SrcSurfaceData xrSrcData;
+MaskBuffer *maskBuffer;
+#endif /* !HEADLESS */
+
+#define BUILD_TRANSFORM_MATRIX(TRANSFORM, M00, M01, M02, M10, M11, M12)                        \
+    {                                                                                          \
+      TRANSFORM.matrix[0][0] = M00;                                                            \
+      TRANSFORM.matrix[0][1] = M01;                                                            \
+      TRANSFORM.matrix[0][2] = M02;                                                            \
+      TRANSFORM.matrix[1][0] = M10;                                                            \
+      TRANSFORM.matrix[1][1] = M11;                                                            \
+      TRANSFORM.matrix[1][2] = M12;                                                            \
+      TRANSFORM.matrix[2][0] = 0;                                                              \
+      TRANSFORM.matrix[2][1] = 0;                                                              \
+      TRANSFORM.matrix[2][2] = 1<<16;                                                          \
+    }
+
+
+JNIEXPORT void JNICALL
+Java_sun_java2d_xr_XRSurfaceData_initOps(JNIEnv *env, jobject xsd,
+                                           jobject peer,
+                                           jobject graphicsConfig, jint depth)
+{
+   J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_initOps");
+
+   Java_sun_java2d_x11_X11SurfaceData_initOps(env, xsd, peer, graphicsConfig, depth);
+}
+
+JNIEXPORT jlong JNICALL Java_sun_java2d_xr_XRSurfaceData_XCreateGC (JNIEnv *env, jclass xsd, jlong pXSData)
+{
+   J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_XCreateGC");
+
+   return Java_sun_java2d_x11_X11SurfaceData_XCreateGC (env, xsd, pXSData);
+}
+
+JNIEXPORT void JNICALL
+Java_sun_java2d_xr_XRSurfaceData_flushNativeSurface(JNIEnv *env, jobject xsd)
+{
+  J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_flushNativeSurface");
+
+  Java_sun_java2d_x11_X11SurfaceData_flushNativeSurface(env, xsd);
+}
+
+
+JNIEXPORT void JNICALL
+Java_sun_java2d_xr_XRSurfaceData_setInvalid(JNIEnv *env, jobject xsd)
+{
+#ifndef HEADLESS
+    J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_setInvalid");
+    X11SDOps *xsdo = (X11SDOps *) SurfaceData_GetOps(env, xsd);
+
+    if (xsdo != NULL) {
+        xsdo->invalid = JNI_TRUE;
+    }
+#endif /* !HEADLESS */
+}
+
+JNIEXPORT jboolean JNICALL
+Java_sun_java2d_xr_XRSurfaceData_XRIsDrawableValid(JNIEnv *env, jobject this)
+{
+    jboolean ret = JNI_FALSE;
+
+#ifndef HEADLESS
+    J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_XRIsDrawableValid");
+    X11SDOps *xsdo = X11SurfaceData_GetOps(env, this);
+
+    if (xsdo->drawable != 0 || X11SD_InitWindow(env, xsdo) == SD_SUCCESS) {
+        ret = JNI_TRUE;
+    }
+
+#endif /* !HEADLESS */
+
+    return ret;
+}
+
+
+JNIEXPORT void JNICALL
+   Java_sun_java2d_xr_XRSurfaceData_XRInitXRender(JNIEnv *env, jobject xsd, jlong pXSData, jint pictFormat)
+{
+#ifndef HEADLESS
+  J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_initXRender");
+  X11SDOps *xsdo;
+  xsdo = (X11SDOps *) jlong_to_ptr(pXSData);
+  if (xsdo == NULL) {
+      return;
+  }
+
+  if(xsdo->xrPic == None)
+  {
+    XRenderPictureAttributes pict_attr;
+    pict_attr.repeat = RepeatNone; 
+    XRenderPictFormat *fmt = XRenderFindStandardFormat(awt_display, pictFormat);
+    xsdo->xrPic = XRenderCreatePicture(awt_display, xsdo->drawable, fmt, CPRepeat, &pict_attr);
+  }
+
+  if(maskBuffer == NULL) 
+  {
+    maskBuffer = initMaskBuffer(xsdo->drawable);
+
+    XRenderPictureAttributes pict_attr;
+    pict_attr.repeat = 1;
+
+    /*Init solid color pen*/
+    XRenderPictFormat *fmt = XRenderFindStandardFormat(awt_display, PictStandardARGB32);
+    Pixmap solidPixmap = XCreatePixmap(awt_display, xsdo->drawable, 1, 1, 32);
+    xrSrcData.solid = XRenderCreatePicture(awt_display, solidPixmap, fmt, CPRepeat, &pict_attr);
+
+    /*Init extra-alpha mask*/
+    fmt = XRenderFindStandardFormat(awt_display, PictStandardA8);
+    Pixmap alphaPixmap = XCreatePixmap(awt_display, xsdo->drawable, 1, 1, 8);
+    xrSrcData.alphaMaskPict = XRenderCreatePicture(awt_display, alphaPixmap, fmt, CPRepeat, &pict_attr);
+  }
+#endif /* !HEADLESS */
+}
+
+JNIEXPORT void JNICALL
+Java_sun_java2d_xr_XRSurfaceData_initIDs(JNIEnv *env, jclass xsd, jboolean gradCacheEnabled)
+{
+#ifndef HEADLESS
+  J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_initIDs");
+
+  xrSrcData.src = None;
+  xrSrcData.solid = None;
+  xrSrcData.texture = None;
+  xrSrcData.gradient = None;
+  xrSrcData.alphaMask = None;
+  xrSrcData.alphaMaskPict = None;
+  xrSrcData.compRule = PictOpOver;
+  xrSrcData.extraAlpha = 1.0f;
+  xrSrcData.compRequired = JNI_FALSE;
+
+  xrSrcData.alphaColor.alpha = 0xffff;
+  xrSrcData.alphaColor.red = 0xffff;
+  xrSrcData.alphaColor.green = 0xffff;
+  xrSrcData.alphaColor.blue = 0xffff;
+
+  xrSrcData.gradCacheEnabled = gradCacheEnabled;
+
+  maskBuffer = NULL;
+
+  XShared_initIDs(env);
+#endif /* !HEADLESS */
+}
+
+
+void XRComposite(Picture mask, Picture dest, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, unsigned int width, unsigned int height)
+{ 
+  Picture cachedSrc = xrSrcData.src;
+  int cachedX = srcX;
+  int cachedY = srcY;
+
+  if(xrSrcData.src == xrSrcData.gradient && xrSrcData.gradCacheEnabled)
+  {
+    XRenderComposite(awt_display, PictOpSrc, xrSrcData.gradient, None, maskBuffer->gradPict, srcX, srcY, 0, 0, 0, 0, width, height);
+    cachedX = 0;
+    cachedY = 0; 
+    cachedSrc = maskBuffer->gradPict;
+  }
+
+   XRenderComposite (awt_display, xrSrcData.compRule, cachedSrc, mask, dest, cachedX, cachedY, maskX, maskY, dstX, dstY, width, height);
+}
+
+
+
+JNIEXPORT void JNICALL
+Java_sun_java2d_xr_XRSurfaceData_XRInitSurface(JNIEnv *env, jclass xsd,
+                                               jint depth,
+                                               jint width, jint height,
+                                               jlong drawable, jint pictFormat)
+{
+#ifndef HEADLESS
+    J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_initSurface");
+
+    jboolean success = JNI_FALSE;
+    X11SDOps *xsdo = X11SurfaceData_GetOps(env, xsd);
+    if (xsdo == NULL) {
+        return;
+    }
+
+    if(XShared_initSurface(env, xsdo, depth, width, height, drawable))
+    {
+      XRenderPictureAttributes pict_attr;
+      XRenderPictFormat *fmt = XRenderFindStandardFormat(awt_display, pictFormat); 
+      xsdo->xrPic = XRenderCreatePicture(awt_display, xsdo->drawable, fmt, 0, &pict_attr);
+    }
+#endif /* !HEADLESS */
+}
+
+
+JNIEXPORT void JNICALL
+Java_sun_java2d_xr_XRSurfaceData_XRResetPaint
+    (JNIEnv *env, jclass xsd)
+{
+#ifndef HEADLESS
+    J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_XRResetPaint");
+    xrSrcData.src = xrSrcData.solid;
+#endif /* !HEADLESS */
+}
+
+JNIEXPORT void JNICALL
+Java_sun_java2d_xr_XRSurfaceData_XRSetRepeat
+    (JNIEnv *env, jclass xsd, jlong pXSData, jint repeat)
+{
+#ifndef HEADLESS
+    J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_XRSetRepeat");
+    X11SDOps *xsdo;
+    xsdo = (X11SDOps *) jlong_to_ptr(pXSData);
+    if (xsdo == NULL) {
+        return;
+    }
+
+    XRenderPictureAttributes pict_attr;
+    pict_attr.repeat = repeat;
+    XRenderChangePicture (awt_display, xsdo->xrPic, CPRepeat, &pict_attr);
+#endif /* !HEADLESS */
+}
+
+
+JNIEXPORT void JNICALL
+Java_sun_java2d_xr_XRSurfaceData_XRSetLinearGradientPaint
+    (JNIEnv *env, jclass xsd, jfloatArray fractionsArray, jintArray pixelsArray, jint x1, jint y1, jint x2, jint y2, jint numStops, jint cycleMethod, jboolean useMask, jboolean linear, jint m00, jint m01, jint m02, jint m10, jint m11, jint m12)
+{
+#ifndef HEADLESS
+   J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_XRSetLinearGradientPaint");
+
+   jint i;
+   jint* pixels;
+   jfloat* fractions;
+
+   if((pixels = (jint *) (*env)->GetPrimitiveArrayCritical(env, pixelsArray, NULL)) == NULL) {
+     return;
+   }
+   if((fractions = (jfloat *) (*env)->GetPrimitiveArrayCritical(env, fractionsArray, NULL)) == NULL) {
+     return; //TODO release pixels first
+   }
+
+   if(xrSrcData.gradient != None) {
+      XRenderFreePicture(awt_display, xrSrcData.gradient);
+      xrSrcData.gradient = None;
+   }
+
+    XLinearGradient grad;
+    XRenderColor colors[numStops];
+    XFixed stops[numStops];
+
+    grad.p1.x = x1;
+    grad.p1.y = y1;
+    grad.p2.x = x2;
+    grad.p2.y = y2;
+
+    for(i=0; i < numStops; i++) {
+      stops[i] = XDoubleToFixed(fractions[i]);
+      decodeRenderColorPre(pixels[i], &colors[i]);
+    }
+
+    xrSrcData.gradient = XRenderCreateLinearGradient(awt_display, &grad, &stops[0], &colors[0], numStops);
+    xrSrcData.src = xrSrcData.gradient;
+
+    XTransform tr;
+    BUILD_TRANSFORM_MATRIX(tr, m00, m01, m02, m10, m11, m12);
+    XRenderSetPictureTransform (awt_display, xrSrcData.gradient, &tr);
+
+    XRenderPictureAttributes pict_attr;
+    pict_attr.repeat = cycleMethod;
+    XRenderChangePicture (awt_display, xrSrcData.gradient, CPRepeat, &pict_attr);
+
+   (*env)->ReleasePrimitiveArrayCritical(env, pixelsArray, pixels, JNI_ABORT);
+   (*env)->ReleasePrimitiveArrayCritical(env, fractionsArray, fractions, JNI_ABORT);
+#endif /* !HEADLESS */
+}
+
+
+JNIEXPORT void JNICALL
+Java_sun_java2d_xr_XRSurfaceData_XRSetRadialGradientPaint
+    (JNIEnv *env, jclass xsd, jfloatArray fractionsArray, jintArray pixelsArray, jint fx, jint numStops, jint cycleMethod, jboolean useMask, jboolean linear, jint innerRadius, jint outerRadius, jint m00, jint m01, jint m02, jint m10, jint m11, jint m12)
+{
+#ifndef HEADLESS
+   J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_XRSetRadialGradientPaint");
+   jint i;
+   jint* pixels;
+   jfloat* fractions;
+
+   if((pixels = (jint *) (*env)->GetPrimitiveArrayCritical(env, pixelsArray, NULL)) == NULL) {
+     return;
+   }
+   if((fractions = (jfloat *) (*env)->GetPrimitiveArrayCritical(env, fractionsArray, NULL)) == NULL) {
+     return;
+   }
+
+   if(xrSrcData.gradient != None) {
+      XRenderFreePicture(awt_display, xrSrcData.gradient);
+      xrSrcData.gradient = None;
+   }
+
+    XRadialGradient grad;
+    XRenderColor colors[numStops];
+    XFixed stops[numStops];
+
+    grad.inner.x = 0;
+    grad.inner.y = 0;
+    grad.inner.radius = innerRadius;
+    grad.outer.x = 0;
+    grad.outer.y = 0;
+    grad.outer.radius = outerRadius;
+
+    for(i=0; i < numStops; i++) {
+      stops[i] = XDoubleToFixed(fractions[i]);
+      decodeRenderColorPre(pixels[i], &colors[i]);
+    }
+
+    xrSrcData.gradient = XRenderCreateRadialGradient(awt_display, &grad, &stops[0], &colors[0], numStops);
+    xrSrcData.src = xrSrcData.gradient;
+
+    XTransform tr;
+    BUILD_TRANSFORM_MATRIX(tr, m00, m01, m02, m10, m11, m12);
+    XRenderSetPictureTransform (awt_display, xrSrcData.gradient, &tr);
+
+    XRenderPictureAttributes pict_attr;
+    pict_attr.repeat = cycleMethod;
+    XRenderChangePicture (awt_display, xrSrcData.gradient, CPRepeat, &pict_attr);
+
+   (*env)->ReleasePrimitiveArrayCritical(env, pixelsArray, pixels, JNI_ABORT);
+   (*env)->ReleasePrimitiveArrayCritical(env, fractionsArray, fractions, JNI_ABORT);
+#endif /* !HEADLESS */
+}
+
+
+JNIEXPORT void JNICALL
+Java_sun_java2d_xr_XRSurfaceData_XRSetTexturePaint
+    (JNIEnv *env, jclass xsd, jlong pXSData)
+{
+#ifndef HEADLESS
+    J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_XRSetTexturePaint");
+
+    X11SDOps *xsdo;
+    xsdo = (X11SDOps *) jlong_to_ptr(pXSData);
+    if (xsdo == NULL) {
+        return;
+    }
+
+    xrSrcData.texture = xsdo->xrPic;
+    xrSrcData.src = xrSrcData.texture;
+#endif /* !HEADLESS */
+}
+
+
+JNIEXPORT void JNICALL
+Java_sun_java2d_xr_XRSurfaceData_XRSetComposite
+    (JNIEnv *env, jclass xsd, jint compRule, jfloat eAlpha)
+{
+#ifndef HEADLESS
+  J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_XRSetComposite");
+
+  xrSrcData.compRule = compRule;
+  xrSrcData.extraAlpha = eAlpha;
+
+  if(eAlpha != 1.0f) {
+    unsigned short alphaValue = XDoubleToUShort(eAlpha);
+    xrSrcData.alphaColor.alpha = alphaValue;
+    xrSrcData.alphaColor.red = alphaValue;
+    xrSrcData.alphaColor.green = alphaValue;
+    xrSrcData.alphaColor.blue = alphaValue;
+    XRenderFillRectangle (awt_display, PictOpSrc, xrSrcData.alphaMaskPict, &xrSrcData.alphaColor, 0, 0, 1, 1);
+    xrSrcData.alphaMask = xrSrcData.alphaMaskPict;
+  }else {
+    xrSrcData.alphaMask = None;
+  }
+#endif /* !HEADLESS */
+}
+
+JNIEXPORT void JNICALL
+Java_sun_java2d_xr_XRSurfaceData_XRSetClip
+    (JNIEnv *env, jclass xsd, jlong pXSData,
+     jint x1, jint y1, jint x2, jint y2,
+     jobject complexclip)
+{
+#ifndef HEADLESS
+    J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_XRSetClip");
+
+    int numrects;
+    XRectangle rects[256];
+    XRectangle *pRect = rects;
+    X11SDOps *xsdo;
+
+    xsdo = (X11SDOps *) jlong_to_ptr(pXSData);
+    if (xsdo == NULL) {
+        return;
+    }
+
+    numrects = RegionToYXBandedRectangles(env,
+            x1, y1, x2, y2, complexclip,
+            &pRect, 256);
+
+
+     XRenderSetPictureClipRectangles (awt_display, xsdo->xrPic, 0, 0, pRect, numrects);
+
+    if (pRect != rects) {
+        free(pRect);
+    }
+#endif /* !HEADLESS */
+}
+
+JNIEXPORT void JNICALL
+Java_sun_java2d_xr_XRSurfaceData_XRResetClip
+    (JNIEnv *env, jclass xsd, jlong pXSData)
+{
+#ifndef HEADLESS
+    J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_XRResetClip");
+    X11SDOps *xsdo;
+
+    xsdo = (X11SDOps *) jlong_to_ptr(pXSData);
+    if (xsdo == NULL) {
+        return;
+    }
+
+    XRectangle clip;
+    clip.x = 0;
+    clip.y = 0;
+    clip.width = 32767;
+    clip.height = 32767;
+
+    XRenderSetPictureClipRectangles (awt_display, xsdo->xrPic, 0, 0, &clip, 1);
+#endif /* !HEADLESS */
+}
+
+
+	//private static native void XRSetTransform(long xsdo, double m00, double m01, double m02, double m10, double m11, double m12);
+JNIEXPORT void JNICALL
+Java_sun_java2d_xr_XRSurfaceData_XRSetTransformNative
+    (JNIEnv *env, jclass xsd, jlong pXSData, jint m00, jint m01, jint m02, jint m10, jint m11, jint m12)
+{
+#ifndef HEADLESS
+    J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_XRSetTransformNative");
+    X11SDOps *xsdo;
+
+    xsdo = (X11SDOps *) jlong_to_ptr(pXSData);
+    if (xsdo == NULL) {
+        return;
+    }
+
+    XTransform tr;
+    BUILD_TRANSFORM_MATRIX(tr, m00, m01, m02, m10, m11, m12);
+
+    XRenderSetPictureTransform (awt_display, xsdo->xrPic, &tr);
+#endif /* !HEADLESS */
+}
+
+
+JNIEXPORT void JNICALL
+Java_sun_java2d_xr_XRSurfaceData_XRSetForeground
+    (JNIEnv *env, jclass xsd, jint pixel)
+{
+#ifndef HEADLESS
+    J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_XRSetForeground");
+
+    decodeRenderColor(pixel, &xrSrcData.solidColor);
+    XRenderFillRectangle (awt_display, PictOpSrc, xrSrcData.solid, &xrSrcData.solidColor, 0, 0, 1, 1);
+#endif /* !HEADLESS */
+}
+
+
+JNIEXPORT void JNICALL
+Java_sun_java2d_xr_XRSurfaceData_XRSetFilter
+    (JNIEnv *env, jclass xsd, jlong pXSData, jint filter)
+{
+#ifndef HEADLESS
+    J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_XRSetFilter");
+    X11SDOps *xsdo;
+
+    xsdo = (X11SDOps *) jlong_to_ptr(pXSData);
+    if (xsdo == NULL) {
+        return;
+    }
+
+    switch(filter)
+    {
+      case 0:
+        XRenderSetPictureFilter(awt_display, xsdo->xrPic, "fast", NULL, 0);
+        break;
+
+      case 1:
+        XRenderSetPictureFilter(awt_display, xsdo->xrPic, "good", NULL, 0);
+        break;
+
+      case 2:
+        XRenderSetPictureFilter(awt_display, xsdo->xrPic, "best", NULL, 0);
+        break;
+    }
+#endif /* !HEADLESS */
+}
+
+static void decodeRenderColor(jint pixel, XRenderColor *color)
+{ 
+   /*Extract color values from pixel, premultiply values. TODO: shouldn't this be done at the Java-level?*/
+    XFixed alpha = (((pixel & 0xFF000000) >> 16) + 255); /*REMIND: We rely on optimizations that this is 0xffff for opaque colors*/
+    XFixed red =   (((pixel & 0x00FF0000) >> 8)  + 255);
+    XFixed green = (((pixel & 0x0000FF00) >> 0)  + 255);
+    XFixed blue =  (((pixel & 0x000000FF) << 8)  + 255);
+
+    XDouble alphaMult = XFixedToDouble(alpha);
+    color->alpha = alpha;
+    color->red = (XFixed) red*alphaMult;
+    color->green = (XFixed) green*alphaMult;
+    color->blue = (XFixed) blue*alphaMult;
+}
+
+static void decodeRenderColorPre(jint pixel, XRenderColor *color)
+{ 
+    color->alpha = (((pixel & 0xFF000000) >> 16) + 255); /*REMIND: We rely on optimizations that this is 0xffff for opaque colors*/
+    color->red =   (((pixel & 0x00FF0000) >> 8)  + 255);
+    color->green = (((pixel & 0x0000FF00) >> 0)  + 255);
+    color->blue =  (((pixel & 0x000000FF) << 8)  + 255);
+}
\ No newline at end of file
diff -Nru openjdk.orig/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.h openjdk/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.h
--- openjdk.orig/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.h	1970-01-01 01:00:00.000000000 +0100
+++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.h	2009-05-13 01:02:29.000000000 +0100
@@ -0,0 +1,33 @@
+#ifndef XRSurfaceData_h_Included
+#define XRSurfaceData_h_Included
+
+#define XDoubleToUShort(f)    ((unsigned short) ((f) * 65535))
+
+typedef struct {
+  Picture src;
+  jboolean compRequired;
+  XRenderColor alphaColor;
+
+  Picture solid;
+  XRenderColor solidColor;
+  Picture texture;
+  Picture gradient;
+
+  jint compRule;
+  jfloat extraAlpha;
+  Picture alphaMask; //Only !None when eA turned on
+
+  Picture alphaMaskPict;
+  jboolean gradCacheEnabled;
+} SrcSurfaceData;
+
+extern SrcSurfaceData xrSrcData;
+extern MaskBuffer *maskBuffer;
+
+void XRComposite(Picture mask, Picture dest, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, unsigned int width, unsigned int height);
+
+static void decodeRenderColor(jint pixel, XRenderColor *color);
+
+static void decodeRenderColorPre(jint pixel, XRenderColor *color);
+
+#endif //XRSurfaceData_h_Included
diff -Nru openjdk.orig/jdk/src/solaris/native/sun/java2d/x11/XRTextRenderer_md.c openjdk/jdk/src/solaris/native/sun/java2d/x11/XRTextRenderer_md.c
--- openjdk.orig/jdk/src/solaris/native/sun/java2d/x11/XRTextRenderer_md.c	1970-01-01 01:00:00.000000000 +0100
+++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRTextRenderer_md.c	2009-05-13 01:02:29.000000000 +0100
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2001-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+#include "GlyphImageRef.h"
+
+#ifdef HEADLESS
+#include "SurfaceData.h"
+#else
+#include "X11SurfaceData.h"
+#include "XRSurfaceData.h"
+#include "GraphicsPrimitiveMgr.h"
+#include "glyphblitting.h"
+#include "sunfontids.h"
+#include "fontscalerdefs.h"
+#include "AccelGlyphCache.h"
+#include "sunfontids.h"
+#include "XRGlyphCache.h"
+#include "Trace.h"
+#endif /* !HEADLESS */
+#include <jlong.h>
+
+#define TEXT_BM_WIDTH   1024
+#define TEXT_BM_HEIGHT  32
+
+
+#define FLOOR_ASSIGN(l, r)\
+ if ((r)<0) (l) = ((int)floor(r)); else (l) = ((int)(r))
+
+#ifndef HEADLESS
+static XRGlyphCacheInfo* grayCache = NULL;
+static XRGlyphCacheInfo* lcdCache = NULL;
+#endif
+
+JNIEXPORT void JNICALL
+XRT_DrawGlyphList(JNIEnv *env, jobject xtr,
+                 jlong dstData, jint numGlyphs, jboolean subPixPos, jboolean rgbOrder, jint lcdContrast,
+                 jboolean usePositions, jfloat xOrigin, jfloat yOrigin, jlong *images, jfloat *positions)
+{
+#ifndef HEADLESS
+  J2dTraceLn(J2D_TRACE_INFO, "XRTextRenderer_md: XRT_DrawGlyphList");
+
+  jint i;
+  jboolean grayscale = JNI_TRUE;
+
+  X11SDOps *xsdo = (X11SDOps *)jlong_to_ptr(dstData);
+  if (xsdo == NULL) {  
+      J2dTraceLn(J2D_TRACE_INFO, "XRTextRenderer_md: Destination-Pointer null!");
+      return;
+    }
+
+  if (numGlyphs > 0) {
+      GlyphInfo *ginfo = (GlyphInfo *)jlong_to_ptr(images[0]);
+      grayscale = (ginfo->rowBytes == ginfo->width);
+      subPixPos = subPixPos && (!grayscale);
+  }
+
+  if(grayCache == NULL && grayscale == JNI_TRUE) {
+    grayCache = XRGlyphCache_Init(XRenderFindStandardFormat(awt_display, PictStandardA8));
+  }else
+  if(lcdCache == NULL && grayscale == JNI_FALSE) {
+    lcdCache = XRGlyphCache_Init(XRenderFindStandardFormat(awt_display, PictStandardARGB32));
+  }
+
+   int eltCnt = -1;
+   jint ids[numGlyphs]; 
+   XGlyphElt32 elts[numGlyphs];
+
+   float advX = xOrigin; //xOrigin;/*Contains all advance-corrections summed up*/
+   float advY = yOrigin; //yOrigin; 
+   int oldPosX = 0, oldPosY = 0; /*Stored to be able to caluclate integer-advance to last glyph*/
+
+   if(subPixPos == JNI_TRUE) {
+     advX += 0.1666667f;
+     advY += 0.1666667f;
+   }else {
+     advX += 0.5f;
+     advY += 0.5f;
+  }
+
+   XRGlyphCacheInfo *glyphCache = (grayscale == JNI_TRUE) ?  grayCache : lcdCache;
+   jboolean cacheResult = XRGlyphCache_CacheGlyphs(glyphCache, images, numGlyphs, &ids[0]);
+   if(cacheResult == JNI_FALSE){
+      J2dTraceLn(J2D_TRACE_INFO, "XRTextRenderer_md: Glyph caching failed");
+      return;
+   }
+
+   for(i=0; i < numGlyphs; i++)
+   {
+      GlyphInfo *jginfo = (GlyphInfo *)jlong_to_ptr(images[i]);
+      XRCacheCellInfo *cellInfo = (XRCacheCellInfo *) jginfo->cellInfo;
+
+	/** If the cached and the required relative position is equal (implies integer value), we can reuse
+	 *  the existing ELT, and let XRender do the positioning.
+	 *  If it does not match the positioning information stored on the server, create a new ELT.
+	 *  advX/Y and posX/Y contain all advance-corrections summed up, so that we don't forget rounding errors happend in the past.
+         *  The actual advance is computed from the difference to the last integer-correction-position.
+         *  TODO: Spaeter mit cache vergleichen, statt einfach mit X-Werten
+	 */
+	int posX = 0, posY = 0;
+	if(usePositions || (jginfo->advanceX != ((float)cellInfo->xOff) || jginfo->advanceY != ((float)cellInfo->yOff)) || eltCnt == -1) 
+        {
+          /*Setup the next elt*/
+	  eltCnt++; 
+	  elts[eltCnt].glyphset = glyphCache->glyphSet;
+          elts[eltCnt].chars = (unsigned int*) &ids[i];
+	  elts[eltCnt].nchars = 1;
+
+  	  if(usePositions)
+	  {
+            /*In this case advX only stores rounding errors*/
+            jfloat x = positions[i*2] + advX;
+            jfloat y = positions[i*2 + 1] + advY;
+            FLOOR_ASSIGN(posX, x);
+            FLOOR_ASSIGN(posY, y);
+ 	    advX -= cellInfo->xOff;
+ 	    advY -= cellInfo->yOff;
+          }else
+          {
+	    /* 
+             * Calculate next glyph's position in the case of relative positioning.
+             * In XRender we can only position glyphs using integer coordinates, therefor
+             * we sum all the advances up as float, and convert them to integer later.
+             * This way rounding-error can be corrected,
+             * and is required to be consistent with the software loops.
+             */
+             FLOOR_ASSIGN(posX, advX);
+             FLOOR_ASSIGN(posY, advY);
+             //Advance of ELT = difference between stored relative positioning information and required float.
+	     advX += (jginfo->advanceX - cellInfo->xOff);
+	     advY += (jginfo->advanceY - cellInfo->yOff);
+          }
+
+            /*Offset of the current glyph is the difference to the last glyph and this one*/
+	    elts[eltCnt].xOff = (posX - oldPosX);
+	    elts[eltCnt].yOff = (posY - oldPosY);
+
+	    oldPosX = posX;
+	    oldPosY = posY;
+	}else
+	{
+           elts[eltCnt].nchars++;
+	}
+   }
+
+  /*TODO: Also integrate into MaskBuffer??*/
+  XRenderCompositeText32(awt_display, PictOpOver, xrSrcData.src, xsdo->xrPic, None, 0, 0, 0, 0, &elts[0], eltCnt+1);
+#endif
+}
+