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