@Override public final void run() { // Lock: Locked Surface/Window by display _and_ MakeCurrent/Release if (sendReshape) { helper.reshape(GLAutoDrawableBase.this, 0, 0, getWidth(), getHeight()); sendReshape = false; } helper.display(GLAutoDrawableBase.this); fpsCounter.tickFPS(); }
/** * Default implementation to destroys the drawable and context of this GLAutoDrawable: * * <ul> * <li>issues the GLEventListener dispose call, if drawable and context are valid * <li>destroys the GLContext, if valid * <li>destroys the GLDrawable, if valid * </ul> * * <p>Method assumes the lock is being hold. * * <p>Override it to extend it to destroy your resources, i.e. the actual window. In such case * call <code>super.destroyImplInLock</code> first. */ protected void destroyImplInLock() { if (preserveGLELSAtDestroy) { preserveGLStateAtDestroy(false); preserveGLEventListenerState(); } if (null != context) { if (context.isCreated()) { // Catch dispose GLExceptions by GLEventListener, just 'print' them // so we can continue with the destruction. try { helper.disposeGL(this, context, true); } catch (GLException gle) { gle.printStackTrace(); } } context = null; } if (null != drawable) { final AbstractGraphicsDevice device = drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice(); drawable.setRealized(false); drawable = null; if (ownsDevice) { device.close(); } } }
private void maybeDoSingleThreadedWorkaround( Runnable eventDispatchThreadAction, Runnable invokeGLAction, boolean isReshape) { if (Threading.isSingleThreaded() && !Threading.isOpenGLThread()) { Threading.invokeOnOpenGLThread(eventDispatchThreadAction); } else { drawableHelper.invokeGL(pbufferDrawable, context, invokeGLAction, initAction); } }
/** Default implementation to handle repaint events from the windowing system */ protected final void defaultWindowRepaintOp() { final GLDrawable _drawable = drawable; if (null != _drawable && _drawable.isRealized()) { if (!_drawable.getNativeSurface().isSurfaceLockedByOtherThread() && !helper.isAnimatorAnimatingOnOtherThread()) { display(); } } }
protected final GLEventListener defaultDisposeGLEventListener( GLEventListener listener, boolean remove) { final RecursiveLock _lock = getLock(); _lock.lock(); try { return helper.disposeGLEventListener( GLAutoDrawableBase.this, drawable, context, listener, remove); } finally { _lock.unlock(); } }
/** * Default implementation to handle resize events from the windowing system. All required locks * are being claimed. */ protected final void defaultWindowResizedOp(int newWidth, int newHeight) throws NativeWindowException, GLException { GLDrawableImpl _drawable = drawable; if (null != _drawable) { if (DEBUG) { final long surfaceHandle = null != getNativeSurface() ? getNativeSurface().getSurfaceHandle() : 0; System.err.println( "GLAutoDrawableBase.sizeChanged: (" + getThreadName() + "): " + newWidth + "x" + newHeight + " - surfaceHandle 0x" + Long.toHexString(surfaceHandle)); } if (!_drawable.getChosenGLCapabilities().isOnscreen()) { final RecursiveLock _lock = getLock(); _lock.lock(); try { final GLDrawableImpl _drawableNew = GLDrawableHelper.resizeOffscreenDrawable(_drawable, context, newWidth, newHeight); if (_drawable != _drawableNew) { // write back _drawable = _drawableNew; drawable = _drawableNew; } } finally { _lock.unlock(); } } sendReshape = true; // async if display() doesn't get called below, but avoiding deadlock if (_drawable.isRealized()) { if (!_drawable.getNativeSurface().isSurfaceLockedByOtherThread() && !helper.isAnimatorAnimatingOnOtherThread()) { display(); } } } }
@Override public final GLContext setContext(GLContext newCtx, boolean destroyPrevCtx) { final RecursiveLock lock = getLock(); lock.lock(); try { final GLContext oldCtx = context; GLDrawableHelper.switchContext( drawable, oldCtx, destroyPrevCtx, newCtx, additionalCtxCreationFlags); context = (GLContextImpl) newCtx; return oldCtx; } finally { lock.unlock(); } }
protected final void defaultDisplay() { if (sendDestroy) { sendDestroy = false; destroy(); return; } final RecursiveLock _lock = getLock(); _lock.lock(); try { if (null == context) { boolean contextCreated = false; final GLDrawableImpl _drawable = drawable; if (null != _drawable && _drawable.isRealized() && 0 < _drawable.getWidth() * _drawable.getHeight()) { final GLContext[] shareWith = {null}; if (!helper.isSharedGLContextPending(shareWith)) { if (!restoreGLEventListenerState()) { context = (GLContextImpl) _drawable.createContext(shareWith[0]); context.setContextCreationFlags(additionalCtxCreationFlags); contextCreated = true; // surface is locked/unlocked implicit by context's makeCurrent/release helper.invokeGL(_drawable, context, defaultDisplayAction, defaultInitAction); } } } if (DEBUG) { System.err.println("GLAutoDrawableBase.defaultDisplay: contextCreated " + contextCreated); } } else { // surface is locked/unlocked implicit by context's makeCurrent/release helper.invokeGL(drawable, context, defaultDisplayAction, defaultInitAction); } } finally { _lock.unlock(); } }
/** * Calls {@link #destroy()} directly if the following requirements are met: * * <ul> * <li>An {@link GLAnimatorControl} is bound (see {@link #getAnimator()}) and running on another * thread. Here we pause the animation while issuing the destruction. * <li>Surface is not locked by another thread (considered anonymous). * </ul> * * <p>Otherwise destroy is being flagged to be called within the next call of display(). * * <p>This method is being used to avoid deadlock if destruction is desired by <i>other</i> * threads, e.g. the window manager. * * @see #defaultWindowDestroyNotifyOp() * @see #defaultDisplay() */ protected final void destroyAvoidAwareOfLocking() { final NativeSurface ns = getNativeSurface(); final GLAnimatorControl ctrl = helper.getAnimator(); // Is an animator thread perform rendering? if (helper.isAnimatorStartedOnOtherThread()) { // Pause animations before initiating safe destroy. final boolean isPaused = ctrl.pause(); destroy(); if (isPaused) { ctrl.resume(); } } else if (null != ns && ns.isSurfaceLockedByOtherThread()) { // Surface is locked by another thread. // Flag that destroy should be performed on the next // attempt to display. sendDestroy = true; // async, but avoiding deadlock } else { // Without an external thread animating or locking the // surface, we are safe. destroy(); } }
@Override public final GLEventListener removeGLEventListener(GLEventListener listener) { return helper.removeGLEventListener(listener); }
@Override public void setGLEventListenerInitState(GLEventListener listener, boolean initialized) { helper.setGLEventListenerInitState(listener, initialized); }
@Override public boolean getGLEventListenerInitState(GLEventListener listener) { return helper.getGLEventListenerInitState(listener); }
@Override public GLEventListener getGLEventListener(int index) throws IndexOutOfBoundsException { return helper.getGLEventListener(index); }
@Override public int getGLEventListenerCount() { return helper.getGLEventListenerCount(); }
@Override public final Thread setExclusiveContextThread(Thread t) throws GLException { return helper.setExclusiveContextThread(t, context); }
@Override public final void setAutoSwapBufferMode(boolean enable) { helper.setAutoSwapBufferMode(enable); }
@Override public final boolean invoke(boolean wait, GLRunnable glRunnable) { return helper.invoke(this, wait, glRunnable); }
public boolean getAutoSwapBufferMode() { return drawableHelper.getAutoSwapBufferMode(); }
@Override public final void run() { // Lock: Locked Surface/Window by MakeCurrent/Release helper.init(GLAutoDrawableBase.this, !sendReshape); resetFPSCounter(); }
@Override public final void setSharedContext(GLContext sharedContext) throws IllegalStateException { helper.setSharedContext(this.context, sharedContext); }
@Override public final void setAnimator(GLAnimatorControl animatorControl) throws GLException { helper.setAnimator(animatorControl); }
public void setAutoSwapBufferMode(boolean onOrOff) { drawableHelper.setAutoSwapBufferMode(onOrOff); }
@Override public final GLAnimatorControl getAnimator() { return helper.getAnimator(); }
@Override public final void addGLEventListener(int index, GLEventListener listener) throws IndexOutOfBoundsException { helper.addGLEventListener(index, listener); }
@Override public final Thread getExclusiveContextThread() { return helper.getExclusiveContextThread(); }
@Override public final void setSharedAutoDrawable(GLAutoDrawable sharedAutoDrawable) throws IllegalStateException { helper.setSharedAutoDrawable(this, sharedAutoDrawable); }
@Override public boolean invoke(final boolean wait, final List<GLRunnable> glRunnables) { return helper.invoke(this, wait, glRunnables); }
@Override public final void addGLEventListener(GLEventListener listener) { helper.addGLEventListener(listener); }
@Override public final boolean getAutoSwapBufferMode() { return helper.getAutoSwapBufferMode(); }
public void invoke(boolean wait, GLRunnable glRunnable) { drawableHelper.invoke(this, wait, glRunnable); }