1 /* |
1 /* |
2 * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. Oracle designates this |
7 * published by the Free Software Foundation. Oracle designates this |
28 import java.awt.AWTException; |
28 import java.awt.AWTException; |
29 import java.awt.BufferCapabilities; |
29 import java.awt.BufferCapabilities; |
30 import java.awt.Component; |
30 import java.awt.Component; |
31 import java.awt.Graphics; |
31 import java.awt.Graphics; |
32 import java.awt.Graphics2D; |
32 import java.awt.Graphics2D; |
33 import java.awt.GraphicsConfiguration; |
|
34 import java.awt.GraphicsDevice; |
|
35 import java.awt.GraphicsEnvironment; |
|
36 import java.awt.Image; |
33 import java.awt.Image; |
37 import java.awt.ImageCapabilities; |
34 import java.awt.ImageCapabilities; |
38 import java.awt.Rectangle; |
35 import java.awt.Rectangle; |
39 import java.awt.Transparency; |
36 import java.awt.Transparency; |
40 import java.awt.color.ColorSpace; |
37 import java.awt.color.ColorSpace; |
78 private BufferCapabilities bufferCaps; |
75 private BufferCapabilities bufferCaps; |
79 private long pConfigInfo; |
76 private long pConfigInfo; |
80 private ContextCapabilities oglCaps; |
77 private ContextCapabilities oglCaps; |
81 private OGLContext context; |
78 private OGLContext context; |
82 private final Object disposerReferent = new Object(); |
79 private final Object disposerReferent = new Object(); |
|
80 private final int maxTextureSize; |
|
81 |
83 private static native boolean initCGL(); |
82 private static native boolean initCGL(); |
84 private static native long getCGLConfigInfo(int displayID, int visualnum, |
83 private static native long getCGLConfigInfo(int displayID, int visualnum, |
85 int swapInterval); |
84 int swapInterval); |
86 private static native int getOGLCapabilities(long configInfo); |
85 private static native int getOGLCapabilities(long configInfo); |
87 |
86 |
|
87 /** |
|
88 * Returns GL_MAX_TEXTURE_SIZE from the shared opengl context. Must be |
|
89 * called under OGLRQ lock, because this method change current context. |
|
90 * |
|
91 * @return GL_MAX_TEXTURE_SIZE |
|
92 */ |
|
93 private static native int nativeGetMaxTextureSize(); |
|
94 |
88 static { |
95 static { |
89 cglAvailable = initCGL(); |
96 cglAvailable = initCGL(); |
90 } |
97 } |
91 |
98 |
92 private CGLGraphicsConfig(CGraphicsDevice device, int pixfmt, |
99 private CGLGraphicsConfig(CGraphicsDevice device, int pixfmt, |
93 long configInfo, ContextCapabilities oglCaps) |
100 long configInfo, int maxTextureSize, |
94 { |
101 ContextCapabilities oglCaps) { |
95 super(device); |
102 super(device); |
96 |
103 |
97 this.pixfmt = pixfmt; |
104 this.pixfmt = pixfmt; |
98 this.pConfigInfo = configInfo; |
105 this.pConfigInfo = configInfo; |
99 this.oglCaps = oglCaps; |
106 this.oglCaps = oglCaps; |
|
107 this.maxTextureSize = maxTextureSize; |
100 context = new OGLContext(OGLRenderQueue.getInstance(), this); |
108 context = new OGLContext(OGLRenderQueue.getInstance(), this); |
101 |
109 |
102 // add a record to the Disposer so that we destroy the native |
110 // add a record to the Disposer so that we destroy the native |
103 // CGLGraphicsConfigInfo data when this object goes away |
111 // CGLGraphicsConfigInfo data when this object goes away |
104 Disposer.addRecord(disposerReferent, |
112 Disposer.addRecord(disposerReferent, |
136 OGLContext.invalidateCurrentContext(); |
145 OGLContext.invalidateCurrentContext(); |
137 |
146 |
138 cfginfo = getCGLConfigInfo(device.getCGDisplayID(), pixfmt, |
147 cfginfo = getCGLConfigInfo(device.getCGDisplayID(), pixfmt, |
139 kOpenGLSwapInterval); |
148 kOpenGLSwapInterval); |
140 if (cfginfo != 0L) { |
149 if (cfginfo != 0L) { |
|
150 textureSize = nativeGetMaxTextureSize(); |
|
151 // 7160609: GL still fails to create a square texture of this |
|
152 // size. Half should be safe enough. |
|
153 // Explicitly not support a texture more than 2^14, see 8010999. |
|
154 textureSize = textureSize <= 16384 ? textureSize / 2 : 8192; |
141 OGLContext.setScratchSurface(cfginfo); |
155 OGLContext.setScratchSurface(cfginfo); |
142 rq.flushAndInvokeNow(new Runnable() { |
156 rq.flushAndInvokeNow(() -> { |
143 public void run() { |
157 ids[0] = OGLContext.getOGLIdString(); |
144 ids[0] = OGLContext.getOGLIdString(); |
|
145 } |
|
146 }); |
158 }); |
147 } |
159 } |
148 } finally { |
160 } finally { |
149 rq.unlock(); |
161 rq.unlock(); |
150 } |
162 } |
152 return null; |
164 return null; |
153 } |
165 } |
154 |
166 |
155 int oglCaps = getOGLCapabilities(cfginfo); |
167 int oglCaps = getOGLCapabilities(cfginfo); |
156 ContextCapabilities caps = new OGLContextCaps(oglCaps, ids[0]); |
168 ContextCapabilities caps = new OGLContextCaps(oglCaps, ids[0]); |
157 |
169 return new CGLGraphicsConfig(device, pixfmt, cfginfo, textureSize, caps); |
158 return new CGLGraphicsConfig(device, pixfmt, cfginfo, caps); |
|
159 } |
170 } |
160 |
171 |
161 public static boolean isCGLAvailable() { |
172 public static boolean isCGLAvailable() { |
162 return cglAvailable; |
173 return cglAvailable; |
163 } |
174 } |
419 @Override |
428 @Override |
420 public void removeDeviceEventListener(AccelDeviceEventListener l) { |
429 public void removeDeviceEventListener(AccelDeviceEventListener l) { |
421 AccelDeviceEventNotifier.removeListener(l); |
430 AccelDeviceEventNotifier.removeListener(l); |
422 } |
431 } |
423 |
432 |
424 private static final Rectangle totalDisplayBounds = new Rectangle(); |
|
425 |
|
426 private static void updateTotalDisplayBounds() { |
|
427 synchronized (totalDisplayBounds) { |
|
428 Rectangle virtualBounds = new Rectangle(); |
|
429 for (GraphicsDevice gd : GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()) { |
|
430 for (GraphicsConfiguration gc : gd.getConfigurations()) { |
|
431 virtualBounds = virtualBounds.union(gc.getBounds()); |
|
432 } |
|
433 } |
|
434 totalDisplayBounds.setBounds(virtualBounds); |
|
435 } |
|
436 } |
|
437 |
|
438 // 7160609: GL still fails to create a square texture of this size, |
|
439 // so we use this value to cap the total display bounds. |
|
440 native private static int getMaxTextureSize(); |
|
441 |
|
442 @Override |
433 @Override |
443 public int getMaxTextureWidth() { |
434 public int getMaxTextureWidth() { |
444 //Temporary disable this logic and use some magic constrain. |
435 return Math.max(maxTextureSize / getDevice().getScaleFactor(), |
445 /* |
436 getBounds().width); |
446 int width; |
|
447 |
|
448 synchronized (totalDisplayBounds) { |
|
449 if (totalDisplayBounds.width == 0) { |
|
450 updateTotalDisplayBounds(); |
|
451 } |
|
452 width = totalDisplayBounds.width; |
|
453 } |
|
454 |
|
455 return Math.min(width, getMaxTextureSize()); |
|
456 */ |
|
457 return getMaxTextureSize() / (getDevice().getScaleFactor() * 2); |
|
458 } |
437 } |
459 |
438 |
460 @Override |
439 @Override |
461 public int getMaxTextureHeight() { |
440 public int getMaxTextureHeight() { |
462 //Temporary disable this logic and use some magic constrain. |
441 return Math.max(maxTextureSize / getDevice().getScaleFactor(), |
463 /* |
442 getBounds().height); |
464 int height; |
|
465 |
|
466 synchronized (totalDisplayBounds) { |
|
467 if (totalDisplayBounds.height == 0) { |
|
468 updateTotalDisplayBounds(); |
|
469 } |
|
470 height = totalDisplayBounds.height; |
|
471 } |
|
472 |
|
473 return Math.min(height, getMaxTextureSize()); |
|
474 */ |
|
475 return getMaxTextureSize() / (getDevice().getScaleFactor() * 2); |
|
476 } |
443 } |
477 } |
444 } |