changeset 1229:0da756c744c9

Add Xrender pipeline support. 2008-11-29 Mark Wielaard <mark@klomp.org> * configure.ac: Add and check --enable-xrender. * Makefile.am: Add XRENDER_PATCHES when ENABLE_XRENDER set. * patches/icedtea-xrender-00[0-8].patch: New patches. * HACKING: Document new patches.
author Mark Wielaard <mark@klomp.org>
date Sun, 30 Nov 2008 11:58:42 +0100
parents 8ce80b4e9a73
children 4924c505eff0
files ChangeLog HACKING Makefile.am configure.ac patches/icedtea-xrender-000.patch patches/icedtea-xrender-001.patch patches/icedtea-xrender-002.patch patches/icedtea-xrender-003.patch patches/icedtea-xrender-004.patch patches/icedtea-xrender-005.patch patches/icedtea-xrender-006.patch patches/icedtea-xrender-007.patch patches/icedtea-xrender-008.patch
diffstat 13 files changed, 12735 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri Nov 28 10:44:51 2008 -0500
+++ b/ChangeLog	Sun Nov 30 11:58:42 2008 +0100
@@ -1,3 +1,10 @@
+2008-11-29  Mark Wielaard  <mark@klomp.org>
+
+	* configure.ac: Add and check --enable-xrender.
+	* Makefile.am: Add XRENDER_PATCHES when ENABLE_XRENDER set.
+	* patches/icedtea-xrender-00[0-8].patch: New patches.
+	* HACKING: Document new patches.
+
 2008-11-28  Gary Benson  <gbenson@redhat.com>
 
 	PR icedtea/265:
--- a/HACKING	Fri Nov 28 10:44:51 2008 -0500
+++ b/HACKING	Sun Nov 30 11:58:42 2008 +0100
@@ -132,6 +132,11 @@
 
 * icedtea-cacao.patch: Don't run 'java' in a new thread.
 
+The following patches are to support Xrender pipeline (-Dsun.java2d.xrender):
+
+* icedtea-xrender-xxx.patch: Numbered patches from xrender branch
+  http://hg.openjdk.java.net/xrender/xrender/jdk
+
 Obsolete Patches
 ================
 
--- a/Makefile.am	Fri Nov 28 10:44:51 2008 -0500
+++ b/Makefile.am	Sun Nov 30 11:58:42 2008 +0100
@@ -561,6 +561,11 @@
 	patches/icedtea-pulse-soundproperties.patch
 endif
 
+if ENABLE_XRENDER
+XRENDER_PATCHES = patches/icedtea-xrender-???.patch
+ICEDTEA_PATCHES += $(sort $(wildcard $(XRENDER_PATCHES)))
+endif
+
 ICEDTEA_PATCHES += \
 	$(DISTRIBUTION_PATCHES)
 
--- a/configure.ac	Fri Nov 28 10:44:51 2008 -0500
+++ b/configure.ac	Sun Nov 30 11:58:42 2008 +0100
@@ -159,6 +159,14 @@
 AM_CONDITIONAL([ENABLE_DOCS], [test x$ENABLE_DOCS = xyes])
 AC_MSG_RESULT(${ENABLE_DOCS})
 
+AC_MSG_CHECKING(whether to include xrender pipeline)
+AC_ARG_ENABLE([xrender],
+	      [AS_HELP_STRING([--disable-xrender],
+	      		      [Disable inclusion of xrender pipeline])],
+	      [ENABLE_XRENDER="${enableval}"], [ENABLE_XRENDER='yes'])
+AM_CONDITIONAL([ENABLE_XRENDER], [test x$ENABLE_XRENDER = xyes])
+AC_MSG_RESULT(${ENABLE_XRENDER})
+
 AC_MSG_CHECKING(whether to build VisualVM)
 AC_ARG_ENABLE([visualvm],
               [AS_HELP_STRING([--enable-visualvm],
@@ -374,6 +382,16 @@
 AC_SUBST(XINERAMA_CFLAGS)
 AC_SUBST(XINERAMA_LIBS)
 
+if test "x${ENABLE_XRENDER}" = "xyes"
+then
+  PKG_CHECK_MODULES(XRENDER, xrender, [XRENDER_FOUND=yes], [XRENDER_FOUND=no])
+  if test "x${XRENDER_FOUND}" = xno
+  then
+    AC_MSG_ERROR([Could not find Xrender extension - \
+Try installing libXrender-devel or configure --disable-xrender.])
+  fi
+fi
+
 dnl Check for libpng headers and libraries.
 PKG_CHECK_MODULES(LIBPNG, libpng,[LIBPNG_FOUND=yes]
 	,[LIBPNG_FOUND=no])
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/icedtea-xrender-000.patch	Sun Nov 30 11:58:42 2008 +0100
@@ -0,0 +1,430 @@
+6675596: SurfaceManagerFactory should allow plugging in different implementations
+Reviewed-by: tdv, campbell
+Contributed-by: Roman Kennke <roman.kennke@aicas.com>
+
+diff -r ed68352f7e42 -r 4af4867ed787 src/share/classes/sun/awt/image/SunVolatileImage.java
+--- openjdk/jdk/src/share/classes/sun/awt/image/SunVolatileImage.java	Wed May 14 09:16:18 2008 -0700
++++ openjdk/jdk/src/share/classes/sun/awt/image/SunVolatileImage.java	Wed May 14 16:05:07 2008 -0700
+@@ -165,7 +165,8 @@
+         {
+             return new BufImgVolatileSurfaceManager(this, context);
+         }
+-        return SurfaceManagerFactory.createVolatileManager(this, context);
++        SurfaceManagerFactory smf = SurfaceManagerFactory.getInstance();
++        return smf.createVolatileManager(this, context);
+     }
+ 
+     private Color getForeground() {
+diff -r ed68352f7e42 -r 4af4867ed787 src/share/classes/sun/java2d/SurfaceManagerFactory.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/share/classes/sun/java2d/SurfaceManagerFactory.java	Wed May 14 16:05:07 2008 -0700
+@@ -0,0 +1,91 @@
++/*
++ * Copyright 2003-2008 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;
++
++import sun.awt.image.SunVolatileImage;
++import sun.awt.image.VolatileSurfaceManager;
++
++/**
++ * This factory creates platform specific VolatileSurfaceManager
++ * implementations.
++ *
++ * There are two platform specific SurfaceManagerFactories in OpenJDK,
++ * UnixSurfaceManagerFactory and WindowsSurfaceManagerFactory.
++ * The actually used SurfaceManagerFactory is set by the respective platform
++ * GraphicsEnvironment implementations in the static initializer.
++ */
++public abstract class SurfaceManagerFactory {
++
++    /**
++     * The single shared instance.
++     */
++    private static SurfaceManagerFactory instance;
++
++    /**
++     * Returns the surface manager factory instance. This returns a factory
++     * that has been set by {@link #setInstance(SurfaceManagerFactory)}.
++     *
++     * @return the surface manager factory
++     */
++    public synchronized static SurfaceManagerFactory getInstance() {
++
++        if (instance == null) {
++            throw new IllegalStateException("No SurfaceManagerFactory set.");
++        }
++        return instance;
++    }
++
++    /**
++     * Sets the surface manager factory. This may only be called once, and it
++     * may not be set back to {@code null} when the factory is already
++     * instantiated.
++     *
++     * @param factory the factory to set
++     */
++    public synchronized static void setInstance(SurfaceManagerFactory factory) {
++
++        if (factory == null) {
++            // We don't want to allow setting this to null at any time.
++            throw new IllegalArgumentException("factory must be non-null");
++        }
++
++        if (instance != null) {
++            // We don't want to re-set the instance at any time.
++            throw new IllegalStateException("The surface manager factory is already initialized");
++        }
++
++        instance = factory;
++    }
++
++    /**
++     * Creates a new instance of a VolatileSurfaceManager given any
++     * arbitrary SunVolatileImage.  An optional context Object can be supplied
++     * as a way for the caller to pass pipeline-specific context data to
++     * the VolatileSurfaceManager (such as a backbuffer handle, for example).
++     */
++     public abstract VolatileSurfaceManager
++         createVolatileManager(SunVolatileImage image, Object context);
++}
+diff -r ed68352f7e42 -r 4af4867ed787 src/solaris/classes/sun/awt/X11GraphicsEnvironment.java
+--- openjdk/jdk/src/solaris/classes/sun/awt/X11GraphicsEnvironment.java	Wed May 14 09:16:18 2008 -0700
++++ openjdk/jdk/src/solaris/classes/sun/awt/X11GraphicsEnvironment.java	Wed May 14 16:05:07 2008 -0700
+@@ -48,6 +48,8 @@
+ import sun.font.FontManager;
+ import sun.font.NativeFont;
+ import sun.java2d.SunGraphicsEnvironment;
++import sun.java2d.SurfaceManagerFactory;
++import sun.java2d.UnixSurfaceManagerFactory;
+ 
+ /**
+  * This is an implementation of a GraphicsEnvironment object for the
+@@ -177,6 +179,10 @@
+                 return null;
+             }
+          });
++
++        // Install the correct surface manager factory.
++        SurfaceManagerFactory.setInstance(new UnixSurfaceManagerFactory());
++
+     }
+ 
+     private static boolean glxAvailable;
+diff -r ed68352f7e42 -r 4af4867ed787 src/solaris/classes/sun/java2d/SurfaceManagerFactory.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/SurfaceManagerFactory.java	Wed May 14 09:16:18 2008 -0700
++++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
+@@ -1,65 +0,0 @@
+-/*
+- * Copyright 2003-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;
+-
+-import java.awt.GraphicsConfiguration;
+-import java.awt.image.BufferedImage;
+-import sun.awt.X11GraphicsConfig;
+-import sun.awt.image.SunVolatileImage;
+-import sun.awt.image.SurfaceManager;
+-import sun.awt.image.VolatileSurfaceManager;
+-import sun.java2d.opengl.GLXGraphicsConfig;
+-import sun.java2d.opengl.GLXVolatileSurfaceManager;
+-import sun.java2d.x11.X11VolatileSurfaceManager;
+-
+-/**
+- * This is a factory class with static methods for creating a
+- * platform-specific instance of a particular SurfaceManager.  Each platform
+- * (Windows, Unix, etc.) has its own specialized SurfaceManagerFactory.
+- */
+-public class SurfaceManagerFactory {
+-    /**
+-     * Creates a new instance of a VolatileSurfaceManager given any
+-     * arbitrary SunVolatileImage.  An optional context Object can be supplied
+-     * as a way for the caller to pass pipeline-specific context data to
+-     * the VolatileSurfaceManager (such as a backbuffer handle, for example).
+-     *
+-     * For Unix platforms, this method returns either an X11- or a GLX-
+-     * specific VolatileSurfaceManager based on the GraphicsConfiguration
+-     * under which the SunVolatileImage was created.
+-     */
+-    public static VolatileSurfaceManager
+-        createVolatileManager(SunVolatileImage vImg,
+-                              Object context)
+-    {
+-        GraphicsConfiguration gc = vImg.getGraphicsConfig();
+-        if (gc instanceof GLXGraphicsConfig) {
+-            return new GLXVolatileSurfaceManager(vImg, context);
+-        } else {
+-            return new X11VolatileSurfaceManager(vImg, context);
+-        }
+-    }
+-}
+diff -r ed68352f7e42 -r 4af4867ed787 src/solaris/classes/sun/java2d/UnixSurfaceManagerFactory.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/classes/sun/java2d/UnixSurfaceManagerFactory.java	Wed May 14 16:05:07 2008 -0700
+@@ -0,0 +1,64 @@
++/*
++ * Copyright 2003-2008 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;
++
++import java.awt.GraphicsConfiguration;
++
++import sun.awt.image.SunVolatileImage;
++import sun.awt.image.VolatileSurfaceManager;
++import sun.java2d.opengl.GLXGraphicsConfig;
++import sun.java2d.opengl.GLXVolatileSurfaceManager;
++import sun.java2d.x11.X11VolatileSurfaceManager;
++
++/**
++ * The SurfaceManagerFactory that creates VolatileSurfaceManager
++ * implementations for the Unix volatile images.
++ */
++public class UnixSurfaceManagerFactory extends SurfaceManagerFactory {
++
++    /**
++     * Creates a new instance of a VolatileSurfaceManager given any
++     * arbitrary SunVolatileImage.  An optional context Object can be supplied
++     * as a way for the caller to pass pipeline-specific context data to
++     * the VolatileSurfaceManager (such as a backbuffer handle, for example).
++     *
++     * For Unix platforms, this method returns either an X11- or a GLX-
++     * specific VolatileSurfaceManager based on the GraphicsConfiguration
++     * under which the SunVolatileImage was created.
++     */
++    public VolatileSurfaceManager createVolatileManager(SunVolatileImage vImg,
++                                                        Object context)
++    {
++        GraphicsConfiguration gc = vImg.getGraphicsConfig();
++        if (gc instanceof GLXGraphicsConfig) {
++            return new GLXVolatileSurfaceManager(vImg, context);
++        } else {
++            return new X11VolatileSurfaceManager(vImg, context);
++        }
++    }
++
++}
+diff -r ed68352f7e42 -r 4af4867ed787 src/windows/classes/sun/awt/Win32GraphicsEnvironment.java
+--- openjdk/jdk/src/windows/classes/sun/awt/Win32GraphicsEnvironment.java	Wed May 14 09:16:18 2008 -0700
++++ openjdk/jdk/src/windows/classes/sun/awt/Win32GraphicsEnvironment.java	Wed May 14 16:05:07 2008 -0700
+@@ -42,6 +42,8 @@
+ import sun.awt.windows.WToolkit;
+ import sun.font.FontManager;
+ import sun.java2d.SunGraphicsEnvironment;
++import sun.java2d.SurfaceManagerFactory;
++import sun.java2d.WindowsSurfaceManagerFactory;
+ import sun.java2d.windows.WindowsFlags;
+ 
+ /**
+@@ -64,6 +66,9 @@
+         WindowsFlags.initFlags();
+         initDisplayWrapper();
+         eudcFontFileName = getEUDCFontFile();
++
++        // Install correct surface manager factory.
++        SurfaceManagerFactory.setInstance(new WindowsSurfaceManagerFactory());
+     }
+ 
+     /**
+diff -r ed68352f7e42 -r 4af4867ed787 src/windows/classes/sun/java2d/SurfaceManagerFactory.java
+--- openjdk/jdk/src/windows/classes/sun/java2d/SurfaceManagerFactory.java	Wed May 14 09:16:18 2008 -0700
++++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
+@@ -1,64 +0,0 @@
+-/*
+- * Copyright 2003-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;
+-
+-import java.awt.GraphicsConfiguration;
+-import java.awt.image.BufferedImage;
+-import sun.awt.image.SunVolatileImage;
+-import sun.awt.image.SurfaceManager;
+-import sun.awt.image.VolatileSurfaceManager;
+-import sun.java2d.opengl.WGLGraphicsConfig;
+-import sun.java2d.opengl.WGLVolatileSurfaceManager;
+-import sun.java2d.windows.WindowsFlags;
+-import sun.java2d.windows.WinVolatileSurfaceManager;
+-
+-/**
+- * This is a factory class with static methods for creating a
+- * platform-specific instance of a particular SurfaceManager.  Each platform
+- * (Windows, Unix, etc.) has its own specialized SurfaceManagerFactory.
+- */
+-public class SurfaceManagerFactory {
+-    /**
+-     * Creates a new instance of a VolatileSurfaceManager given any
+-     * arbitrary SunVolatileImage.  An optional context Object can be supplied
+-     * as a way for the caller to pass pipeline-specific context data to
+-     * the VolatileSurfaceManager (such as a backbuffer handle, for example).
+-     *
+-     * For Windows platforms, this method returns a Windows-specific
+-     * VolatileSurfaceManager.
+-     */
+-    public static VolatileSurfaceManager
+-        createVolatileManager(SunVolatileImage vImg,
+-                              Object context)
+-    {
+-        GraphicsConfiguration gc = vImg.getGraphicsConfig();
+-        if (gc instanceof WGLGraphicsConfig) {
+-            return new WGLVolatileSurfaceManager(vImg, context);
+-        } else {
+-            return new WinVolatileSurfaceManager(vImg, context);
+-        }
+-    }
+-}
+diff -r ed68352f7e42 -r 4af4867ed787 src/windows/classes/sun/java2d/WindowsSurfaceManagerFactory.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/windows/classes/sun/java2d/WindowsSurfaceManagerFactory.java	Wed May 14 16:05:07 2008 -0700
+@@ -0,0 +1,64 @@
++/*
++ * Copyright 2003-2008 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;
++
++import java.awt.GraphicsConfiguration;
++import java.awt.image.BufferedImage;
++import sun.awt.image.SunVolatileImage;
++import sun.awt.image.SurfaceManager;
++import sun.awt.image.VolatileSurfaceManager;
++import sun.java2d.opengl.WGLGraphicsConfig;
++import sun.java2d.opengl.WGLVolatileSurfaceManager;
++import sun.java2d.windows.WindowsFlags;
++import sun.java2d.windows.WinVolatileSurfaceManager;
++
++/**
++ * The SurfaceManagerFactory that creates VolatileSurfaceManager
++ * implementations for the Windows volatile images.
++ */
++public class WindowsSurfaceManagerFactory extends SurfaceManagerFactory {
++
++    /**
++     * Creates a new instance of a VolatileSurfaceManager given any
++     * arbitrary SunVolatileImage.  An optional context Object can be supplied
++     * as a way for the caller to pass pipeline-specific context data to
++     * the VolatileSurfaceManager (such as a backbuffer handle, for example).
++     *
++     * For Windows platforms, this method returns a Windows-specific
++     * VolatileSurfaceManager.
++     */
++    public VolatileSurfaceManager createVolatileManager(SunVolatileImage vImg,
++                                                        Object context)
++    {
++        GraphicsConfiguration gc = vImg.getGraphicsConfig();
++        if (gc instanceof WGLGraphicsConfig) {
++            return new WGLVolatileSurfaceManager(vImg, context);
++        } else {
++            return new WinVolatileSurfaceManager(vImg, context);
++        }
++    }
++
++}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/icedtea-xrender-001.patch	Sun Nov 30 11:58:42 2008 +0100
@@ -0,0 +1,5320 @@
+changeset:   6d294fa2bd42
+user:        ceisserer
+date:        Sat Jul 26 00:13:41 2008 +0200
+summary:     summary: initial implementation of the X render pipeline
+
+diff -r dc592ff5af5e jdk/make/sun/font/FILES_c.gmk
+--- openjdk/jdk/make/sun/font/FILES_c.gmk	Fri Nov 28 22:59:23 2008 +0100
++++ openjdk/jdk/make/sun/font/FILES_c.gmk	Sat Nov 29 19:56:09 2008 +0100
+@@ -117,6 +117,7 @@
+ FILES_cpp_platform = D3DTextRenderer.cpp
+ else
+ FILES_c_platform = X11FontScaler.c \
++                   XRTextRenderer.c \
+                    X11TextRenderer.c
+ FILES_cpp_platform =
+ endif
+diff -r dc592ff5af5e jdk/make/sun/font/Makefile
+--- openjdk/jdk/make/sun/font/Makefile	Fri Nov 28 22:59:23 2008 +0100
++++ openjdk/jdk/make/sun/font/Makefile	Sat Nov 29 19:56:09 2008 +0100
+@@ -92,6 +92,7 @@
+     sun/font/NativeStrike.java \
+     sun/font/NativeStrikeDisposer.java \
+     sun/font/X11TextRenderer.java \
++    sun/font/XRTextRenderer.java \
+     sun/awt/X11GraphicsEnvironment.java 
+ 
+ endif # PLATFORM
+diff -r dc592ff5af5e jdk/make/sun/font/mapfile-vers
+--- openjdk/jdk/make/sun/font/mapfile-vers	Fri Nov 28 22:59:23 2008 +0100
++++ openjdk/jdk/make/sun/font/mapfile-vers	Sat Nov 29 19:56:09 2008 +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 -r dc592ff5af5e jdk/make/sun/font/mapfile-vers.openjdk
+--- openjdk/jdk/make/sun/font/mapfile-vers.openjdk	Fri Nov 28 22:59:23 2008 +0100
++++ openjdk/jdk/make/sun/font/mapfile-vers.openjdk	Sat Nov 29 19:56:09 2008 +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 -r dc592ff5af5e jdk/make/sun/xawt/FILES_c_unix.gmk
+--- openjdk/jdk/make/sun/xawt/FILES_c_unix.gmk	Fri Nov 28 22:59:23 2008 +0100
++++ openjdk/jdk/make/sun/xawt/FILES_c_unix.gmk	Sat Nov 29 19:56:09 2008 +0100
+@@ -77,5 +77,12 @@
+ 	debug_util.c \
+ 	awt_Plugin.c \
+ 	gtk2_interface.c \
+-        swing_GTKEngine.c \
+-        swing_GTKStyle.c
++	swing_GTKEngine.c \
++	swing_GTKStyle.c \
++	ArrayList.c \
++	MaskBuffer.c \
++	XRSurfaceData.c \
++	XRGlyphCache.c \
++	XRTextRenderer_md.c \
++        XRRenderer.c \
++        XRPMBlitLoops.c
+diff -r dc592ff5af5e jdk/make/sun/xawt/Makefile
+--- openjdk/jdk/make/sun/xawt/Makefile	Fri Nov 28 22:59:23 2008 +0100
++++ openjdk/jdk/make/sun/xawt/Makefile	Sat Nov 29 19:56:09 2008 +0100
+@@ -86,7 +86,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 -r dc592ff5af5e jdk/make/sun/xawt/mapfile-vers
+--- openjdk/jdk/make/sun/xawt/mapfile-vers	Fri Nov 28 22:59:23 2008 +0100
++++ openjdk/jdk/make/sun/xawt/mapfile-vers	Sat Nov 29 19:56:09 2008 +0100
+@@ -346,6 +346,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 -r dc592ff5af5e jdk/src/share/classes/sun/java2d/pipe/BufferedPaints.java
+--- openjdk/jdk/src/share/classes/sun/java2d/pipe/BufferedPaints.java	Fri Nov 28 22:59:23 2008 +0100
++++ openjdk/jdk/src/share/classes/sun/java2d/pipe/BufferedPaints.java	Sat Nov 29 19:56:09 2008 +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 -r dc592ff5af5e jdk/src/solaris/classes/sun/awt/X11GraphicsDevice.java
+--- openjdk/jdk/src/solaris/classes/sun/awt/X11GraphicsDevice.java	Fri Nov 28 22:59:23 2008 +0100
++++ openjdk/jdk/src/solaris/classes/sun/awt/X11GraphicsDevice.java	Sat Nov 29 19:56:09 2008 +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();
+@@ -164,10 +167,19 @@
+                 if (ret[i] == null) {
+                     boolean doubleBuffer =
+                         (dbeSupported &&
+-                         doubleBufferVisuals.contains(new Integer(visNum)));
+-                    ret[i] = X11GraphicsConfig.getConfig(this, visNum, depth,
+-                            getConfigColormap(i, screen),
+-                            doubleBuffer);
++                         doubleBufferVisuals.contains(Integer.valueOf(visNum)));
++                    
++                    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(new Integer(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 -r dc592ff5af5e jdk/src/solaris/classes/sun/awt/X11GraphicsEnvironment.java
+--- openjdk/jdk/src/solaris/classes/sun/awt/X11GraphicsEnvironment.java	Fri Nov 28 22:59:23 2008 +0100
++++ openjdk/jdk/src/solaris/classes/sun/awt/X11GraphicsEnvironment.java	Sat Nov 29 19:56:09 2008 +0100
+@@ -47,9 +47,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
+@@ -174,19 +174,43 @@
+                                 "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();
++                        }
+                 }
+-
++               
++   
+                 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();
+ 
+@@ -196,6 +220,15 @@
+ 
+     public static boolean isGLXVerbose() {
+         return glxVerbose;
++    }
++    
++    /*CE*/
++    public static boolean isXRenderAvailable() {
++        return xRenderAvailable;
++    }
++
++    public static boolean isXRenderVerbose() {
++        return xRenderVerbose;
+     }
+ 
+     /**
+@@ -1070,4 +1103,14 @@
+     @Override
+     public void paletteChanged() {
+     }
++
++	public static boolean isX11SurfaceDataInitialized()
++	{
++		return isX11SurfaceDataInitialized;
++	}
++
++	public static void setX11SurfaceDataInitialized()
++	{
++		X11GraphicsEnvironment.isX11SurfaceDataInitialized = true;
++	}
+ }
+diff -r dc592ff5af5e jdk/src/solaris/classes/sun/font/XRTextRenderer.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/classes/sun/font/XRTextRenderer.java	Sat Nov 29 19:56:09 2008 +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 -r dc592ff5af5e jdk/src/solaris/classes/sun/java2d/UnixSurfaceManagerFactory.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/UnixSurfaceManagerFactory.java	Fri Nov 28 22:59:23 2008 +0100
++++ openjdk/jdk/src/solaris/classes/sun/java2d/UnixSurfaceManagerFactory.java	Sat Nov 29 19:56:09 2008 +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 -r dc592ff5af5e jdk/src/solaris/classes/sun/java2d/x11/X11SurfaceData.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/x11/X11SurfaceData.java	Fri Nov 28 22:59:23 2008 +0100
++++ openjdk/jdk/src/solaris/classes/sun/java2d/x11/X11SurfaceData.java	Sat Nov 29 19:56:09 2008 +0100
+@@ -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;
+@@ -70,7 +67,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();
+@@ -198,7 +195,10 @@
+     protected static TextPipe x11textpipe;
+     protected static boolean dgaAvailable;
+ 
+-    static {
++    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
+@@ -232,9 +232,12 @@
+                 X11PMBlitLoops.register();
+                 X11PMBlitBgLoops.register();
+             }
+-        }
++            
++            X11GraphicsEnvironment.setX11SurfaceDataInitialized();
++        }    	
++    	}
+     }
+-
++    
+     /**
+      * Returns true if we can use DGA on any of the screens
+      */
+@@ -616,7 +619,7 @@
+     {
+         // assert SunToolkit.isAWTLockHeldByCurrentThread();
+ 
+-        if (!isValid()) {
++    	if (!isValid()) {
+             throw new InvalidPipeException("bounds changed");
+         }
+ 
+diff -r dc592ff5af5e jdk/src/solaris/classes/sun/java2d/xr/XRDrawImage.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRDrawImage.java	Sat Nov 29 19:56:09 2008 +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 -r dc592ff5af5e jdk/src/solaris/classes/sun/java2d/xr/XRGraphicsConfig.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRGraphicsConfig.java	Sat Nov 29 19:56:09 2008 +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 -r dc592ff5af5e jdk/src/solaris/classes/sun/java2d/xr/XRMaskBlit.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRMaskBlit.java	Sat Nov 29 19:56:09 2008 +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 -r dc592ff5af5e jdk/src/solaris/classes/sun/java2d/xr/XRMaskFill.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRMaskFill.java	Sat Nov 29 19:56:09 2008 +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 -r dc592ff5af5e jdk/src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java	Sat Nov 29 19:56:09 2008 +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 -r dc592ff5af5e jdk/src/solaris/classes/sun/java2d/xr/XRRenderer.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRRenderer.java	Sat Nov 29 19:56:09 2008 +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 -r dc592ff5af5e jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceData.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceData.java	Sat Nov 29 19:56:09 2008 +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 -r dc592ff5af5e jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceDataProxy.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceDataProxy.java	Sat Nov 29 19:56:09 2008 +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 -r dc592ff5af5e jdk/src/solaris/classes/sun/java2d/xr/XRUtils.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRUtils.java	Sat Nov 29 19:56:09 2008 +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 -r dc592ff5af5e jdk/src/solaris/classes/sun/java2d/xr/XRVolatileSurfaceManager.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRVolatileSurfaceManager.java	Sat Nov 29 19:56:09 2008 +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 -r dc592ff5af5e jdk/src/solaris/native/sun/font/XRTextRenderer.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/native/sun/font/XRTextRenderer.c	Sat Nov 29 19:56:09 2008 +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 -r dc592ff5af5e jdk/src/solaris/native/sun/java2d/x11/ArrayList.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/ArrayList.c	Sat Nov 29 19:56:09 2008 +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 -r dc592ff5af5e jdk/src/solaris/native/sun/java2d/x11/ArrayList.h
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/ArrayList.h	Sat Nov 29 19:56:09 2008 +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 -r dc592ff5af5e jdk/src/solaris/native/sun/java2d/x11/MaskBuffer.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/MaskBuffer.c	Sat Nov 29 19:56:09 2008 +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 -r dc592ff5af5e jdk/src/solaris/native/sun/java2d/x11/MaskBuffer.h
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/MaskBuffer.h	Sat Nov 29 19:56:09 2008 +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 -r dc592ff5af5e jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.c
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.c	Fri Nov 28 22:59:23 2008 +0100
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.c	Sat Nov 29 19:56:09 2008 +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,6 +97,49 @@
+ 
+ #endif /* !HEADLESS */
+ 
++jboolean XShared_initIDs(JNIEnv *env)
++{
++#ifndef HEADLESS
++   union {
++        char c[4];
++        int i;
++    } endian;
++
++    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 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
+@@ -107,22 +150,9 @@
+                                            jclass XORComp, jboolean tryDGA)
+ {
+ #ifndef HEADLESS
++  if(XShared_initIDs(env))
++  {
+     void *lib = 0;
+-
+-    union {
+-        char c[4];
+-        int i;
+-    } endian;
+-
+-    endian.i = 0xff000000;
+-    nativeByteOrder = (endian.c[0]) ? MSBFirst : LSBFirst;
+-
+-    cachedXImage = NULL;
+-
+-    if (sizeof(X11RIPrivate) > SD_RASINFO_PRIVATE_SIZE) {
+-        JNU_ThrowInternalError(env, "Private RasInfo structure too large!");
+-        return;
+-    }
+ 
+     xorCompClass = (*env)->NewGlobalRef(env, XORComp);
+ 
+@@ -130,7 +160,7 @@
+     /* 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 */
+ }
+ 
+@@ -286,6 +299,8 @@
+     } else {
+         xsdo->pixelmask = 0xff;
+     }
++
++    xsdo->xrPic = None;
+ #endif /* !HEADLESS */
+ }
+ 
+@@ -366,6 +381,10 @@
+         XFreeGC(awt_display, xsdo->cachedGC);
+         xsdo->cachedGC = NULL;
+     }
++    if(xsdo->xrPic != None) {
++      XRenderFreePicture(awt_display, xsdo->xrPic);
++    }
++
+     AWT_UNLOCK();
+ #endif /* !HEADLESS */
+ }
+@@ -385,6 +404,63 @@
+     }
+ #endif /* !HEADLESS */
+ }
++
++
++jboolean XShared_initSurface(JNIEnv *env, X11SDOps *xsdo, jint depth, jint width, jint height, jlong drawable)
++{
++#ifndef HEADLESS
++
++    if (drawable != (jlong)0) {
++        /* Double-buffering */
++        xsdo->drawable = drawable;
++        xsdo->isPixmap = JNI_FALSE;
++    } else {
++        xsdo->isPixmap = JNI_TRUE;
++        /* REMIND: workaround for bug 4420220 on pgx32 boards:
++           don't use DGA with pixmaps unless USE_DGA_PIXMAPS is set.
++         */
++        xsdo->dgaAvailable = useDGAWithPixmaps;
++
++        xsdo->pmWidth = width;
++        xsdo->pmHeight = height;
++
++#ifdef MITSHM
++        xsdo->shmPMData.pmSize = width * height * depth;
++        xsdo->shmPMData.pixelsReadThreshold = width * height / 8;
++        if (forceSharedPixmaps) {
++            AWT_LOCK();
++            xsdo->drawable = X11SD_CreateSharedPixmap(xsdo);
++            AWT_UNLOCK();
++            if (xsdo->drawable) {
++                xsdo->shmPMData.usingShmPixmap = JNI_TRUE;
++                xsdo->shmPMData.shmPixmap = xsdo->drawable;
++                return JNI_TRUE;
++            }
++        }
++#endif /* MITSHM */
++
++        AWT_LOCK();
++        xsdo->drawable =
++            XCreatePixmap(awt_display,
++                          RootWindow(awt_display,
++                                     xsdo->configData->awt_visInfo.screen),
++                          width, height, depth);
++        AWT_UNLOCK();
++#ifdef MITSHM
++        xsdo->shmPMData.usingShmPixmap = JNI_FALSE;
++        xsdo->shmPMData.pixmap = xsdo->drawable;
++#endif /* MITSHM */
++    }
++    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
+@@ -410,51 +486,8 @@
+        8-bit visuals */
+     xsdo->cData = xsdo->configData->color_data;
+ 
+-    if (drawable != (jlong)0) {
+-        /* Double-buffering */
+-        xsdo->drawable = drawable;
+-        xsdo->isPixmap = JNI_FALSE;
+-    } else {
+-        xsdo->isPixmap = JNI_TRUE;
+-        /* REMIND: workaround for bug 4420220 on pgx32 boards:
+-           don't use DGA with pixmaps unless USE_DGA_PIXMAPS is set.
+-         */
+-        xsdo->dgaAvailable = useDGAWithPixmaps;
+-
+-        xsdo->pmWidth = width;
+-        xsdo->pmHeight = height;
+-
+-#ifdef MITSHM
+-        xsdo->shmPMData.pmSize = width * height * depth;
+-        xsdo->shmPMData.pixelsReadThreshold = width * height / 8;
+-        if (forceSharedPixmaps) {
+-            AWT_LOCK();
+-            xsdo->drawable = X11SD_CreateSharedPixmap(xsdo);
+-            AWT_UNLOCK();
+-            if (xsdo->drawable) {
+-                xsdo->shmPMData.usingShmPixmap = JNI_TRUE;
+-                xsdo->shmPMData.shmPixmap = xsdo->drawable;
+-                return;
+-            }
+-        }
+-#endif /* MITSHM */
+-
+-        AWT_LOCK();
+-        xsdo->drawable =
+-            XCreatePixmap(awt_display,
+-                          RootWindow(awt_display,
+-                                     xsdo->configData->awt_visInfo.screen),
+-                          width, height, depth);
+-        AWT_UNLOCK();
+-#ifdef MITSHM
+-        xsdo->shmPMData.usingShmPixmap = JNI_FALSE;
+-        xsdo->shmPMData.pixmap = xsdo->drawable;
+-#endif /* MITSHM */
+-    }
+-    if (xsdo->drawable == 0) {
+-        JNU_ThrowOutOfMemoryError(env,
+-                                  "Can't create offscreen surface");
+-    }
++    XShared_initSurface(env, xsdo, depth, width, height, drawable);
++    xsdo->xrPic = NULL;
+ #endif /* !HEADLESS */
+ }
+ 
+@@ -700,7 +733,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 -r dc592ff5af5e jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.h
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.h	Fri Nov 28 22:59:23 2008 +0100
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.h	Sat Nov 29 19:56:09 2008 +0100
+@@ -29,6 +29,10 @@
+ #include "awt_GraphicsEnv.h"
+ 
+ #include <jdga.h>
++
++#include <X11/extensions/Xrender.h>
++#include "MaskBuffer.h"
++#include "XRSurfaceData.h"
+ 
+ /**
+  * This include file contains support declarations for loops using the
+@@ -87,6 +91,7 @@
+ } ShmPixmapData;
+ #endif /* MITSHM */
+ 
++
+ struct _X11SDOps {
+     SurfaceDataOps      sdOps;
+     GetPixmapBgFunc     *GetPixmapWithBg;
+@@ -109,6 +114,7 @@
+     jint                bgPixel;       /* bg pixel for the pixmap */
+     jint                pmWidth;       /* width, height of the */
+     jint                pmHeight;      /* pixmap */
++    Picture             xrPic;
+ #ifdef MITSHM
+     ShmPixmapData       shmPMData;     /* data for switching between shm/nonshm pixmaps*/
+ #endif /* MITSHM */
+@@ -155,3 +161,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 -r dc592ff5af5e jdk/src/solaris/native/sun/java2d/x11/XRGlyphCache.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRGlyphCache.c	Sat Nov 29 19:56:09 2008 +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 -r dc592ff5af5e jdk/src/solaris/native/sun/java2d/x11/XRGlyphCache.h
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRGlyphCache.h	Sat Nov 29 19:56:09 2008 +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 -r dc592ff5af5e jdk/src/solaris/native/sun/java2d/x11/XRPMBlitLoops.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRPMBlitLoops.c	Sat Nov 29 19:56:09 2008 +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 -r dc592ff5af5e jdk/src/solaris/native/sun/java2d/x11/XRRenderer.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRRenderer.c	Sat Nov 29 19:56:09 2008 +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 -r dc592ff5af5e jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.c	Sat Nov 29 19:56:09 2008 +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 -r dc592ff5af5e jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.h
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.h	Sat Nov 29 19:56:09 2008 +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 -r dc592ff5af5e jdk/src/solaris/native/sun/java2d/x11/XRTextRenderer_md.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRTextRenderer_md.c	Sat Nov 29 19:56:09 2008 +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
++}
++
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/icedtea-xrender-002.patch	Sun Nov 30 11:58:42 2008 +0100
@@ -0,0 +1,5199 @@
+# HG changeset patch
+# User ceisserer
+# Date 1217623431 -7200
+# Node ID 4b11af86e814b7d62e9e1e19788d527987bb209c
+# Parent  6d294fa2bd421e3c8978730855d7300af692b271
+Summary: Comments, bug fixes, initial solaris work
+
+diff -r 6d294fa2bd42 -r 4b11af86e814 make/sun/xawt/Makefile
+--- openjdk/jdk/make/sun/xawt/Makefile	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/make/sun/xawt/Makefile	Fri Aug 01 22:43:51 2008 +0200
+@@ -86,7 +86,7 @@
+ vpath %.c   $(PLATFORM_SRC)/native/sun/java2d/opengl
+ vpath %.c   $(PLATFORM_SRC)/native/sun/java2d/x11
+ 
+-OTHER_LDLIBS = $(LIBM) -lawt -lXext -lX11 -lXrender -ldl \
++OTHER_LDLIBS = $(LIBM) -lawt -lXext -lX11 -lXrender -ldl -lm \
+                    $(LDFLAGS_COMMON) $(AWT_RUNPATH) $(OTHER_LDFLAGS) -lXtst -lXi
+ 
+ ifeq  ($(PLATFORM), solaris)
+diff -r 6d294fa2bd42 -r 4b11af86e814 make/sun/xawt/mapfile-vers
+--- openjdk/jdk/make/sun/xawt/mapfile-vers	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/make/sun/xawt/mapfile-vers	Fri Aug 01 22:43:51 2008 +0200
+@@ -314,6 +314,15 @@
+         Java_sun_java2d_opengl_GLXSurfaceData_initOps;
+         Java_sun_java2d_opengl_GLXSurfaceData_initPbuffer;
+ 
++        Java_sun_java2d_x11_XSurfaceData_initOps;
++        Java_sun_java2d_x11_XSurfaceData_XCreateGC;
++        Java_sun_java2d_x11_XSurfaceData_XResetClip;
++        Java_sun_java2d_x11_XSurfaceData_XSetClip;
++        Java_sun_java2d_x11_XSurfaceData_flushNativeSurface;
++	Java_sun_java2d_x11_XSurfaceData_isDrawableValid;
++        Java_sun_java2d_x11_XSurfaceData_setInvalid;
++        Java_sun_java2d_x11_XSurfaceData_XSetGraphicsExposures;
++
+         Java_sun_java2d_x11_X11PMBlitBgLoops_nativeBlitBg;
+         Java_sun_java2d_x11_X11PMBlitLoops_nativeBlit;
+         Java_sun_java2d_x11_X11PMBlitLoops_updateBitmask;
+@@ -331,20 +340,12 @@
+ 	Java_sun_java2d_x11_X11Renderer_XFillRect;
+ 	Java_sun_java2d_x11_X11Renderer_XFillRoundRect;
+         Java_sun_java2d_x11_X11Renderer_devCopyArea;
+-        Java_sun_java2d_x11_X11SurfaceData_setInvalid;
+         Java_sun_java2d_x11_X11SurfaceData_initIDs;
+-	Java_sun_java2d_x11_X11SurfaceData_isDrawableValid;
+         Java_sun_java2d_x11_X11SurfaceData_isDgaAvailable;
+-        Java_sun_java2d_x11_X11SurfaceData_initOps;
+         Java_sun_java2d_x11_X11SurfaceData_initSurface;
+-        Java_sun_java2d_x11_X11SurfaceData_flushNativeSurface;
+-        Java_sun_java2d_x11_X11SurfaceData_XCreateGC;
+-        Java_sun_java2d_x11_X11SurfaceData_XResetClip;
+-        Java_sun_java2d_x11_X11SurfaceData_XSetClip;
+         Java_sun_java2d_x11_X11SurfaceData_XSetCopyMode;
+         Java_sun_java2d_x11_X11SurfaceData_XSetXorMode;
+         Java_sun_java2d_x11_X11SurfaceData_XSetForeground;
+-        Java_sun_java2d_x11_X11SurfaceData_XSetGraphicsExposures;
+ 
+         Java_sun_java2d_xr_XRSurfaceData_flushNativeSurface;
+         Java_sun_java2d_xr_XRSurfaceData_XRIsDrawableValid;
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/classes/sun/font/XRTextRenderer.java
+--- openjdk/jdk/src/solaris/classes/sun/font/XRTextRenderer.java	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/font/XRTextRenderer.java	Fri Aug 01 22:43:51 2008 +0200
+@@ -25,7 +25,7 @@
+ 
+ package sun.font;
+ 
+-import sun.awt.SunToolkit;
++import sun.awt.*;
+ import sun.java2d.SunGraphics2D;
+ import sun.java2d.pipe.GlyphListPipe;
+ import sun.java2d.xr.*;
+@@ -33,21 +33,22 @@
+ /**
+  * 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();
+-        }
+-    }
++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 -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/classes/sun/java2d/x11/X11SurfaceData.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/x11/X11SurfaceData.java	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/x11/X11SurfaceData.java	Fri Aug 01 22:43:51 2008 +0200
+@@ -60,7 +60,7 @@
+ import sun.java2d.pipe.TextPipe;
+ import sun.java2d.pipe.Region;
+ 
+-public abstract class X11SurfaceData extends SurfaceData {
++public abstract class X11SurfaceData extends XSurfaceData {
+     X11ComponentPeer peer;
+     X11GraphicsConfig graphicsConfig;
+     private RenderLoops solidloops;
+@@ -70,8 +70,6 @@
+     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();
+-    protected native void flushNativeSurface();
+ 
+     public static final String
+         DESC_INT_BGR_X11        = "Integer BGR Pixmap";
+@@ -405,12 +403,6 @@
+                                         cm, drawable, transparency);
+     }
+ 
+-    /**
+-     * Initializes the native Ops pointer.
+-     */
+-    private native void initOps(X11ComponentPeer peer,
+-                                X11GraphicsConfig gc, int depth);
+-
+     protected X11SurfaceData(X11ComponentPeer peer,
+                              X11GraphicsConfig gc,
+                              SurfaceType sType,
+@@ -568,8 +560,6 @@
+         return sType;
+     }
+ 
+-    public native void setInvalid();
+-
+     public void invalidate() {
+         if (isValid()) {
+             setInvalid();
+@@ -581,18 +571,10 @@
+      * 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 XResetClip(long xgc);
+-    private static native void XSetClip(long xgc,
+-                                        int lox, int loy, int hix, int hiy,
+-                                        Region complexclip);
++     */ 
+     private static native void XSetCopyMode(long xgc);
+     private static native void XSetXorMode(long xgc);
+     private static native void XSetForeground(long xgc, int pixel);
+-    private static native void XSetGraphicsExposures(long xgc,
+-                                                     boolean needExposures);
+ 
+     private long xgc;
+     private Region validatedClip;
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/classes/sun/java2d/x11/XSurfaceData.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/classes/sun/java2d/x11/XSurfaceData.java	Fri Aug 01 22:43:51 2008 +0200
+@@ -0,0 +1,35 @@
++package sun.java2d.x11;
++
++import java.awt.image.*;
++
++import sun.awt.*;
++import sun.java2d.*;
++import sun.java2d.loops.*;
++import sun.java2d.pipe.*;
++
++public abstract class XSurfaceData extends SurfaceData
++{
++	public XSurfaceData(SurfaceType surfaceType, ColorModel cm)
++	{
++		super(surfaceType, cm);
++	}
++	
++    protected native void initOps(X11ComponentPeer peer, X11GraphicsConfig gc, int depth);
++	
++    protected static native long XCreateGC(long pXSData);
++    
++    protected static native void XResetClip(long xgc);
++    
++    protected static native void XSetClip(long xgc,
++                                        int lox, int loy, int hix, int hiy,
++                                        Region complexclip);
++    
++    protected native void flushNativeSurface();
++    
++    protected native boolean isDrawableValid();
++    
++    protected native void setInvalid();
++    
++    protected static native void XSetGraphicsExposures(long xgc,
++            boolean needExposures);
++}
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/classes/sun/java2d/xr/XRDrawImage.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRDrawImage.java	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRDrawImage.java	Fri Aug 01 22:43:51 2008 +0200
+@@ -7,44 +7,36 @@
+ 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);
++	    AffineTransform tx, int interpType, int sx1, int sy1, int sx2,
++	    int sy2, Color bgColor) {
++	SurfaceData dstData = sg.surfaceData;
++	SurfaceData srcData = dstData.getSourceSurfaceData(img,
++		SunGraphics2D.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 (srcData != null && !isBgOperation(srcData, bgColor)
++		&& srcData instanceof XRSurfaceData) {
++	    SurfaceType srcType = srcData.getSurfaceType();
++	    SurfaceType dstType = dstData.getSurfaceType();
+ 
+-                if (blit != null) {
+-                    blit.Transform(srcData, dstData,
+-                                   sg.composite, sg.getCompClip(),
+-                                   tx, interpType,
+-                                   sx1, sy1, 0, 0, sx2-sx1, sy2-sy1);
+-                    return;
+-                }
+-       
+-        }
++	    ((XRSurfaceData) srcData).setPreferredInterpolation(XRUtils
++		    .ATransOpToXRQuality(interpType));
+ 
+-        super.renderImageXform(sg, img, tx, interpType,  sx1, sy1, sx2, sy2, bgColor);
++	    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 -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/classes/sun/java2d/xr/XRGraphicsConfig.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRGraphicsConfig.java	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRGraphicsConfig.java	Fri Aug 01 22:43:51 2008 +0200
+@@ -10,33 +10,31 @@
+ import sun.java2d.*;
+ 
+ /**
+- *
++ * Just a seperate
+  * @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 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);
++	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);
++	    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;
++	return this;
+     }
+ }
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/classes/sun/java2d/xr/XRMaskBlit.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRMaskBlit.java	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRMaskBlit.java	Fri Aug 01 22:43:51 2008 +0200
+@@ -2,11 +2,9 @@
+ 
+ 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.*;
+@@ -14,58 +12,52 @@
+ 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)
++/**
++ * For XRender there is no "blit", everything is just a fill with Repeat of Not.
++ * So basically this just quite the same as MaskFill.
++ * @author Clemens Eisserer
++ */
++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);
++	GraphicsPrimitiveMgr.register(primitives);
++    }
++
++    public XRMaskBlit(SurfaceType srcType, CompositeType compType,
++	    SurfaceType dstType) {
++	super(srcType, CompositeType.AnyAlpha, dstType);
++    }
++
++    protected native void maskBlit(long srcXsdo, long dstxsdo, int srcx,
++	    int srcy, int dstx, int dsty, int w, int h, int maskoff,
++	    int maskscan, int masklen, byte[] mask);
++
++    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;
+ 	}
+ 
+-	public XRMaskBlit(SurfaceType srcType, CompositeType compType, SurfaceType dstType)
+-	{
+-		super(srcType, CompositeType.AnyAlpha, dstType);
++	try {
++	    SunToolkit.awtLock();
++
++	    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(), srcx, srcy, dstx,
++		    dsty, width, height, maskoff, maskscan,
++		    mask != null ? mask.length : 0, mask);
++	} finally {
++	    SunToolkit.awtUnlock();
+ 	}
+-
+-	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 -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/classes/sun/java2d/xr/XRMaskFill.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRMaskFill.java	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRMaskFill.java	Fri Aug 01 22:43:51 2008 +0200
+@@ -12,64 +12,75 @@
+ 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),
++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) };
++		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);
++	GraphicsPrimitiveMgr.register(primitives);
++    }
++
++    protected XRMaskFill(SurfaceType srcType, CompositeType compType,
++	    SurfaceType surfaceType) {
++	super(srcType, compType, surfaceType);
++    }
++
++    protected native void maskFill(long xsdo, int x, int y, int w, int h,
++	    int maskoff, int maskscan, int masklen, byte[] mask);
++
++    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);
++
++	    maskFill(sData.getNativeOps(), x, y, w, h, maskoff, maskscan,
++		    mask != null ? mask.length : 0, mask);
++	} finally {
++	    SunToolkit.awtUnlock();
+ 	}
+-
+-	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 -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java	Fri Aug 01 22:43:51 2008 +0200
+@@ -27,180 +27,177 @@
+ 
+ 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
+-{
++ * XRPMBlitLoops
++ * 
++ * This class accelerates Blits between two surfaces of types *PM.s
++ */
++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),
++    public static void register() {
++	GraphicsPrimitive[] primitives = {
+ 
+-				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 X11PMBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntRgbX11),
++		new X11PMBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntArgbX11),
++		new X11PMBlit(XRSurfaceData.IntArgbX11, XRSurfaceData.IntRgbX11),
++		new X11PMBlit(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),
++		new X11PMScaledBlit(XRSurfaceData.IntRgbX11,
++			XRSurfaceData.IntRgbX11),
++		new X11PMScaledBlit(XRSurfaceData.IntRgbX11,
++			XRSurfaceData.IntArgbX11),
++		new X11PMScaledBlit(XRSurfaceData.IntArgbX11,
++			XRSurfaceData.IntRgbX11),
++		new X11PMScaledBlit(XRSurfaceData.IntArgbX11,
++			XRSurfaceData.IntArgbX11),
+ 
+-				/*TODO Allow blits from argb surfaces too*/
+-		};
+-		GraphicsPrimitiveMgr.register(primitives);
+-	}
++		new X11PMTransformedBlit(XRSurfaceData.IntRgbX11,
++			XRSurfaceData.IntRgbX11),
++		new X11PMTransformedBlit(XRSurfaceData.IntRgbX11,
++			XRSurfaceData.IntArgbX11),
++		new X11PMTransformedBlit(XRSurfaceData.IntArgbX11,
++			XRSurfaceData.IntRgbX11),
++		new X11PMTransformedBlit(XRSurfaceData.IntArgbX11,
++			XRSurfaceData.IntArgbX11),
++	};
++	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];
++    public static native void nativeRenderBlit(long srcData, long dstData,
++	    int sx, int sy, int dx, int dy, int w, int h);
+ }
+ 
+-class X11PMBlit extends Blit
+-{
+-	public X11PMBlit(SurfaceType srcType, SurfaceType dstType)
+-	{
+-		super(srcType, CompositeType.AnyAlpha, dstType);
++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();
+ 	}
+-
+-	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);
++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();
+ 	}
+-
+-	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);
++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);
++
++		try
++		{
++		     sourceTrans.invert();
++		}catch(NoninvertibleTransformException ex)
++		{
++		    sourceTrans.setToIdentity();
++		}
++
++		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();
+ 	}
+-
+-	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 -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/classes/sun/java2d/xr/XRRenderer.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRRenderer.java	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRRenderer.java	Fri Aug 01 22:43:51 2008 +0200
+@@ -13,243 +13,222 @@
+ import sun.java2d.pipe.ShapeSpanIterator;
+ import sun.java2d.pipe.LoopPipe;
+ 
+-public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe
+-{
+-	public XRRenderer()
+-	{}
++/**
++ * XRender provides only accalerated rectangles and lines with some tricks.
++ * To emulate higher geometry we have to pass everything else to DoPath/FillSpans.
++ * 
++ * TODO: DrawRect could be instrified
++ * @author Clemens Eisserer
++ */
+ 
+-	public static XRRenderer getInstance()
+-	{
+-		return new XRRenderer();
+-		//	return (GraphicsPrimitive.tracingEnabled() ? new X11TracingRenderer() : new X11Renderer());
++public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe {
++    public XRRenderer() {
++    }
++
++    public static XRRenderer getInstance() {
++	return new XRRenderer();
++    }
++
++    /**
++     * Common validate method, used by all XRRender functions to
++     * validate the destination context.
++     */
++    private final void validate(SunGraphics2D sg2d) {
++	XRSurfaceData xrsd = (XRSurfaceData) sg2d.surfaceData;
++	xrsd.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) {
++	Path2D.Float p2d = new Path2D.Float();
++	if (npoints > 1) {
++	    p2d.moveTo(xpoints[0], ypoints[0]);
++	    for (int i = 1; i < npoints; i++) {
++		p2d.lineTo(xpoints[i], ypoints[i]);
++	    }
+ 	}
+ 
+-	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.
++	draw(sg2d, p2d);
++    }
+ 
+-		XRSurfaceData x11sd = (XRSurfaceData) sg2d.surfaceData;
+-		x11sd.validate(sg2d.getCompClip(), sg2d.composite, sg2d.transform, sg2d.paint, sg2d, 0);
++    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;
+ 	}
+ 
+-	native void XRDrawLine(long pXSData, int x1, int y1, int x2, int y2);
++	try {
++	    SunToolkit.awtLock();
++	    validate(sg2d);
++	    XRDoPath(sg2d, sg2d.surfaceData.getNativeOps(), transx, transy,
++		    p2df, isFill);
++	} finally {
++	    SunToolkit.awtUnlock();
++	}
++    }
+ 
+-	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 draw(SunGraphics2D sg2d, Shape s) {
++
++	if (sg2d.strokeState == SunGraphics2D.STROKE_THIN) {
++	    doPath(sg2d, s, false);
++	    return;
+ 	}
+ 
+-	public void drawRect(SunGraphics2D sg2d, int x, int y, int width, int height)
+-	{
+-		draw(sg2d, new Rectangle2D.Float(x, y, width, height));
++	if (sg2d.strokeState < SunGraphics2D.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 == SunGraphics2D.STROKE_THIN) {
++	    doPath(sg2d, s, true);
++	    return;
+ 	}
+ 
+-	public void drawPolyline(SunGraphics2D sg2d, int xpoints[], int ypoints[], int npoints)
+-	{
+-		throw new RuntimeException("Not implemented");
++	AffineTransform at;
++	int transx, transy;
++	if (sg2d.transformState < SunGraphics2D.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;
+ 	}
+ 
+-	public void drawPolygon(SunGraphics2D sg2d, int xpoints[], int ypoints[], int npoints)
+-	{
+-		draw(sg2d, new Polygon(xpoints, ypoints, npoints));
++	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 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);
+-
++    native void devCopyArea(long sdOps, long xgc, int srcx, int srcy, int dstx,
++	    int dsty, int w, int h);
+ }
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/classes/sun/java2d/xr/XRSurfaceData.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceData.java	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceData.java	Fri Aug 01 22:43:51 2008 +0200
+@@ -31,7 +31,6 @@
+ 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;
+@@ -39,979 +38,931 @@
+ import sun.java2d.SurfaceDataProxy;
+ import sun.java2d.loops.*;
+ import sun.java2d.pipe.*;
++import sun.java2d.x11.*;
+ import static sun.java2d.xr.XRUtils.XDoubleToFixed;
+ 
+-public abstract class XRSurfaceData extends SurfaceData
+-{
+-	X11ComponentPeer peer;
+-	XRGraphicsConfig graphicsConfig;
+-	private RenderLoops solidloops;
++public abstract class XRSurfaceData extends XSurfaceData {
++    X11ComponentPeer peer;
++    XRGraphicsConfig graphicsConfig;
++    private RenderLoops solidloops;
+ 
+-	protected int depth;
++    protected int depth;
+ 
+-	private static native void initIDs(boolean gradCache);
++    private static native void initIDs(boolean gradCache);
+ 
+-	protected native void XRInitSurface(int depth, int width, int height, long drawable, int pictFormat);
++    protected native void XRInitSurface(int depth, int width, int height,
++	    long drawable, int pictFormat);
+ 
+-	native boolean XRIsDrawableValid();
++    native void XRInitXRender(long xsdo, int pictForm);
+ 
+-	protected native void flushNativeSurface();
++    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";
+ 
+-	native void XRInitXRender(long xsdo, int pictForm);
++    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 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 Raster getRaster(int x, int y, int w, int h) {
++	throw new InternalError("not implemented yet");
++    }
+ 
+-	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);
++    protected XRRenderer xrpipe;
++    protected PixelToShapeConverter xrtxpipe;
++    protected TextPipe xrtextpipe;
++    protected XRDrawImage xrDrawImage;
+ 
+-	public Raster getRaster(int x, int y, int w, int h)
+-	{
+-		throw new InternalError("not implemented yet");
++    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();
++	}
++    }
++
++    /**
++     * Synchronized accessor method for isDrawableValid.
++     */
++    protected boolean isXRDrawableValid() {
++	try {
++	    SunToolkit.awtLock();
++	    return isDrawableValid();
++	} finally {
++	    SunToolkit.awtUnlock();
++	}
++    }
++
++    @Override
++    public SurfaceDataProxy makeProxyFor(SurfaceData srcData) {
++	return XRSurfaceDataProxy.createProxy(srcData, graphicsConfig);
++    }
++
++    public void validatePipe(SunGraphics2D sg2d) {
++	TextPipe textpipe;
++	boolean validated = false;
++
++	/* The textpipe for now can't handle TexturePaint when extra-alpha is specified nore XOR mode*/
++	if (sg2d.compositeState < SunGraphics2D.COMP_XOR
++		&& (sg2d.paintState < SunGraphics2D.PAINT_TEXTURE
++		|| sg2d.composite == null
++		|| !(sg2d.composite instanceof AlphaComposite)
++		|| ((AlphaComposite) sg2d.composite).getAlpha() == 1.0f)) {
++	    textpipe = xrtextpipe;
++	} else {
++	    super.validatePipe(sg2d);
++	    textpipe = sg2d.textpipe;
++	    validated = true;
+ 	}
+ 
+-	protected XRRenderer x11pipe;
+-	protected PixelToShapeConverter x11txpipe;
+-	protected TextPipe x11textpipe;
+-	protected XRDrawImage xrDrawImage;
++	PixelToShapeConverter txPipe = null;
++	XRRenderer nonTxPipe = null;
+ 
+-	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();
++	if (sg2d.antialiasHint != SunHints.INTVAL_ANTIALIAS_ON) {
++	    if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR) {
++		if (sg2d.compositeState < SunGraphics2D.COMP_XOR) {
++		    txPipe = xrtxpipe;
++		    nonTxPipe = xrpipe;
+ 		}
++	    } else if (sg2d.compositeState <= SunGraphics2D.COMP_ALPHA) {
++		if (isPaintValid(sg2d)) {
++		    txPipe = xrtxpipe;
++		    nonTxPipe = xrpipe;
++		}
++		// custom paints handled by super.validatePipe() below
++	    }
+ 	}
+ 
+-	protected boolean isDrawableValid()
+-	{
+-		try
+-		{
+-			SunToolkit.awtLock();
+-			return XRIsDrawableValid();
+-		} finally
+-		{
+-			SunToolkit.awtUnlock();
++	if (txPipe != null) {
++	    if (sg2d.transformState >= SunGraphics2D.TRANSFORM_TRANSLATESCALE) {
++		sg2d.drawpipe = txPipe;
++		sg2d.fillpipe = txPipe;
++	    } else if (sg2d.strokeState != SunGraphics2D.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;
++    }
++
++    /**
++     * Returns an accalerated MaskFill object if the current paint
++     *  is supported by the pipeline.
++     */
++    protected MaskFill getMaskFill(SunGraphics2D sg2d) {
++	if (sg2d.paintState > SunGraphics2D.PAINT_ALPHACOLOR && !isPaintValid(sg2d)) {
++	    return null;
++	}
++	return super.getMaskFill(sg2d);
++    }
++
++    public RenderLoops getRenderLoops(SunGraphics2D sg2d) {
++	if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR
++		&& sg2d.compositeState <= SunGraphics2D.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).
++     * If the surface is opaque a 24-bit/RGB surface is chosen, 
++     * otherwise a 32-bit ARGB surface.
++     */
++    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);
++    }
++
++    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());
++    }
++
++    /**
++     * Inits the XRender-data-structures which belong to the XRSurfaceData.
++     * @param pictureFormat
++     */
++    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);
++
++    /**
++     * CopyArea is implemented using the "old" X11 GC, 
++     * therefor clip and needExposures have to be validated against that GC.
++     * Pictures and GCs don't share state.
++     */
++    public void validateCopyAreaGC(Region gcClip, boolean needExposures) {
++	if (validatedGCClip != gcClip) {
++	    if (gcClip != null) {
++		XSetClip(xgc, gcClip.getLoX(), gcClip.getLoY(),
++			gcClip.getHiX(), gcClip.getHiY(), 
++			gcClip.isRectangular() ? null : gcClip);
++	    } else {
++		XResetClip(xgc);
++	    }
++	    validatedGCClip = gcClip;
++	}
++
++	if (validatedExposures != needExposures) {
++	    validatedExposures = needExposures;
++	    XSetGraphicsExposures(xgc, needExposures);
++	}
++    }
++
++    public boolean copyArea(SunGraphics2D sg2d, int x, int y, int w, int h,
++	    int dx, int dy) {
++	if (xrpipe == null) {
++	    if (!isXRDrawableValid()) {
++		return true;
++	    }
++	    makePipes();
++	}
++	CompositeType comptype = sg2d.imageComp;
++	if (sg2d.transformState < SunGraphics2D.TRANSFORM_TRANSLATESCALE
++		&& (CompositeType.SrcOverNoEa.equals(comptype) || CompositeType.SrcNoEa
++			.equals(comptype))) {
++	    x += sg2d.transX;
++	    y += sg2d.transY;
++	    try {
++		SunToolkit.awtLock();
++		boolean needExposures = canSourceSendExposures(x, y, w, h);
++		validateCopyAreaGC(sg2d.getCompClip(), needExposures);
++		xrpipe.devCopyArea(getNativeOps(), xgc, x, y, x + dx, y + dy,
++			w, h);
++	    } finally {
++		SunToolkit.awtUnlock();
++	    }
++	    return true;
++	}
++	return false;
++    }
++
++    /**
++     * Returns the XRender SurfaceType which is able to fullfill the
++     * specified transparency requirement.
++     */
++    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 void invalidate() {
++	if (isValid()) {
++	    setInvalid();
++	    super.invalidate();
++	}
++    }
++
++    /**
++     * Native methods used to set the state of the native XRender surface
++     */
++    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 static native void XRSetFilter(long xsdo, int value);
++    
++    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 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);
++
++    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; //GC is still used for copyArea
++
++    public static int validatedPixel = -1;
++    public static int validatedPaintState = -1;
++    private static Composite validatedComp;
++    public static Paint validatedPaint;
++
++    private Region validatedClip;
++    private Region validatedGCClip;
++    private boolean validatedExposures = true;
++    private float validatedExtraAlpha = 1.0f;
++    private int validatedFlags;
++
++    private boolean transformInUse = false;
++    private AffineTransform validatedSourceTransform = new AffineTransform();
++    private int validatedRepeat = XRUtils.RepeatNone;
++    private int validatedInterpolation = -1;
++    /*Used if API does not allow to pass interpolation value at the level needed*/
++    private int preferredInterpolation = -1;
++
++    public void setPreferredInterpolation(int interpolation) {
++	this.preferredInterpolation = interpolation;
++    }
++    
++    
++    /*
++     * For now those shape-clips are used for transformed images,
++     * because transformed image for now would invalidate a much larger area that they are intended to do.
++     * However as soon as the transformed-mask approach I am working on turns out
++     * to work well, those will be dropped.
++     */
++    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);
++    }
++
++    /**
++     * Validate the source with the preferred interpolation set sometimes earlier.
++     * @param sxForm
++     * @param repeat
++     */
++    void validateAsSource(AffineTransform sxForm, int repeat) {
++	validateAsSource(sxForm, repeat, preferredInterpolation);
++    }
++
++    /**
++     * Validates an XRSurfaceData when used as source.
++     * Note that the clip is applied when used as source as well as destination.
++     */
++    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;
++	}
++    }
++
++    /**
++     * Utility method for setting the Composite,
++     * passing down the arguments to the native method.
++     * @param comp
++     */
++    private void setComposite(Composite comp) {
++	if (comp instanceof AlphaComposite) {
++	    AlphaComposite aComp = (AlphaComposite) comp;
++	    validatedExtraAlpha = aComp.getAlpha();
++
++	    XRSetComposite(XRUtils.j2dAlphaCompToXR(aComp.getRule()),
++		    validatedExtraAlpha);
++	} else {
++	    throw new InternalError(
++		    "Composite accaleration not implemented for: "
++			    + comp.getClass().getName());
++	}
++    }
++
++    /**
++     * @see: BufferedPaints
++     */
++    public 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;
++    }
++
++    /**
++     * @see: BufferedPaints
++     */
++    public int colorToIntArgbPixel(Color c, boolean linear) {
++	int rgb = c.getRGB();
++
++	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);
++	}
++
++	a *= validatedExtraAlpha;
++
++	return ((a << 24) | (r << 16) | (g << 8) | (b));
++    }
++    
++    /**
++     * The currently only known paint XRender can't support are
++     * radial gradients where focus and center paint differ.
++     */
++    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;
++    }
++
++    /**
++     * Sets a 2-stop gradient.
++     * Utility method generating the by the native method expected
++     * parameters and calling it.
++     */
++    private 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]));
++    }
++    
++    /**
++     * Sets a n-stop linear gradient.
++     * Utility method generating the by the native method expected
++     * parameters and calling it.
++     */
++    public 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]));
++    }
++
++    /**
++     * Sets a Radial Gradient where focus and center point match.
++     * Utility method generating the by the native method expected
++     * parameters and calling it.
++     */
++    public 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]));
++    }
++
++    private 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;
++
++	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) {
++	    at.setToIdentity(); /* TODO: Right thing to do in this case? */
++	}
++
++	x11SrcData.validateAsSource(at, XRUtils.RepeatNormal, 
++		XRUtils.ATransOpToXRQuality(sg2d.interpolationType));
++
++	XRSetTexturePaint(srcData.getNativeOps());
++
++	return paint;
++    }
++
++    /**
++     * Sets the paint as source.
++     * Checks the type of paint and calls the appropriate set*Paint method.
++     * @param sg2d
++     * @param 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");
+ 		}
++	    }
++	}
++    }
++
++    /**
++     * Validates the Surface when used as destination, 
++     * takes care that the native surface has the same state as expected, 
++     * changing it it not.
++     */
++    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;
++	}
++    }
++
++    public void makePipes() { /*TODO: Why was this synchronized, but access not?*/
++	if (xrpipe == null) {
++	    try {
++		SunToolkit.awtLock();
++		xgc = XCreateGC(getNativeOps());
++
++		xrpipe = XRRenderer.getInstance();
++		xrtxpipe = new PixelToShapeConverter(xrpipe);
++		xrtextpipe = 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 (isXRDrawableValid()) {
++		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 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;
++	public boolean canSourceSendExposures(int x, int y, int w, int h) {
++	    return true;
+ 	}
+ 
+ 	/**
+-	 * Method for instantiating a Window SurfaceData
++	 * Returns destination Component associated with this SurfaceData.
+ 	 */
+-	public static XRWindowSurfaceData createData(X11ComponentPeer peer)
+-	{
+-		XRGraphicsConfig gc = getGC(peer);
+-		return new XRWindowSurfaceData(peer, gc, gc.getSurfaceType());
++	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);
+ 	}
+ 
+ 	/**
+-	 * Method for instantiating a Pixmap SurfaceData (offscreen)
++	 * 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 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 int getTransparency() {
++	    return transparency;
+ 	}
+ 
+-	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);
++	public Rectangle getBounds() {
++	    return new Rectangle(width, height);
+ 	}
+ 
+-	//	/**
+-	//	 * 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());
++	@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 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();
+-		}
++	public void flush() {
++	    /*
++	     * We need to invalidate the surface before disposing the native
++	     * Drawable and Picture. This way if an application tries to render to an
++	     * already flushed XRSurfaceData, 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 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.
++	 * Returns destination Image associated with this SurfaceData.
+ 	 */
+-	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 Object getDestination() {
++	    return offscreenImage;
+ 	}
++    }
+ 
+-	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;
+-		}
++    private static LazyPipe lazypipe = new LazyPipe();
++
++    public static class LazyPipe extends ValidatePipe {
++	public boolean validate(SunGraphics2D sg2d) {
++	    XRSurfaceData xsd = (XRSurfaceData) sg2d.surfaceData;
++	    if (!xsd.isXRDrawableValid()) {
+ 		return false;
++	    }
++	    xsd.makePipes();
++	    return super.validate(sg2d);
+ 	}
+-
+-	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 -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/classes/sun/java2d/xr/XRSurfaceDataProxy.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceDataProxy.java	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceDataProxy.java	Fri Aug 01 22:43:51 2008 +0200
+@@ -42,62 +42,51 @@
+ 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.
++ * 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 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 dstConfig) {
++	
++	/*Don't cache already native surfaces*/
++	if (srcData instanceof XRSurfaceData) { 
++	    return UNCACHED;
++	}
++
++	return new XRSurfaceDataProxy(dstConfig, srcData.getTransparency());
+     }
+ 
+     XRGraphicsConfig xrgc;
+     int transparency;
+ 
+     public XRSurfaceDataProxy(XRGraphicsConfig x11gc) {
+-        this.xrgc = 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;
++	    SurfaceData cachedData, int w, int h) {
++	if (cachedData == null) {
++	    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;
++	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 boolean isSupportedOperation(SurfaceData srcData, int txtype,
++	    CompositeType comp, Color bgColor) {
++	return (bgColor == null || transparency == Transparency.TRANSLUCENT);
+     }
+ 
+-	public int getTransparency()
+-	{
+-		return transparency;
+-	}
++    public int getTransparency() {
++	return transparency;
++    }
+ }
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/classes/sun/java2d/xr/XRUtils.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRUtils.java	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRUtils.java	Fri Aug 01 22:43:51 2008 +0200
+@@ -6,137 +6,143 @@
+ 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;
++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;
++    /* 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;
++
++  /**
++   * Maps the specified affineTransformOp to the corresponding XRender
++   * image filter.
++   */
++    public static int ATransOpToXRQuality(int affineTranformOp) {
+ 	
+-	/*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;
++	switch (affineTranformOp) {
++	case AffineTransformOp.TYPE_NEAREST_NEIGHBOR:
++	    return FAST;
++
++	case AffineTransformOp.TYPE_BILINEAR:
++	    return GOOD;
++
++	case AffineTransformOp.TYPE_BICUBIC:
++	    return BEST;
+ 	}
+ 
+-	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 -1;
++    }
+ 
+-		return RepeatNone;
++    /**
++     * Returns the XRender picture Format which is 
++     * required to fullfill the Java2D transparency requirement.
++     */
++    public static int getPictureFormatForTransparency(int transparency) {
++	switch (transparency) {
++	case Transparency.OPAQUE:
++	    return PictStandardRGB24;
++
++	case Transparency.BITMASK:
++	case Transparency.TRANSLUCENT:
++	    return PictStandardARGB32;
+ 	}
+ 
+-	public static int XDoubleToFixed(double dbl)
+-	{
+-		return (int) (dbl * 65536);
++	return -1;
++    }
++
++    /**
++     * Maps the Java2D CycleMethod to XRender's Repeat properties.
++     */
++    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;
+ 	}
+ 
+-	public static int j2dAlphaCompToXR(int j2dRule)
+-	{
+-		switch (j2dRule)
+-		{
+-			case CLEAR:
+-				return PictOpClear;
++	return RepeatNone;
++    }
+ 
+-			case SRC:
+-				//return PictOpOver;
+-				return PictOpSrc;
++    /**
++     * Converts a double into an XFixed.
++     */
++    public static int XDoubleToFixed(double dbl) {
++	return (int) (dbl * 65536);
++    }
+ 
+-			case DST:
+-				return PictOpDst;
++    /**
++     * Maps the specified Java2D composition rule, 
++     * to the corresponding XRender composition rule.
++     */
++    public static int j2dAlphaCompToXR(int j2dRule) {
++	switch (j2dRule) {
++	case CLEAR:
++	    return PictOpClear;
+ 
+-			case SRC_OVER:
+-				return PictOpOver;
++	case SRC:
++	    return PictOpSrc;
+ 
+-			case DST_OVER:
+-				return PictOpOverReverse;
++	case DST:
++	    return PictOpDst;
+ 
+-			case SRC_IN:
+-				return PictOpIn;
++	case SRC_OVER:
++	    return PictOpOver;
+ 
+-			case DST_IN:
+-				return PictOpInReverse;
++	case DST_OVER:
++	    return PictOpOverReverse;
+ 
+-			case SRC_OUT:
+-				return PictOpOut;
++	case SRC_IN:
++	    return PictOpIn;
+ 
+-			case DST_OUT:
+-				return PictOpOutReverse;
++	case DST_IN:
++	    return PictOpInReverse;
+ 
+-			case SRC_ATOP:
+-				return PictOpAtop;
++	case SRC_OUT:
++	    return PictOpOut;
+ 
+-			case DST_ATOP:
+-				return PictOpAtopReverse;
++	case DST_OUT:
++	    return PictOpOutReverse;
+ 
+-			case XOR:
+-				return PictOpXor;
+-		}
++	case SRC_ATOP:
++	    return PictOpAtop;
+ 
+-		throw new InternalError("No XRender equivalent available for requested java2d composition rule");
++	case DST_ATOP:
++	    return PictOpAtopReverse;
++
++	case XOR:
++	    return PictOpXor;
+ 	}
++
++	throw new InternalError("No XRender equivalent available for requested java2d composition rule");
++    }
+ }
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/classes/sun/java2d/xr/XRVolatileSurfaceManager.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRVolatileSurfaceManager.java	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRVolatileSurfaceManager.java	Fri Aug 01 22:43:51 2008 +0200
+@@ -35,13 +35,7 @@
+ 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.
++ * XRender platform implementation of the VolatileSurfaceManager class.
+  */
+ public class XRVolatileSurfaceManager extends VolatileSurfaceManager {
+ 
+@@ -80,13 +74,12 @@
+         return sData;
+     }
+ 
++   /**
++    * XRender should allow copies between different formats and depths.
++    * TODO: verify that this assumption is correct.
++    */
+     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()));
++    	return true;
+     }
+ 
+     /**
+@@ -96,10 +89,8 @@
+     @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 -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/native/sun/java2d/x11/ArrayList.c
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/ArrayList.c	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/ArrayList.c	Fri Aug 01 22:43:51 2008 +0200
+@@ -2,9 +2,7 @@
+ #include <string.h>
+ #include "ArrayList.h"
+ 
+-void initXRList(XrArrayList *list, jint capacity, size_t blkSize)
+-{
+-  //printf("Init XR LIst!\n");fflush(stdout);
++void initXRList(XrArrayList *list, jint capacity, size_t blkSize) {
+   list->used = 0;
+   list->capacity = capacity;
+ 
+@@ -15,10 +13,8 @@
+   }
+ }
+ 
+-void* getNewXR(XrArrayList *list, size_t blkSize)
+-{
+-  if((list->used+1) >= list->capacity)
+-  {
++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);
+@@ -31,9 +27,7 @@
+   return list->elements + (list->used++ * blkSize);
+ }
+ 
+-void clearXRList(XrArrayList *list)
+-{
++void clearXRList(XrArrayList *list) {
+   list->used = 0;
+-  //memset(list->elements, 0, list->used);
+ }
+ 
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/native/sun/java2d/x11/ArrayList.h
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/ArrayList.h	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/ArrayList.h	Fri Aug 01 22:43:51 2008 +0200
+@@ -1,3 +1,8 @@
++/* Utility functions, providing some kind of growable array
++ * with the restriction that elements can only be added 
++ * at the end of the list 
++ */
++
+ #ifndef ArrayList_h_Included
+ #define ArrayList_h_Included
+ 
+@@ -9,10 +14,14 @@
+    jint used;
+ } XrArrayList;
+ 
++/* Initializes the list data strutures */
+ void initXRList(XrArrayList *list, jint capacity, size_t blkSize);
+ 
++/* Returns a pointer to a blksize large memory area, 
++   enlarging the underlaying array on demand */
+ void* getNewXR(XrArrayList *list, size_t blkSize);
+ 
++/* Clears the list content */
+ void clearXRList(XrArrayList *list);
+ 
+ #endif /* ArrayList_h_Included */
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/native/sun/java2d/x11/MaskBuffer.c
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/MaskBuffer.c	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/MaskBuffer.c	Fri Aug 01 22:43:51 2008 +0200
+@@ -1,12 +1,13 @@
+ #include "MaskBuffer.h"
+ #include "XRSurfaceData.h"
+ #include "X11SurfaceData.h"
++#include "Trace.h"
++#include "awt_GraphicsEnv.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)        \
+-  {                                                                      \
++#define GET_DIRTY_LINE_REGION(X1, Y1, X2, Y2, RX1, RY1, RX2, RY2)  {     \
+     if(X1 < X2) {                                                        \
+       RX1 = X1;                                                          \
+       RX2 = X2;                                                          \
+@@ -25,8 +26,8 @@
+   }
+ 
+ #ifndef HEADLESS
+-MaskBuffer* initMaskBuffer(Window window)
+-{
++
++MaskBuffer* initMaskBuffer(Window window) {
+   MaskBuffer *buffer = malloc(sizeof(MaskBuffer));
+   initRegion(&buffer->region);
+  
+@@ -40,21 +41,16 @@
+   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;
+@@ -63,16 +59,21 @@
+   /*Invisible GC for readback assistance*/
+   values.foreground = 0;
+   buffer->clearLineGC = XCreateGC(awt_display, buffer->lineMaskPixmap, GCForeground, &values);
++  buffer->maskGC = XCreateGC(awt_display, buffer->maskPixmap, 0, &values);
++ 
++  buffer->alphaData = malloc(32*32);
++  buffer->alphaImg = XCreateImage(awt_display, &buffer->maskPixmap, 8, ZPixmap, 0, (char *) buffer->alphaData, 32, 32, 8, 0);
++  buffer->aImgWidth = 32;
++  buffer->aImgHeight = 32;
+ 
+   return buffer;
+ }
+ 
+-static void allocTileBuffer(MaskBuffer* buf)
+-{
++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 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);
+@@ -82,7 +83,7 @@
+     buf->tiles = calloc(buf->xTileCap * buf->yTileCap, sizeof(XrTile));
+   }
+ 
+-  //Init/Reset the tiles that will be used later
++  /* 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++) {
+@@ -91,30 +92,22 @@
+  }
+ }
+ 
+-static void cleanMaskBuffer(MaskBuffer *buf)
+-{
+-  initRegion(&buf->region); //TODO: eigentlich nicht noetig
++static void cleanMaskBuffer(MaskBuffer *buf) {
++  initRegion(&buf->region);
+   buf->xTiles = 0;
+   buf->yTiles = 0;
+   clearXRList(&buf->rects);
+   clearXRList(&buf->lines);
+ }
+ 
+-static void getTileDirtyArea(MaskRegion *dirtyRectArea, MaskRegion *dirtyLineArea, MaskRegion *totalDirtyArea)
+-{
++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)
+-{
++static void growDirtyRegion(MaskRegion *region, jint x, jint y, jint x2, jint y2) {
+   if(x < region->x){
+     region->x = x;
+   }
+@@ -129,8 +122,7 @@
+   }
+ }
+ 
+-static void growDirtyRegionTileLimit(MaskRegion *region, jint x, jint y, jint x2, jint y2)
+-{
++static void growDirtyRegionTileLimit(MaskRegion *region, jint x, jint y, jint x2, jint y2) {
+   if(x < region->x){
+     region->x = MAX(x, 0);
+   }
+@@ -149,8 +141,7 @@
+ * Limits the rect's coordinates to the mask coordinates.
+ * The result is used by growDirtyRegion.
+ */
+-static void limitRetcCoords(XRectangle *rect) 
+-{
++static void limitRetcCoords(XRectangle *rect)  {
+    if((rect->x + rect->width) > MASK_TILE_SIZE) {
+       rect->width = MASK_TILE_SIZE - rect->x;
+    }
+@@ -168,16 +159,14 @@
+   }
+ }
+ 
+-static void initRegion(MaskRegion *region)
+-{
+-  region->x = 99999;
++static void initRegion(MaskRegion *region) {
++  region->x = 99999; /*TODO: Integer max/min*/
+   region->y = 99999;
+   region->x2 = -99999;
+   region->y2 = -99999;
+ }
+ 
+-void addRect(MaskBuffer* buf, short x, short y, unsigned short w, unsigned short h)
+-{
++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;
+@@ -187,51 +176,40 @@
+   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.
+-   */
++void addLine(MaskBuffer* buf, int x1, int y1, int x2, int y2) {
++  /* EXA is not able to accalerate diagonal lines, 
++     we try to "guide" it a bit to avoid excessive migration
++     See project documentation for an detailed explanation */
+ 
+   int minX, minY, maxX, maxY;
+-  GET_DIRTY_LINE_REGION(x1, y1, x2, y2, 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)
+-   {
++  if(xDiff == 0 || yDiff == 0) {
+      addRect(buf, minX, minY, maxX - minX + 1, maxY - minY + 1);
+-   }else
+-   if(xDiff == 1 && yDiff == 1)
+-   {
++  } else if(xDiff == 1 && yDiff == 1) {
+      addRect(buf, x1, y1, 1, 1);
+      addRect(buf, x2, y2, 1, 1);
+-   } else 
+-   {
++  } 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)
+-{
++static void initXrTile(XrTile *tile) {
+   initRegion(&tile->dirtyLineArea);
+   initRegion(&tile->dirtyRectArea);
+   clearXRList(&tile->rects);
+   clearXRList(&tile->lines);
+ }
+ 
+-static void storeLinesInTiles(MaskBuffer *buf)
+-{
++static void storeLinesInTiles(MaskBuffer *buf) {
+   int i,n,m;
+ 
+   for(i=0; i < buf->lines.used; i++) {
+@@ -242,8 +220,8 @@
+      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 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;
+@@ -277,8 +255,7 @@
+   }
+ }
+ 
+-static void storeRectsInTiles(MaskBuffer *buf)
+-{
++static void storeRectsInTiles(MaskBuffer *buf) {
+   int i,n,m;
+ 
+   for(i=0; i < buf->rects.used; i++) {
+@@ -296,7 +273,7 @@
+         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));
+ 
+@@ -315,8 +292,7 @@
+   }
+ }
+ 
+-static void translateRects(XrArrayList *rectList, int x, int y)
+-{
++static void translateRects(XrArrayList *rectList, int x, int y) {
+   int i;
+   for(i = 0; i < rectList->used; i++) {
+       XRectangle *rect = ((XRectangle *) rectList->elements) + i;
+@@ -325,20 +301,18 @@
+    }
+ }
+ 
+-void fillMask(MaskBuffer* buf, Picture dest)
+-{
+-  XRenderColor color_black={.red=0, .green=0, .blue=0, .alpha=0xffff};
++void fillMask(MaskBuffer* buf, Picture dest) {
+   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;
++  /*Extra Alpha is already stored in solid-color*/
++  jdouble maskAlpha = (xrSrcData.src != xrSrcData.texture) ? 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, 
++  /* 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);
+@@ -369,9 +343,10 @@
+           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*/
+-          {
++          /*Again, only composite the current tile if required, otherwise just fill rects*/
++	  if(maskRequired || lineList->used  > 0) {
+             Picture mask = None;
++
+             if(lineList->used != 0) {
+               XDrawSegments(awt_display, buf->lineMaskPixmap, buf->drawLineGC, (XSegment *) lineList->elements, lineList->used);
+               mask = buf->lineMaskPicture;
+@@ -386,16 +361,17 @@
+ 
+              XRComposite(mask, dest, x, y, tileDirtyArea.x, tileDirtyArea.y, x, y, width, height);
+ 
+-             /*Clear dirty rectangle of the rect-mask*/
++             /* Clear dirty rectangle of the rect-mask */
+              XRenderFillRectangle (awt_display, PictOpClear, buf->maskPicture, &color_black, tileDirtyArea.x, tileDirtyArea.y, width, height);
+ 
++             /* Clear diagonal lines with lines again,
++                to avoid the sysmem copy marked "dirty" causing migration for the next lines*/
+              if(lineList->used != 0) {
+                XDrawSegments(awt_display, buf->lineMaskPixmap, buf->clearLineGC, (XSegment *) lineList->elements, lineList->used);
+                clearXRList(lineList);
+ 	     }
+           }else
+-          if(rectList->used != 0)
+-          {
++          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);
+@@ -403,8 +379,7 @@
+         }
+       }
+      }
+- } else 
+- {
++  } else {
+    XRenderFillRectangles (awt_display, xrSrcData.compRule, dest, &xrSrcData.solidColor, (XRectangle*) buf->rects.elements, buf->rects.used);
+  }
+ 
+@@ -412,165 +387,3 @@
+ }
+ 
+ #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 -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/native/sun/java2d/x11/MaskBuffer.h
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/MaskBuffer.h	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/MaskBuffer.h	Fri Aug 01 22:43:51 2008 +0200
+@@ -1,3 +1,11 @@
++/* MaskBuffer buffers geometry (for now only lines and rects),
++ * renders those primitives into a mask in one go and composites
++ * using the mask as geometry-buffer.
++ * The advantage is that rendering rects can be done quite efficiently,
++ * but composition scanline-by-scanline is very slow.
++ * Please see the project-page for an in-depth explanation of MaskBuffer.
++ */
++
+ #ifndef MaskBuffer_h_Included
+ #define MaskBuffer_h_Included
+ 
+@@ -10,6 +18,8 @@
+ #include <X11/extensions/Xrender.h>
+ #include <assert.h>
+ 
++/* To not alloc/dealloc the mask pixmap tiling is used.
++   This specifies the size of the alpha-tile.        */
+ #define MASK_TILE_SIZE 256
+ 
+ typedef struct {
+@@ -19,6 +29,7 @@
+   jint y2;
+ }MaskRegion;
+ 
++/*Holds information which belongs to a single tile*/
+ typedef struct {
+   XrArrayList rects;
+   XrArrayList lines;
+@@ -27,6 +38,8 @@
+   MaskRegion dirtyLineArea;
+ } XrTile;
+ 
++/* The MaskBuffer data-structure itself is shared in the application
++   and contains pixmaps for gradient-caching and MaskFill/MaskBlit */
+ typedef struct {
+   Pixmap lineMaskPixmap;
+   Picture lineMaskPicture;
+@@ -35,6 +48,7 @@
+ 
+   Pixmap maskPixmap;
+   Picture maskPicture;
++  GC maskGC;
+   jfloat validatedGCAlpha;
+ 
+   XrArrayList rects;
+@@ -47,34 +61,59 @@
+   int yTileCap;
+   XrTile *tiles;
+ 
+-  Pixmap gradPixmap;
+-  Picture gradPict;
++  XImage *alphaImg;
++  unsigned char* alphaData;
++  jint aImgWidth;
++  jint aImgHeight;
+ }MaskBuffer;
+ 
++/* Initializes the MaskBuffer data structure*/
+ MaskBuffer* initMaskBuffer(Window window);
+ 
++/* Adds a rect which will be filled to the geometry-buffer*/ 
+ void addRect(MaskBuffer* buf, short x, short y, unsigned short w, unsigned short h);
+ 
++/* Adds a line to the geometry-buffer*/
+ void addLine(MaskBuffer* buf, int x1, int y1, int x2, int y2);
+ 
++/* Composites using the stored geometry as mask, using properties stored in SrcSurfaceData*/
+ void fillMask(MaskBuffer* buf, Picture dest);
+ 
++/* Builds a 2D array of tiles and adds the rects buffered by addRect,
++   to the tiles which are affacted. */
+ static void storeRectsInTiles(MaskBuffer *buf);
+ 
++/* Builds a 2D array of tiles and adds the lines stored by addLine 
++ * to the tiles which are affacted*/
++static void storeLinesInTiles(MaskBuffer *buf);
++
++/* Re-sets the MaskBuffer to an empty state */
+ static void cleanMaskBuffer(MaskBuffer *buf);
+ 
++/* Shrinks the rectangle's coordinates if in the middle of two tiles*/
+ static void limitRetcCoords(XRectangle *rect);
+ 
++/* Re-Sets the values of a MaskRegion */
+ static void initRegion(MaskRegion *region);
+ 
++/* If parameters are outside the bounds of the MaskRegion, the MaskRegion will be enlarged */
+ static void growDirtyRegion(MaskRegion *region, jint x, jint y, jint x2, jint y2);
+ 
++/* If parameters are outside the bounds of the MaskRegion, the MaskRegion will be enlarged, 
++   but is limited to the size of a single tile */
+ static void growDirtyRegionTileLimit(MaskRegion *region, jint x, jint y, jint x2, jint y2);
+ 
++/* Re-Sets a tile data-structure*/
+ static void initXrTile(XrTile *tile);
+ 
++/* Returns the total dirty size of both, the rect and the line tile combined */
+ static void getTileDirtyArea(MaskRegion *dirtyRectArea, MaskRegion *dirtyLineArea, MaskRegion *totalDirtyArea);
+ 
++/* Translates all rects in rectList by x/y */
+ static void translateRects(XrArrayList *rectList, int x, int y);
+ 
++/* Allocates and initializes the tile-datastructures nescessary
++   to hold the geometry stored in the MaskBuffer*/
++static void allocTileBuffer(MaskBuffer* buf);
++
+ #endif /* MaskBuffer_h_Included */
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/native/sun/java2d/x11/X11SurfaceData.c
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.c	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.c	Fri Aug 01 22:43:51 2008 +0200
+@@ -97,7 +97,7 @@
+ 
+ #endif /* !HEADLESS */
+ 
+-jboolean XShared_initIDs(JNIEnv *env)
++jboolean XShared_initIDs(JNIEnv *env, jboolean allowShmPixmaps)
+ {
+ #ifndef HEADLESS
+    union {
+@@ -122,14 +122,19 @@
+         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;
+-            }
++
++        if(allowShmPixmaps) {
++          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;
++              }
++          }
++        }else {
++          useMitShmPixmaps = JNI_FALSE;
+         }
+     }
+ 
+@@ -150,7 +155,7 @@
+                                            jclass XORComp, jboolean tryDGA)
+ {
+ #ifndef HEADLESS
+-  if(XShared_initIDs(env))
++  if(XShared_initIDs(env, JNI_TRUE))
+   {
+     void *lib = 0;
+ 
+@@ -189,7 +194,7 @@
+  * Signature: ()Z
+  */
+ JNIEXPORT jboolean JNICALL
+-Java_sun_java2d_x11_X11SurfaceData_isDrawableValid(JNIEnv *env, jobject this)
++Java_sun_java2d_x11_XSurfaceData_isDrawableValid(JNIEnv *env, jobject this)
+ {
+     jboolean ret = JNI_FALSE;
+ 
+@@ -227,7 +232,7 @@
+  * Signature: (Ljava/lang/Object;I)V
+  */
+ JNIEXPORT void JNICALL
+-Java_sun_java2d_x11_X11SurfaceData_initOps(JNIEnv *env, jobject xsd,
++Java_sun_java2d_x11_XSurfaceData_initOps(JNIEnv *env, jobject xsd,
+                                            jobject peer,
+                                            jobject graphicsConfig, jint depth)
+ {
+@@ -311,7 +316,7 @@
+  * Signature: ()V
+  */
+ JNIEXPORT void JNICALL
+-Java_sun_java2d_x11_X11SurfaceData_flushNativeSurface(JNIEnv *env, jobject xsd)
++Java_sun_java2d_x11_XSurfaceData_flushNativeSurface(JNIEnv *env, jobject xsd)
+ {
+ #ifndef HEADLESS
+     SurfaceDataOps *ops = SurfaceData_GetOps(env, xsd);
+@@ -395,7 +400,7 @@
+  * Signature: ()V
+  */
+ JNIEXPORT void JNICALL
+-Java_sun_java2d_x11_X11SurfaceData_setInvalid(JNIEnv *env, jobject xsd)
++Java_sun_java2d_x11_XSurfaceData_setInvalid(JNIEnv *env, jobject xsd)
+ {
+ #ifndef HEADLESS
+     X11SDOps *xsdo = (X11SDOps *) SurfaceData_GetOps(env, xsd);
+@@ -1584,7 +1589,7 @@
+  * Signature: (I)J
+  */
+ JNIEXPORT jlong JNICALL
+-Java_sun_java2d_x11_X11SurfaceData_XCreateGC
++Java_sun_java2d_x11_XSurfaceData_XCreateGC
+     (JNIEnv *env, jclass xsd, jlong pXSData)
+ {
+     jlong ret;
+@@ -1614,7 +1619,7 @@
+  * Signature: (JIIIILsun/java2d/pipe/Region;)V
+  */
+ JNIEXPORT void JNICALL
+-Java_sun_java2d_x11_X11SurfaceData_XResetClip
++Java_sun_java2d_x11_XSurfaceData_XResetClip
+     (JNIEnv *env, jclass xsd, jlong xgc)
+ {
+ #ifndef HEADLESS
+@@ -1629,7 +1634,7 @@
+  * Signature: (JIIIILsun/java2d/pipe/Region;)V
+  */
+ JNIEXPORT void JNICALL
+-Java_sun_java2d_x11_X11SurfaceData_XSetClip
++Java_sun_java2d_x11_XSurfaceData_XSetClip
+     (JNIEnv *env, jclass xsd, jlong xgc,
+      jint x1, jint y1, jint x2, jint y2,
+      jobject complexclip)
+@@ -1704,7 +1709,7 @@
+  * Signature: (JZ)V
+  */
+ JNIEXPORT void JNICALL
+-Java_sun_java2d_x11_X11SurfaceData_XSetGraphicsExposures
++Java_sun_java2d_x11_XSurfaceData_XSetGraphicsExposures
+     (JNIEnv *env, jclass xsd, jlong xgc, jboolean needExposures)
+ {
+ #ifndef HEADLESS
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/native/sun/java2d/x11/X11SurfaceData.h
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.h	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.h	Fri Aug 01 22:43:51 2008 +0200
+@@ -166,17 +166,17 @@
+ /*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);
++jboolean XShared_initIDs(JNIEnv *env, jboolean allowShmPixmaps);
+ 
+-JNIEXPORT void JNICALL
+-Java_sun_java2d_x11_X11SurfaceData_initOps(JNIEnv *env, jobject xsd,
+-                                           jobject peer,
+-                                           jobject graphicsConfig, jint depth);
++// 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);
++// 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);*/
+ 
+-JNIEXPORT void JNICALL
+-Java_sun_java2d_x11_X11SurfaceData_flushNativeSurface(JNIEnv *env, jobject xsd);
+-
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/native/sun/java2d/x11/XRGlyphCache.c
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/XRGlyphCache.c	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRGlyphCache.c	Fri Aug 01 22:43:51 2008 +0200
+@@ -35,6 +35,7 @@
+ 
+     return cache;
+ }
++
+ 
+ static jboolean cleanCache(XRGlyphCacheInfo *cache)
+ {
+@@ -158,7 +159,13 @@
+      
+ 
+      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};
++     XGlyphInfo xginfo;
++     xginfo.x = (jginfo->topLeftX*-1);
++     xginfo.y = (jginfo->topLeftY*-1);
++     xginfo.width = width;
++     xginfo.height = height;
++     xginfo.xOff = cacheCell->xOff;
++     xginfo.yOff = cacheCell->yOff;
+ 
+      XRenderAddGlyphs(awt_display, cache->glyphSet, &gid, &xginfo, 1, glyphBuf, bufLen);
+      
+@@ -242,25 +249,23 @@
+    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*/
+ 
+ 
++// Dev-only debug and trace function.
++// 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);
++//     }
++//   }
++// }
+ // 	  int line_, pix_;
+ // 	  for(line_ = 0; line_ < jginfo->height; line_++)
+ // 	  {
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/native/sun/java2d/x11/XRGlyphCache.h
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/XRGlyphCache.h	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRGlyphCache.h	Fri Aug 01 22:43:51 2008 +0200
+@@ -11,6 +11,7 @@
+ typedef struct _XRGlyphCacheInfo XRGlyphCacheInfo;
+ typedef struct _XRCacheCellInfo XRCacheCellInfo;
+ 
++/* Cell-Cache structure*/
+ struct _XRGlyphCacheInfo {
+     XRCacheCellInfo *cells;
+     jint searchPosition;
+@@ -20,6 +21,10 @@
+     GlyphSet glyphSet;
+ };
+ 
++/* CacheCellInfo structure, 
++*  holds a cached GlyphInfo and
++*  other per-glpyh information.
++*/
+ struct _XRCacheCellInfo {
+     XRGlyphCacheInfo *cacheInfo;
+     GlyphInfo *glyphInfo;
+@@ -33,9 +38,17 @@
+ };
+ 
+ #ifndef HEADLESS
++/*Initialized the GlyphCache structure*/
+ XRGlyphCacheInfo* XRGlyphCache_Init(XRenderPictFormat* glyphSetPictFormat);
++
++/*Add a list of GlyphInfo's to the cache, returns false of not succeeded.*/
+ jboolean XRGlyphCache_CacheGlyphs(XRGlyphCacheInfo *cache, jlong *glyphPtrs, jint glyphCount, jint *ids);
+-void dumpCache(XRGlyphCacheInfo *cache);
++
++/* Frees entries which have not been used a lot, and enlarges cache if nescessary */
++static jboolean cleanCache(XRGlyphCacheInfo *cache);
++
++/* Adds a single glyph to the cache and uploads it to the X-Server*/
++static jboolean uploadGlyph(XRGlyphCacheInfo *cache, GlyphInfo *jginfo, XRCacheCellInfo *cacheCell);
+ #endif
+ 
+ #endif /* XRGlyphCache_h_Included */
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/native/sun/java2d/x11/XRPMBlitLoops.c
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/XRPMBlitLoops.c	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRPMBlitLoops.c	Fri Aug 01 22:43:51 2008 +0200
+@@ -59,84 +59,69 @@
+         return;
+     }
+ 
+-#ifdef MITSHM
+-    if (srcXsdo->isPixmap) {
+-        X11SD_UnPuntPixmap(srcXsdo);
+-    }
+-#endif /* MITSHM */
++    XRenderComposite (awt_display, xrSrcData.compRule, srcXsdo->xrPic, xrSrcData.alphaMask, dstXsdo->xrPic, srcx, srcy, 0, 0, dstx, dsty, width, height); 
+ 
+-/*   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)
++static Picture prepareMaskPM(JNIEnv *env, 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);
++    jboolean useEA = (xrSrcData.src == xrSrcData.texture && 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(maskArray != NULL) {
+ 
+-		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);
++         mask = (unsigned char *) (*env)->GetPrimitiveArrayCritical(env, maskArray, NULL);
+ 
+-		alphaOps->GetRasInfo(env, alphaOps, &alphaInfo);
++         /* Tries to optimize Mask-Upload:  
++          * 1. If existing XImage and supplied buffer match, only adjust the data pointer
++          * 2. If existing XImage is large enough to hold the data put does not match in scan,
++          *    the data is copied in way to fit the XImage.
++          * 3. If data is larger than the existing XImage a new temporary XImage is allocated
++          * The default XImage is optimized for the AA tiles, which are currently 32x32.
++          */
++          XImage *defaultImg = maskBuffer->alphaImg;
++          XImage *img = maskBuffer->alphaImg;
++          jboolean imageFits = defaultImg->width >= w && defaultImg->height >= h;
+ 
+-              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]);  
+-		  }
+-		}
+-             }
++          if(imageFits && maskoff == defaultImg->xoffset && maskscan == defaultImg->bytes_per_line) {
++                defaultImg->data = mask;
++          }else {
++            if(imageFits) {
++               defaultImg->data = maskBuffer->alphaData;
+ 
+-                SurfaceData_InvokeRelease(env, alphaOps, &alphaInfo);
+-                SurfaceData_InvokeUnlock(env, alphaOps, &alphaInfo);
+-                (*env)->ReleasePrimitiveArrayCritical(env, maskArray, mask, JNI_ABORT);
++               for(line=0; line < h; line++) {
++                   for(pix=0; pix < w; pix++) {
++                       img->data[line*img->bytes_per_line + pix] = (unsigned char) (mask[maskscan*line + pix + maskoff]);  
++                   }
++               }
+ 
+-	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 { 
++               /*TODO: handle case where XImage is larger than pixmap*/
++               img = XCreateImage(awt_display, &maskBuffer->maskPixmap, 8, ZPixmap, maskoff, mask, maskscan, h, 8, 0);
++            }
+           }
++
++          XPutImage(awt_display, maskBuffer->maskPixmap, maskBuffer->maskGC, img, 0, 0, 0, 0, w, h);
++          (*env)->ReleasePrimitiveArrayCritical(env, maskArray, mask, JNI_ABORT);
++
++	  if(img != defaultImg) {
++             img->data = NULL;
++             XDestroyImage(img);
++          }
++
++        /* XRender does not expose multitexturing, therefor we have to Composite with the alphaMask to get EA in*/
++	if(useEA)  {
++                XRenderComposite (awt_display, PictOpSrc, maskBuffer->maskPicture, xrSrcData.alphaMask, maskBuffer->lineMaskPicture, 0, 0, 0, 0, 0, 0, w, h); 
++                return maskBuffer->lineMaskPicture;
++	}else {
++           return maskBuffer->maskPicture;
++        }
+     }else
+     {
+       if(useEA) {
+@@ -147,12 +132,11 @@
+     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);
++/* Clean up the area of the masks which have been used as target-pixmap for mask-upload */
++static void cleanMask(Picture mask, int w, int h) {
++  XRenderFillRectangle (awt_display, PictOpClear, maskBuffer->maskPicture, &color_black, 0, 0, w, h);
++  if(mask == maskBuffer->lineMaskPicture) {
++     XRenderFillRectangle (awt_display, PictOpClear, maskBuffer->lineMaskPicture, &color_black, 0, 0, w, h);
+   }
+ }
+ #endif
+@@ -160,7 +144,7 @@
+ JNIEXPORT void JNICALL
+ Java_sun_java2d_xr_XRMaskFill_maskFill
+      (JNIEnv *env, jobject joSelf, 
+-      jlong dstData, jlong alphaData,
++      jlong dstData,
+       jint x, jint y, jint w, jint h,
+       jint maskoff, jint maskscan, 
+       jint masklen, jbyteArray maskArray)
+@@ -169,17 +153,14 @@
+     J2dTraceLn(J2D_TRACE_INFO, "in XRPBMBlitLoops_maskFill");
+ 
+     Picture maskPic;
+-    X11SDOps *dstXsdo, *alphaXsdo;
++    X11SDOps *dstXsdo;
+     dstXsdo = (X11SDOps *)jlong_to_ptr(dstData);
+-    alphaXsdo = (X11SDOps *)jlong_to_ptr(alphaData);
+-    if (dstXsdo == NULL || alphaXsdo == NULL) {
++    if (dstXsdo == NULL) {
+         return;
+     }
+ 
+-    maskPic = prepareMaskPM(env, alphaXsdo, maskArray, maskoff, maskscan, w, h);
+-
++    maskPic = prepareMaskPM(env, 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);
+@@ -190,7 +171,7 @@
+ JNIEXPORT void JNICALL
+ Java_sun_java2d_xr_XRMaskBlit_maskBlit
+      (JNIEnv *env, jobject joSelf, 
+-      jlong srcData, jlong dstData, jlong alphaData,
++      jlong srcData, jlong dstData,
+       jint srcx, jint srcy,
+       jint dstx, jint dsty, jint w, jint h,
+       jint maskoff, jint maskscan, 
+@@ -200,15 +181,14 @@
+     J2dTraceLn(J2D_TRACE_INFO, "in XRPBMBlitLoops_maskBlit");
+ 
+     Picture maskPic;
+-    X11SDOps *srcXsdo, *dstXsdo, *alphaXsdo;
++    X11SDOps *srcXsdo, *dstXsdo;
+     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) {
++    if (srcXsdo == NULL || dstXsdo == NULL) {
+         return;
+     }
+ 
+-    maskPic = prepareMaskPM(env, alphaXsdo, maskArray, maskoff, maskscan, w, h);
++    maskPic = prepareMaskPM(env, 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);
+ 
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/native/sun/java2d/x11/XRRenderer.c
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/XRRenderer.c	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRRenderer.c	Fri Aug 01 22:43:51 2008 +0200
+@@ -49,6 +49,7 @@
+ #define CLAMP_TO_USHORT(x)  (((x) > 65535) ? 65535 : ((x) < 0) ? 0 : (x))
+ 
+ 
++/* Adds a PolyLine consisting of multiple points to the MaskBuffer */
+ JNIEXPORT void JNICALL XRDrawLines(Picture dst, XPoint * points, int npoints)
+ {
+ #ifndef HEADLESS
+@@ -216,6 +217,7 @@
+ #endif /* !HEADLESS */
+ }
+ 
++
+ JNIEXPORT void JNICALL Java_sun_java2d_xr_XRRenderer_XRFillRect
+     (JNIEnv *env, jobject xr,
+      jlong pXSData,
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/native/sun/java2d/x11/XRSurfaceData.c
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.c	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.c	Fri Aug 01 22:43:51 2008 +0200
+@@ -6,6 +6,7 @@
+ #ifndef HEADLESS
+ SrcSurfaceData xrSrcData;
+ MaskBuffer *maskBuffer;
++XRenderColor color_black;
+ #endif /* !HEADLESS */
+ 
+ #define BUILD_TRANSFORM_MATRIX(TRANSFORM, M00, M01, M02, M10, M11, M12)                        \
+@@ -20,65 +21,6 @@
+       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)
+@@ -99,25 +41,37 @@
+     xsdo->xrPic = XRenderCreatePicture(awt_display, xsdo->drawable, fmt, CPRepeat, &pict_attr);
+   }
+ 
+-  if(maskBuffer == NULL) 
+-  {
++  /*TODO: Improper place to initialize that stuff here - however we need a drawable in order to create the pixmaps*/
++  if(maskBuffer == NULL) {
+     maskBuffer = initMaskBuffer(xsdo->drawable);
++    initXRSrcData(xsdo->drawable);
++  }
++#endif /* !HEADLESS */
++}
+ 
++static void initXRSrcData(Drawable *drawable) {
++#ifndef HEADLESS
+     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);
++    XRenderPictFormat *fmt32 = XRenderFindStandardFormat(awt_display, PictStandardARGB32);
++    Pixmap solidPixmap = XCreatePixmap(awt_display, drawable, 1, 1, 32);
++    xrSrcData.solid = XRenderCreatePicture(awt_display, solidPixmap, fmt32, 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);
+-  }
++    XRenderPictFormat *fmt8 = XRenderFindStandardFormat(awt_display, PictStandardA8);
++    Pixmap alphaPixmap = XCreatePixmap(awt_display, drawable, 1, 1, 8);
++    xrSrcData.alphaMaskPict = XRenderCreatePicture(awt_display, alphaPixmap, fmt8, CPRepeat, &pict_attr);
++
++    /*Init gradient cache*/
++    if(xrSrcData.gradCacheEnabled) {
++      xrSrcData.gradPixmap = XCreatePixmap(awt_display, drawable, MASK_TILE_SIZE, MASK_TILE_SIZE, 32);
++      xrSrcData.gradPict = XRenderCreatePicture(awt_display, xrSrcData.gradPixmap, fmt32, 0, &pict_attr);
++    }
+ #endif /* !HEADLESS */
+ }
++
+ 
+ JNIEXPORT void JNICALL
+ Java_sun_java2d_xr_XRSurfaceData_initIDs(JNIEnv *env, jclass xsd, jboolean gradCacheEnabled)
+@@ -133,18 +87,15 @@
+   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);
++  color_black.red=0;
++  color_black.green=0;
++  color_black.blue=0;
++  color_black.alpha=0xffff;
++
++  XShared_initIDs(env, JNI_FALSE);
+ #endif /* !HEADLESS */
+ }
+ 
+@@ -157,10 +108,10 @@
+ 
+   if(xrSrcData.src == xrSrcData.gradient && xrSrcData.gradCacheEnabled)
+   {
+-    XRenderComposite(awt_display, PictOpSrc, xrSrcData.gradient, None, maskBuffer->gradPict, srcX, srcY, 0, 0, 0, 0, width, height);
++    XRenderComposite(awt_display, PictOpSrc, xrSrcData.gradient, None, xrSrcData.gradPict, srcX, srcY, 0, 0, 0, 0, width, height);
+     cachedX = 0;
+     cachedY = 0; 
+-    cachedSrc = maskBuffer->gradPict;
++    cachedSrc = xrSrcData.gradPict;
+   }
+ 
+    XRenderComposite (awt_display, xrSrcData.compRule, cachedSrc, mask, dest, cachedX, cachedY, maskX, maskY, dstX, dstY, width, height);
+@@ -246,20 +197,24 @@
+    }
+ 
+     XLinearGradient grad;
+-    XRenderColor colors[numStops];
+-    XFixed stops[numStops];
+-
+     grad.p1.x = x1;
+     grad.p1.y = y1;
+     grad.p2.x = x2;
+     grad.p2.y = y2;
+ 
++    /*TODO optimized & malloc check*/
++    XRenderColor *colors = (XRenderColor *) malloc(numStops * sizeof(XRenderColor));
++    XFixed *stops =  (XFixed *) malloc(numStops * sizeof(XFixed));
++
+     for(i=0; i < numStops; i++) {
+       stops[i] = XDoubleToFixed(fractions[i]);
+-      decodeRenderColorPre(pixels[i], &colors[i]);
++      decodeRenderColorPre(pixels[i], colors + i);
+     }
+ 
+-    xrSrcData.gradient = XRenderCreateLinearGradient(awt_display, &grad, &stops[0], &colors[0], numStops);
++    xrSrcData.gradient = XRenderCreateLinearGradient(awt_display, &grad, stops, colors, numStops);
++    free(colors);
++    free(stops);
++
+     xrSrcData.src = xrSrcData.gradient;
+ 
+     XTransform tr;
+@@ -299,9 +254,6 @@
+    }
+ 
+     XRadialGradient grad;
+-    XRenderColor colors[numStops];
+-    XFixed stops[numStops];
+-
+     grad.inner.x = 0;
+     grad.inner.y = 0;
+     grad.inner.radius = innerRadius;
+@@ -309,12 +261,19 @@
+     grad.outer.y = 0;
+     grad.outer.radius = outerRadius;
+ 
++    /*TODO optimized & malloc check*/
++    XRenderColor *colors = (XRenderColor *) malloc(numStops * sizeof(XRenderColor));
++    XFixed *stops = (XFixed *) malloc(numStops * sizeof(XFixed));
++
+     for(i=0; i < numStops; i++) {
+       stops[i] = XDoubleToFixed(fractions[i]);
+-      decodeRenderColorPre(pixels[i], &colors[i]);
++      decodeRenderColorPre(pixels[i], colors + i);
+     }
+ 
+-    xrSrcData.gradient = XRenderCreateRadialGradient(awt_display, &grad, &stops[0], &colors[0], numStops);
++    xrSrcData.gradient = XRenderCreateRadialGradient(awt_display, &grad, stops, colors, numStops);
++    free(colors);
++    free(stops);
++
+     xrSrcData.src = xrSrcData.gradient;
+ 
+     XTransform tr;
+@@ -362,11 +321,12 @@
+ 
+   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);
++    XRenderColor alphaColor;
++    alphaColor.alpha = alphaValue;
++    alphaColor.red = alphaValue;
++    alphaColor.green = alphaValue;
++    alphaColor.blue = alphaValue;
++    XRenderFillRectangle (awt_display, PictOpSrc, xrSrcData.alphaMaskPict, &alphaColor, 0, 0, 1, 1);
+     xrSrcData.alphaMask = xrSrcData.alphaMaskPict;
+   }else {
+     xrSrcData.alphaMask = None;
+@@ -430,7 +390,6 @@
+ }
+ 
+ 
+-	//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)
+@@ -498,10 +457,16 @@
+ 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 alpha = (((pixel & 0xFF000000) >> 16) + 255);
+     XFixed red =   (((pixel & 0x00FF0000) >> 8)  + 255);
+     XFixed green = (((pixel & 0x0000FF00) >> 0)  + 255);
+     XFixed blue =  (((pixel & 0x000000FF) << 8)  + 255);
++
++    /* Optimizations are based on the fact that alpha is 0xffff,
++     * but XRender maybe also optimizes if alpha==0, so we correct here in that case */
++    if(alpha == 255) {
++      alpha = 0;
++    }
+ 
+     XDouble alphaMult = XFixedToDouble(alpha);
+     color->alpha = alpha;
+@@ -516,4 +481,8 @@
+     color->red =   (((pixel & 0x00FF0000) >> 8)  + 255);
+     color->green = (((pixel & 0x0000FF00) >> 0)  + 255);
+     color->blue =  (((pixel & 0x000000FF) << 8)  + 255);
++
++    if(color->alpha == 255) {
++      color->alpha = 0;
++    }
+ }
+\ No newline at end of file
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/native/sun/java2d/x11/XRSurfaceData.h
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.h	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.h	Fri Aug 01 22:43:51 2008 +0200
+@@ -3,11 +3,9 @@
+ 
+ #define XDoubleToUShort(f)    ((unsigned short) ((f) * 65535))
+ 
++/* Holds source-parameters*/
+ typedef struct {
+-  Picture src;
+-  jboolean compRequired;
+-  XRenderColor alphaColor;
+-
++  Picture src;            /* Currently used source*/
+   Picture solid;
+   XRenderColor solidColor;
+   Picture texture;
+@@ -15,19 +13,28 @@
+ 
+   jint compRule;
+   jfloat extraAlpha;
+-  Picture alphaMask; //Only !None when eA turned on
++  Picture alphaMaskPict;  /*Reference to the 1x1 alpha Mask*/
++  Picture alphaMask;      /*Alpha-Mask which should be used for composition, either alphaMaskPict or None*/ 
+ 
+-  Picture alphaMaskPict;
+   jboolean gradCacheEnabled;
++  Pixmap gradPixmap;
++  Picture gradPict;
+ } SrcSurfaceData;
+ 
+ extern SrcSurfaceData xrSrcData;
+ extern MaskBuffer *maskBuffer;
++extern XRenderColor color_black;
+ 
++/* Composite using gradient-caching if enabled */ 
+ void XRComposite(Picture mask, Picture dest, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, unsigned int width, unsigned int height);
+ 
++/* Initializes the global source structure*/
++static void initXRSrcData();
++
++/*Decodes non-premultiplied pixel, multiplies it and stores the result in color*/
+ static void decodeRenderColor(jint pixel, XRenderColor *color);
+ 
++/*Decodes a pixel and stores the result in color*/
+ static void decodeRenderColorPre(jint pixel, XRenderColor *color);
+ 
+ #endif //XRSurfaceData_h_Included
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/native/sun/java2d/x11/XRTextRenderer_md.c
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/XRTextRenderer_md.c	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRTextRenderer_md.c	Fri Aug 01 22:43:51 2008 +0200
+@@ -44,7 +44,6 @@
+ #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))
+ 
+@@ -84,8 +83,19 @@
+   }
+ 
+    int eltCnt = -1;
+-   jint ids[numGlyphs]; 
+-   XGlyphElt32 elts[numGlyphs];
++   jint *ids; 
++   XGlyphElt32 *elts;
++
++   /*for less then 128 glyphs we allocate temorary mem on stack*/
++   jint idArray[128];
++   XGlyphElt32 eltArray[128];
++   if(numGlyphs <= 128) {
++     ids = &idArray[0];
++     elts = &eltArray[0];
++   }else {
++     ids = (jint *) malloc(numGlyphs * sizeof(jint));
++     elts = (XGlyphElt32 *) malloc(numGlyphs * sizeof(XGlyphElt32));
++   }
+ 
+    float advX = xOrigin; //xOrigin;/*Contains all advance-corrections summed up*/
+    float advY = yOrigin; //yOrigin; 
+@@ -100,7 +110,7 @@
+   }
+ 
+    XRGlyphCacheInfo *glyphCache = (grayscale == JNI_TRUE) ?  grayCache : lcdCache;
+-   jboolean cacheResult = XRGlyphCache_CacheGlyphs(glyphCache, images, numGlyphs, &ids[0]);
++   jboolean cacheResult = XRGlyphCache_CacheGlyphs(glyphCache, images, numGlyphs, ids);
+    if(cacheResult == JNI_FALSE){
+       J2dTraceLn(J2D_TRACE_INFO, "XRTextRenderer_md: Glyph caching failed");
+       return;
+@@ -116,7 +126,6 @@
+ 	 *  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) 
+@@ -165,7 +174,12 @@
+    }
+ 
+   /*TODO: Also integrate into MaskBuffer??*/
+-  XRenderCompositeText32(awt_display, PictOpOver, xrSrcData.src, xsdo->xrPic, None, 0, 0, 0, 0, &elts[0], eltCnt+1);
++  XRenderCompositeText32(awt_display, PictOpOver, xrSrcData.src, xsdo->xrPic, None, 0, 0, 0, 0, elts, eltCnt+1);
++
++  if(numGlyphs > 128) {
++    free(ids);
++    free(elts);
++  }
+ #endif
+ }
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/icedtea-xrender-003.patch	Sun Nov 30 11:58:42 2008 +0100
@@ -0,0 +1,78 @@
+# HG changeset patch
+# User ceisserer
+# Date 1217704459 -7200
+# Node ID f757686901c7e70f76bfa4860ea2e0c16d7e7252
+# Parent  4b11af86e814b7d62e9e1e19788d527987bb209c
+Summary: Added some missing mappings which caused failures in non-fastdebug mode
+
+diff -r 4b11af86e814 -r f757686901c7 make/sun/awt/mapfile-mawt-vers
+--- openjdk/jdk/make/sun/awt/mapfile-mawt-vers	Fri Aug 01 22:43:51 2008 +0200
++++ openjdk/jdk/make/sun/awt/mapfile-mawt-vers	Sat Aug 02 21:14:19 2008 +0200
+@@ -417,6 +417,36 @@
+                 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_XRSetClip;
++		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_XRRenderer_devCopyArea;
++		Java_sun_java2d_xr_XRMaskFill_maskFill;
++		Java_sun_java2d_xr_XRMaskBlit_maskBlit;
++		XRT_DrawGlyphList;
++
+                 Java_sun_java2d_opengl_OGLMaskFill_maskFill;
+                 Java_sun_java2d_opengl_OGLRenderer_drawPoly;
+                 Java_sun_java2d_opengl_OGLRenderQueue_flushBuffer;
+diff -r 4b11af86e814 -r f757686901c7 make/sun/headless/mapfile-vers
+--- openjdk/jdk/make/sun/headless/mapfile-vers	Fri Aug 01 22:43:51 2008 +0200
++++ openjdk/jdk/make/sun/headless/mapfile-vers	Sat Aug 02 21:14:19 2008 +0200
+@@ -57,6 +57,8 @@
+                 Java_sun_java2d_x11_X11SurfaceData_XSetXorMode;
+                 Java_sun_java2d_x11_X11SurfaceData_XSetForeground;
+ 
++		XRT_DrawGlyphList;
++
+ 		X11SurfaceData_GetOps;
+ 		Java_java_awt_Font_initIDs;
+                 Java_sun_font_FontManager_getFontConfig;
+diff -r 4b11af86e814 -r f757686901c7 make/sun/xawt/mapfile-vers
+--- openjdk/jdk/make/sun/xawt/mapfile-vers	Fri Aug 01 22:43:51 2008 +0200
++++ openjdk/jdk/make/sun/xawt/mapfile-vers	Sat Aug 02 21:14:19 2008 +0200
+@@ -356,6 +356,7 @@
+         Java_sun_java2d_xr_XRSurfaceData_XRSetComposite;
+         Java_sun_java2d_xr_XRSurfaceData_initIDs;
+         Java_sun_java2d_xr_XRSurfaceData_XRInitSurface;
++	Java_sun_java2d_xr_XRSurfaceData_XRSetClip;
+ 	Java_sun_java2d_xr_XRSurfaceData_XRResetClip;
+ 	Java_sun_java2d_xr_XRSurfaceData_XRSetTransformNative;
+         Java_sun_java2d_xr_XRSurfaceData_XRSetFilter;
+@@ -370,6 +371,7 @@
+ 	Java_sun_java2d_xr_XRRenderer_XRFillSpans;
+         Java_sun_java2d_xr_XRRenderer_XRDoPath;
+ 	Java_sun_java2d_xr_XRRenderer_XRDrawLine;
++        Java_sun_java2d_xr_XRRenderer_devCopyArea;
+         Java_sun_java2d_xr_XRMaskFill_maskFill;
+ 	Java_sun_java2d_xr_XRMaskBlit_maskBlit;
+ 	XRT_DrawGlyphList;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/icedtea-xrender-004.patch	Sun Nov 30 11:58:42 2008 +0100
@@ -0,0 +1,86 @@
+# HG changeset patch
+# User ceisserer
+# Date 1217866603 -7200
+# Node ID cf291c1144545d190c719d31a709cf32968ade59
+# Parent  f757686901c7e70f76bfa4860ea2e0c16d7e7252
+Summary: Added some comments
+
+diff -r f757686901c7 -r cf291c114454 make/sun/awt/mapfile-mawt-vers
+--- openjdk/jdk/make/sun/awt/mapfile-mawt-vers	Sat Aug 02 21:14:19 2008 +0200
++++ openjdk/jdk/make/sun/awt/mapfile-mawt-vers	Mon Aug 04 18:16:43 2008 +0200
+@@ -445,7 +445,6 @@
+         	Java_sun_java2d_xr_XRRenderer_devCopyArea;
+ 		Java_sun_java2d_xr_XRMaskFill_maskFill;
+ 		Java_sun_java2d_xr_XRMaskBlit_maskBlit;
+-		XRT_DrawGlyphList;
+ 
+                 Java_sun_java2d_opengl_OGLMaskFill_maskFill;
+                 Java_sun_java2d_opengl_OGLRenderer_drawPoly;
+@@ -541,6 +540,7 @@
+                 AWTCharAscent;
+                 AWTCharDescent;
+                 AWTDrawGlyphList;
++		XRT_DrawGlyphList;
+ 
+ 	local:
+ 		*;
+diff -r f757686901c7 -r cf291c114454 make/sun/awt/mapfile-vers-linux
+--- openjdk/jdk/make/sun/awt/mapfile-vers-linux	Sat Aug 02 21:14:19 2008 +0200
++++ openjdk/jdk/make/sun/awt/mapfile-vers-linux	Mon Aug 04 18:16:43 2008 +0200
+@@ -568,6 +568,7 @@
+                 AWTCharAscent;
+                 AWTCharDescent;
+                 AWTDrawGlyphList;
++		XRT_DrawGlyphList;
+ 
+ 	local:
+ 		*;
+diff -r f757686901c7 -r cf291c114454 make/sun/headless/mapfile-vers
+--- openjdk/jdk/make/sun/headless/mapfile-vers	Sat Aug 02 21:14:19 2008 +0200
++++ openjdk/jdk/make/sun/headless/mapfile-vers	Mon Aug 04 18:16:43 2008 +0200
+@@ -57,8 +57,6 @@
+                 Java_sun_java2d_x11_X11SurfaceData_XSetXorMode;
+                 Java_sun_java2d_x11_X11SurfaceData_XSetForeground;
+ 
+-		XRT_DrawGlyphList;
+-
+ 		X11SurfaceData_GetOps;
+ 		Java_java_awt_Font_initIDs;
+                 Java_sun_font_FontManager_getFontConfig;
+@@ -100,6 +98,7 @@
+                 AWTCharAscent;
+                 AWTCharDescent;
+                 AWTDrawGlyphList;
++		XRT_DrawGlyphList;
+ 
+ 
+ 	local:
+diff -r f757686901c7 -r cf291c114454 src/solaris/native/sun/java2d/x11/XRPMBlitLoops.c
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/XRPMBlitLoops.c	Sat Aug 02 21:14:19 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRPMBlitLoops.c	Mon Aug 04 18:16:43 2008 +0200
+@@ -67,6 +67,9 @@
+ 
+ 
+ #ifndef HEADLESS
++/**
++ * Prepares a mask-picture according to the mask and the properties currently set, which is used for composition later.
++ */
+ static Picture prepareMaskPM(JNIEnv *env, jbyteArray maskArray, jint maskoff, jint maskscan, jint w, jint h)
+ {
+     int line, pix;
+@@ -107,6 +110,7 @@
+             }
+           }
+ 
++          /*Upload Image to X-Server*/
+           XPutImage(awt_display, maskBuffer->maskPixmap, maskBuffer->maskGC, img, 0, 0, 0, 0, w, h);
+           (*env)->ReleasePrimitiveArrayCritical(env, maskArray, mask, JNI_ABORT);
+ 
+@@ -124,6 +128,7 @@
+         }
+     }else
+     {
++      /*If we haven't got a mask (full coverage), we have to return the EA mask, if EA is used*/
+       if(useEA) {
+         return xrSrcData.alphaMask;
+       }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/icedtea-xrender-005.patch	Sun Nov 30 11:58:42 2008 +0100
@@ -0,0 +1,18 @@
+# HG changeset patch
+# User ceisserer
+# Date 1217885774 -7200
+# Node ID 8463c586ceaf12e5bc9d49e916a300c5b2a3ef81
+# Parent  cf291c1144545d190c719d31a709cf32968ade59
+Summary: Fixed Solaris build error
+
+diff -r cf291c114454 -r 8463c586ceaf make/sun/awt/FILES_c_unix.gmk
+--- openjdk/jdk/make/sun/awt/FILES_c_unix.gmk	Mon Aug 04 18:16:43 2008 +0200
++++ openjdk/jdk/make/sun/awt/FILES_c_unix.gmk	Mon Aug 04 23:36:14 2008 +0200
+@@ -212,6 +212,7 @@
+ 	X11SurfaceData.c \
+ 	X11FontScaler_md.c \
+ 	X11TextRenderer_md.c \
++        XRTextRenderer_md.c \
+         OGLBlitLoops.c \
+         OGLBufImgOps.c \
+         OGLContext.c \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/icedtea-xrender-006.patch	Sun Nov 30 11:58:42 2008 +0100
@@ -0,0 +1,295 @@
+# HG changeset patch
+# User ceisserer
+# Date 1217901941 -7200
+# Node ID 2e58d73ce3ffd0301067d097ba443910c387c8d5
+# Parent  8463c586ceaf12e5bc9d49e916a300c5b2a3ef81
+Summary: Added copyright / gpl2 header
+
+diff -r 8463c586ceaf -r 2e58d73ce3ff src/solaris/classes/sun/java2d/xr/XRDrawImage.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRDrawImage.java	Mon Aug 04 23:36:14 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRDrawImage.java	Tue Aug 05 04:05:41 2008 +0200
+@@ -1,3 +1,28 @@
++/*
++ * Copyright 2003-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.*;
+diff -r 8463c586ceaf -r 2e58d73ce3ff src/solaris/classes/sun/java2d/xr/XRMaskBlit.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRMaskBlit.java	Mon Aug 04 23:36:14 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRMaskBlit.java	Tue Aug 05 04:05:41 2008 +0200
+@@ -1,3 +1,28 @@
++/*
++ * Copyright 2003-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 static sun.java2d.loops.CompositeType.SrcNoEa;
+diff -r 8463c586ceaf -r 2e58d73ce3ff src/solaris/classes/sun/java2d/xr/XRMaskFill.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRMaskFill.java	Mon Aug 04 23:36:14 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRMaskFill.java	Tue Aug 05 04:05:41 2008 +0200
+@@ -1,3 +1,28 @@
++/*
++ * Copyright 2003-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 static sun.java2d.loops.CompositeType.SrcNoEa;
+diff -r 8463c586ceaf -r 2e58d73ce3ff src/solaris/classes/sun/java2d/xr/XRRenderer.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRRenderer.java	Mon Aug 04 23:36:14 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRRenderer.java	Tue Aug 05 04:05:41 2008 +0200
+@@ -1,3 +1,28 @@
++/*
++ * Copyright 2003-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.*;
+diff -r 8463c586ceaf -r 2e58d73ce3ff src/solaris/classes/sun/java2d/xr/XRUtils.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRUtils.java	Mon Aug 04 23:36:14 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRUtils.java	Tue Aug 05 04:05:41 2008 +0200
+@@ -1,3 +1,28 @@
++/*
++ * Copyright 2003-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 static java.awt.AlphaComposite.*;
+diff -r 8463c586ceaf -r 2e58d73ce3ff src/solaris/native/sun/java2d/x11/XRGlyphCache.c
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/XRGlyphCache.c	Mon Aug 04 23:36:14 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRGlyphCache.c	Tue Aug 05 04:05:41 2008 +0200
+@@ -1,3 +1,28 @@
++/*
++ * Copyright 2001-2003 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 <malloc.h>
+ #include "jni.h"
+ #include "XRGlyphCache.h"
+diff -r 8463c586ceaf -r 2e58d73ce3ff src/solaris/native/sun/java2d/x11/XRGlyphCache.h
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/XRGlyphCache.h	Mon Aug 04 23:36:14 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRGlyphCache.h	Tue Aug 05 04:05:41 2008 +0200
+@@ -1,3 +1,28 @@
++/*
++ * Copyright 2001-2003 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.
++ */
++
+ #ifndef XRGlyphCache_h_Included
+ #define XRGlyphCache_h_Included
+ 
+diff -r 8463c586ceaf -r 2e58d73ce3ff src/solaris/native/sun/java2d/x11/XRSurfaceData.c
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.c	Mon Aug 04 23:36:14 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.c	Tue Aug 05 04:05:41 2008 +0200
+@@ -1,3 +1,28 @@
++/*
++ * Copyright 2001-2003 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 "GraphicsPrimitiveMgr.h"
+ #include "Region.h"
+ #include "Trace.h"
+diff -r 8463c586ceaf -r 2e58d73ce3ff src/solaris/native/sun/java2d/x11/XRSurfaceData.h
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.h	Mon Aug 04 23:36:14 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.h	Tue Aug 05 04:05:41 2008 +0200
+@@ -1,3 +1,28 @@
++/*
++ * Copyright 2001-2003 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.
++ */
++
+ #ifndef XRSurfaceData_h_Included
+ #define XRSurfaceData_h_Included
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/icedtea-xrender-007.patch	Sun Nov 30 11:58:42 2008 +0100
@@ -0,0 +1,1143 @@
+# HG changeset patch
+# User ceisserer
+# Date 1224775518 -7200
+# Node ID d6ab5f9f96efa37a823e071a27e3555557930203
+# Parent  2e58d73ce3ffd0301067d097ba443910c387c8d5
+TransformedBlit rewrite
+
+diff -r 2e58d73ce3ff -r d6ab5f9f96ef src/solaris/classes/sun/java2d/xr/XRDrawImage.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRDrawImage.java	Tue Aug 05 04:05:41 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRDrawImage.java	Thu Oct 23 17:25:18 2008 +0200
+@@ -42,13 +42,10 @@
+ 	SurfaceData srcData = dstData.getSourceSurfaceData(img,
+ 		SunGraphics2D.TRANSFORM_GENERIC, sg.imageComp, bgColor);
+ 
+-	if (srcData != null && !isBgOperation(srcData, bgColor)
++	if (srcData != null && !isBgOperation(srcData, bgColor) // TODO: Don't bail out on bg-blits
+ 		&& 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);
+diff -r 2e58d73ce3ff -r d6ab5f9f96ef src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java	Tue Aug 05 04:05:41 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java	Thu Oct 23 17:25:18 2008 +0200
+@@ -42,35 +42,25 @@
+     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 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 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),
+-	};
++		new X11PMTransformedBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntRgbX11),
++		new X11PMTransformedBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntArgbX11),
++		new X11PMTransformedBlit(XRSurfaceData.IntArgbX11, XRSurfaceData.IntRgbX11),
++		new X11PMTransformedBlit(XRSurfaceData.IntArgbX11, XRSurfaceData.IntArgbX11), };
+ 	GraphicsPrimitiveMgr.register(primitives);
+     }
+ 
+-    public static native void nativeRenderBlit(long srcData, long dstData,
+-	    int sx, int sy, int dx, int dy, int w, int h);
++    public static native void nativeRenderBlit(long srcData, long dstData, int sx, int sy, int dx, int dy, int w, int h);
++
++    public static native void nativeTransformedRenderBlit(long srcData, long dstData, int sx, int sy, int dx, int dy, int w, int h, int m00, int m01,
++	    int m02, int m10, int m11, int m12, int maskWidth, int maskHeight, int lastMaskWidth, int lastMaskHeight);
+ }
+ 
+ class X11PMBlit extends Blit {
+@@ -78,8 +68,7 @@
+ 	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) {
++    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();
+ 
+@@ -89,8 +78,7 @@
+ 
+ 	    x11sdSrc.validateAsSource(null, XRUtils.RepeatNone, XRUtils.FAST);
+ 
+-	    XRPMBlitLoops.nativeRenderBlit(src.getNativeOps(), dst
+-		    .getNativeOps(), sx, sy, dx, dy, w, h);
++	    XRPMBlitLoops.nativeRenderBlit(src.getNativeOps(), dst.getNativeOps(), sx, sy, dx, dy, w, h);
+ 	} finally {
+ 	    SunToolkit.awtUnlock();
+ 	}
+@@ -101,10 +89,9 @@
+     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) {
++    
++    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();
+ 
+@@ -120,14 +107,13 @@
+ 	    sy1 *= yScale;
+ 	    sy2 *= yScale;
+ 
+-	    AffineTransform xForm = AffineTransform.getScaleInstance(
+-		    1 / xScale, 1 / 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));
++	    /*TODO: This breaks non-integer scaled images*/
++	    XRPMBlitLoops.nativeRenderBlit(src.getNativeOps(), dst.getNativeOps(), (int) sx1, (int) sy1, (int) dx1, (int) dy1, (int) (dx2 - dx1),
++		    (int) (dy2 - dy1));
+ 
+ 	} finally {
+ 	    SunToolkit.awtUnlock();
+@@ -145,59 +131,90 @@
+ 	super(srcType, CompositeType.AnyAlpha, dstType);
+     }
+ 
+-    public void Transform(SurfaceData src, SurfaceData dst, Composite comp,
+-	    Region clip, AffineTransform xform, int hint, int srcx, int srcy,
++    static int lastMaskWidth = 0, lastMaskHeight = 0;
++
++    /**
++     * Possible optimizations: 
++     * - Nearest interpolation -> ExtraAlpha mit 1x1 maske durchführen
++     * - Mehere Maskengroessen anlegen, und skalieren
++     * - Ueberpruefen ob aktueller Maskeninhalt mit skalierung passen wuerde, bzw. nur so viel aendern bis passt (wenn bereich < maske)
++     * - Aendering entweder mit 2 filLRects, oder nur 1 fillrect je nach groesse
++     */
++    
++    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();
++
++	    int xrInterpolationType = XRUtils.ATransOpToXRQuality(hint);
+ 
+ 	    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);
++	    Rectangle2D.Float rect = new Rectangle2D.Float(dstx, dsty, width, height);
++	    Shape shp = xform.createTransformedShape(rect);
++	    Rectangle bounds = shp.getBounds();
++
++	    AffineTransform trx = AffineTransform.getTranslateInstance((-bounds.x), (-bounds.y));
++	    trx.concatenate(xform);
++	    AffineTransform maskTX = (AffineTransform) trx.clone();
++
++	    trx.translate(-srcx, -srcy);
++
+ 	    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();
++		trx.invert();
++	    } catch (NoninvertibleTransformException ex) {
++		trx.setToIdentity();
++		System.err.println("Reseted to identity!");
++	    }
+ 
+-		AffineTransform sourceTrans = (AffineTransform) xform.clone();
+-		sourceTrans.translate(-srcx, -srcy);
++	    boolean omitMask = isMaskOmittable(trx, comp, xrInterpolationType);
+ 
+-		try
+-		{
+-		     sourceTrans.invert();
+-		}catch(NoninvertibleTransformException ex)
+-		{
+-		    sourceTrans.setToIdentity();
++	    if (!omitMask) {
++		int maskWidth = Math.max(width / 8, 1);
++		int maskHeight = Math.max(height / 8, 1);
++		maskTX.scale(((double) width) / maskWidth, ((double) height) / maskHeight);
++
++		try {
++		    maskTX.invert();
++		} catch (NoninvertibleTransformException ex) {
++		    maskTX.setToIdentity();
++		    System.err.println("Reseted to identity!");
+ 		}
+ 
+-		x11sdSrc.validateAsSource(sourceTrans, XRUtils.RepeatNone);
++		x11sdSrc.validateAsSource(trx, XRUtils.RepeatPad, xrInterpolationType);
+ 
+-		if (needClip) {
+-		    x11sdDst.setShapeClip(shp);
+-		}
++		XRPMBlitLoops.nativeTransformedRenderBlit(src.getNativeOps(), dst.getNativeOps(), 0, 0, bounds.x, bounds.y, bounds.width,
++			bounds.height, XRUtils.XDoubleToFixed(maskTX.getScaleX()), XRUtils.XDoubleToFixed(maskTX.getShearX()), XRUtils
++				.XDoubleToFixed(maskTX.getTranslateX()), XRUtils.XDoubleToFixed(maskTX.getShearY()), XRUtils.XDoubleToFixed(maskTX
++				.getScaleY()), XRUtils.XDoubleToFixed(maskTX.getTranslateY()), maskWidth, maskHeight, lastMaskWidth, lastMaskHeight);
+ 
+-		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));
++		lastMaskWidth = maskWidth;
++		lastMaskHeight = maskHeight;
++	    } else {
++		int repeat = xrInterpolationType <= XRUtils.FAST ? XRUtils.RepeatNone : XRUtils.RepeatPad;
++		x11sdSrc.validateAsSource(trx, repeat, xrInterpolationType);
++		XRPMBlitLoops.nativeTransformedRenderBlit(src.getNativeOps(), dst.getNativeOps(), 0, 0, bounds.x, bounds.y, bounds.width,
++			bounds.height, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0);
++	    }
+ 
+-		if (needClip) {
+-		    x11sdDst.resetShapeClip();
+-		}
+-
+-	    } catch (Exception ex) {
+-		ex.printStackTrace();
+-	    }
+ 	} finally {
+ 	    SunToolkit.awtUnlock();
+ 	}
+     }
++
++    protected static boolean isMaskOmittable(AffineTransform trx, Composite comp, int interpolation) {
++	return (interpolation <= XRUtils.FAST || trx.getTranslateX() == (int) trx.getTranslateX() /*
++												     * If
++												     * translate
++												     * is
++												     * integer only
++												     */
++		&& trx.getTranslateY() == (int) trx.getTranslateY() && (trx.getShearX() == 0 && trx.getShearY() == 0 // Only
++															// "90°"
++															// rotation
++		|| trx.getShearX() == -trx.getShearY())) && ((AlphaComposite) comp).getAlpha() == 1.0f; // No
++													// ExtraAlpha!=1
++    }
+ }
+\ No newline at end of file
+diff -r 2e58d73ce3ff -r d6ab5f9f96ef src/solaris/classes/sun/java2d/xr/XRSurfaceData.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceData.java	Tue Aug 05 04:05:41 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceData.java	Thu Oct 23 17:25:18 2008 +0200
+@@ -50,8 +50,7 @@
+ 
+     private static native void initIDs(boolean gradCache);
+ 
+-    protected native void XRInitSurface(int depth, int width, int height,
+-	    long drawable, int pictFormat);
++    protected native void XRInitSurface(int depth, int width, int height, long drawable, int pictFormat);
+ 
+     native void XRInitXRender(long xsdo, int pictForm);
+ 
+@@ -110,12 +109,13 @@
+ 	TextPipe textpipe;
+ 	boolean validated = false;
+ 
+-	/* The textpipe for now can't handle TexturePaint when extra-alpha is specified nore XOR mode*/
++	/*
++	 * The textpipe for now can't handle TexturePaint when extra-alpha is
++	 * specified nore XOR mode
++	 */
+ 	if (sg2d.compositeState < SunGraphics2D.COMP_XOR
+-		&& (sg2d.paintState < SunGraphics2D.PAINT_TEXTURE
+-		|| sg2d.composite == null
+-		|| !(sg2d.composite instanceof AlphaComposite)
+-		|| ((AlphaComposite) sg2d.composite).getAlpha() == 1.0f)) {
++		&& (sg2d.paintState < SunGraphics2D.PAINT_TEXTURE || sg2d.composite == null || !(sg2d.composite instanceof AlphaComposite) || ((AlphaComposite) sg2d.composite)
++			.getAlpha() == 1.0f)) {
+ 	    textpipe = xrtextpipe;
+ 	} else {
+ 	    super.validatePipe(sg2d);
+@@ -167,8 +167,8 @@
+     }
+ 
+     /**
+-     * Returns an accalerated MaskFill object if the current paint
+-     *  is supported by the pipeline.
++     * Returns an accalerated MaskFill object if the current paint is supported
++     * by the pipeline.
+      */
+     protected MaskFill getMaskFill(SunGraphics2D sg2d) {
+ 	if (sg2d.paintState > SunGraphics2D.PAINT_ALPHACOLOR && !isPaintValid(sg2d)) {
+@@ -178,8 +178,7 @@
+     }
+ 
+     public RenderLoops getRenderLoops(SunGraphics2D sg2d) {
+-	if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR
+-		&& sg2d.compositeState <= SunGraphics2D.COMP_ALPHA) {
++	if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR && sg2d.compositeState <= SunGraphics2D.COMP_ALPHA) {
+ 	    return solidloops;
+ 	}
+ 
+@@ -199,28 +198,24 @@
+     }
+ 
+     /**
+-     * Method for instantiating a Pixmap SurfaceData (offscreen).
+-     * If the surface is opaque a 24-bit/RGB surface is chosen, 
+-     * otherwise a 32-bit ARGB surface.
++     * Method for instantiating a Pixmap SurfaceData (offscreen). If the surface
++     * is opaque a 24-bit/RGB surface is chosen, otherwise a 32-bit ARGB
++     * surface.
+      */
+-    public static XRPixmapSurfaceData createData(XRGraphicsConfig gc,
+-	    int width, int height, ColorModel cm, Image image, long drawable,
++    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);
++	    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);
++	return new XRPixmapSurfaceData(gc, width, height, image, getSurfaceType(gc, transparency), cm, drawable, transparency, XRUtils
++		.getPictureFormatForTransparency(transparency), depth);
+     }
+ 
+-    protected XRSurfaceData(X11ComponentPeer peer, XRGraphicsConfig gc,
+-	    SurfaceType sType, ColorModel cm, int depth, int transparency) {
++    protected XRSurfaceData(X11ComponentPeer peer, XRGraphicsConfig gc, SurfaceType sType, ColorModel cm, int depth, int transparency) {
+ 	super(sType, cm);
+ 	this.peer = peer;
+ 	this.graphicsConfig = gc;
+@@ -233,6 +228,7 @@
+ 
+     /**
+      * Inits the XRender-data-structures which belong to the XRSurfaceData.
++     * 
+      * @param pictureFormat
+      */
+     public void initXRender(int pictureFormat) {
+@@ -248,8 +244,7 @@
+ 	if (peer != null) {
+ 	    return (XRGraphicsConfig) peer.getGraphicsConfiguration();
+ 	} else {
+-	    GraphicsEnvironment env = GraphicsEnvironment
+-		    .getLocalGraphicsEnvironment();
++	    GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
+ 	    GraphicsDevice gd = env.getDefaultScreenDevice();
+ 	    return (XRGraphicsConfig) gd.getDefaultConfiguration();
+ 	}
+@@ -269,16 +264,14 @@
+     public abstract boolean canSourceSendExposures(int x, int y, int w, int h);
+ 
+     /**
+-     * CopyArea is implemented using the "old" X11 GC, 
+-     * therefor clip and needExposures have to be validated against that GC.
+-     * Pictures and GCs don't share state.
++     * CopyArea is implemented using the "old" X11 GC, therefor clip and
++     * needExposures have to be validated against that GC. Pictures and GCs
++     * don't share state.
+      */
+     public void validateCopyAreaGC(Region gcClip, boolean needExposures) {
+ 	if (validatedGCClip != gcClip) {
+ 	    if (gcClip != null) {
+-		XSetClip(xgc, gcClip.getLoX(), gcClip.getLoY(),
+-			gcClip.getHiX(), gcClip.getHiY(), 
+-			gcClip.isRectangular() ? null : gcClip);
++		XSetClip(xgc, gcClip.getLoX(), gcClip.getLoY(), gcClip.getHiX(), gcClip.getHiY(), gcClip.isRectangular() ? null : gcClip);
+ 	    } else {
+ 		XResetClip(xgc);
+ 	    }
+@@ -291,8 +284,7 @@
+ 	}
+     }
+ 
+-    public boolean copyArea(SunGraphics2D sg2d, int x, int y, int w, int h,
+-	    int dx, int dy) {
++    public boolean copyArea(SunGraphics2D sg2d, int x, int y, int w, int h, int dx, int dy) {
+ 	if (xrpipe == null) {
+ 	    if (!isXRDrawableValid()) {
+ 		return true;
+@@ -301,16 +293,14 @@
+ 	}
+ 	CompositeType comptype = sg2d.imageComp;
+ 	if (sg2d.transformState < SunGraphics2D.TRANSFORM_TRANSLATESCALE
+-		&& (CompositeType.SrcOverNoEa.equals(comptype) || CompositeType.SrcNoEa
+-			.equals(comptype))) {
++		&& (CompositeType.SrcOverNoEa.equals(comptype) || CompositeType.SrcNoEa.equals(comptype))) {
+ 	    x += sg2d.transX;
+ 	    y += sg2d.transY;
+ 	    try {
+ 		SunToolkit.awtLock();
+ 		boolean needExposures = canSourceSendExposures(x, y, w, h);
+ 		validateCopyAreaGC(sg2d.getCompClip(), needExposures);
+-		xrpipe.devCopyArea(getNativeOps(), xgc, x, y, x + dx, y + dy,
+-			w, h);
++		xrpipe.devCopyArea(getNativeOps(), xgc, x, y, x + dx, y + dy, w, h);
+ 	    } finally {
+ 		SunToolkit.awtUnlock();
+ 	    }
+@@ -320,11 +310,10 @@
+     }
+ 
+     /**
+-     * Returns the XRender SurfaceType which is able to fullfill the
+-     * specified transparency requirement.
++     * Returns the XRender SurfaceType which is able to fullfill the specified
++     * transparency requirement.
+      */
+-    public static SurfaceType getSurfaceType(XRGraphicsConfig gc,
+-	    int transparency) {
++    public static SurfaceType getSurfaceType(XRGraphicsConfig gc, int transparency) {
+ 	SurfaceType sType = null;
+ 
+ 	switch (transparency) {
+@@ -355,45 +344,35 @@
+ 
+     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 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 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 static native void XRSetFilter(long xsdo, int value);
+-    
+-    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 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);
++
++    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 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);
+ 
+     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]));
++	XRSetTransformNative(getNativeOps(), XDoubleToFixed(transformData[0]), XDoubleToFixed(transformData[2]), XDoubleToFixed(transformData[4]),
++		XDoubleToFixed(transformData[1]), XDoubleToFixed(transformData[3]), XDoubleToFixed(transformData[5]));
+     }
+ 
+-    private long xgc; //GC is still used for copyArea
++    private long xgc; // GC is still used for copyArea
+ 
+     public static int validatedPixel = -1;
+     public static int validatedPaintState = -1;
+@@ -410,35 +389,37 @@
+     private AffineTransform validatedSourceTransform = new AffineTransform();
+     private int validatedRepeat = XRUtils.RepeatNone;
+     private int validatedInterpolation = -1;
+-    /*Used if API does not allow to pass interpolation value at the level needed*/
++    /*
++     * Used if API does not allow to pass interpolation value at the level
++     * needed
++     */
+     private int preferredInterpolation = -1;
+ 
+     public void setPreferredInterpolation(int interpolation) {
+ 	this.preferredInterpolation = interpolation;
+     }
+-    
+-    
++
+     /*
+-     * For now those shape-clips are used for transformed images,
+-     * because transformed image for now would invalidate a much larger area that they are intended to do.
+-     * However as soon as the transformed-mask approach I am working on turns out
+-     * to work well, those will be dropped.
++     * For now those shape-clips are used for transformed images, because
++     * transformed image for now would invalidate a much larger area that they
++     * are intended to do. However as soon as the transformed-mask approach I am
++     * working on turns out to work well, those will be dropped.
+      */
+     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);
++	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);
++	XRSetClip(getNativeOps(), validatedClip.getLoX(), validatedClip.getLoY(), validatedClip.getHiX(), validatedClip.getHiY(), validatedClip
++		.isRectangular() ? null : validatedClip);
+     }
+ 
+     /**
+-     * Validate the source with the preferred interpolation set sometimes earlier.
++     * Validate the source with the preferred interpolation set sometimes
++     * earlier.
++     * 
+      * @param sxForm
+      * @param repeat
+      */
+@@ -447,35 +428,40 @@
+     }
+ 
+     /**
+-     * Validates an XRSurfaceData when used as source.
+-     * Note that the clip is applied when used as source as well as destination.
++     * Validates an XRSurfaceData when used as source. Note that the clip is
++     * applied when used as source as well as destination.
+      */
+     void validateAsSource(AffineTransform sxForm, int repeat, int interpolation) {
++	// System.out.println("Source:
++	// "+getBounds().width+"/"+getBounds().height);
++
+ 	if (validatedClip != null) {
+ 	    validatedClip = null;
+ 	    XRResetClip(getNativeOps());
++	    // System.out.println("Clip ge-reseted");
+ 	}
+ 
+ 	if (validatedRepeat != repeat) {
+ 	    validatedRepeat = repeat;
+ 	    XRSetRepeat(getNativeOps(), repeat);
++	    // System.out.println("Repeat ge-reseted");
+ 	}
+ 
+ 	if (sxForm == null) {
+ 	    if (transformInUse) {
+ 		validatedSourceTransform.setToIdentity();
++		// System.out.println("Transform ge-reseted");
+ 		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());
+-		
++	    if (!transformInUse || (transformInUse && !sxForm.equals(validatedSourceTransform))) {
++
++		// System.out.println("Setze transform: "+sxForm);
++
++		validatedSourceTransform.setTransform(sxForm.getScaleX(), sxForm.getShearY(), sxForm.getShearX(), sxForm.getScaleY(), sxForm
++			.getTranslateX(), sxForm.getTranslateY());
++
+ 		XRSetTransform(validatedSourceTransform);
+ 		transformInUse = true;
+ 	    }
+@@ -488,8 +474,9 @@
+     }
+ 
+     /**
+-     * Utility method for setting the Composite,
+-     * passing down the arguments to the native method.
++     * Utility method for setting the Composite, passing down the arguments to
++     * the native method.
++     * 
+      * @param comp
+      */
+     private void setComposite(Composite comp) {
+@@ -497,12 +484,9 @@
+ 	    AlphaComposite aComp = (AlphaComposite) comp;
+ 	    validatedExtraAlpha = aComp.getAlpha();
+ 
+-	    XRSetComposite(XRUtils.j2dAlphaCompToXR(aComp.getRule()),
+-		    validatedExtraAlpha);
++	    XRSetComposite(XRUtils.j2dAlphaCompToXR(aComp.getRule()), validatedExtraAlpha);
+ 	} else {
+-	    throw new InternalError(
+-		    "Composite accaleration not implemented for: "
+-			    + comp.getClass().getName());
++	    throw new InternalError("Composite accaleration not implemented for: " + comp.getClass().getName());
+ 	}
+     }
+ 
+@@ -537,10 +521,10 @@
+ 
+ 	return ((a << 24) | (r << 16) | (g << 8) | (b));
+     }
+-    
++
+     /**
+-     * The currently only known paint XRender can't support are
+-     * radial gradients where focus and center paint differ.
++     * The currently only known paint XRender can't support are radial gradients
++     * where focus and center paint differ.
+      */
+     public static boolean isPaintValid(SunGraphics2D sg2d) {
+ 	if (sg2d.paintState == SunGraphics2D.PAINT_RAD_GRADIENT) {
+@@ -551,14 +535,11 @@
+     }
+ 
+     /**
+-     * Sets a 2-stop gradient.
+-     * Utility method generating the by the native method expected
+-     * parameters and calling it.
++     * Sets a 2-stop gradient. Utility method generating the by the native
++     * method expected parameters and calling it.
+      */
+-    private void setGradientPaint(SunGraphics2D sg2d, GradientPaint paint,
+-	    boolean useMask) {
+-	int[] pixels = convertToIntArgbPixels(new Color[] { paint.getColor1(),
+-		paint.getColor2() }, false);
++    private 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;
+@@ -577,27 +558,19 @@
+ 	double[] transformData = new double[6];
+ 	at.getMatrix(transformData);
+ 
+-	int repeat = paint.isCyclic() ? XRUtils.RepeatReflect
+-		: XRUtils.RepeatPad;
++	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]),
++	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]));
+     }
+-    
++
+     /**
+-     * Sets a n-stop linear gradient.
+-     * Utility method generating the by the native method expected
+-     * parameters and calling it.
++     * Sets a n-stop linear gradient. Utility method generating the by the
++     * native method expected parameters and calling it.
+      */
+-    public void setLinearGradientPaint(SunGraphics2D sg2d,
+-	    LinearGradientPaint paint, boolean useMask) {
++    public void setLinearGradientPaint(SunGraphics2D sg2d, LinearGradientPaint paint, boolean useMask) {
+ 	boolean linear = (paint.getColorSpace() == ColorSpaceType.LINEAR_RGB);
+ 	Color[] colors = paint.getColors();
+ 	int numStops = colors.length;
+@@ -607,8 +580,7 @@
+ 	AffineTransform at = paint.getTransform();
+ 	at.preConcatenate(sg2d.transform);
+ 
+-	int cycleMethod = XRUtils.getRepeatForCycleMethod(paint
+-		.getCycleMethod());
++	int cycleMethod = XRUtils.getRepeatForCycleMethod(paint.getCycleMethod());
+ 	float[] fractions = paint.getFractions();
+ 	int[] pixels = convertToIntArgbPixels(colors, linear);
+ 
+@@ -621,32 +593,24 @@
+ 	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]));
++	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]));
+     }
+ 
+     /**
+-     * Sets a Radial Gradient where focus and center point match.
+-     * Utility method generating the by the native method expected
+-     * parameters and calling it.
++     * Sets a Radial Gradient where focus and center point match. Utility method
++     * generating the by the native method expected parameters and calling it.
+      */
+-    public void setRadialGradientPaint(SunGraphics2D sg2d,
+-	    RadialGradientPaint paint) {
++    public 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());
++	int cycleMethod = XRUtils.getRepeatForCycleMethod(paint.getCycleMethod());
+ 	float[] fractions = paint.getFractions();
+ 	int[] pixels = convertToIntArgbPixels(colors, linear);
+ 	float radius = paint.getRadius();
+@@ -683,28 +647,19 @@
+ 	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]));
++	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]));
+     }
+ 
+-    private TexturePaint setTexturePaint(SunGraphics2D sg2d,
+-	    TexturePaint paint, boolean useMask) {
++    private 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);
++	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);
++	    srcData = dstData.getSourceSurfaceData(paint.getImage(), SunGraphics2D.TRANSFORM_ISIDENT, CompositeType.SrcOver, null);
+ 	    if (!(srcData instanceof XRSurfaceData)) {
+ 		return null;
+ 	    }
+@@ -715,17 +670,15 @@
+ 	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()));
+-	
++	at.scale(anchor.getWidth() / ((double) bi.getWidth()), anchor.getHeight() / ((double) bi.getHeight()));
++
+ 	try {
+ 	    at.invert();
+ 	} catch (NoninvertibleTransformException ex) {
+ 	    at.setToIdentity(); /* TODO: Right thing to do in this case? */
+ 	}
+ 
+-	x11SrcData.validateAsSource(at, XRUtils.RepeatNormal, 
+-		XRUtils.ATransOpToXRQuality(sg2d.interpolationType));
++	x11SrcData.validateAsSource(at, XRUtils.RepeatNormal, XRUtils.ATransOpToXRQuality(sg2d.interpolationType));
+ 
+ 	XRSetTexturePaint(srcData.getNativeOps());
+ 
+@@ -733,8 +686,9 @@
+     }
+ 
+     /**
+-     * Sets the paint as source.
+-     * Checks the type of paint and calls the appropriate set*Paint method.
++     * Sets the paint as source. Checks the type of paint and calls the
++     * appropriate set*Paint method.
++     * 
+      * @param sg2d
+      * @param paint
+      */
+@@ -750,8 +704,7 @@
+ 		    break;
+ 
+ 		case SunGraphics2D.PAINT_LIN_GRADIENT:
+-		    setLinearGradientPaint(sg2d, (LinearGradientPaint) paint,
+-			    false);
++		    setLinearGradientPaint(sg2d, (LinearGradientPaint) paint, false);
+ 		    validatedPaint = paint;
+ 		    break;
+ 
+@@ -761,8 +714,7 @@
+ 		    break;
+ 
+ 		case SunGraphics2D.PAINT_TEXTURE:
+-		    validatedPaint = setTexturePaint(sg2d,
+-			    (TexturePaint) paint, false);
++		    validatedPaint = setTexturePaint(sg2d, (TexturePaint) paint, false);
+ 		    break;
+ 
+ 		default:
+@@ -773,12 +725,10 @@
+     }
+ 
+     /**
+-     * Validates the Surface when used as destination, 
+-     * takes care that the native surface has the same state as expected, 
+-     * changing it it not.
++     * Validates the Surface when used as destination, takes care that the
++     * native surface has the same state as expected, changing it it not.
+      */
+-    public void validate(Region clip, Composite comp, AffineTransform xform,
+-	    Paint paint, SunGraphics2D sg2d, int flags) {
++    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;
+ 
+@@ -789,8 +739,7 @@
+ 	// validate clip
+ 	if (updateClip) {
+ 	    if (clip != null) {
+-		XRSetClip(getNativeOps(), clip.getLoX(), clip.getLoY(), clip
+-			.getHiX(), clip.getHiY(), clip.isRectangular() ? null : clip);
++		XRSetClip(getNativeOps(), clip.getLoX(), clip.getLoY(), clip.getHiX(), clip.getHiY(), clip.isRectangular() ? null : clip);
+ 	    } else {
+ 		XRResetClip(getNativeOps());
+ 	    }
+@@ -830,7 +779,10 @@
+ 	}
+     }
+ 
+-    public void makePipes() { /*TODO: Why was this synchronized, but access not?*/
++    public void makePipes() { /*
++				 * TODO: Why was this synchronized, but access
++				 * not?
++				 */
+ 	if (xrpipe == null) {
+ 	    try {
+ 		SunToolkit.awtLock();
+@@ -847,14 +799,11 @@
+     }
+ 
+     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);
++	public XRWindowSurfaceData(X11ComponentPeer peer, XRGraphicsConfig gc, SurfaceType sType) {
++	    super(peer, gc, sType, peer.getColorModel(), peer.getColorModel().getPixelSize(), Transparency.OPAQUE);
+ 
+ 	    if (isXRDrawableValid()) {
+-		initXRender(XRUtils
+-			.getPictureFormatForTransparency(Transparency.OPAQUE));
++		initXRender(XRUtils.getPictureFormatForTransparency(Transparency.OPAQUE));
+ 		makePipes();
+ 	    }
+ 	}
+@@ -888,8 +837,7 @@
+ 	int height;
+ 	int transparency;
+ 
+-	public XRPixmapSurfaceData(XRGraphicsConfig gc, int width, int height,
+-		Image image, SurfaceType sType, ColorModel cm, long drawable,
++	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;
+@@ -900,8 +848,7 @@
+ 	    makePipes();
+ 	}
+ 
+-	public void initSurface(int depth, int width, int height,
+-		long drawable, int pictFormat) {
++	public void initSurface(int depth, int width, int height, long drawable, int pictFormat) {
+ 	    try {
+ 		SunToolkit.awtLock();
+ 		XRInitSurface(depth, width, height, drawable, pictFormat);
+@@ -936,10 +883,11 @@
+ 	public void flush() {
+ 	    /*
+ 	     * We need to invalidate the surface before disposing the native
+-	     * Drawable and Picture. This way if an application tries to render to an
+-	     * already flushed XRSurfaceData, 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.
++	     * Drawable and Picture. This way if an application tries to render
++	     * to an already flushed XRSurfaceData, 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();
+diff -r 2e58d73ce3ff -r d6ab5f9f96ef src/solaris/native/sun/java2d/x11/MaskBuffer.c
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/MaskBuffer.c	Tue Aug 05 04:05:41 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/MaskBuffer.c	Thu Oct 23 17:25:18 2008 +0200
+@@ -44,13 +44,36 @@
+ 
+   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);
+- 
++
+   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);
+ 
+   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);
++
++/*
++  //1x1 image mask pixmap
++  Pixmap m1p =  XCreatePixmap(awt_display, window, 1, 1, 8);
++  buffer->img1Mask = XRenderCreatePicture(awt_display, m1p, fmt, 0, &pict_attr);
++  XRenderFillRectangle (awt_display, PictOpSrc, buffer->img1Mask, &color_black, 0, 0, 1, 1);
++
++  //8x8 image mask pixmap
++  Pixmap m8p =  XCreatePixmap(awt_display, window, 8, 8, 8);
++  buffer->img8Mask = XRenderCreatePicture(awt_display, m8p, fmt, 0, &pict_attr);
++  XRenderFillRectangle (awt_display, PictOpSrc, buffer->img8Mask, &color_black, 0, 0, 8, 8);
++
++  //64x64 image mask pixmap
++  Pixmap m64p =  XCreatePixmap(awt_display, window, 64, 64, 8);
++  buffer->img64Mask = XRenderCreatePicture(awt_display, m64p, fmt, 0, &pict_attr);
++  XRenderFillRectangle (awt_display, PictOpSrc, buffer->img64Mask, &color_black, 0, 0, 64, 64);
++*/
++
++  Pixmap mp =  XCreatePixmap(awt_display, window, 64, 64, 8);
++  buffer->maxMask = XRenderCreatePicture(awt_display, mp, fmt, 0, &pict_attr);
++  XRenderFillRectangle (awt_display, PictOpClear, buffer->maxMask, &color_black, 0, 0, 64, 64);
++  buffer->maxWidth = 64;
++  buffer->maxHeight = 64;
+ 
+   buffer->validatedGCAlpha = 1.0f;
+   XGCValues values;
+@@ -347,12 +370,12 @@
+ 	  if(maskRequired || lineList->used  > 0) {
+             Picture mask = None;
+ 
+-            if(lineList->used != 0) {
++            if(lineList->used > 0) {
+               XDrawSegments(awt_display, buf->lineMaskPixmap, buf->drawLineGC, (XSegment *) lineList->elements, lineList->used);
+               mask = buf->lineMaskPicture;
+             }
+ 
+-            if(rectList->used != 0) {
++            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;
+@@ -371,7 +394,7 @@
+                clearXRList(lineList);
+ 	     }
+           }else
+-          if(rectList->used != 0) {
++          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);
+diff -r 2e58d73ce3ff -r d6ab5f9f96ef src/solaris/native/sun/java2d/x11/MaskBuffer.h
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/MaskBuffer.h	Tue Aug 05 04:05:41 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/MaskBuffer.h	Thu Oct 23 17:25:18 2008 +0200
+@@ -50,6 +50,13 @@
+   Picture maskPicture;
+   GC maskGC;
+   jfloat validatedGCAlpha;
++
++  /*Picture img1Mask;
++  Picture img8Mask;
++  Picture img64Mask;*/
++  Picture maxMask;
++  jint maxWidth;
++  jint maxHeight;
+ 
+   XrArrayList rects;
+   XrArrayList lines;
+diff -r 2e58d73ce3ff -r d6ab5f9f96ef src/solaris/native/sun/java2d/x11/XRPMBlitLoops.c
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/XRPMBlitLoops.c	Tue Aug 05 04:05:41 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRPMBlitLoops.c	Thu Oct 23 17:25:18 2008 +0200
+@@ -65,6 +65,92 @@
+ #endif /* !HEADLESS */
+ }
+ 
++
++JNIEXPORT void JNICALL
++Java_sun_java2d_xr_XRPMBlitLoops_nativeTransformedRenderBlit
++    (JNIEnv *env, jclass xsd,
++     jlong srcData, jlong dstData,
++     jint srcx, jint srcy,
++     jint dstx, jint dsty,
++     jint width, jint height,
++     jint m00, jint m01, jint m02, jint m10, jint m11, jint m12, jint maskWidth, jint maskHeight, jint lastWidth, jint lastHeight)
++{
++#ifndef HEADLESS
++    J2dTraceLn(J2D_TRACE_INFO, "in XRPBMBlitLoops_nativeTranformedRenderBlit");
++
++    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;
++    }
++
++
++    Picture mask = None;
++    if(maskWidth > -1)
++    {
++      XRenderColor maskColor;
++      maskColor.alpha = XDoubleToUShort(xrSrcData.extraAlpha);
++
++    /*Picture mask;
++    switch(maskSize)
++    {
++      case 1: 
++        mask = maskBuffer->img1Mask;
++        break;
++
++      case 8:
++        mask = maskBuffer->img8Mask;
++        break;
++
++      case 64:
++        mask = maskBuffer->img64Mask;
++        break;
++    }*/
++
++   if(maskBuffer->maxWidth < maskWidth || maskBuffer->maxHeight < maskHeight) {
++     XRenderPictFormat *fmt = XRenderFindStandardFormat(awt_display, PictStandardA8);
++     XRenderPictureAttributes pict_attr;
++     Pixmap mp =  XCreatePixmap(awt_display, RootWindow(awt_display, dstXsdo->configData->awt_visInfo.screen), maskWidth, maskHeight, 8);
++
++     //TODO: Alte maske free'n
++     maskBuffer->maxMask = XRenderCreatePicture(awt_display, mp, fmt, 0, &pict_attr);
++     XRenderFillRectangle (awt_display, PictOpClear, maskBuffer->maxMask, &maskColor, 0, 0, maskWidth, maskHeight);
++     maskBuffer->maxWidth = maskWidth;
++     maskBuffer->maxHeight = maskHeight;
++
++  //   printf("Reinitialized it!\n"); fflush(stdout);
++   }else
++   {
++    XRenderFillRectangle (awt_display, PictOpClear, maskBuffer->maxMask, &maskColor, 0, 0, lastWidth, lastHeight);
++   }
++
++    //printf("Blit: %d, %d, %d, %d\n", maskWidth, maskHeight, lastWidth, lastHeight); fflush(stdout);
++
++    XRenderFillRectangle (awt_display, PictOpSrc, maskBuffer->maxMask, &maskColor, 0, 0, maskWidth, maskHeight);
++    
++    XTransform tr;
++    BUILD_TRANSFORM_MATRIX(tr, m00, m01, m02, m10, m11, m12);
++    XRenderSetPictureTransform (awt_display, maskBuffer->maxMask, &tr);
++
++    mask = maskBuffer->maxMask;
++}
++
++    XRenderComposite (awt_display, xrSrcData.compRule, srcXsdo->xrPic, mask, dstXsdo->xrPic, srcx, srcy, 0, 0, dstx, dsty, width, height); 
++    
++
++    X11SD_DirectRenderNotify(env, dstXsdo);
++#endif /* !HEADLESS */
++}
+ 
+ #ifndef HEADLESS
+ /**
+diff -r 2e58d73ce3ff -r d6ab5f9f96ef src/solaris/native/sun/java2d/x11/XRSurfaceData.c
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.c	Tue Aug 05 04:05:41 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.c	Thu Oct 23 17:25:18 2008 +0200
+@@ -33,19 +33,6 @@
+ MaskBuffer *maskBuffer;
+ XRenderColor color_black;
+ #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_XRInitXRender(JNIEnv *env, jobject xsd, jlong pXSData, jint pictFormat)
+diff -r 2e58d73ce3ff -r d6ab5f9f96ef src/solaris/native/sun/java2d/x11/XRSurfaceData.h
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.h	Tue Aug 05 04:05:41 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.h	Thu Oct 23 17:25:18 2008 +0200
+@@ -27,6 +27,19 @@
+ #define XRSurfaceData_h_Included
+ 
+ #define XDoubleToUShort(f)    ((unsigned short) ((f) * 65535))
++
++#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;                                                          \
++    }
+ 
+ /* Holds source-parameters*/
+ typedef struct {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/icedtea-xrender-008.patch	Sun Nov 30 11:58:42 2008 +0100
@@ -0,0 +1,131 @@
+# HG changeset patch
+# User ceisserer
+# Date 1224781905 -7200
+# Node ID 0ae86de6889ebd18b1a8f0232c50ce2c3049bc40
+# Parent  d6ab5f9f96efa37a823e071a27e3555557930203
+Updated Symbol-Mapping files
+
+diff -r d6ab5f9f96ef -r 0ae86de6889e make/sun/awt/mapfile-mawt-vers
+--- openjdk/jdk/make/sun/awt/mapfile-mawt-vers	Thu Oct 23 17:25:18 2008 +0200
++++ openjdk/jdk/make/sun/awt/mapfile-mawt-vers	Thu Oct 23 19:11:45 2008 +0200
+@@ -438,6 +438,7 @@
+ 		Java_sun_java2d_xr_XRSurfaceData_XRResetPaint;
+ 		Java_sun_java2d_xr_XRSurfaceData_XRSetRepeat;
+ 		Java_sun_java2d_xr_XRPMBlitLoops_nativeRenderBlit;
++                Java_sun_java2d_xr_XRPMBlitLoops_nativeTransformedRenderBlit;
+ 		Java_sun_java2d_xr_XRRenderer_XRFillRect;
+ 		Java_sun_java2d_xr_XRRenderer_XRFillSpans;
+ 		Java_sun_java2d_xr_XRRenderer_XRDoPath;
+diff -r d6ab5f9f96ef -r 0ae86de6889e make/sun/xawt/mapfile-vers
+--- openjdk/jdk/make/sun/xawt/mapfile-vers	Thu Oct 23 17:25:18 2008 +0200
++++ openjdk/jdk/make/sun/xawt/mapfile-vers	Thu Oct 23 19:11:45 2008 +0200
+@@ -367,6 +367,7 @@
+         Java_sun_java2d_xr_XRSurfaceData_XRResetPaint;
+         Java_sun_java2d_xr_XRSurfaceData_XRSetRepeat;
+ 	Java_sun_java2d_xr_XRPMBlitLoops_nativeRenderBlit;
++        Java_sun_java2d_xr_XRPMBlitLoops_nativeTransformedRenderBlit;
+ 	Java_sun_java2d_xr_XRRenderer_XRFillRect;
+ 	Java_sun_java2d_xr_XRRenderer_XRFillSpans;
+         Java_sun_java2d_xr_XRRenderer_XRDoPath;
+diff -r d6ab5f9f96ef -r 0ae86de6889e src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java	Thu Oct 23 17:25:18 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java	Thu Oct 23 19:11:45 2008 +0200
+@@ -31,6 +31,7 @@
+ import sun.java2d.SurfaceData;
+ import java.awt.*;
+ import java.awt.geom.*;
++import java.awt.image.*;
+ 
+ /**
+  * XRPMBlitLoops
+@@ -38,7 +39,7 @@
+  * This class accelerates Blits between two surfaces of types *PM.s
+  */
+ public class XRPMBlitLoops {
+-
++    
+     public static void register() {
+ 	GraphicsPrimitive[] primitives = {
+ 
+@@ -90,15 +91,32 @@
+ 	super(srcType, CompositeType.AnyAlpha, dstType);
+     }
+     
++    /*
++     * TODO:  This breaks scales with non-integer coordinates!
++     */
+     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();
+-
++	    
++//	    int width = sx2-sx1;
++//	    int height = sy2-sy1;
++//	    double xScale = (dx2 - dx1) / width;
++//	    double yScale = (dy2 - dy1) / height;
++//	    AffineTransform scaleTransform = AffineTransform.getTranslateInstance(sx1, sy1);
++//	    scaleTransform.scale(xScale, yScale);
++//	   // scaleTransform.translate(sx1, sy1);
++//	    
++//	    /*
++//             *    static void IsoBlit(SurfaceData src, SurfaceData dst, Composite comp, Region clip, AffineTransform xform, int hint, 
++//             *    int srcx, int srcy, int dstx, int dsty, int width, int height)
++//	     */
++//	    XRPMBlitLoops.IsoBlit(src, dst, comp, clip, scaleTransform, AffineTransformOp.TYPE_NEAREST_NEIGHBOR, 0, 0, (int)(dx1/xScale), (int)(dy1/yScale), width, height);
++////
+ 	    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);
+ 
+@@ -110,8 +128,7 @@
+ 	    AffineTransform xForm = AffineTransform.getScaleInstance(1 / xScale, 1 / yScale);
+ 
+ 	    x11sdSrc.validateAsSource(xForm, XRUtils.RepeatNone, XRUtils.FAST);
+-
+-	    /*TODO: This breaks non-integer scaled images*/
++	    
+ 	    XRPMBlitLoops.nativeRenderBlit(src.getNativeOps(), dst.getNativeOps(), (int) sx1, (int) sy1, (int) dx1, (int) dy1, (int) (dx2 - dx1),
+ 		    (int) (dy2 - dy1));
+ 
+@@ -127,11 +144,12 @@
+  * @author Clemens Eisserer
+  */
+ class X11PMTransformedBlit extends TransformBlit {
++    
++    static int lastMaskWidth = 0, lastMaskHeight = 0;
++    
+     public X11PMTransformedBlit(SurfaceType srcType, SurfaceType dstType) {
+ 	super(srcType, CompositeType.AnyAlpha, dstType);
+     }
+-
+-    static int lastMaskWidth = 0, lastMaskHeight = 0;
+ 
+     /**
+      * Possible optimizations: 
+@@ -145,7 +163,6 @@
+ 	    int dstx, int dsty, int width, int height) {
+ 	try {
+ 	    SunToolkit.awtLock();
+-
+ 	    int xrInterpolationType = XRUtils.ATransOpToXRQuality(hint);
+ 
+ 	    XRSurfaceData x11sdDst = (XRSurfaceData) dst;
+@@ -198,12 +215,11 @@
+ 		XRPMBlitLoops.nativeTransformedRenderBlit(src.getNativeOps(), dst.getNativeOps(), 0, 0, bounds.x, bounds.y, bounds.width,
+ 			bounds.height, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0);
+ 	    }
+-
+ 	} finally {
+ 	    SunToolkit.awtUnlock();
+ 	}
+     }
+-
++    
+     protected static boolean isMaskOmittable(AffineTransform trx, Composite comp, int interpolation) {
+ 	return (interpolation <= XRUtils.FAST || trx.getTranslateX() == (int) trx.getTranslateX() /*
+ 												     * If