Jogamp
Animator: Cleanup and better DEBUG info
[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.
a959c53b
KR
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * - Redistribution of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
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.
15 *
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.
19 *
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.
32 *
33 */
34
2d57c252 35package com.jogamp.newt.opengl;
a959c53b 36
8adc0478
SG
37import java.util.List;
38
dac35658 39import com.jogamp.common.GlueGenVersion;
8c9f3bb3 40import com.jogamp.common.util.VersionUtil;
dac35658 41import com.jogamp.nativewindow.NativeWindowVersion;
2d57c252 42import com.jogamp.newt.*;
1ad8c39d 43import com.jogamp.newt.event.*;
360b6716 44import jogamp.newt.WindowImpl;
8adc0478 45
a959c53b 46import javax.media.nativewindow.*;
018c7e86 47import javax.media.nativewindow.util.Point;
8adc0478 48import javax.media.nativewindow.util.Insets;
a959c53b 49import javax.media.opengl.*;
8adc0478 50
360b6716 51import jogamp.opengl.GLDrawableHelper;
dac35658 52import com.jogamp.opengl.JoglVersion;
a959c53b
KR
53
54/**
0feca163
SG
55 * An implementation of {@link javax.media.opengl.GLAutoDrawable} interface,
56 * using an aggregation of a {@link com.jogamp.newt.Window} implementation.
2268a6ce
SG
57 * <P>
58 * This implementation does not make the OpenGL context current<br>
0feca163
SG
59 * before calling the various input EventListener callbacks, ie {@link com.jogamp.newt.event.MouseListener} etc.<br>
60 * This design decision is made in favor of a more performant and simplified
61 * implementation. Also the event dispatcher shall be implemented OpenGL agnostic.<br>
62 * To be able to use OpenGL commands from within such input {@link com.jogamp.newt.event.NEWTEventListener},<br>
63 * you can inject {@link javax.media.opengl.GLRunnable} objects
64 * via {@link #invoke(boolean, javax.media.opengl.GLRunnable)} to the OpenGL command stream.<br>
2268a6ce 65 * <p>
a959c53b 66 */
1b7b5d34 67public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer {
0feca163 68 private WindowImpl window;
a959c53b 69
476d1d75
MB
70 /**
71 * Constructor. Do not call this directly -- use {@link #create()} instead.
72 */
811bd23e 73 protected GLWindow(Window window) {
018c7e86 74 resetCounter();
0feca163
SG
75 this.window = (WindowImpl) window;
76 ((WindowImpl)this.window).setHandleDestroyNotify(false);
1ad8c39d 77 window.addWindowListener(new WindowAdapter() {
10c696f7 78 @Override
969e4276 79 public void windowRepaint(WindowUpdateEvent e) {
e587f2a7 80 if( !GLWindow.this.window.isWindowLockedByOtherThread() && !GLWindow.this.helper.isExternalAnimatorAnimating() ) {
969e4276
SG
81 display();
82 }
83 }
84
10c696f7 85 @Override
a959c53b
KR
86 public void windowResized(WindowEvent e) {
87 sendReshape = true;
e587f2a7 88 if( !GLWindow.this.window.isWindowLockedByOtherThread() && !GLWindow.this.helper.isExternalAnimatorAnimating() ) {
969e4276
SG
89 display();
90 }
a959c53b
KR
91 }
92
10c696f7 93 @Override
a959c53b 94 public void windowDestroyNotify(WindowEvent e) {
2cbab63b
SG
95 if( DISPOSE_ON_CLOSE == GLWindow.this.getDefaultCloseOperation() ) {
96 // Is an animator thread perform rendering?
97 if (GLWindow.this.helper.isExternalAnimatorRunning()) {
98 // Pause animations before initiating safe destroy.
99 GLAnimatorControl ctrl = GLWindow.this.helper.getAnimator();
100 boolean isPaused = ctrl.pause();
101 destroy();
102 if(isPaused) {
103 ctrl.resume();
104 }
e587f2a7
SG
105 } else if (GLWindow.this.window.isWindowLockedByOtherThread()) {
106 // Window is locked by another thread
2cbab63b
SG
107 // Flag that destroy should be performed on the next
108 // attempt to display.
109 sendDestroy = true;
110 } else {
111 // Without an external thread animating or locking the
112 // surface, we are safe.
113 destroy ();
4c3e9e25 114 }
5ece52d5 115 }
a959c53b
KR
116 }
117 });
0feca163 118 this.window.setLifecycleHook(new GLLifecycleHook());
a959c53b
KR
119 }
120
0feca163
SG
121 /**
122 * Creates a new GLWindow attaching a new Window referencing a new Screen
123 * with the given GLCapabilities.
124 * <P>
125 * The resulting GLWindow owns the Window, Screen and Device, ie it will be destructed.
126 */
29e3b223 127 public static GLWindow create(GLCapabilitiesImmutable caps) {
0feca163 128 return new GLWindow(NewtFactory.createWindow(caps));
a959c53b
KR
129 }
130
0feca163
SG
131 /**
132 * Creates a new GLWindow attaching a new Window referencing the given Screen
133 * with the given GLCapabilities.
134 * <P>
135 * The resulting GLWindow owns the Window, ie it will be destructed.
136 */
29e3b223 137 public static GLWindow create(Screen screen, GLCapabilitiesImmutable caps) {
0feca163 138 return new GLWindow(NewtFactory.createWindow(screen, caps));
a959c53b
KR
139 }
140
0feca163
SG
141 /**
142 * Creates a new GLWindow attaching the given window.
143 * <P>
144 * The resulting GLWindow does not own the given Window, ie it will not be destructed.
145 */
146 public static GLWindow create(Window window) {
811bd23e 147 return new GLWindow(window);
a959c53b 148 }
6e599a26 149
0feca163
SG
150 /**
151 * Creates a new GLWindow attaching a new child Window
152 * of the given <code>parentNativeWindow</code> with the given GLCapabilities.
153 * <P>
154 * The Display/Screen will be compatible with the <code>parentNativeWindow</code>,
155 * or even identical in case it's a Newt Window.
156 * <P>
157 * The resulting GLWindow owns the Window, ie it will be destructed.
158 */
29e3b223 159 public static GLWindow create(NativeWindow parentNativeWindow, GLCapabilitiesImmutable caps) {
0feca163 160 return new GLWindow(NewtFactory.createWindow(parentNativeWindow, caps));
a959c53b 161 }
a959c53b 162
0feca163 163 //----------------------------------------------------------------------
2cbab63b
SG
164 // WindowClosingProtocol implementation
165 //
166 public int getDefaultCloseOperation() {
167 return window.getDefaultCloseOperation();
168 }
169
170 public int setDefaultCloseOperation(int op) {
171 return window.setDefaultCloseOperation(op);
172 }
173
174 //----------------------------------------------------------------------
0feca163
SG
175 // Window Access
176 //
a959c53b 177
7c159772
SG
178 public CapabilitiesChooser setCapabilitiesChooser(CapabilitiesChooser chooser) {
179 return window.setCapabilitiesChooser(chooser);
180 }
181
e4913066 182 public final CapabilitiesImmutable getChosenCapabilities() {
0feca163
SG
183 if (drawable == null) {
184 return window.getChosenCapabilities();
811bd23e 185 }
811bd23e 186
0feca163 187 return drawable.getChosenGLCapabilities();
a959c53b
KR
188 }
189
e4913066 190 public final CapabilitiesImmutable getRequestedCapabilities() {
0feca163 191 return window.getRequestedCapabilities();
811bd23e
SG
192 }
193
0feca163
SG
194 public final Window getWindow() {
195 return window;
811bd23e
SG
196 }
197
018c7e86
SG
198 public final NativeWindow getParent() {
199 return window.getParent();
811bd23e
SG
200 }
201
0feca163 202 public final Screen getScreen() {
a959c53b
KR
203 return window.getScreen();
204 }
205
0feca163 206 public final void setTitle(String title) {
a959c53b
KR
207 window.setTitle(title);
208 }
209
0feca163 210 public final String getTitle() {
a959c53b
KR
211 return window.getTitle();
212 }
213
0feca163 214 public final void setUndecorated(boolean value) {
a959c53b
KR
215 window.setUndecorated(value);
216 }
217
0feca163 218 public final boolean isUndecorated() {
a959c53b
KR
219 return window.isUndecorated();
220 }
221
0feca163 222 public final void setFocusAction(FocusRunnable focusAction) {
a4b16ad5
SG
223 window.setFocusAction(focusAction);
224 }
0feca163
SG
225
226 public final void requestFocus() {
227 window.requestFocus();
811bd23e
SG
228 }
229
609e3083
SG
230 public boolean hasFocus() {
231 return window.hasFocus();
232 }
233
0feca163
SG
234 public final Insets getInsets() {
235 return window.getInsets();
811bd23e 236 }
a959c53b 237
0feca163 238 public final void setPosition(int x, int y) {
a959c53b
KR
239 window.setPosition(x, y);
240 }
7bed517f 241
0feca163 242 public final boolean setFullscreen(boolean fullscreen) {
a959c53b
KR
243 return window.setFullscreen(fullscreen);
244 }
0feca163
SG
245
246 public final boolean isFullscreen() {
247 return window.isFullscreen();
811bd23e 248 }
a959c53b 249
0feca163 250 public final boolean isVisible() {
a959c53b
KR
251 return window.isVisible();
252 }
253
10c696f7 254 @Override
0feca163
SG
255 public final String toString() {
256 return "NEWT-GLWindow[ \n\tHelper: " + helper + ", \n\tDrawable: " + drawable +
257 ", \n\tContext: " + context + /** ", \n\tWindow: "+window+", \n\tFactory: "+factory+ */ "]";
a959c53b
KR
258 }
259
0feca163
SG
260 public final int reparentWindow(NativeWindow newParent) {
261 return window.reparentWindow(newParent);
a959c53b
KR
262 }
263
0feca163
SG
264 public final int reparentWindow(NativeWindow newParent, boolean forceDestroyCreate) {
265 return window.reparentWindow(newParent, forceDestroyCreate);
a959c53b
KR
266 }
267
0feca163
SG
268 public final void removeChild(NativeWindow win) {
269 window.removeChild(win);
a959c53b
KR
270 }
271
0feca163
SG
272 public final void addChild(NativeWindow win) {
273 window.addChild(win);
a959c53b 274 }
2aa29677 275
0feca163
SG
276 //----------------------------------------------------------------------
277 // Window.LifecycleHook Implementation
278 //
969e4276 279
db4d7d19
SG
280 public final void destroy() {
281 window.destroy();
bf584fba
SG
282 }
283
0feca163
SG
284 public final void setVisible(boolean visible) {
285 window.setVisible(visible);
a959c53b
KR
286 }
287
0feca163
SG
288 public final void setSize(int width, int height) {
289 window.setSize(width, height);
a959c53b
KR
290 }
291
0feca163
SG
292 public final boolean isValid() {
293 return window.isValid();
969e4276 294 }
a959c53b 295
0feca163
SG
296 public final boolean isNativeValid() {
297 return window.isNativeValid();
a959c53b
KR
298 }
299
018c7e86
SG
300 public Point getLocationOnScreen(Point storage) {
301 return window.getLocationOnScreen(storage);
302 }
303
0feca163
SG
304 // Hide methods here ..
305 protected class GLLifecycleHook implements WindowImpl.LifecycleHook {
306
307 class DisposeAction implements Runnable {
308 public void run() {
309 // Lock: Covered by DestroyAction ..
310 helper.dispose(GLWindow.this);
311 }
312 }
313 DisposeAction disposeAction = new DisposeAction();
314
db4d7d19
SG
315 public synchronized void destroyActionPreLock() {
316 // nop
e6225fce
SG
317 }
318
db4d7d19 319 public synchronized void destroyActionInLock() {
0feca163 320 if(Window.DEBUG_WINDOW_EVENT || Window.DEBUG_IMPLEMENTATION) {
10c696f7 321 String msg = "GLWindow.destroy() "+Thread.currentThread()+", start";
0feca163
SG
322 System.err.println(msg);
323 //Exception e1 = new Exception(msg);
324 //e1.printStackTrace();
325 }
326
327 if( window.isNativeValid() && null != drawable && drawable.isRealized() ) {
328 if( null != context && context.isCreated() ) {
329 // Catch dispose GLExceptions by GLEventListener, just 'print' them
330 // so we can continue with the destruction.
331 try {
332 helper.invokeGL(drawable, context, disposeAction, null);
333 } catch (GLException gle) {
334 gle.printStackTrace();
335 }
336 context.destroy();
337 }
338 drawable.setRealized(false);
339 }
340 context = null;
341 drawable = null;
342
db4d7d19
SG
343 if(Window.DEBUG_WINDOW_EVENT || Window.DEBUG_IMPLEMENTATION) {
344 System.err.println("GLWindow.destroy() "+Thread.currentThread()+", fin");
0feca163 345 }
db4d7d19 346 }
0feca163 347
db4d7d19 348 public synchronized void invalidate(boolean unrecoverable) {
0feca163 349 if(Window.DEBUG_WINDOW_EVENT || Window.DEBUG_IMPLEMENTATION) {
10c696f7 350 String msg = "GLWindow.invalidate("+unrecoverable+") "+Thread.currentThread()+", start";
db4d7d19
SG
351 System.err.println(msg);
352 //Exception e1 = new Exception(msg);
353 //e1.printStackTrace();
354 }
355 if(unrecoverable) {
356 GLAnimatorControl ctrl = GLWindow.this.getAnimator();
2aa29677
SG
357 if ( null!=ctrl ) {
358 ctrl.remove(GLWindow.this);
db4d7d19
SG
359 }
360 helper=null;
0feca163
SG
361 }
362 }
363
2c1a870f 364 public synchronized void resetCounter() {
0feca163 365 if(Window.DEBUG_WINDOW_EVENT || Window.DEBUG_IMPLEMENTATION) {
2c1a870f
SG
366 System.err.println("GLWindow.resetCounter() "+Thread.currentThread());
367 }
368 GLWindow.this.resetCounter();
369 }
370
371 public synchronized void setVisibleActionPost(boolean visible, boolean nativeWindowCreated) {
372 if(Window.DEBUG_WINDOW_EVENT || Window.DEBUG_IMPLEMENTATION) {
10c696f7 373 String msg = "GLWindow.setVisibleActionPost("+visible+", "+nativeWindowCreated+") "+Thread.currentThread()+", start";
0feca163
SG
374 System.err.println(msg);
375 // Exception e1 = new Exception(msg);
376 // e1.printStackTrace();
377 }
378
379 /* if (nativeWindowCreated && null != context) {
380 throw new GLException("InternalError: Native Windows has been just created, but context wasn't destroyed (is not null)");
381 } */
382 if (null == context && visible && 0 != window.getWindowHandle() && 0<getWidth()*getHeight()) {
383 NativeWindow nw;
384 if (window.getWrappedWindow() != null) {
385 nw = NativeWindowFactory.getNativeWindow(window.getWrappedWindow(), window.getGraphicsConfiguration());
386 } else {
387 nw = window;
388 }
29e3b223 389 GLCapabilitiesImmutable glCaps = (GLCapabilitiesImmutable) nw.getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities();
0feca163
SG
390 if(null==factory) {
391 factory = GLDrawableFactory.getFactory(glCaps.getGLProfile());
392 }
393 if(null==drawable) {
394 drawable = factory.createGLDrawable(nw);
395 }
396 drawable.setRealized(true);
fd0d3f15 397 context = drawable.createContext(sharedContext);
0feca163
SG
398 }
399 if(Window.DEBUG_WINDOW_EVENT || Window.DEBUG_IMPLEMENTATION) {
10c696f7 400 String msg = "GLWindow.setVisibleActionPost("+visible+", "+nativeWindowCreated+") "+Thread.currentThread()+", fin";
0feca163
SG
401 System.err.println(msg);
402 //Exception e1 = new Exception(msg);
403 //e1.printStackTrace();
404 }
405 }
2aa29677
SG
406
407 public synchronized boolean pauseRenderingAction() {
408 boolean animatorPaused = false;
0feca163 409 GLAnimatorControl ctrl = GLWindow.this.getAnimator();
4c3e9e25
SG
410 if ( null!=ctrl ) {
411 animatorPaused = ctrl.pause();
0feca163 412 }
2aa29677 413 return animatorPaused;
0feca163
SG
414 }
415
a0e9d6c8 416 public synchronized void resumeRenderingAction() {
0feca163 417 GLAnimatorControl ctrl = GLWindow.this.getAnimator();
2aa29677 418 if ( null!=ctrl && ctrl.isPaused() ) {
0feca163
SG
419 ctrl.resume();
420 }
421 }
422 }
a0e9d6c8 423
a959c53b
KR
424 //----------------------------------------------------------------------
425 // OpenGL-related methods and state
426 //
427
fd0d3f15 428 private GLContext sharedContext = null;
a959c53b
KR
429 private GLDrawableFactory factory;
430 private GLDrawable drawable;
431 private GLContext context;
432 private GLDrawableHelper helper = new GLDrawableHelper();
433 // To make reshape events be sent immediately before a display event
434 private boolean sendReshape=false;
435 private boolean sendDestroy=false;
436 private boolean perfLog = false;
0feca163
SG
437 private long startTime, curTime, lastCheck;
438 private int totalFrames, lastFrames;
439
a959c53b
KR
440 public GLDrawableFactory getFactory() {
441 return factory;
442 }
443
fd0d3f15
SG
444 /**
445 * Specifies an {@link javax.media.opengl.GLContext OpenGL context} to share with.<br>
446 * At native creation, {@link #setVisible(boolean) setVisible(true)},
447 * a {@link javax.media.opengl.GLDrawable drawable} and {@link javax.media.opengl.GLContext context} is created besides the native Window itself,<br>
448 * hence you shall set the shared context before.
449 *
450 * @param sharedContext The OpenGL context shared by this GLWindow's one
451 */
452 public void setSharedContext(GLContext sharedContext) {
453 this.sharedContext = sharedContext;
454 }
455
a959c53b
KR
456 public void setContext(GLContext newCtx) {
457 context = newCtx;
458 }
459
460 public GLContext getContext() {
461 return context;
462 }
463
464 public GL getGL() {
465 if (context == null) {
466 return null;
467 }
468 return context.getGL();
469 }
470
4e0a5af0 471 public GL setGL(GL gl) {
a959c53b
KR
472 if (context != null) {
473 context.setGL(gl);
4e0a5af0 474 return gl;
a959c53b 475 }
4e0a5af0 476 return null;
a959c53b
KR
477 }
478
479 public void addGLEventListener(GLEventListener listener) {
77413854
SG
480 if(null!=helper) {
481 helper.addGLEventListener(listener);
482 }
a959c53b
KR
483 }
484
302f183c 485 public void addGLEventListener(int index, GLEventListener listener) {
77413854
SG
486 if(null!=helper) {
487 helper.addGLEventListener(index, listener);
488 }
302f183c
SG
489 }
490
a959c53b 491 public void removeGLEventListener(GLEventListener listener) {
77413854
SG
492 if(null!=helper) {
493 helper.removeGLEventListener(listener);
494 }
a959c53b
KR
495 }
496
0feca163 497 public void setAnimator(GLAnimatorControl animatorControl) {
77413854
SG
498 if(null!=helper) {
499 helper.setAnimator(animatorControl);
500 }
969e4276
SG
501 }
502
0feca163 503 public GLAnimatorControl getAnimator() {
77413854
SG
504 if(null!=helper) {
505 return helper.getAnimator();
506 }
507 return null;
969e4276
SG
508 }
509
0feca163
SG
510 public boolean getPerfLogEnabled() { return perfLog; }
511
512 public void enablePerfLog(boolean v) {
513 perfLog = v;
514 }
515
0d24458c 516 public void invoke(boolean wait, GLRunnable glRunnable) {
77413854
SG
517 if(null!=helper) {
518 helper.invoke(this, wait, glRunnable);
519 }
0d24458c
SG
520 }
521
a959c53b 522 public void display() {
cf4c4037
SG
523 display(false);
524 }
525
526 public void display(boolean forceReshape) {
6e599a26
SG
527 if( null == window ) { return; }
528
969e4276 529 if(sendDestroy || ( null!=window && window.hasDeviceChanged() && GLAutoDrawable.SCREEN_CHANGE_ACTION_ENABLED ) ) {
63be4a40
SG
530 sendDestroy=false;
531 destroy();
532 return;
533 }
969e4276 534
5e1a67c9 535 if( null == context && isVisible() && 0<getWidth()*getHeight() ) {
6e599a26
SG
536 // retry native window and drawable/context creation
537 setVisible(true);
538 }
539
2aa29677
SG
540 if(forceReshape) {
541 sendReshape = true;
542 }
543
544 if( isVisible() && null != context ) {
c8a9c59e 545 if( NativeSurface.LOCK_SURFACE_NOT_READY < lockSurface() ) {
1d265b51 546 try {
c8a9c59e
SG
547 helper.invokeGL(drawable, context, displayAction, initAction);
548 } finally {
549 unlockSurface();
550 }
a959c53b
KR
551 }
552 }
553 }
554
a92906bc 555 /** This implementation uses a static value */
a959c53b 556 public void setAutoSwapBufferMode(boolean onOrOff) {
77413854
SG
557 if(null!=helper) {
558 helper.setAutoSwapBufferMode(onOrOff);
559 }
a959c53b
KR
560 }
561
a92906bc 562 /** This implementation uses a static value */
a959c53b 563 public boolean getAutoSwapBufferMode() {
77413854
SG
564 if(null!=helper) {
565 return helper.getAutoSwapBufferMode();
566 }
567 return false;
a959c53b
KR
568 }
569
570 public void swapBuffers() {
2268a6ce 571 if(drawable!=null && context != null) {
1d333a77 572 // Lock: Locked Surface/Window by MakeCurrent/Release
2268a6ce 573 if (context != GLContext.getCurrent()) {
a959c53b
KR
574 // Assume we should try to make the context current before swapping the buffers
575 helper.invokeGL(drawable, context, swapBuffersAction, initAction);
576 } else {
577 drawable.swapBuffers();
578 }
579 }
580 }
581
582 class InitAction implements Runnable {
583 public void run() {
1d333a77 584 // Lock: Locked Surface/Window by MakeCurrent/Release
a959c53b 585 helper.init(GLWindow.this);
018c7e86 586 resetCounter();
a959c53b
KR
587 }
588 }
589 private InitAction initAction = new InitAction();
590
a959c53b
KR
591 class DisplayAction implements Runnable {
592 public void run() {
1d333a77 593 // Lock: Locked Surface/Window by display _and_ MakeCurrent/Release
a959c53b 594 if (sendReshape) {
969e4276 595 helper.reshape(GLWindow.this, 0, 0, getWidth(), getHeight());
a959c53b
KR
596 sendReshape = false;
597 }
598
599 helper.display(GLWindow.this);
600
601 curTime = System.currentTimeMillis();
602 totalFrames++;
603
604 if(perfLog) {
605 long dt0, dt1;
606 lastFrames++;
607 dt0 = curTime-lastCheck;
608 if ( dt0 > 5000 ) {
609 dt1 = curTime-startTime;
0feca163 610 System.err.println(dt0/1000 +"s: "+ lastFrames + "f, " + (lastFrames*1000)/dt0 + " fps, "+dt0/lastFrames+" ms/f; "+
a959c53b
KR
611 "total: "+ dt1/1000+"s, "+(totalFrames*1000)/dt1 + " fps, "+dt1/totalFrames+" ms/f");
612 lastCheck=curTime;
613 lastFrames=0;
614 }
615 }
616 }
617 }
a92906bc 618 private DisplayAction displayAction = new DisplayAction();
a959c53b 619
0feca163
SG
620 /**
621 * @return Time of the first display call in milliseconds.
622 * This value is reset if becoming visible again or reparenting.
0feca163
SG
623 */
624 public final long getStartTime() {
018c7e86 625 return startTime;
0feca163 626 }
a959c53b 627
0feca163
SG
628 /**
629 * @return Time of the last display call in milliseconds.
630 * This value is reset if becoming visible again or reparenting.
0feca163
SG
631 */
632 public final long getCurrentTime() {
018c7e86 633 return curTime;
0feca163
SG
634 }
635
636 /**
637 * @return Duration <code>getCurrentTime() - getStartTime()</code>.
638 *
639 * @see #getStartTime()
640 * @see #getCurrentTime()
641 */
642 public final long getDuration() {
643 return getCurrentTime()-getStartTime();
644 }
645
646 /**
647 * @return Number of frames displayed since the first display call, ie <code>getStartTime()</code>.
648 * This value is reset if becoming visible again or reparenting.
0feca163 649 */
018c7e86
SG
650 public final int getTotalFrames() {
651 return totalFrames;
652 }
653
654 /** Reset all counter (startTime, currentTime, frame number) */
10c696f7 655 public final synchronized void resetCounter() {
018c7e86
SG
656 startTime = System.currentTimeMillis(); // overwrite startTime to real init one
657 curTime = startTime;
658 lastCheck = startTime;
659 totalFrames = 0; lastFrames = 0;
0feca163 660 }
a959c53b 661
a959c53b
KR
662 class SwapBuffersAction implements Runnable {
663 public void run() {
664 drawable.swapBuffers();
665 }
666 }
a959c53b
KR
667 private SwapBuffersAction swapBuffersAction = new SwapBuffersAction();
668
669 //----------------------------------------------------------------------
0feca163 670 // GLDrawable methods
a959c53b
KR
671 //
672
018c7e86
SG
673 public final NativeSurface getNativeSurface() {
674 return null!=drawable ? drawable.getNativeSurface() : null;
a959c53b
KR
675 }
676
0feca163
SG
677 public final long getHandle() {
678 return null!=drawable ? drawable.getHandle() : 0;
8883fa88 679 }
680
0feca163
SG
681 public final int getX() {
682 return window.getX();
6e599a26
SG
683 }
684
0feca163
SG
685 public final int getY() {
686 return window.getY();
6e599a26
SG
687 }
688
0feca163
SG
689 public final int getWidth() {
690 return window.getWidth();
a959c53b
KR
691 }
692
0feca163
SG
693 public final int getHeight() {
694 return window.getHeight();
1d333a77
SG
695 }
696
a959c53b
KR
697 //----------------------------------------------------------------------
698 // GLDrawable methods that are not really needed
699 //
700
0feca163 701 public final GLContext createContext(GLContext shareWith) {
a959c53b
KR
702 return drawable.createContext(shareWith);
703 }
704
0feca163 705 public final void setRealized(boolean realized) {
a959c53b
KR
706 }
707
0feca163 708 public final boolean isRealized() {
811bd23e
SG
709 return ( null != drawable ) ? drawable.isRealized() : false;
710 }
711
29e3b223 712 public final GLCapabilitiesImmutable getChosenGLCapabilities() {
a959c53b
KR
713 if (drawable == null) {
714 throw new GLException("No drawable yet");
715 }
716
717 return drawable.getChosenGLCapabilities();
718 }
719
0feca163 720 public final GLProfile getGLProfile() {
a959c53b
KR
721 if (drawable == null) {
722 throw new GLException("No drawable yet");
723 }
724
725 return drawable.getGLProfile();
726 }
0feca163
SG
727
728 //----------------------------------------------------------------------
1b7b5d34
SG
729 // NEWTEventConsumer
730 //
731 public boolean consumeEvent(NEWTEvent event) {
732 return window.consumeEvent(event);
733 }
734
735 //----------------------------------------------------------------------
0feca163
SG
736 // Window completion
737 //
738 public final void windowRepaint(int x, int y, int width, int height) {
739 window.windowRepaint(x, y, width, height);
740 }
741
742 public final void enqueueEvent(boolean wait, com.jogamp.newt.event.NEWTEvent event) {
743 window.enqueueEvent(wait, event);
744 }
745
746 public final void runOnEDTIfAvail(boolean wait, final Runnable task) {
747 window.runOnEDTIfAvail(wait, task);
748 }
749
750 public final SurfaceUpdatedListener getSurfaceUpdatedListener(int index) {
751 return window.getSurfaceUpdatedListener(index);
752 }
753
754 public final SurfaceUpdatedListener[] getSurfaceUpdatedListeners() {
755 return window.getSurfaceUpdatedListeners();
756 }
757
758 public final void removeAllSurfaceUpdatedListener() {
759 window.removeAllSurfaceUpdatedListener();
760 }
761
762 public final void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) {
763 window.removeSurfaceUpdatedListener(l);
764 }
765
766 public final void addSurfaceUpdatedListener(SurfaceUpdatedListener l) {
767 window.addSurfaceUpdatedListener(l);
768 }
769
770 public final void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l) throws IndexOutOfBoundsException {
771 window.addSurfaceUpdatedListener(index, l);
772 }
773
774 public void sendWindowEvent(int eventType) {
775 window.sendWindowEvent(eventType);
776 }
777
778 public final WindowListener getWindowListener(int index) {
779 return window.getWindowListener(index);
780 }
781
782 public final WindowListener[] getWindowListeners() {
783 return window.getWindowListeners();
784 }
785
786 public final void removeWindowListener(WindowListener l) {
787 window.removeWindowListener(l);
788 }
789
790 public final void addWindowListener(WindowListener l) {
791 window.addWindowListener(l);
792 }
793
794 public final void addWindowListener(int index, WindowListener l) throws IndexOutOfBoundsException {
795 window.addWindowListener(index, l);
796 }
797
798 public final void addKeyListener(KeyListener l) {
799 window.addKeyListener(l);
800 }
801
802 public final void addKeyListener(int index, KeyListener l) {
803 window.addKeyListener(index, l);
804 }
805
806 public final void removeKeyListener(KeyListener l) {
807 window.removeKeyListener(l);
808 }
809
810 public final KeyListener getKeyListener(int index) {
811 return window.getKeyListener(index);
812 }
813
814 public final KeyListener[] getKeyListeners() {
815 return window.getKeyListeners();
816 }
817
818 public final void addMouseListener(MouseListener l) {
819 window.addMouseListener(l);
820 }
821
822 public final void addMouseListener(int index, MouseListener l) {
823 window.addMouseListener(index, l);
824 }
825
826 public final void removeMouseListener(MouseListener l) {
827 window.removeMouseListener(l);
828 }
829
830 public final MouseListener getMouseListener(int index) {
831 return window.getMouseListener(index);
832 }
833
834 public final MouseListener[] getMouseListeners() {
835 return window.getMouseListeners();
836 }
837
838 //----------------------------------------------------------------------
839 // NativeWindow completion
840 //
841
842 public final int lockSurface() {
843 return window.lockSurface();
844 }
845
846 public final void unlockSurface() throws NativeWindowException {
847 window.unlockSurface();
848 }
849
850 public final boolean isSurfaceLockedByOtherThread() {
851 return window.isSurfaceLockedByOtherThread();
852 }
853
854 public final boolean isSurfaceLocked() {
855 return window.isSurfaceLocked();
856 }
857
858 public final Thread getSurfaceLockOwner() {
859 return window.getSurfaceLockOwner();
860
861 }
862
0feca163
SG
863 public final boolean surfaceSwap() {
864 return window.surfaceSwap();
865 }
866
867 public final void invalidate() {
868 window.invalidate();
869 }
870
871 public final long getWindowHandle() {
872 return window.getWindowHandle();
873
874 }
875
876 public final long getSurfaceHandle() {
877 return window.getSurfaceHandle();
878
879 }
880
881 public final AbstractGraphicsConfiguration getGraphicsConfiguration() {
882 return window.getGraphicsConfiguration();
883 }
884
885 public final long getDisplayHandle() {
886 return window.getDisplayHandle();
887 }
888
889 public final int getScreenIndex() {
890 return window.getScreenIndex();
891 }
892
018c7e86
SG
893 public final void surfaceUpdated(Object updater, NativeSurface ns, long when) {
894 window.surfaceUpdated(updater, ns, when);
0feca163 895 }
597d10f5
SG
896
897 /**
898 * A most simple JOGL AWT test entry
899 */
900 public static void main(String args[]) {
8c9f3bb3 901 System.err.println(VersionUtil.getPlatformInfo());
6ea02e25
SG
902 System.err.println(GlueGenVersion.getInstance());
903 System.err.println(NativeWindowVersion.getInstance());
2aa90676 904 System.err.println(JoglVersion.getInstance());
6ea02e25 905 System.err.println(NewtVersion.getInstance());
8adc0478
SG
906
907 GLProfile glp = GLProfile.getDefault();
908 GLDrawableFactory factory = GLDrawableFactory.getFactory(glp);
909 List/*<GLCapabilitiesImmutable>*/ availCaps = factory.getAvailableCapabilities(null);
910 for(int i=0; i<availCaps.size(); i++) {
911 System.err.println(availCaps.get(i));
912 }
913 GLCapabilitiesImmutable caps = new GLCapabilities( glp );
597d10f5
SG
914
915 GLWindow glWindow = GLWindow.create(caps);
916 glWindow.setSize(128, 128);
917
918 glWindow.addGLEventListener(new GLEventListener() {
919 public void init(GLAutoDrawable drawable) {
920 GL gl = drawable.getGL();
10c696f7 921 System.err.println(JoglVersion.getGLInfo(gl, null));
597d10f5
SG
922 }
923
924 public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
925 }
926
927 public void display(GLAutoDrawable drawable) {
928 }
929
930 public void dispose(GLAutoDrawable drawable) {
931 }
932 });
933
934 glWindow.setVisible(true);
db4d7d19 935 glWindow.invalidate();
597d10f5
SG
936 }
937
a959c53b 938}
http://JogAmp.org git info: FAQ, tutorial and man pages.