mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-21 11:34:38 +02:00
6307603: [X11] Use RENDER extension for complex operations done in software
Reviewed-by: bae, igor, prr
This commit is contained in:
parent
8b69138923
commit
1771e20459
65 changed files with 8085 additions and 171 deletions
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
32
jdk/src/share/classes/sun/font/GlyphDisposedListener.java
Normal file
32
jdk/src/share/classes/sun/font/GlyphDisposedListener.java
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* 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...
|
||||
*/
|
||||
|
|
|
@ -1,2 +1,5 @@
|
|||
# Jules Rendering Engine module
|
||||
sun.java2d.jules.JulesRenderingEngine
|
||||
|
||||
# Pisces Rendering Engine module
|
||||
sun.java2d.pisces.PiscesRenderingEngine
|
|
@ -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,11 +170,17 @@ public class X11GraphicsDevice
|
|||
boolean doubleBuffer =
|
||||
(dbeSupported &&
|
||||
doubleBufferVisuals.contains(Integer.valueOf(visNum)));
|
||||
|
||||
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,12 +252,22 @@ public class X11GraphicsDevice
|
|||
doubleBuffer =
|
||||
doubleBufferVisuals.contains(Integer.valueOf(visNum));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static native void enterFullScreenExclusive(long window);
|
||||
private static native void exitFullScreenExclusive(long window);
|
||||
|
|
|
@ -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:
|
||||
|
|
301
jdk/src/solaris/classes/sun/font/XRGlyphCache.java
Normal file
301
jdk/src/solaris/classes/sun/font/XRGlyphCache.java
Normal file
|
@ -0,0 +1,301 @@
|
|||
/*
|
||||
* 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());
|
||||
}
|
||||
}
|
||||
}
|
206
jdk/src/solaris/classes/sun/font/XRGlyphCacheEntry.java
Normal file
206
jdk/src/solaris/classes/sun/font/XRGlyphCacheEntry.java
Normal file
|
@ -0,0 +1,206 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
152
jdk/src/solaris/classes/sun/font/XRTextRenderer.java
Normal file
152
jdk/src/solaris/classes/sun/font/XRTextRenderer.java
Normal file
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
* 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,8 +55,11 @@ public class UnixSurfaceManagerFactory extends SurfaceManagerFactory {
|
|||
Object context)
|
||||
{
|
||||
GraphicsConfiguration gc = vImg.getGraphicsConfig();
|
||||
|
||||
if (gc instanceof GLXGraphicsConfig) {
|
||||
return new GLXVolatileSurfaceManager(vImg, context);
|
||||
} else if(gc instanceof XRGraphicsConfig) {
|
||||
return new XRVolatileSurfaceManager(vImg, context);
|
||||
}else {
|
||||
return new X11VolatileSurfaceManager(vImg, context);
|
||||
}
|
||||
|
|
109
jdk/src/solaris/classes/sun/java2d/jules/IdleTileCache.java
Normal file
109
jdk/src/solaris/classes/sun/java2d/jules/IdleTileCache.java
Normal file
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,349 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
271
jdk/src/solaris/classes/sun/java2d/jules/JulesPathBuf.java
Normal file
271
jdk/src/solaris/classes/sun/java2d/jules/JulesPathBuf.java
Normal file
|
@ -0,0 +1,271 @@
|
|||
/*
|
||||
* 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");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
102
jdk/src/solaris/classes/sun/java2d/jules/JulesShapePipe.java
Normal file
102
jdk/src/solaris/classes/sun/java2d/jules/JulesShapePipe.java
Normal file
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
}
|
67
jdk/src/solaris/classes/sun/java2d/jules/JulesTile.java
Normal file
67
jdk/src/solaris/classes/sun/java2d/jules/JulesTile.java
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
146
jdk/src/solaris/classes/sun/java2d/jules/TileWorker.java
Normal file
146
jdk/src/solaris/classes/sun/java2d/jules/TileWorker.java
Normal file
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
110
jdk/src/solaris/classes/sun/java2d/jules/TrapezoidList.java
Normal file
110
jdk/src/solaris/classes/sun/java2d/jules/TrapezoidList.java
Normal file
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* 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"));
|
||||
|
@ -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;
|
||||
|
|
40
jdk/src/solaris/classes/sun/java2d/x11/XSurfaceData.java
Normal file
40
jdk/src/solaris/classes/sun/java2d/x11/XSurfaceData.java
Normal file
|
@ -0,0 +1,40 @@
|
|||
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);
|
||||
}
|
133
jdk/src/solaris/classes/sun/java2d/xr/DirtyRegion.java
Normal file
133
jdk/src/solaris/classes/sun/java2d/xr/DirtyRegion.java
Normal file
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
127
jdk/src/solaris/classes/sun/java2d/xr/GrowableByteArray.java
Normal file
127
jdk/src/solaris/classes/sun/java2d/xr/GrowableByteArray.java
Normal file
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
}
|
84
jdk/src/solaris/classes/sun/java2d/xr/GrowableEltArray.java
Normal file
84
jdk/src/solaris/classes/sun/java2d/xr/GrowableEltArray.java
Normal file
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
114
jdk/src/solaris/classes/sun/java2d/xr/GrowableIntArray.java
Normal file
114
jdk/src/solaris/classes/sun/java2d/xr/GrowableIntArray.java
Normal file
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
79
jdk/src/solaris/classes/sun/java2d/xr/GrowableRectArray.java
Normal file
79
jdk/src/solaris/classes/sun/java2d/xr/GrowableRectArray.java
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
}
|
166
jdk/src/solaris/classes/sun/java2d/xr/MaskTile.java
Normal file
166
jdk/src/solaris/classes/sun/java2d/xr/MaskTile.java
Normal file
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
327
jdk/src/solaris/classes/sun/java2d/xr/MaskTileManager.java
Normal file
327
jdk/src/solaris/classes/sun/java2d/xr/MaskTileManager.java
Normal file
|
@ -0,0 +1,327 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
}
|
57
jdk/src/solaris/classes/sun/java2d/xr/MutableInteger.java
Normal file
57
jdk/src/solaris/classes/sun/java2d/xr/MutableInteger.java
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
53
jdk/src/solaris/classes/sun/java2d/xr/XIDGenerator.java
Normal file
53
jdk/src/solaris/classes/sun/java2d/xr/XIDGenerator.java
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
117
jdk/src/solaris/classes/sun/java2d/xr/XRBackend.java
Normal file
117
jdk/src/solaris/classes/sun/java2d/xr/XRBackend.java
Normal file
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
343
jdk/src/solaris/classes/sun/java2d/xr/XRBackendNative.java
Normal file
343
jdk/src/solaris/classes/sun/java2d/xr/XRBackendNative.java
Normal file
|
@ -0,0 +1,343 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
141
jdk/src/solaris/classes/sun/java2d/xr/XRColor.java
Normal file
141
jdk/src/solaris/classes/sun/java2d/xr/XRColor.java
Normal file
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
334
jdk/src/solaris/classes/sun/java2d/xr/XRCompositeManager.java
Normal file
334
jdk/src/solaris/classes/sun/java2d/xr/XRCompositeManager.java
Normal file
|
@ -0,0 +1,334 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
67
jdk/src/solaris/classes/sun/java2d/xr/XRDrawImage.java
Normal file
67
jdk/src/solaris/classes/sun/java2d/xr/XRDrawImage.java
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
61
jdk/src/solaris/classes/sun/java2d/xr/XRGraphicsConfig.java
Normal file
61
jdk/src/solaris/classes/sun/java2d/xr/XRGraphicsConfig.java
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
94
jdk/src/solaris/classes/sun/java2d/xr/XRMaskBlit.java
Normal file
94
jdk/src/solaris/classes/sun/java2d/xr/XRMaskBlit.java
Normal file
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* 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 sun.java2d.loops.CompositeType.SrcNoEa;
|
||||
import static sun.java2d.loops.CompositeType.SrcOver;
|
||||
|
||||
import java.awt.Composite;
|
||||
|
||||
import sun.awt.*;
|
||||
import sun.java2d.*;
|
||||
import sun.java2d.loops.*;
|
||||
import sun.java2d.pipe.Region;
|
||||
|
||||
/**
|
||||
* For XRender there is no "blit", everything is just a fill with Repeat or Not.
|
||||
* So basically this just quite the same as MaskFill.
|
||||
*
|
||||
* @author Clemens Eisserer
|
||||
*/
|
||||
public class XRMaskBlit extends MaskBlit {
|
||||
static void register() {
|
||||
GraphicsPrimitive[] primitives = {
|
||||
new XRMaskBlit(XRSurfaceData.IntArgbPreX11, SrcOver,
|
||||
XRSurfaceData.IntArgbPreX11),
|
||||
new XRMaskBlit(XRSurfaceData.IntRgbX11, SrcOver,
|
||||
XRSurfaceData.IntRgbX11),
|
||||
new XRMaskBlit(XRSurfaceData.IntArgbPreX11, SrcNoEa,
|
||||
XRSurfaceData.IntRgbX11),
|
||||
new XRMaskBlit(XRSurfaceData.IntRgbX11, SrcNoEa,
|
||||
XRSurfaceData.IntArgbPreX11)
|
||||
};
|
||||
GraphicsPrimitiveMgr.register(primitives);
|
||||
}
|
||||
|
||||
public XRMaskBlit(SurfaceType srcType, CompositeType compType,
|
||||
SurfaceType dstType) {
|
||||
super(srcType, CompositeType.AnyAlpha, dstType);
|
||||
}
|
||||
|
||||
protected native void maskBlit(long srcXsdo, long dstxsdo, int srcx,
|
||||
int srcy, int dstx, int dsty, int w, int h, int maskoff,
|
||||
int maskscan, int masklen, byte[] mask);
|
||||
|
||||
public void MaskBlit(SurfaceData src, SurfaceData dst, Composite comp,
|
||||
Region clip, int srcx, int srcy, int dstx, int dsty, int width,
|
||||
int height, byte[] mask, int maskoff, int maskscan) {
|
||||
if (width <= 0 || height <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
SunToolkit.awtLock();
|
||||
|
||||
XRSurfaceData x11sd = (XRSurfaceData) src;
|
||||
x11sd.validateAsSource(null, XRUtils.RepeatNone, XRUtils.FAST);
|
||||
|
||||
XRCompositeManager maskBuffer = x11sd.maskBuffer;
|
||||
XRSurfaceData x11dst = (XRSurfaceData) dst;
|
||||
x11dst.validateAsDestination(null, clip);
|
||||
|
||||
int maskPict = maskBuffer.getMaskBuffer().
|
||||
uploadMask(width, height, maskscan, maskoff, mask);
|
||||
maskBuffer.XRComposite(x11sd.getPicture(), maskPict, x11sd.picture,
|
||||
srcx, srcy, 0, 0, dstx, dsty, width, height);
|
||||
maskBuffer.getMaskBuffer().clearUploadMask(maskPict, width, height);
|
||||
} finally {
|
||||
SunToolkit.awtUnlock();
|
||||
}
|
||||
}
|
||||
}
|
115
jdk/src/solaris/classes/sun/java2d/xr/XRMaskFill.java
Normal file
115
jdk/src/solaris/classes/sun/java2d/xr/XRMaskFill.java
Normal file
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* 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 sun.java2d.loops.CompositeType.SrcNoEa;
|
||||
|
||||
import static sun.java2d.loops.CompositeType.SrcOver;
|
||||
import static sun.java2d.loops.SurfaceType.AnyColor;
|
||||
import static sun.java2d.loops.SurfaceType.GradientPaint;
|
||||
import static sun.java2d.loops.SurfaceType.LinearGradientPaint;
|
||||
import static sun.java2d.loops.SurfaceType.OpaqueColor;
|
||||
import static sun.java2d.loops.SurfaceType.OpaqueGradientPaint;
|
||||
import static sun.java2d.loops.SurfaceType.OpaqueLinearGradientPaint;
|
||||
import static sun.java2d.loops.SurfaceType.OpaqueRadialGradientPaint;
|
||||
import static sun.java2d.loops.SurfaceType.OpaqueTexturePaint;
|
||||
import static sun.java2d.loops.SurfaceType.RadialGradientPaint;
|
||||
import static sun.java2d.loops.SurfaceType.TexturePaint;
|
||||
|
||||
import java.awt.*;
|
||||
import sun.awt.*;
|
||||
import sun.java2d.*;
|
||||
import sun.java2d.loops.*;
|
||||
|
||||
public class XRMaskFill extends MaskFill {
|
||||
static void register() {
|
||||
GraphicsPrimitive[] primitives = {
|
||||
new XRMaskFill(AnyColor, SrcOver, XRSurfaceData.IntRgbX11),
|
||||
new XRMaskFill(OpaqueColor, SrcNoEa, XRSurfaceData.IntRgbX11),
|
||||
new XRMaskFill(GradientPaint, SrcOver, XRSurfaceData.IntRgbX11),
|
||||
new XRMaskFill(OpaqueGradientPaint, SrcNoEa,
|
||||
XRSurfaceData.IntRgbX11),
|
||||
new XRMaskFill(LinearGradientPaint, SrcOver,
|
||||
XRSurfaceData.IntRgbX11),
|
||||
new XRMaskFill(OpaqueLinearGradientPaint, SrcNoEa,
|
||||
XRSurfaceData.IntRgbX11),
|
||||
new XRMaskFill(RadialGradientPaint, SrcOver,
|
||||
XRSurfaceData.IntRgbX11),
|
||||
new XRMaskFill(OpaqueRadialGradientPaint, SrcNoEa,
|
||||
XRSurfaceData.IntRgbX11),
|
||||
new XRMaskFill(TexturePaint, SrcOver, XRSurfaceData.IntRgbX11),
|
||||
new XRMaskFill(OpaqueTexturePaint, SrcNoEa,
|
||||
XRSurfaceData.IntRgbX11),
|
||||
|
||||
new XRMaskFill(AnyColor, SrcOver, XRSurfaceData.IntArgbPreX11),
|
||||
new XRMaskFill(OpaqueColor, SrcNoEa, XRSurfaceData.IntArgbPreX11),
|
||||
new XRMaskFill(GradientPaint, SrcOver, XRSurfaceData.IntArgbPreX11),
|
||||
new XRMaskFill(OpaqueGradientPaint, SrcNoEa,
|
||||
XRSurfaceData.IntArgbPreX11),
|
||||
new XRMaskFill(LinearGradientPaint, SrcOver,
|
||||
XRSurfaceData.IntArgbPreX11),
|
||||
new XRMaskFill(OpaqueLinearGradientPaint, SrcNoEa,
|
||||
XRSurfaceData.IntArgbPreX11),
|
||||
new XRMaskFill(RadialGradientPaint, SrcOver,
|
||||
XRSurfaceData.IntArgbPreX11),
|
||||
new XRMaskFill(OpaqueRadialGradientPaint, SrcNoEa,
|
||||
XRSurfaceData.IntArgbPreX11),
|
||||
new XRMaskFill(TexturePaint, SrcOver, XRSurfaceData.IntArgbPreX11),
|
||||
new XRMaskFill(OpaqueTexturePaint, SrcNoEa,
|
||||
XRSurfaceData.IntArgbPreX11)
|
||||
};
|
||||
|
||||
GraphicsPrimitiveMgr.register(primitives);
|
||||
}
|
||||
|
||||
protected XRMaskFill(SurfaceType srcType, CompositeType compType,
|
||||
SurfaceType surfaceType) {
|
||||
super(srcType, compType, surfaceType);
|
||||
}
|
||||
|
||||
protected native void maskFill(long xsdo, int x, int y, int w, int h,
|
||||
int maskoff, int maskscan, int masklen, byte[] mask);
|
||||
|
||||
public void MaskFill(SunGraphics2D sg2d, SurfaceData sData, Composite comp,
|
||||
final int x, final int y, final int w, final int h,
|
||||
final byte[] mask, final int maskoff, final int maskscan) {
|
||||
try {
|
||||
SunToolkit.awtLock();
|
||||
|
||||
XRSurfaceData x11sd = (XRSurfaceData) sData;
|
||||
x11sd.validateAsDestination(null, sg2d.getCompClip());
|
||||
|
||||
XRCompositeManager maskBuffer = x11sd.maskBuffer;
|
||||
maskBuffer.validateCompositeState(comp, sg2d.transform, sg2d.paint, sg2d);
|
||||
|
||||
int maskPict = maskBuffer.getMaskBuffer().uploadMask(w, h, maskscan, maskoff, mask);
|
||||
maskBuffer.XRComposite(XRUtils.None, maskPict, x11sd.picture, x, y, 0, 0, x, y, w, h);
|
||||
maskBuffer.getMaskBuffer().clearUploadMask(maskPict, w, h);
|
||||
} finally {
|
||||
SunToolkit.awtUnlock();
|
||||
}
|
||||
}
|
||||
}
|
129
jdk/src/solaris/classes/sun/java2d/xr/XRMaskImage.java
Normal file
129
jdk/src/solaris/classes/sun/java2d/xr/XRMaskImage.java
Normal file
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* 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.*;
|
||||
|
||||
/**
|
||||
* Management of mask used for some blit-types.
|
||||
*
|
||||
* @author Clemens Eisserer
|
||||
*/
|
||||
|
||||
public class XRMaskImage {
|
||||
|
||||
private static final int MASK_SCALE_FACTOR = 8;
|
||||
|
||||
private static final int BLIT_MASK_SIZE = 8;
|
||||
|
||||
Dimension blitMaskDimensions = new Dimension(BLIT_MASK_SIZE, BLIT_MASK_SIZE);
|
||||
int blitMaskPixmap;
|
||||
int blitMaskPicture;
|
||||
int lastMaskWidth = 0;
|
||||
int lastMaskHeight = 0;
|
||||
AffineTransform lastMaskTransform;
|
||||
|
||||
XRCompositeManager xrMgr;
|
||||
XRBackend con;
|
||||
|
||||
public XRMaskImage(XRCompositeManager xrMgr, int parentDrawable) {
|
||||
this.xrMgr = xrMgr;
|
||||
this.con = xrMgr.getBackend();
|
||||
|
||||
initBlitMask(parentDrawable, BLIT_MASK_SIZE, BLIT_MASK_SIZE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Prepares a mask used by a TransformedBlit, fills mask-contents and applies
|
||||
* transformation.
|
||||
*/
|
||||
public int prepareBlitMask(XRSurfaceData dst, AffineTransform maskTX, int width,
|
||||
int height) {
|
||||
|
||||
int maskWidth = Math.max(width / MASK_SCALE_FACTOR, 1);
|
||||
int maskHeight = Math.max(height / MASK_SCALE_FACTOR, 1);
|
||||
maskTX.scale(((double) width) / maskWidth, ((double) height) / maskHeight);
|
||||
|
||||
try {
|
||||
maskTX.invert();
|
||||
} catch (NoninvertibleTransformException ex) {
|
||||
maskTX.setToIdentity();
|
||||
}
|
||||
|
||||
ensureBlitMaskSize(maskWidth, maskHeight);
|
||||
|
||||
if (lastMaskTransform == null || !lastMaskTransform.equals(maskTX)) {
|
||||
con.setPictureTransform(blitMaskPicture, maskTX);
|
||||
lastMaskTransform = maskTX;
|
||||
}
|
||||
|
||||
if (lastMaskWidth != maskWidth || lastMaskHeight != maskHeight) {
|
||||
//Only clear mask, if previous mask area is larger than new one, otherwise simple overpaint it
|
||||
if (lastMaskWidth > maskWidth || lastMaskHeight > maskHeight) {
|
||||
con.renderRectangle(blitMaskPicture, XRUtils.PictOpClear, XRColor.NO_ALPHA, 0, 0, lastMaskWidth, lastMaskHeight);
|
||||
}
|
||||
|
||||
con.renderRectangle(blitMaskPicture, XRUtils.PictOpSrc, xrMgr.getAlphaColor(), 0, 0, maskWidth, maskHeight);
|
||||
}
|
||||
|
||||
lastMaskWidth = maskWidth;
|
||||
lastMaskHeight = maskHeight;
|
||||
|
||||
return blitMaskPicture;
|
||||
}
|
||||
|
||||
private void initBlitMask(int parentDrawable, int width, int height) {
|
||||
int newPM = con.createPixmap(parentDrawable, 8, width, height);
|
||||
int newPict = con.createPicture(newPM, XRUtils.PictStandardA8);
|
||||
|
||||
/*Free old mask*/
|
||||
if (blitMaskPixmap != 0) {
|
||||
con.freePixmap(blitMaskPixmap);
|
||||
con.freePicture(blitMaskPicture);
|
||||
}
|
||||
|
||||
blitMaskPixmap = newPM;
|
||||
blitMaskPicture = newPict;
|
||||
|
||||
con.renderRectangle(blitMaskPicture, XRUtils.PictOpClear, XRColor.NO_ALPHA, 0, 0, width, height);
|
||||
|
||||
blitMaskDimensions.width = width;
|
||||
blitMaskDimensions.height = height;
|
||||
lastMaskWidth = 0;
|
||||
lastMaskHeight = 0;
|
||||
lastMaskTransform = null;
|
||||
}
|
||||
|
||||
private void ensureBlitMaskSize(int minSizeX, int minSizeY) {
|
||||
if (minSizeX > blitMaskDimensions.width || minSizeY > blitMaskDimensions.height) {
|
||||
int newWidth = Math.max(minSizeX, blitMaskDimensions.width);
|
||||
int newHeight = Math.max(minSizeY, blitMaskDimensions.height);
|
||||
initBlitMask(blitMaskPixmap, newWidth, newHeight);
|
||||
}
|
||||
}
|
||||
}
|
400
jdk/src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java
Normal file
400
jdk/src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java
Normal file
|
@ -0,0 +1,400 @@
|
|||
/*
|
||||
* 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 sun.awt.SunToolkit;
|
||||
import sun.awt.image.*;
|
||||
import sun.java2d.loops.*;
|
||||
import sun.java2d.pipe.*;
|
||||
import sun.java2d.*;
|
||||
import java.awt.*;
|
||||
import java.awt.geom.*;
|
||||
import java.lang.ref.*;
|
||||
|
||||
public class XRPMBlitLoops {
|
||||
|
||||
static WeakReference<SunVolatileImage> argbTmpPM = new WeakReference<SunVolatileImage>(null);
|
||||
static WeakReference<SunVolatileImage> rgbTmpPM = new WeakReference<SunVolatileImage>(null);
|
||||
|
||||
public XRPMBlitLoops() {
|
||||
}
|
||||
|
||||
public static void register() {
|
||||
GraphicsPrimitive[] primitives = { new XRPMBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntRgbX11),
|
||||
new XRPMBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntArgbPreX11),
|
||||
new XRPMBlit(XRSurfaceData.IntArgbPreX11, XRSurfaceData.IntRgbX11),
|
||||
new XRPMBlit(XRSurfaceData.IntArgbPreX11, XRSurfaceData.IntArgbPreX11),
|
||||
|
||||
new XRPMScaledBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntRgbX11),
|
||||
new XRPMScaledBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntArgbPreX11),
|
||||
new XRPMScaledBlit(XRSurfaceData.IntArgbPreX11, XRSurfaceData.IntRgbX11),
|
||||
new XRPMScaledBlit(XRSurfaceData.IntArgbPreX11, XRSurfaceData.IntArgbPreX11),
|
||||
|
||||
new XRPMTransformedBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntRgbX11),
|
||||
new XRPMTransformedBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntArgbPreX11),
|
||||
new XRPMTransformedBlit(XRSurfaceData.IntArgbPreX11, XRSurfaceData.IntRgbX11),
|
||||
new XRPMTransformedBlit(XRSurfaceData.IntArgbPreX11, XRSurfaceData.IntArgbPreX11),
|
||||
|
||||
/* SW -> Surface Blits */
|
||||
new XrSwToPMBlit(SurfaceType.IntArgb, XRSurfaceData.IntRgbX11),
|
||||
new XrSwToPMBlit(SurfaceType.IntRgb, XRSurfaceData.IntRgbX11),
|
||||
new XrSwToPMBlit(SurfaceType.IntBgr, XRSurfaceData.IntRgbX11),
|
||||
new XrSwToPMBlit(SurfaceType.ThreeByteBgr, XRSurfaceData.IntRgbX11),
|
||||
new XrSwToPMBlit(SurfaceType.Ushort565Rgb, XRSurfaceData.IntRgbX11),
|
||||
new XrSwToPMBlit(SurfaceType.Ushort555Rgb, XRSurfaceData.IntRgbX11),
|
||||
new XrSwToPMBlit(SurfaceType.ByteIndexed, XRSurfaceData.IntRgbX11),
|
||||
|
||||
new XrSwToPMBlit(SurfaceType.IntArgb, XRSurfaceData.IntArgbPreX11),
|
||||
new XrSwToPMBlit(SurfaceType.IntRgb, XRSurfaceData.IntArgbPreX11),
|
||||
new XrSwToPMBlit(SurfaceType.IntBgr, XRSurfaceData.IntArgbPreX11),
|
||||
new XrSwToPMBlit(SurfaceType.ThreeByteBgr, XRSurfaceData.IntArgbPreX11),
|
||||
new XrSwToPMBlit(SurfaceType.Ushort565Rgb, XRSurfaceData.IntArgbPreX11),
|
||||
new XrSwToPMBlit(SurfaceType.Ushort555Rgb, XRSurfaceData.IntArgbPreX11),
|
||||
new XrSwToPMBlit(SurfaceType.ByteIndexed, XRSurfaceData.IntArgbPreX11),
|
||||
|
||||
/* SW->Surface Scales */
|
||||
new XrSwToPMScaledBlit(SurfaceType.IntArgb, XRSurfaceData.IntRgbX11),
|
||||
new XrSwToPMScaledBlit(SurfaceType.IntRgb, XRSurfaceData.IntRgbX11),
|
||||
new XrSwToPMScaledBlit(SurfaceType.IntBgr, XRSurfaceData.IntRgbX11),
|
||||
new XrSwToPMScaledBlit(SurfaceType.ThreeByteBgr, XRSurfaceData.IntRgbX11),
|
||||
new XrSwToPMScaledBlit(SurfaceType.Ushort565Rgb, XRSurfaceData.IntRgbX11),
|
||||
new XrSwToPMScaledBlit(SurfaceType.Ushort555Rgb, XRSurfaceData.IntRgbX11),
|
||||
new XrSwToPMScaledBlit(SurfaceType.ByteIndexed, XRSurfaceData.IntRgbX11),
|
||||
|
||||
new XrSwToPMScaledBlit(SurfaceType.IntArgb, XRSurfaceData.IntArgbPreX11),
|
||||
new XrSwToPMScaledBlit(SurfaceType.IntRgb, XRSurfaceData.IntArgbPreX11),
|
||||
new XrSwToPMScaledBlit(SurfaceType.IntBgr, XRSurfaceData.IntArgbPreX11),
|
||||
new XrSwToPMScaledBlit(SurfaceType.ThreeByteBgr, XRSurfaceData.IntArgbPreX11),
|
||||
new XrSwToPMScaledBlit(SurfaceType.Ushort565Rgb, XRSurfaceData.IntArgbPreX11),
|
||||
new XrSwToPMScaledBlit(SurfaceType.Ushort555Rgb, XRSurfaceData.IntArgbPreX11),
|
||||
new XrSwToPMScaledBlit(SurfaceType.ByteIndexed, XRSurfaceData.IntArgbPreX11),
|
||||
|
||||
/* SW->Surface Transforms */
|
||||
new XrSwToPMTransformedBlit(SurfaceType.IntArgb, XRSurfaceData.IntRgbX11),
|
||||
new XrSwToPMTransformedBlit(SurfaceType.IntRgb, XRSurfaceData.IntRgbX11),
|
||||
new XrSwToPMTransformedBlit(SurfaceType.IntBgr, XRSurfaceData.IntRgbX11),
|
||||
new XrSwToPMTransformedBlit(SurfaceType.ThreeByteBgr, XRSurfaceData.IntRgbX11),
|
||||
new XrSwToPMTransformedBlit(SurfaceType.Ushort565Rgb, XRSurfaceData.IntRgbX11),
|
||||
new XrSwToPMTransformedBlit(SurfaceType.Ushort555Rgb, XRSurfaceData.IntRgbX11),
|
||||
new XrSwToPMTransformedBlit(SurfaceType.ByteIndexed, XRSurfaceData.IntRgbX11),
|
||||
|
||||
new XrSwToPMTransformedBlit(SurfaceType.IntArgb, XRSurfaceData.IntArgbPreX11),
|
||||
new XrSwToPMTransformedBlit(SurfaceType.IntRgb, XRSurfaceData.IntArgbPreX11),
|
||||
new XrSwToPMTransformedBlit(SurfaceType.IntBgr, XRSurfaceData.IntArgbPreX11),
|
||||
new XrSwToPMTransformedBlit(SurfaceType.ThreeByteBgr, XRSurfaceData.IntArgbPreX11),
|
||||
new XrSwToPMTransformedBlit(SurfaceType.Ushort565Rgb, XRSurfaceData.IntArgbPreX11),
|
||||
new XrSwToPMTransformedBlit(SurfaceType.Ushort555Rgb, XRSurfaceData.IntArgbPreX11),
|
||||
new XrSwToPMTransformedBlit(SurfaceType.ByteIndexed, XRSurfaceData.IntArgbPreX11), };
|
||||
GraphicsPrimitiveMgr.register(primitives);
|
||||
}
|
||||
|
||||
/**
|
||||
* Caches a SW surface using a temporary pixmap. The pixmap is held by a WeakReference,
|
||||
* allowing it to shrink again after some time.
|
||||
*/
|
||||
protected static XRSurfaceData cacheToTmpSurface(SurfaceData src, XRSurfaceData dst, int w, int h, int sx, int sy) {
|
||||
SunVolatileImage vImg;
|
||||
SurfaceType vImgSurfaceType;
|
||||
|
||||
if (src.getTransparency() == Transparency.OPAQUE) {
|
||||
vImg = rgbTmpPM.get();
|
||||
vImgSurfaceType = SurfaceType.IntRgb;
|
||||
} else {
|
||||
vImg = argbTmpPM.get();
|
||||
vImgSurfaceType = SurfaceType.IntArgbPre;
|
||||
}
|
||||
|
||||
if (vImg == null || vImg.getWidth() < w || vImg.getHeight() < h) {
|
||||
if (vImg != null) {
|
||||
vImg.flush();
|
||||
}
|
||||
vImg = (SunVolatileImage) dst.getGraphicsConfig().createCompatibleVolatileImage(w, h, src.getTransparency());
|
||||
vImg.setAccelerationPriority(1.0f);
|
||||
|
||||
if (src.getTransparency() == SurfaceData.OPAQUE) {
|
||||
rgbTmpPM = new WeakReference<SunVolatileImage>(vImg);
|
||||
} else {
|
||||
argbTmpPM = new WeakReference<SunVolatileImage>(vImg);
|
||||
}
|
||||
}
|
||||
|
||||
Blit swToSurfaceBlit = Blit.getFromCache(src.getSurfaceType(), CompositeType.SrcNoEa, vImgSurfaceType);
|
||||
XRSurfaceData vImgSurface = (XRSurfaceData) vImg.getDestSurface();
|
||||
swToSurfaceBlit.Blit(src, vImgSurface, null, null, sx, sy, 0, 0, w, h);
|
||||
|
||||
return vImgSurface;
|
||||
}
|
||||
}
|
||||
|
||||
class XRPMBlit extends Blit {
|
||||
public XRPMBlit(SurfaceType srcType, SurfaceType dstType) {
|
||||
super(srcType, CompositeType.AnyAlpha, dstType);
|
||||
}
|
||||
|
||||
public void Blit(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int sx, int sy, int dx, int dy, int w, int h) {
|
||||
try {
|
||||
SunToolkit.awtLock();
|
||||
|
||||
XRSurfaceData x11sdDst = (XRSurfaceData) dst;
|
||||
x11sdDst.validateAsDestination(null, clip);
|
||||
XRSurfaceData x11sdSrc = (XRSurfaceData) src;
|
||||
x11sdSrc.validateAsSource(null, XRUtils.RepeatNone, XRUtils.FAST);
|
||||
|
||||
x11sdDst.maskBuffer.validateCompositeState(comp, null, null, null);
|
||||
|
||||
x11sdDst.maskBuffer.compositeBlit(x11sdSrc, x11sdDst, sx, sy, dx, dy, w, h);
|
||||
} finally {
|
||||
SunToolkit.awtUnlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class XRPMScaledBlit extends ScaledBlit {
|
||||
public XRPMScaledBlit(SurfaceType srcType, SurfaceType dstType) {
|
||||
super(srcType, CompositeType.AnyAlpha, dstType);
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: This breaks scales with non-integer coordinates!?!?!
|
||||
*/
|
||||
public void Scale(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int sx1, int sy1, int sx2, int sy2, double dx1, double dy1,
|
||||
double dx2, double dy2) {
|
||||
try {
|
||||
SunToolkit.awtLock();
|
||||
|
||||
XRSurfaceData x11sdDst = (XRSurfaceData) dst;
|
||||
x11sdDst.validateAsDestination(null, clip);
|
||||
XRSurfaceData x11sdSrc = (XRSurfaceData) src;
|
||||
x11sdDst.maskBuffer.validateCompositeState(comp, null, null, null);
|
||||
|
||||
double xScale = (dx2 - dx1) / (sx2 - sx1);
|
||||
double yScale = (dy2 - dy1) / (sy2 - sy1);
|
||||
|
||||
sx1 *= xScale;
|
||||
sx2 *= xScale;
|
||||
sy1 *= yScale;
|
||||
sy2 *= yScale;
|
||||
|
||||
AffineTransform xForm = AffineTransform.getScaleInstance(1 / xScale, 1 / yScale);
|
||||
|
||||
x11sdSrc.validateAsSource(xForm, XRUtils.RepeatNone, XRUtils.FAST); /*
|
||||
* TODO:
|
||||
* padded
|
||||
* blit
|
||||
* required
|
||||
* :
|
||||
* -
|
||||
* /
|
||||
* ?
|
||||
* ?
|
||||
*/
|
||||
x11sdDst.maskBuffer.compositeBlit(x11sdSrc, x11sdDst, (int) sx1, (int) sy1, (int) dx1, (int) dy1, (int) (dx2 - dx1), (int) (dy2 - dy1));
|
||||
} finally {
|
||||
SunToolkit.awtUnlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called also if scale+transform is set
|
||||
*
|
||||
* @author Clemens Eisserer
|
||||
*/
|
||||
class XRPMTransformedBlit extends TransformBlit {
|
||||
|
||||
public XRPMTransformedBlit(SurfaceType srcType, SurfaceType dstType) {
|
||||
super(srcType, CompositeType.AnyAlpha, dstType);
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculates the composite-rectangle required for transformed blits. This
|
||||
* method is functionally equal to: Shape shp =
|
||||
* xform.createTransformedShape(rect); Rectangle bounds = shp.getBounds();
|
||||
* but performs significantly better.
|
||||
*/
|
||||
public Rectangle getCompositeBounds(AffineTransform tr, int dstx, int dsty, int width, int height) {
|
||||
double[] compBounds = new double[8];
|
||||
compBounds[0] = dstx;
|
||||
compBounds[1] = dsty;
|
||||
compBounds[2] = dstx + width;
|
||||
compBounds[3] = dsty;
|
||||
compBounds[4] = dstx + width;
|
||||
compBounds[5] = dsty + height;
|
||||
compBounds[6] = dstx;
|
||||
compBounds[7] = dsty + height;
|
||||
|
||||
tr.transform(compBounds, 0, compBounds, 0, 4);
|
||||
|
||||
double minX = Math.min(compBounds[0], Math.min(compBounds[2], Math.min(compBounds[4], compBounds[6])));
|
||||
double minY = Math.min(compBounds[1], Math.min(compBounds[3], Math.min(compBounds[5], compBounds[7])));
|
||||
double maxX = Math.max(compBounds[0], Math.max(compBounds[2], Math.max(compBounds[4], compBounds[6])));
|
||||
double maxY = Math.max(compBounds[1], Math.max(compBounds[3], Math.max(compBounds[5], compBounds[7])));
|
||||
|
||||
minX = Math.floor(minX);
|
||||
minY = Math.floor(minY);
|
||||
maxX = Math.ceil(maxX);
|
||||
maxY = Math.ceil(maxY);
|
||||
|
||||
return new Rectangle((int) minX, (int) minY, (int) (maxX - minX), (int) (maxY - minY));
|
||||
}
|
||||
|
||||
public void Transform(SurfaceData src, SurfaceData dst, Composite comp, Region clip, AffineTransform xform, int hint, int srcx, int srcy,
|
||||
int dstx, int dsty, int width, int height) {
|
||||
try {
|
||||
SunToolkit.awtLock();
|
||||
|
||||
int filter = XRUtils.ATransOpToXRQuality(hint);
|
||||
|
||||
XRSurfaceData x11sdDst = (XRSurfaceData) dst;
|
||||
x11sdDst.validateAsDestination(null, clip);
|
||||
XRSurfaceData x11sdSrc = (XRSurfaceData) src;
|
||||
x11sdDst.maskBuffer.validateCompositeState(comp, null, null, null);
|
||||
|
||||
Rectangle bounds = getCompositeBounds(xform, dstx, dsty, width, height);
|
||||
|
||||
AffineTransform trx = AffineTransform.getTranslateInstance((-bounds.x), (-bounds.y));
|
||||
trx.concatenate(xform);
|
||||
AffineTransform maskTX = (AffineTransform) trx.clone();
|
||||
|
||||
trx.translate(-srcx, -srcy);
|
||||
|
||||
try {
|
||||
trx.invert();
|
||||
} catch (NoninvertibleTransformException ex) {
|
||||
trx.setToIdentity();
|
||||
System.err.println("Reseted to identity!");
|
||||
}
|
||||
|
||||
boolean omitMask = isMaskOmittable(trx, comp, filter);
|
||||
|
||||
if (!omitMask) {
|
||||
XRMaskImage mask = x11sdSrc.maskBuffer.getMaskImage();
|
||||
|
||||
x11sdSrc.validateAsSource(trx, XRUtils.RepeatPad, filter);
|
||||
int maskPicture = mask.prepareBlitMask(x11sdDst, maskTX, width, height);
|
||||
x11sdDst.maskBuffer.con.renderComposite(XRCompositeManager.getInstance(x11sdSrc).getCompRule(), x11sdSrc.picture, maskPicture, x11sdDst.picture,
|
||||
0, 0, 0, 0, bounds.x, bounds.y, bounds.width, bounds.height);
|
||||
} else {
|
||||
int repeat = filter == XRUtils.FAST ? XRUtils.RepeatNone : XRUtils.RepeatPad;
|
||||
|
||||
x11sdSrc.validateAsSource(trx, repeat, filter);
|
||||
x11sdDst.maskBuffer.compositeBlit(x11sdSrc, x11sdDst, 0, 0, bounds.x, bounds.y, bounds.width, bounds.height);
|
||||
}
|
||||
} finally {
|
||||
SunToolkit.awtUnlock();
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: Is mask ever omitable??? ... should be for 90 degree rotation and no shear, but we always need to use RepeatPad */
|
||||
protected static boolean isMaskOmittable(AffineTransform trx, Composite comp, int filter) {
|
||||
return (filter == XRUtils.FAST || trx.getTranslateX() == (int) trx.getTranslateX() /*
|
||||
* If
|
||||
* translate
|
||||
* is
|
||||
* integer
|
||||
* only
|
||||
*/
|
||||
&& trx.getTranslateY() == (int) trx.getTranslateY() && (trx.getShearX() == 0 && trx.getShearY() == 0 // Only
|
||||
// 90 degree
|
||||
// rotation
|
||||
|| trx.getShearX() == -trx.getShearY())) && ((AlphaComposite) comp).getAlpha() == 1.0f; // No
|
||||
// ExtraAlpha!=1
|
||||
}
|
||||
}
|
||||
|
||||
class XrSwToPMBlit extends Blit {
|
||||
Blit pmToSurfaceBlit;
|
||||
|
||||
XrSwToPMBlit(SurfaceType srcType, SurfaceType dstType) {
|
||||
super(srcType, CompositeType.AnyAlpha, dstType);
|
||||
pmToSurfaceBlit = new XRPMBlit(dstType, dstType);
|
||||
}
|
||||
|
||||
public void Blit(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int sx, int sy, int dx, int dy, int w, int h) {
|
||||
/*
|
||||
* If the blit is write-only (putimge), no need for a temporary VI.
|
||||
*/
|
||||
if (CompositeType.SrcOverNoEa.equals(comp) && (src.getTransparency() == Transparency.OPAQUE)) {
|
||||
Blit opaqueSwToSurfaceBlit = Blit.getFromCache(src.getSurfaceType(), CompositeType.SrcNoEa, dst.getSurfaceType());
|
||||
opaqueSwToSurfaceBlit.Blit(src, dst, comp, clip, sx, sy, dx, dy, w, h);
|
||||
} else {
|
||||
try {
|
||||
SunToolkit.awtLock();
|
||||
|
||||
XRSurfaceData vImgSurface = XRPMBlitLoops.cacheToTmpSurface(src, (XRSurfaceData) dst, w, h, sx, sy);
|
||||
pmToSurfaceBlit.Blit(vImgSurface, dst, comp, clip, 0, 0, dx, dy, w, h);
|
||||
} finally {
|
||||
SunToolkit.awtUnlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class XrSwToPMScaledBlit extends ScaledBlit {
|
||||
ScaledBlit pmToSurfaceBlit;
|
||||
|
||||
XrSwToPMScaledBlit(SurfaceType srcType, SurfaceType dstType) {
|
||||
super(srcType, CompositeType.AnyAlpha, dstType);
|
||||
pmToSurfaceBlit = new XRPMScaledBlit(dstType, dstType);
|
||||
}
|
||||
|
||||
public void Scale(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int sx1, int sy1, int sx2, int sy2, double dx1, double dy1,
|
||||
double dx2, double dy2) {
|
||||
{
|
||||
int w = sx2 - sx1;
|
||||
int h = sy2 - sy1;
|
||||
|
||||
try {
|
||||
SunToolkit.awtLock();
|
||||
XRSurfaceData vImgSurface = XRPMBlitLoops.cacheToTmpSurface(src, (XRSurfaceData) dst, w, h, sx1, sy1);
|
||||
pmToSurfaceBlit.Scale(vImgSurface, dst, comp, clip, 0, 0, w, h, dx1, dy1, dx2, dy2);
|
||||
} finally {
|
||||
SunToolkit.awtUnlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class XrSwToPMTransformedBlit extends TransformBlit {
|
||||
TransformBlit pmToSurfaceBlit;
|
||||
|
||||
XrSwToPMTransformedBlit(SurfaceType srcType, SurfaceType dstType) {
|
||||
super(srcType, CompositeType.AnyAlpha, dstType);
|
||||
pmToSurfaceBlit = new XRPMTransformedBlit(dstType, dstType);
|
||||
}
|
||||
|
||||
public void Transform(SurfaceData src, SurfaceData dst, Composite comp, Region clip, AffineTransform xform, int hint, int sx, int sy, int dstx,
|
||||
int dsty, int w, int h) {
|
||||
try {
|
||||
SunToolkit.awtLock();
|
||||
|
||||
XRSurfaceData vImgSurface = XRPMBlitLoops.cacheToTmpSurface(src, (XRSurfaceData) dst, w, h, sx, sy);
|
||||
pmToSurfaceBlit.Transform(vImgSurface, dst, comp, clip, xform, hint, 0, 0, dstx, dsty, w, h);
|
||||
} finally {
|
||||
SunToolkit.awtUnlock();
|
||||
}
|
||||
}
|
||||
}
|
314
jdk/src/solaris/classes/sun/java2d/xr/XRPaints.java
Normal file
314
jdk/src/solaris/classes/sun/java2d/xr/XRPaints.java
Normal file
|
@ -0,0 +1,314 @@
|
|||
/*
|
||||
* 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.MultipleGradientPaint.*;
|
||||
import java.awt.geom.*;
|
||||
import java.awt.image.*;
|
||||
|
||||
import sun.java2d.*;
|
||||
import sun.java2d.loops.*;
|
||||
import sun.java2d.pipe.*;
|
||||
|
||||
abstract class XRPaints {
|
||||
static XRCompositeManager xrCompMan;
|
||||
|
||||
static final XRGradient xrGradient = new XRGradient();
|
||||
static final XRLinearGradient xrLinearGradient = new XRLinearGradient();
|
||||
static final XRRadialGradient xrRadialGradient = new XRRadialGradient();
|
||||
static final XRTexture xrTexture = new XRTexture();
|
||||
|
||||
public static void register(XRCompositeManager xrComp) {
|
||||
xrCompMan = xrComp;
|
||||
}
|
||||
|
||||
private static XRPaints getXRPaint(SunGraphics2D sg2d) {
|
||||
switch (sg2d.paintState) {
|
||||
case SunGraphics2D.PAINT_GRADIENT:
|
||||
return xrGradient;
|
||||
|
||||
case SunGraphics2D.PAINT_LIN_GRADIENT:
|
||||
return xrLinearGradient;
|
||||
|
||||
case SunGraphics2D.PAINT_RAD_GRADIENT:
|
||||
return xrRadialGradient;
|
||||
|
||||
case SunGraphics2D.PAINT_TEXTURE:
|
||||
return xrTexture;
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to locate an implementation corresponding to the paint state of
|
||||
* the provided SunGraphics2D object. If no implementation can be found, or
|
||||
* if the paint cannot be accelerated under the conditions of the
|
||||
* SunGraphics2D, this method returns false; otherwise, returns true.
|
||||
*/
|
||||
static boolean isValid(SunGraphics2D sg2d) {
|
||||
XRPaints impl = getXRPaint(sg2d);
|
||||
return (impl != null && impl.isPaintValid(sg2d));
|
||||
}
|
||||
|
||||
static void setPaint(SunGraphics2D sg2d, Paint paint) {
|
||||
XRPaints impl = getXRPaint(sg2d);
|
||||
if (impl != null) {
|
||||
impl.setXRPaint(sg2d, paint);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this implementation is able to accelerate the Paint
|
||||
* object associated with, and under the conditions of, the provided
|
||||
* SunGraphics2D instance; otherwise returns false.
|
||||
*/
|
||||
abstract boolean isPaintValid(SunGraphics2D sg2d);
|
||||
|
||||
abstract void setXRPaint(SunGraphics2D sg2d, Paint paint);
|
||||
|
||||
private static class XRGradient extends XRPaints {
|
||||
private XRGradient() {
|
||||
}
|
||||
|
||||
/**
|
||||
* There are no restrictions for accelerating GradientPaint, so this
|
||||
* method always returns true.
|
||||
*/
|
||||
@Override
|
||||
boolean isPaintValid(SunGraphics2D sg2d) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void setXRPaint(SunGraphics2D sg2d, Paint pt) {
|
||||
GradientPaint paint = (GradientPaint) pt;
|
||||
|
||||
int[] pixels = convertToIntArgbPixels(new Color[] { paint.getColor1(), paint.getColor2() }, false);
|
||||
|
||||
float fractions[] = new float[2];
|
||||
fractions[0] = 0;
|
||||
fractions[1] = 1;
|
||||
|
||||
Point2D pt1 = paint.getPoint1();
|
||||
Point2D pt2 = paint.getPoint2();
|
||||
|
||||
AffineTransform at = (AffineTransform) sg2d.transform.clone();
|
||||
try {
|
||||
at.invert();
|
||||
} catch (NoninvertibleTransformException ex) {
|
||||
at.setToIdentity();
|
||||
}
|
||||
|
||||
int repeat = paint.isCyclic() ? XRUtils.RepeatReflect : XRUtils.RepeatPad;
|
||||
|
||||
XRBackend con = xrCompMan.getBackend();
|
||||
int gradient = con.createLinearGradient(pt1, pt2, fractions, pixels, repeat, at);
|
||||
xrCompMan.setGradientPaint(new XRSurfaceData.XRInternalSurfaceData(con, gradient, at));
|
||||
}
|
||||
}
|
||||
|
||||
public int getGradientLength(Point2D pt1, Point2D pt2) {
|
||||
double xDiff = Math.max(pt1.getX(), pt2.getX()) - Math.min(pt1.getX(), pt2.getX());
|
||||
double yDiff = Math.max(pt1.getY(), pt2.getY()) - Math.min(pt1.getY(), pt2.getY());
|
||||
return (int) Math.ceil(Math.sqrt(xDiff*xDiff + yDiff*yDiff));
|
||||
}
|
||||
|
||||
private static class XRLinearGradient extends XRPaints {
|
||||
|
||||
@Override
|
||||
boolean isPaintValid(SunGraphics2D sg2d) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
void setXRPaint(SunGraphics2D sg2d, Paint pt) {
|
||||
LinearGradientPaint paint = (LinearGradientPaint) pt;
|
||||
boolean linear = (paint.getColorSpace() == ColorSpaceType.LINEAR_RGB);
|
||||
|
||||
Color[] colors = paint.getColors();
|
||||
Point2D pt1 = paint.getStartPoint();
|
||||
Point2D pt2 = paint.getEndPoint();
|
||||
|
||||
|
||||
AffineTransform at = paint.getTransform();
|
||||
at.preConcatenate(sg2d.transform);
|
||||
|
||||
int repeat = XRUtils.getRepeatForCycleMethod(paint.getCycleMethod());
|
||||
float[] fractions = paint.getFractions();
|
||||
int[] pixels = convertToIntArgbPixels(colors, linear);
|
||||
|
||||
try {
|
||||
at.invert();
|
||||
} catch (NoninvertibleTransformException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
XRBackend con = xrCompMan.getBackend();
|
||||
int gradient = con.createLinearGradient(pt1, pt2, fractions, pixels, repeat, at);
|
||||
xrCompMan.setGradientPaint(new XRSurfaceData.XRInternalSurfaceData(con, gradient, at));
|
||||
}
|
||||
}
|
||||
|
||||
private static class XRRadialGradient extends XRPaints {
|
||||
|
||||
@Override
|
||||
boolean isPaintValid(SunGraphics2D sg2d) {
|
||||
RadialGradientPaint grad = (RadialGradientPaint) sg2d.paint;
|
||||
return grad.getFocusPoint().equals(grad.getCenterPoint());
|
||||
}
|
||||
|
||||
@Override
|
||||
void setXRPaint(SunGraphics2D sg2d, Paint pt) {
|
||||
RadialGradientPaint paint = (RadialGradientPaint) pt;
|
||||
boolean linear = (paint.getColorSpace() == ColorSpaceType.LINEAR_RGB);
|
||||
Color[] colors = paint.getColors();
|
||||
Point2D center = paint.getCenterPoint();
|
||||
Point2D focus = paint.getFocusPoint();
|
||||
|
||||
int repeat = XRUtils.getRepeatForCycleMethod(paint.getCycleMethod());
|
||||
float[] fractions = paint.getFractions();
|
||||
int[] pixels = convertToIntArgbPixels(colors, linear);
|
||||
float radius = paint.getRadius();
|
||||
|
||||
// save original (untransformed) center and focus points
|
||||
double cx = center.getX();
|
||||
double cy = center.getY();
|
||||
double fx = focus.getX();
|
||||
double fy = focus.getY();
|
||||
|
||||
AffineTransform at = paint.getTransform();
|
||||
at.preConcatenate(sg2d.transform);
|
||||
focus = at.transform(focus, focus);
|
||||
|
||||
// transform unit circle to gradient coords; we start with the
|
||||
// unit circle (center=(0,0), focus on positive x-axis, radius=1)
|
||||
// and then transform into gradient space
|
||||
at.translate(cx, cy);
|
||||
at.rotate(fx - cx, fy - cy);
|
||||
// at.scale(radius, radius);
|
||||
|
||||
// invert to get mapping from device coords to unit circle
|
||||
try {
|
||||
at.invert();
|
||||
} catch (Exception e) {
|
||||
at.setToScale(0.0, 0.0);
|
||||
}
|
||||
focus = at.transform(focus, focus);
|
||||
|
||||
// clamp the focus point so that it does not rest on, or outside
|
||||
// of, the circumference of the gradient circle
|
||||
fx = Math.min(focus.getX(), 0.99);
|
||||
|
||||
XRBackend con = xrCompMan.getBackend();
|
||||
int gradient = con.createRadialGradient(new Point2D.Float(0, 0), new Point2D.Float(0, 0), 0, radius, fractions, pixels, repeat, at);
|
||||
xrCompMan.setGradientPaint(new XRSurfaceData.XRInternalSurfaceData(con, gradient, at));
|
||||
}
|
||||
}
|
||||
|
||||
private static class XRTexture extends XRPaints {
|
||||
|
||||
@Override
|
||||
boolean isPaintValid(SunGraphics2D sg2d) {
|
||||
TexturePaint paint = (TexturePaint) sg2d.paint;
|
||||
BufferedImage bi = paint.getImage();
|
||||
XRSurfaceData dstData = (XRSurfaceData) sg2d.getDestSurface();
|
||||
|
||||
SurfaceData srcData = dstData.getSourceSurfaceData(bi, SunGraphics2D.TRANSFORM_ISIDENT, CompositeType.SrcOver, null);
|
||||
if (!(srcData instanceof XRSurfaceData)) {
|
||||
// REMIND: this is a hack that attempts to cache the system
|
||||
// memory image from the TexturePaint instance into an
|
||||
// OpenGL texture...
|
||||
srcData = dstData.getSourceSurfaceData(bi, SunGraphics2D.TRANSFORM_ISIDENT, CompositeType.SrcOver, null);
|
||||
if (!(srcData instanceof XRSurfaceData)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
void setXRPaint(SunGraphics2D sg2d, Paint pt) {
|
||||
TexturePaint paint = (TexturePaint) pt;
|
||||
|
||||
BufferedImage bi = paint.getImage();
|
||||
SurfaceData dstData = sg2d.surfaceData;
|
||||
SurfaceData srcData = dstData.getSourceSurfaceData(bi, SunGraphics2D.TRANSFORM_ISIDENT, CompositeType.SrcOver, null);
|
||||
|
||||
// REMIND: this hack tries to ensure that we have a cached texture
|
||||
if (!(srcData instanceof XRSurfaceData)) {
|
||||
srcData = dstData.getSourceSurfaceData(paint.getImage(), SunGraphics2D.TRANSFORM_ISIDENT, CompositeType.SrcOver, null);
|
||||
if (!(srcData instanceof XRSurfaceData)) {
|
||||
throw new InternalError("Surface not cachable");
|
||||
}
|
||||
}
|
||||
|
||||
XRSurfaceData x11SrcData = (XRSurfaceData) srcData;
|
||||
|
||||
AffineTransform at = (AffineTransform) sg2d.transform.clone();
|
||||
Rectangle2D anchor = paint.getAnchorRect();
|
||||
at.translate(anchor.getX(), anchor.getY());
|
||||
at.scale(anchor.getWidth() / ((double) bi.getWidth()), anchor.getHeight() / ((double) bi.getHeight()));
|
||||
|
||||
try {
|
||||
at.invert();
|
||||
} catch (NoninvertibleTransformException ex) {
|
||||
at.setToIdentity(); /* TODO: Right thing to do in this case? */
|
||||
}
|
||||
|
||||
x11SrcData.validateAsSource(at, XRUtils.RepeatNormal, XRUtils.ATransOpToXRQuality(sg2d.interpolationType));
|
||||
xrCompMan.setTexturePaint(((XRSurfaceData) srcData));
|
||||
}
|
||||
}
|
||||
|
||||
public int[] convertToIntArgbPixels(Color[] colors, boolean linear) {
|
||||
int[] pixels = new int[colors.length];
|
||||
for (int i = 0; i < colors.length; i++) {
|
||||
pixels[i] = colorToIntArgbPixel(colors[i], linear);
|
||||
}
|
||||
return pixels;
|
||||
}
|
||||
|
||||
public int colorToIntArgbPixel(Color c, boolean linear) {
|
||||
int rgb = c.getRGB();
|
||||
|
||||
int a = rgb >>> 24;
|
||||
int r = (rgb >> 16) & 0xff;
|
||||
int g = (rgb >> 8) & 0xff;
|
||||
int b = (rgb) & 0xff;
|
||||
if (linear) {
|
||||
r = BufferedPaints.convertSRGBtoLinearRGB(r);
|
||||
g = BufferedPaints.convertSRGBtoLinearRGB(g);
|
||||
b = BufferedPaints.convertSRGBtoLinearRGB(b);
|
||||
}
|
||||
|
||||
a *= xrCompMan.getExtraAlpha();
|
||||
|
||||
return ((a << 24) | (r << 16) | (g << 8) | (b));
|
||||
}
|
||||
}
|
331
jdk/src/solaris/classes/sun/java2d/xr/XRRenderer.java
Normal file
331
jdk/src/solaris/classes/sun/java2d/xr/XRRenderer.java
Normal file
|
@ -0,0 +1,331 @@
|
|||
/*
|
||||
* 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.awt.SunToolkit;
|
||||
import sun.java2d.SunGraphics2D;
|
||||
import sun.java2d.loops.*;
|
||||
import sun.java2d.pipe.Region;
|
||||
import sun.java2d.pipe.PixelDrawPipe;
|
||||
import sun.java2d.pipe.PixelFillPipe;
|
||||
import sun.java2d.pipe.ShapeDrawPipe;
|
||||
import sun.java2d.pipe.SpanIterator;
|
||||
import sun.java2d.pipe.ShapeSpanIterator;
|
||||
import sun.java2d.pipe.LoopPipe;
|
||||
|
||||
/**
|
||||
* XRender provides only accalerated rectangles. To emulate higher "order"
|
||||
* geometry we have to pass everything else to DoPath/FillSpans.
|
||||
*
|
||||
* TODO: DrawRect could be instrified
|
||||
*
|
||||
* @author Clemens Eisserer
|
||||
*/
|
||||
|
||||
public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe {
|
||||
XRDrawHandler drawHandler;
|
||||
MaskTileManager tileManager;
|
||||
|
||||
public XRRenderer(MaskTileManager tileManager) {
|
||||
this.tileManager = tileManager;
|
||||
this.drawHandler = new XRDrawHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 drawLine(SunGraphics2D sg2d, int x1, int y1, int x2, int y2) {
|
||||
try {
|
||||
SunToolkit.awtLock();
|
||||
|
||||
validateSurface(sg2d);
|
||||
int transx = sg2d.transX;
|
||||
int transy = sg2d.transY;
|
||||
|
||||
XRSurfaceData xrsd = (XRSurfaceData) sg2d.surfaceData;
|
||||
|
||||
tileManager.addLine(x1 + transx, y1 + transy,
|
||||
x2 + transx, y2 + transy);
|
||||
tileManager.fillMask(xrsd);
|
||||
} finally {
|
||||
SunToolkit.awtUnlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void drawRect(SunGraphics2D sg2d,
|
||||
int x, int y, int width, int height) {
|
||||
draw(sg2d, new Rectangle2D.Float(x, y, width, height));
|
||||
}
|
||||
|
||||
public void drawPolyline(SunGraphics2D sg2d,
|
||||
int xpoints[], int ypoints[], int npoints) {
|
||||
Path2D.Float p2d = new Path2D.Float();
|
||||
if (npoints > 1) {
|
||||
p2d.moveTo(xpoints[0], ypoints[0]);
|
||||
for (int i = 1; i < npoints; i++) {
|
||||
p2d.lineTo(xpoints[i], ypoints[i]);
|
||||
}
|
||||
}
|
||||
|
||||
draw(sg2d, p2d);
|
||||
}
|
||||
|
||||
public void drawPolygon(SunGraphics2D sg2d,
|
||||
int xpoints[], int ypoints[], int npoints) {
|
||||
draw(sg2d, new Polygon(xpoints, ypoints, npoints));
|
||||
}
|
||||
|
||||
public synchronized void fillRect(SunGraphics2D sg2d,
|
||||
int x, int y, int width, int height) {
|
||||
SunToolkit.awtLock();
|
||||
try {
|
||||
validateSurface(sg2d);
|
||||
|
||||
XRSurfaceData xrsd = (XRSurfaceData) sg2d.surfaceData;
|
||||
|
||||
x += sg2d.transform.getTranslateX();
|
||||
y += sg2d.transform.getTranslateY();
|
||||
|
||||
tileManager.addRect(x, y, width, height);
|
||||
tileManager.fillMask(xrsd);
|
||||
|
||||
} finally {
|
||||
SunToolkit.awtUnlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void fillPolygon(SunGraphics2D sg2d,
|
||||
int xpoints[], int ypoints[], int npoints) {
|
||||
fill(sg2d, new Polygon(xpoints, ypoints, npoints));
|
||||
}
|
||||
|
||||
public void drawRoundRect(SunGraphics2D sg2d,
|
||||
int x, int y, int width, int height,
|
||||
int arcWidth, int arcHeight) {
|
||||
draw(sg2d, new RoundRectangle2D.Float(x, y, width, height,
|
||||
arcWidth, arcHeight));
|
||||
}
|
||||
|
||||
public void fillRoundRect(SunGraphics2D sg2d, int x, int y,
|
||||
int width, int height,
|
||||
int arcWidth, int arcHeight) {
|
||||
fill(sg2d, new RoundRectangle2D.Float(x, y, width, height,
|
||||
arcWidth, arcHeight));
|
||||
}
|
||||
|
||||
public void drawOval(SunGraphics2D sg2d,
|
||||
int x, int y, int width, int height) {
|
||||
draw(sg2d, new Ellipse2D.Float(x, y, width, height));
|
||||
}
|
||||
|
||||
public void fillOval(SunGraphics2D sg2d,
|
||||
int x, int y, int width, int height) {
|
||||
fill(sg2d, new Ellipse2D.Float(x, y, width, height));
|
||||
}
|
||||
|
||||
public void drawArc(SunGraphics2D sg2d,
|
||||
int x, int y, int width, int height,
|
||||
int startAngle, int arcAngle) {
|
||||
draw(sg2d, new Arc2D.Float(x, y, width, height,
|
||||
startAngle, arcAngle, Arc2D.OPEN));
|
||||
}
|
||||
|
||||
public void fillArc(SunGraphics2D sg2d,
|
||||
int x, int y, int width, int height,
|
||||
int startAngle, int arcAngle) {
|
||||
fill(sg2d, new Arc2D.Float(x, y, width, height,
|
||||
startAngle, arcAngle, Arc2D.PIE));
|
||||
}
|
||||
|
||||
private class XRDrawHandler extends ProcessPath.DrawHandler {
|
||||
|
||||
XRDrawHandler() {
|
||||
// these are bogus values; the caller will use validate()
|
||||
// to ensure that they are set properly prior to each usage
|
||||
super(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method needs to be called prior to each draw/fillPath()
|
||||
* operation to ensure the clip bounds are up to date.
|
||||
*/
|
||||
void validate(SunGraphics2D sg2d) {
|
||||
Region clip = sg2d.getCompClip();
|
||||
setBounds(clip.getLoX(), clip.getLoY(),
|
||||
clip.getHiX(), clip.getHiY(), sg2d.strokeHint);
|
||||
validateSurface(sg2d);
|
||||
}
|
||||
|
||||
public void drawLine(int x1, int y1, int x2, int y2) {
|
||||
tileManager.addLine(x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
public void drawPixel(int x, int y) {
|
||||
tileManager.addRect(x, y, 1, 1);
|
||||
}
|
||||
|
||||
public void drawScanline(int x1, int x2, int y) {
|
||||
tileManager.addRect(x1, y, x2 - x1 + 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
protected void drawPath(SunGraphics2D sg2d, Path2D.Float p2df,
|
||||
int transx, int transy) {
|
||||
SunToolkit.awtLock();
|
||||
try {
|
||||
validateSurface(sg2d);
|
||||
drawHandler.validate(sg2d);
|
||||
ProcessPath.drawPath(drawHandler, p2df, transx, transy);
|
||||
tileManager.fillMask(((XRSurfaceData) sg2d.surfaceData));
|
||||
} finally {
|
||||
SunToolkit.awtUnlock();
|
||||
}
|
||||
}
|
||||
|
||||
protected void fillPath(SunGraphics2D sg2d, Path2D.Float p2df,
|
||||
int transx, int transy) {
|
||||
SunToolkit.awtLock();
|
||||
try {
|
||||
validateSurface(sg2d);
|
||||
drawHandler.validate(sg2d);
|
||||
ProcessPath.fillPath(drawHandler, p2df, transx, transy);
|
||||
tileManager.fillMask(((XRSurfaceData) sg2d.surfaceData));
|
||||
} finally {
|
||||
SunToolkit.awtUnlock();
|
||||
}
|
||||
}
|
||||
|
||||
protected void fillSpans(SunGraphics2D sg2d, SpanIterator si,
|
||||
int transx, int transy) {
|
||||
SunToolkit.awtLock();
|
||||
try {
|
||||
validateSurface(sg2d);
|
||||
int[] spanBox = new int[4];
|
||||
while (si.nextSpan(spanBox)) {
|
||||
tileManager.addRect(spanBox[0] + transx,
|
||||
spanBox[1] + transy,
|
||||
spanBox[2] - spanBox[0],
|
||||
spanBox[3] - spanBox[1]);
|
||||
}
|
||||
tileManager.fillMask(((XRSurfaceData) sg2d.surfaceData));
|
||||
} finally {
|
||||
SunToolkit.awtUnlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void draw(SunGraphics2D sg2d, Shape s) {
|
||||
if (sg2d.strokeState == SunGraphics2D.STROKE_THIN) {
|
||||
Path2D.Float p2df;
|
||||
int transx, transy;
|
||||
if (sg2d.transformState <= SunGraphics2D.TRANSFORM_INT_TRANSLATE) {
|
||||
if (s instanceof Path2D.Float) {
|
||||
p2df = (Path2D.Float) s;
|
||||
} else {
|
||||
p2df = new Path2D.Float(s);
|
||||
}
|
||||
transx = sg2d.transX;
|
||||
transy = sg2d.transY;
|
||||
} else {
|
||||
p2df = new Path2D.Float(s, sg2d.transform);
|
||||
transx = 0;
|
||||
transy = 0;
|
||||
}
|
||||
drawPath(sg2d, p2df, transx, transy);
|
||||
} else if (sg2d.strokeState < SunGraphics2D.STROKE_CUSTOM) {
|
||||
ShapeSpanIterator si = LoopPipe.getStrokeSpans(sg2d, s);
|
||||
try {
|
||||
fillSpans(sg2d, si, 0, 0);
|
||||
} finally {
|
||||
si.dispose();
|
||||
}
|
||||
} else {
|
||||
fill(sg2d, sg2d.stroke.createStrokedShape(s));
|
||||
}
|
||||
}
|
||||
|
||||
public void fill(SunGraphics2D sg2d, Shape s) {
|
||||
int transx, transy;
|
||||
|
||||
if (sg2d.strokeState == SunGraphics2D.STROKE_THIN) {
|
||||
// Here we are able to use fillPath() for
|
||||
// high-quality fills.
|
||||
Path2D.Float p2df;
|
||||
if (sg2d.transformState <= SunGraphics2D.TRANSFORM_INT_TRANSLATE) {
|
||||
if (s instanceof Path2D.Float) {
|
||||
p2df = (Path2D.Float) s;
|
||||
} else {
|
||||
p2df = new Path2D.Float(s);
|
||||
}
|
||||
transx = sg2d.transX;
|
||||
transy = sg2d.transY;
|
||||
} else {
|
||||
p2df = new Path2D.Float(s, sg2d.transform);
|
||||
transx = 0;
|
||||
transy = 0;
|
||||
}
|
||||
fillPath(sg2d, p2df, transx, transy);
|
||||
return;
|
||||
}
|
||||
|
||||
AffineTransform at;
|
||||
if (sg2d.transformState <= SunGraphics2D.TRANSFORM_INT_TRANSLATE) {
|
||||
// Transform (translation) will be done by FillSpans
|
||||
at = null;
|
||||
transx = sg2d.transX;
|
||||
transy = sg2d.transY;
|
||||
} else {
|
||||
// Transform will be done by the PathIterator
|
||||
at = sg2d.transform;
|
||||
transx = transy = 0;
|
||||
}
|
||||
|
||||
ShapeSpanIterator ssi = LoopPipe.getFillSSI(sg2d);
|
||||
try {
|
||||
// Subtract transx/y from the SSI clip to match the
|
||||
// (potentially untranslated) geometry fed to it
|
||||
Region clip = sg2d.getCompClip();
|
||||
ssi.setOutputAreaXYXY(clip.getLoX() - transx,
|
||||
clip.getLoY() - transy,
|
||||
clip.getHiX() - transx,
|
||||
clip.getHiY() - transy);
|
||||
ssi.appendPath(s.getPathIterator(at));
|
||||
fillSpans(sg2d, ssi, transx, transy);
|
||||
} finally {
|
||||
ssi.dispose();
|
||||
}
|
||||
}
|
||||
}
|
668
jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceData.java
Normal file
668
jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceData.java
Normal file
|
@ -0,0 +1,668 @@
|
|||
/*
|
||||
* 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 java.awt.image.*;
|
||||
import sun.awt.*;
|
||||
import sun.java2d.InvalidPipeException;
|
||||
import sun.java2d.SunGraphics2D;
|
||||
import sun.java2d.SurfaceData;
|
||||
import sun.java2d.SurfaceDataProxy;
|
||||
import sun.java2d.jules.*;
|
||||
import sun.java2d.loops.*;
|
||||
import sun.java2d.pipe.*;
|
||||
import sun.java2d.x11.*;
|
||||
import sun.font.FontManagerNativeLibrary;
|
||||
|
||||
public abstract class XRSurfaceData extends XSurfaceData {
|
||||
X11ComponentPeer peer;
|
||||
XRGraphicsConfig graphicsConfig;
|
||||
XRBackend renderQueue;
|
||||
|
||||
private RenderLoops solidloops;
|
||||
|
||||
protected int depth;
|
||||
|
||||
private static native void initIDs();
|
||||
|
||||
protected native void XRInitSurface(int depth, int width, int height,
|
||||
long drawable, int pictFormat);
|
||||
|
||||
native void initXRPicture(long xsdo, int pictForm);
|
||||
|
||||
public static final String DESC_BYTE_A8_X11 = "Byte A8 Pixmap";
|
||||
public static final String DESC_INT_RGB_X11 = "Integer RGB Pixmap";
|
||||
public static final String DESC_INT_ARGB_X11 = "Integer ARGB-Pre Pixmap";
|
||||
|
||||
public static final SurfaceType
|
||||
ByteA8X11 = SurfaceType.ByteGray.deriveSubType(DESC_BYTE_A8_X11);
|
||||
public static final SurfaceType
|
||||
IntRgbX11 = SurfaceType.IntRgb.deriveSubType(DESC_INT_RGB_X11);
|
||||
public static final SurfaceType
|
||||
IntArgbPreX11 = SurfaceType.IntArgbPre.deriveSubType(DESC_INT_ARGB_X11);
|
||||
|
||||
public Raster getRaster(int x, int y, int w, int h) {
|
||||
throw new InternalError("not implemented yet");
|
||||
}
|
||||
|
||||
protected XRRenderer xrpipe;
|
||||
protected PixelToShapeConverter xrtxpipe;
|
||||
protected TextPipe xrtextpipe;
|
||||
protected XRDrawImage xrDrawImage;
|
||||
|
||||
protected ShapeDrawPipe aaShapePipe;
|
||||
protected PixelToShapeConverter aaPixelToShapeConv;
|
||||
|
||||
public static void initXRSurfaceData() {
|
||||
if (!isX11SurfaceDataInitialized()) {
|
||||
FontManagerNativeLibrary.load();
|
||||
initIDs();
|
||||
XRPMBlitLoops.register();
|
||||
XRMaskFill.register();
|
||||
XRMaskBlit.register();
|
||||
|
||||
setX11SurfaceDataInitialized();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronized accessor method for isDrawableValid.
|
||||
*/
|
||||
protected boolean isXRDrawableValid() {
|
||||
try {
|
||||
SunToolkit.awtLock();
|
||||
return isDrawableValid();
|
||||
} finally {
|
||||
SunToolkit.awtUnlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SurfaceDataProxy makeProxyFor(SurfaceData srcData) {
|
||||
return XRSurfaceDataProxy.createProxy(srcData, graphicsConfig);
|
||||
}
|
||||
|
||||
public void validatePipe(SunGraphics2D sg2d) {
|
||||
TextPipe textpipe;
|
||||
boolean validated = false;
|
||||
|
||||
/*
|
||||
* The textpipe for now can't handle TexturePaint when extra-alpha is
|
||||
* specified nore XOR mode
|
||||
*/
|
||||
if (sg2d.compositeState < SunGraphics2D.COMP_XOR &&
|
||||
(sg2d.paintState < SunGraphics2D.PAINT_TEXTURE ||
|
||||
sg2d.composite == null ||
|
||||
!(sg2d.composite instanceof AlphaComposite) ||
|
||||
((AlphaComposite) sg2d.composite).getAlpha() == 1.0f))
|
||||
{
|
||||
textpipe = xrtextpipe;
|
||||
} else {
|
||||
super.validatePipe(sg2d);
|
||||
textpipe = sg2d.textpipe;
|
||||
validated = true;
|
||||
}
|
||||
|
||||
PixelToShapeConverter txPipe = null;
|
||||
XRRenderer nonTxPipe = null;
|
||||
|
||||
/*
|
||||
* TODO: Can we rely on the GC for ARGB32 surfaces?
|
||||
*/
|
||||
if (sg2d.antialiasHint != SunHints.INTVAL_ANTIALIAS_ON) {
|
||||
if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR) {
|
||||
if (sg2d.compositeState <= SunGraphics2D.COMP_XOR) {
|
||||
txPipe = xrtxpipe;
|
||||
nonTxPipe = xrpipe;
|
||||
}
|
||||
} else if (sg2d.compositeState <= SunGraphics2D.COMP_ALPHA) {
|
||||
if (XRPaints.isValid(sg2d)) {
|
||||
txPipe = xrtxpipe;
|
||||
nonTxPipe = xrpipe;
|
||||
}
|
||||
// custom paints handled by super.validatePipe() below
|
||||
}
|
||||
}
|
||||
|
||||
if (sg2d.antialiasHint == SunHints.INTVAL_ANTIALIAS_ON &&
|
||||
JulesPathBuf.isCairoAvailable())
|
||||
{
|
||||
sg2d.shapepipe = aaShapePipe;
|
||||
sg2d.drawpipe = aaPixelToShapeConv;
|
||||
sg2d.fillpipe = aaPixelToShapeConv;
|
||||
} else {
|
||||
if (txPipe != null) {
|
||||
if (sg2d.transformState >= SunGraphics2D.TRANSFORM_TRANSLATESCALE) {
|
||||
sg2d.drawpipe = txPipe;
|
||||
sg2d.fillpipe = txPipe;
|
||||
} else if (sg2d.strokeState != SunGraphics2D.STROKE_THIN) {
|
||||
sg2d.drawpipe = txPipe;
|
||||
sg2d.fillpipe = nonTxPipe;
|
||||
} else {
|
||||
sg2d.drawpipe = nonTxPipe;
|
||||
sg2d.fillpipe = nonTxPipe;
|
||||
}
|
||||
sg2d.shapepipe = nonTxPipe;
|
||||
} else {
|
||||
if (!validated) {
|
||||
super.validatePipe(sg2d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// install the text pipe based on our earlier decision
|
||||
sg2d.textpipe = textpipe;
|
||||
|
||||
// always override the image pipe with the specialized XRender pipe
|
||||
sg2d.imagepipe = xrDrawImage;
|
||||
}
|
||||
|
||||
protected MaskFill getMaskFill(SunGraphics2D sg2d) {
|
||||
if (sg2d.paintState > SunGraphics2D.PAINT_ALPHACOLOR &&
|
||||
!XRPaints.isValid(sg2d))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return super.getMaskFill(sg2d);
|
||||
}
|
||||
|
||||
public RenderLoops getRenderLoops(SunGraphics2D sg2d) {
|
||||
if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR &&
|
||||
sg2d.compositeState <= SunGraphics2D.COMP_ALPHA)
|
||||
{
|
||||
return solidloops;
|
||||
}
|
||||
|
||||
return super.getRenderLoops(sg2d);
|
||||
}
|
||||
|
||||
public GraphicsConfiguration getDeviceConfiguration() {
|
||||
return graphicsConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for instantiating a Window SurfaceData
|
||||
*/
|
||||
public static XRWindowSurfaceData createData(X11ComponentPeer peer) {
|
||||
XRGraphicsConfig gc = getGC(peer);
|
||||
return new XRWindowSurfaceData(peer, gc, gc.getSurfaceType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for instantiating a Pixmap SurfaceData (offscreen).
|
||||
* If the surface * is opaque a 24-bit/RGB surface is chosen,
|
||||
* otherwise a 32-bit ARGB surface.
|
||||
*/
|
||||
public static XRPixmapSurfaceData createData(XRGraphicsConfig gc,
|
||||
int width, int height,
|
||||
ColorModel cm, Image image,
|
||||
long drawable,
|
||||
int transparency) {
|
||||
int depth = transparency > Transparency.OPAQUE ? 32 : 24;
|
||||
if (depth == 24) {
|
||||
cm = new DirectColorModel(depth,
|
||||
0x00FF0000, 0x0000FF00, 0x000000FF);
|
||||
} else {
|
||||
cm = new DirectColorModel(depth, 0x00FF0000, 0x0000FF00,
|
||||
0x000000FF, 0xFF000000);
|
||||
}
|
||||
|
||||
return new XRPixmapSurfaceData
|
||||
(gc, width, height, image, getSurfaceType(gc, transparency),
|
||||
cm, drawable, transparency,
|
||||
XRUtils.getPictureFormatForTransparency(transparency), depth);
|
||||
}
|
||||
|
||||
protected XRSurfaceData(X11ComponentPeer peer, XRGraphicsConfig gc,
|
||||
SurfaceType sType, ColorModel cm, int depth, int transparency)
|
||||
{
|
||||
super(sType, cm);
|
||||
this.peer = peer;
|
||||
this.graphicsConfig = gc;
|
||||
this.solidloops = graphicsConfig.getSolidLoops(sType);
|
||||
this.depth = depth;
|
||||
initOps(peer, graphicsConfig, depth);
|
||||
|
||||
setBlitProxyKey(gc.getProxyKey());
|
||||
}
|
||||
|
||||
protected XRSurfaceData(XRBackend renderQueue) {
|
||||
super(XRSurfaceData.IntRgbX11,
|
||||
new DirectColorModel(24, 0x00FF0000, 0x0000FF00, 0x000000FF));
|
||||
this.renderQueue = renderQueue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inits the XRender-data-structures which belong to the XRSurfaceData.
|
||||
*
|
||||
* @param pictureFormat
|
||||
*/
|
||||
public void initXRender(int pictureFormat) {
|
||||
try {
|
||||
SunToolkit.awtLock();
|
||||
initXRPicture(getNativeOps(), pictureFormat);
|
||||
renderQueue = XRCompositeManager.getInstance(this).getBackend();
|
||||
maskBuffer = XRCompositeManager.getInstance(this);
|
||||
} catch (Throwable ex) {
|
||||
ex.printStackTrace();
|
||||
} finally {
|
||||
SunToolkit.awtUnlock();
|
||||
}
|
||||
}
|
||||
|
||||
public static XRGraphicsConfig getGC(X11ComponentPeer peer) {
|
||||
if (peer != null) {
|
||||
return (XRGraphicsConfig) peer.getGraphicsConfiguration();
|
||||
} else {
|
||||
GraphicsEnvironment env =
|
||||
GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
GraphicsDevice gd = env.getDefaultScreenDevice();
|
||||
return (XRGraphicsConfig) gd.getDefaultConfiguration();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a boolean indicating whether or not a copyArea from the given
|
||||
* rectangle source coordinates might be incomplete and result in X11
|
||||
* GraphicsExposure events being generated from XCopyArea. This method
|
||||
* allows the SurfaceData copyArea method to determine if it needs to set
|
||||
* the GraphicsExposures attribute of the X11 GC to True or False to receive
|
||||
* or avoid the events.
|
||||
*
|
||||
* @return true if there is any chance that an XCopyArea from the given
|
||||
* source coordinates could produce any X11 Exposure events.
|
||||
*/
|
||||
public abstract boolean canSourceSendExposures(int x, int y, int w, int h);
|
||||
|
||||
/**
|
||||
* CopyArea is implemented using the "old" X11 GC, therefor clip and
|
||||
* needExposures have to be validated against that GC. Pictures and GCs
|
||||
* don't share state.
|
||||
*/
|
||||
public void validateCopyAreaGC(Region gcClip, boolean needExposures) {
|
||||
if (validatedGCClip != gcClip) {
|
||||
if (gcClip != null)
|
||||
renderQueue.setGCClipRectangles(xgc, gcClip);
|
||||
validatedGCClip = gcClip;
|
||||
}
|
||||
|
||||
if (validatedExposures != needExposures) {
|
||||
validatedExposures = needExposures;
|
||||
renderQueue.setGCExposures(xgc, needExposures);
|
||||
}
|
||||
|
||||
if (validatedXorComp != null) {
|
||||
renderQueue.setGCMode(xgc, true);
|
||||
renderQueue.setGCForeground(xgc, validatedGCForegroundPixel);
|
||||
validatedXorComp = null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean copyArea(SunGraphics2D sg2d, int x, int y, int w, int h,
|
||||
int dx, int dy) {
|
||||
if (xrpipe == null) {
|
||||
if (!isXRDrawableValid()) {
|
||||
return true;
|
||||
}
|
||||
makePipes();
|
||||
}
|
||||
CompositeType comptype = sg2d.imageComp;
|
||||
if (sg2d.transformState < SunGraphics2D.TRANSFORM_TRANSLATESCALE &&
|
||||
(CompositeType.SrcOverNoEa.equals(comptype) ||
|
||||
CompositeType.SrcNoEa.equals(comptype)))
|
||||
{
|
||||
x += sg2d.transX;
|
||||
y += sg2d.transY;
|
||||
try {
|
||||
SunToolkit.awtLock();
|
||||
boolean needExposures = canSourceSendExposures(x, y, w, h);
|
||||
validateCopyAreaGC(sg2d.getCompClip(), needExposures);
|
||||
renderQueue.copyArea(xid, xid, xgc, x, y, w, h, x + dx, y + dy);
|
||||
} finally {
|
||||
SunToolkit.awtUnlock();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the XRender SurfaceType which is able to fullfill the specified
|
||||
* transparency requirement.
|
||||
*/
|
||||
public static SurfaceType getSurfaceType(XRGraphicsConfig gc,
|
||||
int transparency) {
|
||||
SurfaceType sType = null;
|
||||
|
||||
switch (transparency) {
|
||||
case Transparency.OPAQUE:
|
||||
sType = XRSurfaceData.IntRgbX11;
|
||||
break;
|
||||
|
||||
case Transparency.BITMASK:
|
||||
case Transparency.TRANSLUCENT:
|
||||
sType = XRSurfaceData.IntArgbPreX11;
|
||||
break;
|
||||
}
|
||||
|
||||
return sType;
|
||||
}
|
||||
|
||||
public void invalidate() {
|
||||
if (isValid()) {
|
||||
setInvalid();
|
||||
super.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
private long xgc; // GC is still used for copyArea
|
||||
private int validatedGCForegroundPixel = 0;
|
||||
private XORComposite validatedXorComp;
|
||||
private int xid;
|
||||
public int picture;
|
||||
public XRCompositeManager maskBuffer;
|
||||
|
||||
private Region validatedClip;
|
||||
private Region validatedGCClip;
|
||||
private boolean validatedExposures = true;
|
||||
|
||||
boolean transformInUse = false;
|
||||
AffineTransform validatedSourceTransform = new AffineTransform();
|
||||
int validatedRepeat = XRUtils.RepeatNone;
|
||||
int validatedFilter = XRUtils.FAST;
|
||||
|
||||
/**
|
||||
* Validates an XRSurfaceData when used as source. Note that the clip is
|
||||
* applied when used as source as well as destination.
|
||||
*/
|
||||
void validateAsSource(AffineTransform sxForm, int repeat, int filter) {
|
||||
|
||||
if (validatedClip != null) {
|
||||
validatedClip = null;
|
||||
renderQueue.setClipRectangles(picture, null);
|
||||
}
|
||||
|
||||
if (validatedRepeat != repeat && repeat != -1) {
|
||||
validatedRepeat = repeat;
|
||||
renderQueue.setPictureRepeat(picture, repeat);
|
||||
}
|
||||
|
||||
if (sxForm == null) {
|
||||
if (transformInUse) {
|
||||
validatedSourceTransform.setToIdentity();
|
||||
renderQueue.setPictureTransform(picture,
|
||||
validatedSourceTransform);
|
||||
transformInUse = false;
|
||||
}
|
||||
} else if (!transformInUse ||
|
||||
(transformInUse && !sxForm.equals(validatedSourceTransform))) {
|
||||
validatedSourceTransform.setTransform(sxForm.getScaleX(),
|
||||
sxForm.getShearY(),
|
||||
sxForm.getShearX(),
|
||||
sxForm.getScaleY(),
|
||||
sxForm.getTranslateX(),
|
||||
sxForm.getTranslateY());
|
||||
renderQueue.setPictureTransform(picture, validatedSourceTransform);
|
||||
transformInUse = true;
|
||||
}
|
||||
|
||||
if (filter != validatedFilter && filter != -1) {
|
||||
renderQueue.setFilter(picture, filter);
|
||||
validatedFilter = filter;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the Surface when used as destination.
|
||||
*/
|
||||
public void validateAsDestination(SunGraphics2D sg2d, Region clip) {
|
||||
if (!isValid()) {
|
||||
throw new InvalidPipeException("bounds changed");
|
||||
}
|
||||
|
||||
boolean updateGCClip = false;
|
||||
if (clip != validatedClip) {
|
||||
renderQueue.setClipRectangles(picture, clip);
|
||||
validatedClip = clip;
|
||||
updateGCClip = true;
|
||||
}
|
||||
|
||||
if (sg2d != null && sg2d.compositeState == SunGraphics2D.COMP_XOR) {
|
||||
if (validatedXorComp != sg2d.getComposite()) {
|
||||
validatedXorComp = (XORComposite) sg2d.getComposite();
|
||||
int xorpixelmod = validatedXorComp.getXorPixel();
|
||||
renderQueue.setGCMode(xgc, false);
|
||||
|
||||
// validate pixel
|
||||
int pixel = sg2d.pixel;
|
||||
if (validatedGCForegroundPixel != pixel) {
|
||||
renderQueue.setGCForeground(xgc, pixel ^ xorpixelmod);
|
||||
validatedGCForegroundPixel = pixel;
|
||||
}
|
||||
}
|
||||
|
||||
if (updateGCClip) {
|
||||
renderQueue.setGCClipRectangles(xgc, clip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void makePipes() { /*
|
||||
* TODO: Why is this synchronized,
|
||||
* but access not?
|
||||
*/
|
||||
if (xrpipe == null) {
|
||||
try {
|
||||
SunToolkit.awtLock();
|
||||
xgc = renderQueue.createGC(xid); // TODO: GC leak? where to
|
||||
// clean up?
|
||||
|
||||
xrpipe = new XRRenderer(maskBuffer.getMaskBuffer());
|
||||
xrtxpipe = new PixelToShapeConverter(xrpipe);
|
||||
xrtextpipe = maskBuffer.getTextRenderer();
|
||||
xrDrawImage = new XRDrawImage();
|
||||
|
||||
if (JulesPathBuf.isCairoAvailable()) {
|
||||
aaShapePipe =
|
||||
new JulesShapePipe(XRCompositeManager.getInstance(this));
|
||||
aaPixelToShapeConv = new PixelToShapeConverter(aaShapePipe);
|
||||
}
|
||||
} finally {
|
||||
SunToolkit.awtUnlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class XRWindowSurfaceData extends XRSurfaceData {
|
||||
public XRWindowSurfaceData(X11ComponentPeer peer,
|
||||
XRGraphicsConfig gc, SurfaceType sType) {
|
||||
super(peer, gc, sType, peer.getColorModel(),
|
||||
peer.getColorModel().getPixelSize(), Transparency.OPAQUE);
|
||||
|
||||
if (isXRDrawableValid()) {
|
||||
initXRender(XRUtils.
|
||||
getPictureFormatForTransparency(Transparency.OPAQUE));
|
||||
makePipes();
|
||||
}
|
||||
}
|
||||
|
||||
public SurfaceData getReplacement() {
|
||||
return peer.getSurfaceData();
|
||||
}
|
||||
|
||||
public Rectangle getBounds() {
|
||||
Rectangle r = peer.getBounds();
|
||||
r.x = r.y = 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canSourceSendExposures(int x, int y, int w, int h) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns destination Component associated with this SurfaceData.
|
||||
*/
|
||||
public Object getDestination() {
|
||||
return peer.getTarget();
|
||||
}
|
||||
}
|
||||
|
||||
public static class XRInternalSurfaceData extends XRSurfaceData {
|
||||
public XRInternalSurfaceData(XRBackend renderQueue, int pictXid,
|
||||
AffineTransform transform) {
|
||||
super(renderQueue);
|
||||
this.picture = pictXid;
|
||||
this.validatedSourceTransform = transform;
|
||||
|
||||
if (validatedSourceTransform != null) {
|
||||
transformInUse = true;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canSourceSendExposures(int x, int y, int w, int h) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Rectangle getBounds() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object getDestination() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public SurfaceData getReplacement() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class XRPixmapSurfaceData extends XRSurfaceData {
|
||||
Image offscreenImage;
|
||||
int width;
|
||||
int height;
|
||||
int transparency;
|
||||
|
||||
public XRPixmapSurfaceData(XRGraphicsConfig gc, int width, int height,
|
||||
Image image, SurfaceType sType,
|
||||
ColorModel cm, long drawable,
|
||||
int transparency, int pictFormat,
|
||||
int depth) {
|
||||
super(null, gc, sType, cm, depth, transparency);
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
offscreenImage = image;
|
||||
this.transparency = transparency;
|
||||
initSurface(depth, width, height, drawable, pictFormat);
|
||||
|
||||
initXRender(pictFormat);
|
||||
makePipes();
|
||||
}
|
||||
|
||||
public void initSurface(int depth, int width, int height,
|
||||
long drawable, int pictFormat) {
|
||||
try {
|
||||
SunToolkit.awtLock();
|
||||
XRInitSurface(depth, width, height, drawable, pictFormat);
|
||||
} finally {
|
||||
SunToolkit.awtUnlock();
|
||||
}
|
||||
}
|
||||
|
||||
public SurfaceData getReplacement() {
|
||||
return restoreContents(offscreenImage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Need this since the surface data is created with the color model of
|
||||
* the target GC, which is always opaque. But in SunGraphics2D.blitSD we
|
||||
* choose loops based on the transparency on the source SD, so it could
|
||||
* choose wrong loop (blit instead of blitbg, for example).
|
||||
*/
|
||||
public int getTransparency() {
|
||||
return transparency;
|
||||
}
|
||||
|
||||
public Rectangle getBounds() {
|
||||
return new Rectangle(width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canSourceSendExposures(int x, int y, int w, int h) {
|
||||
return (x < 0 || y < 0 || (x + w) > width || (y + h) > height);
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
/*
|
||||
* We need to invalidate the surface before disposing the native
|
||||
* Drawable and Picture. This way if an application tries to render
|
||||
* to an already flushed XRSurfaceData, we will notice in the
|
||||
* validate() method above that it has been invalidated, and we will
|
||||
* avoid using those native resources that have already been
|
||||
* disposed.
|
||||
*/
|
||||
invalidate();
|
||||
flushNativeSurface();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns destination Image associated with this SurfaceData.
|
||||
*/
|
||||
public Object getDestination() {
|
||||
return offscreenImage;
|
||||
}
|
||||
}
|
||||
|
||||
public long getGC() {
|
||||
return xgc;
|
||||
}
|
||||
|
||||
public static class LazyPipe extends ValidatePipe {
|
||||
public boolean validate(SunGraphics2D sg2d) {
|
||||
XRSurfaceData xsd = (XRSurfaceData) sg2d.surfaceData;
|
||||
if (!xsd.isXRDrawableValid()) {
|
||||
return false;
|
||||
}
|
||||
xsd.makePipes();
|
||||
return super.validate(sg2d);
|
||||
}
|
||||
}
|
||||
|
||||
public int getPicture() {
|
||||
return picture;
|
||||
}
|
||||
|
||||
public int getXid() {
|
||||
return xid;
|
||||
}
|
||||
|
||||
public XRGraphicsConfig getGraphicsConfig() {
|
||||
return graphicsConfig;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* 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.Color;
|
||||
import java.awt.Transparency;
|
||||
import sun.java2d.SurfaceData;
|
||||
import sun.java2d.SurfaceDataProxy;
|
||||
import sun.java2d.loops.CompositeType;
|
||||
|
||||
/**
|
||||
* The proxy class contains the logic if to replace a SurfaceData with a
|
||||
* cached X11 Pixmap and the code to create the accelerated surfaces.
|
||||
*/
|
||||
public class XRSurfaceDataProxy extends SurfaceDataProxy implements Transparency {
|
||||
|
||||
public static SurfaceDataProxy createProxy(SurfaceData srcData,
|
||||
XRGraphicsConfig dstConfig) {
|
||||
|
||||
/*Don't cache already native surfaces*/
|
||||
if (srcData instanceof XRSurfaceData) {
|
||||
return UNCACHED;
|
||||
}
|
||||
|
||||
return new XRSurfaceDataProxy(dstConfig, srcData.getTransparency());
|
||||
}
|
||||
|
||||
XRGraphicsConfig xrgc;
|
||||
int transparency;
|
||||
|
||||
public XRSurfaceDataProxy(XRGraphicsConfig x11gc) {
|
||||
this.xrgc = x11gc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SurfaceData validateSurfaceData(SurfaceData srcData,
|
||||
SurfaceData cachedData, int w, int h) {
|
||||
if (cachedData == null) {
|
||||
cachedData = XRSurfaceData.createData(xrgc, w, h, xrgc
|
||||
.getColorModel(), null, 0, getTransparency());
|
||||
}
|
||||
return cachedData;
|
||||
}
|
||||
|
||||
public XRSurfaceDataProxy(XRGraphicsConfig x11gc, int transparency) {
|
||||
this.xrgc = x11gc;
|
||||
this.transparency = transparency;
|
||||
}
|
||||
|
||||
//TODO: Is that really ok?
|
||||
@Override
|
||||
public boolean isSupportedOperation(SurfaceData srcData, int txtype,
|
||||
CompositeType comp, Color bgColor) {
|
||||
return (bgColor == null || transparency == Transparency.TRANSLUCENT);
|
||||
}
|
||||
|
||||
public int getTransparency() {
|
||||
return transparency;
|
||||
}
|
||||
}
|
261
jdk/src/solaris/classes/sun/java2d/xr/XRUtils.java
Normal file
261
jdk/src/solaris/classes/sun/java2d/xr/XRUtils.java
Normal file
|
@ -0,0 +1,261 @@
|
|||
/*
|
||||
* 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.MultipleGradientPaint.*;
|
||||
import java.awt.image.*;
|
||||
import sun.java2d.loops.*;
|
||||
import static java.awt.AlphaComposite.*;
|
||||
|
||||
/**
|
||||
* XRender constants and utility methods.
|
||||
*
|
||||
* @author Clemens Eisserer
|
||||
*/
|
||||
|
||||
public class XRUtils {
|
||||
public static final int None = 0;
|
||||
|
||||
/* Composition Operators */
|
||||
public static final byte PictOpClear = 0;
|
||||
public static final byte PictOpSrc = 1;
|
||||
public static final byte PictOpDst = 2;
|
||||
public static final byte PictOpOver = 3;
|
||||
public static final byte PictOpOverReverse = 4;
|
||||
public static final byte PictOpIn = 5;
|
||||
public static final byte PictOpInReverse = 6;
|
||||
public static final byte PictOpOut = 7;
|
||||
public static final byte PictOpOutReverse = 8;
|
||||
public static final byte PictOpAtop = 9;
|
||||
public static final byte PictOpAtopReverse = 10;
|
||||
public static final byte PictOpXor = 11;
|
||||
public static final byte PictOpAdd = 12;
|
||||
public static final byte PictOpSaturate = 13;
|
||||
|
||||
/* Repeats */
|
||||
public static final int RepeatNone = 0;
|
||||
public static final int RepeatNormal = 1;
|
||||
public static final int RepeatPad = 2;
|
||||
public static final int RepeatReflect = 3;
|
||||
|
||||
/* Interpolation qualities */
|
||||
public static final int FAST = 0;
|
||||
public static final int GOOD = 1;
|
||||
public static final int BEST = 2;
|
||||
public static final byte[] FAST_NAME = "fast".getBytes();
|
||||
public static final byte[] GOOD_NAME = "good".getBytes();
|
||||
public static final byte[] BEST_NAME = "best".getBytes();
|
||||
|
||||
/* PictFormats */
|
||||
public static final int PictStandardARGB32 = 0;
|
||||
public static final int PictStandardRGB24 = 1;
|
||||
public static final int PictStandardA8 = 2;
|
||||
public static final int PictStandardA4 = 3;
|
||||
public static final int PictStandardA1 = 4;
|
||||
|
||||
/**
|
||||
* Maps the specified affineTransformOp to the corresponding XRender image
|
||||
* filter.
|
||||
*/
|
||||
public static int ATransOpToXRQuality(int affineTranformOp) {
|
||||
|
||||
switch (affineTranformOp) {
|
||||
case AffineTransformOp.TYPE_NEAREST_NEIGHBOR:
|
||||
return FAST;
|
||||
|
||||
case AffineTransformOp.TYPE_BILINEAR:
|
||||
return GOOD;
|
||||
|
||||
case AffineTransformOp.TYPE_BICUBIC:
|
||||
return BEST;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps the specified affineTransformOp to the corresponding XRender image
|
||||
* filter.
|
||||
*/
|
||||
public static byte[] ATransOpToXRQualityName(int affineTranformOp) {
|
||||
|
||||
switch (affineTranformOp) {
|
||||
case AffineTransformOp.TYPE_NEAREST_NEIGHBOR:
|
||||
return FAST_NAME;
|
||||
|
||||
case AffineTransformOp.TYPE_BILINEAR:
|
||||
return GOOD_NAME;
|
||||
|
||||
case AffineTransformOp.TYPE_BICUBIC:
|
||||
return BEST_NAME;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static byte[] getFilterName(int filterType) {
|
||||
switch (filterType) {
|
||||
case FAST:
|
||||
return FAST_NAME;
|
||||
case GOOD:
|
||||
return GOOD_NAME;
|
||||
case BEST:
|
||||
return BEST_NAME;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the XRender picture Format which is required to fullfill the
|
||||
* Java2D transparency requirement.
|
||||
*/
|
||||
public static int getPictureFormatForTransparency(int transparency) {
|
||||
switch (transparency) {
|
||||
case Transparency.OPAQUE:
|
||||
return PictStandardRGB24;
|
||||
|
||||
case Transparency.BITMASK:
|
||||
case Transparency.TRANSLUCENT:
|
||||
return PictStandardARGB32;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
public static SurfaceType getXRSurfaceTypeForTransparency(int transparency) {
|
||||
if (transparency == Transparency.OPAQUE) {
|
||||
return SurfaceType.IntRgb;
|
||||
}else {
|
||||
return SurfaceType.IntArgbPre;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps Java2D CycleMethod to XRender's Repeat property.
|
||||
*/
|
||||
public static int getRepeatForCycleMethod(CycleMethod cycleMethod) {
|
||||
if (cycleMethod.equals(CycleMethod.NO_CYCLE)) {
|
||||
return RepeatPad;
|
||||
} else if (cycleMethod.equals(CycleMethod.REFLECT)) {
|
||||
return RepeatReflect;
|
||||
} else if (cycleMethod.equals(CycleMethod.REPEAT)) {
|
||||
return RepeatNormal;
|
||||
}
|
||||
|
||||
return RepeatNone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a double into an XFixed.
|
||||
*/
|
||||
public static int XDoubleToFixed(double dbl) {
|
||||
return (int) (dbl * 65536);
|
||||
}
|
||||
|
||||
public static double XFixedToDouble(int fixed) {
|
||||
return ((double) fixed) / 65536;
|
||||
}
|
||||
|
||||
public static int[] convertFloatsToFixed(float[] values) {
|
||||
int[] fixed = new int[values.length];
|
||||
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
fixed[i] = XDoubleToFixed(values[i]);
|
||||
}
|
||||
|
||||
return fixed;
|
||||
}
|
||||
|
||||
public static long intToULong(int signed) {
|
||||
if (signed < 0) {
|
||||
return ((long) signed) + (((long) Integer.MAX_VALUE) -
|
||||
((long) Integer.MIN_VALUE) + 1);
|
||||
}
|
||||
|
||||
return signed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps the specified Java2D composition rule, to the corresponding XRender
|
||||
* composition rule.
|
||||
*/
|
||||
public static byte j2dAlphaCompToXR(int j2dRule) {
|
||||
switch (j2dRule) {
|
||||
case CLEAR:
|
||||
return PictOpClear;
|
||||
|
||||
case SRC:
|
||||
return PictOpSrc;
|
||||
|
||||
case DST:
|
||||
return PictOpDst;
|
||||
|
||||
case SRC_OVER:
|
||||
return PictOpOver;
|
||||
|
||||
case DST_OVER:
|
||||
return PictOpOverReverse;
|
||||
|
||||
case SRC_IN:
|
||||
return PictOpIn;
|
||||
|
||||
case DST_IN:
|
||||
return PictOpInReverse;
|
||||
|
||||
case SRC_OUT:
|
||||
return PictOpOut;
|
||||
|
||||
case DST_OUT:
|
||||
return PictOpOutReverse;
|
||||
|
||||
case SRC_ATOP:
|
||||
return PictOpAtop;
|
||||
|
||||
case DST_ATOP:
|
||||
return PictOpAtopReverse;
|
||||
|
||||
case XOR:
|
||||
return PictOpXor;
|
||||
}
|
||||
|
||||
throw new InternalError("No XRender equivalent available for requested java2d composition rule: "+j2dRule);
|
||||
}
|
||||
|
||||
public static short clampToShort(int x) {
|
||||
return (short) (x > Short.MAX_VALUE
|
||||
? Short.MAX_VALUE
|
||||
: (x < Short.MIN_VALUE ? Short.MIN_VALUE : x));
|
||||
}
|
||||
|
||||
public static short clampToUShort(int x) {
|
||||
return (short) (x > 65535 ? 65535 : (x < 0) ? 0 : x);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* 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.GraphicsConfiguration;
|
||||
import java.awt.ImageCapabilities;
|
||||
import java.awt.image.ColorModel;
|
||||
import sun.awt.image.SunVolatileImage;
|
||||
import sun.awt.image.VolatileSurfaceManager;
|
||||
import sun.java2d.SurfaceData;
|
||||
|
||||
/**
|
||||
* XRender platform implementation of the VolatileSurfaceManager class.
|
||||
*/
|
||||
public class XRVolatileSurfaceManager extends VolatileSurfaceManager {
|
||||
|
||||
public XRVolatileSurfaceManager(SunVolatileImage vImg, Object context) {
|
||||
super(vImg, context);
|
||||
}
|
||||
|
||||
protected boolean isAccelerationEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a pixmap-based SurfaceData object
|
||||
*/
|
||||
protected SurfaceData initAcceleratedSurface() {
|
||||
SurfaceData sData;
|
||||
|
||||
try {
|
||||
XRGraphicsConfig gc = (XRGraphicsConfig) vImg.getGraphicsConfig();
|
||||
ColorModel cm = gc.getColorModel();
|
||||
long drawable = 0;
|
||||
if (context instanceof Long) {
|
||||
drawable = ((Long)context).longValue();
|
||||
}
|
||||
sData = XRSurfaceData.createData(gc,
|
||||
vImg.getWidth(),
|
||||
vImg.getHeight(),
|
||||
cm, vImg, drawable,
|
||||
vImg.getTransparency());
|
||||
} catch (NullPointerException ex) {
|
||||
sData = null;
|
||||
} catch (OutOfMemoryError er) {
|
||||
sData = null;
|
||||
}
|
||||
|
||||
return sData;
|
||||
}
|
||||
|
||||
/**
|
||||
* XRender should allow copies between different formats and depths.
|
||||
* TODO: verify that this assumption is correct.
|
||||
*/
|
||||
protected boolean isConfigValid(GraphicsConfiguration gc) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Need to override the default behavior because Pixmaps-based
|
||||
* images are accelerated but not volatile.
|
||||
*/
|
||||
@Override
|
||||
public ImageCapabilities getCapabilities(GraphicsConfiguration gc) {
|
||||
if (isConfigValid(gc) && isAccelerationEnabled()) {
|
||||
return new ImageCapabilities(true);
|
||||
}
|
||||
return new ImageCapabilities(false);
|
||||
}
|
||||
}
|
59
jdk/src/solaris/classes/sun/java2d/xr/XcbRequestCounter.java
Normal file
59
jdk/src/solaris/classes/sun/java2d/xr/XcbRequestCounter.java
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* UInt32 "emulation", mimics the behaviour of xcb's request counter.
|
||||
* In order to be compatible with xcb we have to wrap exactly when xcb would do.
|
||||
* @author Clemens Eisserer
|
||||
*/
|
||||
|
||||
public class XcbRequestCounter {
|
||||
private final static long MAX_UINT = 4294967295L;
|
||||
|
||||
long value;
|
||||
|
||||
public XcbRequestCounter(long value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public void setValue(long value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public long getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void add(long v) {
|
||||
value += v;
|
||||
|
||||
/*Handle 32-bit unsigned int overflow*/
|
||||
if (value > MAX_UINT) {
|
||||
value = 0; //-= MAX_UINT; //Shouldn't that be zero?!?!
|
||||
}
|
||||
}
|
||||
}
|
|
@ -71,7 +71,7 @@ extern int J2DXErrHandler(Display *display, XErrorEvent *xerr);
|
|||
extern AwtGraphicsConfigDataPtr
|
||||
getGraphicsConfigFromComponentPeer(JNIEnv *env, jobject this);
|
||||
extern struct X11GraphicsConfigIDs x11GraphicsConfigIDs;
|
||||
static jint X11SD_InitWindow(JNIEnv *env, X11SDOps *xsdo);
|
||||
|
||||
static int X11SD_FindClip(SurfaceDataBounds *b, SurfaceDataBounds *bounds,
|
||||
X11SDOps *xsdo);
|
||||
static int X11SD_ClipToRoot(SurfaceDataBounds *b, SurfaceDataBounds *bounds,
|
||||
|
@ -97,6 +97,54 @@ static XImage * cachedXImage;
|
|||
|
||||
#endif /* !HEADLESS */
|
||||
|
||||
jboolean XShared_initIDs(JNIEnv *env, jboolean allowShmPixmaps)
|
||||
{
|
||||
#ifndef HEADLESS
|
||||
union {
|
||||
char c[4];
|
||||
int i;
|
||||
} endian;
|
||||
|
||||
endian.i = 0xff000000;
|
||||
nativeByteOrder = (endian.c[0]) ? MSBFirst : LSBFirst;
|
||||
|
||||
dgaAvailable = JNI_FALSE;
|
||||
|
||||
cachedXImage = NULL;
|
||||
|
||||
if (sizeof(X11RIPrivate) > SD_RASINFO_PRIVATE_SIZE) {
|
||||
JNU_ThrowInternalError(env, "Private RasInfo structure too large!");
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
#ifdef MITSHM
|
||||
if (getenv("NO_AWT_MITSHM") == NULL &&
|
||||
getenv("NO_J2D_MITSHM") == NULL) {
|
||||
char * force;
|
||||
TryInitMITShm(env, &useMitShmExt, &useMitShmPixmaps);
|
||||
|
||||
if(allowShmPixmaps) {
|
||||
useMitShmPixmaps = (useMitShmPixmaps == CAN_USE_MITSHM);
|
||||
force = getenv("J2D_PIXMAPS");
|
||||
if (force != NULL) {
|
||||
if (useMitShmPixmaps && (strcmp(force, "shared") == 0)) {
|
||||
forceSharedPixmaps = JNI_TRUE;
|
||||
} else if (strcmp(force, "server") == 0) {
|
||||
useMitShmPixmaps = JNI_FALSE;
|
||||
}
|
||||
}
|
||||
}else {
|
||||
useMitShmPixmaps = JNI_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return JNI_TRUE;
|
||||
#endif /* MITSHM */
|
||||
|
||||
#endif /* !HEADLESS */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Class: sun_java2d_x11_X11SurfaceData
|
||||
* Method: initIDs
|
||||
|
@ -107,30 +155,17 @@ Java_sun_java2d_x11_X11SurfaceData_initIDs(JNIEnv *env, jclass xsd,
|
|||
jclass XORComp, jboolean tryDGA)
|
||||
{
|
||||
#ifndef HEADLESS
|
||||
if(XShared_initIDs(env, JNI_TRUE))
|
||||
{
|
||||
void *lib = 0;
|
||||
|
||||
union {
|
||||
char c[4];
|
||||
int i;
|
||||
} endian;
|
||||
|
||||
endian.i = 0xff000000;
|
||||
nativeByteOrder = (endian.c[0]) ? MSBFirst : LSBFirst;
|
||||
|
||||
cachedXImage = NULL;
|
||||
|
||||
if (sizeof(X11RIPrivate) > SD_RASINFO_PRIVATE_SIZE) {
|
||||
JNU_ThrowInternalError(env, "Private RasInfo structure too large!");
|
||||
return;
|
||||
}
|
||||
|
||||
xorCompClass = (*env)->NewGlobalRef(env, XORComp);
|
||||
|
||||
if (tryDGA && (getenv("NO_J2D_DGA") == NULL)) {
|
||||
/* we use RTLD_NOW because of bug 4032715 */
|
||||
lib = dlopen("libsunwjdga.so", RTLD_NOW);
|
||||
}
|
||||
dgaAvailable = JNI_FALSE;
|
||||
|
||||
if (lib != NULL) {
|
||||
JDgaStatus ret = JDGA_FAILED;
|
||||
void *sym = dlsym(lib, "JDgaLibInit");
|
||||
|
@ -149,24 +184,7 @@ Java_sun_java2d_x11_X11SurfaceData_initIDs(JNIEnv *env, jclass xsd,
|
|||
lib = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MITSHM
|
||||
if (getenv("NO_AWT_MITSHM") == NULL &&
|
||||
getenv("NO_J2D_MITSHM") == NULL) {
|
||||
char * force;
|
||||
TryInitMITShm(env, &useMitShmExt, &useMitShmPixmaps);
|
||||
useMitShmPixmaps = (useMitShmPixmaps == CAN_USE_MITSHM);
|
||||
force = getenv("J2D_PIXMAPS");
|
||||
if (force != NULL) {
|
||||
if (useMitShmPixmaps && (strcmp(force, "shared") == 0)) {
|
||||
forceSharedPixmaps = JNI_TRUE;
|
||||
} else if (strcmp(force, "server") == 0) {
|
||||
useMitShmPixmaps = JNI_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* MITSHM */
|
||||
|
||||
#endif /* !HEADLESS */
|
||||
}
|
||||
|
||||
|
@ -176,7 +194,7 @@ Java_sun_java2d_x11_X11SurfaceData_initIDs(JNIEnv *env, jclass xsd,
|
|||
* Signature: ()Z
|
||||
*/
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_sun_java2d_x11_X11SurfaceData_isDrawableValid(JNIEnv *env, jobject this)
|
||||
Java_sun_java2d_x11_XSurfaceData_isDrawableValid(JNIEnv *env, jobject this)
|
||||
{
|
||||
jboolean ret = JNI_FALSE;
|
||||
|
||||
|
@ -193,22 +211,6 @@ Java_sun_java2d_x11_X11SurfaceData_isDrawableValid(JNIEnv *env, jobject this)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_java2d_x11_X11SurfaceData
|
||||
* Method: isDgaAvailable
|
||||
* Signature: ()Z
|
||||
*/
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_sun_java2d_x11_X11SurfaceData_isDgaAvailable(JNIEnv *env, jobject this)
|
||||
{
|
||||
#if defined(HEADLESS) || defined(__linux__)
|
||||
return JNI_FALSE;
|
||||
#else
|
||||
return dgaAvailable;
|
||||
#endif /* HEADLESS */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Class: sun_java2d_x11_X11SurfaceData
|
||||
* Method: isShmPMAvailable
|
||||
|
@ -224,6 +226,20 @@ Java_sun_java2d_x11_X11SurfaceData_isShmPMAvailable(JNIEnv *env, jobject this)
|
|||
#endif /* HEADLESS, MITSHM */
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_java2d_x11_X11SurfaceData
|
||||
* Method: isDgaAvailable
|
||||
* Signature: ()Z
|
||||
*/
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_sun_java2d_x11_X11SurfaceData_isDgaAvailable(JNIEnv *env, jobject this)
|
||||
{
|
||||
#if defined(HEADLESS) || defined(__linux__)
|
||||
return JNI_FALSE;
|
||||
#else
|
||||
return dgaAvailable;
|
||||
#endif /* HEADLESS */
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_java2d_x11_X11SurfaceData
|
||||
|
@ -231,7 +247,7 @@ Java_sun_java2d_x11_X11SurfaceData_isShmPMAvailable(JNIEnv *env, jobject this)
|
|||
* Signature: (Ljava/lang/Object;I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_java2d_x11_X11SurfaceData_initOps(JNIEnv *env, jobject xsd,
|
||||
Java_sun_java2d_x11_XSurfaceData_initOps(JNIEnv *env, jobject xsd,
|
||||
jobject peer,
|
||||
jobject graphicsConfig, jint depth)
|
||||
{
|
||||
|
@ -304,6 +320,8 @@ Java_sun_java2d_x11_X11SurfaceData_initOps(JNIEnv *env, jobject xsd,
|
|||
} else {
|
||||
xsdo->pixelmask = 0xff;
|
||||
}
|
||||
|
||||
xsdo->xrPic = None;
|
||||
#endif /* !HEADLESS */
|
||||
}
|
||||
|
||||
|
@ -313,7 +331,7 @@ Java_sun_java2d_x11_X11SurfaceData_initOps(JNIEnv *env, jobject xsd,
|
|||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_java2d_x11_X11SurfaceData_flushNativeSurface(JNIEnv *env, jobject xsd)
|
||||
Java_sun_java2d_x11_XSurfaceData_flushNativeSurface(JNIEnv *env, jobject xsd)
|
||||
{
|
||||
#ifndef HEADLESS
|
||||
SurfaceDataOps *ops = SurfaceData_GetOps(env, xsd);
|
||||
|
@ -384,6 +402,11 @@ X11SD_Dispose(JNIEnv *env, SurfaceDataOps *ops)
|
|||
XFreeGC(awt_display, xsdo->cachedGC);
|
||||
xsdo->cachedGC = NULL;
|
||||
}
|
||||
|
||||
if(xsdo->xrPic != None) {
|
||||
XRenderFreePicture(awt_display, xsdo->xrPic);
|
||||
}
|
||||
|
||||
AWT_UNLOCK();
|
||||
#endif /* !HEADLESS */
|
||||
}
|
||||
|
@ -393,7 +416,7 @@ X11SD_Dispose(JNIEnv *env, SurfaceDataOps *ops)
|
|||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_java2d_x11_X11SurfaceData_setInvalid(JNIEnv *env, jobject xsd)
|
||||
Java_sun_java2d_x11_XSurfaceData_setInvalid(JNIEnv *env, jobject xsd)
|
||||
{
|
||||
#ifndef HEADLESS
|
||||
X11SDOps *xsdo = (X11SDOps *) SurfaceData_GetOps(env, xsd);
|
||||
|
@ -404,29 +427,10 @@ Java_sun_java2d_x11_X11SurfaceData_setInvalid(JNIEnv *env, jobject xsd)
|
|||
#endif /* !HEADLESS */
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_java2d_x11_X11SurfaceData
|
||||
* Method: initSurface
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_java2d_x11_X11SurfaceData_initSurface(JNIEnv *env, jclass xsd,
|
||||
jint depth,
|
||||
jint width, jint height,
|
||||
jlong drawable)
|
||||
|
||||
jboolean XShared_initSurface(JNIEnv *env, X11SDOps *xsdo, jint depth, jint width, jint height, jlong drawable)
|
||||
{
|
||||
#ifndef HEADLESS
|
||||
X11SDOps *xsdo = X11SurfaceData_GetOps(env, xsd);
|
||||
if (xsdo == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (xsdo->configData->awt_cmap == (Colormap)NULL) {
|
||||
awtJNI_CreateColorData(env, xsdo->configData, 1);
|
||||
}
|
||||
/* color_data will be initialized in awtJNI_CreateColorData for
|
||||
8-bit visuals */
|
||||
xsdo->cData = xsdo->configData->color_data;
|
||||
|
||||
if (drawable != (jlong)0) {
|
||||
/* Double-buffering */
|
||||
|
@ -452,7 +456,7 @@ Java_sun_java2d_x11_X11SurfaceData_initSurface(JNIEnv *env, jclass xsd,
|
|||
if (xsdo->drawable) {
|
||||
xsdo->shmPMData.usingShmPixmap = JNI_TRUE;
|
||||
xsdo->shmPMData.shmPixmap = xsdo->drawable;
|
||||
return;
|
||||
return JNI_TRUE;
|
||||
}
|
||||
}
|
||||
#endif /* MITSHM */
|
||||
|
@ -472,7 +476,40 @@ Java_sun_java2d_x11_X11SurfaceData_initSurface(JNIEnv *env, jclass xsd,
|
|||
if (xsdo->drawable == 0) {
|
||||
JNU_ThrowOutOfMemoryError(env,
|
||||
"Can't create offscreen surface");
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
return JNI_TRUE;
|
||||
#endif /* !HEADLESS */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Class: sun_java2d_x11_X11SurfaceData
|
||||
* Method: initSurface
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_java2d_x11_X11SurfaceData_initSurface(JNIEnv *env, jclass xsd,
|
||||
jint depth,
|
||||
jint width, jint height,
|
||||
jlong drawable)
|
||||
{
|
||||
#ifndef HEADLESS
|
||||
X11SDOps *xsdo = X11SurfaceData_GetOps(env, xsd);
|
||||
if (xsdo == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (xsdo->configData->awt_cmap == (Colormap)NULL) {
|
||||
awtJNI_CreateColorData(env, xsdo->configData, 1);
|
||||
}
|
||||
/* color_data will be initialized in awtJNI_CreateColorData for
|
||||
8-bit visuals */
|
||||
xsdo->cData = xsdo->configData->color_data;
|
||||
|
||||
XShared_initSurface(env, xsdo, depth, width, height, drawable);
|
||||
xsdo->xrPic = NULL;
|
||||
#endif /* !HEADLESS */
|
||||
}
|
||||
|
||||
|
@ -718,7 +755,7 @@ jboolean X11SD_CachedXImageFits(jint width, jint height, jint depth,
|
|||
}
|
||||
#endif /* MITSHM */
|
||||
|
||||
static jint X11SD_InitWindow(JNIEnv *env, X11SDOps *xsdo)
|
||||
jint X11SD_InitWindow(JNIEnv *env, X11SDOps *xsdo)
|
||||
{
|
||||
if (xsdo->isPixmap == JNI_TRUE) {
|
||||
return SD_FAILURE;
|
||||
|
@ -1568,7 +1605,7 @@ X11SD_ReleasePixmapWithBg(JNIEnv *env, X11SDOps *xsdo)
|
|||
* Signature: (I)J
|
||||
*/
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_sun_java2d_x11_X11SurfaceData_XCreateGC
|
||||
Java_sun_java2d_x11_XSurfaceData_XCreateGC
|
||||
(JNIEnv *env, jclass xsd, jlong pXSData)
|
||||
{
|
||||
jlong ret;
|
||||
|
@ -1598,7 +1635,7 @@ Java_sun_java2d_x11_X11SurfaceData_XCreateGC
|
|||
* Signature: (JIIIILsun/java2d/pipe/Region;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_java2d_x11_X11SurfaceData_XResetClip
|
||||
Java_sun_java2d_x11_XSurfaceData_XResetClip
|
||||
(JNIEnv *env, jclass xsd, jlong xgc)
|
||||
{
|
||||
#ifndef HEADLESS
|
||||
|
@ -1613,7 +1650,7 @@ Java_sun_java2d_x11_X11SurfaceData_XResetClip
|
|||
* Signature: (JIIIILsun/java2d/pipe/Region;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_java2d_x11_X11SurfaceData_XSetClip
|
||||
Java_sun_java2d_x11_XSurfaceData_XSetClip
|
||||
(JNIEnv *env, jclass xsd, jlong xgc,
|
||||
jint x1, jint y1, jint x2, jint y2,
|
||||
jobject complexclip)
|
||||
|
@ -1688,7 +1725,7 @@ Java_sun_java2d_x11_X11SurfaceData_XSetForeground
|
|||
* Signature: (JZ)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_java2d_x11_X11SurfaceData_XSetGraphicsExposures
|
||||
Java_sun_java2d_x11_XSurfaceData_XSetGraphicsExposures
|
||||
(JNIEnv *env, jclass xsd, jlong xgc, jboolean needExposures)
|
||||
{
|
||||
#ifndef HEADLESS
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
|
||||
#include <jdga.h>
|
||||
|
||||
#include <X11/extensions/Xrender.h>
|
||||
|
||||
/**
|
||||
* This include file contains support declarations for loops using the
|
||||
* X11 extended SurfaceData interface to talk to an X11 drawable from
|
||||
|
@ -110,6 +112,7 @@ struct _X11SDOps {
|
|||
jboolean isBgInitialized; /* whether the bg pixel is valid */
|
||||
jint pmWidth; /* width, height of the */
|
||||
jint pmHeight; /* pixmap */
|
||||
Picture xrPic;
|
||||
#ifdef MITSHM
|
||||
ShmPixmapData shmPMData; /* data for switching between shm/nonshm pixmaps*/
|
||||
#endif /* MITSHM */
|
||||
|
@ -136,6 +139,9 @@ void X11SD_DisposeXImage(XImage * image);
|
|||
void X11SD_DirectRenderNotify(JNIEnv *env, X11SDOps *xsdo);
|
||||
#endif /* !HEADLESS */
|
||||
|
||||
jboolean XShared_initIDs(JNIEnv *env, jboolean allowShmPixmaps);
|
||||
jboolean XShared_initSurface(JNIEnv *env, X11SDOps *xsdo, jint depth, jint width, jint height, jlong drawable);
|
||||
|
||||
/*
|
||||
* This function returns a pointer to a native X11SDOps structure
|
||||
* for accessing the indicated X11 SurfaceData Java object. It
|
||||
|
|
784
jdk/src/solaris/native/sun/java2d/x11/XRBackendNative.c
Normal file
784
jdk/src/solaris/native/sun/java2d/x11/XRBackendNative.c
Normal file
|
@ -0,0 +1,784 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "X11SurfaceData.h"
|
||||
#include <jni.h>
|
||||
#include <math.h>
|
||||
#include "Region.h"
|
||||
#include "fontscalerdefs.h"
|
||||
|
||||
#include <X11/extensions/Xrender.h>
|
||||
|
||||
#ifndef X_RenderCreateLinearGradient
|
||||
typedef struct _XLinearGradient {
|
||||
XPointFixed p1;
|
||||
XPointFixed p2;
|
||||
} XLinearGradient;
|
||||
#endif
|
||||
|
||||
#ifndef X_RenderCreateRadialGradient
|
||||
typedef struct _XCircle {
|
||||
XFixed x;
|
||||
XFixed y;
|
||||
XFixed radius;
|
||||
} XCircle;
|
||||
|
||||
typedef struct _XRadialGradient {
|
||||
XCircle inner;
|
||||
XCircle outer;
|
||||
} XRadialGradient;
|
||||
#endif
|
||||
|
||||
#ifdef __solaris__
|
||||
/* Solaris 10 will not have these symbols at runtime */
|
||||
#include <dlfcn.h>
|
||||
#include <link.h>
|
||||
|
||||
typedef Picture (*XRenderCreateLinearGradientFuncType)
|
||||
(Display *dpy,
|
||||
const XLinearGradient *gradient,
|
||||
const XFixed *stops,
|
||||
const XRenderColor *colors,
|
||||
int nstops);
|
||||
|
||||
typedef Picture (*XRenderCreateRadialGradientFuncType)
|
||||
(Display *dpy,
|
||||
const XRadialGradient *gradient,
|
||||
const XFixed *stops,
|
||||
const XRenderColor *colors,
|
||||
int nstops);
|
||||
|
||||
static
|
||||
XRenderCreateLinearGradientFuncType XRenderCreateLinearGradientFunc = NULL;
|
||||
static
|
||||
XRenderCreateRadialGradientFuncType XRenderCreateRadialGradientFunc = NULL;
|
||||
#endif
|
||||
|
||||
#define BUILD_TRANSFORM_MATRIX(TRANSFORM, M00, M01, M02, M10, M11, M12) \
|
||||
{ \
|
||||
TRANSFORM.matrix[0][0] = M00; \
|
||||
TRANSFORM.matrix[0][1] = M01; \
|
||||
TRANSFORM.matrix[0][2] = M02; \
|
||||
TRANSFORM.matrix[1][0] = M10; \
|
||||
TRANSFORM.matrix[1][1] = M11; \
|
||||
TRANSFORM.matrix[1][2] = M12; \
|
||||
TRANSFORM.matrix[2][0] = 0; \
|
||||
TRANSFORM.matrix[2][1] = 0; \
|
||||
TRANSFORM.matrix[2][2] = 1<<16; \
|
||||
}
|
||||
|
||||
|
||||
static jboolean IsXRenderAvailable() {
|
||||
|
||||
void *xrenderlib;
|
||||
|
||||
int major_opcode, first_event, first_error;
|
||||
|
||||
if (!XQueryExtension(awt_display, "RENDER",
|
||||
&major_opcode, &first_event, &first_error)) {
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
#ifdef __solaris__
|
||||
xrenderlib = dlopen("libXrender.so",RTLD_GLOBAL|RTLD_LAZY);
|
||||
if (xrenderlib != NULL) {
|
||||
|
||||
XRenderCreateLinearGradientFunc =
|
||||
(XRenderCreateLinearGradientFuncType)
|
||||
dlsym(xrenderlib, "XRenderCreateLinearGradient");
|
||||
|
||||
XRenderCreateRadialGradientFunc =
|
||||
(XRenderCreateRadialGradientFuncType)
|
||||
dlsym(xrenderlib, "XRenderCreateRadialGradient");
|
||||
|
||||
if (XRenderCreateLinearGradientFunc == NULL ||
|
||||
XRenderCreateRadialGradientFunc == NULL)
|
||||
{
|
||||
dlclose(xrenderlib);
|
||||
return JNI_FALSE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return JNI_TRUE;
|
||||
}
|
||||
/*
|
||||
* Class: sun_awt_X11GraphicsEnvironment
|
||||
* Method: initGLX
|
||||
* Signature: ()Z
|
||||
*/
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_sun_awt_X11GraphicsEnvironment_initXRender
|
||||
(JNIEnv *env, jclass x11ge)
|
||||
{
|
||||
#ifndef HEADLESS
|
||||
static jboolean xrenderAvailable = JNI_FALSE;
|
||||
static jboolean firstTime = JNI_TRUE;
|
||||
|
||||
if (firstTime) {
|
||||
AWT_LOCK();
|
||||
xrenderAvailable = IsXRenderAvailable();
|
||||
AWT_UNLOCK();
|
||||
firstTime = JNI_FALSE;
|
||||
}
|
||||
return xrenderAvailable;
|
||||
#else
|
||||
return JNI_FALSE;
|
||||
#endif /* !HEADLESS */
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_java2d_xr_XRBackendNative_initIDs(JNIEnv *env, jclass cls) {
|
||||
char *maskData;
|
||||
XImage* defaultImg;
|
||||
jfieldID maskImgID;
|
||||
jlong fmt8 =
|
||||
ptr_to_jlong(XRenderFindStandardFormat(awt_display, PictStandardA8));
|
||||
jlong fmt32 =
|
||||
ptr_to_jlong(XRenderFindStandardFormat(awt_display, PictStandardARGB32));
|
||||
jfieldID a8ID = (*env)->GetStaticFieldID(env, cls, "FMTPTR_A8", "J");
|
||||
jfieldID argb32ID = (*env)->GetStaticFieldID(env, cls, "FMTPTR_ARGB32", "J");
|
||||
|
||||
(*env)->SetStaticLongField(env, cls, a8ID, fmt8);
|
||||
(*env)->SetStaticLongField(env, cls, argb32ID, fmt32);
|
||||
|
||||
maskData = (char *) malloc(32*32);
|
||||
if (maskData == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
defaultImg = XCreateImage(awt_display, NULL, 8, ZPixmap, 0, maskData, 32, 32, 8, 0);
|
||||
defaultImg->data = maskData; //required?
|
||||
maskImgID = (*env)->GetStaticFieldID(env, cls, "MASK_XIMG", "J");
|
||||
(*env)->SetStaticLongField(env, cls, maskImgID, ptr_to_jlong(defaultImg));
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_java2d_xr_XRBackendNative_freeGC
|
||||
(JNIEnv *env, jobject this, jlong gc) {
|
||||
XFreeGC(awt_display, (GC) jlong_to_ptr(gc));
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_sun_java2d_xr_XRBackendNative_createGC
|
||||
(JNIEnv *env, jobject this, jint drawable) {
|
||||
GC xgc = XCreateGC(awt_display, (Drawable) drawable, 0L, NULL);
|
||||
return ptr_to_jlong(xgc);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_java2d_xr_XRBackendNative_createPixmap(JNIEnv *env, jobject this,
|
||||
jint drawable, jint depth,
|
||||
jint width, jint height) {
|
||||
return (jint) XCreatePixmap(awt_display, (Drawable) drawable,
|
||||
width, height, depth);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_java2d_xr_XRBackendNative_createPictureNative
|
||||
(JNIEnv *env, jclass cls, jint drawable, jlong formatPtr) {
|
||||
XRenderPictureAttributes pict_attr;
|
||||
return XRenderCreatePicture(awt_display, (Drawable) drawable,
|
||||
(XRenderPictFormat *) jlong_to_ptr(formatPtr),
|
||||
0, &pict_attr);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_java2d_xr_XRBackendNative_freePicture
|
||||
(JNIEnv *env, jobject this, jint picture) {
|
||||
XRenderFreePicture(awt_display, (Picture) picture);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_java2d_xr_XRBackendNative_freePixmap
|
||||
(JNIEnv *env, jobject this, jint pixmap) {
|
||||
XFreePixmap(awt_display, (Pixmap) pixmap);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_java2d_xr_XRBackendNative_setPictureRepeat
|
||||
(JNIEnv *env, jobject this, jint picture, jint repeat) {
|
||||
XRenderPictureAttributes pict_attr;
|
||||
pict_attr.repeat = repeat;
|
||||
XRenderChangePicture (awt_display, (Picture) picture, CPRepeat, &pict_attr);
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_java2d_xr_XRBackendNative_setGCExposures
|
||||
(JNIEnv *env, jobject this, jlong gc, jboolean exposure) {
|
||||
XSetGraphicsExposures(awt_display,
|
||||
(GC) jlong_to_ptr(gc), exposure ? True : False); //TODO: ????
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_java2d_xr_XRBackendNative_setGCForeground
|
||||
(JNIEnv *env, jobject this, jlong gc, jint pixel) {
|
||||
XSetForeground(awt_display, (GC) jlong_to_ptr(gc), (unsigned long) pixel);
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_java2d_xr_XRBackendNative_copyArea
|
||||
(JNIEnv *env, jobject this, jint src, jint dst, jlong gc,
|
||||
jint srcx, jint srcy, jint width, jint height, jint dstx, jint dsty) {
|
||||
XCopyArea(awt_display, (Drawable) src, (Drawable) dst,
|
||||
(GC) jlong_to_ptr(gc), srcx, srcy, width, height, dstx, dsty);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_java2d_xr_XRBackendNative_renderComposite
|
||||
(JNIEnv *env, jobject this, jbyte op, jint src, jint mask, jint dst,
|
||||
jint srcX, jint srcY, jint maskX, jint maskY,
|
||||
jint dstX, jint dstY, jint width, jint height) {
|
||||
XRenderComposite (awt_display, op,
|
||||
(Picture)src, (Picture)mask, (Picture)dst,
|
||||
srcX, srcY, maskX, maskY, dstX, dstY, width, height);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_java2d_xr_XRBackendNative_renderRectangle
|
||||
(JNIEnv *env, jobject this, jint dst, jbyte op,
|
||||
jshort red, jshort green, jshort blue, jshort alpha,
|
||||
jint x, jint y, jint width, jint height) {
|
||||
XRenderColor color;
|
||||
color.alpha = alpha;
|
||||
color.red = red;
|
||||
color.green = green;
|
||||
color.blue = blue;
|
||||
XRenderFillRectangle(awt_display, op, (Picture) dst, &color,
|
||||
x, y, width, height);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_java2d_xr_XRBackendNative_XRenderRectanglesNative
|
||||
(JNIEnv *env, jclass xsd, jint dst, jbyte op,
|
||||
jshort red, jshort green, jshort blue, jshort alpha,
|
||||
jintArray rectArray, jint rectCnt) {
|
||||
int i;
|
||||
jint* rects;
|
||||
XRectangle *xRects;
|
||||
XRectangle sRects[256];
|
||||
|
||||
XRenderColor color;
|
||||
color.alpha = alpha;
|
||||
color.red = red;
|
||||
color.green = green;
|
||||
color.blue = blue;
|
||||
|
||||
if (rectCnt <= 256) {
|
||||
xRects = &sRects[0];
|
||||
} else {
|
||||
xRects = (XRectangle *) malloc(sizeof(XRectangle) * rectCnt);
|
||||
if (xRects == NULL) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ((rects = (jint *) (*env)->GetPrimitiveArrayCritical(env, rectArray, NULL)) == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i=0; i < rectCnt; i++) {
|
||||
xRects[i].x = rects[i*4 + 0];
|
||||
xRects[i].y = rects[i*4 + 1];
|
||||
xRects[i].width = rects[i*4 + 2];
|
||||
xRects[i].height = rects[i*4 + 3];
|
||||
}
|
||||
|
||||
XRenderFillRectangles(awt_display, op,
|
||||
(Picture) dst, &color, xRects, rectCnt);
|
||||
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, rectArray, rects, JNI_ABORT);
|
||||
if (xRects != &sRects[0]) {
|
||||
free(xRects);
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_java2d_xr_XRBackendNative_XRSetTransformNative
|
||||
(JNIEnv *env, jclass xsd, jint pic,
|
||||
jint m00, jint m01, jint m02, jint m10, jint m11, jint m12) {
|
||||
|
||||
XTransform tr;
|
||||
BUILD_TRANSFORM_MATRIX(tr, m00, m01, m02, m10, m11, m12);
|
||||
XRenderSetPictureTransform (awt_display, (Picture) pic, &tr);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_java2d_xr_XRBackendNative_XRCreateLinearGradientPaintNative
|
||||
(JNIEnv *env, jclass xsd, jfloatArray fractionsArray,
|
||||
jshortArray pixelsArray, jint x1, jint y1, jint x2, jint y2,
|
||||
jint numStops, jint repeat,
|
||||
jint m00, jint m01, jint m02, jint m10, jint m11, jint m12) {
|
||||
jint i;
|
||||
jshort* pixels;
|
||||
jfloat* fractions;
|
||||
XTransform tr;
|
||||
XRenderPictureAttributes pict_attr;
|
||||
Picture gradient = 0;
|
||||
XRenderColor *colors;
|
||||
XFixed *stops;
|
||||
XLinearGradient grad;
|
||||
|
||||
if ((pixels = (jshort *)
|
||||
(*env)->GetPrimitiveArrayCritical(env, pixelsArray, NULL)) == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if ((fractions = (jfloat *)
|
||||
(*env)->GetPrimitiveArrayCritical(env, fractionsArray, NULL)) == NULL) {
|
||||
(*env)->ReleasePrimitiveArrayCritical(env,
|
||||
pixelsArray, pixels, JNI_ABORT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
grad.p1.x = x1;
|
||||
grad.p1.y = y1;
|
||||
grad.p2.x = x2;
|
||||
grad.p2.y = y2;
|
||||
|
||||
/*TODO optimized & malloc check*/
|
||||
colors = (XRenderColor *) malloc(numStops * sizeof(XRenderColor));
|
||||
stops = (XFixed *) malloc(numStops * sizeof(XFixed));
|
||||
|
||||
for (i=0; i < numStops; i++) {
|
||||
stops[i] = XDoubleToFixed(fractions[i]);
|
||||
colors[i].alpha = pixels[i*4 + 0];
|
||||
colors[i].red = pixels[i*4 + 1];
|
||||
colors[i].green = pixels[i*4 + 2];
|
||||
colors[i].blue = pixels[i*4 + 3];
|
||||
}
|
||||
#ifdef __solaris__
|
||||
if (XRenderCreateLinearGradientFunc!=NULL) {
|
||||
gradient = (*XRenderCreateLinearGradientFunc)(awt_display, &grad, stops, colors, numStops);
|
||||
}
|
||||
#else
|
||||
gradient = XRenderCreateLinearGradient(awt_display, &grad, stops, colors, numStops);
|
||||
#endif
|
||||
free(colors);
|
||||
free(stops);
|
||||
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, pixelsArray, pixels, JNI_ABORT);
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, fractionsArray, fractions, JNI_ABORT);
|
||||
|
||||
if (gradient != 0) {
|
||||
BUILD_TRANSFORM_MATRIX(tr, m00, m01, m02, m10, m11, m12);
|
||||
XRenderSetPictureTransform (awt_display, gradient, &tr);
|
||||
pict_attr.repeat = repeat;
|
||||
XRenderChangePicture (awt_display, gradient, CPRepeat, &pict_attr);
|
||||
}
|
||||
|
||||
return (jint) gradient;
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_java2d_xr_XRBackendNative_XRCreateRadialGradientPaintNative
|
||||
(JNIEnv *env, jclass xsd, jfloatArray fractionsArray,
|
||||
jshortArray pixelsArray, jint numStops,
|
||||
jint innerRadius, jint outerRadius, jint repeat,
|
||||
jint m00, jint m01, jint m02, jint m10, jint m11, jint m12) {
|
||||
jint i;
|
||||
jshort* pixels;
|
||||
jfloat* fractions;
|
||||
XTransform tr;
|
||||
XRenderPictureAttributes pict_attr;
|
||||
Picture gradient = 0;
|
||||
XRenderColor *colors;
|
||||
XFixed *stops;
|
||||
XRadialGradient grad;
|
||||
|
||||
|
||||
if ((pixels =
|
||||
(jshort *)(*env)->GetPrimitiveArrayCritical(env, pixelsArray, NULL)) == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if ((fractions = (jfloat *)
|
||||
(*env)->GetPrimitiveArrayCritical(env, fractionsArray, NULL)) == NULL) {
|
||||
(*env)->ReleasePrimitiveArrayCritical(env,
|
||||
pixelsArray, pixels, JNI_ABORT);
|
||||
return -1; //TODO release pixels first
|
||||
}
|
||||
|
||||
grad.inner.x = 0;
|
||||
grad.inner.y = 0;
|
||||
grad.inner.radius = innerRadius;
|
||||
grad.outer.x = 0;
|
||||
grad.outer.y = 0;
|
||||
grad.outer.radius = outerRadius;
|
||||
|
||||
/*TODO optimized & malloc check*/
|
||||
colors = (XRenderColor *) malloc(numStops * sizeof(XRenderColor));
|
||||
stops = (XFixed *) malloc(numStops * sizeof(XFixed));
|
||||
|
||||
for (i=0; i < numStops; i++) {
|
||||
stops[i] = XDoubleToFixed(fractions[i]);
|
||||
colors[i].alpha = pixels[i*4 + 0];
|
||||
colors[i].red = pixels[i*4 + 1];
|
||||
colors[i].green = pixels[i*4 + 2];
|
||||
colors[i].blue = pixels[i*4 + 3];
|
||||
}
|
||||
#ifdef __solaris__
|
||||
if (XRenderCreateRadialGradientFunc != NULL) {
|
||||
gradient = (jint) (*XRenderCreateRadialGradientFunc)(awt_display, &grad, stops, colors, numStops);
|
||||
}
|
||||
#else
|
||||
gradient = (jint) XRenderCreateRadialGradient(awt_display, &grad, stops, colors, numStops);
|
||||
#endif
|
||||
free(colors);
|
||||
free(stops);
|
||||
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, pixelsArray, pixels, JNI_ABORT);
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, fractionsArray, fractions, JNI_ABORT);
|
||||
|
||||
|
||||
if (gradient != 0) {
|
||||
BUILD_TRANSFORM_MATRIX(tr, m00, m01, m02, m10, m11, m12);
|
||||
XRenderSetPictureTransform (awt_display, gradient, &tr);
|
||||
pict_attr.repeat = repeat;
|
||||
XRenderChangePicture (awt_display, gradient, CPRepeat, &pict_attr);
|
||||
}
|
||||
|
||||
return (jint) gradient;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_java2d_xr_XRBackendNative_setFilter
|
||||
(JNIEnv *env, jobject this, jint picture, jint filter) {
|
||||
|
||||
char * filterName = "fast";
|
||||
|
||||
switch(filter) {
|
||||
case 0:
|
||||
filterName = "fast";
|
||||
break;
|
||||
|
||||
case 1:
|
||||
filterName = "good";
|
||||
break;
|
||||
|
||||
case 2:
|
||||
filterName = "best";
|
||||
break;
|
||||
}
|
||||
|
||||
XRenderSetPictureFilter(awt_display, (Picture) picture, filterName, NULL, 0);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_java2d_xr_XRBackendNative_XRSetClipNative
|
||||
(JNIEnv *env, jclass xsd, jlong dst,
|
||||
jint x1, jint y1, jint x2, jint y2,
|
||||
jobject complexclip, jboolean isGC)
|
||||
{
|
||||
int numrects;
|
||||
XRectangle rects[256];
|
||||
XRectangle *pRect = rects;
|
||||
|
||||
numrects = RegionToYXBandedRectangles(env,
|
||||
x1, y1, x2, y2, complexclip,
|
||||
&pRect, 256);
|
||||
|
||||
if (isGC == JNI_TRUE) {
|
||||
if (dst != (jlong) 0) {
|
||||
XSetClipRectangles(awt_display, (GC) jlong_to_ptr(dst), 0, 0, pRect, numrects, YXBanded);
|
||||
}
|
||||
} else {
|
||||
XRenderSetPictureClipRectangles (awt_display, (Picture) dst, 0, 0, pRect, numrects);
|
||||
}
|
||||
|
||||
if (pRect != rects) {
|
||||
free(pRect);
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_java2d_xr_XRBackendNative_putMaskNative
|
||||
(JNIEnv *env, jclass cls, jint drawable, jlong gc, jbyteArray imageData,
|
||||
jint sx, jint sy, jint dx, jint dy, jint width, jint height,
|
||||
jint maskOff, jint maskScan, jfloat ea, jlong imgPtr) {
|
||||
|
||||
int line, pix;
|
||||
char *mask;
|
||||
char *defaultData;
|
||||
XImage *defaultImg, *img;
|
||||
jboolean imageFits;
|
||||
|
||||
if ((mask = (char *)
|
||||
(*env)->GetPrimitiveArrayCritical(env, imageData, NULL)) == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
defaultImg = (XImage *) jlong_to_ptr(imgPtr);
|
||||
|
||||
if (ea != 1.0f) {
|
||||
for (line=0; line < height; line++) {
|
||||
for (pix=0; pix < width; pix++) {
|
||||
int index = maskScan*line + pix + maskOff;
|
||||
mask[index] = (((unsigned char) mask[index])*ea);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 1. If existing XImage and supplied buffer match, only adjust the data pointer
|
||||
* 2. If existing XImage is large enough to hold the data but does not match in
|
||||
* scan the data is copied to fit the XImage.
|
||||
* 3. If data is larger than the existing XImage a new temporary XImage is
|
||||
* allocated.
|
||||
* The default XImage is optimized for the AA tiles, which are currently 32x32.
|
||||
*/
|
||||
defaultData = defaultImg->data;
|
||||
img = defaultImg;
|
||||
imageFits = defaultImg->width >= width && defaultImg->height >= height;
|
||||
|
||||
if (imageFits &&
|
||||
maskOff == defaultImg->xoffset && maskScan == defaultImg->bytes_per_line) {
|
||||
defaultImg->data = mask;
|
||||
} else {
|
||||
if (imageFits) {
|
||||
for (line=0; line < height; line++) {
|
||||
for (pix=0; pix < width; pix++) {
|
||||
img->data[line*img->bytes_per_line + pix] =
|
||||
(unsigned char) (mask[maskScan*line + pix + maskOff]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
img = XCreateImage(awt_display, NULL, 8, ZPixmap,
|
||||
maskOff, mask, maskScan, height, 8, 0);
|
||||
}
|
||||
}
|
||||
|
||||
XPutImage(awt_display, (Pixmap) drawable, (GC) jlong_to_ptr(gc),
|
||||
img, 0, 0, 0, 0, width, height);
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, imageData, mask, JNI_ABORT);
|
||||
|
||||
if (img != defaultImg) {
|
||||
img->data = NULL;
|
||||
XDestroyImage(img);
|
||||
}
|
||||
defaultImg->data = defaultData;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_java2d_xr_XRBackendNative_XRAddGlyphsNative
|
||||
(JNIEnv *env, jclass cls, jint glyphSet,
|
||||
jlongArray glyphInfoPtrsArray, jint glyphCnt,
|
||||
jbyteArray pixelDataArray, int pixelDataLength) {
|
||||
jlong *glyphInfoPtrs;
|
||||
unsigned char *pixelData;
|
||||
int i;
|
||||
|
||||
XGlyphInfo *xginfo = (XGlyphInfo *) malloc(sizeof(XGlyphInfo) * glyphCnt);
|
||||
Glyph *gid = (Glyph *) malloc(sizeof(Glyph) * glyphCnt);
|
||||
|
||||
if (xginfo == NULL || gid == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((glyphInfoPtrs = (jlong *) (*env)->GetPrimitiveArrayCritical(env, glyphInfoPtrsArray, NULL)) == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((pixelData = (unsigned char *)
|
||||
(*env)->GetPrimitiveArrayCritical(env, pixelDataArray, NULL)) == NULL) {
|
||||
(*env)->ReleasePrimitiveArrayCritical(env,
|
||||
glyphInfoPtrsArray, glyphInfoPtrs, JNI_ABORT);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i=0; i < glyphCnt; i++) {
|
||||
GlyphInfo *jginfo = (GlyphInfo *) jlong_to_ptr(glyphInfoPtrs[i]);
|
||||
|
||||
gid[i] = (Glyph) (0xffffffff & ((unsigned int) jginfo->cellInfo));
|
||||
xginfo[i].x = (-jginfo->topLeftX);
|
||||
xginfo[i].y = (-jginfo->topLeftY);
|
||||
xginfo[i].width = jginfo->width;
|
||||
xginfo[i].height = jginfo->height;
|
||||
xginfo[i].xOff = round(jginfo->advanceX);
|
||||
xginfo[i].yOff = round(jginfo->advanceY);
|
||||
}
|
||||
|
||||
XRenderAddGlyphs(awt_display, glyphSet, &gid[0], &xginfo[0], glyphCnt,
|
||||
pixelData, pixelDataLength);
|
||||
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, glyphInfoPtrsArray, glyphInfoPtrs, JNI_ABORT);
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, pixelDataArray, pixelData, JNI_ABORT);
|
||||
|
||||
free(xginfo);
|
||||
free(gid);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_java2d_xr_XRBackendNative_XRFreeGlyphsNative
|
||||
(JNIEnv *env, jclass cls, jint glyphSet, jintArray gidArray, jint glyphCnt) {
|
||||
jint *gids;
|
||||
int i;
|
||||
|
||||
if ((gids = (jint *) (*env)->GetPrimitiveArrayCritical(env, gidArray, NULL)) == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
XRenderFreeGlyphs (awt_display, (GlyphSet) glyphSet, (Glyph *) gids, glyphCnt);
|
||||
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, gidArray, gids, JNI_ABORT);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_java2d_xr_XRBackendNative_XRenderCreateGlyphSetNative
|
||||
(JNIEnv *env, jclass cls, jlong format) {
|
||||
return XRenderCreateGlyphSet(awt_display, (XRenderPictFormat *) jlong_to_ptr(format));
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_java2d_xr_XRBackendNative_XRenderCompositeTextNative
|
||||
(JNIEnv *env, jclass cls, jint op, jint src, jint dst, jlong maskFmt,
|
||||
jintArray eltArray, jintArray glyphIDArray, jint eltCnt, jint glyphCnt) {
|
||||
jint i;
|
||||
jint *ids;
|
||||
jint *elts;
|
||||
XGlyphElt32 *xelts;
|
||||
Glyph *xids;
|
||||
XGlyphElt32 selts[24];
|
||||
Glyph sids[256];
|
||||
int charCnt = 0;
|
||||
|
||||
if (eltCnt <= 24) {
|
||||
xelts = &selts[0];
|
||||
}else {
|
||||
xelts = (XGlyphElt32 *) malloc(sizeof(XGlyphElt32) * eltCnt);
|
||||
}
|
||||
|
||||
if (glyphCnt <= 256) {
|
||||
xids = &sids[0];
|
||||
}else {
|
||||
xids = (Glyph *) malloc(sizeof(Glyph) * glyphCnt);
|
||||
}
|
||||
|
||||
if ((ids = (jint *) (*env)->GetPrimitiveArrayCritical(env, glyphIDArray, NULL)) == NULL) {
|
||||
return;
|
||||
}
|
||||
if ((elts = (jint *)
|
||||
(*env)->GetPrimitiveArrayCritical(env, eltArray, NULL)) == NULL) {
|
||||
(*env)->ReleasePrimitiveArrayCritical(env,
|
||||
glyphIDArray, ids, JNI_ABORT);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i=0; i < glyphCnt; i++) {
|
||||
xids[i] = (Glyph) ids[i];
|
||||
}
|
||||
|
||||
for (i=0; i < eltCnt; i++) {
|
||||
xelts[i].nchars = elts[i*4 + 0];
|
||||
xelts[i].xOff = elts[i*4 + 1];
|
||||
xelts[i].yOff = elts[i*4 + 2];
|
||||
xelts[i].glyphset = (GlyphSet) elts[i*4 + 3];
|
||||
xelts[i].chars = (unsigned int *) &xids[charCnt];
|
||||
|
||||
charCnt += xelts[i].nchars;
|
||||
}
|
||||
|
||||
XRenderCompositeText32(awt_display, op, (Picture) src, (Picture) dst,
|
||||
(XRenderPictFormat *) jlong_to_ptr(maskFmt),
|
||||
0, 0, 0, 0, xelts, eltCnt);
|
||||
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, glyphIDArray, ids, JNI_ABORT);
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, eltArray, elts, JNI_ABORT);
|
||||
|
||||
if (xelts != &selts[0]) {
|
||||
free(xelts);
|
||||
}
|
||||
|
||||
if (xids != &sids[0]) {
|
||||
free(xids);
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_java2d_xr_XRBackendNative_setGCMode
|
||||
(JNIEnv *env, jobject this, jlong gc, jboolean copy) {
|
||||
GC xgc = (GC) jlong_to_ptr(gc);
|
||||
|
||||
if (copy == JNI_TRUE) {
|
||||
XSetFunction(awt_display, xgc, GXcopy);
|
||||
} else {
|
||||
XSetFunction(awt_display, xgc, GXxor);
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_java2d_xr_XRBackendNative_GCRectanglesNative
|
||||
(JNIEnv *env, jclass xsd, jint dst, jlong gc,
|
||||
jintArray rectArray, jint rectCnt) {
|
||||
int i;
|
||||
jint* rects;
|
||||
XRectangle *xRects;
|
||||
XRectangle sRects[256];
|
||||
|
||||
if (rectCnt <= 256) {
|
||||
xRects = &sRects[0];
|
||||
} else {
|
||||
xRects = (XRectangle *) malloc(sizeof(XRectangle) * rectCnt);
|
||||
if (xRects == NULL) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ((rects = (jint *) (*env)->GetPrimitiveArrayCritical(env, rectArray, NULL)) == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i=0; i < rectCnt; i++) {
|
||||
xRects[i].x = rects[i*4 + 0];
|
||||
xRects[i].y = rects[i*4 + 1];
|
||||
xRects[i].width = rects[i*4 + 2];
|
||||
xRects[i].height = rects[i*4 + 3];
|
||||
}
|
||||
|
||||
XFillRectangles(awt_display, (Drawable) dst, (GC) jlong_to_ptr(gc), xRects, rectCnt);
|
||||
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, rectArray, rects, JNI_ABORT);
|
||||
if (xRects != &sRects[0]) {
|
||||
free(xRects);
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_java2d_xr_XRBackendNative_renderCompositeTrapezoidsNative
|
||||
(JNIEnv *env, jclass cls, jbyte op, jint src, jlong maskFmt,
|
||||
jint dst, jint srcX, jint srcY, jintArray trapArray) {
|
||||
jint *traps;
|
||||
|
||||
if ((traps = (jint *) (*env)->GetPrimitiveArrayCritical(env, trapArray, NULL)) == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
XRenderCompositeTrapezoids(awt_display, op, (Picture) src, (Picture) dst,
|
||||
(XRenderPictFormat *) jlong_to_ptr(maskFmt),
|
||||
srcX, srcY, (XTrapezoid *) (traps+5), traps[0]);
|
||||
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, trapArray, traps, JNI_ABORT);
|
||||
}
|
116
jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.c
Normal file
116
jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.c
Normal file
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "GraphicsPrimitiveMgr.h"
|
||||
#include "Region.h"
|
||||
#include "Trace.h"
|
||||
#include "X11SurfaceData.h"
|
||||
|
||||
/*#include <xcb/xcb.h>*/
|
||||
#include <Xrender.h>
|
||||
|
||||
#ifndef RepeatNone /* added in 0.10 */
|
||||
#define RepeatNone 0
|
||||
#define RepeatNormal 1
|
||||
#define RepeatPad 2
|
||||
#define RepeatReflect 3
|
||||
#endif
|
||||
|
||||
|
||||
#include <sys/uio.h>
|
||||
#include <dlfcn.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#ifndef HEADLESS
|
||||
jfieldID pictID;
|
||||
jfieldID xidID;
|
||||
jfieldID blitMaskPMID;
|
||||
jfieldID blitMaskPictID;
|
||||
#endif /* !HEADLESS */
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_java2d_xr_XRSurfaceData_initXRPicture(JNIEnv *env, jobject xsd,
|
||||
jlong pXSData,
|
||||
jint pictFormat)
|
||||
{
|
||||
#ifndef HEADLESS
|
||||
|
||||
X11SDOps *xsdo;
|
||||
XRenderPictFormat *fmt;
|
||||
|
||||
J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_initXRender");
|
||||
|
||||
xsdo = (X11SDOps *) jlong_to_ptr(pXSData);
|
||||
if (xsdo == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (xsdo->xrPic == None) {
|
||||
XRenderPictureAttributes pict_attr;
|
||||
pict_attr.repeat = RepeatNone;
|
||||
fmt = XRenderFindStandardFormat(awt_display, pictFormat);
|
||||
xsdo->xrPic =
|
||||
XRenderCreatePicture(awt_display, xsdo->drawable, fmt,
|
||||
CPRepeat, &pict_attr);
|
||||
}
|
||||
|
||||
(*env)->SetIntField (env, xsd, pictID, xsdo->xrPic);
|
||||
(*env)->SetIntField (env, xsd, xidID, xsdo->drawable);
|
||||
#endif /* !HEADLESS */
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_java2d_xr_XRSurfaceData_initIDs(JNIEnv *env, jclass xsd)
|
||||
{
|
||||
#ifndef HEADLESS
|
||||
J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_initIDs");
|
||||
|
||||
pictID = (*env)->GetFieldID(env, xsd, "picture", "I");
|
||||
xidID = (*env)->GetFieldID(env, xsd, "xid", "I");
|
||||
|
||||
XShared_initIDs(env, JNI_FALSE);
|
||||
#endif /* !HEADLESS */
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_java2d_xr_XRSurfaceData_XRInitSurface(JNIEnv *env, jclass xsd,
|
||||
jint depth,
|
||||
jint width, jint height,
|
||||
jlong drawable, jint pictFormat)
|
||||
{
|
||||
#ifndef HEADLESS
|
||||
X11SDOps *xsdo;
|
||||
|
||||
J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_initSurface");
|
||||
|
||||
xsdo = X11SurfaceData_GetOps(env, xsd);
|
||||
if (xsdo == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
XShared_initSurface(env, xsdo, depth, width, height, drawable);
|
||||
#endif /* !HEADLESS */
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue