diff options
author | Kevin Rushforth <[email protected]> | 2007-04-11 02:32:57 +0000 |
---|---|---|
committer | Kevin Rushforth <[email protected]> | 2007-04-11 02:32:57 +0000 |
commit | bb50b4103b87cf155d8243561db499d8e037fa68 (patch) | |
tree | 72a934651fa6b826ac7ac6fdaf1c017aba463d90 /src | |
parent | 430dea1b8b5b45f14dd986e60a6aee606efb237c (diff) |
Fixed issue 347: OffScreen Canvas3D always reloads textures, display lists
git-svn-id: https://svn.java.net/svn/j3d-core~svn/trunk@814 ba19aa83-45c5-6ac9-afd3-db810772062c
Diffstat (limited to 'src')
5 files changed, 147 insertions, 67 deletions
diff --git a/src/classes/share/javax/media/j3d/Canvas3D.java b/src/classes/share/javax/media/j3d/Canvas3D.java index 391fb00..4b10aab 100644 --- a/src/classes/share/javax/media/j3d/Canvas3D.java +++ b/src/classes/share/javax/media/j3d/Canvas3D.java @@ -1094,18 +1094,22 @@ public class Canvas3D extends Canvas { // QUESTION: keep a list of off-screen Screen3D objects? // Does this list need to be grouped by GraphicsDevice? - // since this canvas will not receive the addNotify - // callback from AWT, set the added flag here - added = true; synchronized(dirtyMaskLock) { cvDirtyMask[0] |= MOVED_OR_RESIZED_DIRTY; cvDirtyMask[1] |= MOVED_OR_RESIZED_DIRTY; } - // this canvas will not receive the paint callback either, - // so set the necessary flags here as well + // this canvas will not receive the paint callback, + // so we need to set the necessary flags here firstPaintCalled = true; - ctx = null; + + if (manualRendering) { + // since this canvas will not receive the addNotify + // callback from AWT, set the added flag here for + // evaluateActive to work correctly + added = true; + } + evaluateActive(); // create the rendererStructure object @@ -1336,29 +1340,28 @@ public class Canvas3D extends Canvas { cvDirtyMask[0] |= MOVED_OR_RESIZED_DIRTY; cvDirtyMask[1] |= MOVED_OR_RESIZED_DIRTY; } - - canvasId = VirtualUniverse.mc.getCanvasId(); - canvasIdAlloc = true; - canvasBit = 1 << canvasId; - + + allocateCanvasId(); + validCanvas = true; added = true; // Since we won't get a paint call for off-screen canvases, we need - // to set the first paint and visible flags here + // to set the first paint and visible flags here. We also need to + // call evaluateActive for the same reason. if (offScreen) { firstPaintCalled = true; visible = true; + evaluateActive(); } // In case the same canvas is removed and add back, // we have to change isRunningStatus back to true; if (isRunning && !fatalError) { - isRunningStatus = true; - } - + isRunningStatus = true; + } - ctxTimeStamp = 0; + ctxTimeStamp = 0; if ((view != null) && (view.universe != null)) { view.universe.checkForEnableEvents(); } @@ -1435,10 +1438,7 @@ public class Canvas3D extends Canvas { screen.removeUser(this); evaluateActive(); - VirtualUniverse.mc.freeCanvasId(canvasId); - canvasIdAlloc = false; - canvasBit = 0; - canvasId = 0; + freeCanvasId(); ra = null; graphicsContext3D = null; @@ -1488,6 +1488,23 @@ public class Canvas3D extends Canvas { this.windowParent = null; } + void allocateCanvasId() { + if (!canvasIdAlloc) { + canvasId = VirtualUniverse.mc.getCanvasId(); + canvasBit = 1 << canvasId; + canvasIdAlloc = true; + } + } + + void freeCanvasId() { + if (canvasIdAlloc) { + VirtualUniverse.mc.freeCanvasId(canvasId); + canvasBit = 0; + canvasId = 0; + canvasIdAlloc = false; + } + } + // This decides if the canvas is active void evaluateActive() { // Note that no need to check for isRunning, we want @@ -1809,6 +1826,7 @@ public class Canvas3D extends Canvas { */ public void setOffScreenBuffer(ImageComponent2D buffer) { int width, height; + boolean freeCanvasId = false; if (!offScreen) throw new IllegalStateException(J3dI18N.getString("Canvas3D1")); @@ -1858,17 +1876,7 @@ public class Canvas3D extends Canvas { // Issues 347, 348 - assign a canvasId for off-screen Canvas3D if (manualRendering) { - if (!canvasIdAlloc) { - canvasId = VirtualUniverse.mc.getCanvasId(); - canvasIdAlloc = true; - - // NOTE: We are backing out the following part of the - // following fix for issue 347 due to a regression in - // off-screen texture mapping, caused by a race condition. - // This does not affect issue 348 since the shader code - // uses the canvasId and not the canvasBit. -// canvasBit = 1 << canvasId; - } + sendAllocateCanvasId(); } } else { @@ -1876,12 +1884,7 @@ public class Canvas3D extends Canvas { // Issues 347, 348 - release canvasId for off-screen Canvas3D if (manualRendering) { - if (canvasIdAlloc) { - VirtualUniverse.mc.freeCanvasId(canvasId); - canvasIdAlloc = false; - canvasBit = 0; - canvasId = 0; - } + freeCanvasId = true; } } @@ -1908,6 +1911,10 @@ public class Canvas3D extends Canvas { removeCtx(); } + if (freeCanvasId) { + sendFreeCanvasId(); + } + offScreenBuffer = buffer; synchronized(dirtyMaskLock) { @@ -2139,13 +2146,18 @@ public class Canvas3D extends Canvas { * @since Java 3D 1.2 */ public void waitForOffScreenRendering() { - // TODO KCR : throw exception if !offScreen - // TODO KCR Issue 131: throw exception if !manualRendering + if (!offScreen) { + throw new IllegalStateException(J3dI18N.getString("Canvas3D1")); + } + + if (Thread.currentThread() instanceof Renderer) { + throw new IllegalStateException(J3dI18N.getString("Canvas3D31")); + } while (offScreenRendering) { - MasterControl.threadYield(); - } + MasterControl.threadYield(); + } } @@ -4330,6 +4342,20 @@ public class Canvas3D extends Canvas { } } + // Send a allocateCanvasId message to Renderer (via MasterControl) without + // waiting for it to be done + private void sendAllocateCanvasId() { + // Send message to Renderer thread to allocate a canvasId + VirtualUniverse.mc.sendAllocateCanvasId(this); + } + + // Send a freeCanvasId message to Renderer (via MasterControl) without + // waiting for it to be done + private void sendFreeCanvasId() { + // Send message to Renderer thread to free the canvasId + VirtualUniverse.mc.sendFreeCanvasId(this); + } + private void removeCtx() { if ((screen != null) && diff --git a/src/classes/share/javax/media/j3d/ExceptionStrings.properties b/src/classes/share/javax/media/j3d/ExceptionStrings.properties index 40e0553..05ee875 100644 --- a/src/classes/share/javax/media/j3d/ExceptionStrings.properties +++ b/src/classes/share/javax/media/j3d/ExceptionStrings.properties @@ -145,6 +145,7 @@ Canvas3D27=Canvas3D: ImageComponent2D is already being used by an immediate mode Canvas3D28=Canvas3D: ImageComponent2D is already being used by by another Canvas3D as an off-screen buffer. Canvas3D29=Canvas3D: Non-recoverable graphics configuration error Canvas3D30=Canvas3D: Non-recoverable off-screen rendering error +Canvas3D31=Canvas3D: Can't wait for off-screen rendering in a canvas callback BoundingPolytope0=BoundingPolytope( Bounds) unrecognized bounds object BoundingPolytope1=BoundingPolytope( Bounds) unrecognized bounds type BoundingPolytope2=set( Bounds) unrecognized bounds type diff --git a/src/classes/share/javax/media/j3d/J3dMessage.java b/src/classes/share/javax/media/j3d/J3dMessage.java index aef730a..aa1da68 100644 --- a/src/classes/share/javax/media/j3d/J3dMessage.java +++ b/src/classes/share/javax/media/j3d/J3dMessage.java @@ -87,7 +87,9 @@ class J3dMessage extends Object { static final int DESTROY_CTX_AND_OFFSCREENBUFFER = 62; static final int SHADER_ATTRIBUTE_CHANGED = 63; static final int SHADER_ATTRIBUTE_SET_CHANGED = 64; - static final int SHADER_APPEARANCE_CHANGED = 65; + static final int SHADER_APPEARANCE_CHANGED = 65; + static final int ALLOCATE_CANVASID = 66; + static final int FREE_CANVASID = 67; /** * This is the time snapshot at which this change occured diff --git a/src/classes/share/javax/media/j3d/MasterControl.java b/src/classes/share/javax/media/j3d/MasterControl.java index 56a7c86..f2ad82c 100644 --- a/src/classes/share/javax/media/j3d/MasterControl.java +++ b/src/classes/share/javax/media/j3d/MasterControl.java @@ -69,12 +69,13 @@ class MasterControl { static final Integer SET_GRAPHICSCONFIG_FEATURES = new Integer(19); static final Integer SET_QUERYPROPERTIES = new Integer(20); static final Integer SET_VIEW = new Integer(21); - - private static Logger devLogger=null; + + // Developer logger to report informational messages; see getDevLogger() + private static Logger devLogger = null; - // Should we log developer issues ? + // Flag indicating whether devLogger is enabled static boolean logDevIssues = false; - + private static boolean librariesLoaded = false; /** @@ -676,7 +677,7 @@ class MasterControl { }; for (int i = 0; i < obsoleteProps.length; i++) { if (getProperty(obsoleteProps[i]) != null) { - System.err.println(obsoleteProps[i] + " : property ignored"); + System.err.println("Java 3D: " + obsoleteProps[i] + " property ignored"); } } @@ -694,29 +695,31 @@ class MasterControl { for(int i=0; i<canvasIds.length; i++) { canvasIds[i] = false; } - canvasFreeIndex = 0; - + canvasFreeIndex = 0; + if (devLogger==null) { devLogger = Logger.getLogger("j3d.developer"); final Logger fLogger = devLogger; java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - String levelStr = System.getProperty("j3d.developer.level"); - if (levelStr!=null) { - try { - fLogger.setLevel( Level.parse(levelStr) ); - System.err.println("Java 3D: Developer Logger level = "+fLogger.getLevel().getName()); - } catch (IllegalArgumentException ex) { - System.err.println("Java 3D: Developer Logger level unrecognized : "+levelStr); - } catch (Exception ex) { - System.err.println(ex); + new java.security.PrivilegedAction() { + public Object run() { + String levelStr = System.getProperty("j3d.developer.level"); + if (levelStr != null) { + try { + fLogger.setLevel( Level.parse(levelStr) ); + System.err.println("Java 3D: Developer logger level = " + + fLogger.getLevel().getName()); + } catch (IllegalArgumentException ex) { + System.err.println("Java 3D: Unrecognized developer logger level : " + levelStr); + } catch (Exception ex) { + System.err.println(ex); + System.err.println("Java 3D: Error setting developer logger level : "+ levelStr); + } } - } - return null; - } - }); - logDevIssues = ((devLogger.getLevel()!=null) && devLogger.getLevel()!=Level.OFF); + return null; + } + }); + logDevIssues = ((devLogger.getLevel()!=null) && (devLogger.getLevel()!=Level.OFF)); } } @@ -2911,6 +2914,50 @@ class MasterControl { } } + // Issue 347 - Pass AllocateCanvasId to the Renderer thread for execution + void sendAllocateCanvasId(Canvas3D c) { + synchronized (mcThreadLock) { + // Issue 364: create master control thread if needed + createMasterControlThread(); + assert mcThread != null; + + Renderer rdr = createRenderer(c.graphicsConfiguration); + J3dMessage createMessage = new J3dMessage(); + createMessage.threads = J3dThread.RENDER_THREAD; + createMessage.type = J3dMessage.ALLOCATE_CANVASID; + createMessage.universe = null; + createMessage.view = null; + createMessage.args[0] = c; + rdr.rendererStructure.addMessage(createMessage); + synchronized (requestObjList) { + setWorkForRequestRenderer(); + pendingRequest = true; + } + } + } + + // Issue 347 - Pass AllocateCanvasId to the Renderer thread for execution + void sendFreeCanvasId(Canvas3D c) { + synchronized (mcThreadLock) { + // Issue 364: create master control thread if needed + createMasterControlThread(); + assert mcThread != null; + + Renderer rdr = createRenderer(c.graphicsConfiguration); + J3dMessage createMessage = new J3dMessage(); + createMessage.threads = J3dThread.RENDER_THREAD; + createMessage.type = J3dMessage.FREE_CANVASID; + createMessage.universe = null; + createMessage.view = null; + createMessage.args[0] = c; + rdr.rendererStructure.addMessage(createMessage); + synchronized (requestObjList) { + setWorkForRequestRenderer(); + pendingRequest = true; + } + } + } + /** * This is the MasterControl work method for Java 3D diff --git a/src/classes/share/javax/media/j3d/Renderer.java b/src/classes/share/javax/media/j3d/Renderer.java index f1c283d..7bb2a84 100644 --- a/src/classes/share/javax/media/j3d/Renderer.java +++ b/src/classes/share/javax/media/j3d/Renderer.java @@ -587,7 +587,11 @@ class Renderer extends J3dThread { canvas.offScreenBufferPending = false; m[nmesg++].decRefcount(); continue; - } + } else if (renderType == J3dMessage.ALLOCATE_CANVASID) { + canvas.allocateCanvasId(); + } else if (renderType == J3dMessage.FREE_CANVASID) { + canvas.freeCanvasId(); + } if ((canvas.view == null) || !canvas.firstPaintCalled) { // This happen when the canvas just remove from the View @@ -769,7 +773,7 @@ class Renderer extends J3dThread { // // Instrumentation of Java 3D renderer // long startRenderTime = System.nanoTime(); - m[nmesg++].decRefcount(); + m[nmesg++].decRefcount(); if (canvas.isFatalError()) { continue; |