diff options
author | Chien Yang <[email protected]> | 2004-08-13 03:15:32 +0000 |
---|---|---|
committer | Chien Yang <[email protected]> | 2004-08-13 03:15:32 +0000 |
commit | 3069025614f7b03f6ccd148a72dcb564ea8ebdd1 (patch) | |
tree | 8c5da4cfdde9fcab8d691225f38a2b6a3aa80992 /src | |
parent | 3f3187ab805a0173fb5a3e1e7466688d52314c64 (diff) |
Issue number: 18
Fixed Issue 18 : Moved the execution of destroyOffScreenBuffer and createOffScreenBuffer
to the renderer thread.
git-svn-id: https://svn.java.net/svn/j3d-core~svn/trunk@33 ba19aa83-45c5-6ac9-afd3-db810772062c
Diffstat (limited to 'src')
-rw-r--r-- | src/classes/share/javax/media/j3d/Canvas3D.java | 64 | ||||
-rw-r--r-- | src/classes/share/javax/media/j3d/J3dMessage.java | 1 | ||||
-rw-r--r-- | src/classes/share/javax/media/j3d/Renderer.java | 49 |
3 files changed, 83 insertions, 31 deletions
diff --git a/src/classes/share/javax/media/j3d/Canvas3D.java b/src/classes/share/javax/media/j3d/Canvas3D.java index ba6016c..2135a9c 100644 --- a/src/classes/share/javax/media/j3d/Canvas3D.java +++ b/src/classes/share/javax/media/j3d/Canvas3D.java @@ -1753,21 +1753,13 @@ public class Canvas3D extends Canvas { } // TODO: illegalSharing - + if ((offScreenCanvasSize.width != bufferRetained.width) || - (offScreenCanvasSize.height != bufferRetained.height)) { - - // NOTE: the setOffScreenBuffer method really shouldn't - // make any GLX calls (which the native create/destroy - // OffScreenBuffer methods do). It should send a message - // to the Renderer thread and have it done there, although - // that would be problematic if called from a - // Behavior. As it is, there is a small, but non-zero - // chance of a similar bug cropping up for a system with - // multiple views and multiple on-screen canvases. - + (offScreenCanvasSize.height != bufferRetained.height)) { + if (window != 0) { - destroyOffScreenBuffer(ctx, screen.display, window); + // Fix for Issue 18. + // Will do destroyOffScreenBuffer in the Renderer thread. removeCtx(true); window = 0; } @@ -1777,13 +1769,12 @@ public class Canvas3D extends Canvas { bufferRetained.height); this.setSize(offScreenCanvasSize); - // create off screen buffer - window = createOffScreenBuffer(ctx, screen.display, vid, - offScreenCanvasSize.width, offScreenCanvasSize.height); - ctx = 0; + sendCreateOffScreenBuffer(); + + ctx = 0; } if (ctx != 0) { - removeCtx(true); + removeCtx(false); } offScreenBuffer = buffer; @@ -1846,6 +1837,7 @@ public class Canvas3D extends Canvas { */ public void renderOffScreenBuffer() { + if (!offScreen) throw new IllegalStateException(J3dI18N.getString("Canvas3D1")); @@ -1917,7 +1909,9 @@ public class Canvas3D extends Canvas { offScreenRendering = true; if (view.inCanvasCallback) { + if (screen.renderer == null) { + // It is possible that screen.renderer = null when this View // is shared by another onScreen Canvas and this callback // is from that Canvas. In this case it need one more @@ -1933,6 +1927,7 @@ public class Canvas3D extends Canvas { // the renderer message queue, and call renderer doWork // to do the offscreen rendering now if (Thread.currentThread() == screen.renderer) { + J3dMessage createMessage = VirtualUniverse.mc.getMessage(); createMessage.threads = J3dThread.RENDER_THREAD; createMessage.type = J3dMessage.RENDER_OFFSCREEN; @@ -1956,6 +1951,7 @@ public class Canvas3D extends Canvas { // the renderer thread screen.renderer.doWork(0); } else { + // TODO: // Now we are in trouble, this will cause deadlock if // waitForOffScreenRendering() is invoked @@ -1970,6 +1966,7 @@ public class Canvas3D extends Canvas { } } else if (Thread.currentThread() instanceof BehaviorScheduler) { + // If called from behavior scheduler, send a message directly to // the renderer message queue. // Note that we didn't use @@ -1986,6 +1983,7 @@ public class Canvas3D extends Canvas { VirtualUniverse.mc.setWorkForRequestRenderer(); } else { + // send a message to renderBin J3dMessage createMessage = VirtualUniverse.mc.getMessage(); createMessage.threads = J3dThread.UPDATE_RENDER; @@ -2221,6 +2219,7 @@ public class Canvas3D extends Canvas { } void doSwap() { + if (firstPaintCalled && useDoubleBuffer) { try { if (validCtx && (ctx != 0) && (view != null)) { @@ -3947,16 +3946,37 @@ public class Canvas3D extends Canvas { final void endScene() { endScene(ctx); } + - void removeCtx(boolean offscreen) { + // Fix for Issue 18 + // Pass CreateOffScreenBuffer to the Renderer thread for execution. + private void sendCreateOffScreenBuffer() { + + J3dMessage createMessage = VirtualUniverse.mc.getMessage(); + createMessage.threads = J3dThread.RENDER_THREAD; + createMessage.type = J3dMessage.CREATE_OFFSCREENBUFFER; + createMessage.universe = this.view.universe; + createMessage.view = this.view; + createMessage.args[0] = this; + screen.renderer.rendererStructure.addMessage(createMessage); + VirtualUniverse.mc.setWorkForRequestRenderer(); + + } + + private void removeCtx(boolean destroyOffscreen) { if ((screen != null) && (screen.renderer != null) && (ctx != 0)) { + + // Fix for Issue 18 + // Pass destroyOffscreen boolean Renderer thread to perform destroyOffScreenBuffer. VirtualUniverse.mc.postRequest(MasterControl.FREE_CONTEXT, new Object[]{this, - new Long(screen.display), - new Integer(window), - new Long(ctx)}); + new Long(screen.display), + new Integer(window), + new Long(ctx), + new Boolean(destroyOffscreen)}); + // Fix for Issue 19 // Wait for the context to be freed unless called from // a Behavior or from a Rendering thread diff --git a/src/classes/share/javax/media/j3d/J3dMessage.java b/src/classes/share/javax/media/j3d/J3dMessage.java index 586c23a..5c6a6ef 100644 --- a/src/classes/share/javax/media/j3d/J3dMessage.java +++ b/src/classes/share/javax/media/j3d/J3dMessage.java @@ -83,6 +83,7 @@ class J3dMessage extends Object { static final int VIEWSPECIFICGROUP_CLEAR = 58; static final int ORDERED_GROUP_TABLE_CHANGED = 59; static final int BEHAVIOR_REEVALUATE = 60; + static final int CREATE_OFFSCREENBUFFER = 61; /** * This is the time snapshot at which this change occured diff --git a/src/classes/share/javax/media/j3d/Renderer.java b/src/classes/share/javax/media/j3d/Renderer.java index eabfa6e..df39882 100644 --- a/src/classes/share/javax/media/j3d/Renderer.java +++ b/src/classes/share/javax/media/j3d/Renderer.java @@ -326,7 +326,7 @@ class Renderer extends J3dThread { // from MasterControl freeContext(View v) cv = (Canvas3D) args[1]; removeCtx(cv, cv.screen.display, cv.window, cv.ctx, - true, true); + true, true, false); } else if (mtype == MasterControl.RESETCANVAS_CLEANUP) { // from MasterControl RESET_CANVAS postRequest cv = (Canvas3D) args[1]; @@ -342,10 +342,14 @@ class Renderer extends J3dThread { ((Long) obj[1]).longValue(), ((Integer) obj[2]).intValue(), ((Long) obj[3]).longValue(), - false, !c.offScreen); + false, !c.offScreen, + ((Boolean)obj[4]).booleanValue()); + } return; } else { // RENDER || REQUESTRENDER + + int renderType; nmesg = 0; int totalMessages = 0; @@ -447,6 +451,19 @@ class Renderer extends J3dThread { continue; } + + if (renderType == J3dMessage.CREATE_OFFSCREENBUFFER) { + // Fix for issue 18. + canvas.window = + canvas.createOffScreenBuffer(canvas.ctx, + canvas.screen.display, + canvas.vid, + canvas.offScreenCanvasSize.width, + canvas.offScreenCanvasSize.height); + m[nmesg++].decRefcount(); + continue; + } + if (!canvas.validCanvas && (renderType != J3dMessage.RENDER_OFFSCREEN)) { m[nmesg++].decRefcount(); @@ -600,22 +617,24 @@ class Renderer extends J3dThread { } m[nmesg++].decRefcount(); } else { // retained mode rendering + m[nmesg++].decRefcount(); ImageComponent2DRetained offBufRetained = null; - if (renderType == J3dMessage.RENDER_OFFSCREEN) { + if (renderType == J3dMessage.RENDER_OFFSCREEN) { + if (canvas.window == 0 || !canvas.active) { canvas.offScreenRendering = false; continue; } else { offBufRetained = (ImageComponent2DRetained) - canvas.offScreenBuffer.retained; - + canvas.offScreenBuffer.retained; + if (offBufRetained.isByReference()) { offBufRetained.geomLock.getLock(); offBufRetained.evaluateExtensions( - canvas.extensionsSupported); + canvas.extensionsSupported); } } } else if (!canvas.active) { @@ -632,6 +651,7 @@ class Renderer extends J3dThread { // gets yanked from us during a remove. if (canvas.useSharedCtx) { + if (sharedCtx == 0) { display = canvas.screen.display; @@ -669,8 +689,9 @@ class Renderer extends J3dThread { canvas.drawingSurfaceObject.unLock(); } } - if (canvas.ctx == 0) { + if (canvas.ctx == 0) { + display = canvas.screen.display; // Always lock for context create @@ -766,6 +787,7 @@ class Renderer extends J3dThread { } canvas.drawingSurfaceObject.unLock(); } else { + if (canvas.isRunning) { canvas.makeCtxCurrent(); } @@ -1454,10 +1476,19 @@ class Renderer extends J3dThread { // Canvas3D postRequest() offScreen rendering since the // user thread will not wait for it. Also we can just // reuse it as Canvas3D did not destroy. - void removeCtx(Canvas3D cv, long display, int window, long ctx, - boolean resetCtx, boolean freeBackground) { + private void removeCtx(Canvas3D cv, long display, int window, long ctx, + boolean resetCtx, boolean freeBackground, + boolean destroyOffScreenBuffer) { + synchronized (VirtualUniverse.mc.contextCreationLock) { + // Fix for issue 18. + // Since we are now the renderer thread, + // we can safely execute destroyOffScreenBuffer. + if(destroyOffScreenBuffer) { + cv.makeCtxCurrent(); + cv.destroyOffScreenBuffer(ctx, display, window); + } if (ctx != 0) { int idx = listOfCtxs.indexOf(new Long(ctx)); if (idx >= 0) { |