JOGL v2.6.0-rc-20250822
JOGL, High-Performance Graphics Binding for Java™ (public API).
GLCanvas.java
Go to the documentation of this file.
1/**
2 * Copyright 2011 JogAmp Community. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification, are
5 * permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * The views and conclusions contained in the software and documentation are those of the
25 * authors and should not be interpreted as representing official policies, either expressed
26 * or implied, of JogAmp Community.
27 */
28package com.jogamp.opengl.swt;
29
30import java.util.List;
31
32import com.jogamp.nativewindow.AbstractGraphicsConfiguration;
33import com.jogamp.nativewindow.AbstractGraphicsDevice;
34import com.jogamp.nativewindow.AbstractGraphicsScreen;
35import com.jogamp.nativewindow.GraphicsConfigurationFactory;
36import com.jogamp.nativewindow.NativeSurface;
37import com.jogamp.nativewindow.NativeWindowException;
38import com.jogamp.nativewindow.ProxySurface;
39import com.jogamp.nativewindow.UpstreamSurfaceHook;
40import com.jogamp.nativewindow.VisualIDHolder;
41import com.jogamp.nativewindow.VisualIDHolder.VIDType;
42import com.jogamp.opengl.GL;
43import com.jogamp.opengl.GLAnimatorControl;
44import com.jogamp.opengl.GLAutoDrawable;
45import com.jogamp.opengl.GLCapabilities;
46import com.jogamp.opengl.GLCapabilitiesChooser;
47import com.jogamp.opengl.GLCapabilitiesImmutable;
48import com.jogamp.opengl.GLContext;
49import com.jogamp.opengl.GLDrawable;
50import com.jogamp.opengl.GLDrawableFactory;
51import com.jogamp.opengl.GLEventListener;
52import com.jogamp.opengl.GLException;
53import com.jogamp.opengl.GLProfile;
54import com.jogamp.opengl.GLRunnable;
55import com.jogamp.opengl.GLSharedContextSetter;
56import com.jogamp.opengl.Threading;
57
58import jogamp.nativewindow.macosx.OSXUtil;
59import jogamp.nativewindow.x11.X11Util;
60import jogamp.opengl.Debug;
61import jogamp.opengl.GLContextImpl;
62import jogamp.opengl.GLDrawableHelper;
63import jogamp.opengl.GLDrawableImpl;
64
65import org.eclipse.swt.SWT;
66import org.eclipse.swt.graphics.Color;
67import org.eclipse.swt.graphics.Rectangle;
68import org.eclipse.swt.internal.DPIUtil;
69import org.eclipse.swt.layout.FillLayout;
70import org.eclipse.swt.widgets.Canvas;
71import org.eclipse.swt.widgets.Composite;
72import org.eclipse.swt.widgets.Display;
73import org.eclipse.swt.widgets.Event;
74import org.eclipse.swt.widgets.Listener;
75import org.eclipse.swt.widgets.Shell;
76
77import com.jogamp.common.GlueGenVersion;
78import com.jogamp.common.os.Platform;
79import com.jogamp.common.util.VersionUtil;
80import com.jogamp.common.util.locks.LockFactory;
81import com.jogamp.common.util.locks.RecursiveLock;
82import com.jogamp.nativewindow.swt.SWTAccessor;
83import com.jogamp.nativewindow.x11.X11GraphicsDevice;
84import com.jogamp.opengl.JoglVersion;
85
86/**
87 * Native SWT Canvas implementing GLAutoDrawable
88 * <p>
89 * Implementation allows use of custom {@link GLCapabilities}.
90 * </p>
91 * <p>
92 * <a name="contextSharing"><h5>OpenGL Context Sharing</h5></a>
93 * To share a {@link GLContext} see the following note in the documentation overview:
94 * <a href="../../../../overview-summary.html#SHARING">context sharing</a>
95 * as well as {@link GLSharedContextSetter}.
96 * </p>
97 */
98public class GLCanvas extends Canvas implements GLAutoDrawable, GLSharedContextSetter {
99 private static final boolean DEBUG = Debug.debug("GLCanvas");
100
101 /*
102 * Flag for whether the SWT thread should be used for OpenGL calls when in single-threaded mode. This is controlled
103 * by the setting of the threading mode to worker (do not use SWT thread), awt (use SWT thread), or false (always use
104 * calling thread).
105 *
106 * @see Threading
107 *
108 * Now done dynamically to avoid early loading of gluegen library.
109 */
110 //private static final boolean useSWTThread = ThreadingImpl.getMode() != ThreadingImpl.WORKER;
111
112 /* GL Stuff */
113 private final RecursiveLock lock = LockFactory.createRecursiveLock();
114 private final GLDrawableHelper helper = new GLDrawableHelper();
115
116 private final GLCapabilitiesImmutable capsRequested;
117 private final GLCapabilitiesChooser capsChooser;
118
119 private volatile Rectangle clientAreaPixels, clientAreaWindow;
120 private volatile GLDrawableImpl drawable; // volatile: avoid locking for read-only access
121 private volatile GLContextImpl context; // volatile: avoid locking for read-only access
122
123 /* Native window surface */
124 private final boolean useX11GTK;
125 private volatile long x11Window; // .. or X11 child window (for GL rendering)
126 private final AbstractGraphicsScreen screen;
127
128 /* Construction parameters stored for GLAutoDrawable accessor methods */
129 private int additionalCtxCreationFlags = 0;
130
131
132 /* Flag indicating whether an unprocessed reshape is pending. */
133 private volatile boolean sendReshape; // volatile: maybe written by WindowManager thread w/o locking
134
135 private static String getThreadName() { return Thread.currentThread().getName(); }
136 private static String toHexString(final int v) { return "0x"+Integer.toHexString(v); }
137 private static String toHexString(final long v) { return "0x"+Long.toHexString(v); }
138
139 /*
140 * Invokes init(...) on all GLEventListeners. Assumes context is current when run.
141 */
142 private final Runnable initAction = new Runnable() {
143 @Override
144 public void run() {
145 helper.init(GLCanvas.this, !sendReshape);
146 }
147 };
148
149 /*
150 * Action to handle display in OpenGL, also processes reshape since they should be done at the same time.
151 *
152 * Assumes GLContext is current when run.
153 */
154 private final Runnable displayAction = new Runnable() {
155 @Override
156 public void run() {
157 if (sendReshape) {
158 helper.reshape(GLCanvas.this, 0, 0, clientAreaPixels.width, clientAreaPixels.height);
159 sendReshape = false;
160 }
161 helper.display(GLCanvas.this);
162 }
163 };
164
165 /* Action to make specified context current prior to running displayAction */
166 private final Runnable makeCurrentAndDisplayOnGLAction = new Runnable() {
167 @Override
168 public void run() {
169 final RecursiveLock _lock = lock;
170 _lock.lock();
171 try {
172 if( !GLCanvas.this.isDisposed() ) {
173 helper.invokeGL(drawable, context, displayAction, initAction);
174 }
175 } finally {
176 _lock.unlock();
177 }
178 }
179 };
180
181 /* Swaps buffers, assuming the GLContext is current */
182 private final Runnable swapBuffersOnGLAction = new Runnable() {
183 @Override
184 public void run() {
185 final RecursiveLock _lock = lock;
186 _lock.lock();
187 try {
188 final boolean drawableOK = null != drawable && drawable.isRealized();
189 if( drawableOK && !GLCanvas.this.isDisposed() ) {
190 drawable.swapBuffers();
191 }
192 } finally {
193 _lock.unlock();
194 }
195 }
196 };
197
198 /*
199 * Disposes of OpenGL resources
200 */
201 private final Runnable disposeOnEDTGLAction = new Runnable() {
202 @Override
203 public void run() {
204 final RecursiveLock _lock = lock;
205 _lock.lock();
206 try {
207 final GLAnimatorControl animator = getAnimator();
208 final boolean animatorPaused;
209 if(null!=animator) {
210 // can't remove us from animator for recreational addNotify()
211 animatorPaused = animator.pause();
212 } else {
213 animatorPaused = false;
214 }
215
216 GLException exceptionOnDisposeGL = null;
217 if( null != context ) {
218 if( context.isCreated() ) {
219 try {
220 if( !GLCanvas.this.isDisposed() ) {
221 helper.disposeGL(GLCanvas.this, context, true);
222 } else {
223 context.destroy();
224 }
225 } catch (final GLException gle) {
226 exceptionOnDisposeGL = gle;
227 }
228 }
229 context = null;
230 }
231
232 Throwable exceptionOnUnrealize = null;
233 if( null != drawable ) {
234 try {
235 drawable.setRealized(false);
236 } catch( final Throwable re ) {
237 exceptionOnUnrealize = re;
238 }
239 drawable = null;
240 }
241
242 Throwable exceptionOnDeviceClose = null;
243 try {
244 if( 0 != x11Window) {
245 SWTAccessor.destroyX11Window(screen.getDevice(), x11Window);
246 x11Window = 0;
247 }
248 screen.getDevice().close();
249 } catch (final Throwable re) {
250 exceptionOnDeviceClose = re;
251 }
252
253 if (animatorPaused) {
254 animator.resume();
255 }
256
257 // throw exception in order of occurrence ..
258 if( null != exceptionOnDisposeGL ) {
259 throw exceptionOnDisposeGL;
260 }
261 if( null != exceptionOnUnrealize ) {
262 throw GLException.newGLException(exceptionOnUnrealize);
263 }
264 if( null != exceptionOnDeviceClose ) {
265 throw GLException.newGLException(exceptionOnDeviceClose);
266 }
267 } finally {
268 _lock.unlock();
269 }
270 }
271 };
272
273 private class DisposeGLEventListenerAction implements Runnable {
274 private GLEventListener listener;
275 private final boolean remove;
276 private DisposeGLEventListenerAction(final GLEventListener listener, final boolean remove) {
277 this.listener = listener;
278 this.remove = remove;
279 }
280
281 @Override
282 public void run() {
283 final RecursiveLock _lock = lock;
284 _lock.lock();
285 try {
286 if( !GLCanvas.this.isDisposed() ) {
287 listener = helper.disposeGLEventListener(GLCanvas.this, drawable, context, listener, remove);
288 }
289 } finally {
290 _lock.unlock();
291 }
292 }
293 };
294
295 /**
296 * Creates an instance using {@link #GLCanvas(Composite, int, GLCapabilitiesImmutable, GLCapabilitiesChooser)}
297 * on the SWT thread.
298 *
299 * @param parent
300 * Required (non-null) parent Composite.
301 * @param style
302 * Optional SWT style bit-field. The {@link SWT#NO_BACKGROUND} bit is set before passing this up to the
303 * Canvas constructor, so OpenGL handles the background.
304 * @param caps
305 * Optional GLCapabilities. If not provided, the default capabilities for the default GLProfile for the
306 * graphics device determined by the parent Composite are used. Note that the GLCapabilities that are
307 * actually used may differ based on the capabilities of the graphics device.
308 * @param chooser
309 * Optional GLCapabilitiesChooser to customize the selection of the used GLCapabilities based on the
310 * requested GLCapabilities, and the available capabilities of the graphics device.
311 * @return a new instance
312 */
313 public static GLCanvas create(final Composite parent, final int style, final GLCapabilitiesImmutable caps,
314 final GLCapabilitiesChooser chooser) {
315 final GLCanvas[] res = new GLCanvas[] { null };
316 parent.getDisplay().syncExec(new Runnable() {
317 @Override
318 public void run() {
319 res[0] = new GLCanvas( parent, style, caps, chooser );
320 }
321 });
322 return res[0];
323 }
324
325 /**
326 * Creates a new SWT GLCanvas.
327 *
328 * @param parent
329 * Required (non-null) parent Composite.
330 * @param style
331 * Optional SWT style bit-field. The {@link SWT#NO_BACKGROUND} bit is set before passing this up to the
332 * Canvas constructor, so OpenGL handles the background.
333 * @param capsReqUser
334 * Optional GLCapabilities. If not provided, the default capabilities for the default GLProfile for the
335 * graphics device determined by the parent Composite are used. Note that the GLCapabilities that are
336 * actually used may differ based on the capabilities of the graphics device.
337 * @param capsChooser
338 * Optional GLCapabilitiesChooser to customize the selection of the used GLCapabilities based on the
339 * requested GLCapabilities, and the available capabilities of the graphics device.
340 */
341 public GLCanvas(final Composite parent, final int style, final GLCapabilitiesImmutable capsReqUser,
342 final GLCapabilitiesChooser capsChooser) {
343 /* NO_BACKGROUND required to avoid clearing bg in native SWT widget (we do this in the GL display) */
344 super(parent, style | SWT.NO_BACKGROUND);
345
346 GLProfile.initSingleton(); // ensure JOGL is completely initialized
347
348 SWTAccessor.setRealized(this, true);
349
350 clientAreaPixels = SWTAccessor.getClientAreaInPixels(this);
351 clientAreaWindow = getClientArea();
352
353 /* Get the nativewindow-Graphics Device associated with this control (which is determined by the parent Composite).
354 * Note: SWT is owner of the native handle, hence closing operation will be a NOP. */
355 final AbstractGraphicsDevice swtDevice = SWTAccessor.getDevice(this);
356
357 useX11GTK = SWTAccessor.useX11GTK();
358 if(useX11GTK) {
359 // Decoupled X11 Device/Screen allowing X11 display lock-free off-thread rendering
360 final long x11DeviceHandle = X11Util.openDisplay(swtDevice.getConnection());
361 if( 0 == x11DeviceHandle ) {
362 throw new RuntimeException("Error creating display(EDT): "+swtDevice.getConnection());
363 }
364 final AbstractGraphicsDevice x11Device = new X11GraphicsDevice(x11DeviceHandle, AbstractGraphicsDevice.DEFAULT_UNIT, true /* owner */);
365 screen = SWTAccessor.getScreen(x11Device, -1 /* default */);
366 } else {
367 screen = SWTAccessor.getScreen(swtDevice, -1 /* default */);
368 }
369
370 /* Select default GLCapabilities if none was provided, otherwise use cloned provided caps */
371 if(null == capsReqUser) {
372 this.capsRequested = new GLCapabilities(GLProfile.getDefault(screen.getDevice()));
373 } else {
374 this.capsRequested = (GLCapabilitiesImmutable) capsReqUser.cloneMutable();
375 }
376 this.capsChooser = capsChooser;
377
378 // post create .. when ready
379 x11Window = 0;
380 drawable = null;
381 context = null;
382
383 // Bug 1362 fix or workaround: Seems SWT/GTK3 at least performs lazy initialization
384 // Minimal action required: setBackground of the parent canvas before reparenting!
385 //
386 // SWT 3.110 (Eclipse 4.10?) would require color to be disposed, hence use pre-allocated.
387 // Since at least 'Eclipse 4.26.0 Release Build: 4.26' no more disposal of Color required.
388 setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WHITE));
389
390 final Listener listener = new Listener () {
391 @Override
392 public void handleEvent (final Event event) {
393 switch (event.type) {
394 case SWT.Paint:
395 displayIfNoAnimatorNoCheck();
396 break;
397 case SWT.Resize:
398 if (DEBUG) { System.err.println(getThreadName()+": SWT.GLCanvas.Resize.0 "+toString()); }
400 break;
401 case SWT.ZoomChanged:
402 if (DEBUG) { System.err.println(getThreadName()+": SWT.GLCanvas.ZoomChanged.0 "+toString()); }
404 break;
405 case SWT.Dispose:
406 if (DEBUG) { System.err.println(getThreadName()+": SWT.GLCanvas.Dispose.0 "+toString()); }
407 GLCanvas.this.dispose();
408 break;
409 }
410 }
411 };
412 addListener (SWT.Resize, listener);
413 addListener (SWT.Paint, listener);
414 addListener (SWT.Dispose, listener);
415 }
416
417 @Override
418 public final void setSharedContext(final GLContext sharedContext) throws IllegalStateException {
419 helper.setSharedContext(this.context, sharedContext);
420 }
421
422 @Override
423 public final void setSharedAutoDrawable(final GLAutoDrawable sharedAutoDrawable) throws IllegalStateException {
424 helper.setSharedAutoDrawable(this, sharedAutoDrawable);
425 }
426
427 private final UpstreamSurfaceHook swtCanvasUpStreamHook = new UpstreamSurfaceHook() {
428 @Override
429 public final void create(final ProxySurface s) { /* nop */ }
430
431 @Override
432 public final void destroy(final ProxySurface s) { /* nop */ }
433
434 @Override
435 public final int getSurfaceWidth(final ProxySurface s) {
436 return clientAreaPixels.width;
437 }
438
439 @Override
440 public final int getSurfaceHeight(final ProxySurface s) {
441 return clientAreaPixels.height;
442 }
443
444 @Override
445 public String toString() {
446 return "SWTCanvasUpstreamSurfaceHook[upstream: "+GLCanvas.this.toString()+", "+clientAreaPixels.width+"x"+clientAreaPixels.height+" [pixel], "+clientAreaWindow.width+"x"+clientAreaWindow.height+" [win]]";
447 }
448
449 /**
450 * {@inheritDoc}
451 * <p>
452 * Returns <code>null</code>.
453 * </p>
454 */
455 @Override
456 public final NativeSurface getUpstreamSurface() {
457 return null;
458 }
459 };
460
461 protected final void updateSizeCheck() {
462 final Rectangle oClientAreaPixels = clientAreaPixels;
463 final Rectangle nClientAreaPixels = SWTAccessor.getClientAreaInPixels(this);
464
465 if(DEBUG) {
466 System.err.println(getThreadName()+": GLCanvas.sizeChanged: clientAreaPixels.o "+getClientArea());
467 System.err.println(getThreadName()+": GLCanvas.sizeChanged: clientAreaPixels.n "+nClientAreaPixels);
468 }
469
470 if ( nClientAreaPixels != null &&
471 ( nClientAreaPixels.width != oClientAreaPixels.width || nClientAreaPixels.height != oClientAreaPixels.height )
472 ) {
473 clientAreaPixels = nClientAreaPixels; // write back new value
474 clientAreaWindow = getClientArea();
475
476 final GLDrawableImpl _drawable = drawable;
477 final boolean drawableOK = null != _drawable && _drawable.isRealized();
478 if(DEBUG) {
479 final long dh = drawableOK ? _drawable.getHandle() : 0;
480 System.err.println(getThreadName()+": GLCanvas.sizeChanged: ("+Thread.currentThread().getName()+"): "+nClientAreaPixels.x+"/"+nClientAreaPixels.y+" "+nClientAreaPixels.width+"x"+nClientAreaPixels.height+" - drawableHandle "+toHexString(dh));
481 }
482 if( drawableOK ) {
483 if( ! _drawable.getChosenGLCapabilities().isOnscreen() ) {
484 final RecursiveLock _lock = lock;
485 _lock.lock();
486 try {
487 final GLDrawableImpl _drawableNew = GLDrawableHelper.resizeOffscreenDrawable(_drawable, context, nClientAreaPixels.width, nClientAreaPixels.height);
488 if(_drawable != _drawableNew) {
489 // write back
490 drawable = _drawableNew;
491 }
492 } finally {
493 _lock.unlock();
494 }
495 }
496 }
497 if(0 != x11Window) {
498 SWTAccessor.resizeX11Window(screen.getDevice(), clientAreaPixels, x11Window);
499 }
500 sendReshape = true; // async if display() doesn't get called below, but avoiding deadlock
501 }
502 }
503
504 private boolean isValidAndVisibleOnEDTActionResult;
505 private final Runnable isValidAndVisibleOnEDTAction = new Runnable() {
506 @Override
507 public void run() {
508 isValidAndVisibleOnEDTActionResult = !GLCanvas.this.isDisposed() && GLCanvas.this.isVisible();
509 } };
510
511 private final boolean isValidAndVisibleOnEDT() {
512 synchronized(isValidAndVisibleOnEDTAction) {
513 runOnEDTIfAvail(true, isValidAndVisibleOnEDTAction);
514 return isValidAndVisibleOnEDTActionResult;
515 }
516 }
517
518 /** assumes drawable == null (implying !drawable.isRealized()) ! Checks of !isDispose() and isVisible() */
519 protected final boolean validateDrawableAndContextWithCheck() {
520 if( !isValidAndVisibleOnEDT() ) {
521 return false;
522 }
523 return validateDrawableAndContextPostCheck();
524 }
525
526 private final boolean isDrawableAndContextValid() {
527 // drawable != null implies drawable.isRealized()==true
528 return null != drawable && null != context;
529 }
530
531 /** assumes drawable == null (implying !drawable.isRealized()) || context == null ! No check of !isDispose() and isVisible() */
532 private final boolean validateDrawableAndContextPostCheck() {
533 boolean res;
534 final RecursiveLock _lock = lock;
535 _lock.lock();
536 try {
537 if(null == drawable) {
538 // 'displayable' (isValidAndVisibleOnEDT()) must have been checked upfront if appropriate!
539 createDrawableImpl(); // checks clientArea size (i.e. drawable size) and perf. realization
540 }
541 final GLDrawable _drawable = drawable;
542 if ( null != _drawable ) {
543 // drawable realization goes in-hand w/ it's construction
544 if( null == context ) {
545 // re-try context creation
546 res = createContextImpl(_drawable); // pending creation.
547 } else {
548 res = true;
549 }
550 if(res) {
551 sendReshape = true;
552 }
553 } else {
554 if(DEBUG) {
555 System.err.println(getThreadName()+": SWT.GLCanvas.validate "+toHexString(hashCode())+": null drawable");
556 }
557 res = false;
558 }
559 if(DEBUG) {
560 final boolean isDrawableNull = null == drawable;
561 final boolean isDrawableRealized = !isDrawableNull ? drawable.isRealized() : false;
562 System.err.println(getThreadName()+": SWT.GLCanvas.validate.X "+toHexString(hashCode())+": "+res+", drawable[null "+isDrawableNull+", realized "+isDrawableRealized+"], has context "+(null!=context));
563 }
564 } finally {
565 _lock.unlock();
566 }
567 return res;
568 }
569 private final void createDrawableImpl() {
570 final Rectangle nClientArea = clientAreaPixels;
571 if(0 >= nClientArea.width || 0 >= nClientArea.height) {
572 if(DEBUG) {
573 System.err.println(getThreadName()+": SWT.GLCanvas.validate.X "+toHexString(hashCode())+": drawable could not be created: size < 0x0");
574 }
575 return; // early out
576 }
577 final AbstractGraphicsDevice device = screen.getDevice();
578 device.open();
579
580 final long nativeWindowHandle;
581 if( useX11GTK ) {
582 final GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(device, capsRequested);
583 final AbstractGraphicsConfiguration cfg = factory.chooseGraphicsConfiguration(
584 capsRequested, capsRequested, capsChooser, screen, VisualIDHolder.VID_UNDEFINED);
585 if(DEBUG) {
586 System.err.println(getThreadName()+": SWT.GLCanvas.X11 "+toHexString(hashCode())+": factory: "+factory+", chosen config: "+cfg);
587 }
588 if (null == cfg) {
589 throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
590 }
591 final int visualID = cfg.getVisualID(VIDType.NATIVE);
592 if( VisualIDHolder.VID_UNDEFINED != visualID ) {
593 // gdkWindow = SWTAccessor.createCompatibleGDKChildWindow(this, visualID, clientArea.width, clientArea.height);
594 // nativeWindowHandle = SWTAccessor.gdk_window_get_xwindow(gdkWindow);
595 x11Window = SWTAccessor.createCompatibleX11ChildWindow(screen, this, visualID, clientAreaPixels.width, clientAreaPixels.height);
596 nativeWindowHandle = x11Window;
597 } else {
598 throw new GLException("Could not choose valid visualID: "+toHexString(visualID)+", "+this);
599 }
600 } else {
601 nativeWindowHandle = SWTAccessor.getWindowHandle(this);
602 if( SWTAccessor.isOSX ) {
603 final float reqPixelScale = DPIUtil.autoScaleUp(this, 1f);
604 if( DEBUG ) {
605 System.err.println(getThreadName()+": SWT.GLCanvas.OSX "+toHexString(hashCode())+": Scaling: devZoom "+DPIUtil.getDeviceZoom()+", general "+DPIUtil.autoScaleUp(1f)+", onWidged "+reqPixelScale);
606 }
607 if( reqPixelScale > 1f ) {
608 OSXUtil.SetWindowPixelScale(nativeWindowHandle, reqPixelScale);
609 }
610 }
611 }
612 final GLDrawableFactory glFactory = GLDrawableFactory.getFactory(capsRequested.getGLProfile());
613
614 // Create a NativeWindow proxy for the SWT canvas
615 final ProxySurface proxySurface = glFactory.createProxySurface(device, screen.getIndex(), nativeWindowHandle,
616 capsRequested, capsChooser, swtCanvasUpStreamHook);
617 // Associate a GL surface with the proxy
618 final GLDrawableImpl _drawable = (GLDrawableImpl) glFactory.createGLDrawable(proxySurface);
619 _drawable.setRealized(true);
620 if(!_drawable.isRealized()) {
621 // oops
622 if(DEBUG) {
623 System.err.println(getThreadName()+": SWT.GLCanvas.validate.X "+proxySurface);
624 System.err.println(getThreadName()+": SWT.GLCanvas.validate.X "+toHexString(hashCode())+": Drawable could not be realized: "+_drawable);
625 }
626 } else {
627 if(DEBUG) {
628 System.err.println(getThreadName()+": SWT.GLCanvas.validate "+proxySurface);
629 System.err.println(getThreadName()+": SWT.GLCanvas.validate "+toHexString(hashCode())+": Drawable created and realized: "+_drawable);
630 }
631 drawable = _drawable;
632 }
633 }
634 private boolean createContextImpl(final GLDrawable drawable) {
635 final GLContext[] shareWith = { null };
636 if( !helper.isSharedGLContextPending(shareWith) ) {
637 context = (GLContextImpl) drawable.createContext(shareWith[0]);
638 context.setContextCreationFlags(additionalCtxCreationFlags);
639 if(DEBUG) {
640 System.err.println(getThreadName()+": SWT.GLCanvas.validate "+toHexString(hashCode())+": Context created: has shared "+(null != shareWith[0]));
641 }
642 return true;
643 } else {
644 if(DEBUG) {
645 System.err.println(getThreadName()+": SWT.GLCanvas.validate "+toHexString(hashCode())+": Context !created: pending share");
646 }
647 return false;
648 }
649 }
650
651 @Override
652 public void update() {
653 // don't paint background etc .. nop avoids flickering
654 // super.update();
655 }
656
657 /**
658 @Override
659 public boolean forceFocus() {
660 final boolean r = super.forceFocus();
661 if(r && 0 != gdkWindow) {
662 SWTGTKUtil.focusGDKWindow(gdkWindow);
663 }
664 return r;
665 } */
666
667 @Override
668 public void dispose() {
669 runInGLThread(disposeOnEDTGLAction);
670 super.dispose();
671 }
672
673 private final void displayIfNoAnimatorNoCheck() {
674 if ( !helper.isAnimatorAnimatingOnOtherThread() ) {
675 if( isDrawableAndContextValid() || validateDrawableAndContextPostCheck() ) {
676 runInGLThread(makeCurrentAndDisplayOnGLAction);
677 }
678 }
679 }
680
681 //
682 // GL[Auto]Drawable
683 //
684
685 @Override
686 public void display() {
687 if( isDrawableAndContextValid() || validateDrawableAndContextWithCheck() ) {
688 runInGLThread(makeCurrentAndDisplayOnGLAction);
689 }
690 }
691
692 @Override
693 public final Object getUpstreamWidget() {
694 return this;
695 }
696
697 @Override
698 public final RecursiveLock getUpstreamLock() { return lock; }
699
700 @Override
701 public int getSurfaceWidth() {
702 return clientAreaPixels.width;
703 }
704
705 @Override
706 public int getSurfaceHeight() {
707 return clientAreaPixels.height;
708 }
709
710 @Override
711 public boolean isGLOriented() {
712 final GLDrawable _drawable = drawable;
713 return null != _drawable ? _drawable.isGLOriented() : true;
714 }
715
716 @Override
717 public void addGLEventListener(final GLEventListener listener) {
718 helper.addGLEventListener(listener);
719 }
720
721 @Override
722 public void addGLEventListener(final int idx, final GLEventListener listener) throws IndexOutOfBoundsException {
723 helper.addGLEventListener(idx, listener);
724 }
725
726 @Override
728 return helper.getGLEventListenerCount();
729 }
730
731 @Override
732 public GLEventListener getGLEventListener(final int index) throws IndexOutOfBoundsException {
733 return helper.getGLEventListener(index);
734 }
735
736 @Override
738 return helper.areAllGLEventListenerInitialized();
739 }
740
741 @Override
742 public boolean getGLEventListenerInitState(final GLEventListener listener) {
743 return helper.getGLEventListenerInitState(listener);
744 }
745
746 @Override
747 public void setGLEventListenerInitState(final GLEventListener listener, final boolean initialized) {
748 helper.setGLEventListenerInitState(listener, initialized);
749 }
750
751 @Override
752 public GLEventListener disposeGLEventListener(final GLEventListener listener, final boolean remove) {
753 final DisposeGLEventListenerAction r = new DisposeGLEventListenerAction(listener, remove);
754 runInGLThread(r);
755 return r.listener;
756 }
757
758 @Override
760 return helper.removeGLEventListener(listener);
761 }
762
763 /**
764 * {@inheritDoc}
765 *
766 * <p>
767 * This impl. calls this class's {@link #dispose()} SWT override,
768 * where the actual implementation resides.
769 * </p>
770 */
771 @Override
772 public void destroy() {
773 dispose();
774 }
775
776 @Override
778 return helper.getAnimator();
779 }
780
781 @Override
782 public final Thread setExclusiveContextThread(final Thread t) throws GLException {
783 return helper.setExclusiveContextThread(t, context);
784 }
785
786 @Override
787 public final Thread getExclusiveContextThread() {
788 return helper.getExclusiveContextThread();
789 }
790
791 @Override
792 public boolean getAutoSwapBufferMode() {
793 return helper.getAutoSwapBufferMode();
794 }
795
796 @Override
798 return drawable;
799 }
800
801 @Override
803 return context;
804 }
805
806 @Override
808 return additionalCtxCreationFlags;
809 }
810
811 @Override
812 public GL getGL() {
813 final GLContext _context = context;
814 return (null == _context) ? null : _context.getGL();
815 }
816
817 @Override
818 public boolean invoke(final boolean wait, final GLRunnable runnable) throws IllegalStateException {
819 return helper.invoke(this, wait, runnable);
820 }
821
822 @Override
823 public boolean invoke(final boolean wait, final List<GLRunnable> runnables) throws IllegalStateException {
824 return helper.invoke(this, wait, runnables);
825 }
826
827 @Override
828 public void flushGLRunnables() {
829 helper.flushGLRunnables();
830 }
831
832 @Override
833 public void setAnimator(final GLAnimatorControl arg0) throws GLException {
834 helper.setAnimator(arg0);
835 }
836
837 @Override
838 public void setAutoSwapBufferMode(final boolean arg0) {
839 helper.setAutoSwapBufferMode(arg0);
840 }
841
842 @Override
843 public GLContext setContext(final GLContext newCtx, final boolean destroyPrevCtx) {
844 final RecursiveLock _lock = lock;
845 _lock.lock();
846 try {
847 final GLContext oldCtx = context;
848 GLDrawableHelper.switchContext(drawable, oldCtx, destroyPrevCtx, newCtx, additionalCtxCreationFlags);
849 context=(GLContextImpl)newCtx;
850 return oldCtx;
851 } finally {
852 _lock.unlock();
853 }
854 }
855
856 @Override
857 public void setContextCreationFlags(final int arg0) {
858 additionalCtxCreationFlags = arg0;
859 final GLContext _context = context;
860 if(null != _context) {
861 _context.setContextCreationFlags(additionalCtxCreationFlags);
862 }
863 }
864
865 @Override
866 public GL setGL(final GL arg0) {
867 final GLContext _context = context;
868 if (null != _context) {
869 _context.setGL(arg0);
870 return arg0;
871 }
872 return null;
873 }
874
875 @Override
876 public GLContext createContext(final GLContext shareWith) {
877 final RecursiveLock _lock = lock;
878 _lock.lock();
879 try {
880 if(drawable != null) {
881 final GLContext _ctx = drawable.createContext(shareWith);
882 _ctx.setContextCreationFlags(additionalCtxCreationFlags);
883 return _ctx;
884 }
885 return null;
886 } finally {
887 _lock.unlock();
888 }
889 }
890
891 @Override
893 final GLDrawable _drawable = drawable;
894 return null != _drawable ? (GLCapabilitiesImmutable)_drawable.getChosenGLCapabilities() : null;
895 }
896
897 @Override
899 final GLDrawable _drawable = drawable;
900 return null != _drawable ? (GLCapabilitiesImmutable)_drawable.getRequestedGLCapabilities() : null;
901 }
902
903 @Override
905 final GLDrawable _drawable = drawable;
906 return (_drawable != null) ? _drawable.getFactory() : null;
907 }
908
909 @Override
911 return capsRequested.getGLProfile();
912 }
913
914 @Override
915 public long getHandle() {
916 final GLDrawable _drawable = drawable;
917 return (_drawable != null) ? _drawable.getHandle() : 0;
918 }
919
920 @Override
922 final GLDrawable _drawable = drawable;
923 return (_drawable != null) ? _drawable.getNativeSurface() : null;
924 }
925
926 @Override
927 public boolean isRealized() {
928 final GLDrawable _drawable = drawable;
929 return (_drawable != null) ? _drawable.isRealized() : false;
930 }
931
932 @Override
933 public void setRealized(final boolean arg0) {
934 /* Intentionally empty */
935 }
936
937 @Override
938 public void swapBuffers() throws GLException {
939 runInGLThread(swapBuffersOnGLAction);
940 }
941
942 /**
943 * {@inheritDoc}
944 * <p>
945 * Implementation always supports multithreading, hence method always returns <code>true</code>.
946 * </p>
947 */
948 @Override
949 public final boolean isThreadGLCapable() { return true; }
950
951 /**
952 * Runs the specified action in an SWT compatible thread, which is:
953 * <ul>
954 * <li>Mac OSX
955 * <ul>
956 * <!--li>AWT EDT: In case AWT is available, the AWT EDT is the OSX UI main thread</li-->
957 * <!--li><i>Main Thread</i>: Run on OSX UI main thread.</li-->
958 * <li>Current thread</li>
959 * </ul></li>
960 * <li>Linux, Windows, ..
961 * <ul>
962 * <!--li>Use {@link Threading#invokeOnOpenGLThread(boolean, Runnable)}</li-->
963 * <li>Current thread</li>
964 * </ul></li>
965 * </ul>
966 * The current thread seems to be valid for all platforms,
967 * since no SWT lifecycle tasks are being performed w/ this call.
968 * Only GL task, which are independent from the SWT threading model.
969 *
970 * @see Platform#AWT_AVAILABLE
971 * @see Platform#getOSType()
972 */
973 private void runInGLThread(final Runnable action) {
974 /**
975 if(Platform.OSType.MACOS == Platform.OS_TYPE) {
976 SWTAccessor.invoke(true, action);
977 } else {
978 Threading.invokeOnOpenGLThread(true, action);
979 } */
980 /**
981 if( !isDisposed() ) {
982 final Display d = getDisplay();
983 if( d.getThread() == Thread.currentThread() ) {
984 action.run();
985 } else {
986 d.syncExec(action);
987 }
988 } */
989 action.run();
990 }
991
992 private void runOnEDTIfAvail(final boolean wait, final Runnable action) {
993 final Display d = isDisposed() ? null : getDisplay();
994 if( null == d || d.isDisposed() || d.getThread() == Thread.currentThread() ) {
995 action.run();
996 } else if(wait) {
997 d.syncExec(action);
998 } else {
999 d.asyncExec(action);
1000 }
1001 }
1002
1003 @Override
1004 public String toString() {
1005 final GLDrawable _drawable = drawable;
1006 final int dw = (null!=_drawable) ? _drawable.getSurfaceWidth() : -1;
1007 final int dh = (null!=_drawable) ? _drawable.getSurfaceHeight() : -1;
1008
1009 return "SWT-GLCanvas[Realized "+isRealized()+
1010 ",\n\t"+((null!=_drawable)?_drawable.getClass().getName():"null-drawable")+
1011 ",\n\tFactory "+getFactory()+
1012 ",\n\thandle "+toHexString(getHandle())+
1013 ",\n\tDrawable size "+dw+"x"+dh+
1014 ",\n\tSWT size "+getSurfaceWidth()+"x"+getSurfaceHeight()+"]";
1015 }
1016
1017 public static void main(final String[] args) {
1018 System.err.println(VersionUtil.getPlatformInfo());
1019 System.err.println(GlueGenVersion.getInstance());
1020 // System.err.println(NativeWindowVersion.getInstance());
1021 System.err.println(JoglVersion.getInstance());
1022
1023 System.err.println(JoglVersion.getDefaultOpenGLInfo(null, null, true).toString());
1024
1026 final Display display = new Display();
1027 final Shell shell = new Shell(display);
1028 shell.setSize(128,128);
1029 shell.setLayout(new FillLayout());
1030
1031 final GLCanvas canvas = new GLCanvas(shell, 0, caps, null);
1032
1033 canvas.addGLEventListener(new GLEventListener() {
1034 @Override
1035 public void init(final GLAutoDrawable drawable) {
1036 final GL gl = drawable.getGL();
1037 System.err.println(JoglVersion.getGLInfo(gl, null));
1038 }
1039 @Override
1040 public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) {}
1041 @Override
1042 public void display(final GLAutoDrawable drawable) {}
1043 @Override
1044 public void dispose(final GLAutoDrawable drawable) {}
1045 });
1046 shell.open();
1047 canvas.display();
1048 display.dispose();
1049 }
1050}
static void destroyX11Window(final AbstractGraphicsDevice device, final long x11Window)
static Rectangle getClientAreaInPixels(final Scrollable s)
Returns the unscaled Scrollable#getClientArea() in pixels.
static AbstractGraphicsDevice getDevice(final Control swtControl)
static AbstractGraphicsScreen getScreen(final AbstractGraphicsDevice device, final int screen)
static void resizeX11Window(final AbstractGraphicsDevice device, final Rectangle clientArea, final long x11Window)
static void setRealized(final Control swtControl, final boolean realize)
Encapsulates a graphics device on X11 platforms.
Specifies a set of OpenGL capabilities.
Abstraction for an OpenGL rendering context.
Definition: GLContext.java:74
abstract void setContextCreationFlags(int flags)
abstract GL setGL(GL gl)
Sets the GL pipeline object for this GLContext.
abstract GL getGL()
Returns the GL pipeline object for this GLContext.
final RecursiveLock lock
Definition: GLContext.java:226
A generic exception for OpenGL errors used throughout the binding as a substitute for RuntimeExceptio...
static GLException newGLException(final Throwable t)
Constructs a GLException object with the specified root cause with a decorating message including the...
Specifies the the OpenGL profile.
Definition: GLProfile.java:77
static GLProfile getDefault(final AbstractGraphicsDevice device)
Returns a default GLProfile object, reflecting the best for the running platform.
Definition: GLProfile.java:739
static AbstractGraphicsDevice getDefaultDevice()
static void initSingleton()
Static initialization of JOGL.
Definition: GLProfile.java:204
static JoglVersion getInstance()
static StringBuilder getGLInfo(final GL gl, final StringBuilder sb)
static StringBuilder getDefaultOpenGLInfo(AbstractGraphicsDevice device, StringBuilder sb, final boolean withCapabilitiesInfo)
Native SWT Canvas implementing GLAutoDrawable.
Definition: GLCanvas.java:98
GLEventListener removeGLEventListener(final GLEventListener listener)
Removes the given listener from this drawable queue.
Definition: GLCanvas.java:759
final GLDrawable getDelegatedDrawable()
If the implementation uses delegation, return the delegated GLDrawable instance, otherwise return thi...
Definition: GLCanvas.java:797
void setAutoSwapBufferMode(final boolean arg0)
Enables or disables automatic buffer swapping for this drawable.
Definition: GLCanvas.java:838
GLProfile getGLProfile()
Fetches the GLProfile for this drawable.
Definition: GLCanvas.java:910
boolean isRealized()
Returns true if this drawable is realized, otherwise false.
Definition: GLCanvas.java:927
final RecursiveLock getUpstreamLock()
Returns the recursive lock object of the upstream widget to synchronize multithreaded access on top o...
Definition: GLCanvas.java:698
GLContext setContext(final GLContext newCtx, final boolean destroyPrevCtx)
Associate the new context, newtCtx, to this auto-drawable.
Definition: GLCanvas.java:843
void destroy()
Destroys all resources associated with this GLAutoDrawable, inclusive the GLContext....
Definition: GLCanvas.java:772
static void main(final String[] args)
Definition: GLCanvas.java:1017
boolean invoke(final boolean wait, final GLRunnable runnable)
Enqueues a one-shot GLRunnable, which will be executed within the next display() call after all regis...
Definition: GLCanvas.java:818
long getHandle()
Returns the GL drawable handle, guaranteed to be valid after realization and while it's surface is be...
Definition: GLCanvas.java:915
GLCanvas(final Composite parent, final int style, final GLCapabilitiesImmutable capsReqUser, final GLCapabilitiesChooser capsChooser)
Creates a new SWT GLCanvas.
Definition: GLCanvas.java:341
GLContext getContext()
Returns the context associated with this drawable.
Definition: GLCanvas.java:802
NativeSurface getNativeSurface()
Returns the associated NativeSurface of this NativeSurfaceHolder.Returns the underlying NativeSurface...
Definition: GLCanvas.java:921
void setGLEventListenerInitState(final GLEventListener listener, final boolean initialized)
Sets the given listener's initialized state.
Definition: GLCanvas.java:747
boolean areAllGLEventListenerInitialized()
Returns true if all added GLEventListener are initialized, otherwise false.
Definition: GLCanvas.java:737
void addGLEventListener(final int idx, final GLEventListener listener)
Adds the given listener at the given index of this drawable queue.
Definition: GLCanvas.java:722
int getGLEventListenerCount()
Returns the number of GLEventListener of this drawable queue.
Definition: GLCanvas.java:727
int getSurfaceWidth()
Returns the width of this GLDrawable's surface client area in pixel units.
Definition: GLCanvas.java:701
GLEventListener disposeGLEventListener(final GLEventListener listener, final boolean remove)
Disposes the given listener via dispose(..) if it has been initialized and added to this queue.
Definition: GLCanvas.java:752
boolean invoke(final boolean wait, final List< GLRunnable > runnables)
Extends invoke(boolean, GLRunnable) functionality allowing to inject a list of GLRunnables.
Definition: GLCanvas.java:823
boolean isGLOriented()
Returns true if the drawable is rendered in OpenGL's coordinate system, origin at bottom left.
Definition: GLCanvas.java:711
static GLCanvas create(final Composite parent, final int style, final GLCapabilitiesImmutable caps, final GLCapabilitiesChooser chooser)
Creates an instance using GLCanvas(Composite, int, GLCapabilitiesImmutable, GLCapabilitiesChooser) on...
Definition: GLCanvas.java:313
GL setGL(final GL arg0)
Sets the GL pipeline object this GLAutoDrawable uses.
Definition: GLCanvas.java:866
GLEventListener getGLEventListener(final int index)
Returns the GLEventListener at the given index of this drawable queue.
Definition: GLCanvas.java:732
void setRealized(final boolean arg0)
Indicates to GLDrawable implementations whether the underlying surface has been created and can be dr...
Definition: GLCanvas.java:933
GLCapabilitiesImmutable getRequestedGLCapabilities()
Fetches the GLCapabilitiesImmutable corresponding to the user requested OpenGL capabilities (pixel fo...
Definition: GLCanvas.java:898
final Object getUpstreamWidget()
Method may return the upstream UI toolkit object holding this GLAutoDrawable instance,...
Definition: GLCanvas.java:693
final Thread getExclusiveContextThread()
Definition: GLCanvas.java:787
GLCapabilitiesImmutable getChosenGLCapabilities()
Fetches the GLCapabilitiesImmutable corresponding to the chosen OpenGL capabilities (pixel format / v...
Definition: GLCanvas.java:892
boolean getAutoSwapBufferMode()
Indicates whether automatic buffer swapping is enabled for this drawable.
Definition: GLCanvas.java:792
int getSurfaceHeight()
Returns the height of this GLDrawable's surface client area in pixel units.
Definition: GLCanvas.java:706
boolean getGLEventListenerInitState(final GLEventListener listener)
Retrieves whether the given listener is initialized or not.
Definition: GLCanvas.java:742
void flushGLRunnables()
Flushes all enqueued GLRunnable of this GLAutoDrawable including notifying waiting executor.
Definition: GLCanvas.java:828
final void setSharedAutoDrawable(final GLAutoDrawable sharedAutoDrawable)
Specifies an GLAutoDrawable, which OpenGL context shall be shared by this GLAutoDrawable's GLContext.
Definition: GLCanvas.java:423
final boolean isThreadGLCapable()
Indicates whether the current thread is capable of performing OpenGL-related work....
Definition: GLCanvas.java:949
final Thread setExclusiveContextThread(final Thread t)
Dedicates this instance's GLContext to the given thread.
Definition: GLCanvas.java:782
void addGLEventListener(final GLEventListener listener)
Adds the given listener to the end of this drawable queue.
Definition: GLCanvas.java:717
final void setSharedContext(final GLContext sharedContext)
Specifies an OpenGL context, which shall be shared by this GLAutoDrawable's GLContext.
Definition: GLCanvas.java:418
void dispose()
@Override public boolean forceFocus() { final boolean r = super.forceFocus(); if(r && 0 !...
Definition: GLCanvas.java:668
GLContext createContext(final GLContext shareWith)
Creates a new context for drawing to this drawable that will optionally share buffer objects,...
Definition: GLCanvas.java:876
GLAnimatorControl getAnimator()
Definition: GLCanvas.java:777
final boolean validateDrawableAndContextWithCheck()
assumes drawable == null (implying !drawable.isRealized()) ! Checks of !isDispose() and isVisible()
Definition: GLCanvas.java:519
void swapBuffers()
Swaps the front and back buffers of this drawable.
Definition: GLCanvas.java:938
void setContextCreationFlags(final int arg0)
Definition: GLCanvas.java:857
GLDrawableFactory getFactory()
Return the GLDrawableFactory being used to create this instance.
Definition: GLCanvas.java:904
void setAnimator(final GLAnimatorControl arg0)
Registers the usage of an animator, an com.jogamp.opengl.GLAnimatorControl implementation.
Definition: GLCanvas.java:833
GL getGL()
Returns the GL pipeline object this GLAutoDrawable uses.
Definition: GLCanvas.java:812
A interface describing a graphics device in a toolkit-independent manner.
boolean close()
Optionally closing the device if handle is not null.
boolean open()
Optionally [re]opening the device if handle is null.
static int DEFAULT_UNIT
Default unit id for the 1st device: 0.
String getConnection()
Returns the semantic GraphicsDevice connection.
A interface describing a graphics screen in a toolkit-independent manner.
int getIndex()
Returns the screen index this graphics screen is valid for.
AbstractGraphicsDevice getDevice()
Return the device this graphics configuration is valid for.
Provides low-level information required for hardware-accelerated rendering using a surface in a platf...
Provides a mutable NativeSurface, i.e.
Interface allowing upstream caller to pass lifecycle actions and size info to a ProxySurface instance...
An animator control interface, which implementation may drive a com.jogamp.opengl....
boolean resume()
Resumes animation if paused.
boolean pause()
Pauses this animator.
A higher-level abstraction than GLDrawable which supplies an event based mechanism (GLEventListener) ...
GL getGL()
Returns the GL pipeline object this GLAutoDrawable uses.
Provides a mechanism by which applications can customize the window type selection for a given GLCapa...
Specifies an immutable set of OpenGL capabilities.
GLProfile getGLProfile()
Returns the GL profile you desire or used by the drawable.
An abstraction for an OpenGL rendering target.
Definition: GLDrawable.java:51
GLCapabilitiesImmutable getChosenGLCapabilities()
Fetches the GLCapabilitiesImmutable corresponding to the chosen OpenGL capabilities (pixel format / v...
int getSurfaceWidth()
Returns the width of this GLDrawable's surface client area in pixel units.
GLCapabilitiesImmutable getRequestedGLCapabilities()
Fetches the GLCapabilitiesImmutable corresponding to the user requested OpenGL capabilities (pixel fo...
long getHandle()
Returns the GL drawable handle, guaranteed to be valid after realization and while it's surface is be...
boolean isRealized()
Returns true if this drawable is realized, otherwise false.
boolean isGLOriented()
Returns true if the drawable is rendered in OpenGL's coordinate system, origin at bottom left.
NativeSurface getNativeSurface()
Returns the associated NativeSurface of this NativeSurfaceHolder.
GLDrawableFactory getFactory()
Return the GLDrawableFactory being used to create this instance.
int getSurfaceHeight()
Returns the height of this GLDrawable's surface client area in pixel units.
Declares events which client code can use to manage OpenGL rendering into a GLAutoDrawable.
Adds capabilities to set a shared GLContext directly or via an GLAutoDrawable.