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 pData 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 }