WGLSurfaceData.java revision 13220:a8e9ad77ac81
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
26package sun.java2d.opengl;
27
28import java.awt.Component;
29import java.awt.GraphicsConfiguration;
30import java.awt.GraphicsDevice;
31import java.awt.GraphicsEnvironment;
32import java.awt.Image;
33import java.awt.Rectangle;
34import java.awt.geom.AffineTransform;
35import java.awt.image.ColorModel;
36import sun.awt.SunToolkit;
37import sun.awt.Win32GraphicsDevice;
38import sun.awt.windows.WComponentPeer;
39import sun.java2d.SurfaceData;
40
41public 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}
274