4632N/A/*
4632N/A * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
4632N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4632N/A *
4632N/A * This code is free software; you can redistribute it and/or modify it
4632N/A * under the terms of the GNU General Public License version 2 only, as
4632N/A * published by the Free Software Foundation. Oracle designates this
4632N/A * particular file as subject to the "Classpath" exception as provided
4632N/A * by Oracle in the LICENSE file that accompanied this code.
4632N/A *
4632N/A * This code is distributed in the hope that it will be useful, but WITHOUT
4632N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
4632N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
4632N/A * version 2 for more details (a copy is included in the LICENSE file that
4632N/A * accompanied this code).
4632N/A *
4632N/A * You should have received a copy of the GNU General Public License version
4632N/A * 2 along with this work; if not, write to the Free Software Foundation,
4632N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
4632N/A *
4632N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
4632N/A * or visit www.oracle.com if you need additional information or have any
4632N/A * questions.
4632N/A */
4632N/A
4632N/Apackage sun.java2d.opengl;
4632N/A
4632N/Aimport java.awt.Graphics;
4632N/Aimport java.awt.GraphicsConfiguration;
4632N/Aimport java.awt.GraphicsDevice;
4632N/Aimport java.awt.GraphicsEnvironment;
4632N/Aimport java.awt.Image;
4632N/Aimport java.awt.Rectangle;
4632N/Aimport java.awt.image.ColorModel;
4632N/A
4632N/Aimport sun.java2d.SunGraphics2D;
4632N/Aimport sun.java2d.SurfaceData;
4632N/A
4632N/Aimport sun.lwawt.macosx.CPlatformView;
4632N/A
4632N/Apublic abstract class CGLSurfaceData extends OGLSurfaceData {
4632N/A
6084N/A protected final int scale;
6084N/A protected final int width;
6084N/A protected final int height;
4632N/A protected CPlatformView pView;
4632N/A private CGLGraphicsConfig graphicsConfig;
4632N/A
4639N/A native void validate(int xoff, int yoff, int width, int height, boolean isOpaque);
4632N/A
4639N/A private native void initOps(long pConfigInfo, long pPeerData, long layerPtr,
4639N/A int xoff, int yoff, boolean isOpaque);
4632N/A
4632N/A protected native boolean initPbuffer(long pData, long pConfigInfo,
4632N/A boolean isOpaque, int width, int height);
4632N/A
6084N/A protected CGLSurfaceData(CGLGraphicsConfig gc, ColorModel cm, int type,
6084N/A int width, int height) {
6084N/A super(gc, cm, type);
6084N/A // TEXTURE shouldn't be scaled, it is used for managed BufferedImages.
6084N/A scale = type == TEXTURE ? 1 : gc.getDevice().getScaleFactor();
6084N/A this.width = width * scale;
6084N/A this.height = height * scale;
6084N/A }
6084N/A
4632N/A protected CGLSurfaceData(CPlatformView pView, CGLGraphicsConfig gc,
6084N/A ColorModel cm, int type,int width, int height)
4632N/A {
6084N/A this(gc, cm, type, width, height);
4632N/A this.pView = pView;
4632N/A this.graphicsConfig = gc;
4632N/A
4632N/A long pConfigInfo = gc.getNativeConfigInfo();
4632N/A long pPeerData = 0L;
4639N/A boolean isOpaque = true;
4632N/A if (pView != null) {
4632N/A pPeerData = pView.getAWTView();
4639N/A isOpaque = pView.isOpaque();
4632N/A }
4639N/A initOps(pConfigInfo, pPeerData, 0, 0, 0, isOpaque);
4639N/A }
4639N/A
4639N/A protected CGLSurfaceData(CGLLayer layer, CGLGraphicsConfig gc,
6084N/A ColorModel cm, int type,int width, int height)
4639N/A {
6084N/A this(gc, cm, type, width, height);
4639N/A this.graphicsConfig = gc;
4639N/A
4639N/A long pConfigInfo = gc.getNativeConfigInfo();
4639N/A long layerPtr = 0L;
4639N/A boolean isOpaque = true;
4639N/A if (layer != null) {
4639N/A layerPtr = layer.getPointer();
4639N/A isOpaque = layer.isOpaque();
4639N/A }
4639N/A initOps(pConfigInfo, 0, layerPtr, 0, 0, isOpaque);
4632N/A }
4632N/A
4632N/A @Override //SurfaceData
4632N/A public GraphicsConfiguration getDeviceConfiguration() {
4632N/A return graphicsConfig;
4632N/A }
4632N/A
4632N/A /**
4632N/A * Creates a SurfaceData object representing the primary (front) buffer of
4632N/A * an on-screen Window.
4632N/A */
4632N/A public static CGLWindowSurfaceData createData(CPlatformView pView) {
4632N/A CGLGraphicsConfig gc = getGC(pView);
4632N/A return new CGLWindowSurfaceData(pView, gc);
4632N/A }
4632N/A
4632N/A /**
4639N/A * Creates a SurfaceData object representing the intermediate buffer
4639N/A * between the Java2D flusher thread and the AppKit thread.
4639N/A */
4639N/A public static CGLLayerSurfaceData createData(CGLLayer layer) {
4639N/A CGLGraphicsConfig gc = getGC(layer);
4639N/A Rectangle r = layer.getBounds();
4639N/A return new CGLLayerSurfaceData(layer, gc, r.width, r.height);
4639N/A }
4639N/A
4639N/A /**
4632N/A * Creates a SurfaceData object representing the back buffer of a
4632N/A * double-buffered on-screen Window.
4632N/A */
4632N/A public static CGLOffScreenSurfaceData createData(CPlatformView pView,
4632N/A Image image, int type) {
4632N/A CGLGraphicsConfig gc = getGC(pView);
4632N/A Rectangle r = pView.getBounds();
4632N/A if (type == FLIP_BACKBUFFER) {
4632N/A return new CGLOffScreenSurfaceData(pView, gc, r.width, r.height,
4632N/A image, gc.getColorModel(), FLIP_BACKBUFFER);
4632N/A } else {
4632N/A return new CGLVSyncOffScreenSurfaceData(pView, gc, r.width,
4632N/A r.height, image, gc.getColorModel(), type);
4632N/A }
4632N/A }
4632N/A
4632N/A /**
4632N/A * Creates a SurfaceData object representing an off-screen buffer (either a
4632N/A * Pbuffer or Texture).
4632N/A */
4632N/A public static CGLOffScreenSurfaceData createData(CGLGraphicsConfig gc,
4632N/A int width, int height, ColorModel cm, Image image, int type) {
4632N/A return new CGLOffScreenSurfaceData(null, gc, width, height, image, cm,
4632N/A type);
4632N/A }
4632N/A
4632N/A public static CGLGraphicsConfig getGC(CPlatformView pView) {
4632N/A if (pView != null) {
4632N/A return (CGLGraphicsConfig)pView.getGraphicsConfiguration();
4632N/A } else {
4632N/A // REMIND: this should rarely (never?) happen, but what if
4632N/A // default config is not CGL?
4632N/A GraphicsEnvironment env = GraphicsEnvironment
4639N/A .getLocalGraphicsEnvironment();
4632N/A GraphicsDevice gd = env.getDefaultScreenDevice();
4632N/A return (CGLGraphicsConfig) gd.getDefaultConfiguration();
4632N/A }
4632N/A }
4632N/A
4639N/A public static CGLGraphicsConfig getGC(CGLLayer layer) {
4639N/A return (CGLGraphicsConfig)layer.getGraphicsConfiguration();
4639N/A }
4639N/A
4639N/A public void validate() {
4632N/A // Overridden in CGLWindowSurfaceData below
4632N/A }
4632N/A
6084N/A @Override
6084N/A public int getDefaultScale() {
6084N/A return scale;
6084N/A }
6084N/A
6084N/A @Override
6084N/A public boolean copyArea(SunGraphics2D sg2d, int x, int y, int w, int h,
6084N/A int dx, int dy) {
6084N/A final int state = sg2d.transformState;
6084N/A if (state > SunGraphics2D.TRANSFORM_TRANSLATESCALE
6084N/A || sg2d.compositeState >= SunGraphics2D.COMP_XOR) {
6084N/A return false;
6084N/A }
6084N/A if (state <= SunGraphics2D.TRANSFORM_ANY_TRANSLATE) {
6084N/A x += sg2d.transX;
6084N/A y += sg2d.transY;
6084N/A } else if (state == SunGraphics2D.TRANSFORM_TRANSLATESCALE) {
6084N/A final double[] coords = {x, y, x + w, y + h, x + dx, y + dy};
6084N/A sg2d.transform.transform(coords, 0, coords, 0, 3);
6084N/A x = (int) Math.ceil(coords[0] - 0.5);
6084N/A y = (int) Math.ceil(coords[1] - 0.5);
6084N/A w = ((int) Math.ceil(coords[2] - 0.5)) - x;
6084N/A h = ((int) Math.ceil(coords[3] - 0.5)) - y;
6084N/A dx = ((int) Math.ceil(coords[4] - 0.5)) - x;
6084N/A dy = ((int) Math.ceil(coords[5] - 0.5)) - y;
6084N/A }
6084N/A oglRenderPipe.copyArea(sg2d, x, y, w, h, dx, dy);
6084N/A return true;
6084N/A }
6084N/A
4632N/A protected native void clearWindow();
4632N/A
4632N/A public static class CGLWindowSurfaceData extends CGLSurfaceData {
4632N/A
4632N/A public CGLWindowSurfaceData(CPlatformView pView,
4632N/A CGLGraphicsConfig gc) {
6084N/A super(pView, gc, gc.getColorModel(), WINDOW, 0, 0);
4632N/A }
4632N/A
4632N/A @Override
4632N/A public SurfaceData getReplacement() {
4632N/A return pView.getSurfaceData();
4632N/A }
4632N/A
4632N/A @Override
4632N/A public Rectangle getBounds() {
4632N/A Rectangle r = pView.getBounds();
4632N/A return new Rectangle(0, 0, r.width, r.height);
4632N/A }
4632N/A
4632N/A /**
4632N/A * Returns destination Component associated with this SurfaceData.
4632N/A */
4632N/A @Override
4632N/A public Object getDestination() {
4632N/A return pView.getDestination();
4632N/A }
4632N/A
4639N/A public void validate() {
4632N/A OGLRenderQueue rq = OGLRenderQueue.getInstance();
4632N/A rq.lock();
4632N/A try {
4632N/A rq.flushAndInvokeNow(new Runnable() {
4632N/A public void run() {
4632N/A Rectangle peerBounds = pView.getBounds();
4639N/A validate(0, 0, peerBounds.width, peerBounds.height, pView.isOpaque());
4632N/A }
4632N/A });
4632N/A } finally {
4632N/A rq.unlock();
4632N/A }
4632N/A }
4632N/A
4632N/A @Override
4632N/A public void invalidate() {
4632N/A super.invalidate();
4632N/A clearWindow();
4632N/A }
4632N/A }
4632N/A
4632N/A /**
4639N/A * A surface which implements an intermediate buffer between
4639N/A * the Java2D flusher thread and the AppKit thread.
4639N/A *
4639N/A * This surface serves as a buffer attached to a CGLLayer and
4639N/A * the layer redirects all painting to the buffer's graphics.
4639N/A */
4639N/A public static class CGLLayerSurfaceData extends CGLSurfaceData {
4639N/A
4639N/A private CGLLayer layer;
4639N/A
4639N/A public CGLLayerSurfaceData(CGLLayer layer, CGLGraphicsConfig gc,
4639N/A int width, int height) {
6084N/A super(layer, gc, gc.getColorModel(), FBOBJECT, width, height);
4639N/A this.layer = layer;
6084N/A initSurface(this.width, this.height);
4639N/A }
4639N/A
4639N/A @Override
4639N/A public SurfaceData getReplacement() {
4639N/A return layer.getSurfaceData();
4639N/A }
4639N/A
4639N/A @Override
4639N/A boolean isOnScreen() {
4639N/A return true;
4639N/A }
4639N/A
4639N/A @Override
4639N/A public Rectangle getBounds() {
4639N/A return new Rectangle(width, height);
4639N/A }
4639N/A
4639N/A @Override
4639N/A public Object getDestination() {
4639N/A return layer.getDestination();
4639N/A }
4639N/A
4639N/A @Override
4639N/A public int getTransparency() {
4639N/A return layer.getTransparency();
4639N/A }
4639N/A
4639N/A @Override
4639N/A public void invalidate() {
4639N/A super.invalidate();
4639N/A clearWindow();
4639N/A }
4639N/A }
4639N/A
4639N/A /**
4632N/A * A surface which implements a v-synced flip back-buffer with COPIED
4632N/A * FlipContents.
4632N/A *
4632N/A * This surface serves as a back-buffer to the outside world, while it is
4632N/A * actually an offscreen surface. When the BufferStrategy this surface
4632N/A * belongs to is showed, it is first copied to the real private
4632N/A * FLIP_BACKBUFFER, which is then flipped.
4632N/A */
4632N/A public static class CGLVSyncOffScreenSurfaceData extends
4632N/A CGLOffScreenSurfaceData {
4632N/A private CGLOffScreenSurfaceData flipSurface;
4632N/A
4632N/A public CGLVSyncOffScreenSurfaceData(CPlatformView pView,
4632N/A CGLGraphicsConfig gc, int width, int height, Image image,
4632N/A ColorModel cm, int type) {
4632N/A super(pView, gc, width, height, image, cm, type);
4632N/A flipSurface = CGLSurfaceData.createData(pView, image,
4632N/A FLIP_BACKBUFFER);
4632N/A }
4632N/A
4632N/A public SurfaceData getFlipSurface() {
4632N/A return flipSurface;
4632N/A }
4632N/A
4632N/A @Override
4632N/A public void flush() {
4632N/A flipSurface.flush();
4632N/A super.flush();
4632N/A }
4632N/A }
4632N/A
4632N/A public static class CGLOffScreenSurfaceData extends CGLSurfaceData {
4632N/A private Image offscreenImage;
4632N/A
4632N/A public CGLOffScreenSurfaceData(CPlatformView pView,
4639N/A CGLGraphicsConfig gc, int width, int height, Image image,
4639N/A ColorModel cm, int type) {
6084N/A super(pView, gc, cm, type, width, height);
4632N/A offscreenImage = image;
6084N/A initSurface(this.width, this.height);
4632N/A }
4632N/A
4632N/A @Override
4632N/A public SurfaceData getReplacement() {
4632N/A return restoreContents(offscreenImage);
4632N/A }
4632N/A
4632N/A @Override
4632N/A public Rectangle getBounds() {
4632N/A if (type == FLIP_BACKBUFFER) {
4632N/A Rectangle r = pView.getBounds();
4632N/A return new Rectangle(0, 0, r.width, r.height);
4632N/A } else {
4632N/A return new Rectangle(width, height);
4632N/A }
4632N/A }
4632N/A
4632N/A /**
4632N/A * Returns destination Image associated with this SurfaceData.
4632N/A */
4632N/A @Override
4632N/A public Object getDestination() {
4632N/A return offscreenImage;
4632N/A }
4632N/A }
4632N/A
4632N/A // Mac OS X specific APIs for JOGL/Java2D bridge...
4632N/A
4632N/A // given a surface create and attach GL context, then return it
4632N/A private native static long createCGLContextOnSurface(CGLSurfaceData sd,
4632N/A long sharedContext);
4632N/A
4632N/A public static long createOGLContextOnSurface(Graphics g, long sharedContext) {
4632N/A SurfaceData sd = ((SunGraphics2D) g).surfaceData;
4632N/A if ((sd instanceof CGLSurfaceData) == true) {
4632N/A CGLSurfaceData cglsd = (CGLSurfaceData) sd;
4632N/A return createCGLContextOnSurface(cglsd, sharedContext);
4632N/A } else {
4632N/A return 0L;
4632N/A }
4632N/A }
4632N/A
4632N/A // returns whether or not the makeCurrent operation succeeded
4632N/A native static boolean makeCGLContextCurrentOnSurface(CGLSurfaceData sd,
4632N/A long ctx);
4632N/A
4632N/A public static boolean makeOGLContextCurrentOnSurface(Graphics g, long ctx) {
4632N/A SurfaceData sd = ((SunGraphics2D) g).surfaceData;
4632N/A if ((ctx != 0L) && ((sd instanceof CGLSurfaceData) == true)) {
4632N/A CGLSurfaceData cglsd = (CGLSurfaceData) sd;
4632N/A return makeCGLContextCurrentOnSurface(cglsd, ctx);
4632N/A } else {
4632N/A return false;
4632N/A }
4632N/A }
4632N/A
4632N/A // additional cleanup
4632N/A private native static void destroyCGLContext(long ctx);
4632N/A
4632N/A public static void destroyOGLContext(long ctx) {
4632N/A if (ctx != 0L) {
4632N/A destroyCGLContext(ctx);
4632N/A }
4632N/A }
4632N/A}