1 /* 2 * Copyright (c) 2004, 2009, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.java2d.opengl; 27 28 import java.awt.Component; 29 import java.awt.GraphicsConfiguration; 30 import java.awt.GraphicsDevice; 31 import java.awt.GraphicsEnvironment; 32 import java.awt.Image; 33 import java.awt.Rectangle; 34 import java.awt.image.ColorModel; 35 import sun.awt.SunToolkit; 36 import sun.awt.windows.WComponentPeer; 37 import sun.java2d.SurfaceData; 38 39 public abstract class WGLSurfaceData extends OGLSurfaceData { 40 41 protected WComponentPeer peer; 42 private WGLGraphicsConfig graphicsConfig; 43 44 private native void initOps(long pConfigInfo, WComponentPeer peer, 45 long hwnd); 46 protected native boolean initPbuffer(long pData, long pConfigInfo, 47 boolean isOpaque, 48 int width, int height); 49 50 protected WGLSurfaceData(WComponentPeer peer, WGLGraphicsConfig gc, 51 ColorModel cm, int type) 52 { 53 super(gc, cm, type); 54 this.peer = peer; 55 this.graphicsConfig = gc; 56 57 long pConfigInfo = gc.getNativeConfigInfo(); 58 long hwnd = peer != null ? peer.getHWnd() : 0L; 59 60 initOps(pConfigInfo, peer, hwnd); 61 } 62 63 public GraphicsConfiguration getDeviceConfiguration() { 64 return graphicsConfig; 65 } 66 67 /** 68 * Creates a SurfaceData object representing the primary (front) buffer 69 * of an on-screen Window. 70 */ 71 public static WGLWindowSurfaceData createData(WComponentPeer peer) { 72 // the OGL pipeline can render directly to the screen and interfere 73 // with layered windows, which is why we don't allow accelerated 74 // surfaces in this case 75 if (!peer.isAccelCapable() || 76 !SunToolkit.isContainingTopLevelOpaque((Component)peer.getTarget())) 77 { 78 return null; 79 } 80 WGLGraphicsConfig gc = getGC(peer); 81 return new WGLWindowSurfaceData(peer, gc); 82 } 83 84 /** 85 * Creates a SurfaceData object representing the back buffer of a 86 * double-buffered on-screen Window. 87 */ 88 public static WGLOffScreenSurfaceData createData(WComponentPeer peer, 89 Image image, 90 int type) 91 { 92 // the OGL pipeline can render directly to the screen and interfere 93 // with layered windows, which is why we don't allow accelerated 94 // surfaces in this case 95 if (!peer.isAccelCapable() || 96 !SunToolkit.isContainingTopLevelOpaque((Component)peer.getTarget())) 97 { 98 return null; 99 } 100 WGLGraphicsConfig gc = getGC(peer); 101 Rectangle r = peer.getBounds(); 102 if (type == FLIP_BACKBUFFER) { 103 return new WGLOffScreenSurfaceData(peer, gc, r.width, r.height, 104 image, peer.getColorModel(), 105 type); 106 } else { 107 return new WGLVSyncOffScreenSurfaceData(peer, gc, r.width, r.height, 108 image, peer.getColorModel(), 109 type); 110 } 111 } 112 113 /** 114 * Creates a SurfaceData object representing an off-screen buffer (either 115 * a Pbuffer or Texture). 116 */ 117 public static WGLOffScreenSurfaceData createData(WGLGraphicsConfig gc, 118 int width, int height, 119 ColorModel cm, 120 Image image, int type) 121 { 122 return new WGLOffScreenSurfaceData(null, gc, width, height, 123 image, cm, type); 124 } 125 126 public static WGLGraphicsConfig getGC(WComponentPeer peer) { 127 if (peer != null) { 128 return (WGLGraphicsConfig)peer.getGraphicsConfiguration(); 129 } else { 130 // REMIND: this should rarely (never?) happen, but what if 131 // default config is not WGL? 132 GraphicsEnvironment env = 133 GraphicsEnvironment.getLocalGraphicsEnvironment(); 134 GraphicsDevice gd = env.getDefaultScreenDevice(); 135 return (WGLGraphicsConfig)gd.getDefaultConfiguration(); 136 } 137 } 138 139 public static class WGLWindowSurfaceData extends WGLSurfaceData { 140 141 public WGLWindowSurfaceData(WComponentPeer peer, 142 WGLGraphicsConfig gc) 143 { 144 super(peer, gc, peer.getColorModel(), WINDOW); 145 } 146 147 public SurfaceData getReplacement() { 148 return peer.getSurfaceData(); 149 } 150 151 public Rectangle getBounds() { 152 Rectangle r = peer.getBounds(); 153 r.x = r.y = 0; 154 return r; 155 } 156 157 /** 158 * Returns destination Component associated with this SurfaceData. 159 */ 160 public Object getDestination() { 161 return peer.getTarget(); 162 } 163 } 164 165 /** 166 * A surface which implements a v-synced flip back-buffer with COPIED 167 * FlipContents. 168 * 169 * This surface serves as a back-buffer to the outside world, while 170 * it is actually an offscreen surface. When the BufferStrategy this surface 171 * belongs to is showed, it is first copied to the real private 172 * FLIP_BACKBUFFER, which is then flipped. 173 */ 174 public static class WGLVSyncOffScreenSurfaceData extends 175 WGLOffScreenSurfaceData 176 { 177 private WGLOffScreenSurfaceData flipSurface; 178 179 public WGLVSyncOffScreenSurfaceData(WComponentPeer peer, 180 WGLGraphicsConfig gc, 181 int width, int height, 182 Image image, ColorModel cm, 183 int type) 184 { 185 super(peer, gc, width, height, image, cm, type); 186 flipSurface = WGLSurfaceData.createData(peer, image, FLIP_BACKBUFFER); 187 } 188 189 public SurfaceData getFlipSurface() { 190 return flipSurface; 191 } 192 193 @Override 194 public void flush() { 195 flipSurface.flush(); 196 super.flush(); 197 } 198 199 } 200 201 public static class WGLOffScreenSurfaceData extends WGLSurfaceData { 202 203 private Image offscreenImage; 204 private int width, height; 205 206 public WGLOffScreenSurfaceData(WComponentPeer peer, 207 WGLGraphicsConfig gc, 208 int width, int height, 209 Image image, ColorModel cm, 210 int type) 211 { 212 super(peer, gc, cm, type); 213 214 this.width = width; 215 this.height = height; 216 offscreenImage = image; 217 218 initSurface(width, height); 219 } 220 221 public SurfaceData getReplacement() { 222 return restoreContents(offscreenImage); 223 } 224 225 public Rectangle getBounds() { 226 if (type == FLIP_BACKBUFFER) { 227 Rectangle r = peer.getBounds(); 228 r.x = r.y = 0; 229 return r; 230 } else { 231 return new Rectangle(width, height); 232 } 233 } 234 235 /** 236 * Returns destination Image associated with this SurfaceData. 237 */ 238 public Object getDestination() { 239 return offscreenImage; 240 } 241 } 242 243 /** 244 * Updates the layered window with the contents of the surface. 245 * 246 * @param psdops pointer to the native ogl sd structure 247 * @param peer pointer to the AwtWindow peer data 248 * @param w width of the window 249 * @param h height of the window 250 * @see sun.awt.windows.TranslucentWindowPainter 251 */ 252 public static native boolean updateWindowAccelImpl(long psdops, 253 WComponentPeer peer, 254 int w, int h); 255 }