提交 da1ca23f 编写于 作者: C ceisserer

6307603: [X11] Use RENDER extension for complex operations done in software

Reviewed-by: bae, igor, prr
上级 d273fa06
......@@ -639,21 +639,8 @@ AWT_RUNPATH = -R/usr/dt/lib$(ISA_DIR) -R$(OPENWIN_RUNTIME_LIB)
# in general this is ok to continue to do.
LIBCXX = /usr/lib$(ISA_DIR)/libCrun.so.1
# Math Library (libm.so), do not use -lm.
# There might be two versions of libm.so on the build system:
# libm.so.1 and libm.so.2, and we want libm.so.1.
# Depending on the Solaris release being used to build with,
# /usr/lib/libm.so could point at a libm.so.2, so we are
# explicit here so that the libjvm.so you have built will work on an
# older Solaris release that might not have libm.so.2.
# This is a critical factor in allowing builds on Solaris 10 or newer
# to run on Solaris 8 or 9.
#
# Note: Historically there was also a problem picking up a static version
# of libm.a from the compiler area, but that problem has gone away
# with the newer compilers. Use of libm.a would cause .so bloat.
#
LIBM = /usr/lib$(ISA_DIR)/libm.so.1
# JDK now requires Solaris 10, so pick up libm.so.2
LIBM = /usr/lib$(ISA_DIR)/libm.so.2
# Socket library
LIBSOCKET = -lsocket
......
......@@ -312,6 +312,7 @@ SUNWprivate_1.1 {
Java_sun_awt_X11GraphicsEnvironment_initGLX;
Java_sun_awt_X11GraphicsEnvironment_pRunningXinerama;
Java_sun_awt_X11GraphicsEnvironment_getXineramaCenterPoint;
Java_sun_awt_X11GraphicsEnvironment_initXRender;
#Java_sun_awt_motif_MEmbedCanvasPeer_initXEmbedServer;
#Java_sun_awt_motif_MEmbedCanvasPeer_destroyXEmbedServer;
#Java_sun_awt_motif_MEmbedCanvasPeer_isXEmbedActive;
......@@ -406,18 +407,53 @@ SUNWprivate_1.1 {
Java_sun_java2d_x11_X11SurfaceData_initIDs;
Java_sun_java2d_x11_X11SurfaceData_initOps;
Java_sun_java2d_x11_X11SurfaceData_initSurface;
Java_sun_java2d_x11_X11SurfaceData_isDrawableValid;
Java_sun_java2d_x11_X11SurfaceData_isDgaAvailable;
Java_sun_java2d_x11_X11SurfaceData_isShmPMAvailable;
Java_sun_java2d_x11_X11SurfaceData_setInvalid;
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_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_xr_XRSurfaceData_initXRPicture;
Java_sun_java2d_xr_XRSurfaceData_initIDs;
Java_sun_java2d_xr_XRSurfaceData_XRInitSurface;
Java_sun_java2d_xr_XRBackendNative_initIDs;
Java_sun_java2d_xr_XIDGenerator_bufferXIDs;
Java_sun_java2d_xr_XRBackendNative_freeGC;
Java_sun_java2d_xr_XRBackendNative_createGC;
Java_sun_java2d_xr_XRBackendNative_createPixmap;
Java_sun_java2d_xr_XRBackendNative_createPictureNative;
Java_sun_java2d_xr_XRBackendNative_freePicture;
Java_sun_java2d_xr_XRBackendNative_freePixmap;
Java_sun_java2d_xr_XRBackendNative_setPictureRepeat;
Java_sun_java2d_xr_XRBackendNative_setGCExposures;
Java_sun_java2d_xr_XRBackendNative_setGCForeground;
Java_sun_java2d_xr_XRBackendNative_copyArea;
Java_sun_java2d_xr_XRBackendNative_renderComposite;
Java_sun_java2d_xr_XRBackendNative_renderRectangle;
Java_sun_java2d_xr_XRBackendNative_XRenderRectanglesNative;
Java_sun_java2d_xr_XRBackendNative_XRSetTransformNative;
Java_sun_java2d_xr_XRBackendNative_XRCreateLinearGradientPaintNative;
Java_sun_java2d_xr_XRBackendNative_XRCreateRadialGradientPaintNative;
Java_sun_java2d_xr_XRBackendNative_setFilter;
Java_sun_java2d_xr_XRBackendNative_XRSetClipNative;
Java_sun_java2d_xr_XRBackendNative_putMaskNative;
Java_sun_java2d_xr_XRBackendNative_XRAddGlyphsNative;
Java_sun_java2d_xr_XRBackendNative_XRFreeGlyphsNative;
Java_sun_java2d_xr_XRBackendNative_XRenderCreateGlyphSetNative;
Java_sun_java2d_xr_XRBackendNative_XRenderCompositeTextNative;
Java_sun_java2d_xr_XRBackendNative_setGCMode;
Java_sun_java2d_xr_XRBackendNative_GCRectanglesNative;
Java_sun_java2d_xr_XRUtils_initFormatPtrs;
Java_sun_java2d_xr_XRBackendNative_renderCompositeTrapezoidsNative;
XRT_DrawGlyphList;
Java_sun_java2d_opengl_OGLContext_getOGLIdString;
Java_sun_java2d_opengl_OGLMaskFill_maskFill;
......
......@@ -425,6 +425,7 @@ SUNWprivate_1.1 {
Java_sun_awt_X11GraphicsEnvironment_initDisplay;
Java_sun_awt_X11GraphicsEnvironment_pRunningXinerama;
Java_sun_awt_X11GraphicsEnvironment_getXineramaCenterPoint;
Java_sun_awt_X11GraphicsEnvironment_initXRender;
......
......@@ -46,17 +46,20 @@ SUNWprivate_1.1 {
Java_sun_java2d_x11_X11Renderer_XFillRoundRect;
Java_sun_java2d_x11_X11Renderer_devCopyArea;
Java_sun_java2d_x11_X11SurfaceData_initIDs;
Java_sun_java2d_x11_X11SurfaceData_initOps;
Java_sun_java2d_x11_X11SurfaceData_isDrawableValid;
Java_sun_java2d_x11_X11SurfaceData_initSurface;
Java_sun_java2d_x11_X11SurfaceData_setInvalid;
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_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;
X11SurfaceData_GetOps;
Java_java_awt_Font_initIDs;
Java_sun_font_FontConfigManager_getFontConfig;
......
......@@ -113,7 +113,7 @@ CPPFLAGS += -I$(OPENWIN_HOME)/include \
# Libraries to link in.
#
ifeq ($(PLATFORM), solaris)
OTHER_LDLIBS = -L$(LIBDIR)/$(LIBARCH) -L$(OPENWIN_LIB) -L$(LIBDIR)/$(LIBARCH)/xawt -lmawt
OTHER_LDLIBS = -L$(LIBDIR)/$(LIBARCH) -L$(OPENWIN_LIB) -L$(LIBDIR)/$(LIBARCH)/xawt -lmawt -L/usr/openwin/sfw/lib$(ISA_DIR) -lXrender
endif # PLATFORM
ifeq ($(PLATFORM), linux)
......
......@@ -80,4 +80,6 @@ FILES_c = \
swing_GTKEngine.c \
swing_GTKStyle.c \
rect.c \
sun_awt_X11_GtkFileDialogPeer.c
sun_awt_X11_GtkFileDialogPeer.c \
XRSurfaceData.c \
XRBackendNative.c
......@@ -49,6 +49,11 @@ AUTO_JAVA_PRUNE = WrapperGenerator.java
LDFLAGS += -L$(OPENWIN_LIB)
# For Xrender extension.
ifeq ($(PLATFORM), solaris)
LDFLAGS += -L/usr/openwin/sfw/lib$(ISA_DIR) -R/usr/openwin/sfw/lib$(ISA_DIR)
endif
ifeq ($(PLATFORM), linux)
LDFLAGS += -lpthread
dummy := $(shell $(MKDIR) -p $(LIB_LOCATION))
......@@ -88,7 +93,7 @@ vpath %.c $(SHARE_SRC)/native/sun/java2d/opengl
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)
......@@ -122,7 +127,7 @@ CPPFLAGS += -DXAWT -DXAWT_HACK \
-I$(PLATFORM_SRC)/native/sun/awt/medialib \
-I$(PLATFORM_SRC)/native/sun/font \
-I$(SHARE_SRC)/native/sun/awt \
-I$(PLATFORM_SRC)/native/sun/awt
-I$(PLATFORM_SRC)/native/sun/awt
ifeq ($(PLATFORM), linux)
# Allows for builds on Debian GNU Linux, X11 is in a different place
......
......@@ -192,6 +192,7 @@ SUNWprivate_1.1 {
Java_sun_font_X11FontManager_setNativeFontPath;
Java_sun_awt_X11GraphicsEnvironment_initDisplay;
Java_sun_awt_X11GraphicsEnvironment_initGLX;
Java_sun_awt_X11GraphicsEnvironment_initXRender;
Java_sun_awt_X11GraphicsEnvironment_checkShmExt;
Java_sun_awt_X11GraphicsEnvironment_getNumScreens;
Java_sun_awt_X11GraphicsEnvironment_getDefaultScreenNum;
......@@ -355,21 +356,52 @@ SUNWprivate_1.1 {
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_isShmPMAvailable;
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_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_xr_XRSurfaceData_initXRPicture;
Java_sun_java2d_xr_XRSurfaceData_initIDs;
Java_sun_java2d_xr_XRSurfaceData_XRInitSurface;
Java_sun_java2d_xr_XRBackendNative_initIDs;
Java_sun_java2d_xr_XRBackendNative_freeGC;
Java_sun_java2d_xr_XRBackendNative_createGC;
Java_sun_java2d_xr_XRBackendNative_createPixmap;
Java_sun_java2d_xr_XRBackendNative_createPictureNative;
Java_sun_java2d_xr_XRBackendNative_freePicture;
Java_sun_java2d_xr_XRBackendNative_freePixmap;
Java_sun_java2d_xr_XRBackendNative_setPictureRepeat;
Java_sun_java2d_xr_XRBackendNative_setGCExposures;
Java_sun_java2d_xr_XRBackendNative_setGCForeground;
Java_sun_java2d_xr_XRBackendNative_copyArea;
Java_sun_java2d_xr_XRBackendNative_renderComposite;
Java_sun_java2d_xr_XRBackendNative_renderRectangle;
Java_sun_java2d_xr_XRBackendNative_XRenderRectanglesNative;
Java_sun_java2d_xr_XRBackendNative_XRSetTransformNative;
Java_sun_java2d_xr_XRBackendNative_XRCreateLinearGradientPaintNative;
Java_sun_java2d_xr_XRBackendNative_XRCreateRadialGradientPaintNative;
Java_sun_java2d_xr_XRBackendNative_setFilter;
Java_sun_java2d_xr_XRBackendNative_XRSetClipNative;
Java_sun_java2d_xr_XRBackendNative_putMaskNative;
Java_sun_java2d_xr_XRBackendNative_XRAddGlyphsNative;
Java_sun_java2d_xr_XRBackendNative_XRFreeGlyphsNative;
Java_sun_java2d_xr_XRBackendNative_XRenderCreateGlyphSetNative;
Java_sun_java2d_xr_XRBackendNative_XRenderCompositeTextNative;
Java_sun_java2d_xr_XRBackendNative_setGCMode;
Java_sun_java2d_xr_XRBackendNative_GCRectanglesNative;
Java_sun_java2d_xr_XRBackendNative_renderCompositeTrapezoidsNative;
Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1arrow;
Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1box;
......@@ -397,8 +429,8 @@ SUNWprivate_1.1 {
Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetClassValue;
Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetPangoFontName;
Java_sun_awt_X11_GtkFileDialogPeer_run;
Java_sun_awt_X11_GtkFileDialogPeer_quit;
Java_sun_awt_X11_GtkFileDialogPeer_run;
Java_sun_awt_X11_GtkFileDialogPeer_quit;
Java_sun_print_CUPSPrinter_initIDs;
Java_sun_print_CUPSPrinter_getCupsServer;
......
/*
* Copyright 2010 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 java.util.*;
public interface GlyphDisposedListener {
public void glyphDisposed(ArrayList<Long> glyphs);
}
......@@ -31,6 +31,7 @@ import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.util.*;
import sun.java2d.Disposer;
import sun.java2d.pipe.BufferedContext;
......@@ -66,6 +67,9 @@ public final class StrikeCache {
static ReferenceQueue refQueue = Disposer.getQueue();
static ArrayList<GlyphDisposedListener> disposeListeners = new ArrayList<GlyphDisposedListener>(1);
/* Reference objects may have their referents cleared when GC chooses.
* During application client start-up there is typically at least one
* GC which causes the hotspot VM to clear soft (not just weak) references
......@@ -108,6 +112,8 @@ public final class StrikeCache {
static int topLeftXOffset;
static int topLeftYOffset;
static int pixelDataOffset;
static int cacheCellOffset;
static int managedOffset;
static long invisibleGlyphPtr;
/* Native method used to return information used for unsafe
......@@ -129,7 +135,7 @@ public final class StrikeCache {
static {
long[] nativeInfo = new long[11];
long[] nativeInfo = new long[13];
getGlyphCacheDescription(nativeInfo);
//Can also get address size from Unsafe class :-
//nativeAddressSize = unsafe.addressSize();
......@@ -144,6 +150,9 @@ public final class StrikeCache {
topLeftYOffset = (int)nativeInfo[8];
pixelDataOffset = (int)nativeInfo[9];
invisibleGlyphPtr = nativeInfo[10];
cacheCellOffset = (int) nativeInfo[11];
managedOffset = (int) nativeInfo[12];
if (nativeAddressSize < 4) {
throw new InternalError("Unexpected address size for font data: " +
nativeAddressSize);
......@@ -195,10 +204,10 @@ public final class StrikeCache {
private static final void doDispose(FontStrikeDisposer disposer) {
if (disposer.intGlyphImages != null) {
freeIntMemory(disposer.intGlyphImages,
freeCachedIntMemory(disposer.intGlyphImages,
disposer.pScalerContext);
} else if (disposer.longGlyphImages != null) {
freeLongMemory(disposer.longGlyphImages,
freeCachedLongMemory(disposer.longGlyphImages,
disposer.pScalerContext);
} else if (disposer.segIntGlyphImages != null) {
/* NB Now making multiple JNI calls in this case.
......@@ -207,7 +216,7 @@ public final class StrikeCache {
*/
for (int i=0; i<disposer.segIntGlyphImages.length; i++) {
if (disposer.segIntGlyphImages[i] != null) {
freeIntMemory(disposer.segIntGlyphImages[i],
freeCachedIntMemory(disposer.segIntGlyphImages[i],
disposer.pScalerContext);
/* native will only free the scaler context once */
disposer.pScalerContext = 0L;
......@@ -218,19 +227,19 @@ public final class StrikeCache {
* for a strike that never was asked to rasterise a glyph.
*/
if (disposer.pScalerContext != 0L) {
freeIntMemory(new int[0], disposer.pScalerContext);
freeCachedIntMemory(new int[0], disposer.pScalerContext);
}
} else if (disposer.segLongGlyphImages != null) {
for (int i=0; i<disposer.segLongGlyphImages.length; i++) {
if (disposer.segLongGlyphImages[i] != null) {
freeLongMemory(disposer.segLongGlyphImages[i],
freeCachedLongMemory(disposer.segLongGlyphImages[i],
disposer.pScalerContext);
disposer.pScalerContext = 0L;
disposer.segLongGlyphImages[i] = null;
}
}
if (disposer.pScalerContext != 0L) {
freeLongMemory(new long[0], disposer.pScalerContext);
freeCachedLongMemory(new long[0], disposer.pScalerContext);
}
} else if (disposer.pScalerContext != 0L) {
/* Rarely a strike may have been created that never cached
......@@ -238,9 +247,9 @@ public final class StrikeCache {
* context.
*/
if (longAddresses()) {
freeLongMemory(new long[0], disposer.pScalerContext);
freeCachedLongMemory(new long[0], disposer.pScalerContext);
} else {
freeIntMemory(new int[0], disposer.pScalerContext);
freeCachedIntMemory(new int[0], disposer.pScalerContext);
}
}
}
......@@ -304,6 +313,68 @@ public final class StrikeCache {
private static native void freeIntMemory(int[] glyphPtrs, long pContext);
private static native void freeLongMemory(long[] glyphPtrs, long pContext);
private static void freeCachedIntMemory(int[] glyphPtrs, long pContext) {
synchronized(disposeListeners) {
if (disposeListeners.size() > 0) {
ArrayList<Long> gids = null;
for (int i = 0; i < glyphPtrs.length; i++) {
if (glyphPtrs[i] != 0 && unsafe.getByte(glyphPtrs[i] + managedOffset) == 0
&& unsafe.getInt(glyphPtrs[i] + cacheCellOffset) != 0) {
if (gids == null) {
gids = new ArrayList<Long>();
}
gids.add((long) glyphPtrs[i]);
}
}
if (gids != null) {
notifyDisposeListeners(gids);
}
}
}
freeIntMemory(glyphPtrs, pContext);
}
private static void freeCachedLongMemory(long[] glyphPtrs, long pContext) {
synchronized(disposeListeners) {
if (disposeListeners.size() > 0) {
ArrayList<Long> gids = null;
for (int i=0; i < glyphPtrs.length; i++) {
if (glyphPtrs[i] != 0
&& unsafe.getByte(glyphPtrs[i] + managedOffset) == 0
&& unsafe.getInt(glyphPtrs[i] + cacheCellOffset) != 0) {
if (gids == null) {
gids = new ArrayList<Long>();
}
gids.add((long) glyphPtrs[i]);
}
}
if (gids != null) {
notifyDisposeListeners(gids);
}
}
}
freeLongMemory(glyphPtrs, pContext);
}
public static void addGlyphDisposedListener(GlyphDisposedListener listener) {
synchronized(disposeListeners) {
disposeListeners.add(listener);
}
}
private static void notifyDisposeListeners(ArrayList<Long> glyphs) {
for (GlyphDisposedListener listener : disposeListeners) {
listener.glyphDisposed(glyphs);
}
}
public static Reference getStrikeRef(FontStrike strike) {
return getStrikeRef(strike, cacheRefTypeWeak);
......
......@@ -307,7 +307,7 @@ public class BufferedPaints {
* 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;
......
......@@ -117,6 +117,11 @@ public class RenderBuffer {
curAddress = baseAddress;
}
public final RenderBuffer skip(long numBytes) {
curAddress += numBytes;
return this;
}
/**
* putByte() methods...
*/
......
# Jules Rendering Engine module
sun.java2d.jules.JulesRenderingEngine
# Pisces Rendering Engine module
sun.java2d.pisces.PiscesRenderingEngine
sun.java2d.pisces.PiscesRenderingEngine
\ No newline at end of file
......@@ -325,6 +325,7 @@ AccelGlyphCache_AddCellInfo(GlyphInfo *glyph, CacheCellInfo *cellInfo)
cellInfo->glyphInfo = glyph;
cellInfo->nextGCI = glyph->cellInfo;
glyph->cellInfo = cellInfo;
glyph->managed = MANAGED_GLYPH;
}
/**
......
......@@ -84,15 +84,26 @@ typedef float t2kScalar;
#define t2kScalarAverage(a, b) (((a) + (b)) / (t2kScalar)(2))
/* managed: 1 means the glyph has a hardware cached
* copy, and its freeing is managed by the the usual
* 2D disposer code.
* A value of 0 means its either unaccelerated (and so has no cellInfos)
* or we want to free this in a different way.
* The field uses previously unused padding, so doesn't enlarge
* the structure.
*/
#define UNMANAGED_GLYPH 0
#define MANAGED_GLYPH 1
typedef struct GlyphInfo {
float advanceX;
float advanceY;
UInt16 width;
UInt16 height;
UInt16 rowBytes;
UInt8 managed;
float topLeftX;
float topLeftY;
struct _CacheCellInfo *cellInfo;
void *cellInfo;
UInt8 *image;
} GlyphInfo;
......
......@@ -782,6 +782,7 @@ Java_sun_font_FreetypeFontScaler_getGlyphImageNative(
return ptr_to_jlong(glyphInfo);
}
glyphInfo->cellInfo = NULL;
glyphInfo->managed = UNMANAGED_GLYPH;
glyphInfo->rowBytes = width;
glyphInfo->width = width;
glyphInfo->height = height;
......@@ -1130,7 +1131,7 @@ static void addToGP(GPData* gpdata, FT_Outline*outline) {
current_type = SEG_LINETO;
}
} else if (FT_CURVE_TAG(outline->tags[i]) == FT_CURVE_TAG_CUBIC) {
/* Bit 1 is meaningful for off points only.
/* Bit 1 is meaningful for 'off' points only.
If set, it indicates a third-order Bezier arc control
point; and a second-order control point if unset. */
current_type = SEG_CUBICTO;
......
......@@ -233,7 +233,8 @@ JNIEXPORT void JNICALL Java_sun_font_StrikeCache_freeIntMemory
for (i=0; i< len; i++) {
if (ptrs[i] != 0) {
GlyphInfo *ginfo = (GlyphInfo *)ptrs[i];
if (ginfo->cellInfo != NULL) {
if (ginfo->cellInfo != NULL &&
ginfo->managed == MANAGED_GLYPH) {
// invalidate this glyph's accelerated cache cell
AccelGlyphCache_RemoveAllCellInfos(ginfo);
}
......@@ -264,7 +265,8 @@ JNIEXPORT void JNICALL Java_sun_font_StrikeCache_freeLongMemory
for (i=0; i< len; i++) {
if (ptrs[i] != 0L) {
GlyphInfo *ginfo = (GlyphInfo *) jlong_to_ptr(ptrs[i]);
if (ginfo->cellInfo != NULL) {
if (ginfo->cellInfo != NULL &&
ginfo->managed == MANAGED_GLYPH) {
AccelGlyphCache_RemoveAllCellInfos(ginfo);
}
free((void*)ginfo);
......@@ -285,7 +287,7 @@ Java_sun_font_StrikeCache_getGlyphCacheDescription
GlyphInfo *info;
size_t baseAddr;
if ((*env)->GetArrayLength(env, results) < 10) {
if ((*env)->GetArrayLength(env, results) < 13) {
return;
}
......@@ -310,6 +312,9 @@ Java_sun_font_StrikeCache_getGlyphCacheDescription
nresults[8] = (size_t)&(info->topLeftY)-baseAddr;
nresults[9] = (size_t)&(info->image)-baseAddr;
nresults[10] = (jlong)(uintptr_t)info; /* invisible glyph */
nresults[11] = (size_t)&(info->cellInfo)-baseAddr;
nresults[12] = (size_t)&(info->managed)-baseAddr;
(*env)->ReleasePrimitiveArrayCritical(env, results, nresults, 0);
}
......
......@@ -244,6 +244,7 @@ static void
OGLTR_AddToGlyphCache(GlyphInfo *glyph, jboolean rgbOrder)
{
GLenum pixelFormat;
CacheCellInfo *ccinfo;
J2dTraceLn(J2D_TRACE_INFO, "OGLTR_AddToGlyphCache");
......@@ -258,11 +259,12 @@ OGLTR_AddToGlyphCache(GlyphInfo *glyph, jboolean rgbOrder)
}
AccelGlyphCache_AddGlyph(glyphCache, glyph);
ccinfo = (CacheCellInfo *) glyph->cellInfo;
if (glyph->cellInfo != NULL) {
if (ccinfo != NULL) {
// store glyph image in texture cell
j2d_glTexSubImage2D(GL_TEXTURE_2D, 0,
glyph->cellInfo->x, glyph->cellInfo->y,
ccinfo->x, ccinfo->y,
glyph->width, glyph->height,
pixelFormat, GL_UNSIGNED_BYTE, glyph->image);
}
......@@ -668,7 +670,7 @@ OGLTR_DrawGrayscaleGlyphViaCache(OGLContext *oglc,
}
}
cell = ginfo->cellInfo;
cell = (CacheCellInfo *) (ginfo->cellInfo);
cell->timesRendered++;
x1 = (jfloat)x;
......@@ -871,7 +873,7 @@ OGLTR_DrawLCDGlyphViaCache(OGLContext *oglc, OGLSDOps *dstOps,
}
}
cell = ginfo->cellInfo;
cell = (CacheCellInfo *) (ginfo->cellInfo);
cell->timesRendered++;
// location of the glyph in the destination's coordinate space
......
......@@ -39,6 +39,7 @@ import java.util.HashSet;
import java.util.HashMap;
import sun.java2d.opengl.GLXGraphicsConfig;
import sun.java2d.xr.XRGraphicsConfig;
import sun.java2d.loops.SurfaceType;
/**
......@@ -152,6 +153,8 @@ public class X11GraphicsDevice
}
boolean glxSupported = X11GraphicsEnvironment.isGLXAvailable();
boolean xrenderSupported = X11GraphicsEnvironment.isXRenderAvailable();
boolean dbeSupported = isDBESupported();
if (dbeSupported && doubleBufferVisuals == null) {
doubleBufferVisuals = new HashSet();
......@@ -167,9 +170,15 @@ public class X11GraphicsDevice
boolean doubleBuffer =
(dbeSupported &&
doubleBufferVisuals.contains(Integer.valueOf(visNum)));
ret[i] = X11GraphicsConfig.getConfig(this, visNum, depth,
getConfigColormap(i, screen),
doubleBuffer);
if (xrenderSupported) {
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;
......@@ -243,9 +252,19 @@ public class X11GraphicsDevice
doubleBuffer =
doubleBufferVisuals.contains(Integer.valueOf(visNum));
}
defaultConfig = X11GraphicsConfig.getConfig(this, visNum,
depth, getConfigColormap(0, screen),
doubleBuffer);
if (X11GraphicsEnvironment.isXRenderAvailable()) {
if (X11GraphicsEnvironment.isXRenderVerbose()) {
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);
}
}
}
}
......
......@@ -26,6 +26,7 @@
package sun.awt;
import java.awt.GraphicsDevice;
import java.awt.Point;
import java.awt.Rectangle;
import java.io.BufferedReader;
......@@ -51,6 +52,7 @@ import sun.java2d.SunGraphicsEnvironment;
import sun.java2d.SurfaceManagerFactory;
import sun.java2d.UnixSurfaceManagerFactory;
import sun.util.logging.PlatformLogger;
import sun.java2d.xr.XRSurfaceData;
/**
* This is an implementation of a GraphicsEnvironment object for the
......@@ -92,6 +94,18 @@ public class X11GraphicsEnvironment
}
}
// Now check for XRender system property
boolean xRenderRequested = false;
String xProp = System.getProperty("sun.java2d.xrender");
if (xProp != null) {
if (xProp.equals("true") || xProp.equals("t")) {
xRenderRequested = true;
} else if (xProp.equals("True") || xProp.equals("T")) {
xRenderRequested = true;
xRenderVerbose = true;
}
}
// initialize the X11 display connection
initDisplay(glxRequested);
......@@ -104,6 +118,19 @@ public class X11GraphicsEnvironment
"pipeline (GLX 1.3 not available)");
}
}
// only attempt to initialize Xrender if it was requested
if (xRenderRequested) {
xRenderAvailable = initXRender();
if (xRenderVerbose && !xRenderAvailable) {
System.out.println(
"Could not enable XRender pipeline");
}
}
if (xRenderAvailable) {
XRSurfaceData.initXRSurfaceData();
}
}
return null;
......@@ -115,6 +142,7 @@ public class X11GraphicsEnvironment
}
private static boolean glxAvailable;
private static boolean glxVerbose;
......@@ -128,6 +156,18 @@ public class X11GraphicsEnvironment
return glxVerbose;
}
private static boolean xRenderVerbose;
private static boolean xRenderAvailable;
private static native boolean initXRender();
public static boolean isXRenderAvailable() {
return xRenderAvailable;
}
public static boolean isXRenderVerbose() {
return xRenderVerbose;
}
/**
* Checks if Shared Memory extension can be used.
* Returns:
......
/*
* Copyright 2010 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 java.io.*;
import java.util.*;
import sun.awt.*;
import sun.java2d.xr.*;
/**
* Glyph cache used by the XRender pipeline.
*
* @author Clemens Eisserer
*/
public class XRGlyphCache implements GlyphDisposedListener {
XRBackend con;
XRCompositeManager maskBuffer;
HashMap<MutableInteger, XRGlyphCacheEntry> cacheMap = new HashMap<MutableInteger, XRGlyphCacheEntry>(256);
int nextID = 1;
MutableInteger tmp = new MutableInteger(0);
int grayGlyphSet;
int lcdGlyphSet;
int time = 0;
int cachedPixels = 0;
static final int MAX_CACHED_PIXELS = 100000;
ArrayList<Integer> freeGlyphIDs = new ArrayList<Integer>(255);
static final boolean batchGlyphUpload = true; // Boolean.parseBoolean(System.getProperty("sun.java2d.xrender.batchGlyphUpload"));
public XRGlyphCache(XRCompositeManager maskBuf) {
this.con = maskBuf.getBackend();
this.maskBuffer = maskBuf;
grayGlyphSet = con.XRenderCreateGlyphSet(XRUtils.PictStandardA8);
lcdGlyphSet = con.XRenderCreateGlyphSet(XRUtils.PictStandardARGB32);
StrikeCache.addGlyphDisposedListener(this);
}
public void glyphDisposed(ArrayList<Long> glyphPtrList) {
try {
SunToolkit.awtLock();
ArrayList<Integer> glyphIDList = new ArrayList<Integer>(glyphPtrList.size());
for (long glyphPtr : glyphPtrList) {
glyphIDList.add(XRGlyphCacheEntry.getGlyphID(glyphPtr));
}
freeGlyphs(glyphIDList);
} finally {
SunToolkit.awtUnlock();
}
}
protected int getFreeGlyphID() {
if (freeGlyphIDs.size() > 0) {
int newID = freeGlyphIDs.remove(freeGlyphIDs.size() - 1);
;
return newID;
}
return nextID++;
}
protected XRGlyphCacheEntry getEntryForPointer(long imgPtr) {
int id = XRGlyphCacheEntry.getGlyphID(imgPtr);
if (id == 0) {
return null;
}
tmp.setValue(id);
return cacheMap.get(tmp);
}
public XRGlyphCacheEntry[] cacheGlyphs(GlyphList glyphList) {
time++;
XRGlyphCacheEntry[] entries = new XRGlyphCacheEntry[glyphList.getNumGlyphs()];
long[] imgPtrs = glyphList.getImages();
ArrayList<XRGlyphCacheEntry> uncachedGlyphs = null;
for (int i = 0; i < glyphList.getNumGlyphs(); i++) {
XRGlyphCacheEntry glyph;
// Find uncached glyphs and queue them for upload
if ((glyph = getEntryForPointer(imgPtrs[i])) == null) {
glyph = new XRGlyphCacheEntry(imgPtrs[i], glyphList);
glyph.setGlyphID(getFreeGlyphID());
cacheMap.put(new MutableInteger(glyph.getGlyphID()), glyph);
if (uncachedGlyphs == null) {
uncachedGlyphs = new ArrayList<XRGlyphCacheEntry>();
}
uncachedGlyphs.add(glyph);
}
glyph.setLastUsed(time);
entries[i] = glyph;
}
// Add glyphs to cache
if (uncachedGlyphs != null) {
uploadGlyphs(entries, uncachedGlyphs, glyphList, null);
}
return entries;
}
protected void uploadGlyphs(XRGlyphCacheEntry[] glyphs, ArrayList<XRGlyphCacheEntry> uncachedGlyphs, GlyphList gl, int[] glIndices) {
for (XRGlyphCacheEntry glyph : uncachedGlyphs) {
cachedPixels += glyph.getPixelCnt();
}
if (cachedPixels > MAX_CACHED_PIXELS) {
clearCache(glyphs);
}
boolean containsLCDGlyphs = containsLCDGlyphs(uncachedGlyphs);
List<XRGlyphCacheEntry>[] seperatedGlyphList = seperateGlyphTypes(uncachedGlyphs, containsLCDGlyphs);
List<XRGlyphCacheEntry> grayGlyphList = seperatedGlyphList[0];
List<XRGlyphCacheEntry> lcdGlyphList = seperatedGlyphList[1];
/*
* Some XServers crash when uploading multiple glyphs at once. TODO:
* Implement build-switch in local case for distributors who know their
* XServer is fixed
*/
if (batchGlyphUpload) {
if (grayGlyphList != null && grayGlyphList.size() > 0) {
con.XRenderAddGlyphs(grayGlyphSet, gl, grayGlyphList, generateGlyphImageStream(grayGlyphList));
}
if (lcdGlyphList != null && lcdGlyphList.size() > 0) {
con.XRenderAddGlyphs(lcdGlyphSet, gl, lcdGlyphList, generateGlyphImageStream(lcdGlyphList));
}
} else {
ArrayList<XRGlyphCacheEntry> tmpList = new ArrayList<XRGlyphCacheEntry>(1);
tmpList.add(null);
for (XRGlyphCacheEntry entry : uncachedGlyphs) {
tmpList.set(0, entry);
if (entry.getGlyphSet() == grayGlyphSet) {
con.XRenderAddGlyphs(grayGlyphSet, gl, tmpList, generateGlyphImageStream(tmpList));
} else {
con.XRenderAddGlyphs(lcdGlyphSet, gl, tmpList, generateGlyphImageStream(tmpList));
}
}
}
}
/**
* Seperates lcd and grayscale glyphs queued for upload, and sets the
* appropriate glyphset for the cache entries.
*/
protected List<XRGlyphCacheEntry>[] seperateGlyphTypes(List<XRGlyphCacheEntry> glyphList, boolean containsLCDGlyphs) {
ArrayList<XRGlyphCacheEntry> lcdGlyphs = null;
ArrayList<XRGlyphCacheEntry> grayGlyphs = null;
for (XRGlyphCacheEntry cacheEntry : glyphList) {
if (cacheEntry.isGrayscale(containsLCDGlyphs)) {
if (grayGlyphs == null) {
grayGlyphs = new ArrayList<XRGlyphCacheEntry>(glyphList.size());
}
cacheEntry.setGlyphSet(grayGlyphSet);
grayGlyphs.add(cacheEntry);
} else {
if (lcdGlyphs == null) {
lcdGlyphs = new ArrayList<XRGlyphCacheEntry>(glyphList.size());
}
cacheEntry.setGlyphSet(lcdGlyphSet);
lcdGlyphs.add(cacheEntry);
}
}
return new List[] { grayGlyphs, lcdGlyphs };
}
/**
* Copies the glyph-images into a continous buffer, required for uploading.
*/
protected byte[] generateGlyphImageStream(List<XRGlyphCacheEntry> glyphList) {
boolean isLCDGlyph = glyphList.get(0).getGlyphSet() == lcdGlyphSet;
ByteArrayOutputStream stream = new ByteArrayOutputStream((isLCDGlyph ? 4 : 1) * 48 * glyphList.size());
for (XRGlyphCacheEntry cacheEntry : glyphList) {
cacheEntry.writePixelData(stream, isLCDGlyph);
}
return stream.toByteArray();
}
protected boolean containsLCDGlyphs(List<XRGlyphCacheEntry> entries) {
boolean containsLCDGlyphs = false;
for (XRGlyphCacheEntry entry : entries) {
containsLCDGlyphs = !(entry.getSourceRowBytes() == entry.getWidth());
if (containsLCDGlyphs) {
return true;
}
}
return false;
}
protected void clearCache(XRGlyphCacheEntry[] glyps) {
/*
* Glyph uploading is so slow anyway, we can afford some inefficiency
* here, as the cache should usually be quite small. TODO: Implement
* something not that stupid ;)
*/
ArrayList<XRGlyphCacheEntry> cacheList = new ArrayList<XRGlyphCacheEntry>(cacheMap.values());
Collections.sort(cacheList, new Comparator<XRGlyphCacheEntry>() {
public int compare(XRGlyphCacheEntry e1, XRGlyphCacheEntry e2) {
return e2.getLastUsed() - e1.getLastUsed();
}
});
for (XRGlyphCacheEntry glyph : glyps) {
glyph.setPinned();
}
ArrayList<Integer> deleteGlyphList = new ArrayList<Integer>();
int pixelsToRelease = cachedPixels - MAX_CACHED_PIXELS;
for (int i = cacheList.size() - 1; i >= 0 && pixelsToRelease > 0; i--) {
XRGlyphCacheEntry entry = cacheList.get(i);
if (!entry.isPinned()) {
pixelsToRelease -= entry.getPixelCnt();
deleteGlyphList.add(new Integer(entry.getGlyphID()));
}
}
for (XRGlyphCacheEntry glyph : glyps) {
glyph.setUnpinned();
}
freeGlyphs(deleteGlyphList);
}
private void freeGlyphs(List<Integer> glyphIdList) {
freeGlyphIDs.addAll(glyphIdList);
GrowableIntArray removedLCDGlyphs = new GrowableIntArray(1, 1);
GrowableIntArray removedGrayscaleGlyphs = new GrowableIntArray(1, 1);
for (Integer glyphId : glyphIdList) {
tmp.setValue(glyphId.intValue());
XRGlyphCacheEntry entry = cacheMap.get(tmp);
cachedPixels -= entry.getPixelCnt();
int removedGlyphID = entry.getGlyphID();
tmp.setValue(removedGlyphID);
cacheMap.remove(tmp);
if (entry.getGlyphSet() == grayGlyphSet) {
removedGrayscaleGlyphs.addInt(removedGlyphID);
} else {
removedLCDGlyphs.addInt(removedGlyphID);
}
entry.setGlyphID(0);
}
if (removedGrayscaleGlyphs.getSize() > 0) {
con.XRenderFreeGlyphs(grayGlyphSet, removedGrayscaleGlyphs.getSizedArray());
}
if (removedLCDGlyphs.getSize() > 0) {
con.XRenderFreeGlyphs(lcdGlyphSet, removedLCDGlyphs.getSizedArray());
}
}
}
/*
* Copyright 2010 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 java.io.*;
/**
* Stores glyph-related data, used in the pure-java glyphcache.
*
* @author Clemens Eisserer
*/
public class XRGlyphCacheEntry {
long glyphInfoPtr;
int lastUsed;
boolean pinned;
int xOff;
int yOff;
int glyphSet;
public XRGlyphCacheEntry(long glyphInfoPtr, GlyphList gl) {
this.glyphInfoPtr = glyphInfoPtr;
/* TODO: Does it make sence to cache results? */
xOff = (int) Math.round(getXAdvance());
yOff = (int) Math.round(getYAdvance());
}
public int getXOff() {
return xOff;
}
public int getYOff() {
return yOff;
}
public void setGlyphSet(int glyphSet) {
this.glyphSet = glyphSet;
}
public int getGlyphSet() {
return glyphSet;
}
public static int getGlyphID(long glyphInfoPtr) {
return (int) StrikeCache.unsafe.getInt(glyphInfoPtr + StrikeCache.cacheCellOffset);
}
public static void setGlyphID(long glyphInfoPtr, int id) {
StrikeCache.unsafe.putInt(glyphInfoPtr + StrikeCache.cacheCellOffset, id);
}
public int getGlyphID() {
return getGlyphID(glyphInfoPtr);
}
public void setGlyphID(int id) {
setGlyphID(glyphInfoPtr, id);
}
public float getXAdvance() {
return StrikeCache.unsafe.getFloat(glyphInfoPtr + StrikeCache.xAdvanceOffset);
}
public float getYAdvance() {
return StrikeCache.unsafe.getFloat(glyphInfoPtr + StrikeCache.yAdvanceOffset);
}
public int getSourceRowBytes() {
return StrikeCache.unsafe.getShort(glyphInfoPtr + StrikeCache.rowBytesOffset);
}
public int getWidth() {
return StrikeCache.unsafe.getShort(glyphInfoPtr + StrikeCache.widthOffset);
}
public int getHeight() {
return StrikeCache.unsafe.getShort(glyphInfoPtr + StrikeCache.heightOffset);
}
public void writePixelData(ByteArrayOutputStream os, boolean uploadAsLCD) {
long pixelDataAddress;
if (StrikeCache.nativeAddressSize == 4) {
pixelDataAddress = 0xffffffff & StrikeCache.unsafe.getInt(glyphInfoPtr + StrikeCache.pixelDataOffset);
} else {
pixelDataAddress = StrikeCache.unsafe.getLong(glyphInfoPtr + StrikeCache.pixelDataOffset);
}
if (pixelDataAddress == 0L) {
return;
}
int width = getWidth();
int height = getHeight();
int rowBytes = getSourceRowBytes();
int paddedWidth = getPaddedWidth(uploadAsLCD);
if (!uploadAsLCD) {
for (int line = 0; line < height; line++) {
for(int x = 0; x < paddedWidth; x++) {
if(x < width) {
os.write(StrikeCache.unsafe.getByte(pixelDataAddress + (line * rowBytes + x)));
}else {
/*pad to multiple of 4 bytes per line*/
os.write(0);
}
}
}
} else {
for (int line = 0; line < height; line++) {
int rowStart = line * rowBytes;
int rowBytesWidth = width * 3;
int srcpix = 0;
while (srcpix < rowBytesWidth) {
os.write(StrikeCache.unsafe.getByte
(pixelDataAddress + (rowStart + srcpix + 2)));
os.write(StrikeCache.unsafe.getByte
(pixelDataAddress + (rowStart + srcpix + 1)));
os.write(StrikeCache.unsafe.getByte
(pixelDataAddress + (rowStart + srcpix + 0)));
os.write(255);
srcpix += 3;
}
}
}
}
public float getTopLeftXOffset() {
return StrikeCache.unsafe.getFloat(glyphInfoPtr + StrikeCache.topLeftXOffset);
}
public float getTopLeftYOffset() {
return StrikeCache.unsafe.getFloat(glyphInfoPtr + StrikeCache.topLeftYOffset);
}
public long getGlyphInfoPtr() {
return glyphInfoPtr;
}
public boolean isGrayscale(boolean listContainsLCDGlyphs) {
return getSourceRowBytes() == getWidth() && !(getWidth() == 0 && getHeight() == 0 && listContainsLCDGlyphs);
}
public int getPaddedWidth(boolean listContainsLCDGlyphs) {
int width = getWidth();
return isGrayscale(listContainsLCDGlyphs) ? (int) Math.ceil(width / 4.0) * 4 : width;
}
public int getDestinationRowBytes(boolean listContainsLCDGlyphs) {
boolean grayscale = isGrayscale(listContainsLCDGlyphs);
return grayscale ? getPaddedWidth(grayscale) : getWidth() * 4;
}
public int getGlyphDataLenth(boolean listContainsLCDGlyphs) {
return getDestinationRowBytes(listContainsLCDGlyphs) * getHeight();
}
public void setPinned() {
pinned = true;
}
public void setUnpinned() {
pinned = false;
}
public int getLastUsed() {
return lastUsed;
}
public void setLastUsed(int lastUsed) {
this.lastUsed = lastUsed;
}
public int getPixelCnt() {
return getWidth() * getHeight();
}
public boolean isPinned() {
return pinned;
}
}
/*
* Copyright 2010 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.*;
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
*
* @author Clemens Eisserer
*/
public class XRTextRenderer extends GlyphListPipe {
XRGlyphCache glyphCache;
XRCompositeManager maskBuffer;
XRBackend backend;
GrowableEltArray eltList;
public XRTextRenderer(XRCompositeManager buffer) {
glyphCache = new XRGlyphCache(buffer);
maskBuffer = buffer;
backend = buffer.getBackend();
eltList = new GrowableEltArray(64);
}
protected void drawGlyphList(SunGraphics2D sg2d, GlyphList gl) {
if (gl.getNumGlyphs() == 0) {
return;
}
try {
SunToolkit.awtLock();
XRSurfaceData x11sd = (XRSurfaceData) sg2d.surfaceData;
x11sd.validateAsDestination(null, sg2d.getCompClip());
x11sd.maskBuffer.validateCompositeState(sg2d.composite, sg2d.transform, sg2d.paint, sg2d);
float advX = gl.getX();
float advY = gl.getY();
int oldPosX = 0, oldPosY = 0;
if (gl.isSubPixPos()) {
advX += 0.1666667f;
advY += 0.1666667f;
} else {
advX += 0.5f;
advY += 0.5f;
}
XRGlyphCacheEntry[] cachedGlyphs = glyphCache.cacheGlyphs(gl);
boolean containsLCDGlyphs = false;
int activeGlyphSet = cachedGlyphs[0].getGlyphSet();
int eltIndex = -1;
gl.getBounds();
float[] positions = gl.getPositions();
for (int i = 0; i < gl.getNumGlyphs(); i++) {
gl.setGlyphIndex(i);
XRGlyphCacheEntry cacheEntry = cachedGlyphs[i];
eltList.getGlyphs().addInt(cacheEntry.getGlyphID());
int glyphSet = cacheEntry.getGlyphSet();
containsLCDGlyphs |= (glyphSet == glyphCache.lcdGlyphSet);
int posX = 0, posY = 0;
if (gl.usePositions()
|| (cacheEntry.getXAdvance() != ((float) cacheEntry.getXOff()) || cacheEntry.getYAdvance() != ((float) cacheEntry.getYOff()))
|| eltIndex < 0 || glyphSet != activeGlyphSet) {
eltIndex = eltList.getNextIndex();
eltList.setCharCnt(eltIndex, 1);
activeGlyphSet = glyphSet;
eltList.setGlyphSet(eltIndex, glyphSet);
if (gl.usePositions()) {
// /*In this case advX only stores rounding errors*/
float x = positions[i * 2] + advX;
float y = positions[i * 2 + 1] + advY;
posX = (int) Math.floor(x);
posY = (int) Math.floor(y);
advX -= cacheEntry.getXOff();
advY -= cacheEntry.getYOff();
} 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.
*/
posX = (int) Math.floor(advX);
posY = (int) Math.floor(advY);
// Advance of ELT = difference between stored
// relative
// positioning information and required float.
advX += (cacheEntry.getXAdvance() - cacheEntry.getXOff());
advY += (cacheEntry.getYAdvance() - cacheEntry.getYOff());
}
/*
* Offset of the current glyph is the difference to the last
* glyph and this one
*/
eltList.setXOff(eltIndex, (posX - oldPosX));
eltList.setYOff(eltIndex, (posY - oldPosY));
oldPosX = posX;
oldPosY = posY;
} else {
eltList.setCharCnt(eltIndex, eltList.getCharCnt(eltIndex) + 1);
}
}
int maskFormat = containsLCDGlyphs ? XRUtils.PictStandardARGB32 : XRUtils.PictStandardA8;
maskBuffer.compositeText(x11sd.picture, 0, maskFormat, eltList);
eltList.clear();
} finally {
SunToolkit.awtUnlock();
}
}
}
......@@ -33,6 +33,7 @@ import sun.awt.image.VolatileSurfaceManager;
import sun.java2d.opengl.GLXGraphicsConfig;
import sun.java2d.opengl.GLXVolatileSurfaceManager;
import sun.java2d.x11.X11VolatileSurfaceManager;
import sun.java2d.xr.*;
/**
* The SurfaceManagerFactory that creates VolatileSurfaceManager
......@@ -54,9 +55,12 @@ public class UnixSurfaceManagerFactory extends SurfaceManagerFactory {
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);
}
}
......
/*
* Copyright 2010 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.jules;
import java.util.*;
public class IdleTileCache {
final static int IDLE_TILE_SYNC_GRANULARITY = 16;
final static ArrayList<JulesTile> idleBuffers = new ArrayList<JulesTile>();
ArrayList<JulesTile> idleTileWorkerCacheList = new ArrayList<JulesTile>();
ArrayList<JulesTile> idleTileConsumerCacheList =
new ArrayList<JulesTile>(IDLE_TILE_SYNC_GRANULARITY);
/**
* Return a cached Tile, if possible from cache.
* Allowed caller: Rasterizer/Producer-Thread
*
* @param: maxCache - Specify the maximum amount of tiles needed
*/
public JulesTile getIdleTileWorker(int maxCache) {
/* Try to fetch idle tiles from the global cache list */
if (idleTileWorkerCacheList.size() == 0) {
idleTileWorkerCacheList.ensureCapacity(maxCache);
synchronized (idleBuffers) {
for (int i = 0; i < maxCache && idleBuffers.size() > 0; i++) {
idleTileWorkerCacheList.add(
idleBuffers.remove(idleBuffers.size() - 1));
}
}
}
if (idleTileWorkerCacheList.size() > 0) {
return idleTileWorkerCacheList.remove(idleTileWorkerCacheList.size() - 1);
}
return new JulesTile();
}
/**
* Release tile and allow it to be re-used by another thread. Allowed
* Allowed caller: MaskBlit/Consumer-Thread
*/
public void releaseTile(JulesTile tile) {
if (tile != null && tile.hasBuffer()) {
idleTileConsumerCacheList.add(tile);
if (idleTileConsumerCacheList.size() > IDLE_TILE_SYNC_GRANULARITY) {
synchronized (idleBuffers) {
idleBuffers.addAll(idleTileConsumerCacheList);
}
idleTileConsumerCacheList.clear();
}
}
}
/**
* Releases thread-local tiles cached for use by the rasterizing thread.
* Allowed caller: Rasterizer/Producer-Thread
*/
public void disposeRasterizerResources() {
releaseTiles(idleTileWorkerCacheList);
}
/**
* Releases thread-local tiles cached for performance reasons. Allowed
* Allowed caller: MaskBlit/Consumer-Thread
*/
public void disposeConsumerResources() {
releaseTiles(idleTileConsumerCacheList);
}
/**
* Release a list of tiles and allow it to be re-used by another thread.
* Thread safe.
*/
public void releaseTiles(List<JulesTile> tileList) {
if (tileList.size() > 0) {
synchronized (idleBuffers) {
idleBuffers.addAll(tileList);
}
tileList.clear();
}
}
}
/*
* Copyright 2010 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.jules;
import java.awt.*;
import java.awt.geom.*;
import java.util.concurrent.*;
import sun.java2d.pipe.*;
import sun.java2d.xr.*;
public class JulesAATileGenerator implements AATileGenerator {
/* Threading stuff */
final static ExecutorService rasterThreadPool =
Executors.newCachedThreadPool();
final static int CPU_CNT = Runtime.getRuntime().availableProcessors();
final static boolean ENABLE_THREADING = false;
final static int THREAD_MIN = 16;
final static int THREAD_BEGIN = 16;
IdleTileCache tileCache;
TileWorker worker;
boolean threaded = false;
int rasterTileCnt;
/* Tiling */
final static int TILE_SIZE = 32;
final static int TILE_SIZE_FP = 32 << 16;
int left, right, top, bottom, width, height;
int leftFP, topFP;
int tileCnt, tilesX, tilesY;
int currTilePos = 0;
TrapezoidList traps;
TileTrapContainer[] tiledTrapArray;
JulesTile mainTile;
public JulesAATileGenerator(Shape s, AffineTransform at, Region clip,
BasicStroke bs, boolean thin,
boolean normalize, int[] bbox) {
JulesPathBuf buf = new JulesPathBuf();
if (bs == null) {
traps = buf.tesselateFill(s, at, clip);
} else {
traps = buf.tesselateStroke(s, bs, thin, false, true, at, clip);
}
calculateArea(bbox);
bucketSortTraps();
calculateTypicalAlpha();
threaded = ENABLE_THREADING &&
rasterTileCnt >= THREAD_MIN && CPU_CNT >= 2;
if (threaded) {
tileCache = new IdleTileCache();
worker = new TileWorker(this, THREAD_BEGIN, tileCache);
rasterThreadPool.execute(worker);
}
mainTile = new JulesTile();
}
private static native long
rasterizeTrapezoidsNative(long pixmanImagePtr, int[] traps,
int[] trapPos, int trapCnt,
byte[] buffer, int xOff, int yOff);
private static native void freePixmanImgPtr(long pixmanImgPtr);
private void calculateArea(int[] bbox) {
tilesX = 0;
tilesY = 0;
tileCnt = 0;
bbox[0] = 0;
bbox[1] = 0;
bbox[2] = 0;
bbox[3] = 0;
if (traps.getSize() > 0) {
left = traps.getLeft();
right = traps.getRight();
top = traps.getTop();
bottom = traps.getBottom();
leftFP = left << 16;
topFP = top << 16;
bbox[0] = left;
bbox[1] = top;
bbox[2] = right;
bbox[3] = bottom;
width = right - left;
height = bottom - top;
if (width > 0 && height > 0) {
tilesX = (int) Math.ceil(((double) width) / TILE_SIZE);
tilesY = (int) Math.ceil(((double) height) / TILE_SIZE);
tileCnt = tilesY * tilesX;
tiledTrapArray = new TileTrapContainer[tileCnt];
} else {
// If there is no area touched by the traps, don't
// render them.
traps.setSize(0);
}
}
}
private void bucketSortTraps() {
for (int i = 0; i < traps.getSize(); i++) {
int top = traps.getTop(i) - XRUtils.XDoubleToFixed(this.top);
int bottom = traps.getBottom(i) - topFP;
int p1xLeft = traps.getP1XLeft(i) - leftFP;
int p2xLeft = traps.getP2XLeft(i) - leftFP;
int p1xRight = traps.getP1XRight(i) - leftFP;
int p2xRight = traps.getP2XRight(i) - leftFP;
int minLeft = Math.min(p1xLeft, p2xLeft);
int maxRight = Math.max(p1xRight, p2xRight);
maxRight = maxRight > 0 ? maxRight - 1 : maxRight;
bottom = bottom > 0 ? bottom - 1 : bottom;
int startTileY = top / TILE_SIZE_FP;
int endTileY = bottom / TILE_SIZE_FP;
int startTileX = minLeft / TILE_SIZE_FP;
int endTileX = maxRight / TILE_SIZE_FP;
for (int n = startTileY; n <= endTileY; n++) {
for (int m = startTileX; m <= endTileX; m++) {
int trapArrayPos = n * tilesX + m;
TileTrapContainer trapTileList = tiledTrapArray[trapArrayPos];
if (trapTileList == null) {
trapTileList = new TileTrapContainer(new GrowableIntArray(1, 16));
tiledTrapArray[trapArrayPos] = trapTileList;
}
trapTileList.getTraps().addInt(i);
}
}
}
}
public void getAlpha(byte[] tileBuffer, int offset, int rowstride) {
JulesTile tile = null;
if (threaded) {
tile = worker.getPreRasterizedTile(currTilePos);
}
if (tile != null) {
System.arraycopy(tile.getImgBuffer(), 0,
tileBuffer, 0, tileBuffer.length);
tileCache.releaseTile(tile);
} else {
mainTile.setImgBuffer(tileBuffer);
rasterizeTile(currTilePos, mainTile);
}
nextTile();
}
public void calculateTypicalAlpha() {
rasterTileCnt = 0;
for (int index = 0; index < tileCnt; index++) {
TileTrapContainer trapCont = tiledTrapArray[index];
if (trapCont != null) {
GrowableIntArray trapList = trapCont.getTraps();
int tileAlpha = 127;
if (trapList == null || trapList.getSize() == 0) {
tileAlpha = 0;
} else if (doTrapsCoverTile(trapList, index)) {
tileAlpha = 0xff;
}
if (tileAlpha == 127 || tileAlpha == 0xff) {
rasterTileCnt++;
}
trapCont.setTileAlpha(tileAlpha);
}
}
}
/*
* Optimization for large fills. Foutunatly cairo does generate an y-sorted
* list of trapezoids. This makes it quite simple to check wether a tile is
* fully covered by traps by: - Checking wether the tile is fully covered by
* traps vertically (trap 2 starts where trap 1 ended) - Checking wether all
* traps cover the tile horizontally This also works, when a single tile
* coveres the whole tile.
*/
protected boolean doTrapsCoverTile(GrowableIntArray trapList, int tileIndex) {
// Don't bother optimizing tiles with lots of traps, usually it won't
// succeed anyway.
if (trapList.getSize() > TILE_SIZE) {
return false;
}
int tileStartX = getXPos(tileIndex) * TILE_SIZE_FP + leftFP;
int tileStartY = getYPos(tileIndex) * TILE_SIZE_FP + topFP;
int tileEndX = tileStartX + TILE_SIZE_FP;
int tileEndY = tileStartY + TILE_SIZE_FP;
// Check wether first tile covers the beginning of the tile vertically
int firstTop = traps.getTop(trapList.getInt(0));
int firstBottom = traps.getBottom(trapList.getInt(0));
if (firstTop > tileStartY || firstBottom < tileStartY) {
return false;
}
// Initialize lastBottom with top, in order to pass the checks for the
// first iteration
int lastBottom = firstTop;
for (int i = 0; i < trapList.getSize(); i++) {
int trapPos = trapList.getInt(i);
if (traps.getP1XLeft(trapPos) > tileStartX ||
traps.getP2XLeft(trapPos) > tileStartX ||
traps.getP1XRight(trapPos) < tileEndX ||
traps.getP2XRight(trapPos) < tileEndX ||
traps.getTop(trapPos) != lastBottom)
{
return false;
}
lastBottom = traps.getBottom(trapPos);
}
// When the last trap covered the tileEnd vertically, the tile is fully
// covered
return lastBottom >= tileEndY;
}
public int getTypicalAlpha() {
if (tiledTrapArray[currTilePos] == null) {
return 0;
} else {
return tiledTrapArray[currTilePos].getTileAlpha();
}
}
public void dispose() {
freePixmanImgPtr(mainTile.getPixmanImgPtr());
if (threaded) {
tileCache.disposeConsumerResources();
worker.disposeConsumerResources();
}
}
protected JulesTile rasterizeTile(int tileIndex, JulesTile tile) {
int tileOffsetX = left + getXPos(tileIndex) * TILE_SIZE;
int tileOffsetY = top + getYPos(tileIndex) * TILE_SIZE;
TileTrapContainer trapCont = tiledTrapArray[tileIndex];
GrowableIntArray trapList = trapCont.getTraps();
if (trapCont.getTileAlpha() == 127) {
long pixmanImgPtr =
rasterizeTrapezoidsNative(tile.getPixmanImgPtr(),
traps.getTrapArray(),
trapList.getArray(),
trapList.getSize(),
tile.getImgBuffer(),
tileOffsetX, tileOffsetY);
tile.setPixmanImgPtr(pixmanImgPtr);
}
tile.setTilePos(tileIndex);
return tile;
}
protected int getXPos(int arrayPos) {
return arrayPos % tilesX;
}
protected int getYPos(int arrayPos) {
return arrayPos / tilesX;
}
public void nextTile() {
currTilePos++;
}
public int getTileHeight() {
return TILE_SIZE;
}
public int getTileWidth() {
return TILE_SIZE;
}
public int getTileCount() {
return tileCnt;
}
public TileTrapContainer getTrapContainer(int index) {
return tiledTrapArray[index];
}
}
class TileTrapContainer {
int tileAlpha;
GrowableIntArray traps;
public TileTrapContainer(GrowableIntArray traps) {
this.traps = traps;
}
public void setTileAlpha(int tileAlpha) {
this.tileAlpha = tileAlpha;
}
public int getTileAlpha() {
return tileAlpha;
}
public GrowableIntArray getTraps() {
return traps;
}
}
/*
* Copyright 2010 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.jules;
import java.awt.*;
import java.awt.geom.*;
import sun.awt.X11GraphicsEnvironment;
import sun.java2d.pipe.*;
import sun.java2d.xr.*;
public class JulesPathBuf {
static final double[] emptyDash = new double[0];
private static final byte CAIRO_PATH_OP_MOVE_TO = 0;
private static final byte CAIRO_PATH_OP_LINE_TO = 1;
private static final byte CAIRO_PATH_OP_CURVE_TO = 2;
private static final byte CAIRO_PATH_OP_CLOSE_PATH = 3;
private static final int CAIRO_FILL_RULE_WINDING = 0;
private static final int CAIRO_FILL_RULE_EVEN_ODD = 1;
GrowablePointArray points = new GrowablePointArray(128);
GrowableByteArray ops = new GrowableByteArray(1, 128);
int[] xTrapArray = new int[512];
private static final boolean isCairoAvailable;
static {
isCairoAvailable =
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<Boolean>() {
public Boolean run() {
boolean loadSuccess = false;
if (X11GraphicsEnvironment.isXRenderAvailable()) {
try {
System.loadLibrary("jules");
loadSuccess = true;
if (X11GraphicsEnvironment.isXRenderVerbose()) {
System.out.println(
"Xrender: INFO: Jules library loaded");
}
} catch (UnsatisfiedLinkError ex) {
loadSuccess = false;
if (X11GraphicsEnvironment.isXRenderVerbose()) {
System.out.println(
"Xrender: INFO: Jules library not installed.");
}
}
}
return Boolean.valueOf(loadSuccess);
}
});
}
public static boolean isCairoAvailable() {
return isCairoAvailable;
}
public TrapezoidList tesselateFill(Shape s, AffineTransform at, Region clip) {
int windingRule = convertPathData(s, at);
xTrapArray[0] = 0;
xTrapArray = tesselateFillNative(points.getArray(), ops.getArray(),
points.getSize(), ops.getSize(),
xTrapArray, xTrapArray.length,
getCairoWindingRule(windingRule),
clip.getLoX(), clip.getLoY(),
clip.getHiX(), clip.getHiY());
return new TrapezoidList(xTrapArray);
}
public TrapezoidList tesselateStroke(Shape s, BasicStroke bs, boolean thin,
boolean adjust, boolean antialias,
AffineTransform at, Region clip) {
float lw;
if (thin) {
if (antialias) {
lw = 0.5f;
} else {
lw = 1.0f;
}
} else {
lw = bs.getLineWidth();
}
convertPathData(s, at);
double[] dashArray = floatToDoubleArray(bs.getDashArray());
xTrapArray[0] = 0;
xTrapArray =
tesselateStrokeNative(points.getArray(), ops.getArray(),
points.getSize(), ops.getSize(),
xTrapArray, xTrapArray.length, lw,
bs.getEndCap(), bs.getLineJoin(),
bs.getMiterLimit(), dashArray,
dashArray.length, bs.getDashPhase(),
1, 0, 0, 0, 1, 0,
clip.getLoX(), clip.getLoY(),
clip.getHiX(), clip.getHiY());
return new TrapezoidList(xTrapArray);
}
protected double[] floatToDoubleArray(float[] dashArrayFloat) {
double[] dashArrayDouble = emptyDash;
if (dashArrayFloat != null) {
dashArrayDouble = new double[dashArrayFloat.length];
for (int i = 0; i < dashArrayFloat.length; i++) {
dashArrayDouble[i] = dashArrayFloat[i];
}
}
return dashArrayDouble;
}
protected int convertPathData(Shape s, AffineTransform at) {
PathIterator pi = s.getPathIterator(at);
double[] coords = new double[6];
double currX = 0;
double currY = 0;
while (!pi.isDone()) {
int curOp = pi.currentSegment(coords);
int pointIndex;
switch (curOp) {
case PathIterator.SEG_MOVETO:
ops.addByte(CAIRO_PATH_OP_MOVE_TO);
pointIndex = points.getNextIndex();
points.setX(pointIndex, DoubleToCairoFixed(coords[0]));
points.setY(pointIndex, DoubleToCairoFixed(coords[1]));
currX = coords[0];
currY = coords[1];
break;
case PathIterator.SEG_LINETO:
ops.addByte(CAIRO_PATH_OP_LINE_TO);
pointIndex = points.getNextIndex();
points.setX(pointIndex, DoubleToCairoFixed(coords[0]));
points.setY(pointIndex, DoubleToCairoFixed(coords[1]));
currX = coords[0];
currY = coords[1];
break;
/**
* q0 = p0
* q1 = (p0+2*p1)/3
* q2 = (p2+2*p1)/3
* q3 = p2
*/
case PathIterator.SEG_QUADTO:
double x1 = coords[0];
double y1 = coords[1];
double x2, y2;
double x3 = coords[2];
double y3 = coords[3];
x2 = x1 + (x3 - x1) / 3;
y2 = y1 + (y3 - y1) / 3;
x1 = currX + 2 * (x1 - currX) / 3;
y1 =currY + 2 * (y1 - currY) / 3;
ops.addByte(CAIRO_PATH_OP_CURVE_TO);
pointIndex = points.getNextIndex();
points.setX(pointIndex, DoubleToCairoFixed(x1));
points.setY(pointIndex, DoubleToCairoFixed(y1));
pointIndex = points.getNextIndex();
points.setX(pointIndex, DoubleToCairoFixed(x2));
points.setY(pointIndex, DoubleToCairoFixed(y2));
pointIndex = points.getNextIndex();
points.setX(pointIndex, DoubleToCairoFixed(x3));
points.setY(pointIndex, DoubleToCairoFixed(y3));
currX = x3;
currY = y3;
break;
case PathIterator.SEG_CUBICTO:
ops.addByte(CAIRO_PATH_OP_CURVE_TO);
pointIndex = points.getNextIndex();
points.setX(pointIndex, DoubleToCairoFixed(coords[0]));
points.setY(pointIndex, DoubleToCairoFixed(coords[1]));
pointIndex = points.getNextIndex();
points.setX(pointIndex, DoubleToCairoFixed(coords[2]));
points.setY(pointIndex, DoubleToCairoFixed(coords[3]));
pointIndex = points.getNextIndex();
points.setX(pointIndex, DoubleToCairoFixed(coords[4]));
points.setY(pointIndex, DoubleToCairoFixed(coords[5]));
currX = coords[4];
currY = coords[5];
break;
case PathIterator.SEG_CLOSE:
ops.addByte(CAIRO_PATH_OP_CLOSE_PATH);
break;
}
pi.next();
}
return pi.getWindingRule();
}
private static native int[]
tesselateStrokeNative(int[] pointArray, byte[] ops,
int pointCnt, int opCnt,
int[] xTrapArray, int xTrapArrayLength,
double lineWidth, int lineCap, int lineJoin,
double miterLimit, double[] dashArray,
int dashCnt, double offset,
double m00, double m01, double m02,
double m10, double m11, double m12,
int clipLowX, int clipLowY,
int clipWidth, int clipHeight);
private static native int[]
tesselateFillNative(int[] pointArray, byte[] ops, int pointCnt,
int opCnt, int[] xTrapArray, int xTrapArrayLength,
int windingRule, int clipLowX, int clipLowY, int clipWidth, int clipHeight);
public void clear() {
points.clear();
ops.clear();
xTrapArray[0] = 0;
}
private static int DoubleToCairoFixed(double dbl) {
return (int) (dbl * 256);
}
private static int getCairoWindingRule(int j2dWindingRule) {
switch(j2dWindingRule) {
case PathIterator.WIND_EVEN_ODD:
return CAIRO_FILL_RULE_EVEN_ODD;
case PathIterator.WIND_NON_ZERO:
return CAIRO_FILL_RULE_WINDING;
default:
throw new IllegalArgumentException("Illegal Java2D winding rule specified");
}
}
}
/*
* Copyright 2010 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.jules;
import java.awt.*;
import java.awt.geom.*;
import sun.java2d.pipe.*;
import sun.java2d.pisces.*;
public class JulesRenderingEngine extends PiscesRenderingEngine {
@Override
public AATileGenerator
getAATileGenerator(Shape s, AffineTransform at, Region clip,
BasicStroke bs, boolean thin,
boolean normalize, int[] bbox) {
if (JulesPathBuf.isCairoAvailable()) {
return new JulesAATileGenerator(s, at, clip, bs, thin,
normalize, bbox);
} else {
return super.getAATileGenerator(s, at, clip, bs, thin,
normalize, bbox);
}
}
public float getMinimumAAPenSize() {
return 0.5f;
}
}
/*
* Copyright 2010 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.jules;
import java.awt.*;
import sun.awt.*;
import sun.java2d.*;
import sun.java2d.pipe.*;
import sun.java2d.xr.*;
public class JulesShapePipe implements ShapeDrawPipe {
XRCompositeManager compMan;
JulesPathBuf buf = new JulesPathBuf();
public JulesShapePipe(XRCompositeManager compMan) {
this.compMan = compMan;
}
/**
* Common validate method, used by all XRRender functions to validate the
* destination context.
*/
private final void validateSurface(SunGraphics2D sg2d) {
XRSurfaceData xrsd = (XRSurfaceData) sg2d.surfaceData;
xrsd.validateAsDestination(sg2d, sg2d.getCompClip());
xrsd.maskBuffer.validateCompositeState(sg2d.composite, sg2d.transform,
sg2d.paint, sg2d);
}
public void draw(SunGraphics2D sg2d, Shape s) {
try {
SunToolkit.awtLock();
validateSurface(sg2d);
XRSurfaceData xrsd = (XRSurfaceData) sg2d.surfaceData;
BasicStroke bs;
if (sg2d.stroke instanceof BasicStroke) {
bs = (BasicStroke) sg2d.stroke;
} else { //TODO: What happens in the case of a !BasicStroke??
s = sg2d.stroke.createStrokedShape(s);
bs = null;
}
boolean adjust =
(bs != null && sg2d.strokeHint != SunHints.INTVAL_STROKE_PURE);
boolean thin = (sg2d.strokeState <= SunGraphics2D.STROKE_THINDASHED);
TrapezoidList traps =
buf.tesselateStroke(s, bs, thin, adjust, true,
sg2d.transform, sg2d.getCompClip());
compMan.XRCompositeTraps(xrsd.picture,
sg2d.transX, sg2d.transY, traps);
buf.clear();
} finally {
SunToolkit.awtUnlock();
}
}
public void fill(SunGraphics2D sg2d, Shape s) {
try {
SunToolkit.awtLock();
validateSurface(sg2d);
XRSurfaceData xrsd = (XRSurfaceData) sg2d.surfaceData;
TrapezoidList traps = buf.tesselateFill(s, sg2d.transform,
sg2d.getCompClip());
compMan.XRCompositeTraps(xrsd.picture, 0, 0, traps);
buf.clear();
} finally {
SunToolkit.awtUnlock();
}
}
}
/*
* Copyright 2010 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.jules;
public class JulesTile {
byte[] imgBuffer;
long pixmanImgPtr = 0;
int tilePos;
public JulesTile() {
}
public byte[] getImgBuffer() {
if(imgBuffer == null) {
imgBuffer = new byte[1024];
}
return imgBuffer;
}
public long getPixmanImgPtr() {
return pixmanImgPtr;
}
public void setPixmanImgPtr(long pixmanImgPtr) {
this.pixmanImgPtr = pixmanImgPtr;
}
public boolean hasBuffer() {
return imgBuffer != null;
}
public int getTilePos() {
return tilePos;
}
public void setTilePos(int tilePos) {
this.tilePos = tilePos;
}
public void setImgBuffer(byte[] imgBuffer){
this.imgBuffer = imgBuffer;
}
}
/*
* Copyright 2010 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.jules;
import java.util.*;
public class TileWorker implements Runnable {
final static int RASTERIZED_TILE_SYNC_GRANULARITY = 8;
final ArrayList<JulesTile> rasterizedTileConsumerCache =
new ArrayList<JulesTile>();
final LinkedList<JulesTile> rasterizedBuffers = new LinkedList<JulesTile>();
IdleTileCache tileCache;
JulesAATileGenerator tileGenerator;
int workerStartIndex;
volatile int consumerPos = 0;
/* Threading statistics */
int mainThreadCnt = 0;
int workerCnt = 0;
int doubled = 0;
public TileWorker(JulesAATileGenerator tileGenerator, int workerStartIndex, IdleTileCache tileCache) {
this.tileGenerator = tileGenerator;
this.workerStartIndex = workerStartIndex;
this.tileCache = tileCache;
}
public void run() {
ArrayList<JulesTile> tiles = new ArrayList<JulesTile>(16);
for (int i = workerStartIndex; i < tileGenerator.getTileCount(); i++) {
TileTrapContainer tile = tileGenerator.getTrapContainer(i);
if (tile != null && tile.getTileAlpha() == 127) {
JulesTile rasterizedTile =
tileGenerator.rasterizeTile(i,
tileCache.getIdleTileWorker(
tileGenerator.getTileCount() - i - 1));
tiles.add(rasterizedTile);
if (tiles.size() > RASTERIZED_TILE_SYNC_GRANULARITY) {
addRasterizedTiles(tiles);
tiles.clear();
}
}
i = Math.max(i, consumerPos + RASTERIZED_TILE_SYNC_GRANULARITY / 2);
}
addRasterizedTiles(tiles);
tileCache.disposeRasterizerResources();
}
/**
* Returns a rasterized tile for the specified tilePos,
* or null if it isn't available.
* Allowed caller: MaskBlit/Consumer-Thread
*/
public JulesTile getPreRasterizedTile(int tilePos) {
JulesTile tile = null;
if (rasterizedTileConsumerCache.size() == 0 &&
tilePos >= workerStartIndex)
{
synchronized (rasterizedBuffers) {
rasterizedTileConsumerCache.addAll(rasterizedBuffers);
rasterizedBuffers.clear();
}
}
while (tile == null && rasterizedTileConsumerCache.size() > 0) {
JulesTile t = rasterizedTileConsumerCache.get(0);
if (t.getTilePos() > tilePos) {
break;
}
if (t.getTilePos() < tilePos) {
tileCache.releaseTile(t);
doubled++;
}
if (t.getTilePos() <= tilePos) {
rasterizedTileConsumerCache.remove(0);
}
if (t.getTilePos() == tilePos) {
tile = t;
}
}
if (tile == null) {
mainThreadCnt++;
// If there are no tiles left, tell the producer the current
// position. This avoids producing tiles twice.
consumerPos = tilePos;
} else {
workerCnt++;
}
return tile;
}
private void addRasterizedTiles(ArrayList<JulesTile> tiles) {
synchronized (rasterizedBuffers) {
rasterizedBuffers.addAll(tiles);
}
}
/**
* Releases cached tiles.
* Allowed caller: MaskBlit/Consumer-Thread
*/
public void disposeConsumerResources() {
synchronized (rasterizedBuffers) {
tileCache.releaseTiles(rasterizedBuffers);
}
tileCache.releaseTiles(rasterizedTileConsumerCache);
}
}
/*
* Copyright 2010 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.jules;
public class TrapezoidList {
public static final int TRAP_START_INDEX = 5;
public static final int TRAP_SIZE = 10;
int[] trapArray;
public TrapezoidList(int[] trapArray) {
this.trapArray = trapArray;
}
public final int[] getTrapArray() {
return trapArray;
}
public final int getSize() {
return trapArray[0];
}
public final void setSize(int size) {
trapArray[0] = 0;
}
public final int getLeft() {
return trapArray[1];
}
public final int getTop() {
return trapArray[2];
}
public final int getRight() {
return trapArray[3];
}
public final int getBottom() {
return trapArray[4];
}
private final int getTrapStartAddresse(int pos) {
return TRAP_START_INDEX + TRAP_SIZE * pos;
}
public final int getTop(int pos) {
return trapArray[getTrapStartAddresse(pos) + 0];
}
public final int getBottom(int pos) {
return trapArray[getTrapStartAddresse(pos) + 1];
}
public final int getP1XLeft(int pos) {
return trapArray[getTrapStartAddresse(pos) + 2];
}
public final int getP1YLeft(int pos) {
return trapArray[getTrapStartAddresse(pos) + 3];
}
public final int getP2XLeft(int pos) {
return trapArray[getTrapStartAddresse(pos) + 4];
}
public final int getP2YLeft(int pos) {
return trapArray[getTrapStartAddresse(pos) + 5];
}
public final int getP1XRight(int pos) {
return trapArray[getTrapStartAddresse(pos) + 6];
}
public final int getP1YRight(int pos) {
return trapArray[getTrapStartAddresse(pos) + 7];
}
public final int getP2XRight(int pos) {
return trapArray[getTrapStartAddresse(pos) + 8];
}
public final int getP2YRight(int pos) {
return trapArray[getTrapStartAddresse(pos) + 9];
}
}
......@@ -46,6 +46,7 @@ import sun.awt.SunHints;
import sun.awt.SunToolkit;
import sun.awt.X11ComponentPeer;
import sun.awt.X11GraphicsConfig;
import sun.awt.X11GraphicsEnvironment;
import sun.awt.image.PixelConverter;
import sun.font.X11TextRenderer;
import sun.java2d.InvalidPipeException;
......@@ -64,7 +65,7 @@ import sun.java2d.pipe.PixelToShapeConverter;
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;
......@@ -74,8 +75,6 @@ public abstract class X11SurfaceData extends SurfaceData {
private static native void initIDs(Class xorComp, boolean tryDGA);
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";
......@@ -212,7 +211,8 @@ public abstract class X11SurfaceData extends SurfaceData {
protected static boolean dgaAvailable;
static {
if (!GraphicsEnvironment.isHeadless()) {
if (!isX11SurfaceDataInitialized() &&
!GraphicsEnvironment.isHeadless()) {
// If a screen magnifier is present, don't attempt to use DGA
String magPresent = (String) java.security.AccessController.doPrivileged
(new sun.security.action.GetPropertyAction("javax.accessibility.screen_magnifier_present"));
......@@ -245,7 +245,7 @@ public abstract class X11SurfaceData extends SurfaceData {
X11PMBlitLoops.register();
X11PMBlitBgLoops.register();
}
}
}
}
/**
......@@ -432,11 +432,11 @@ public abstract class X11SurfaceData extends SurfaceData {
cm, drawable, transparency);
}
/**
* Initializes the native Ops pointer.
*/
private native void initOps(X11ComponentPeer peer,
X11GraphicsConfig gc, int depth);
// /**
// * Initializes the native Ops pointer.
// */
// private native void initOps(X11ComponentPeer peer,
// X11GraphicsConfig gc, int depth);
protected X11SurfaceData(X11ComponentPeer peer,
X11GraphicsConfig gc,
......@@ -613,8 +613,6 @@ public abstract class X11SurfaceData extends SurfaceData {
return sType;
}
public native void setInvalid();
public void invalidate() {
if (isValid()) {
setInvalid();
......@@ -628,16 +626,9 @@ public abstract class X11SurfaceData extends SurfaceData {
* 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;
......
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 {
static boolean isX11SurfaceDataInitialized = false;
public static boolean isX11SurfaceDataInitialized() {
return isX11SurfaceDataInitialized;
}
public static void setX11SurfaceDataInitialized() {
isX11SurfaceDataInitialized = true;
}
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);
}
/*
* Copyright 2010 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.lang.Math.min;
import static java.lang.Math.max;
import static sun.java2d.xr.MaskTileManager.MASK_SIZE;
/**
* This class implements region tracking, used by the tiled-mask code.
*
* @author Clemens Eisserer
*/
public class DirtyRegion implements Cloneable {
int x, y, x2, y2;
public DirtyRegion() {
clear();
}
public void clear() {
x = Integer.MAX_VALUE;
y = Integer.MAX_VALUE;
x2 = Integer.MIN_VALUE;
y2 = Integer.MIN_VALUE;
}
public void growDirtyRegion(int x, int y, int x2, int y2) {
this.x = min(x, this.x);
this.y = min(y, this.y);
this.x2 = max(x2, this.x2);
this.y2 = max(y2, this.y2);
}
public int getWidth() {
return x2 - x;
}
public int getHeight() {
return y2 - y;
}
public void growDirtyRegionTileLimit(int x, int y, int x2, int y2) {
if (x < this.x) {
this.x = max(x, 0);
}
if (y < this.y) {
this.y = max(y, 0);
}
if (x2 > this.x2) {
this.x2 = min(x2, MASK_SIZE);
}
if (y2 > this.y2) {
this.y2 = min(y2, MASK_SIZE);
}
}
public static DirtyRegion combineRegion(DirtyRegion region1,
DirtyRegion region2) {
DirtyRegion region = new DirtyRegion();
region.x = min(region1.x, region2.x);
region.y = min(region1.y, region2.y);
region.x2 = max(region1.x2, region2.x2);
region.y2 = max(region1.y2, region2.y2);
return region;
}
public void setDirtyLineRegion(int x1, int y1, int x2, int y2) {
if (x1 < x2) {
this.x = x1;
this.x2 = x2;
} else {
this.x = x2;
this.x2 = x1;
}
if (y1 < y2) {
this.y = y1;
this.y2 = y2;
} else {
this.y = y2;
this.y2 = y1;
}
}
public void translate(int x, int y) {
if (this.x != Integer.MAX_VALUE) {
this.x += x;
this.x2 += x;
this.y += y;
this.y2 += y;
}
}
public String toString() {
return this.getClass().getName() +
"(x: " + x + ", y:" + y + ", x2:" + x2 + ", y2:" + y2 + ")";
}
public DirtyRegion cloneRegion() {
try {
return (DirtyRegion) clone();
} catch (CloneNotSupportedException ex) {
ex.printStackTrace();
}
return null;
}
}
/*
* Copyright 2010 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.util.*;
/**
* Growable int array, designed to allow subclasses to emulate
* the behaviour of value types.
*
* @author Clemens Eisserer
*/
public class GrowableByteArray
{
byte[] array;
int size;
int cellSize;
public GrowableByteArray(int cellSize, int initialSize)
{
array = new byte[initialSize];
size = 0;
this.cellSize = cellSize;
}
private int getNextCellIndex()
{
int oldSize = size;
size += cellSize;
if (size >= array.length)
{
growArray();
}
return oldSize;
}
/**
* @return a direct reference to the backing array.
*/
public byte[] getArray()
{
return array;
}
/**
* @return a copy of the backing array.
*/
public byte[] getSizedArray()
{
return Arrays.copyOf(array, getSize());
}
public final int getByte(int index)
{
return array[getCellIndex(index)];
}
/**
* Returns the index of the next free cell,
* and grows the backing arrays if required.
*/
public final int getNextIndex()
{
return getNextCellIndex() / cellSize;
}
protected final int getCellIndex(int cellIndex)
{
return cellSize * cellIndex;
}
public final void addByte(byte i)
{
int nextIndex = getNextIndex();
array[nextIndex] = i;
}
/**
* @return The number of stored cells.
*/
public final int getSize()
{
return size / cellSize;
}
public void clear()
{
size = 0;
}
protected void growArray()
{
int newSize = Math.max(array.length * 2, 10);
byte[] oldArray = array;
array = new byte[newSize];
System.arraycopy(oldArray, 0, array, 0, oldArray.length);
}
}
/*
* Copyright 2010 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;
/**
* Class to efficiently store glyph information for laid out glyphs,
* passed to native or java backend.
*
* @author Clemens Eisserer
*/
public class GrowableEltArray extends GrowableIntArray {
private static final int ELT_SIZE = 4;
GrowableIntArray glyphs;
public GrowableEltArray(int initialSize)
{
super(ELT_SIZE, initialSize);
glyphs = new GrowableIntArray(1, initialSize*8);
}
public final int getCharCnt(int index) {
return array[getCellIndex(index) + 0];
}
public final void setCharCnt(int index, int cnt) {
array[getCellIndex(index) + 0] = cnt;
}
public final int getXOff(int index) {
return array[getCellIndex(index) + 1];
}
public final void setXOff(int index, int xOff) {
array[getCellIndex(index) + 1] = xOff;
}
public final int getYOff(int index) {
return array[getCellIndex(index) + 2];
}
public final void setYOff(int index, int yOff) {
array[getCellIndex(index) + 2] = yOff;
}
public final int getGlyphSet(int index) {
return array[getCellIndex(index) + 3];
}
public final void setGlyphSet(int index, int glyphSet) {
array[getCellIndex(index) + 3] = glyphSet;
}
public GrowableIntArray getGlyphs() {
return glyphs;
}
public void clear() {
glyphs.clear();
super.clear();
}
}
/*
* Copyright 2010 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.util.*;
/**
* Growable int array, designed to allow subclasses to emulate
* the behaviour of value types.
*
* @author Clemens Eisserer
*/
public class GrowableIntArray {
int[] array;
int size;
int cellSize;
public GrowableIntArray(int cellSize, int initialSize) {
array = new int[initialSize];
size = 0;
this.cellSize = cellSize;
}
private int getNextCellIndex() {
int oldSize = size;
size += cellSize;
if (size >= array.length) {
growArray();
}
return oldSize;
}
/**
* @return a direct reference to the backing array.
*/
public int[] getArray() {
return array;
}
/**
* @return a copy of the backing array.
*/
public int[] getSizedArray() {
return Arrays.copyOf(array, getSize());
}
/**
* Returns the index of the next free cell,
* and grows the backing arrays if required.
*/
public final int getNextIndex() {
return getNextCellIndex() / cellSize;
}
protected final int getCellIndex(int cellIndex) {
return cellSize * cellIndex;
}
public final int getInt(int cellIndex) {
return array[cellIndex];
}
public final void addInt(int i) {
int nextIndex = getNextIndex();
array[nextIndex] = i;
}
/**
* @return The number of stored cells.
*/
public final int getSize() {
return size / cellSize;
}
public void clear() {
size = 0;
}
protected void growArray() {
int newSize = Math.max(array.length * 2, 10);
int[] oldArray = array;
array = new int[newSize];
System.arraycopy(oldArray, 0, array, 0, oldArray.length);
}
}
/*
* Copyright 2010 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;
/**
* Class to efficiently store rectangles.
*
* @author Clemens Eisserer
*/
public class GrowablePointArray extends GrowableIntArray
{
private static final int POINT_SIZE = 2;
public GrowablePointArray(int initialSize)
{
super(POINT_SIZE, initialSize);
}
public final int getX(int index)
{
return array[getCellIndex(index)];
}
public final int getY(int index)
{
return array[getCellIndex(index) + 1];
}
public final void setX(int index, int x)
{
array[getCellIndex(index)] = x;
}
public final void setY(int index, int y)
{
array[getCellIndex(index) + 1] = y;
}
}
/*
* Copyright 2010 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;
/**
* Class to efficiently store rectangles.
*
* @author Clemens Eisserer
*/
public class GrowableRectArray extends GrowableIntArray {
private static final int RECT_SIZE = 4;
public GrowableRectArray(int initialSize) {
super(RECT_SIZE, initialSize);
}
public final void setX(int index, int x) {
array[getCellIndex(index)] = x;
}
public final void setY(int index, int y) {
array[getCellIndex(index) + 1] = y;
}
public final void setWidth(int index, int width) {
array[getCellIndex(index) + 2] = width;
}
public final void setHeight(int index, int height) {
array[getCellIndex(index) + 3] = height;
}
public final int getX(int index) {
return array[getCellIndex(index)];
}
public final int getY(int index) {
return array[getCellIndex(index) + 1];
}
public final int getWidth(int index) {
return array[getCellIndex(index) + 2];
}
public final int getHeight(int index) {
return array[getCellIndex(index) + 3];
}
public final void translateRects(int x, int y) {
for (int i = 0; i < getSize(); i++) {
setX(i, getX(i) + x);
setY(i, getY(i) + y);
}
}
}
/*
* Copyright 2010 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;
/**
* Represents a single tile, used to store the rectangles covering the area
* of the mask where the tile is located.
*
* @author Clemens Eisserer
*/
public class MaskTile {
GrowableRectArray rects;
DirtyRegion dirtyArea;
public MaskTile()
{
rects = new GrowableRectArray(128);
dirtyArea = new DirtyRegion();
}
public void addRect(int x, int y, int width, int height) {
int index = rects.getNextIndex();
rects.setX(index, x);
rects.setY(index, y);
rects.setWidth(index, width);
rects.setHeight(index, height);
}
public void addLine(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
*/
DirtyRegion region = new DirtyRegion();
region.setDirtyLineRegion(x1, y1, x2, y2);
int xDiff = region.x2 - region.x;
int yDiff = region.y2 - region.y;
if (xDiff == 0 || yDiff == 0) {
addRect(region.x, region.y,
region.x2 - region.x + 1, region.y2 - region.y + 1);
} else if (xDiff == 1 && yDiff == 1) {
addRect(x1, y1, 1, 1);
addRect(x2, y2, 1, 1);
} else {
lineToRects(x1, y1, x2, y2);
}
}
private void lineToRects(int xstart, int ystart, int xend, int yend) {
int x, y, t, dx, dy, incx, incy, pdx, pdy, ddx, ddy, es, el, err;
/* Entfernung in beiden Dimensionen berechnen */
dx = xend - xstart;
dy = yend - ystart;
/* Vorzeichen des Inkrements bestimmen */
incx = dx > 0 ? 1 : (dx < 0) ? -1 : 0;
incy = dy > 0 ? 1 : (dy < 0) ? -1 : 0;
if (dx < 0)
dx = -dx;
if (dy < 0)
dy = -dy;
/* feststellen, welche Entfernung groesser ist */
if (dx > dy) {
/* x ist schnelle Richtung */
pdx = incx;
pdy = 0; /* pd. ist Parallelschritt */
ddx = incx;
ddy = incy; /* dd. ist Diagonalschritt */
es = dy;
el = dx; /* Fehlerschritte schnell, langsam */
} else {
/* y ist schnelle Richtung */
pdx = 0;
pdy = incy; /* pd. ist Parallelschritt */
ddx = incx;
ddy = incy; /* dd. ist Diagonalschritt */
es = dx;
el = dy; /* Fehlerschritte schnell, langsam */
}
/* Initialisierungen vor Schleifenbeginn */
x = xstart;
y = ystart;
err = el / 2;
addRect(x, y, 1, 1);
/* Pixel berechnen */
for (t = 0; t < el; ++t) /* t zaehlt die Pixel, el ist auch Anzahl */
{
/* Aktualisierung Fehlerterm */
err -= es;
if (err < 0) {
/* Fehlerterm wieder positiv (>=0) machen */
err += el;
/* Schritt in langsame Richtung, Diagonalschritt */
x += ddx;
y += ddy;
} else {
/* Schritt in schnelle Richtung, Parallelschritt */
x += pdx;
y += pdy;
}
addRect(x, y, 1, 1);
// SetPixel(x,y);
// System.out.println(x+":"+y);
}
}
public void calculateDirtyAreas()
{
for (int i=0; i < rects.getSize(); i++) {
int x = rects.getX(i);
int y = rects.getY(i);
dirtyArea.growDirtyRegion(x, y,
x + rects.getWidth(i),
y + rects.getHeight(i));
}
}
public void reset() {
rects.clear();
dirtyArea.clear();
}
public void translate(int x, int y) {
if (rects.getSize() > 0) {
dirtyArea.translate(x, y);
}
rects.translateRects(x, y);
}
public GrowableRectArray getRects() {
return rects;
}
public DirtyRegion getDirtyArea() {
return dirtyArea;
}
}
/*
* Copyright 2010 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.util.*;
/**
* We render non-antialiased geometry (consisting of rectangles) into a mask,
* which is later used in a composition step.
* To avoid mask-allocations of large size, MaskTileManager splits
* geometry larger than MASK_SIZE into several tiles,
* and stores the geometry in instances of MaskTile.
*
* @author Clemens Eisserer
*/
public class MaskTileManager {
public static final int MASK_SIZE = 256;
MaskTile mainTile = new MaskTile();
ArrayList<MaskTile> tileList;
int allocatedTiles = 0;
int xTiles, yTiles;
XRCompositeManager xrMgr;
XRBackend con;
int maskPixmap;
int maskPicture;
long maskGC;
int lineMaskPixmap;
int lineMaskPicture;
long drawLineGC;
long clearLineGC;
public MaskTileManager(XRCompositeManager xrMgr, int parentXid) {
tileList = new ArrayList<MaskTile>();
this.xrMgr = xrMgr;
this.con = xrMgr.getBackend();
maskPixmap = con.createPixmap(parentXid, 8, MASK_SIZE, MASK_SIZE);
maskPicture = con.createPicture(maskPixmap, XRUtils.PictStandardA8);
con.renderRectangle(maskPicture, XRUtils.PictOpClear,
new XRColor(Color.black),
0, 0, MASK_SIZE, MASK_SIZE);
maskGC = con.createGC(maskPixmap);
con.setGCExposures(maskGC, false);
lineMaskPixmap = con.createPixmap(parentXid, 8, MASK_SIZE, MASK_SIZE);
lineMaskPicture =
con.createPicture(lineMaskPixmap, XRUtils.PictStandardA8);
con.renderRectangle(lineMaskPicture, XRUtils.PictOpClear,
new XRColor(Color.black), 0, 0, MASK_SIZE, MASK_SIZE);
drawLineGC = con.createGC(lineMaskPixmap);
con.setGCExposures(drawLineGC, false);
con.setGCForeground(drawLineGC, 255);
clearLineGC = con.createGC(lineMaskPixmap);
con.setGCExposures(clearLineGC, false);
con.setGCForeground(clearLineGC, 0);
}
/**
* Adds a rectangle to the mask.
*/
public void addRect(int x, int y, int width, int height) {
mainTile.addRect(x, y, width, height);
}
/**
* Adds a line to the mask.
*/
public void addLine(int x1, int y1, int x2, int y2) {
mainTile.addLine(x1, y1, x2, y2);
}
/**
* Transfers the geometry stored (rectangles, lines) to one or more masks,
* and renders the result to the destination surface.
*/
public void fillMask(XRSurfaceData dst) {
boolean maskRequired = xrMgr.maskRequired();
if (maskRequired) {
mainTile.calculateDirtyAreas();
DirtyRegion dirtyArea = mainTile.getDirtyArea().cloneRegion();
mainTile.translate(-dirtyArea.x, -dirtyArea.y);
XRColor maskColor = xrMgr.getMaskColor();
// We don't need tiling if all geometry fits in a single tile
if (dirtyArea.getWidth() <= MASK_SIZE &&
dirtyArea.getHeight() <= MASK_SIZE)
{
compositeSingleTile(dst, mainTile, dirtyArea,
maskRequired, 0, 0, maskColor);
} else {
allocTiles(dirtyArea);
tileRects();
for (int i = 0; i < yTiles; i++) {
for (int m = 0; m < xTiles; m++) {
MaskTile tile = tileList.get(i * xTiles + m);
int tileStartX = m * MASK_SIZE;
int tileStartY = i * MASK_SIZE;
compositeSingleTile(dst, tile, dirtyArea, maskRequired,
tileStartX, tileStartY, maskColor);
}
}
}
} else {
xrMgr.XRRenderRectangles(dst, mainTile.getRects());
}
mainTile.reset();
}
/**
* Uploads aa geometry generated for maskblit/fill into the mask pixmap.
*/
public int uploadMask(int w, int h, int maskscan, int maskoff, byte[] mask) {
int maskPic = XRUtils.None;
if (mask != null) {
float maskAlpha =
xrMgr.isTexturePaintActive() ? xrMgr.getExtraAlpha() : 1.0f;
con.putMaskImage(maskPixmap, maskGC, mask, 0, 0, 0, 0,
w, h, maskoff, maskscan, maskAlpha);
maskPic = maskPicture;
} else if (xrMgr.isTexturePaintActive()) {
maskPic = xrMgr.getExtraAlphaMask();
}
return maskPic;
}
/**
* Clears the area of the mask-pixmap used for uploading aa coverage values.
*/
public void clearUploadMask(int mask, int w, int h) {
if (mask == maskPicture) {
con.renderRectangle(maskPicture, XRUtils.PictOpClear,
XRColor.NO_ALPHA, 0, 0, w, h);
}
}
/**
* Renders the rectangles provided to the mask, and does a composition
* operation with the properties set inXRCompositeManager.
*/
protected void compositeSingleTile(XRSurfaceData dst, MaskTile tile,
DirtyRegion dirtyArea,
boolean maskRequired,
int tileStartX, int tileStartY,
XRColor maskColor) {
if (tile.rects.getSize() > 0) {
DirtyRegion tileDirtyArea = tile.getDirtyArea();
int x = tileDirtyArea.x + tileStartX + dirtyArea.x;
int y = tileDirtyArea.y + tileStartY + dirtyArea.y;
int width = tileDirtyArea.x2 - tileDirtyArea.x;
int height = tileDirtyArea.y2 - tileDirtyArea.y;
width = Math.min(width, MASK_SIZE);
height = Math.min(height, MASK_SIZE);
int rectCnt = tile.rects.getSize();
if (maskRequired) {
int mask = XRUtils.None;
/*
* Optimization: When the tile only contains one rectangle, the
* composite-operation boundaries can be used as geometry
*/
if (rectCnt > 1) {
con.renderRectangles(maskPicture, XRUtils.PictOpSrc,
maskColor, tile.rects);
mask = maskPicture;
} else {
if (xrMgr.isTexturePaintActive()) {
mask = xrMgr.getExtraAlphaMask();
}
}
xrMgr.XRComposite(XRUtils.None, mask, dst.getPicture(),
x, y, tileDirtyArea.x, tileDirtyArea.y,
x, y, width, height);
/* Clear dirty rectangle of the rect-mask */
if (rectCnt > 1) {
con.renderRectangle(maskPicture, XRUtils.PictOpClear,
XRColor.NO_ALPHA,
tileDirtyArea.x, tileDirtyArea.y,
width, height);
}
tile.reset();
} else if (rectCnt > 0) {
tile.rects.translateRects(tileStartX + dirtyArea.x,
tileStartY + dirtyArea.y);
xrMgr.XRRenderRectangles(dst, tile.rects);
}
}
}
/**
* Allocates enough MaskTile instances, to cover the whole
* mask area, or resets existing ones.
*/
protected void allocTiles(DirtyRegion maskArea) {
xTiles = (maskArea.getWidth() / MASK_SIZE) + 1;
yTiles = (maskArea.getHeight() / MASK_SIZE) + 1;
int tileCnt = xTiles * yTiles;
if (tileCnt > allocatedTiles) {
for (int i = 0; i < tileCnt; i++) {
if (i < allocatedTiles) {
tileList.get(i).reset();
} else {
tileList.add(new MaskTile());
}
}
allocatedTiles = tileCnt;
}
}
/**
* Tiles the stored rectangles, if they are larger than the MASK_SIZE
*/
protected void tileRects() {
GrowableRectArray rects = mainTile.rects;
for (int i = 0; i < rects.getSize(); i++) {
int tileXStartIndex = rects.getX(i) / MASK_SIZE;
int tileYStartIndex = rects.getY(i) / MASK_SIZE;
int tileXLength =
((rects.getX(i) + rects.getWidth(i)) / MASK_SIZE + 1) -
tileXStartIndex;
int tileYLength =
((rects.getY(i) + rects.getHeight(i)) / MASK_SIZE + 1) -
tileYStartIndex;
for (int n = 0; n < tileYLength; n++) {
for (int m = 0; m < tileXLength; m++) {
int tileIndex =
xTiles * (tileYStartIndex + n) + tileXStartIndex + m;
MaskTile tile = tileList.get(tileIndex);
GrowableRectArray rectTileList = tile.getRects();
int tileArrayIndex = rectTileList.getNextIndex();
int tileStartPosX = (tileXStartIndex + m) * MASK_SIZE;
int tileStartPosY = (tileYStartIndex + n) * MASK_SIZE;
rectTileList.setX(tileArrayIndex, rects.getX(i) - tileStartPosX);
rectTileList.setY(tileArrayIndex, rects.getY(i) - tileStartPosY);
rectTileList.setWidth(tileArrayIndex, rects.getWidth(i));
rectTileList.setHeight(tileArrayIndex, rects.getHeight(i));
limitRectCoords(rectTileList, tileArrayIndex);
tile.getDirtyArea().growDirtyRegion
(rectTileList.getX(tileArrayIndex),
rectTileList.getY(tileArrayIndex),
rectTileList.getWidth(tileArrayIndex) +
rectTileList.getX(tileArrayIndex),
rectTileList.getHeight(tileArrayIndex) +
rectTileList.getY(tileArrayIndex));
}
}
}
}
/**
* Limits the rect's coordinates to the mask coordinates. The result is used
* by growDirtyRegion.
*/
private void limitRectCoords(GrowableRectArray rects, int index) {
if ((rects.getX(index) + rects.getWidth(index)) > MASK_SIZE) {
rects.setWidth(index, MASK_SIZE - rects.getX(index));
}
if ((rects.getY(index) + rects.getHeight(index)) > MASK_SIZE) {
rects.setHeight(index, MASK_SIZE - rects.getY(index));
}
if (rects.getX(index) < 0) {
rects.setWidth(index, rects.getWidth(index) + rects.getX(index));
rects.setX(index, 0);
}
if (rects.getY(index) < 0) {
rects.setHeight(index, rects.getHeight(index) + rects.getY(index));
rects.setY(index, 0);
}
}
}
/*
* Copyright 2010 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;
/**
* Simple MutableInteger implementation to be used as a reuseable HashMap key.
*
* @author Clemens Eisserer
*/
public class MutableInteger {
private int value;
public MutableInteger(int value) {
this.setValue(value);
}
public int hashCode() {
return getValue();
}
public boolean equals(Object o) {
return (o instanceof MutableInteger) &&
(((MutableInteger) o).getValue() == getValue());
}
public void setValue(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
/*
* Copyright 2010 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;
/**
* Class provides unused XIDs, used for creating server-side objects
* created by the java backend.
* It does buffering, to minimize JNI overhead.
*
* @author Clemens Eisserer
*/
public class XIDGenerator {
private final static int XID_BUFFER_SIZE = 512;
int[] xidBuffer = new int[XID_BUFFER_SIZE];
int currentIndex = XID_BUFFER_SIZE;
public int getNextXID() {
if (currentIndex >= XID_BUFFER_SIZE) {
bufferXIDs(xidBuffer, xidBuffer.length);
currentIndex = 0;
}
return xidBuffer[currentIndex++];
}
private static native void bufferXIDs(int[] buffer, int arraySize);
}
/*
* Copyright 2010 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;
/**
* XRender pipeline backend interface.
* Currently there are two different backends implemented:
* - XRBackendJava: And experimental backend, generating protocol directly using java-code and xcb's socket handoff functionality.
* - XRBackendNative: Native 1:1 binding with libX11.
*/
import java.awt.geom.*;
import java.util.*;
import sun.font.*;
import sun.java2d.jules.*;
import sun.java2d.pipe.*;
public interface XRBackend {
public void freePicture(int picture);
public void freePixmap(int pixmap);
public int createPixmap(int drawable, int depth, int width, int height);
public int createPicture(int drawable, int formatID);
public long createGC(int drawable);
public void freeGC(long gc); /* TODO: Use!! */
public void copyArea(int src, int dst, long gc, int srcx, int srcy,
int width, int height, int dstx, int dsty);
public void putMaskImage(int drawable, long gc, byte[] imageData,
int sx, int sy, int dx, int dy,
int width, int height, int maskOff,
int maskScan, float ea);
public void setGCClipRectangles(long gc, Region clip);
public void GCRectangles(int drawable, long gc, GrowableRectArray rects);
public void setClipRectangles(int picture, Region clip);
public void setGCExposures(long gc, boolean exposure);
public void setGCForeground(long gc, int pixel);
public void setPictureTransform(int picture, AffineTransform transform);
public void setPictureRepeat(int picture, int repeat);
public void setFilter(int picture, int filter);
public void renderRectangle(int dst, byte op, XRColor color,
int x, int y, int width, int height);
public void renderRectangles(int dst, byte op, XRColor color,
GrowableRectArray rects);
public void renderComposite(byte op, int src, int mask, int dst,
int srcX, int srcY, int maskX, int maskY,
int dstX, int dstY, int width, int height);
public int XRenderCreateGlyphSet(int formatID);
public void XRenderAddGlyphs(int glyphSet, GlyphList gl,
List<XRGlyphCacheEntry> cacheEntries,
byte[] pixelData);
public void XRenderFreeGlyphs(int glyphSet, int[] gids);
public void XRenderCompositeText(byte op, int src, int dst,
int maskFormatID,
int xSrc, int ySrc, int xDst, int yDst,
int glyphset, GrowableEltArray elts);
public int createRadialGradient(Point2D inner, Point2D outer,
float innerRadius, float outerRadius,
float[] fractions, int[] pixels,
int repeat, AffineTransform transform);
public int createLinearGradient(Point2D p1, Point2D p2, float[] fractions,
int[] pixels, int repeat,
AffineTransform transform);
public void setGCMode(long gc, boolean copy);
public void renderCompositeTrapezoids(byte op, int src, int maskFormat,
int dst, int srcX, int srcY,
TrapezoidList trapList);
}
/*
* Copyright 2010 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.geom.*;
import java.util.*;
import sun.font.*;
import sun.java2d.jules.*;
import sun.java2d.pipe.*;
import static sun.java2d.xr.XRUtils.XDoubleToFixed;
/**
* Native implementation of XRBackend.
* Almost direct 1:1 binding to libX11.
*
* @author Clemens Eisserer
*/
public class XRBackendNative implements XRBackend {
static {
initIDs();
}
private static long FMTPTR_A8;
private static long FMTPTR_ARGB32;
private static long MASK_XIMG;
private static native void initIDs();
public native long createGC(int drawable);
public native void freeGC(long gc);
public native int createPixmap(int drawable, int depth,
int width, int height);
private native int createPictureNative(int drawable, long formatID);
public native void freePicture(int picture);
public native void freePixmap(int pixmap);
public native void setGCExposures(long gc, boolean exposure);
public native void setGCForeground(long gc, int pixel);
public native void setPictureRepeat(int picture, int repeat);
public native void copyArea(int src, int dst, long gc,
int srcx, int srcy, int width, int height,
int dstx, int dsty);
public native void setGCMode(long gc, boolean copy);
private static native void GCRectanglesNative(int drawable, long gc,
int[] rectArray, int rectCnt);
public native void renderComposite(byte op, int src, int mask,
int dst, int srcX, int srcY,
int maskX, int maskY, int dstX, int dstY,
int width, int height);
private native void renderRectangle(int dst, byte op,
short red, short green,
short blue, short alpha,
int x, int y, int width, int height);
private static native void
XRenderRectanglesNative(int dst, byte op,
short red, short green,
short blue, short alpha,
int[] rects, int rectCnt);
private native void XRSetTransformNative(int pic,
int m00, int m01, int m02,
int m10, int m11, int m12);
private static native int
XRCreateLinearGradientPaintNative(float[] fractionsArray,
short[] pixelsArray,
int x1, int y1, int x2, int y2,
int numStops, int repeat,
int m00, int m01, int m02,
int m10, int m11, int m12);
private native static int
XRCreateRadialGradientPaintNative(float[] fractionsArray,
short[] pixelsArray, int numStops,
int innerRadius, int outerRadius,
int repeat,
int m00, int m01, int m02,
int m10, int m11, int m12);
public native void setFilter(int picture, int filter);
private static native void XRSetClipNative(long dst,
int x1, int y1, int x2, int y2,
Region clip, boolean isGC);
public void GCRectangles(int drawable, long gc, GrowableRectArray rects) {
GCRectanglesNative(drawable, gc, rects.getArray(), rects.getSize());
}
public int createPicture(int drawable, int formatID) {
return createPictureNative(drawable, getFormatPtr(formatID));
}
public void setPictureTransform(int picture, AffineTransform transform) {
XRSetTransformNative(picture,
XDoubleToFixed(transform.getScaleX()),
XDoubleToFixed(transform.getShearX()),
XDoubleToFixed(transform.getTranslateX()),
XDoubleToFixed(transform.getShearY()),
XDoubleToFixed(transform.getScaleY()),
XDoubleToFixed(transform.getTranslateY()));
}
public void renderRectangle(int dst, byte op, XRColor color,
int x, int y, int width, int height) {
renderRectangle(dst, op, (short)color.red, (short)color.green,
(short)color.blue, (short)color.alpha,
x, y, width, height);
}
private short[] getRenderColors(int[] pixels) {
short[] renderColors = new short[pixels.length * 4];
XRColor c = new XRColor();
for (int i = 0; i < pixels.length; i++) {
c.setColorValues(pixels[i], true);
renderColors[i * 4 + 0] = (short) c.alpha;
renderColors[i * 4 + 1] = (short) c.red;
renderColors[i * 4 + 2] = (short) c.green;
renderColors[i * 4 + 3] = (short) c.blue;
}
return renderColors;
}
private static long getFormatPtr(int formatID) {
switch (formatID) {
case XRUtils.PictStandardA8:
return FMTPTR_A8;
case XRUtils.PictStandardARGB32:
return FMTPTR_ARGB32;
}
return 0L;
}
public int createLinearGradient(Point2D p1, Point2D p2, float[] fractions,
int[] pixels, int repeat, AffineTransform trx) {
short[] colorValues = getRenderColors(pixels);
int gradient =
XRCreateLinearGradientPaintNative(fractions, colorValues,
XDoubleToFixed(p1.getX()), XDoubleToFixed(p1.getY()),
XDoubleToFixed(p2.getX()), XDoubleToFixed(p2.getY()),
fractions.length, repeat,
XDoubleToFixed(trx.getScaleX()),
XDoubleToFixed(trx.getShearX()),
XDoubleToFixed(trx.getTranslateX()),
XDoubleToFixed(trx.getShearY()),
XDoubleToFixed(trx.getScaleY()),
XDoubleToFixed(trx.getTranslateY()));
return gradient;
}
public int createRadialGradient(Point2D inner, Point2D outer,
float innerRadius, float outerRadius,
float[] fractions, int[] pixels, int repeat,
AffineTransform trx) {
short[] colorValues = getRenderColors(pixels);
return XRCreateRadialGradientPaintNative
(fractions, colorValues, fractions.length,
XDoubleToFixed(innerRadius),
XDoubleToFixed(outerRadius),
repeat,
XDoubleToFixed(trx.getScaleX()),
XDoubleToFixed(trx.getShearX()),
XDoubleToFixed(trx.getTranslateX()),
XDoubleToFixed(trx.getShearY()),
XDoubleToFixed(trx.getScaleY()),
XDoubleToFixed(trx.getTranslateY()));
}
public void setGCClipRectangles(long gc, Region clip) {
XRSetClipNative(gc, clip.getLoX(), clip.getLoY(),
clip.getHiX(), clip.getHiY(),
clip.isRectangular() ? null : clip, true);
}
public void setClipRectangles(int picture, Region clip) {
if (clip != null) {
XRSetClipNative(picture, clip.getLoX(), clip.getLoY(),
clip.getHiX(), clip.getHiY(),
clip.isRectangular() ? null : clip, false);
} else {
XRSetClipNative(picture, 0, 0, 32767, 32767, null, false);
}
}
public void renderRectangles(int dst, byte op, XRColor color,
GrowableRectArray rects) {
XRenderRectanglesNative(dst, op,
(short) color.red, (short) color.green,
(short) color.blue, (short) color.alpha,
rects.getArray(), rects
.getSize());
}
private static long[] getGlyphInfoPtrs(List<XRGlyphCacheEntry> cacheEntries) {
long[] glyphInfoPtrs = new long[cacheEntries.size()];
for (int i = 0; i < cacheEntries.size(); i++) {
glyphInfoPtrs[i] = cacheEntries.get(i).getGlyphInfoPtr();
}
return glyphInfoPtrs;
}
public void XRenderAddGlyphs(int glyphSet, GlyphList gl,
List<XRGlyphCacheEntry> cacheEntries,
byte[] pixelData) {
long[] glyphInfoPtrs = getGlyphInfoPtrs(cacheEntries);
XRAddGlyphsNative(glyphSet, glyphInfoPtrs,
glyphInfoPtrs.length, pixelData, pixelData.length);
}
public void XRenderFreeGlyphs(int glyphSet, int[] gids) {
XRFreeGlyphsNative(glyphSet, gids, gids.length);
}
private static native void XRAddGlyphsNative(int glyphSet,
long[] glyphInfoPtrs,
int glyphCnt,
byte[] pixelData,
int pixelDataLength);
private static native void XRFreeGlyphsNative(int glyphSet,
int[] gids, int idCnt);
private static native void
XRenderCompositeTextNative(int op, int src, int dst,
long maskFormat, int[] eltArray,
int[] glyphIDs, int eltCnt, int glyphCnt);
public int XRenderCreateGlyphSet(int formatID) {
return XRenderCreateGlyphSetNative(getFormatPtr(formatID));
}
private static native int XRenderCreateGlyphSetNative(long format);
public void XRenderCompositeText(byte op, int src, int dst,
int maskFormatID,
int src2, int src3, int dst2, int dst3,
int glyphset, GrowableEltArray elts) {
GrowableIntArray glyphs = elts.getGlyphs();
XRenderCompositeTextNative(op, src, dst, 0, elts.getArray(),
glyphs.getArray(), elts.getSize(),
glyphs.getSize());
}
public void putMaskImage(int drawable, long gc, byte[] imageData,
int sx, int sy, int dx, int dy,
int width, int height, int maskOff,
int maskScan, float ea) {
putMaskNative(drawable, gc, imageData, sx, sy, dx, dy,
width, height, maskOff, maskScan, ea, MASK_XIMG);
}
private static native void putMaskNative(int drawable, long gc,
byte[] imageData,
int sx, int sy, int dx, int dy,
int width, int height,
int maskOff, int maskScan,
float ea, long xImg);
public void padBlit(byte op, int srcPict, int maskPict, int dstPict,
AffineTransform maskTrx, int maskWidth, int maskHeight,
int lastMaskWidth, int lastMaskHeight,
int sx, int sy, int dx, int dy, int w, int h) {
padBlitNative(op, srcPict, maskPict, dstPict,
XDoubleToFixed(maskTrx.getScaleX()),
XDoubleToFixed(maskTrx.getShearX()),
XDoubleToFixed(maskTrx.getTranslateX()),
XDoubleToFixed(maskTrx.getShearY()),
XDoubleToFixed(maskTrx.getScaleY()),
XDoubleToFixed(maskTrx.getTranslateY()),
maskWidth, maskHeight, lastMaskWidth, lastMaskHeight,
sx, sy, dx, dy, w, h);
}
private static native void padBlitNative(byte op, int srcPict,
int maskPict, int dstPict,
int m00, int m01, int m02,
int m10, int m11, int m12,
int maskWidth, int maskHeight,
int lastMaskWidth,
int lastMaskHeight,
int sx, int sy, int dx, int dy,
int w, int h);
public void renderCompositeTrapezoids(byte op, int src, int maskFormat,
int dst, int srcX, int srcY,
TrapezoidList trapList) {
renderCompositeTrapezoidsNative(op, src, getFormatPtr(maskFormat),
dst, srcX, srcY,
trapList.getTrapArray());
}
private static native void
renderCompositeTrapezoidsNative(byte op, int src, long maskFormat,
int dst, int srcX, int srcY,
int[] trapezoids);
}
/*
* Copyright 2010 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.*;
/**
* XRender color class.
*
* @author Clemens Eisserer
*/
public class XRColor {
public static final XRColor FULL_ALPHA = new XRColor(0xffff, 0, 0, 0);
public static final XRColor NO_ALPHA = new XRColor(0, 0, 0, 0);
int red, green, blue, alpha;
public XRColor() {
red = 0;
green = 0;
blue = 0;
alpha = 0;
}
public XRColor(int alpha, int red, int green, int blue) {
this.alpha = alpha;
this.red = red;
this.green = green;
this.blue = blue;
}
public XRColor(Color color) {
}
public void setColorValues(Color color) {
alpha = byteToXRColorValue(color.getAlpha());
red = byteToXRColorValue(
(int)(color.getRed() * color.getAlpha() / 255.0));
green = byteToXRColorValue(
(int)(color.getGreen() * color.getAlpha() / 255.0));
blue = byteToXRColorValue(
(int)(color.getBlue() * color.getAlpha() / 255.0));
}
public static int[] ARGBPrePixelToXRColors(int[] pixels) {
int[] colorValues = new int[pixels.length * 4];
XRColor c = new XRColor();
for (int i = 0; i < pixels.length; i++) {
c.setColorValues(pixels[i], true);
colorValues[i * 4 + 0] = c.alpha;
colorValues[i * 4 + 1] = c.red;
colorValues[i * 4 + 2] = c.green;
colorValues[i * 4 + 3] = c.blue;
}
return colorValues;
}
public void setColorValues(int pixel, boolean pre) {
long pix = XRUtils.intToULong(pixel);
alpha = (int) (((pix & 0xFF000000) >> 16) + 255);
red = (int) (((pix & 0x00FF0000) >> 8) + 255);
green = (int) (((pix & 0x0000FF00) >> 0) + 255);
blue = (int) (((pix & 0x000000FF) << 8) + 255);
if (alpha == 255) {
alpha = 0;
}
if (!pre) {
double alphaMult = XRUtils.XFixedToDouble(alpha);
this.red = (int) (red * alphaMult);
this.green = (int) (green * alphaMult);
this.blue = (int) (blue * alphaMult);
}
}
public static int byteToXRColorValue(int byteValue) {
int xrValue = 0;
if (byteValue != 0) {
if (byteValue == 255) {
xrValue = 0xffff;
} else {
xrValue = ((byteValue << 8) + 255);
}
}
return xrValue;
}
public String toString(){
return "A:"+alpha+" R:"+red+" G:"+green+" B:"+blue;
}
public void setAlpha(int alpha) {
this.alpha = alpha;
}
public int getAlpha() {
return alpha;
}
public int getRed() {
return red;
}
public int getGreen() {
return green;
}
public int getBlue() {
return blue;
}
}
/*
* Copyright 2010 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.geom.*;
import sun.font.*;
import sun.java2d.*;
import sun.java2d.jules.*;
import sun.java2d.loops.*;
/**
* Manages per-application resources, e.g. the 1x1 pixmap used for solid color
* fill as well as per-application state e.g. the currently set source picture
* used for composition .
*
* @author Clemens Eisserer
*/
public class XRCompositeManager {
private static boolean enableGradCache = true;
private static XRCompositeManager instance;
XRSurfaceData src;
XRSurfaceData texture;
XRSurfaceData gradient;
int alphaMask = XRUtils.None;
XRColor solidColor = new XRColor();
float extraAlpha = 1.0f;
byte compRule = XRUtils.PictOpOver;
XRColor alphaColor = new XRColor();
XRSurfaceData solidSrcPict;
int alphaMaskPict;
int gradCachePixmap;
int gradCachePicture;
boolean xorEnabled = false;
int validatedPixel = 0;
Composite validatedComp;
Paint validatedPaint;
float validatedExtraAlpha = 1.0f;
XRBackend con;
MaskTileManager maskBuffer;
XRTextRenderer textRenderer;
XRMaskImage maskImage;
public static synchronized XRCompositeManager getInstance(
XRSurfaceData surface) {
if (instance == null) {
instance = new XRCompositeManager(surface);
}
return instance;
}
private XRCompositeManager(XRSurfaceData surface) {
con = new XRBackendNative();
// con = XRBackendJava.getInstance();
String gradProp = System.getProperty("sun.java2d.xrgradcache");
enableGradCache = gradProp == null ||
!(gradProp.equalsIgnoreCase("false") ||
gradProp.equalsIgnoreCase("f"));
XRPaints.register(this);
initResources(surface);
maskBuffer = new MaskTileManager(this, surface.getXid());
textRenderer = new XRTextRenderer(this);
maskImage = new XRMaskImage(this, surface.getXid());
}
public void initResources(XRSurfaceData surface) {
int parentXid = surface.getXid();
int solidPixmap = con.createPixmap(parentXid, 32, 1, 1);
int solidSrcPictXID = con.createPicture(solidPixmap,
XRUtils.PictStandardARGB32);
con.setPictureRepeat(solidSrcPictXID, XRUtils.RepeatNormal);
con.renderRectangle(solidSrcPictXID, XRUtils.PictOpSrc,
XRColor.FULL_ALPHA, 0, 0, 1, 1);
solidSrcPict = new XRSurfaceData.XRInternalSurfaceData(con,
solidSrcPictXID, null);
setForeground(0);
int extraAlphaMask = con.createPixmap(parentXid, 8, 1, 1);
alphaMaskPict = con.createPicture(extraAlphaMask,
XRUtils.PictStandardA8);
con.setPictureRepeat(alphaMaskPict, XRUtils.RepeatNormal);
con.renderRectangle(alphaMaskPict, XRUtils.PictOpClear,
XRColor.NO_ALPHA, 0, 0, 1, 1);
if (enableGradCache) {
gradCachePixmap = con.createPixmap(parentXid, 32,
MaskTileManager.MASK_SIZE, MaskTileManager.MASK_SIZE);
gradCachePicture = con.createPicture(gradCachePixmap,
XRUtils.PictStandardARGB32);
}
}
public void setForeground(int pixel) {
solidColor.setColorValues(pixel, false);
con.renderRectangle(solidSrcPict.picture, XRUtils.PictOpSrc,
solidColor, 0, 0, 1, 1);
}
public void setGradientPaint(XRSurfaceData gradient) {
if (this.gradient != null) {
con.freePicture(this.gradient.picture);
}
this.gradient = gradient;
src = gradient;
}
public void setTexturePaint(XRSurfaceData texture) {
this.texture = texture;
src = texture;
}
public void XRResetPaint() {
src = solidSrcPict;
}
public void validateCompositeState(Composite comp, AffineTransform xform,
Paint paint, SunGraphics2D sg2d) {
boolean updatePaint = (paint != validatedPaint) || paint == null;
// validate composite
if ((comp != validatedComp)) {
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;
}
if (sg2d != null && validatedPixel != sg2d.pixel) {
validatedPixel = sg2d.pixel;
setForeground(validatedPixel);
}
// validate paint
if (updatePaint) {
if (paint != null && sg2d != null
&& sg2d.paintState >= SunGraphics2D.PAINT_GRADIENT) {
XRPaints.setPaint(sg2d, paint);
} else {
XRResetPaint();
}
validatedPaint = paint;
}
if (src != solidSrcPict) {
AffineTransform at = (AffineTransform) xform.clone();
try {
at.invert();
} catch (NoninvertibleTransformException e) {
at.setToIdentity();
}
src.validateAsSource(at, -1, -1);
}
}
private void setComposite(Composite comp) {
if (comp instanceof AlphaComposite) {
AlphaComposite aComp = (AlphaComposite) comp;
validatedExtraAlpha = aComp.getAlpha();
this.compRule = XRUtils.j2dAlphaCompToXR(aComp.getRule());
this.extraAlpha = validatedExtraAlpha;
if (extraAlpha == 1.0f) {
alphaMask = XRUtils.None;
alphaColor.alpha = XRColor.FULL_ALPHA.alpha;
} else {
alphaColor.alpha = XRColor
.byteToXRColorValue((int) (extraAlpha * 255));
alphaMask = alphaMaskPict;
con.renderRectangle(alphaMaskPict, XRUtils.PictOpSrc,
alphaColor, 0, 0, 1, 1);
}
xorEnabled = false;
} else if (comp instanceof XORComposite) {
/* XOR composite validation is handled in XRSurfaceData */
xorEnabled = true;
} else {
throw new InternalError(
"Composite accaleration not implemented for: "
+ comp.getClass().getName());
}
}
public boolean maskRequired() {
return (!xorEnabled)
&& ((src != solidSrcPict)
|| (src == solidSrcPict && solidColor.alpha != 0xffff) || (extraAlpha != 1.0f));
}
public void XRComposite(int src, int mask, int dst, int srcX, int srcY,
int maskX, int maskY, int dstX, int dstY, int width, int height) {
int cachedSrc = (src == XRUtils.None) ? this.src.picture : src;
int cachedX = srcX;
int cachedY = srcY;
if (enableGradCache && gradient != null
&& cachedSrc == gradient.picture) {
con.renderComposite(XRUtils.PictOpSrc, gradient.picture,
XRUtils.None, gradCachePicture, srcX, srcY, 0, 0, 0, 0,
width, height);
cachedX = 0;
cachedY = 0;
cachedSrc = gradCachePicture;
}
con.renderComposite(compRule, cachedSrc, mask, dst, cachedX, cachedY,
maskX, maskY, dstX, dstY, width, height);
}
public void XRCompositeTraps(int dst, int srcX, int srcY,
TrapezoidList trapList) {
int renderReferenceX = 0;
int renderReferenceY = 0;
if (trapList.getP1YLeft(0) < trapList.getP2YLeft(0)) {
renderReferenceX = trapList.getP1XLeft(0);
renderReferenceY = trapList.getP1YLeft(0);
} else {
renderReferenceX = trapList.getP2XLeft(0);
renderReferenceY = trapList.getP2YLeft(0);
}
renderReferenceX = (int) Math.floor(XRUtils
.XFixedToDouble(renderReferenceX));
renderReferenceY = (int) Math.floor(XRUtils
.XFixedToDouble(renderReferenceY));
con.renderCompositeTrapezoids(compRule, src.picture,
XRUtils.PictStandardA8, dst, renderReferenceX,
renderReferenceY, trapList);
}
public void XRRenderRectangles(XRSurfaceData dst, GrowableRectArray rects) {
if (xorEnabled) {
con.GCRectangles(dst.getXid(), dst.getGC(), rects);
} else {
con.renderRectangles(dst.getPicture(), compRule, solidColor, rects);
}
}
public void compositeBlit(XRSurfaceData src, XRSurfaceData dst, int sx,
int sy, int dx, int dy, int w, int h) {
con.renderComposite(compRule, src.picture, alphaMask, dst.picture, sx,
sy, 0, 0, dx, dy, w, h);
}
public void compositeText(int dst, int glyphSet, int maskFormat,
GrowableEltArray elts) {
con.XRenderCompositeText(compRule, src.picture, dst, maskFormat, 0, 0,
0, 0, glyphSet, elts);
}
public XRColor getMaskColor() {
return !isTexturePaintActive() ? XRColor.FULL_ALPHA : getAlphaColor();
}
public int getExtraAlphaMask() {
return alphaMask;
}
public boolean isTexturePaintActive() {
return src == texture;
}
public XRColor getAlphaColor() {
return alphaColor;
}
public XRBackend getBackend() {
return con;
}
public float getExtraAlpha() {
return validatedExtraAlpha;
}
public byte getCompRule() {
return compRule;
}
public XRTextRenderer getTextRenderer() {
return textRenderer;
}
public MaskTileManager getMaskBuffer() {
return maskBuffer;
}
public XRMaskImage getMaskImage() {
return maskImage;
}
}
/*
* Copyright 2010 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.geom.*;
import sun.java2d.*;
import sun.java2d.loops.*;
import sun.java2d.pipe.*;
/**
* Class used for re-routing transformed blits to the accelerated loops.
*/
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,
SunGraphics2D.TRANSFORM_GENERIC, sg.imageComp, bgColor);
if (srcData != null && !isBgOperation(srcData, bgColor)) { // TODO: Do we bail out on bgBlits?
// && srcData instanceof XRSurfaceData) {
SurfaceType srcType = srcData.getSurfaceType();
SurfaceType dstType = dstData.getSurfaceType();
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);
}
}
/*
* Copyright 2010 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.
*/
/*
* 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.*;
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;
}
}
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册