package sun.java2d.opengl;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.image.ColorModel;
import sun.java2d.SunGraphics2D;
import sun.java2d.SurfaceData;
import sun.lwawt.macosx.CPlatformView;
public abstract class CGLSurfaceData extends OGLSurfaceData {
protected final int scale;
protected final int width;
protected final int height;
protected CPlatformView pView;
private CGLGraphicsConfig graphicsConfig;
native void validate(int xoff, int yoff, int width, int height, boolean isOpaque);
private native void initOps(long pConfigInfo, long pPeerData, long layerPtr,
int xoff, int yoff, boolean isOpaque);
protected native boolean initPbuffer(long pData, long pConfigInfo,
boolean isOpaque, int width, int height);
protected CGLSurfaceData(CGLGraphicsConfig gc, ColorModel cm, int type,
int width, int height) {
super(gc, cm, type);
scale = type == TEXTURE ? 1 : gc.getDevice().getScaleFactor();
this.width = width * scale;
this.height = height * scale;
}
protected CGLSurfaceData(CPlatformView pView, CGLGraphicsConfig gc,
ColorModel cm, int type,int width, int height)
{
this(gc, cm, type, width, height);
this.pView = pView;
this.graphicsConfig = gc;
long pConfigInfo = gc.getNativeConfigInfo();
long pPeerData = 0L;
boolean isOpaque = true;
if (pView != null) {
pPeerData = pView.getAWTView();
isOpaque = pView.isOpaque();
}
initOps(pConfigInfo, pPeerData, 0, 0, 0, isOpaque);
}
protected CGLSurfaceData(CGLLayer layer, CGLGraphicsConfig gc,
ColorModel cm, int type,int width, int height)
{
this(gc, cm, type, width, height);
this.graphicsConfig = gc;
long pConfigInfo = gc.getNativeConfigInfo();
long layerPtr = 0L;
boolean isOpaque = true;
if (layer != null) {
layerPtr = layer.getPointer();
isOpaque = layer.isOpaque();
}
initOps(pConfigInfo, 0, layerPtr, 0, 0, isOpaque);
}
@Override
public GraphicsConfiguration getDeviceConfiguration() {
return graphicsConfig;
}
public static CGLWindowSurfaceData createData(CPlatformView pView) {
CGLGraphicsConfig gc = getGC(pView);
return new CGLWindowSurfaceData(pView, gc);
}
public static CGLLayerSurfaceData createData(CGLLayer layer) {
CGLGraphicsConfig gc = getGC(layer);
Rectangle r = layer.getBounds();
return new CGLLayerSurfaceData(layer, gc, r.width, r.height);
}
public static CGLOffScreenSurfaceData createData(CPlatformView pView,
Image image, int type) {
CGLGraphicsConfig gc = getGC(pView);
Rectangle r = pView.getBounds();
if (type == FLIP_BACKBUFFER) {
return new CGLOffScreenSurfaceData(pView, gc, r.width, r.height,
image, gc.getColorModel(), FLIP_BACKBUFFER);
} else {
return new CGLVSyncOffScreenSurfaceData(pView, gc, r.width,
r.height, image, gc.getColorModel(), type);
}
}
public static CGLOffScreenSurfaceData createData(CGLGraphicsConfig gc,
int width, int height, ColorModel cm, Image image, int type) {
return new CGLOffScreenSurfaceData(null, gc, width, height, image, cm,
type);
}
public static CGLGraphicsConfig getGC(CPlatformView pView) {
if (pView != null) {
return (CGLGraphicsConfig)pView.getGraphicsConfiguration();
} else {
GraphicsEnvironment env = GraphicsEnvironment
.getLocalGraphicsEnvironment();
GraphicsDevice gd = env.getDefaultScreenDevice();
return (CGLGraphicsConfig) gd.getDefaultConfiguration();
}
}
public static CGLGraphicsConfig getGC(CGLLayer layer) {
return (CGLGraphicsConfig)layer.getGraphicsConfiguration();
}
public void validate() {
}
@Override
public int getDefaultScale() {
return scale;
}
@Override
public boolean copyArea(SunGraphics2D sg2d, int x, int y, int w, int h,
int dx, int dy) {
final int state = sg2d.transformState;
if (state > SunGraphics2D.TRANSFORM_TRANSLATESCALE
|| sg2d.compositeState >= SunGraphics2D.COMP_XOR) {
return false;
}
if (state <= SunGraphics2D.TRANSFORM_ANY_TRANSLATE) {
x += sg2d.transX;
y += sg2d.transY;
} else if (state == SunGraphics2D.TRANSFORM_TRANSLATESCALE) {
final double[] coords = {x, y, x + w, y + h, x + dx, y + dy};
sg2d.transform.transform(coords, 0, coords, 0, 3);
x = (int) Math.ceil(coords[0] - 0.5);
y = (int) Math.ceil(coords[1] - 0.5);
w = ((int) Math.ceil(coords[2] - 0.5)) - x;
h = ((int) Math.ceil(coords[3] - 0.5)) - y;
dx = ((int) Math.ceil(coords[4] - 0.5)) - x;
dy = ((int) Math.ceil(coords[5] - 0.5)) - y;
}
oglRenderPipe.copyArea(sg2d, x, y, w, h, dx, dy);
return true;
}
protected native void clearWindow();
public static class CGLWindowSurfaceData extends CGLSurfaceData {
public CGLWindowSurfaceData(CPlatformView pView,
CGLGraphicsConfig gc) {
super(pView, gc, gc.getColorModel(), WINDOW, 0, 0);
}
@Override
public SurfaceData getReplacement() {
return pView.getSurfaceData();
}
@Override
public Rectangle getBounds() {
Rectangle r = pView.getBounds();
return new Rectangle(0, 0, r.width, r.height);
}
@Override
public Object getDestination() {
return pView.getDestination();
}
public void validate() {
OGLRenderQueue rq = OGLRenderQueue.getInstance();
rq.lock();
try {
rq.flushAndInvokeNow(new Runnable() {
public void run() {
Rectangle peerBounds = pView.getBounds();
validate(0, 0, peerBounds.width, peerBounds.height, pView.isOpaque());
}
});
} finally {
rq.unlock();
}
}
@Override
public void invalidate() {
super.invalidate();
clearWindow();
}
}
public static class CGLLayerSurfaceData extends CGLSurfaceData {
private CGLLayer layer;
public CGLLayerSurfaceData(CGLLayer layer, CGLGraphicsConfig gc,
int width, int height) {
super(layer, gc, gc.getColorModel(), FBOBJECT, width, height);
this.layer = layer;
initSurface(this.width, this.height);
}
@Override
public SurfaceData getReplacement() {
return layer.getSurfaceData();
}
@Override
boolean isOnScreen() {
return true;
}
@Override
public Rectangle getBounds() {
return new Rectangle(width, height);
}
@Override
public Object getDestination() {
return layer.getDestination();
}
@Override
public int getTransparency() {
return layer.getTransparency();
}
@Override
public void invalidate() {
super.invalidate();
clearWindow();
}
}
public static class CGLVSyncOffScreenSurfaceData extends
CGLOffScreenSurfaceData {
private CGLOffScreenSurfaceData flipSurface;
public CGLVSyncOffScreenSurfaceData(CPlatformView pView,
CGLGraphicsConfig gc, int width, int height, Image image,
ColorModel cm, int type) {
super(pView, gc, width, height, image, cm, type);
flipSurface = CGLSurfaceData.createData(pView, image,
FLIP_BACKBUFFER);
}
public SurfaceData getFlipSurface() {
return flipSurface;
}
@Override
public void flush() {
flipSurface.flush();
super.flush();
}
}
public static class CGLOffScreenSurfaceData extends CGLSurfaceData {
private Image offscreenImage;
public CGLOffScreenSurfaceData(CPlatformView pView,
CGLGraphicsConfig gc, int width, int height, Image image,
ColorModel cm, int type) {
super(pView, gc, cm, type, width, height);
offscreenImage = image;
initSurface(this.width, this.height);
}
@Override
public SurfaceData getReplacement() {
return restoreContents(offscreenImage);
}
@Override
public Rectangle getBounds() {
if (type == FLIP_BACKBUFFER) {
Rectangle r = pView.getBounds();
return new Rectangle(0, 0, r.width, r.height);
} else {
return new Rectangle(width, height);
}
}
@Override
public Object getDestination() {
return offscreenImage;
}
}
private native static long createCGLContextOnSurface(CGLSurfaceData sd,
long sharedContext);
public static long createOGLContextOnSurface(Graphics g, long sharedContext) {
SurfaceData sd = ((SunGraphics2D) g).surfaceData;
if ((sd instanceof CGLSurfaceData) == true) {
CGLSurfaceData cglsd = (CGLSurfaceData) sd;
return createCGLContextOnSurface(cglsd, sharedContext);
} else {
return 0L;
}
}
native static boolean makeCGLContextCurrentOnSurface(CGLSurfaceData sd,
long ctx);
public static boolean makeOGLContextCurrentOnSurface(Graphics g, long ctx) {
SurfaceData sd = ((SunGraphics2D) g).surfaceData;
if ((ctx != 0L) && ((sd instanceof CGLSurfaceData) == true)) {
CGLSurfaceData cglsd = (CGLSurfaceData) sd;
return makeCGLContextCurrentOnSurface(cglsd, ctx);
} else {
return false;
}
}
private native static void destroyCGLContext(long ctx);
public static void destroyOGLContext(long ctx) {
if (ctx != 0L) {
destroyCGLContext(ctx);
}
}
}