Jogamp
Bug 741 HiDPI: Simplify ScalableSurface (2): Add request pixelScale API entry, fixed...
[jogl.git] / src / newt / classes / com / jogamp / newt / opengl / GLWindow.java
CommitLineData
a959c53b
KR
1/*
2 * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
0feca163 3 * Copyright (c) 2010 JogAmp Community. All rights reserved.
3334a924 4 *
a959c53b
KR
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
3334a924 8 *
a959c53b
KR
9 * - Redistribution of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
3334a924 11 *
a959c53b
KR
12 * - Redistribution in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
3334a924 15 *
a959c53b
KR
16 * Neither the name of Sun Microsystems, Inc. or the names of
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
3334a924 19 *
a959c53b
KR
20 * This software is provided "AS IS," without a warranty of any kind. ALL
21 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
22 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
23 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
24 * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
25 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
26 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
27 * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
28 * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
29 * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
30 * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
31 * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
3334a924 32 *
a959c53b
KR
33 */
34
2d57c252 35package com.jogamp.newt.opengl;
a959c53b 36
cc64ad2b
SG
37import java.security.AccessController;
38import java.security.PrivilegedAction;
6ebf649d
SG
39import java.util.List;
40
3334a924
SG
41import javax.media.nativewindow.AbstractGraphicsConfiguration;
42import javax.media.nativewindow.CapabilitiesChooser;
43import javax.media.nativewindow.CapabilitiesImmutable;
44import javax.media.nativewindow.NativeSurface;
45import javax.media.nativewindow.NativeWindow;
46import javax.media.nativewindow.NativeWindowException;
3334a924 47import javax.media.nativewindow.SurfaceUpdatedListener;
d4670328 48import javax.media.nativewindow.util.InsetsImmutable;
018c7e86 49import javax.media.nativewindow.util.Point;
98ed02cd 50import javax.media.nativewindow.util.Rectangle;
3334a924
SG
51import javax.media.opengl.FPSCounter;
52import javax.media.opengl.GL;
1a20ef3a
SG
53import javax.media.opengl.GL3;
54import javax.media.opengl.GL4ES3;
3334a924
SG
55import javax.media.opengl.GLAnimatorControl;
56import javax.media.opengl.GLAutoDrawable;
57import javax.media.opengl.GLCapabilities;
58import javax.media.opengl.GLCapabilitiesImmutable;
59import javax.media.opengl.GLContext;
4dd44b98 60import javax.media.opengl.GLDrawable;
3334a924 61import javax.media.opengl.GLDrawableFactory;
1a20ef3a
SG
62import javax.media.opengl.GLES2;
63import javax.media.opengl.GLES3;
3334a924 64import javax.media.opengl.GLEventListener;
4b5a0f65 65import javax.media.opengl.GLException;
3334a924 66import javax.media.opengl.GLProfile;
a7024efb 67import javax.media.opengl.GLRunnable;
8adc0478 68
3334a924 69import jogamp.newt.WindowImpl;
eed8508a
SG
70import jogamp.opengl.GLAutoDrawableBase;
71import jogamp.opengl.GLContextImpl;
72import jogamp.opengl.GLDrawableImpl;
3334a924
SG
73
74import com.jogamp.common.GlueGenVersion;
75import com.jogamp.common.util.VersionUtil;
4b5a0f65 76import com.jogamp.common.util.locks.RecursiveLock;
6ebf649d 77import com.jogamp.newt.MonitorDevice;
3334a924
SG
78import com.jogamp.newt.NewtFactory;
79import com.jogamp.newt.Screen;
80import com.jogamp.newt.Window;
e7ffa68b 81import com.jogamp.newt.Display.PointerIcon;
bc72e232 82import com.jogamp.newt.event.GestureHandler;
3334a924
SG
83import com.jogamp.newt.event.KeyListener;
84import com.jogamp.newt.event.MouseListener;
85import com.jogamp.newt.event.NEWTEvent;
86import com.jogamp.newt.event.NEWTEventConsumer;
a7024efb 87import com.jogamp.newt.event.NEWTEventListener;
3334a924
SG
88import com.jogamp.newt.event.WindowAdapter;
89import com.jogamp.newt.event.WindowEvent;
90import com.jogamp.newt.event.WindowListener;
91import com.jogamp.newt.event.WindowUpdateEvent;
dac35658 92import com.jogamp.opengl.JoglVersion;
e5df5210 93import com.jogamp.opengl.GLStateKeeper;
a959c53b
KR
94
95/**
76562bc5
SG
96 * An implementation of {@link GLAutoDrawable} and {@link Window} interface,
97 * using a delegated {@link Window} instance, which may be an aggregation (lifecycle: created and destroyed).
2268a6ce 98 * <P>
e5df5210
SG
99 * This implementation supports {@link GLStateKeeper GL state preservation},
100 * hence {@link #isGLStatePreservationSupported()} returns <code>true</code>.
101 * </P>
102 * <P>
2268a6ce 103 * This implementation does not make the OpenGL context current<br>
a7024efb 104 * before calling the various input EventListener callbacks, ie {@link MouseListener} etc.<br>
0feca163
SG
105 * This design decision is made in favor of a more performant and simplified
106 * implementation. Also the event dispatcher shall be implemented OpenGL agnostic.<br>
a7024efb
SG
107 * To be able to use OpenGL commands from within such input {@link NEWTEventListener},<br>
108 * you can inject {@link GLRunnable} objects
109 * via {@link #invoke(boolean, GLRunnable)} to the OpenGL command stream.<br>
3334a924 110 * </p>
a959c53b 111 */
eed8508a 112public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Window, NEWTEventConsumer, FPSCounter {
28b0df6c 113 private final WindowImpl window;
a959c53b 114
476d1d75
MB
115 /**
116 * Constructor. Do not call this directly -- use {@link #create()} instead.
117 */
811bd23e 118 protected GLWindow(Window window) {
4dd44b98 119 super(null, null, false /* always handle device lifecycle ourselves */);
0feca163 120 this.window = (WindowImpl) window;
808a9a27 121 this.window.setWindowDestroyNotifyAction( new Runnable() {
f1ae8ddb 122 @Override
808a9a27
SG
123 public void run() {
124 defaultWindowDestroyNotifyOp();
125 } } );
1ad8c39d 126 window.addWindowListener(new WindowAdapter() {
10c696f7 127 @Override
969e4276 128 public void windowRepaint(WindowUpdateEvent e) {
9b35c574 129 defaultWindowRepaintOp();
969e4276
SG
130 }
131
10c696f7 132 @Override
5e9c02bc 133 public void windowResized(WindowEvent e) {
f9a00b91 134 defaultWindowResizedOp(getSurfaceWidth(), getSurfaceHeight());
a959c53b
KR
135 }
136
a959c53b 137 });
0feca163 138 this.window.setLifecycleHook(new GLLifecycleHook());
a959c53b
KR
139 }
140
20bf031d
SG
141 @Override
142 public final Object getUpstreamWidget() {
143 return window;
144 }
5e9c02bc 145
0feca163 146 /**
3334a924 147 * Creates a new GLWindow attaching a new Window referencing a
8a7ebf29
SG
148 * new default Screen and default Display with the given GLCapabilities.
149 * <p>
150 * The lifecycle of this Window's Screen and Display is handled via {@link Screen#addReference()}
151 * and {@link Screen#removeReference()}.
152 * </p>
3334a924 153 * The default Display will be reused if already instantiated.
0feca163 154 */
29e3b223 155 public static GLWindow create(GLCapabilitiesImmutable caps) {
0feca163 156 return new GLWindow(NewtFactory.createWindow(caps));
a959c53b
KR
157 }
158
0feca163
SG
159 /**
160 * Creates a new GLWindow attaching a new Window referencing the given Screen
161 * with the given GLCapabilities.
8a7ebf29
SG
162 * <p>
163 * The lifecycle of this Window's Screen and Display is handled via {@link Screen#addReference()}
164 * and {@link Screen#removeReference()}.
165 * </p>
0feca163 166 */
29e3b223 167 public static GLWindow create(Screen screen, GLCapabilitiesImmutable caps) {
0feca163 168 return new GLWindow(NewtFactory.createWindow(screen, caps));
a959c53b
KR
169 }
170
3334a924 171 /**
0feca163 172 * Creates a new GLWindow attaching the given window.
8a7ebf29
SG
173 * <p>
174 * The lifecycle of this Window's Screen and Display is handled via {@link Screen#addReference()}
175 * and {@link Screen#removeReference()}.
176 * </p>
0feca163
SG
177 */
178 public static GLWindow create(Window window) {
811bd23e 179 return new GLWindow(window);
a959c53b 180 }
6e599a26 181
3334a924
SG
182 /**
183 * Creates a new GLWindow attaching a new child Window
0feca163 184 * of the given <code>parentNativeWindow</code> with the given GLCapabilities.
8a7ebf29 185 * <p>
0feca163
SG
186 * The Display/Screen will be compatible with the <code>parentNativeWindow</code>,
187 * or even identical in case it's a Newt Window.
3334a924 188 * An already instantiated compatible Display will be reused.
8a7ebf29
SG
189 * </p>
190 * <p>
191 * The lifecycle of this Window's Screen and Display is handled via {@link Screen#addReference()}
192 * and {@link Screen#removeReference()}.
193 * </p>
0feca163 194 */
29e3b223 195 public static GLWindow create(NativeWindow parentNativeWindow, GLCapabilitiesImmutable caps) {
0feca163 196 return new GLWindow(NewtFactory.createWindow(parentNativeWindow, caps));
a959c53b 197 }
a959c53b 198
0feca163 199 //----------------------------------------------------------------------
2cbab63b
SG
200 // WindowClosingProtocol implementation
201 //
3334a924 202 @Override
935523a8 203 public WindowClosingMode getDefaultCloseOperation() {
2cbab63b
SG
204 return window.getDefaultCloseOperation();
205 }
206
3334a924 207 @Override
935523a8 208 public WindowClosingMode setDefaultCloseOperation(WindowClosingMode op) {
2cbab63b
SG
209 return window.setDefaultCloseOperation(op);
210 }
211
212 //----------------------------------------------------------------------
0feca163
SG
213 // Window Access
214 //
a959c53b 215
3334a924 216 @Override
7c159772
SG
217 public CapabilitiesChooser setCapabilitiesChooser(CapabilitiesChooser chooser) {
218 return window.setCapabilitiesChooser(chooser);
219 }
220
3334a924 221 @Override
e4913066 222 public final CapabilitiesImmutable getChosenCapabilities() {
4dd44b98 223 final GLDrawable _drawable = drawable;
5e9c02bc 224 return null != _drawable ? _drawable.getChosenGLCapabilities() : window.getChosenCapabilities();
a959c53b
KR
225 }
226
3334a924 227 @Override
e4913066 228 public final CapabilitiesImmutable getRequestedCapabilities() {
0feca163 229 return window.getRequestedCapabilities();
811bd23e
SG
230 }
231
3334a924 232 @Override
76562bc5
SG
233 public final Window getDelegatedWindow() {
234 return window.getDelegatedWindow();
811bd23e
SG
235 }
236
3334a924 237 @Override
018c7e86
SG
238 public final NativeWindow getParent() {
239 return window.getParent();
811bd23e
SG
240 }
241
3334a924 242 @Override
0feca163 243 public final Screen getScreen() {
a959c53b
KR
244 return window.getScreen();
245 }
246
3334a924 247 @Override
6ebf649d
SG
248 public final MonitorDevice getMainMonitor() {
249 return window.getMainMonitor();
250 }
251
252 @Override
0feca163 253 public final void setTitle(String title) {
a959c53b
KR
254 window.setTitle(title);
255 }
256
3334a924 257 @Override
0feca163 258 public final String getTitle() {
a959c53b
KR
259 return window.getTitle();
260 }
261
3334a924 262 @Override
24e0591b
SG
263 public final boolean isPointerVisible() {
264 return window.isPointerVisible();
265 }
3334a924
SG
266
267 @Override
24e0591b 268 public final void setPointerVisible(boolean mouseVisible) {
3334a924 269 window.setPointerVisible(mouseVisible);
24e0591b 270 }
3334a924
SG
271
272 @Override
e7ffa68b
SG
273 public final PointerIcon getPointerIcon() {
274 return window.getPointerIcon();
275 }
276
277 @Override
278 public final void setPointerIcon(final PointerIcon pi) {
279 window.setPointerIcon(pi);
280 }
281
282 @Override
24e0591b
SG
283 public final boolean isPointerConfined() {
284 return window.isPointerConfined();
285 }
3334a924
SG
286
287 @Override
24e0591b
SG
288 public final void confinePointer(boolean grab) {
289 window.confinePointer(grab);
290 }
3334a924
SG
291
292 @Override
0feca163 293 public final void setUndecorated(boolean value) {
a959c53b
KR
294 window.setUndecorated(value);
295 }
296
3334a924 297 @Override
24e0591b
SG
298 public final void warpPointer(int x, int y) {
299 window.warpPointer(x, y);
300 }
3334a924 301 @Override
0feca163 302 public final boolean isUndecorated() {
a959c53b
KR
303 return window.isUndecorated();
304 }
305
3334a924 306 @Override
a245d530
SG
307 public final void setAlwaysOnTop(boolean value) {
308 window.setAlwaysOnTop(value);
309 }
3334a924
SG
310
311 @Override
a245d530
SG
312 public final boolean isAlwaysOnTop() {
313 return window.isAlwaysOnTop();
314 }
3334a924
SG
315
316 @Override
0feca163 317 public final void setFocusAction(FocusRunnable focusAction) {
a4b16ad5
SG
318 window.setFocusAction(focusAction);
319 }
3334a924
SG
320
321 @Override
3db4e89c
SG
322 public void setKeyboardFocusHandler(KeyListener l) {
323 window.setKeyboardFocusHandler(l);
324 }
3334a924
SG
325
326 @Override
0feca163
SG
327 public final void requestFocus() {
328 window.requestFocus();
811bd23e
SG
329 }
330
3334a924 331 @Override
3db4e89c 332 public final void requestFocus(boolean wait) {
3334a924 333 window.requestFocus(wait);
3db4e89c 334 }
3334a924
SG
335
336 @Override
609e3083
SG
337 public boolean hasFocus() {
338 return window.hasFocus();
339 }
340
3334a924
SG
341 @Override
342 public final InsetsImmutable getInsets() {
0feca163 343 return window.getInsets();
811bd23e 344 }
3334a924
SG
345
346 @Override
eed8508a
SG
347 public final int getX() {
348 return window.getX();
349 }
350
351 @Override
352 public final int getY() {
353 return window.getY();
354 }
5e9c02bc 355
eed8508a 356 @Override
d149c554
SG
357 public final int getWidth() {
358 return window.getWidth();
eed8508a
SG
359 }
360
361 @Override
d149c554
SG
362 public final int getHeight() {
363 return window.getHeight();
f9a00b91
SG
364 }
365
366 @Override
98ed02cd
SG
367 public final Rectangle getBounds() {
368 return window.getBounds();
f9a00b91
SG
369 }
370
371 @Override
98ed02cd
SG
372 public final int getSurfaceWidth() {
373 return window.getSurfaceWidth();
374 }
375
376 @Override
377 public final int getSurfaceHeight() {
378 return window.getSurfaceHeight();
fb57c652
SG
379 }
380
381 @Override
98ed02cd
SG
382 public final Rectangle getSurfaceBounds() {
383 return window.getSurfaceBounds();
384 }
385
386 @Override
387 public final int[] convertToWindowUnits(final int[] pixelUnitsAndResult) {
fb57c652
SG
388 return window.convertToWindowUnits(pixelUnitsAndResult);
389 }
390
391 @Override
98ed02cd 392 public final int[] convertToPixelUnits(final int[] windowUnitsAndResult) {
fb57c652 393 return window.convertToPixelUnits(windowUnitsAndResult);
f9a00b91
SG
394 }
395
396 @Override
98ed02cd
SG
397 public final Rectangle convertToWindowUnits(final Rectangle pixelUnitsAndResult) {
398 return window.convertToWindowUnits(pixelUnitsAndResult);
f9a00b91
SG
399 }
400
401 @Override
98ed02cd
SG
402 public final Rectangle convertToPixelUnits(final Rectangle windowUnitsAndResult) {
403 return window.convertToPixelUnits(windowUnitsAndResult);
eed8508a 404 }
5e9c02bc 405
eed8508a 406 @Override
58153310
SG
407 public final void setSurfaceScale(final int[] pixelScale) {
408 window.setSurfaceScale(pixelScale);
2571ed0b
SG
409 }
410
411 @Override
58153310
SG
412 public final int[] getRequestedSurfaceScale(final int[] result) {
413 return window.getRequestedSurfaceScale(result);
414 }
415
416 @Override
417 public final int[] getCurrentSurfaceScale(final int[] result) {
418 return window.getCurrentSurfaceScale(result);
2571ed0b
SG
419 }
420
421 @Override
0feca163 422 public final void setPosition(int x, int y) {
a959c53b
KR
423 window.setPosition(x, y);
424 }
3334a924
SG
425 @Override
426 public void setTopLevelPosition(int x, int y) {
d4670328
SG
427 window.setTopLevelPosition(x, y);
428 }
7bed517f 429
3334a924 430 @Override
0feca163 431 public final boolean setFullscreen(boolean fullscreen) {
a959c53b
KR
432 return window.setFullscreen(fullscreen);
433 }
5e9c02bc 434
6ebf649d
SG
435 @Override
436 public boolean setFullscreen(List<MonitorDevice> monitors) {
437 return window.setFullscreen(monitors);
438 }
0feca163 439
3334a924 440 @Override
0feca163
SG
441 public final boolean isFullscreen() {
442 return window.isFullscreen();
811bd23e 443 }
a959c53b 444
3334a924 445 @Override
0feca163 446 public final boolean isVisible() {
a959c53b
KR
447 return window.isVisible();
448 }
449
10c696f7 450 @Override
0feca163 451 public final String toString() {
3334a924 452 return "NEWT-GLWindow[ \n\tHelper: " + helper + ", \n\tDrawable: " + drawable +
6451e3c0 453 ", \n\tContext: " + context + ", \n\tWindow: "+window+ /** ", \n\tFactory: "+factory+ */ "]";
a959c53b
KR
454 }
455
3334a924 456 @Override
c9faebb8 457 public final ReparentOperation reparentWindow(NativeWindow newParent) {
0feca163 458 return window.reparentWindow(newParent);
a959c53b
KR
459 }
460
3334a924 461 @Override
8be1fc98
SG
462 public final ReparentOperation reparentWindow(NativeWindow newParent, int x, int y, boolean forceDestroyCreate) {
463 return window.reparentWindow(newParent, x, y, forceDestroyCreate);
a959c53b
KR
464 }
465
3334a924 466 @Override
a00406f2
SG
467 public final ReparentOperation reparentWindow(NativeWindow newParent, int x, int y, int hints) {
468 return window.reparentWindow(newParent, x, y, hints);
469 }
470
471 @Override
be7995cb
SG
472 public final boolean removeChild(NativeWindow win) {
473 return window.removeChild(win);
a959c53b
KR
474 }
475
3334a924 476 @Override
be7995cb
SG
477 public final boolean addChild(NativeWindow win) {
478 return window.addChild(win);
a959c53b 479 }
3334a924 480
0feca163
SG
481 //----------------------------------------------------------------------
482 // Window.LifecycleHook Implementation
483 //
969e4276 484
3334a924 485 @Override
db4d7d19
SG
486 public final void destroy() {
487 window.destroy();
bf584fba
SG
488 }
489
3334a924 490 @Override
808a9a27
SG
491 public void setWindowDestroyNotifyAction(Runnable r) {
492 window.setWindowDestroyNotifyAction(r);
493 }
5e9c02bc 494
808a9a27 495 @Override
0feca163
SG
496 public final void setVisible(boolean visible) {
497 window.setVisible(visible);
a959c53b
KR
498 }
499
3334a924 500 @Override
24eab4dc
SG
501 public void setVisible(boolean wait, boolean visible) {
502 window.setVisible(wait, visible);
503 }
504
505 @Override
0feca163
SG
506 public final void setSize(int width, int height) {
507 window.setSize(width, height);
a959c53b 508 }
3334a924 509 @Override
fb57c652
SG
510 public final void setSurfaceSize(int pixelWidth, int pixelHeight) {
511 window.setSurfaceSize(pixelWidth, pixelHeight);
512 }
513 @Override
d4670328 514 public void setTopLevelSize(int width, int height) {
3334a924 515 window.setTopLevelSize(width, height);
d4670328 516 }
3334a924
SG
517
518 @Override
0feca163
SG
519 public final boolean isNativeValid() {
520 return window.isNativeValid();
a959c53b
KR
521 }
522
3334a924 523 @Override
018c7e86
SG
524 public Point getLocationOnScreen(Point storage) {
525 return window.getLocationOnScreen(storage);
526 }
527
0feca163
SG
528 // Hide methods here ..
529 protected class GLLifecycleHook implements WindowImpl.LifecycleHook {
530
3334a924 531 @Override
e5df5210
SG
532 public void preserveGLStateAtDestroy(boolean value) {
533 GLWindow.this.preserveGLStateAtDestroy(value);
e2506d76 534 }
5e9c02bc 535
e2506d76 536 @Override
db4d7d19
SG
537 public synchronized void destroyActionPreLock() {
538 // nop
e6225fce
SG
539 }
540
3334a924 541 @Override
db4d7d19 542 public synchronized void destroyActionInLock() {
9c316a0f 543 if(Window.DEBUG_IMPLEMENTATION) {
209a5ac2 544 String msg = "GLWindow.destroy() "+WindowImpl.getThreadName()+", start";
0feca163
SG
545 System.err.println(msg);
546 //Exception e1 = new Exception(msg);
547 //e1.printStackTrace();
548 }
5e9c02bc 549
4b5a0f65 550 destroyImplInLock();
3334a924 551
9c316a0f 552 if(Window.DEBUG_IMPLEMENTATION) {
209a5ac2 553 System.err.println("GLWindow.destroy() "+WindowImpl.getThreadName()+", fin");
0feca163 554 }
db4d7d19 555 }
0feca163 556
3334a924 557 @Override
2c1a870f 558 public synchronized void resetCounter() {
9c316a0f 559 if(Window.DEBUG_IMPLEMENTATION) {
209a5ac2 560 System.err.println("GLWindow.resetCounter() "+WindowImpl.getThreadName());
2c1a870f 561 }
ea819ff7 562 GLWindow.this.resetFPSCounter();
85d70b7d
SG
563 final GLAnimatorControl animator = GLWindow.this.getAnimator();
564 if( null != animator ) {
565 animator.resetFPSCounter();
566 }
2c1a870f
SG
567 }
568
3334a924 569 @Override
2c1a870f 570 public synchronized void setVisibleActionPost(boolean visible, boolean nativeWindowCreated) {
5b05aa83 571 long t0;
9c316a0f 572 if(Window.DEBUG_IMPLEMENTATION) {
5b05aa83 573 t0 = System.nanoTime();
209a5ac2 574 System.err.println("GLWindow.setVisibleActionPost("+visible+", "+nativeWindowCreated+") "+WindowImpl.getThreadName()+", start");
5b05aa83
SG
575 } else {
576 t0 = 0;
0feca163 577 }
5e9c02bc 578
f9a00b91 579 if (null == drawable && visible && 0 != window.getWindowHandle() && 0<getSurfaceWidth()*getSurfaceHeight()) {
b7389836
SG
580 if( ( null != context ) ) {
581 throw new InternalError("GLWindow.LifecycleHook.setVisiblePost: "+WindowImpl.getThreadName()+" - Null drawable, but valid context - "+GLWindow.this);
582 }
7f7a23dd
SG
583 final GLContext[] shareWith = { null };
584 if( !helper.isSharedGLContextPending(shareWith) ) {
585 final NativeSurface ns;
586 {
587 final NativeSurface wrapped_ns = window.getWrappedSurface();
588 ns = null != wrapped_ns ? wrapped_ns : window;
589 }
590 final GLCapabilitiesImmutable glCaps = (GLCapabilitiesImmutable) ns.getGraphicsConfiguration().getChosenCapabilities();
591 if(null==factory) {
592 factory = GLDrawableFactory.getFactory(glCaps.getGLProfile());
593 }
594 drawable = (GLDrawableImpl) factory.createGLDrawable(ns);
595 drawable.setRealized(true);
596
597 if( !GLWindow.this.restoreGLEventListenerState() ) {
598 context = (GLContextImpl) drawable.createContext(shareWith[0]);
599 context.setContextCreationFlags(additionalCtxCreationFlags);
600 }
e2506d76 601 }
0feca163 602 }
9c316a0f 603 if(Window.DEBUG_IMPLEMENTATION) {
209a5ac2 604 System.err.println("GLWindow.setVisibleActionPost("+visible+", "+nativeWindowCreated+") "+WindowImpl.getThreadName()+", fin: dt "+ (System.nanoTime()-t0)/1e6 +"ms");
0feca163
SG
605 }
606 }
3334a924 607
f47230cb 608 private GLAnimatorControl savedAnimator = null;
3334a924
SG
609
610 @Override
2aa29677
SG
611 public synchronized boolean pauseRenderingAction() {
612 boolean animatorPaused = false;
f47230cb
SG
613 savedAnimator = GLWindow.this.getAnimator();
614 if ( null != savedAnimator ) {
615 animatorPaused = savedAnimator.pause();
0feca163 616 }
2aa29677 617 return animatorPaused;
0feca163
SG
618 }
619
3334a924 620 @Override
a0e9d6c8 621 public synchronized void resumeRenderingAction() {
f47230cb
SG
622 if ( null != savedAnimator && savedAnimator.isPaused() ) {
623 savedAnimator.resume();
0feca163
SG
624 }
625 }
5e9c02bc 626
cc64ad2b
SG
627 @SuppressWarnings("deprecation")
628 @Override
629 public void shutdownRenderingAction() {
630 final GLAnimatorControl anim = GLWindow.this.getAnimator();
631 if ( null != anim && anim.isAnimating() ) {
c8f7884c
SG
632 final Thread animThread = anim.getThread();
633 if( animThread == Thread.currentThread() ) {
634 anim.stop(); // on anim thread, non-blocking
635 } else {
636 AccessController.doPrivileged(new PrivilegedAction<Object>() {
f1ae8ddb 637 @Override
c8f7884c
SG
638 public Object run() {
639 if( anim.isAnimating() && null != animThread ) {
640 try {
641 animThread.stop();
642 } catch(Throwable t) {
32171ee4
SG
643 if( DEBUG ) {
644 System.err.println("Catched "+t.getClass().getName()+": "+t.getMessage());
645 t.printStackTrace();
646 }
c8f7884c
SG
647 }
648 }
649 return null;
650 } } );
651 }
cc64ad2b
SG
652 }
653 }
0feca163 654 }
a0e9d6c8 655
a959c53b
KR
656 //----------------------------------------------------------------------
657 // OpenGL-related methods and state
658 //
659
4b5a0f65
SG
660 @Override
661 protected final RecursiveLock getLock() {
662 return window.getLock();
663 }
5e9c02bc 664
3334a924 665 @Override
a959c53b 666 public void display() {
28b0df6c 667 if( !isNativeValid() || !isVisible() ) { return; }
3334a924 668
28b0df6c 669 if(sendDestroy || ( window.hasDeviceChanged() && GLAutoDrawable.SCREEN_CHANGE_ACTION_ENABLED ) ) {
63be4a40
SG
670 sendDestroy=false;
671 destroy();
672 return;
673 }
6e599a26 674
4dd44b98 675 final boolean done;
4b5a0f65
SG
676 final RecursiveLock lock = window.getLock();
677 lock.lock(); // sync: context/drawable could have been recreated/destroyed while animating
3334a924 678 try {
3334a924
SG
679 if( null != context ) {
680 // surface is locked/unlocked implicit by context's makeCurrent/release
eed8508a 681 helper.invokeGL(drawable, context, defaultDisplayAction, defaultInitAction);
4dd44b98
SG
682 done = true;
683 } else {
684 done = false;
3334a924
SG
685 }
686 } finally {
4b5a0f65 687 lock.unlock();
a959c53b 688 }
f9a00b91 689 if( !done && ( 0 < getSurfaceWidth() && 0 < getSurfaceHeight() ) ) {
4dd44b98
SG
690 // retry drawable and context creation, will itself issue resize -> display
691 setVisible(true);
692 }
a959c53b 693 }
5e9c02bc 694
e5df5210
SG
695 /**
696 * {@inheritDoc}
697 * <p>
698 * GLWindow supports GL state preservation, hence returns <code>true</code>.
699 * </p>
700 */
3ad03e41
SG
701 @Override
702 public final boolean isGLStatePreservationSupported() { return true; }
3334a924 703
a959c53b 704 //----------------------------------------------------------------------
0feca163 705 // GLDrawable methods
a959c53b 706 //
eed8508a 707 private GLDrawableFactory factory;
a959c53b 708
3334a924 709 @Override
4b5a0f65 710 public final GLDrawableFactory getFactory() {
eed8508a 711 return factory;
a959c53b
KR
712 }
713
3334a924 714 @Override
4b5a0f65
SG
715 public final void swapBuffers() throws GLException {
716 defaultSwapBuffers();
717 }
5e9c02bc 718
0feca163 719 //----------------------------------------------------------------------
3334a924 720 // NEWTEventConsumer
1b7b5d34 721 //
3334a924 722 @Override
1b7b5d34
SG
723 public boolean consumeEvent(NEWTEvent event) {
724 return window.consumeEvent(event);
725 }
726
727 //----------------------------------------------------------------------
0feca163
SG
728 // Window completion
729 //
3334a924 730 @Override
0feca163
SG
731 public final void windowRepaint(int x, int y, int width, int height) {
732 window.windowRepaint(x, y, width, height);
733 }
734
3334a924 735 @Override
0feca163
SG
736 public final void enqueueEvent(boolean wait, com.jogamp.newt.event.NEWTEvent event) {
737 window.enqueueEvent(wait, event);
738 }
739
3334a924 740 @Override
0feca163
SG
741 public final void runOnEDTIfAvail(boolean wait, final Runnable task) {
742 window.runOnEDTIfAvail(wait, task);
743 }
0feca163 744
3334a924 745 @Override
0feca163
SG
746 public void sendWindowEvent(int eventType) {
747 window.sendWindowEvent(eventType);
748 }
749
3334a924 750 @Override
0feca163
SG
751 public final WindowListener getWindowListener(int index) {
752 return window.getWindowListener(index);
753 }
754
3334a924 755 @Override
0feca163
SG
756 public final WindowListener[] getWindowListeners() {
757 return window.getWindowListeners();
758 }
759
3334a924 760 @Override
0feca163
SG
761 public final void removeWindowListener(WindowListener l) {
762 window.removeWindowListener(l);
763 }
764
3334a924 765 @Override
0feca163
SG
766 public final void addWindowListener(WindowListener l) {
767 window.addWindowListener(l);
768 }
769
3334a924 770 @Override
0feca163
SG
771 public final void addWindowListener(int index, WindowListener l) throws IndexOutOfBoundsException {
772 window.addWindowListener(index, l);
773 }
774
3334a924 775 @Override
533e072a
SG
776 public final void setKeyboardVisible(boolean visible) {
777 window.setKeyboardVisible(visible);
778 }
3334a924
SG
779
780 @Override
533e072a
SG
781 public final boolean isKeyboardVisible() {
782 return window.isKeyboardVisible();
783 }
3334a924
SG
784
785 @Override
0feca163
SG
786 public final void addKeyListener(KeyListener l) {
787 window.addKeyListener(l);
788 }
789
3334a924 790 @Override
0feca163
SG
791 public final void addKeyListener(int index, KeyListener l) {
792 window.addKeyListener(index, l);
793 }
794
3334a924 795 @Override
0feca163
SG
796 public final void removeKeyListener(KeyListener l) {
797 window.removeKeyListener(l);
798 }
799
3334a924 800 @Override
0feca163
SG
801 public final KeyListener getKeyListener(int index) {
802 return window.getKeyListener(index);
803 }
804
3334a924 805 @Override
0feca163
SG
806 public final KeyListener[] getKeyListeners() {
807 return window.getKeyListeners();
808 }
809
3334a924 810 @Override
0feca163
SG
811 public final void addMouseListener(MouseListener l) {
812 window.addMouseListener(l);
813 }
814
3334a924 815 @Override
0feca163
SG
816 public final void addMouseListener(int index, MouseListener l) {
817 window.addMouseListener(index, l);
818 }
819
3334a924 820 @Override
0feca163
SG
821 public final void removeMouseListener(MouseListener l) {
822 window.removeMouseListener(l);
823 }
824
3334a924 825 @Override
0feca163
SG
826 public final MouseListener getMouseListener(int index) {
827 return window.getMouseListener(index);
828 }
829
3334a924 830 @Override
0feca163
SG
831 public final MouseListener[] getMouseListeners() {
832 return window.getMouseListeners();
833 }
834
bc72e232
SG
835 @Override
836 public void setDefaultGesturesEnabled(boolean enable) {
837 window.setDefaultGesturesEnabled(enable);
838 }
839 @Override
840 public boolean areDefaultGesturesEnabled() {
841 return window.areDefaultGesturesEnabled();
842 }
843 @Override
844 public final void addGestureHandler(GestureHandler gh) {
845 window.addGestureHandler(gh);
846 }
847 @Override
848 public final void addGestureHandler(int index, GestureHandler gh) {
849 window.addGestureHandler(index, gh);
850 }
851 @Override
852 public final void removeGestureHandler(GestureHandler gh) {
853 window.removeGestureHandler(gh);
854 }
855 @Override
856 public final void addGestureListener(GestureHandler.GestureListener gl) {
857 window.addGestureListener(-1, gl);
858 }
859 @Override
860 public final void addGestureListener(int index, GestureHandler.GestureListener gl) {
861 window.addGestureListener(index, gl);
862 }
863 @Override
864 public final void removeGestureListener(GestureHandler.GestureListener gl) {
865 window.removeGestureListener(gl);
866 }
5e9c02bc 867
0feca163
SG
868 //----------------------------------------------------------------------
869 // NativeWindow completion
870 //
871
a06e40cc 872 @Override
d10c7916 873 public final int lockSurface() throws NativeWindowException, RuntimeException {
0feca163
SG
874 return window.lockSurface();
875 }
876
a06e40cc 877 @Override
d10c7916 878 public final void unlockSurface() {
0feca163
SG
879 window.unlockSurface();
880 }
881
a06e40cc 882 @Override
0feca163
SG
883 public final boolean isSurfaceLockedByOtherThread() {
884 return window.isSurfaceLockedByOtherThread();
885 }
886
a06e40cc 887 @Override
0feca163
SG
888 public final Thread getSurfaceLockOwner() {
889 return window.getSurfaceLockOwner();
890
891 }
892
3334a924 893 @Override
0feca163
SG
894 public final boolean surfaceSwap() {
895 return window.surfaceSwap();
896 }
897
3334a924 898 @Override
8be9d9b5
SG
899 public final void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) {
900 window.removeSurfaceUpdatedListener(l);
901 }
902
903 @Override
904 public final void addSurfaceUpdatedListener(SurfaceUpdatedListener l) {
905 window.addSurfaceUpdatedListener(l);
906 }
907
908 @Override
909 public final void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l) throws IndexOutOfBoundsException {
910 window.addSurfaceUpdatedListener(index, l);
911 }
912
913 @Override
914 public final void surfaceUpdated(Object updater, NativeSurface ns, long when) {
915 window.surfaceUpdated(updater, ns, when);
916 }
917
918 @Override
0feca163
SG
919 public final long getWindowHandle() {
920 return window.getWindowHandle();
921
922 }
923
3334a924 924 @Override
0feca163
SG
925 public final long getSurfaceHandle() {
926 return window.getSurfaceHandle();
927
928 }
929
3334a924 930 @Override
0feca163
SG
931 public final AbstractGraphicsConfiguration getGraphicsConfiguration() {
932 return window.getGraphicsConfiguration();
933 }
934
3334a924 935 @Override
0feca163
SG
936 public final long getDisplayHandle() {
937 return window.getDisplayHandle();
938 }
939
3334a924 940 @Override
0feca163
SG
941 public final int getScreenIndex() {
942 return window.getScreenIndex();
943 }
944
597d10f5
SG
945 /**
946 * A most simple JOGL AWT test entry
947 */
948 public static void main(String args[]) {
1a20ef3a
SG
949 final boolean forceES2;
950 final boolean forceES3;
951 final boolean forceGL3;
952 final boolean forceGL4ES3;
953 {
954 boolean _forceES2 = false;
955 boolean _forceES3 = false;
956 boolean _forceGL3 = false;
957 boolean _forceGL4ES3 = false;
958 if( null != args ) {
959 for(int i=0; i<args.length; i++) {
960 if(args[i].equals("-es2")) {
961 _forceES2 = true;
962 } else if(args[i].equals("-es3")) {
963 _forceES3 = true;
964 } else if(args[i].equals("-gl3")) {
965 _forceGL3 = true;
966 } else if(args[i].equals("-gl4es3")) {
967 _forceGL4ES3 = true;
5e9c02bc 968 }
1a20ef3a 969 }
3a0d7703 970 }
1a20ef3a
SG
971 forceES2 = _forceES2;
972 forceES3 = _forceES3;
973 forceGL3 = _forceGL3;
974 forceGL4ES3 = _forceGL4ES3;
3a0d7703 975 }
1a20ef3a
SG
976 System.err.println("forceES2 "+forceES2);
977 System.err.println("forceES3 "+forceES3);
978 System.err.println("forceGL3 "+forceGL3);
979 System.err.println("forceGL4ES3 "+forceGL4ES3);
5e9c02bc 980
8c9f3bb3 981 System.err.println(VersionUtil.getPlatformInfo());
6ea02e25 982 System.err.println(GlueGenVersion.getInstance());
2aa90676 983 System.err.println(JoglVersion.getInstance());
8adc0478 984
20bf031d 985 System.err.println(JoglVersion.getDefaultOpenGLInfo(null, null, true).toString());
4011e70e 986
3a0d7703 987 final GLProfile glp;
1a20ef3a
SG
988 if(forceGL4ES3) {
989 glp = GLProfile.get(GLProfile.GL4ES3);
990 } else if(forceGL3) {
3a0d7703
SG
991 glp = GLProfile.get(GLProfile.GL3);
992 } else if(forceES3) {
993 glp = GLProfile.get(GLProfile.GLES3);
994 } else if(forceES2) {
995 glp = GLProfile.get(GLProfile.GLES2);
996 } else {
997 glp = GLProfile.getDefault();
998 }
3349511a 999 final GLCapabilitiesImmutable caps = new GLCapabilities( glp );
3a0d7703 1000 System.err.println("Requesting: "+caps);
597d10f5
SG
1001
1002 GLWindow glWindow = GLWindow.create(caps);
1003 glWindow.setSize(128, 128);
1004
1005 glWindow.addGLEventListener(new GLEventListener() {
3334a924 1006 @Override
597d10f5
SG
1007 public void init(GLAutoDrawable drawable) {
1008 GL gl = drawable.getGL();
10c696f7 1009 System.err.println(JoglVersion.getGLInfo(gl, null));
3349511a
SG
1010 System.err.println("Requested: "+drawable.getNativeSurface().getGraphicsConfiguration().getRequestedCapabilities());
1011 System.err.println("Chosen : "+drawable.getChosenGLCapabilities());
1a20ef3a
SG
1012 System.err.println("GL impl. class "+gl.getClass().getName());
1013 if( gl.isGL4ES3() ) {
1014 GL4ES3 _gl = gl.getGL4ES3();
1015 System.err.println("GL4ES3 retrieved, impl. class "+_gl.getClass().getName());
1016 }
1017 if( gl.isGL3() ) {
1018 GL3 _gl = gl.getGL3();
1019 System.err.println("GL3 retrieved, impl. class "+_gl.getClass().getName());
1020 }
1021 if( gl.isGLES3() ) {
1022 GLES3 _gl = gl.getGLES3();
1023 System.err.println("GLES3 retrieved, impl. class "+_gl.getClass().getName());
1024 }
1025 if( gl.isGLES2() ) {
1026 GLES2 _gl = gl.getGLES2();
1027 System.err.println("GLES2 retrieved, impl. class "+_gl.getClass().getName());
1028 }
597d10f5
SG
1029 }
1030
3334a924 1031 @Override
597d10f5
SG
1032 public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
1033 }
1034
3334a924 1035 @Override
597d10f5
SG
1036 public void display(GLAutoDrawable drawable) {
1037 }
1038
3334a924 1039 @Override
597d10f5
SG
1040 public void dispose(GLAutoDrawable drawable) {
1041 }
1042 });
1043
1044 glWindow.setVisible(true);
f47230cb 1045 glWindow.destroy();
597d10f5 1046 }
a959c53b 1047}
http://JogAmp.org git info: FAQ, tutorial and man pages.