Print this page
rev 54883 : JDK-8220154 Improve java2d rendering performance on macOS by using Metal framework
Split |
Close |
Expand all |
Collapse all |
--- old/src/java.desktop/macosx/classes/sun/java2d/opengl/CGLSurfaceData.java
+++ new/src/java.desktop/macosx/classes/sun/java2d/opengl/CGLSurfaceData.java
1 1 /*
2 2 * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 4 *
5 5 * This code is free software; you can redistribute it and/or modify it
6 6 * under the terms of the GNU General Public License version 2 only, as
7 7 * published by the Free Software Foundation. Oracle designates this
8 8 * particular file as subject to the "Classpath" exception as provided
9 9 * by Oracle in the LICENSE file that accompanied this code.
10 10 *
11 11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 14 * version 2 for more details (a copy is included in the LICENSE file that
15 15 * accompanied this code).
16 16 *
17 17 * You should have received a copy of the GNU General Public License version
18 18 * 2 along with this work; if not, write to the Free Software Foundation,
19 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 20 *
21 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 22 * or visit www.oracle.com if you need additional information or have any
23 23 * questions.
24 24 */
25 25
26 26 package sun.java2d.opengl;
27 27
28 28 import java.awt.Graphics;
29 29 import java.awt.GraphicsConfiguration;
30 30 import java.awt.GraphicsDevice;
31 31 import java.awt.GraphicsEnvironment;
32 32 import java.awt.Image;
33 33 import java.awt.Rectangle;
34 34 import java.awt.image.ColorModel;
35 35
36 36 import sun.java2d.SunGraphics2D;
37 37 import sun.java2d.SurfaceData;
38 38
39 39 import sun.lwawt.macosx.CPlatformView;
40 40
41 41 public abstract class CGLSurfaceData extends OGLSurfaceData {
42 42
43 43 protected final int scale;
44 44 protected final int width;
45 45 protected final int height;
46 46 protected CPlatformView pView;
47 47 private CGLGraphicsConfig graphicsConfig;
48 48
49 49 native void validate(int xoff, int yoff, int width, int height, boolean isOpaque);
50 50
51 51 private native void initOps(long pConfigInfo, long pPeerData, long layerPtr,
52 52 int xoff, int yoff, boolean isOpaque);
53 53
54 54 protected CGLSurfaceData(CGLGraphicsConfig gc, ColorModel cm, int type,
55 55 int width, int height) {
56 56 super(gc, cm, type);
57 57 // TEXTURE shouldn't be scaled, it is used for managed BufferedImages.
58 58 scale = type == TEXTURE ? 1 : gc.getDevice().getScaleFactor();
59 59 this.width = width * scale;
60 60 this.height = height * scale;
61 61 }
62 62
63 63 protected CGLSurfaceData(CPlatformView pView, CGLGraphicsConfig gc,
64 64 ColorModel cm, int type,int width, int height)
65 65 {
66 66 this(gc, cm, type, width, height);
67 67 this.pView = pView;
68 68 this.graphicsConfig = gc;
69 69
70 70 long pConfigInfo = gc.getNativeConfigInfo();
71 71 long pPeerData = 0L;
72 72 boolean isOpaque = true;
73 73 if (pView != null) {
74 74 pPeerData = pView.getAWTView();
75 75 isOpaque = pView.isOpaque();
76 76 }
77 77 initOps(pConfigInfo, pPeerData, 0, 0, 0, isOpaque);
78 78 }
79 79
80 80 protected CGLSurfaceData(CGLLayer layer, CGLGraphicsConfig gc,
81 81 ColorModel cm, int type,int width, int height)
82 82 {
83 83 this(gc, cm, type, width, height);
84 84 this.graphicsConfig = gc;
85 85
86 86 long pConfigInfo = gc.getNativeConfigInfo();
87 87 long layerPtr = 0L;
88 88 boolean isOpaque = true;
89 89 if (layer != null) {
90 90 layerPtr = layer.getPointer();
91 91 isOpaque = layer.isOpaque();
92 92 }
93 93 initOps(pConfigInfo, 0, layerPtr, 0, 0, isOpaque);
94 94 }
95 95
96 96 @Override //SurfaceData
97 97 public GraphicsConfiguration getDeviceConfiguration() {
98 98 return graphicsConfig;
99 99 }
100 100
101 101 /**
102 102 * Creates a SurfaceData object representing the primary (front) buffer of
103 103 * an on-screen Window.
104 104 */
105 105 public static CGLWindowSurfaceData createData(CPlatformView pView) {
106 106 CGLGraphicsConfig gc = getGC(pView);
107 107 return new CGLWindowSurfaceData(pView, gc);
108 108 }
109 109
110 110 /**
111 111 * Creates a SurfaceData object representing the intermediate buffer
112 112 * between the Java2D flusher thread and the AppKit thread.
113 113 */
114 114 public static CGLLayerSurfaceData createData(CGLLayer layer) {
115 115 CGLGraphicsConfig gc = getGC(layer);
116 116 Rectangle r = layer.getBounds();
117 117 return new CGLLayerSurfaceData(layer, gc, r.width, r.height);
118 118 }
119 119
120 120 /**
121 121 * Creates a SurfaceData object representing the back buffer of a
122 122 * double-buffered on-screen Window.
123 123 */
124 124 public static CGLOffScreenSurfaceData createData(CPlatformView pView,
125 125 Image image, int type) {
126 126 CGLGraphicsConfig gc = getGC(pView);
127 127 Rectangle r = pView.getBounds();
128 128 if (type == FLIP_BACKBUFFER) {
129 129 return new CGLOffScreenSurfaceData(pView, gc, r.width, r.height,
130 130 image, gc.getColorModel(), FLIP_BACKBUFFER);
131 131 } else {
132 132 return new CGLVSyncOffScreenSurfaceData(pView, gc, r.width,
133 133 r.height, image, gc.getColorModel(), type);
134 134 }
135 135 }
136 136
137 137 /**
138 138 * Creates a SurfaceData object representing an off-screen buffer (either a
139 139 * FBO or Texture).
140 140 */
141 141 public static CGLOffScreenSurfaceData createData(CGLGraphicsConfig gc,
142 142 int width, int height, ColorModel cm, Image image, int type) {
143 143 return new CGLOffScreenSurfaceData(null, gc, width, height, image, cm,
144 144 type);
145 145 }
146 146
147 147 public static CGLGraphicsConfig getGC(CPlatformView pView) {
148 148 if (pView != null) {
149 149 return (CGLGraphicsConfig)pView.getGraphicsConfiguration();
150 150 } else {
151 151 // REMIND: this should rarely (never?) happen, but what if
152 152 // default config is not CGL?
153 153 GraphicsEnvironment env = GraphicsEnvironment
154 154 .getLocalGraphicsEnvironment();
155 155 GraphicsDevice gd = env.getDefaultScreenDevice();
156 156 return (CGLGraphicsConfig) gd.getDefaultConfiguration();
157 157 }
158 158 }
159 159
160 160 public static CGLGraphicsConfig getGC(CGLLayer layer) {
161 161 return (CGLGraphicsConfig)layer.getGraphicsConfiguration();
162 162 }
163 163
164 164 public void validate() {
165 165 // Overridden in CGLWindowSurfaceData below
166 166 }
167 167
168 168 @Override
169 169 public double getDefaultScaleX() {
170 170 return scale;
171 171 }
172 172
173 173 @Override
174 174 public double getDefaultScaleY() {
175 175 return scale;
176 176 }
177 177
178 178 protected native void clearWindow();
179 179
180 180 public static class CGLWindowSurfaceData extends CGLSurfaceData {
181 181
182 182 public CGLWindowSurfaceData(CPlatformView pView,
183 183 CGLGraphicsConfig gc) {
184 184 super(pView, gc, gc.getColorModel(), WINDOW, 0, 0);
185 185 }
186 186
187 187 @Override
188 188 public SurfaceData getReplacement() {
189 189 return pView.getSurfaceData();
190 190 }
191 191
192 192 @Override
193 193 public Rectangle getBounds() {
194 194 Rectangle r = pView.getBounds();
195 195 return new Rectangle(0, 0, r.width, r.height);
196 196 }
197 197
198 198 /**
199 199 * Returns destination Component associated with this SurfaceData.
200 200 */
201 201 @Override
202 202 public Object getDestination() {
203 203 return pView.getDestination();
204 204 }
205 205
206 206 public void validate() {
207 207 OGLRenderQueue rq = OGLRenderQueue.getInstance();
208 208 rq.lock();
209 209 try {
210 210 rq.flushAndInvokeNow(new Runnable() {
211 211 public void run() {
212 212 Rectangle peerBounds = pView.getBounds();
213 213 validate(0, 0, peerBounds.width, peerBounds.height, pView.isOpaque());
214 214 }
215 215 });
216 216 } finally {
217 217 rq.unlock();
218 218 }
219 219 }
220 220
221 221 @Override
222 222 public void invalidate() {
223 223 super.invalidate();
224 224 clearWindow();
225 225 }
226 226 }
227 227
228 228 /**
229 229 * A surface which implements an intermediate buffer between
230 230 * the Java2D flusher thread and the AppKit thread.
231 231 *
232 232 * This surface serves as a buffer attached to a CGLLayer and
233 233 * the layer redirects all painting to the buffer's graphics.
234 234 */
235 235 public static class CGLLayerSurfaceData extends CGLSurfaceData {
236 236
237 237 private CGLLayer layer;
238 238
239 239 public CGLLayerSurfaceData(CGLLayer layer, CGLGraphicsConfig gc,
240 240 int width, int height) {
241 241 super(layer, gc, gc.getColorModel(), FBOBJECT, width, height);
↓ open down ↓ |
241 lines elided |
↑ open up ↑ |
242 242 this.layer = layer;
243 243 initSurface(this.width, this.height);
244 244 }
245 245
246 246 @Override
247 247 public SurfaceData getReplacement() {
248 248 return layer.getSurfaceData();
249 249 }
250 250
251 251 @Override
252 - boolean isOnScreen() {
252 + public boolean isOnScreen() {
253 253 return true;
254 254 }
255 255
256 256 @Override
257 257 public Rectangle getBounds() {
258 258 return new Rectangle(width, height);
259 259 }
260 260
261 261 @Override
262 262 public Object getDestination() {
263 263 return layer.getDestination();
264 264 }
265 265
266 266 @Override
267 267 public int getTransparency() {
268 268 return layer.getTransparency();
269 269 }
270 270
271 271 @Override
272 272 public void invalidate() {
273 273 super.invalidate();
274 274 clearWindow();
275 275 }
276 276 }
277 277
278 278 /**
279 279 * A surface which implements a v-synced flip back-buffer with COPIED
280 280 * FlipContents.
281 281 *
282 282 * This surface serves as a back-buffer to the outside world, while it is
283 283 * actually an offscreen surface. When the BufferStrategy this surface
284 284 * belongs to is showed, it is first copied to the real private
285 285 * FLIP_BACKBUFFER, which is then flipped.
286 286 */
287 287 public static class CGLVSyncOffScreenSurfaceData extends
288 288 CGLOffScreenSurfaceData {
289 289 private CGLOffScreenSurfaceData flipSurface;
290 290
291 291 public CGLVSyncOffScreenSurfaceData(CPlatformView pView,
292 292 CGLGraphicsConfig gc, int width, int height, Image image,
293 293 ColorModel cm, int type) {
294 294 super(pView, gc, width, height, image, cm, type);
295 295 flipSurface = CGLSurfaceData.createData(pView, image,
296 296 FLIP_BACKBUFFER);
297 297 }
298 298
299 299 public SurfaceData getFlipSurface() {
300 300 return flipSurface;
301 301 }
302 302
303 303 @Override
304 304 public void flush() {
305 305 flipSurface.flush();
306 306 super.flush();
307 307 }
308 308 }
309 309
310 310 public static class CGLOffScreenSurfaceData extends CGLSurfaceData {
311 311 private Image offscreenImage;
312 312
313 313 public CGLOffScreenSurfaceData(CPlatformView pView,
314 314 CGLGraphicsConfig gc, int width, int height, Image image,
315 315 ColorModel cm, int type) {
316 316 super(pView, gc, cm, type, width, height);
317 317 offscreenImage = image;
318 318 initSurface(this.width, this.height);
319 319 }
320 320
321 321 @Override
322 322 public SurfaceData getReplacement() {
323 323 return restoreContents(offscreenImage);
324 324 }
325 325
326 326 @Override
327 327 public Rectangle getBounds() {
328 328 if (type == FLIP_BACKBUFFER) {
329 329 Rectangle r = pView.getBounds();
330 330 return new Rectangle(0, 0, r.width, r.height);
331 331 } else {
332 332 return new Rectangle(width, height);
333 333 }
334 334 }
335 335
336 336 /**
337 337 * Returns destination Image associated with this SurfaceData.
338 338 */
339 339 @Override
340 340 public Object getDestination() {
341 341 return offscreenImage;
342 342 }
343 343 }
344 344
345 345 // Mac OS X specific APIs for JOGL/Java2D bridge...
346 346
347 347 // given a surface create and attach GL context, then return it
348 348 private static native long createCGLContextOnSurface(CGLSurfaceData sd,
349 349 long sharedContext);
350 350
351 351 public static long createOGLContextOnSurface(Graphics g, long sharedContext) {
352 352 SurfaceData sd = ((SunGraphics2D) g).surfaceData;
353 353 if ((sd instanceof CGLSurfaceData) == true) {
354 354 CGLSurfaceData cglsd = (CGLSurfaceData) sd;
355 355 return createCGLContextOnSurface(cglsd, sharedContext);
356 356 } else {
357 357 return 0L;
358 358 }
359 359 }
360 360
361 361 // returns whether or not the makeCurrent operation succeeded
362 362 static native boolean makeCGLContextCurrentOnSurface(CGLSurfaceData sd,
363 363 long ctx);
364 364
365 365 public static boolean makeOGLContextCurrentOnSurface(Graphics g, long ctx) {
366 366 SurfaceData sd = ((SunGraphics2D) g).surfaceData;
367 367 if ((ctx != 0L) && ((sd instanceof CGLSurfaceData) == true)) {
368 368 CGLSurfaceData cglsd = (CGLSurfaceData) sd;
369 369 return makeCGLContextCurrentOnSurface(cglsd, ctx);
370 370 } else {
371 371 return false;
372 372 }
373 373 }
374 374
375 375 // additional cleanup
376 376 private static native void destroyCGLContext(long ctx);
377 377
378 378 public static void destroyOGLContext(long ctx) {
379 379 if (ctx != 0L) {
380 380 destroyCGLContext(ctx);
381 381 }
382 382 }
383 383 }
↓ open down ↓ |
121 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX