Commits

Michael Ludwig  committed 80b35cc

Improve and fix context management bugs.

  • Participants
  • Parent commits 4fdef22

Comments (0)

Files changed (4)

File ferox-renderer-jogl/src/main/java/com/ferox/renderer/impl/jogl/JoglContext.java

 
     @Override
     public void release() {
-        // JOGL did something tricky underneath us, so at least release that context, since release()
-        // is meant to guarantee no context is bound
-        GLContext actual = GLContext.getCurrent();
-        if (actual != context) {
-            if (actual != null) {
-                GLContext.getCurrent().release();
-            }
-            return;
-        }
-
         int error;
         try {
             error = context.getGL().glGetError();

File ferox-renderer-lwjgl/src/main/java/com/ferox/renderer/impl/lwjgl/LwjglStaticDisplaySurface.java

                 while (!isDestroyed()) {
                     try {
                         long blockedTime = -System.nanoTime();
-                        framework.getContextManager().invokeOnContextThread(new InputTask(), false).get();
-                        framework.getContextManager().invokeOnContextThread(new CloseRequestTask(), false)
+                        framework.getContextManager().invokeOnContextThread(new MaintenanceTask(), false)
                                  .get();
                         blockedTime += System.nanoTime();
 
             }
         }
 
-        private class InputTask implements Callable<Void> {
+        private class MaintenanceTask implements Callable<Void> {
             @Override
             public Void call() throws Exception {
+                framework.getContextManager().ensureContext(context);
                 adapter.poll();
-                return null;
-            }
-        }
 
-        private class CloseRequestTask implements Callable<Void> {
-            @Override
-            public Void call() throws Exception {
                 boolean closeAllowed;
                 synchronized (LwjglStaticDisplayDestructible.this) {
                     closeAllowed = closable;

File ferox-renderer/src/main/java/com/ferox/renderer/impl/ContextManager.java

     public OpenGLContext ensureContext() {
         Thread current = Thread.currentThread();
         if (current == thread) {
-            // Delegate to the thread implementation
-            return thread.ensureContext();
+            if (thread.currentContext != null) {
+                return thread.currentContext;
+            }
+            thread.ensureContext(sharedContext);
+            return sharedContext;
+        } else {
+            // Should never happen, these methods should be restricted to the ContextThreads
+            throw new IllegalThreadStateException("ensureContext() cannot be called on this Thread");
+        }
+    }
+
+    public void ensureContext(OpenGLContext context) {
+        Thread current = Thread.currentThread();
+        if (current == thread) {
+            // delegate to thread implementation
+            thread.ensureContext(context);
         } else {
             // Should never happen, these methods should be restricted to the ContextThreads
             throw new IllegalThreadStateException("ensureContext() cannot be called on this Thread");
             tasks = new LinkedBlockingDeque<>(10);
         }
 
-        public OpenGLContext ensureContext() {
-            if (currentContext == null) {
-                // There is no surface to piggy-back off of, so we we use the shared context
-                if (sharedContext == null) {
-                    // bad initialization code, a task got queued before the shared
-                    // context was created (should not happen)
-                    throw new IllegalStateException("Shared context has not been created yet");
-                }
+        public void ensureContext(OpenGLContext context) {
+            if (context != currentContext) {
+                // Release and unlock the current context
+                releaseContext();
 
-                sharedContext.makeCurrent();
-
-                currentContext = sharedContext;
-            } // else there's a current context from somewhere, just go with it
-
-            return currentContext;
+                // Now make new context current
+                context.makeCurrent();
+                currentContext = context;
+            }
         }
 
         public OpenGLContext setActiveSurface(AbstractSurface surface) {
                 // Now check to see if the underlying context needs to change
                 OpenGLContext newContext = surface.getContext();
                 if (newContext != null) {
-                    if (newContext != currentContext) {
-                        // New surface needs its own context, so release and unlock the current context
-                        releaseContext();
-
-                        // Now make its context current
-                        newContext.makeCurrent();
-                        currentContext = newContext;
-                    }
-                } else {
+                    ensureContext(newContext);
+                } else if (currentContext == null) {
                     // Make sure we have a context for this surface, since it doesn't have its own
-                    ensureContext();
+                    ensureContext(sharedContext);
                 }
 
                 activeSurface = surface;

File ferox-renderer/src/main/java/com/ferox/renderer/impl/FrameworkImpl.java

                 fullscreenSurface = null;
             }
 
+            impl.contextManager.forceRelease();
             AbstractOnscreenSurface created = impl.surfaceFactory
                                                   .createOnscreenSurface(FrameworkImpl.this, options,
                                                                          impl.contextManager
                                                                              .getSharedContext());
             impl.destructibleManager.manage(created, created.getSurfaceDestructible());
-            impl.contextManager.setActiveSurface(created);
 
             if (created.isFullscreen()) {
                 fullscreenSurface = new WeakReference<OnscreenSurface>(created);
 
         @Override
         public TextureSurface call() throws Exception {
+            impl.contextManager.forceRelease();
             AbstractTextureSurface created = impl.surfaceFactory
                                                  .createTextureSurface(FrameworkImpl.this, options,
                                                                        impl.contextManager
                                                                            .getSharedContext());
             impl.destructibleManager.manage(created, created.getSurfaceDestructible());
-            impl.contextManager.setActiveSurface(created);
             return created;
         }
     }