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