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