mirror of
https://github.com/2003scape/deep-c-rsc.git
synced 2024-03-22 05:49:51 -04:00
281 lines
11 KiB
Java
281 lines
11 KiB
Java
/*
|
|
* This file is modified by Ivan Maidanski <ivmai@ivmaisoft.com>
|
|
* Project name: JCGO-SUNAWT (http://www.ivmaisoft.com/jcgo/)
|
|
*/
|
|
|
|
/*
|
|
* @(#)X11RemoteOffScreenImage.java 1.15 03/01/23
|
|
*
|
|
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
|
|
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
|
*/
|
|
|
|
package sun.awt.motif;
|
|
|
|
import java.awt.Component;
|
|
import java.awt.Color;
|
|
import java.awt.Graphics2D;
|
|
import java.awt.GraphicsConfiguration;
|
|
import java.awt.image.BufferedImage;
|
|
import java.awt.image.ColorModel;
|
|
import java.awt.image.DataBuffer;
|
|
import java.awt.image.DirectColorModel;
|
|
import java.awt.image.PixelInterleavedSampleModel;
|
|
import java.awt.image.SampleModel;
|
|
import java.awt.image.SinglePixelPackedSampleModel;
|
|
import java.awt.image.WritableRaster;
|
|
import sun.awt.X11SurfaceData;
|
|
import sun.awt.X11SurfaceData.X11PixmapSurfaceData;
|
|
import sun.awt.image.AcceleratedOffScreenImage;
|
|
import sun.awt.image.BufImgSurfaceData;
|
|
import sun.awt.image.DataBufferNative;
|
|
import sun.awt.image.WritableRasterNative;
|
|
import sun.java2d.SunGraphics2D;
|
|
import sun.java2d.SurfaceData;
|
|
import sun.java2d.loops.CompositeType;
|
|
import sun.java2d.pipe.DrawImage;
|
|
|
|
/**
|
|
* This class extends the functionality of X11OffScreenImage by
|
|
* forcing the use of a pixmap-based surfaceData object. In
|
|
* X11OffScreenImage, the default surfaceData object is the default
|
|
* one used by BufferedImage, setup by a call to the superclass
|
|
* constructor. Acceleration is achieved by caching a version of
|
|
* the data in a pixmap and copying from that pixmap when appropriate.
|
|
* <P>
|
|
* This is sufficient for accelerating sprite-type images, which are
|
|
* rendered to infrequently but copied from often. Back buffers
|
|
* do not benefit from this acceleration since the cached copy
|
|
* would never be used. This is deemed sufficient for local X
|
|
* usage; users performing complex Java2D operations (e.g.,
|
|
* anti-aliasing, compositing, text, or anything that requires
|
|
* read-modify-write operations) would see a degradation in performance
|
|
* were we to force all operations to go through the pixmap-based
|
|
* image.
|
|
* <P>
|
|
* In the RemoteX case, however, performance is so abysmal in the
|
|
* case of double-buffering (with the back buffer living in the
|
|
* Java heap), that the advantage of speeding up the basic
|
|
* applications (i.e., those using 1.1 API or simple Swing operations,
|
|
* and thus avoiding complex Java2D read-modify-write operations)
|
|
* is judged to outweigh the possible performance loss in some
|
|
* applications from having the back buffer located in a pixmap.
|
|
* <P>
|
|
* The decision to instantiate this class (versus X11OffScreenImage)
|
|
* is based on whether we are running remotely and whether the
|
|
* user has enabled/disabled a property related to this issue:
|
|
* -Dsun.java2d.remote
|
|
*/
|
|
public class X11RemoteOffScreenImage extends X11OffScreenImage {
|
|
|
|
int bufImageTypeSw; // Cache for later BI creation
|
|
// in getSnapshot()
|
|
SurfaceData bisd; // intermediate BufImgSD for use in
|
|
// copyBackupToAccelerated
|
|
|
|
private static native void initIDs();
|
|
|
|
static {
|
|
initIDs();
|
|
}
|
|
|
|
public X11RemoteOffScreenImage(Component c, ColorModel cm, WritableRaster raster,
|
|
boolean isRasterPremultiplied)
|
|
{
|
|
super(c, cm, raster, isRasterPremultiplied, false);
|
|
bufImageTypeSw = getType();
|
|
if (!accelerationEnabled) {
|
|
return;
|
|
}
|
|
GraphicsConfiguration gc =
|
|
X11SurfaceData.getGC(c == null ? null : (MComponentPeer)c.getPeer());
|
|
initAcceleratedBackground(gc, getWidth(), getHeight());
|
|
if (surfaceDataHw != null) {
|
|
setCurrentSurfaceData(surfaceDataHw);
|
|
// this is the trick: we treat surfaceDataHw as the default
|
|
// software sd in X11OffScreenImage, this way we can use
|
|
// all of the functionality of X11OSI.
|
|
// REMIND: rename surfaceDataHw and surfaceDataSw to
|
|
// something more appropriate, i.e. sdDefault and sdCached
|
|
surfaceDataSw = surfaceDataHw;
|
|
initContents();
|
|
createNativeRaster();
|
|
}
|
|
}
|
|
|
|
private native void
|
|
setSurfaceDataNative(SurfaceData sData);
|
|
private native void
|
|
setRasterNative(WritableRaster raster);
|
|
|
|
private void setCurrentSurfaceData(SurfaceData sd) {
|
|
if (sd != surfaceData) {
|
|
surfaceData = sd; // OffScreenImage copy
|
|
setSurfaceDataNative(sd); // BufferedImage copy
|
|
}
|
|
}
|
|
|
|
public void initContents() {
|
|
Graphics2D g2 = createGraphics();
|
|
g2.clearRect(0, 0, getWidth(), getHeight());
|
|
g2.dispose();
|
|
}
|
|
|
|
/**
|
|
* Need to override this method as we don't need to check for
|
|
* the number of copies done from this image
|
|
*/
|
|
public SurfaceData getSourceSurfaceData(SurfaceData destSD,
|
|
CompositeType comp,
|
|
Color bgColor) {
|
|
if (accelerationEnabled &&
|
|
(destSD != surfaceDataHw) &&
|
|
destSurfaceAccelerated(destSD))
|
|
{
|
|
// First, we validate the pixmap sd if necessary and then return
|
|
// the appropriate surfaceData object.
|
|
|
|
validate(destSD.getDeviceConfiguration());
|
|
if (surfaceDataHw != null) {
|
|
return surfaceDataHw;
|
|
}
|
|
}
|
|
return surfaceDataSw;
|
|
}
|
|
|
|
private void createNativeRaster() {
|
|
ColorModel cm = getColorModel();
|
|
SampleModel smHw = null;
|
|
int dataType = 0;
|
|
int scanStride = getWidth();
|
|
|
|
switch (cm.getPixelSize()) {
|
|
case 8:
|
|
case 12:
|
|
// 8-bits uses PixelInterleavedSampleModel
|
|
if (cm.getPixelSize() == 8) {
|
|
dataType = DataBuffer.TYPE_BYTE;
|
|
} else {
|
|
dataType = DataBuffer.TYPE_USHORT;
|
|
}
|
|
|
|
int[] bandOffsets = new int[1];
|
|
bandOffsets[0] = 0;
|
|
smHw = new PixelInterleavedSampleModel(dataType, getWidth(),
|
|
getHeight(),
|
|
1, scanStride,
|
|
bandOffsets);
|
|
break;
|
|
|
|
// all others use SinglePixelPackedSampleModel
|
|
case 15:
|
|
case 16:
|
|
dataType = DataBuffer.TYPE_USHORT;
|
|
int[] bitMasks = new int[3];
|
|
DirectColorModel dcm = (DirectColorModel)cm;
|
|
bitMasks[0] = dcm.getRedMask();
|
|
bitMasks[1] = dcm.getGreenMask();
|
|
bitMasks[2] = dcm.getBlueMask();
|
|
smHw = new SinglePixelPackedSampleModel(dataType, getWidth(),
|
|
getHeight(), scanStride,
|
|
bitMasks);
|
|
break;
|
|
|
|
case 24:
|
|
case 32:
|
|
dataType = DataBuffer.TYPE_INT;
|
|
bitMasks = new int[3];
|
|
dcm = (DirectColorModel)cm;
|
|
bitMasks[0] = dcm.getRedMask();
|
|
bitMasks[1] = dcm.getGreenMask();
|
|
bitMasks[2] = dcm.getBlueMask();
|
|
smHw = new SinglePixelPackedSampleModel(dataType, getWidth(),
|
|
getHeight(), scanStride,
|
|
bitMasks);
|
|
break;
|
|
|
|
default:
|
|
throw new InternalError("Unsupported depth " + cm.getPixelSize());
|
|
}
|
|
DataBuffer dbn = new DataBufferNative(surfaceDataHw, dataType,
|
|
getWidth(), getHeight());
|
|
// set the native raster as a default raster of BI
|
|
setRasterNative(WritableRasterNative.createNativeRaster(smHw, dbn));
|
|
}
|
|
|
|
/**
|
|
* Returns a BufferedImage representation of this image.
|
|
* In this default method, it just returns this object.
|
|
* Platform-dependent implementations may choose to return
|
|
* something different. For example, X11RemoteOffScreenImage
|
|
* might want to return a BufferedImage that points to data current
|
|
* with its pixmap version of the image.
|
|
*/
|
|
public BufferedImage getSnapshot() {
|
|
BufferedImage bImg;
|
|
|
|
if (bufImageTypeSw > 0) {
|
|
bImg = new BufferedImage(getWidth(), getHeight(),
|
|
bufImageTypeSw);
|
|
} else {
|
|
ColorModel colormodel = getColorModel();
|
|
WritableRaster writableraster =
|
|
colormodel.createCompatibleWritableRaster(getWidth(),
|
|
getHeight());
|
|
bImg = new BufferedImage(colormodel, writableraster,
|
|
colormodel.isAlphaPremultiplied(), null);
|
|
}
|
|
|
|
Graphics2D g = bImg.createGraphics();
|
|
g.drawImage(this, 0, 0, null);
|
|
g.dispose();
|
|
return bImg;
|
|
}
|
|
|
|
protected void copyBackupToAccelerated() {
|
|
if (surfaceDataSw != null && surfaceDataHw != null &&
|
|
surfaceDataSw != surfaceDataHw) {
|
|
java.awt.Font defaultFont =
|
|
new java.awt.Font("Dialog", java.awt.Font.PLAIN, 12);
|
|
|
|
// we can't render directly from hw sd to hw sd
|
|
// as we might end up in XCopyArea with pixmaps from different
|
|
// screens. So we use a temp BI SD as a bypass:
|
|
// OSI.surfaceDataSw -> bisd -> AccOSI.surfaceDataHw
|
|
if (bisd == null) {
|
|
BufferedImage bi;
|
|
|
|
if (bufImageTypeSw > 0) {
|
|
bi = new BufferedImage(getWidth(), getHeight(),
|
|
bufImageTypeSw);
|
|
} else {
|
|
ColorModel colormodel = getColorModel();
|
|
WritableRaster writableraster =
|
|
colormodel.createCompatibleWritableRaster(getWidth(),
|
|
getHeight());
|
|
bi = new BufferedImage(colormodel, writableraster,
|
|
colormodel.isAlphaPremultiplied(), null);
|
|
}
|
|
|
|
bisd = BufImgSurfaceData.createData(bi);
|
|
}
|
|
|
|
SunGraphics2D swG2d =
|
|
new SunGraphics2D(bisd, java.awt.Color.black,
|
|
java.awt.Color.white, defaultFont);
|
|
|
|
DrawImage.renderSurfaceData(swG2d, surfaceDataSw,
|
|
(java.awt.Color)null,
|
|
0, 0, 0, 0, getWidth(), getHeight());
|
|
swG2d.dispose();
|
|
SunGraphics2D hwG2D =
|
|
new SunGraphics2D(surfaceDataHw, java.awt.Color.black,
|
|
java.awt.Color.white, defaultFont);
|
|
DrawImage.renderSurfaceData(hwG2D, bisd,
|
|
(java.awt.Color)null,
|
|
0, 0, 0, 0, getWidth(), getHeight());
|
|
hwG2D.dispose();
|
|
}
|
|
}
|
|
}
|