Commit | Line | Data |
---|---|---|
a959c53b KR |
1 | /* |
2 | * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. | |
3 | * | |
4 | * Redistribution and use in source and binary forms, with or without | |
5 | * modification, are permitted provided that the following conditions are | |
6 | * met: | |
7 | * | |
8 | * - Redistribution of source code must retain the above copyright | |
9 | * notice, this list of conditions and the following disclaimer. | |
10 | * | |
11 | * - Redistribution in binary form must reproduce the above copyright | |
12 | * notice, this list of conditions and the following disclaimer in the | |
13 | * documentation and/or other materials provided with the distribution. | |
14 | * | |
15 | * Neither the name of Sun Microsystems, Inc. or the names of | |
16 | * contributors may be used to endorse or promote products derived from | |
17 | * this software without specific prior written permission. | |
18 | * | |
19 | * This software is provided "AS IS," without a warranty of any kind. ALL | |
20 | * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, | |
21 | * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A | |
22 | * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN | |
23 | * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR | |
24 | * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR | |
25 | * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR | |
26 | * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR | |
27 | * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE | |
28 | * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, | |
29 | * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF | |
30 | * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. | |
31 | * | |
32 | */ | |
33 | ||
be452bbf | 34 | package com.jogamp.javafx.newt.opengl; |
a959c53b | 35 | |
be452bbf | 36 | import com.jogamp.javafx.newt.*; |
a959c53b KR |
37 | import javax.media.nativewindow.*; |
38 | import javax.media.opengl.*; | |
f3bc93b0 | 39 | import com.jogamp.opengl.impl.GLDrawableHelper; |
a92906bc | 40 | import java.util.*; |
a959c53b KR |
41 | |
42 | /** | |
43 | * An implementation of {@link Window} which is customized for OpenGL | |
2268a6ce SG |
44 | * use, and which implements the {@link javax.media.opengl.GLAutoDrawable} interface. |
45 | * <P> | |
46 | * This implementation does not make the OpenGL context current<br> | |
47 | * before calling the various input EventListener callbacks (MouseListener, KeyListener, | |
48 | * etc.).<br> | |
49 | * This design decision is made to favor a more performant and simplified | |
50 | * implementation, as well as the event dispatcher shall be allowed | |
51 | * not having a notion about OpenGL. | |
52 | * <p> | |
a959c53b KR |
53 | */ |
54 | public class GLWindow extends Window implements GLAutoDrawable { | |
a92906bc SG |
55 | private static List/*GLWindow*/ glwindows = new ArrayList(); |
56 | ||
eab82899 | 57 | private boolean ownerOfWinScrDpy; |
a959c53b | 58 | private Window window; |
2268a6ce | 59 | private boolean runPumpMessages; |
a959c53b KR |
60 | |
61 | /** Constructor. Do not call this directly -- use {@link | |
62 | create()} instead. */ | |
eab82899 SG |
63 | protected GLWindow(Window window, boolean ownerOfWinScrDpy) { |
64 | this.ownerOfWinScrDpy = ownerOfWinScrDpy; | |
a959c53b KR |
65 | this.window = window; |
66 | this.window.setAutoDrawableClient(true); | |
2268a6ce | 67 | this.runPumpMessages = ( null == getScreen().getDisplay().getEDT() ) ; |
a959c53b KR |
68 | window.addWindowListener(new WindowListener() { |
69 | public void windowResized(WindowEvent e) { | |
70 | sendReshape = true; | |
71 | } | |
72 | ||
73 | public void windowMoved(WindowEvent e) { | |
74 | } | |
75 | ||
76 | public void windowGainedFocus(WindowEvent e) { | |
77 | } | |
78 | ||
79 | public void windowLostFocus(WindowEvent e) { | |
80 | } | |
81 | ||
82 | public void windowDestroyNotify(WindowEvent e) { | |
83 | sendDestroy = true; | |
84 | } | |
85 | }); | |
a92906bc SG |
86 | |
87 | List newglw = (List) ((ArrayList) glwindows).clone(); | |
88 | newglw.add(this); | |
89 | glwindows=newglw; | |
a959c53b KR |
90 | } |
91 | ||
92 | /** Creates a new GLWindow on the local display, screen 0, with a | |
93 | dummy visual ID, and with the default GLCapabilities. */ | |
94 | public static GLWindow create() { | |
95 | return create(null, null, false); | |
96 | } | |
97 | ||
98 | public static GLWindow create(boolean undecorated) { | |
99 | return create(null, null, undecorated); | |
100 | } | |
101 | ||
102 | /** Creates a new GLWindow referring to the given window. */ | |
103 | public static GLWindow create(Window window) { | |
104 | return create(window, null, false); | |
105 | } | |
106 | public static GLWindow create(GLCapabilities caps) { | |
107 | return create(null, caps, false); | |
108 | } | |
109 | ||
110 | /** Creates a new GLWindow on the local display, screen 0, with a | |
111 | dummy visual ID, and with the given GLCapabilities. */ | |
112 | public static GLWindow create(GLCapabilities caps, boolean undecorated) { | |
113 | return create(null, caps, undecorated); | |
114 | } | |
115 | ||
3cc7335e SG |
116 | /** Either or: window (prio), or caps and undecorated (2nd choice) */ |
117 | private static GLWindow create(Window window, | |
118 | GLCapabilities caps, | |
119 | boolean undecorated) { | |
a92906bc | 120 | Display display; |
eab82899 | 121 | boolean ownerOfWinScrDpy=false; |
a959c53b | 122 | if (window == null) { |
3cc7335e SG |
123 | if (caps == null) { |
124 | caps = new GLCapabilities(null); // default .. | |
125 | } | |
eab82899 | 126 | ownerOfWinScrDpy = true; |
a92906bc | 127 | display = NewtFactory.createDisplay(null); // local display |
a959c53b KR |
128 | Screen screen = NewtFactory.createScreen(display, 0); // screen 0 |
129 | window = NewtFactory.createWindow(screen, caps, undecorated); | |
130 | } | |
131 | ||
eab82899 | 132 | return new GLWindow(window, ownerOfWinScrDpy); |
a959c53b KR |
133 | } |
134 | ||
a92906bc SG |
135 | /** |
136 | * EXPERIMENTAL<br> | |
137 | * Enable or disables running the {@link Display#pumpMessages} in the {@link #display()} call.<br> | |
138 | * The default behavior is to run {@link Display#pumpMessages}.<P> | |
139 | * | |
140 | * The idea was that in a single threaded environment with one {@link Display} and many {@link Window}'s, | |
141 | * a performance benefit was expected while disabling the implicit {@link Display#pumpMessages} and | |
142 | * do it once via {@link GLWindow#runCurrentThreadPumpMessage()} <br> | |
143 | * This could not have been verified. No measurable difference could have been recognized.<P> | |
144 | * | |
145 | * Best performance has been achieved with one GLWindow per thread.<br> | |
146 | * | |
2268a6ce | 147 | * Enabling local pump messages while using the EDT, |
be452bbf | 148 | * {@link com.jogamp.javafx.newt.NewtFactory#setUseEDT(boolean)}, |
2268a6ce SG |
149 | * will result in an exception. |
150 | * | |
a92906bc SG |
151 | * @deprecated EXPERIMENTAL, semantic is about to be removed after further verification. |
152 | */ | |
153 | public void setRunPumpMessages(boolean onoff) { | |
2268a6ce SG |
154 | if( onoff && null!=getScreen().getDisplay().getEDT() ) { |
155 | throw new GLException("GLWindow.setRunPumpMessages(true) - Can't do with EDT on"); | |
156 | } | |
a92906bc SG |
157 | runPumpMessages = onoff; |
158 | } | |
159 | ||
3cc7335e | 160 | protected void createNative(long parentWindowHandle, Capabilities caps) { |
a959c53b KR |
161 | shouldNotCallThis(); |
162 | } | |
163 | ||
164 | protected void closeNative() { | |
165 | shouldNotCallThis(); | |
166 | } | |
167 | ||
eab82899 | 168 | protected void dispose(boolean regenerate, boolean sendEvent) { |
a959c53b | 169 | if(Window.DEBUG_WINDOW_EVENT || window.DEBUG_IMPLEMENTATION) { |
eab82899 | 170 | Exception e1 = new Exception("GLWindow.dispose("+regenerate+") "+Thread.currentThread()+", 1"); |
a959c53b KR |
171 | e1.printStackTrace(); |
172 | } | |
173 | ||
eab82899 SG |
174 | if(sendEvent) { |
175 | sendDisposeEvent(); | |
176 | } | |
a959c53b KR |
177 | |
178 | if (context != null) { | |
179 | context.destroy(); | |
180 | } | |
181 | if (drawable != null) { | |
182 | drawable.setRealized(false); | |
183 | } | |
184 | ||
a959c53b KR |
185 | if(regenerate) { |
186 | if(null==window) { | |
187 | throw new GLException("GLWindow.dispose(true): null window"); | |
188 | } | |
189 | ||
190 | // recreate GLDrawable, to reflect the new graphics configurations | |
191 | NativeWindow nw; | |
192 | if (window.getWrappedWindow() != null) { | |
193 | nw = NativeWindowFactory.getNativeWindow(window.getWrappedWindow(), window.getGraphicsConfiguration()); | |
194 | } else { | |
195 | nw = window; | |
196 | } | |
197 | drawable = factory.createGLDrawable(nw); | |
198 | drawable.setRealized(true); | |
a959c53b KR |
199 | context = drawable.createContext(null); |
200 | sendReshape = true; // ensure a reshape event is send .. | |
201 | } | |
202 | ||
203 | if(Window.DEBUG_WINDOW_EVENT || window.DEBUG_IMPLEMENTATION) { | |
2268a6ce | 204 | System.out.println("GLWindow.dispose("+regenerate+") "+Thread.currentThread()+", fin: "+this); |
a959c53b KR |
205 | } |
206 | } | |
207 | ||
208 | public synchronized void destroy() { | |
eab82899 | 209 | destroy(true); |
2268a6ce SG |
210 | } |
211 | ||
eab82899 SG |
212 | /** @param sendDisposeEvent should be false in a [time,reliable] critical shutdown */ |
213 | public synchronized void destroy(boolean sendDisposeEvent) { | |
a959c53b | 214 | if(Window.DEBUG_WINDOW_EVENT || window.DEBUG_IMPLEMENTATION) { |
2268a6ce | 215 | Exception e1 = new Exception("GLWindow.destroy "+Thread.currentThread()+", 1: "+this); |
a959c53b KR |
216 | e1.printStackTrace(); |
217 | } | |
218 | ||
a92906bc SG |
219 | List newglw = (List) ((ArrayList) glwindows).clone(); |
220 | newglw.remove(this); | |
221 | glwindows=newglw; | |
222 | ||
eab82899 | 223 | dispose(false, sendDisposeEvent); |
a959c53b | 224 | |
a959c53b | 225 | if(null!=window) { |
eab82899 SG |
226 | if(ownerOfWinScrDpy) { |
227 | window.destroy(true); | |
a959c53b | 228 | } |
a959c53b KR |
229 | } |
230 | ||
231 | drawable = null; | |
232 | context = null; | |
eab82899 | 233 | window = null; |
a959c53b | 234 | |
eab82899 SG |
235 | if(Window.DEBUG_WINDOW_EVENT || window.DEBUG_IMPLEMENTATION) { |
236 | System.out.println("GLWindow.destroy "+Thread.currentThread()+", fin: "+this); | |
a959c53b | 237 | } |
a959c53b KR |
238 | } |
239 | ||
240 | public boolean getPerfLogEnabled() { return perfLog; } | |
241 | ||
242 | public void enablePerfLog(boolean v) { | |
243 | perfLog = v; | |
244 | } | |
245 | ||
a959c53b | 246 | public void setVisible(boolean visible) { |
2268a6ce SG |
247 | if(Window.DEBUG_WINDOW_EVENT || window.DEBUG_IMPLEMENTATION) { |
248 | System.out.println(Thread.currentThread()+" GLWindow.setVisible("+visible+") START ; isVisible "+this.visible+" ; has context "+(null!=context)); | |
249 | } | |
250 | this.visible=visible; | |
a959c53b KR |
251 | window.setVisible(visible); |
252 | if (visible && context == null) { | |
253 | NativeWindow nw; | |
254 | if (window.getWrappedWindow() != null) { | |
255 | nw = NativeWindowFactory.getNativeWindow(window.getWrappedWindow(), window.getGraphicsConfiguration()); | |
256 | } else { | |
257 | nw = window; | |
258 | } | |
259 | GLCapabilities glCaps = (GLCapabilities) nw.getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities(); | |
260 | factory = GLDrawableFactory.getFactory(glCaps.getGLProfile()); | |
261 | drawable = factory.createGLDrawable(nw); | |
262 | drawable.setRealized(true); | |
a959c53b KR |
263 | context = drawable.createContext(null); |
264 | sendReshape = true; // ensure a reshape event is send .. | |
265 | } | |
2268a6ce SG |
266 | if(Window.DEBUG_WINDOW_EVENT || window.DEBUG_IMPLEMENTATION) { |
267 | System.out.println(Thread.currentThread()+" GLWindow.setVisible("+visible+") END ; has context "+(null!=context)); | |
268 | } | |
a959c53b KR |
269 | } |
270 | ||
271 | public Screen getScreen() { | |
272 | return window.getScreen(); | |
273 | } | |
274 | ||
275 | public void setTitle(String title) { | |
276 | window.setTitle(title); | |
277 | } | |
278 | ||
279 | public String getTitle() { | |
280 | return window.getTitle(); | |
281 | } | |
282 | ||
283 | public void setUndecorated(boolean value) { | |
284 | window.setUndecorated(value); | |
285 | } | |
286 | ||
287 | public boolean isUndecorated() { | |
288 | return window.isUndecorated(); | |
289 | } | |
290 | ||
291 | public void setSize(int width, int height) { | |
292 | window.setSize(width, height); | |
293 | } | |
294 | ||
295 | public void setPosition(int x, int y) { | |
296 | window.setPosition(x, y); | |
297 | } | |
298 | ||
7bed517f | 299 | public Insets getInsets() { |
300 | return window.getInsets(); | |
301 | } | |
302 | ||
a959c53b KR |
303 | public boolean setFullscreen(boolean fullscreen) { |
304 | return window.setFullscreen(fullscreen); | |
305 | } | |
306 | ||
307 | public boolean isVisible() { | |
308 | return window.isVisible(); | |
309 | } | |
310 | ||
311 | public int getX() { | |
312 | return window.getX(); | |
313 | } | |
314 | ||
315 | public int getY() { | |
316 | return window.getY(); | |
317 | } | |
318 | ||
319 | public int getWidth() { | |
320 | return window.getWidth(); | |
321 | } | |
322 | ||
323 | public int getHeight() { | |
324 | return window.getHeight(); | |
325 | } | |
326 | ||
327 | public boolean isFullscreen() { | |
328 | return window.isFullscreen(); | |
329 | } | |
330 | ||
bf584fba SG |
331 | public void addSurfaceUpdatedListener(SurfaceUpdatedListener l) { |
332 | window.addSurfaceUpdatedListener(l); | |
333 | } | |
334 | public void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) { | |
335 | window.removeSurfaceUpdatedListener(l); | |
336 | } | |
337 | public SurfaceUpdatedListener[] getSurfaceUpdatedListener() { | |
338 | return window.getSurfaceUpdatedListener(); | |
339 | } | |
340 | public void surfaceUpdated(Object updater, NativeWindow window0, long when) { | |
341 | window.surfaceUpdated(updater, window, when); | |
342 | } | |
343 | ||
a959c53b KR |
344 | public void addMouseListener(MouseListener l) { |
345 | window.addMouseListener(l); | |
346 | } | |
347 | ||
348 | public void removeMouseListener(MouseListener l) { | |
349 | window.removeMouseListener(l); | |
350 | } | |
351 | ||
352 | public MouseListener[] getMouseListeners() { | |
353 | return window.getMouseListeners(); | |
354 | } | |
355 | ||
356 | public void addKeyListener(KeyListener l) { | |
357 | window.addKeyListener(l); | |
358 | } | |
359 | ||
360 | public void removeKeyListener(KeyListener l) { | |
361 | window.removeKeyListener(l); | |
362 | } | |
363 | ||
364 | public KeyListener[] getKeyListeners() { | |
365 | return window.getKeyListeners(); | |
366 | } | |
367 | ||
368 | public void addWindowListener(WindowListener l) { | |
369 | window.addWindowListener(l); | |
370 | } | |
371 | ||
372 | public void removeWindowListener(WindowListener l) { | |
373 | window.removeWindowListener(l); | |
374 | } | |
375 | ||
376 | public WindowListener[] getWindowListeners() { | |
377 | return window.getWindowListeners(); | |
378 | } | |
379 | ||
380 | public String toString() { | |
bf584fba | 381 | return "NEWT-GLWindow[ \n\tDrawable: "+drawable+", \n\tWindow: "+window+", \n\tHelper: "+helper+", \n\tFactory: "+factory+"]"; |
a959c53b KR |
382 | } |
383 | ||
384 | //---------------------------------------------------------------------- | |
385 | // OpenGL-related methods and state | |
386 | // | |
387 | ||
a959c53b KR |
388 | private GLDrawableFactory factory; |
389 | private GLDrawable drawable; | |
390 | private GLContext context; | |
391 | private GLDrawableHelper helper = new GLDrawableHelper(); | |
392 | // To make reshape events be sent immediately before a display event | |
393 | private boolean sendReshape=false; | |
394 | private boolean sendDestroy=false; | |
395 | private boolean perfLog = false; | |
396 | ||
397 | public GLDrawableFactory getFactory() { | |
398 | return factory; | |
399 | } | |
400 | ||
401 | public void setContext(GLContext newCtx) { | |
402 | context = newCtx; | |
403 | } | |
404 | ||
405 | public GLContext getContext() { | |
406 | return context; | |
407 | } | |
408 | ||
409 | public GL getGL() { | |
410 | if (context == null) { | |
411 | return null; | |
412 | } | |
413 | return context.getGL(); | |
414 | } | |
415 | ||
4e0a5af0 | 416 | public GL setGL(GL gl) { |
a959c53b KR |
417 | if (context != null) { |
418 | context.setGL(gl); | |
4e0a5af0 | 419 | return gl; |
a959c53b | 420 | } |
4e0a5af0 | 421 | return null; |
a959c53b KR |
422 | } |
423 | ||
424 | public void addGLEventListener(GLEventListener listener) { | |
425 | helper.addGLEventListener(listener); | |
426 | } | |
427 | ||
428 | public void removeGLEventListener(GLEventListener listener) { | |
429 | helper.removeGLEventListener(listener); | |
430 | } | |
431 | ||
432 | public void display() { | |
cf4c4037 SG |
433 | display(false); |
434 | } | |
435 | ||
436 | public void display(boolean forceReshape) { | |
2268a6ce | 437 | if(window!=null && drawable!=null && context != null) { |
a92906bc | 438 | if(runPumpMessages) { |
2268a6ce | 439 | window.getScreen().getDisplay().pumpMessages(); |
a92906bc | 440 | } |
a959c53b | 441 | if(window.hasDeviceChanged() && GLAutoDrawable.SCREEN_CHANGE_ACTION_ENABLED) { |
eab82899 | 442 | dispose(true, true); |
a959c53b KR |
443 | } |
444 | if (sendDestroy) { | |
445 | destroy(); | |
446 | sendDestroy=false; | |
447 | } else { | |
cf4c4037 SG |
448 | if(forceReshape) { |
449 | sendReshape = true; | |
450 | } | |
a959c53b KR |
451 | helper.invokeGL(drawable, context, displayAction, initAction); |
452 | } | |
453 | } | |
454 | } | |
455 | ||
456 | private void sendDisposeEvent() { | |
2268a6ce | 457 | if(drawable!=null && context != null) { |
a959c53b KR |
458 | helper.invokeGL(drawable, context, disposeAction, null); |
459 | } | |
460 | } | |
461 | ||
a92906bc | 462 | /** This implementation uses a static value */ |
a959c53b | 463 | public void setAutoSwapBufferMode(boolean onOrOff) { |
2268a6ce | 464 | helper.setAutoSwapBufferMode(onOrOff); |
a959c53b KR |
465 | } |
466 | ||
a92906bc | 467 | /** This implementation uses a static value */ |
a959c53b | 468 | public boolean getAutoSwapBufferMode() { |
2268a6ce | 469 | return helper.getAutoSwapBufferMode(); |
a959c53b KR |
470 | } |
471 | ||
472 | public void swapBuffers() { | |
2268a6ce SG |
473 | if(drawable!=null && context != null) { |
474 | if (context != GLContext.getCurrent()) { | |
a959c53b KR |
475 | // Assume we should try to make the context current before swapping the buffers |
476 | helper.invokeGL(drawable, context, swapBuffersAction, initAction); | |
477 | } else { | |
478 | drawable.swapBuffers(); | |
479 | } | |
480 | } | |
481 | } | |
482 | ||
483 | class InitAction implements Runnable { | |
484 | public void run() { | |
485 | helper.init(GLWindow.this); | |
486 | startTime = System.currentTimeMillis(); | |
487 | curTime = startTime; | |
488 | if(perfLog) { | |
489 | lastCheck = startTime; | |
490 | totalFrames = 0; lastFrames = 0; | |
491 | } | |
492 | } | |
493 | } | |
494 | private InitAction initAction = new InitAction(); | |
495 | ||
496 | class DisposeAction implements Runnable { | |
497 | public void run() { | |
498 | helper.dispose(GLWindow.this); | |
499 | } | |
500 | } | |
501 | private DisposeAction disposeAction = new DisposeAction(); | |
502 | ||
503 | class DisplayAction implements Runnable { | |
504 | public void run() { | |
505 | if (sendReshape) { | |
506 | int width = getWidth(); | |
507 | int height = getHeight(); | |
508 | getGL().glViewport(0, 0, width, height); | |
509 | helper.reshape(GLWindow.this, 0, 0, width, height); | |
510 | sendReshape = false; | |
511 | } | |
512 | ||
513 | helper.display(GLWindow.this); | |
514 | ||
515 | curTime = System.currentTimeMillis(); | |
516 | totalFrames++; | |
517 | ||
518 | if(perfLog) { | |
519 | long dt0, dt1; | |
520 | lastFrames++; | |
521 | dt0 = curTime-lastCheck; | |
522 | if ( dt0 > 5000 ) { | |
523 | dt1 = curTime-startTime; | |
524 | System.out.println(dt0/1000 +"s: "+ lastFrames + "f, " + (lastFrames*1000)/dt0 + " fps, "+dt0/lastFrames+" ms/f; "+ | |
525 | "total: "+ dt1/1000+"s, "+(totalFrames*1000)/dt1 + " fps, "+dt1/totalFrames+" ms/f"); | |
526 | lastCheck=curTime; | |
527 | lastFrames=0; | |
528 | } | |
529 | } | |
530 | } | |
531 | } | |
a92906bc | 532 | private DisplayAction displayAction = new DisplayAction(); |
a959c53b KR |
533 | |
534 | public long getStartTime() { return startTime; } | |
535 | public long getCurrentTime() { return curTime; } | |
536 | public long getDuration() { return curTime-startTime; } | |
537 | public int getTotalFrames() { return totalFrames; } | |
538 | ||
539 | private long startTime = 0; | |
540 | private long curTime = 0; | |
541 | private long lastCheck = 0; | |
542 | private int totalFrames = 0, lastFrames = 0; | |
a959c53b | 543 | |
a959c53b KR |
544 | class SwapBuffersAction implements Runnable { |
545 | public void run() { | |
546 | drawable.swapBuffers(); | |
547 | } | |
548 | } | |
a959c53b KR |
549 | private SwapBuffersAction swapBuffersAction = new SwapBuffersAction(); |
550 | ||
551 | //---------------------------------------------------------------------- | |
552 | // GLDrawable methods | |
553 | // | |
554 | ||
555 | public NativeWindow getNativeWindow() { | |
556 | return null!=drawable ? drawable.getNativeWindow() : null; | |
557 | } | |
558 | ||
559 | public synchronized int lockSurface() throws NativeWindowException { | |
560 | if(null!=drawable) return drawable.getNativeWindow().lockSurface(); | |
561 | return NativeWindow.LOCK_SURFACE_NOT_READY; | |
562 | } | |
563 | ||
564 | public synchronized void unlockSurface() { | |
565 | if(null!=drawable) drawable.getNativeWindow().unlockSurface(); | |
566 | else throw new NativeWindowException("NEWT-GLWindow not locked"); | |
567 | } | |
568 | ||
569 | public synchronized boolean isSurfaceLocked() { | |
570 | if(null!=drawable) return drawable.getNativeWindow().isSurfaceLocked(); | |
571 | return false; | |
572 | } | |
573 | ||
574 | public synchronized Exception getLockedStack() { | |
575 | if(null!=drawable) return drawable.getNativeWindow().getLockedStack(); | |
576 | return null; | |
577 | } | |
578 | ||
8883fa88 | 579 | public boolean surfaceSwap() { |
580 | if(null!=drawable) return drawable.getNativeWindow().surfaceSwap(); | |
581 | return super.surfaceSwap(); | |
582 | } | |
583 | ||
a959c53b KR |
584 | public long getWindowHandle() { |
585 | if(null!=drawable) return drawable.getNativeWindow().getWindowHandle(); | |
586 | return super.getWindowHandle(); | |
587 | } | |
588 | ||
589 | public long getSurfaceHandle() { | |
590 | if(null!=drawable) return drawable.getNativeWindow().getSurfaceHandle(); | |
591 | return super.getSurfaceHandle(); | |
592 | } | |
593 | ||
594 | //---------------------------------------------------------------------- | |
595 | // GLDrawable methods that are not really needed | |
596 | // | |
597 | ||
598 | public GLContext createContext(GLContext shareWith) { | |
599 | return drawable.createContext(shareWith); | |
600 | } | |
601 | ||
602 | public void setRealized(boolean realized) { | |
603 | } | |
604 | ||
605 | public GLCapabilities getChosenGLCapabilities() { | |
606 | if (drawable == null) { | |
607 | throw new GLException("No drawable yet"); | |
608 | } | |
609 | ||
610 | return drawable.getChosenGLCapabilities(); | |
611 | } | |
612 | ||
613 | public GLProfile getGLProfile() { | |
614 | if (drawable == null) { | |
615 | throw new GLException("No drawable yet"); | |
616 | } | |
617 | ||
618 | return drawable.getGLProfile(); | |
619 | } | |
620 | ||
621 | //---------------------------------------------------------------------- | |
622 | // Internals only below this point | |
623 | // | |
624 | ||
625 | private void shouldNotCallThis() { | |
626 | throw new NativeWindowException("Should not call this"); | |
627 | } | |
628 | } |
http://JogAmp.org | git info: FAQ, tutorial and man pages. |