1 /*
2 * Copyright (c) 2011, 2019, 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
47 import sun.awt.image.OffScreenImage;
48 import sun.awt.image.SunVolatileImage;
49 import sun.java2d.Disposer;
50 import sun.java2d.DisposerRecord;
51 import sun.java2d.Surface;
52 import sun.java2d.SurfaceData;
53 import sun.java2d.opengl.OGLContext.OGLContextCaps;
54 import sun.java2d.pipe.hw.AccelSurface;
55 import sun.java2d.pipe.hw.AccelTypedVolatileImage;
56 import sun.java2d.pipe.hw.ContextCapabilities;
57 import sun.lwawt.LWComponentPeer;
58
59 import static sun.java2d.opengl.OGLContext.OGLContextCaps.CAPS_DOUBLEBUFFERED;
60 import static sun.java2d.opengl.OGLContext.OGLContextCaps.CAPS_EXT_FBOBJECT;
61 import static sun.java2d.opengl.OGLSurfaceData.FBOBJECT;
62 import static sun.java2d.opengl.OGLSurfaceData.TEXTURE;
63
64 public final class CGLGraphicsConfig extends CGraphicsConfig
65 implements OGLGraphicsConfig
66 {
67 //private static final int kOpenGLSwapInterval =
68 // RuntimeOptions.getCurrentOptions().OpenGLSwapInterval;
69 private static final int kOpenGLSwapInterval = 0; // TODO
70 private static boolean cglAvailable;
71 private static ImageCapabilities imageCaps = new CGLImageCaps();
72
73 private int pixfmt;
74 private BufferCapabilities bufferCaps;
75 private long pConfigInfo;
76 private ContextCapabilities oglCaps;
77 private final OGLContext context;
78 private final Object disposerReferent = new Object();
79 private final int maxTextureSize;
80
81 private static native boolean initCGL();
82 private static native long getCGLConfigInfo(int displayID, int visualnum,
83 int swapInterval);
84 private static native int getOGLCapabilities(long configInfo);
85
86 /**
87 * Returns GL_MAX_TEXTURE_SIZE from the shared opengl context. Must be
88 * called under OGLRQ lock, because this method change current context.
89 *
90 * @return GL_MAX_TEXTURE_SIZE
91 */
92 private static native int nativeGetMaxTextureSize();
93
94 static {
95 cglAvailable = initCGL();
96 }
97
98 private CGLGraphicsConfig(CGraphicsDevice device, int pixfmt,
99 long configInfo, int maxTextureSize,
100 ContextCapabilities oglCaps) {
101 super(device);
102
103 this.pixfmt = pixfmt;
104 this.pConfigInfo = configInfo;
105 this.oglCaps = oglCaps;
106 this.maxTextureSize = maxTextureSize;
107 context = new OGLContext(OGLRenderQueue.getInstance());
108
109 // add a record to the Disposer so that we destroy the native
110 // CGLGraphicsConfigInfo data when this object goes away
111 Disposer.addRecord(disposerReferent,
112 new CGLGCDisposerRecord(pConfigInfo));
113 }
114
115 @Override
116 public Object getProxyKey() {
117 return this;
118 }
119
120 @Override
121 public SurfaceData createManagedSurface(int w, int h, int transparency) {
122 return CGLSurfaceData.createData(this, w, h,
123 getColorModel(transparency),
124 null,
125 OGLSurfaceData.TEXTURE);
126 }
127
128 public static CGLGraphicsConfig getConfig(CGraphicsDevice device,
129 int displayID, int pixfmt)
130 {
131 if (!cglAvailable) {
132 return null;
133 }
134
135 long cfginfo = 0;
136 int textureSize = 0;
137 final String[] ids = new String[1];
138 OGLRenderQueue rq = OGLRenderQueue.getInstance();
139 rq.lock();
140 try {
141 // getCGLConfigInfo() creates and destroys temporary
142 // surfaces/contexts, so we should first invalidate the current
143 // Java-level context and flush the queue...
144 OGLContext.invalidateCurrentContext();
145 cfginfo = getCGLConfigInfo(displayID, pixfmt, kOpenGLSwapInterval);
146 if (cfginfo != 0L) {
147 textureSize = nativeGetMaxTextureSize();
148 // 7160609: GL still fails to create a square texture of this
149 // size. Half should be safe enough.
150 // Explicitly not support a texture more than 2^14, see 8010999.
151 textureSize = textureSize <= 16384 ? textureSize / 2 : 8192;
152 OGLContext.setScratchSurface(cfginfo);
153 rq.flushAndInvokeNow(() -> {
154 ids[0] = OGLContext.getOGLIdString();
155 });
156 }
157 } finally {
158 rq.unlock();
159 }
160 if (cfginfo == 0) {
161 return null;
162 }
163
164 int oglCaps = getOGLCapabilities(cfginfo);
165 ContextCapabilities caps = new OGLContextCaps(oglCaps, ids[0]);
166 return new CGLGraphicsConfig(device, pixfmt, cfginfo, textureSize, caps);
167 }
168
169 public static boolean isCGLAvailable() {
170 return cglAvailable;
171 }
172
173 /**
174 * Returns true if the provided capability bit is present for this config.
175 * See OGLContext.java for a list of supported capabilities.
176 */
177 @Override
178 public boolean isCapPresent(int cap) {
179 return ((oglCaps.getCaps() & cap) != 0);
180 }
181
182 @Override
183 public long getNativeConfigInfo() {
184 return pConfigInfo;
185 }
186
236
237 // TODO: CGraphicsConfig doesn't implement displayChanged() yet
238 //@Override
239 public synchronized void displayChanged() {
240 //super.displayChanged();
241
242 // the context could hold a reference to a CGLSurfaceData, which in
243 // turn has a reference back to this CGLGraphicsConfig, so in order
244 // for this instance to be disposed we need to break the connection
245 OGLRenderQueue rq = OGLRenderQueue.getInstance();
246 rq.lock();
247 try {
248 OGLContext.invalidateCurrentContext();
249 } finally {
250 rq.unlock();
251 }
252 }
253
254 @Override
255 public String toString() {
256 String display = getDevice().getIDstring();
257 return ("CGLGraphicsConfig[" + display + ", pixfmt=" + pixfmt + "]");
258 }
259
260 @Override
261 public SurfaceData createSurfaceData(CGLLayer layer) {
262 return CGLSurfaceData.createData(layer);
263 }
264
265 @Override
266 public Image createAcceleratedImage(Component target,
267 int width, int height)
268 {
269 ColorModel model = getColorModel(Transparency.OPAQUE);
270 WritableRaster wr = model.createCompatibleWritableRaster(width, height);
271 return new OffScreenImage(target, model, wr,
272 model.isAlphaPremultiplied());
273 }
274
275 @Override
276 public void assertOperationSupported(final int numBuffers,
277 final BufferCapabilities caps)
|
1 /*
2 * Copyright (c) 2011, 2020, 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
47 import sun.awt.image.OffScreenImage;
48 import sun.awt.image.SunVolatileImage;
49 import sun.java2d.Disposer;
50 import sun.java2d.DisposerRecord;
51 import sun.java2d.Surface;
52 import sun.java2d.SurfaceData;
53 import sun.java2d.opengl.OGLContext.OGLContextCaps;
54 import sun.java2d.pipe.hw.AccelSurface;
55 import sun.java2d.pipe.hw.AccelTypedVolatileImage;
56 import sun.java2d.pipe.hw.ContextCapabilities;
57 import sun.lwawt.LWComponentPeer;
58
59 import static sun.java2d.opengl.OGLContext.OGLContextCaps.CAPS_DOUBLEBUFFERED;
60 import static sun.java2d.opengl.OGLContext.OGLContextCaps.CAPS_EXT_FBOBJECT;
61 import static sun.java2d.opengl.OGLSurfaceData.FBOBJECT;
62 import static sun.java2d.opengl.OGLSurfaceData.TEXTURE;
63
64 public final class CGLGraphicsConfig extends CGraphicsConfig
65 implements OGLGraphicsConfig
66 {
67 private static boolean cglAvailable;
68 private static ImageCapabilities imageCaps = new CGLImageCaps();
69
70 private BufferCapabilities bufferCaps;
71 private long pConfigInfo;
72 private ContextCapabilities oglCaps;
73 private final OGLContext context;
74 private final Object disposerReferent = new Object();
75 private final int maxTextureSize;
76
77 private static native boolean initCGL();
78 private static native long getCGLConfigInfo();
79 private static native int getOGLCapabilities(long configInfo);
80
81 /**
82 * Returns GL_MAX_TEXTURE_SIZE from the shared opengl context. Must be
83 * called under OGLRQ lock, because this method change current context.
84 *
85 * @return GL_MAX_TEXTURE_SIZE
86 */
87 private static native int nativeGetMaxTextureSize();
88
89 static {
90 cglAvailable = initCGL();
91 }
92
93 private CGLGraphicsConfig(CGraphicsDevice device, long configInfo,
94 int maxTextureSize, ContextCapabilities oglCaps) {
95 super(device);
96 this.pConfigInfo = configInfo;
97 this.oglCaps = oglCaps;
98 this.maxTextureSize = maxTextureSize;
99 context = new OGLContext(OGLRenderQueue.getInstance());
100
101 // add a record to the Disposer so that we destroy the native
102 // CGLGraphicsConfigInfo data when this object goes away
103 Disposer.addRecord(disposerReferent,
104 new CGLGCDisposerRecord(pConfigInfo));
105 }
106
107 @Override
108 public Object getProxyKey() {
109 return this;
110 }
111
112 @Override
113 public SurfaceData createManagedSurface(int w, int h, int transparency) {
114 return CGLSurfaceData.createData(this, w, h,
115 getColorModel(transparency),
116 null,
117 OGLSurfaceData.TEXTURE);
118 }
119
120 public static CGLGraphicsConfig getConfig(CGraphicsDevice device)
121 {
122 if (!cglAvailable) {
123 return null;
124 }
125
126 long cfginfo = 0;
127 int textureSize = 0;
128 final String[] ids = new String[1];
129 OGLRenderQueue rq = OGLRenderQueue.getInstance();
130 rq.lock();
131 try {
132 // getCGLConfigInfo() creates and destroys temporary
133 // surfaces/contexts, so we should first invalidate the current
134 // Java-level context and flush the queue...
135 OGLContext.invalidateCurrentContext();
136 cfginfo = getCGLConfigInfo();
137 if (cfginfo != 0L) {
138 textureSize = nativeGetMaxTextureSize();
139 // 7160609: GL still fails to create a square texture of this
140 // size. Half should be safe enough.
141 // Explicitly not support a texture more than 2^14, see 8010999.
142 textureSize = textureSize <= 16384 ? textureSize / 2 : 8192;
143 OGLContext.setScratchSurface(cfginfo);
144 rq.flushAndInvokeNow(() -> {
145 ids[0] = OGLContext.getOGLIdString();
146 });
147 }
148 } finally {
149 rq.unlock();
150 }
151 if (cfginfo == 0) {
152 return null;
153 }
154
155 int oglCaps = getOGLCapabilities(cfginfo);
156 ContextCapabilities caps = new OGLContextCaps(oglCaps, ids[0]);
157 return new CGLGraphicsConfig(device, cfginfo, textureSize, caps);
158 }
159
160 public static boolean isCGLAvailable() {
161 return cglAvailable;
162 }
163
164 /**
165 * Returns true if the provided capability bit is present for this config.
166 * See OGLContext.java for a list of supported capabilities.
167 */
168 @Override
169 public boolean isCapPresent(int cap) {
170 return ((oglCaps.getCaps() & cap) != 0);
171 }
172
173 @Override
174 public long getNativeConfigInfo() {
175 return pConfigInfo;
176 }
177
227
228 // TODO: CGraphicsConfig doesn't implement displayChanged() yet
229 //@Override
230 public synchronized void displayChanged() {
231 //super.displayChanged();
232
233 // the context could hold a reference to a CGLSurfaceData, which in
234 // turn has a reference back to this CGLGraphicsConfig, so in order
235 // for this instance to be disposed we need to break the connection
236 OGLRenderQueue rq = OGLRenderQueue.getInstance();
237 rq.lock();
238 try {
239 OGLContext.invalidateCurrentContext();
240 } finally {
241 rq.unlock();
242 }
243 }
244
245 @Override
246 public String toString() {
247 return ("CGLGraphicsConfig[" + getDevice().getIDstring() + "]");
248 }
249
250 @Override
251 public SurfaceData createSurfaceData(CGLLayer layer) {
252 return CGLSurfaceData.createData(layer);
253 }
254
255 @Override
256 public Image createAcceleratedImage(Component target,
257 int width, int height)
258 {
259 ColorModel model = getColorModel(Transparency.OPAQUE);
260 WritableRaster wr = model.createCompatibleWritableRaster(width, height);
261 return new OffScreenImage(target, model, wr,
262 model.isAlphaPremultiplied());
263 }
264
265 @Override
266 public void assertOperationSupported(final int numBuffers,
267 final BufferCapabilities caps)
|