1 /* 2 * Copyright (c) 2004, 2015, 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 47 protected WGLSurfaceData(WComponentPeer peer, WGLGraphicsConfig gc, 48 ColorModel cm, int type) 49 { 50 super(gc, cm, type); 51 this.peer = peer; 52 this.graphicsConfig = gc; 53 54 long pConfigInfo = gc.getNativeConfigInfo(); 55 long hwnd = peer != null ? peer.getHWnd() : 0L; 56 57 initOps(pConfigInfo, peer, hwnd); 58 } 59 60 public GraphicsConfiguration getDeviceConfiguration() { 61 return graphicsConfig; 62 } 63 64 /** 65 * Creates a SurfaceData object representing the primary (front) buffer 66 * of an on-screen Window. 67 */ 68 public static WGLWindowSurfaceData createData(WComponentPeer peer) { 69 // the OGL pipeline can render directly to the screen and interfere 70 // with layered windows, which is why we don't allow accelerated 71 // surfaces in this case 72 if (!peer.isAccelCapable() || 73 !SunToolkit.isContainingTopLevelOpaque((Component)peer.getTarget())) 74 { 75 return null; 76 } 77 WGLGraphicsConfig gc = getGC(peer); 78 return new WGLWindowSurfaceData(peer, gc); 79 } 80 81 /** 82 * Creates a SurfaceData object representing the back buffer of a 83 * double-buffered on-screen Window. 84 */ 85 public static WGLOffScreenSurfaceData createData(WComponentPeer peer, 86 Image image, 87 int type) 88 { 89 // the OGL pipeline can render directly to the screen and interfere 90 // with layered windows, which is why we don't allow accelerated 91 // surfaces in this case 92 if (!peer.isAccelCapable() || 93 !SunToolkit.isContainingTopLevelOpaque((Component)peer.getTarget())) 94 { 95 return null; 96 } 97 WGLGraphicsConfig gc = getGC(peer); 98 Rectangle r = peer.getBounds(); 99 if (type == FLIP_BACKBUFFER) { 100 return new WGLOffScreenSurfaceData(peer, gc, r.width, r.height, 101 image, peer.getColorModel(), 102 type); 103 } else { 104 return new WGLVSyncOffScreenSurfaceData(peer, gc, r.width, r.height, 105 image, peer.getColorModel(), 106 type); 107 } 108 } 109 110 /** 111 * Creates a SurfaceData object representing an off-screen buffer (either 112 * a Pbuffer or Texture). 113 */ 114 public static WGLOffScreenSurfaceData createData(WGLGraphicsConfig gc, 115 int width, int height, 116 ColorModel cm, 117 Image image, int type) 118 { 119 return new WGLOffScreenSurfaceData(null, gc, width, height, 120 image, cm, type); 121 } 122 123 public static WGLGraphicsConfig getGC(WComponentPeer peer) { 124 if (peer != null) { 125 return (WGLGraphicsConfig)peer.getGraphicsConfiguration(); 126 } else { 127 // REMIND: this should rarely (never?) happen, but what if 128 // default config is not WGL? 129 GraphicsEnvironment env = 130 GraphicsEnvironment.getLocalGraphicsEnvironment(); 131 GraphicsDevice gd = env.getDefaultScreenDevice(); 132 return (WGLGraphicsConfig)gd.getDefaultConfiguration(); 133 } 134 } 135 136 public static class WGLWindowSurfaceData extends WGLSurfaceData { 137 138 public WGLWindowSurfaceData(WComponentPeer peer, 139 WGLGraphicsConfig gc) 140 { 141 super(peer, gc, peer.getColorModel(), WINDOW); 142 } 143 144 public SurfaceData getReplacement() { 145 return peer.getSurfaceData(); 146 } 147 148 public Rectangle getBounds() { 149 Rectangle r = peer.getBounds(); 150 r.x = r.y = 0; 151 return r; 152 } 153 154 /** 155 * Returns destination Component associated with this SurfaceData. 156 */ 157 public Object getDestination() { 158 return peer.getTarget(); 159 } 160 } 161 162 /** 163 * A surface which implements a v-synced flip back-buffer with COPIED 164 * FlipContents. 165 * 166 * This surface serves as a back-buffer to the outside world, while 167 * it is actually an offscreen surface. When the BufferStrategy this surface 168 * belongs to is showed, it is first copied to the real private 169 * FLIP_BACKBUFFER, which is then flipped. 170 */ 171 public static class WGLVSyncOffScreenSurfaceData extends 172 WGLOffScreenSurfaceData 173 { 174 private WGLOffScreenSurfaceData flipSurface; 175 176 public WGLVSyncOffScreenSurfaceData(WComponentPeer peer, 177 WGLGraphicsConfig gc, 178 int width, int height, 179 Image image, ColorModel cm, 180 int type) 181 { 182 super(peer, gc, width, height, image, cm, type); 183 flipSurface = WGLSurfaceData.createData(peer, image, FLIP_BACKBUFFER); 184 } 185 186 public SurfaceData getFlipSurface() { 187 return flipSurface; 188 } 189 190 @Override 191 public void flush() { 192 flipSurface.flush(); 193 super.flush(); 194 } 195 196 } 197 198 public static class WGLOffScreenSurfaceData extends WGLSurfaceData { 199 200 private Image offscreenImage; 201 private int width, height; 202 203 public WGLOffScreenSurfaceData(WComponentPeer peer, 204 WGLGraphicsConfig gc, 205 int width, int height, 206 Image image, ColorModel cm, 207 int type) 208 { 209 super(peer, gc, cm, type); 210 211 this.width = width; 212 this.height = height; 213 offscreenImage = image; 214 215 initSurface(width, height); 216 } 217 218 public SurfaceData getReplacement() { 219 return restoreContents(offscreenImage); 220 } 221 222 public Rectangle getBounds() { 223 if (type == FLIP_BACKBUFFER) { 224 Rectangle r = peer.getBounds(); 225 r.x = r.y = 0; 226 return r; 227 } else { 228 return new Rectangle(width, height); 229 } 230 } 231 232 /** 233 * Returns destination Image associated with this SurfaceData. 234 */ 235 public Object getDestination() { 236 return offscreenImage; 237 } 238 } 239 240 /** 241 * Updates the layered window with the contents of the surface. 242 * 243 * @param psdops pointer to the native ogl sd structure 244 * @param peer pointer to the AwtWindow peer data 245 * @param w width of the window 246 * @param h height of the window 247 * @see sun.awt.windows.TranslucentWindowPainter 248 */ 249 public static native boolean updateWindowAccelImpl(long psdops, 250 WComponentPeer peer, 251 int w, int h); 252 }