mirror of
https://github.com/2003scape/deep-c-rsc.git
synced 2024-03-22 05:49:51 -04:00
483 lines
19 KiB
Java
483 lines
19 KiB
Java
/*
|
|
* This file is modified by Ivan Maidanski <ivmai@ivmaisoft.com>
|
|
* Project name: JCGO-SUNAWT (http://www.ivmaisoft.com/jcgo/)
|
|
*/
|
|
|
|
/*
|
|
* @(#)Win32OffScreenSurfaceData.java 1.42 03/01/30
|
|
*
|
|
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
|
|
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
|
*/
|
|
|
|
package sun.awt.windows;
|
|
|
|
import java.awt.Color;
|
|
import java.awt.GraphicsConfiguration;
|
|
import java.awt.Image;
|
|
import java.awt.Rectangle;
|
|
import java.awt.Transparency;
|
|
import java.awt.color.ColorSpace;
|
|
import java.awt.image.BufferedImage;
|
|
import java.awt.image.ColorModel;
|
|
import java.awt.image.ComponentColorModel;
|
|
import java.awt.image.DirectColorModel;
|
|
import java.awt.image.IndexColorModel;
|
|
import java.awt.image.Raster;
|
|
|
|
import sun.awt.SunHints;
|
|
import sun.java2d.SunGraphics2D;
|
|
import sun.java2d.SurfaceData;
|
|
import sun.java2d.pipe.PixelToShapeConverter;
|
|
import sun.java2d.loops.GraphicsPrimitive;
|
|
import sun.java2d.loops.SurfaceType;
|
|
import sun.java2d.loops.RenderLoops;
|
|
import sun.awt.Win32ColorModel24;
|
|
import sun.awt.Win32GraphicsDevice;
|
|
import sun.awt.Win32GraphicsConfig;
|
|
|
|
/**
|
|
* Win32OffScreenSurfaceData
|
|
*
|
|
* This class implements a hardware-accelerated video memory surface. It uses
|
|
* a custom renderer (Win32DDRenderer) to render via DirectDraw into the
|
|
* surface and uses a custom Blit loop (Win32BlitLoops) to copy between
|
|
* two hardware-accelerated surfaces (including the screen).
|
|
*/
|
|
public class Win32OffScreenSurfaceData extends SurfaceData {
|
|
|
|
int width;
|
|
int height;
|
|
int transparency;
|
|
|
|
private GraphicsConfiguration graphicsConfig;
|
|
private Image image;
|
|
private static boolean forceDDVram;
|
|
private RenderLoops solidloops;
|
|
private static boolean d3dEnabled = true;
|
|
private boolean localD3dEnabled = true;
|
|
protected boolean d3dClippingEnabled = false;
|
|
private static boolean ddScaleEnabled = false;
|
|
private boolean ddSurfacePunted = false;
|
|
|
|
private static native void initDDraw(boolean sharing);
|
|
private static native boolean enableD3D(boolean forceD3D);
|
|
private static native void initIDs();
|
|
private static int textureBpp = 32;
|
|
static boolean directXInitialized = false;
|
|
|
|
public static void initD3D() {
|
|
if (!directXInitialized) {
|
|
boolean forceD3D = false;
|
|
directXInitialized = true;
|
|
String d3dProp = (String) java.security.AccessController.doPrivileged(
|
|
new sun.security.action.GetPropertyAction("sun.java2d.d3d"));
|
|
String d3dTexBppProp = (String) java.security.AccessController.doPrivileged(
|
|
new sun.security.action.GetPropertyAction("sun.java2d.d3dtexbpp"));
|
|
if (d3dProp != null) {
|
|
if (d3dProp.equals("true") || d3dProp.equals("t")) {
|
|
forceD3D = true;
|
|
d3dEnabled = true;
|
|
} else if (d3dProp.equals("false") || d3dProp.equals("f")) {
|
|
d3dEnabled = false;
|
|
}
|
|
}
|
|
if (d3dTexBppProp != null) {
|
|
try {
|
|
int parsed = Integer.parseInt(d3dTexBppProp);
|
|
if (parsed == 32 || parsed == 16) {
|
|
textureBpp = parsed;
|
|
System.out.println("Texture bpp is set to " + textureBpp);
|
|
}
|
|
} catch (NumberFormatException e) {}
|
|
}
|
|
if (d3dEnabled) {
|
|
d3dEnabled = enableD3D(forceD3D);
|
|
if (d3dEnabled) {
|
|
D3DBlitLoops.register();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static {
|
|
initIDs();
|
|
String noddraw = (String) java.security.AccessController.doPrivileged(
|
|
new sun.security.action.GetPropertyAction("sun.java2d.noddraw"));
|
|
String ddoffscreenProp = (String) java.security.AccessController.doPrivileged(
|
|
new sun.security.action.GetPropertyAction("sun.java2d.ddoffscreen"));
|
|
String ddForceVramProp = (String) java.security.AccessController.doPrivileged(
|
|
new sun.security.action.GetPropertyAction("sun.java2d.ddforcevram"));
|
|
String ddBlitProp = (String) java.security.AccessController.doPrivileged(
|
|
new sun.security.action.GetPropertyAction("sun.java2d.ddblit"));
|
|
String ddScaleProp = (String) java.security.AccessController.doPrivileged(
|
|
new sun.security.action.GetPropertyAction("sun.java2d.ddscale"));
|
|
String offscreenSharingProp = (String) java.security.AccessController.doPrivileged(
|
|
new sun.security.action.GetPropertyAction("sun.java2d.offscreenSharing"));
|
|
boolean ddoffscreenDisable = (ddoffscreenProp != null &&
|
|
(ddoffscreenProp.equals("false") ||
|
|
ddoffscreenProp.equals("f")));
|
|
forceDDVram = (ddForceVramProp != null &&
|
|
(ddForceVramProp.equals("true") ||
|
|
ddForceVramProp.equals("t")));
|
|
boolean ddBlitDisable = (ddBlitProp != null &&
|
|
(ddBlitProp.equals("false") ||
|
|
ddBlitProp.equals("f")));
|
|
boolean ddScaleDisable = (ddScaleProp == null ||
|
|
(ddScaleProp.equals("false") ||
|
|
ddScaleProp.equals("f")));
|
|
boolean offscreenSharing = ((offscreenSharingProp != null) &&
|
|
!(offscreenSharingProp.equals("false") ||
|
|
offscreenSharingProp.equals("f")));
|
|
if (offscreenSharing) {
|
|
System.out.println("Warning: offscreenSharing has been enabled. " +
|
|
"The use of this capability will change in future " +
|
|
"releases and applications that depend on it " +
|
|
"may not work correctly");
|
|
}
|
|
|
|
initD3D();
|
|
// REMIND: This isn't really thought-out; if the user doesn't have or
|
|
// doesn't want ddraw then we should not even have this surface type
|
|
// in the loop
|
|
if (noddraw == null && !ddoffscreenDisable) {
|
|
String magPresent = (String)java.security.AccessController.doPrivileged(
|
|
new sun.security.action.GetPropertyAction("javax.accessibility.screen_magnifier_present"));
|
|
if (magPresent == null || !magPresent.equals("true")) {
|
|
if ("false".equals(magPresent) || getOsMajorVer() < 6)
|
|
initDDraw(offscreenSharing);
|
|
if (!ddBlitDisable) {
|
|
// Register out hardware-accelerated Blit loops
|
|
Win32BlitLoops.register();
|
|
} else {
|
|
System.out.println("DirectDraw Blits disabled");
|
|
}
|
|
if (!ddScaleDisable) {
|
|
Win32ScaleLoops.register();
|
|
ddScaleEnabled = true;
|
|
System.out.println("DirectDraw Scaling enabled");
|
|
}
|
|
if (forceDDVram) {
|
|
System.out.println("DirectDraw surfaces constrained to use vram");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
private static int getOsMajorVer() {
|
|
try {
|
|
String ver = System.getProperty("os.version");
|
|
int pos;
|
|
if (ver != null && (pos = ver.indexOf('.')) > 0)
|
|
return Integer.parseInt(ver.substring(0, pos));
|
|
}
|
|
catch (SecurityException e) {
|
|
}
|
|
catch (NumberFormatException e) {
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
public static SurfaceType getSurfaceType(ColorModel cm, int transparency) {
|
|
// REMIND: If ddraw not available, set sType to non-ddraw surface type
|
|
|
|
if (transparency == Transparency.TRANSLUCENT) {
|
|
if (cm.getPixelSize() == 16) {
|
|
return Win32SurfaceData.Ushort4444ArgbD3D;
|
|
} else {
|
|
return Win32SurfaceData.IntArgbD3D;
|
|
}
|
|
}
|
|
boolean transparent = (transparency == Transparency.BITMASK);
|
|
switch (cm.getPixelSize()) {
|
|
case 32:
|
|
case 24:
|
|
if (cm instanceof DirectColorModel) {
|
|
if (((DirectColorModel)cm).getRedMask() == 0xff0000) {
|
|
return transparent ? Win32SurfaceData.IntRgbDD_BM :
|
|
Win32SurfaceData.IntRgbDD;
|
|
} else {
|
|
return transparent ? Win32SurfaceData.IntRgbxDD_BM :
|
|
Win32SurfaceData.IntRgbxDD;
|
|
}
|
|
} else {
|
|
return transparent ? Win32SurfaceData.ThreeByteBgrDD_BM :
|
|
Win32SurfaceData.ThreeByteBgrDD;
|
|
}
|
|
case 15:
|
|
return transparent ? Win32SurfaceData.Ushort555RgbDD_BM :
|
|
Win32SurfaceData.Ushort555RgbDD;
|
|
case 16:
|
|
if ((cm instanceof DirectColorModel) &&
|
|
(((DirectColorModel)cm).getBlueMask() == 0x3e))
|
|
{
|
|
return transparent ? Win32SurfaceData.Ushort555RgbxDD_BM :
|
|
Win32SurfaceData.Ushort555RgbxDD;
|
|
} else {
|
|
return transparent ? Win32SurfaceData.Ushort565RgbDD_BM :
|
|
Win32SurfaceData.Ushort565RgbDD;
|
|
}
|
|
case 8:
|
|
if (cm.getColorSpace().getType() == ColorSpace.TYPE_GRAY &&
|
|
cm instanceof ComponentColorModel) {
|
|
return transparent ? Win32SurfaceData.ByteGrayDD_BM :
|
|
Win32SurfaceData.ByteGrayDD;
|
|
} else if (cm instanceof IndexColorModel &&
|
|
isOpaqueGray((IndexColorModel)cm)) {
|
|
return transparent ? Win32SurfaceData.Index8GrayDD_BM :
|
|
Win32SurfaceData.Index8GrayDD;
|
|
} else {
|
|
return transparent ? Win32SurfaceData.ByteIndexedDD_BM :
|
|
Win32SurfaceData.ByteIndexedOpaqueDD;
|
|
}
|
|
default:
|
|
throw new sun.java2d.InvalidPipeException("Unsupported bit " +
|
|
"depth: " +
|
|
cm.getPixelSize());
|
|
}
|
|
}
|
|
|
|
public static Win32OffScreenSurfaceData createData(int width, int height,
|
|
ColorModel cm, GraphicsConfiguration graphicsConfig,
|
|
Image image, int transparency) {
|
|
|
|
if (!((Win32GraphicsDevice)graphicsConfig.getDevice()).
|
|
isOffscreenAccelerationEnabled()) {
|
|
// If acceleration is disabled on this device, don't create
|
|
// a surface of this type
|
|
return null;
|
|
}
|
|
|
|
// need to use device color model for textures
|
|
if (transparency == Transparency.TRANSLUCENT) {
|
|
cm = ((Win32PeerlessImage)image).getDeviceColorModel();
|
|
}
|
|
|
|
Win32OffScreenSurfaceData ret = new Win32OffScreenSurfaceData(width,
|
|
height, getSurfaceType(cm, transparency),
|
|
cm, graphicsConfig, image, transparency);
|
|
Win32GraphicsDevice gd =
|
|
(Win32GraphicsDevice)graphicsConfig.getDevice();
|
|
|
|
ret.initSurface(cm.getPixelSize(), width, height, gd.getScreen(),
|
|
(image instanceof WVolatileImage), transparency, forceDDVram);
|
|
// d3dClippingEnabled is set during the call to initSurface
|
|
if (ret.d3dClippingEnabled) {
|
|
ret.d3dPipe = d3dClipPipe;
|
|
ret.d3dTxPipe = d3dTxClipPipe;
|
|
} else {
|
|
ret.d3dPipe = d3dNoClipPipe;
|
|
ret.d3dTxPipe = d3dTxNoClipPipe;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
protected static Win32D3DRenderer d3dNoClipPipe;
|
|
protected static Win32D3DRenderer d3dClipPipe;
|
|
protected static Win32DDRenderer ddPipe;
|
|
protected static PixelToShapeConverter d3dTxNoClipPipe;
|
|
protected static PixelToShapeConverter d3dTxClipPipe;
|
|
protected static PixelToShapeConverter ddTxPipe;
|
|
// The next 2 instance variables are set if d3dEnabled during
|
|
// construction, depending on whether d3d can handle clipping
|
|
// or not
|
|
protected Win32D3DRenderer d3dPipe = null;
|
|
protected PixelToShapeConverter d3dTxPipe = null;
|
|
|
|
static {
|
|
d3dNoClipPipe = new Win32D3DRenderer(false);
|
|
d3dClipPipe = new Win32D3DRenderer(true);
|
|
ddPipe = new Win32DDRenderer();
|
|
if (GraphicsPrimitive.tracingEnabled()) {
|
|
d3dNoClipPipe = d3dNoClipPipe.traceWrapD3D();
|
|
d3dClipPipe = d3dClipPipe.traceWrapD3D();
|
|
ddPipe = ddPipe.traceWrapDD();
|
|
}
|
|
d3dTxNoClipPipe = new PixelToShapeConverter(d3dNoClipPipe);
|
|
d3dTxClipPipe = new PixelToShapeConverter(d3dClipPipe);
|
|
ddTxPipe = new PixelToShapeConverter(ddPipe);
|
|
}
|
|
|
|
public void validatePipe(SunGraphics2D sg2d) {
|
|
if (sg2d.antialiasHint != SunHints.INTVAL_ANTIALIAS_ON &&
|
|
sg2d.paintState == sg2d.PAINT_SOLIDCOLOR &&
|
|
sg2d.compositeState == sg2d.COMP_ISCOPY &&
|
|
sg2d.clipState != sg2d.CLIP_SHAPE)
|
|
{
|
|
PixelToShapeConverter txPipe;
|
|
Win32DDRenderer nontxPipe;
|
|
if (d3dEnabled && localD3dEnabled) {
|
|
txPipe = d3dTxPipe;
|
|
nontxPipe = d3dPipe;
|
|
} else {
|
|
txPipe = ddTxPipe;
|
|
nontxPipe = ddPipe;
|
|
}
|
|
sg2d.imagepipe = imagepipe;
|
|
if (sg2d.transformState > sg2d.TRANSFORM_TRANSLATEONLY) {
|
|
sg2d.drawpipe = txPipe;
|
|
sg2d.fillpipe = txPipe;
|
|
} else if (sg2d.strokeState != sg2d.STROKE_THIN){
|
|
sg2d.drawpipe = txPipe;
|
|
sg2d.fillpipe = nontxPipe;
|
|
} else {
|
|
sg2d.drawpipe = nontxPipe;
|
|
sg2d.fillpipe = nontxPipe;
|
|
}
|
|
sg2d.shapepipe = nontxPipe;
|
|
if (sg2d.textAntialiasHint == SunHints.INTVAL_TEXT_ANTIALIAS_ON) {
|
|
sg2d.textpipe = aaTextRenderer;
|
|
} else {
|
|
sg2d.textpipe = solidTextRenderer;
|
|
}
|
|
// This is needed for AA text.
|
|
// Note that even a SolidTextRenderer can dispatch AA text
|
|
// if a GlyphVector overrides the AA setting.
|
|
sg2d.loops = solidloops;
|
|
} else {
|
|
super.validatePipe(sg2d);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Disables D3D on this surfaceData object. This can happen
|
|
* when we encounter an error in rendering a D3D primitive
|
|
* (for example, if we were unable to create a D3D device).
|
|
* Upon next validation, this renderer will then choose a
|
|
* non-D3D pipe.
|
|
*/
|
|
public void disableD3D() {
|
|
localD3dEnabled = false;
|
|
}
|
|
|
|
public static boolean isDDScaleEnabled() {
|
|
return ddScaleEnabled;
|
|
}
|
|
|
|
public Raster getRaster(int x, int y, int w, int h) {
|
|
throw new InternalError("not implemented yet");
|
|
}
|
|
|
|
public void lock() {
|
|
// REMIND: Do we need this call here? Who calls the Java method?
|
|
}
|
|
|
|
public void unlock() {
|
|
// REMIND: Do we need this call here? Who calls the Java method?
|
|
}
|
|
|
|
public RenderLoops getRenderLoops(SunGraphics2D sg2d) {
|
|
if (sg2d.paintState == sg2d.PAINT_SOLIDCOLOR &&
|
|
sg2d.compositeState == sg2d.COMP_ISCOPY)
|
|
{
|
|
return solidloops;
|
|
}
|
|
return super.getRenderLoops(sg2d);
|
|
}
|
|
|
|
public GraphicsConfiguration getDeviceConfiguration() {
|
|
return graphicsConfig;
|
|
}
|
|
|
|
/**
|
|
* Initializes the native Ops pointer.
|
|
*/
|
|
private native void initOps(int depth, int transparency);
|
|
|
|
/**
|
|
* This native method creates the offscreen surface in video memory and
|
|
* (if necessary) initializes DirectDraw
|
|
*/
|
|
public native void initSurface(int depth, int width, int height,
|
|
int screen,
|
|
boolean isVolatile,
|
|
int transparency,
|
|
boolean disablePunts);
|
|
|
|
public native void restoreSurface();
|
|
|
|
/**
|
|
* Protected constructor. Use createData() to create an object.
|
|
*/
|
|
protected Win32OffScreenSurfaceData(int width, int height,
|
|
SurfaceType sType, ColorModel cm,
|
|
GraphicsConfiguration graphicsConfig,
|
|
Image image, int transparency)
|
|
{
|
|
super(sType, cm);
|
|
this.width = width;
|
|
this.height = height;
|
|
this.graphicsConfig = graphicsConfig;
|
|
this.image = image;
|
|
initOps(cm.getPixelSize(), transparency);
|
|
this.transparency = transparency;
|
|
this.solidloops =
|
|
((Win32GraphicsConfig)graphicsConfig).getSolidLoops(sType);
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
* we could choose wrong loop (blit instead of blitbg,
|
|
* for example, which will cause problems in transparent
|
|
* case).
|
|
*/
|
|
public int getTransparency() {
|
|
return transparency;
|
|
}
|
|
|
|
public static int getTextureBpp() {
|
|
return textureBpp;
|
|
}
|
|
|
|
public SurfaceData getReplacement() {
|
|
// When someone asks for a new surface data, we punt to our
|
|
// container image which will attempt to restore the contents
|
|
// of this surface or, failing that, will return null
|
|
|
|
if (image instanceof Win32OffScreenImage) {
|
|
// Only this type of image has auto-restore
|
|
// REMIND: don't like this hack - we should just generically
|
|
// punt to our parent image and let it decide without having
|
|
// to figure out what our parent is.
|
|
return ((Win32OffScreenImage)image).restoreContents();
|
|
} else if (image instanceof WVolatileImage) {
|
|
return ((WVolatileImage)image).restoreContents();
|
|
} else {
|
|
throw new InternalError();
|
|
}
|
|
}
|
|
|
|
public Rectangle getBounds() {
|
|
return new Rectangle(width, height);
|
|
}
|
|
|
|
private native void nativeInvalidate();
|
|
|
|
public void invalidate() {
|
|
if (isValid()) {
|
|
nativeInvalidate();
|
|
super.invalidate();
|
|
}
|
|
}
|
|
|
|
public native void setTransparentPixel(int pixel);
|
|
|
|
public native void flush();
|
|
|
|
/**
|
|
* Returns true if the native representation of this image has been
|
|
* moved into ddraw system memory. This happens when many reads
|
|
* or read-modify-write operations are requested of that surface.
|
|
* If we have moved that surface into system memory, we should note that
|
|
* here so that someone wanting to copy something to this surface will
|
|
* take that into account during that copy.
|
|
*/
|
|
public boolean surfacePunted() {
|
|
return ddSurfacePunted;
|
|
}
|
|
}
|