diff options
author | Kevin Rushforth <[email protected]> | 2007-04-10 15:51:49 +0000 |
---|---|---|
committer | Kevin Rushforth <[email protected]> | 2007-04-10 15:51:49 +0000 |
commit | ca26623d800685a36d7ef5bb34772f9d5af6e5cb (patch) | |
tree | e84de09f26efbcf0ab1b25179005b9a3a22844e0 | |
parent | a385d633137c6f000d5cd4ef0e47576ed13dc6c9 (diff) |
Fixed the following issues:
348: Programmable shaders do not work for OffScreen Canvas3D
378: Shaders are not rendered when Canvas3D is created and destroyed
git-svn-id: https://svn.java.net/svn/j3d-core~svn/trunk@812 ba19aa83-45c5-6ac9-afd3-db810772062c
5 files changed, 154 insertions, 59 deletions
diff --git a/src/classes/share/javax/media/j3d/Canvas3D.java b/src/classes/share/javax/media/j3d/Canvas3D.java index 607c010..391fb00 100644 --- a/src/classes/share/javax/media/j3d/Canvas3D.java +++ b/src/classes/share/javax/media/j3d/Canvas3D.java @@ -1532,7 +1532,7 @@ public class Canvas3D extends Canvas { void setFrustumPlanes(Vector4d[] planes) { if(VirtualUniverse.mc.viewFrustumCulling) { - /* System.out.println("Canvas3D.setFrustumPlanes()"); */ + /* System.err.println("Canvas3D.setFrustumPlanes()"); */ viewFrustum.set(planes); } } @@ -1862,9 +1862,11 @@ public class Canvas3D extends Canvas { canvasId = VirtualUniverse.mc.getCanvasId(); canvasIdAlloc = true; - // NOTE: We are backing out the following part of the following fix for issues - // 347 and 348 due to a regression in texture mapping, and due - // to the fact that it is an incomplete fix. + // 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; } } @@ -4768,7 +4770,7 @@ public class Canvas3D extends Canvas { continue; } if (val >= textureIDResourceTable.size()) { - System.out.println("Error in freeResourcesInFreeList : ResourceIDTableSize = " + + System.err.println("Error in freeResourcesInFreeList : ResourceIDTableSize = " + textureIDResourceTable.size() + " val = " + val); } else { diff --git a/src/classes/share/javax/media/j3d/MasterControl.java b/src/classes/share/javax/media/j3d/MasterControl.java index 25d5339..8b830ab 100644 --- a/src/classes/share/javax/media/j3d/MasterControl.java +++ b/src/classes/share/javax/media/j3d/MasterControl.java @@ -968,8 +968,8 @@ class MasterControl { break; } - if ( canvasFreeIndex >= canvasIds.length) { - throw new RuntimeException("Cannot render to more than 32 Canvas3Ds"); + if (i >= canvasIds.length) { + throw new RuntimeException("Cannot render to more than 32 Canvas3Ds"); } canvasIds[i] = true; diff --git a/src/classes/share/javax/media/j3d/ShaderProgramRetained.java b/src/classes/share/javax/media/j3d/ShaderProgramRetained.java index 3d3caf6..453cfca 100644 --- a/src/classes/share/javax/media/j3d/ShaderProgramRetained.java +++ b/src/classes/share/javax/media/j3d/ShaderProgramRetained.java @@ -54,6 +54,10 @@ abstract class ShaderProgramRetained extends NodeComponentRetained { // need to synchronize access from multiple rendering threads Object resourceLock = new Object(); + + // Package-scope default constructor + ShaderProgramRetained() { + } /** * Sets the vertex attribute names array for this ShaderProgram @@ -378,7 +382,7 @@ abstract class ShaderProgramRetained extends NodeComponentRetained { void setLive(boolean backgroundGroup, int refCount) { - // System.out.println("ShaderProgramRetained.setLive()"); + // System.err.println("ShaderProgramRetained.setLive()"); if (shaders != null) { for (int i = 0; i < shaders.length; i++){ @@ -393,7 +397,7 @@ abstract class ShaderProgramRetained extends NodeComponentRetained { void clearLive(int refCount) { - // System.out.println("ShaderProgramRetained.clearLive()"); + // System.err.println("ShaderProgramRetained.clearLive()"); super.clearLive(refCount); @@ -469,14 +473,17 @@ abstract class ShaderProgramRetained extends NodeComponentRetained { // ShaderProgram can't be modified once it is live. assert(false); - System.out.println("ShaderProgramRetained : updateMirrorObject NOT IMPLEMENTED YET"); + System.err.println("ShaderProgramRetained : updateMirrorObject NOT IMPLEMENTED YET"); } /** * Method to create a ShaderProgramData object for the specified - * canvas/renderer if it doesn't already exist + * canvas/renderer if it doesn't already exist. + * + * Issue 378 : reset the ShaderProgramData object if the context + * has been recreated for the particular canvas / renderer. */ - private void createShaderProgramData(int cvRdrIndex) { + private void createShaderProgramData(int cvRdrIndex, long ctxTimeStamp) { // Create shaderProgram resources if it has not been done. synchronized(resourceLock) { if(shaderProgramData == null) { @@ -494,7 +501,12 @@ abstract class ShaderProgramRetained extends NodeComponentRetained { if(shaderProgramData[cvRdrIndex] == null) { shaderProgramData[cvRdrIndex] = new ShaderProgramData(); + } else if (shaderProgramData[cvRdrIndex].getCtxTimeStamp() != ctxTimeStamp) { + // Issue 378 - reset the shader program data for this canvas / renderer + // if the context has been recreated + shaderProgramData[cvRdrIndex].reset(); } + shaderProgramData[cvRdrIndex].setCtxTimeStamp(ctxTimeStamp); } } @@ -527,7 +539,7 @@ abstract class ShaderProgramRetained extends NodeComponentRetained { ShaderId[] shaderIds = new ShaderId[shaders.length]; for(int i=0; i<shaders.length; i++) { synchronized(shaders[i]) { - shaderIds[i] = shaders[i].shaderIds[cvRdrIndex]; + shaderIds[i] = shaders[i].shaderData[cvRdrIndex].getShaderId(); } } ShaderError err = @@ -611,43 +623,24 @@ abstract class ShaderProgramRetained extends NodeComponentRetained { } /** - * Method to create the native shader. + * Method to create the native shader. We must already have + * called createShaderData for this cvRdrIndex. */ private ShaderError createShader(Canvas3D cv, int cvRdrIndex, ShaderRetained shader) { // Create shaderProgram resources if it has not been done. synchronized(shader.resourceLock) { - if(shader.shaderIds == null){ - // We rely on Java to initial the array elements to 0 or false; - shader.shaderIds = new ShaderId[cvRdrIndex+1]; - shader.compiled = new boolean[cvRdrIndex+1]; - } else if( shader.shaderIds.length <= cvRdrIndex) { - // We rely on Java to initial the array elements to 0 or false; - ShaderId[] tempSIds = new ShaderId[cvRdrIndex+1]; - boolean[] tempCompiled = new boolean[cvRdrIndex+1]; - - System.arraycopy(shader.shaderIds, 0, - tempSIds, 0, - shader.shaderIds.length); - shader.shaderIds = tempSIds; - - System.arraycopy(shader.compiled, 0, - tempCompiled, 0, - shader.compiled.length); - shader.compiled = tempCompiled; - } - - if(shader.shaderIds[cvRdrIndex] != null) { + if (shader.shaderData[cvRdrIndex].getShaderId() != null) { // We have already created the shaderId for this Canvas. return null; } - + ShaderId[] shaderIdArr = new ShaderId[1]; ShaderError err = createShader(cv.ctx, shader, shaderIdArr); if(err != null) { return err; } - shader.shaderIds[cvRdrIndex] = shaderIdArr[0]; + shader.shaderData[cvRdrIndex].setShaderId(shaderIdArr[0]); } return null; } @@ -659,17 +652,17 @@ abstract class ShaderProgramRetained extends NodeComponentRetained { synchronized(shader.resourceLock) { - if(shader.compiled[cvRdrIndex] == true) { + if (shader.shaderData[cvRdrIndex].isCompiled()) { // We have already compiled the shaderId for this Canvas. return null; } String source = ((SourceCodeShaderRetained)shader).getShaderSource(); - ShaderError err = compileShader(cv.ctx, shader.shaderIds[cvRdrIndex], source); + ShaderError err = compileShader(cv.ctx, shader.shaderData[cvRdrIndex].getShaderId(), source); if(err != null) { return err; } - shader.compiled[cvRdrIndex] = true; + shader.shaderData[cvRdrIndex].setCompiled(true); } return null; @@ -717,20 +710,22 @@ abstract class ShaderProgramRetained extends NodeComponentRetained { // Destroy shader resource if it exists synchronized(shader.resourceLock) { - // Check whether an entry in the shaderIds array has been allocated - if (shader.shaderIds == null || shader.shaderIds.length <= cvRdrIndex) { + // Check whether an entry in the shaderData array has been allocated + if (shader.shaderData == null || + shader.shaderData.length <= cvRdrIndex || + shader.shaderData[cvRdrIndex] == null) { return; } // Nothing to do if the shaderId is null - if (shader.shaderIds[cvRdrIndex] == null) { + if (shader.shaderData[cvRdrIndex].getShaderId() == null) { return; } // Destroy the native resource and set the ID to null for this canvas/renderer // Ignore any possible shader error, because there is no meaningful way to report it - destroyShader(cv.ctx, shader.shaderIds[cvRdrIndex]); - shader.shaderIds[cvRdrIndex] = null; + destroyShader(cv.ctx, shader.shaderData[cvRdrIndex].getShaderId()); + shader.shaderData[cvRdrIndex].reset(); } } @@ -777,13 +772,22 @@ abstract class ShaderProgramRetained extends NodeComponentRetained { * update the shader program state */ void updateNative(Canvas3D cv, boolean enable) { - // System.out.println("ShaderProgramRetained.updateNative : "); + // System.err.println("ShaderProgramRetained.updateNative : "); final boolean useSharedCtx = cv.useSharedCtx && cv.screen.renderer.sharedCtx != null; - final int cvRdrIndex = useSharedCtx ? cv.screen.renderer.rendererId : cv.canvasId; + int cvRdrIndex; + long ctxTimeStamp; + + if (useSharedCtx) { + cvRdrIndex = cv.screen.renderer.rendererId; + ctxTimeStamp = cv.screen.renderer.sharedCtxTimeStamp; + } else { + cvRdrIndex = cv.canvasId; + ctxTimeStamp = cv.ctxTimeStamp; + } // Create ShaderProgramData object for this canvas/renderer if it doesn't already exist - createShaderProgramData(cvRdrIndex); + createShaderProgramData(cvRdrIndex, ctxTimeStamp); // Check whether this shader program type is supported for this canvas if (!verifyShaderProgramSupported(cv)) { @@ -810,8 +814,8 @@ abstract class ShaderProgramRetained extends NodeComponentRetained { loadShaderProgram = true; } - //System.out.println(".... loadShaderProgram = " + loadShaderProgram); - //System.out.println(".... resourceCreationMask= " + resourceCreationMask); + //System.err.println(".... loadShaderProgram = " + loadShaderProgram); + //System.err.println(".... resourceCreationMask= " + resourceCreationMask); ShaderError err = null; boolean errorOccurred = false; @@ -823,6 +827,9 @@ abstract class ShaderProgramRetained extends NodeComponentRetained { // Create shader resources if not already done for(int i=0; i < shaders.length; i++) { + // Create ShaderProgramData object for this canvas/renderer if it doesn't already exist + shaders[i].createShaderData(cvRdrIndex, ctxTimeStamp); + if (shaders[i].compileErrorOccurred) { errorOccurred = true; } @@ -1109,7 +1116,10 @@ abstract class ShaderProgramRetained extends NodeComponentRetained { } class ShaderProgramData extends Object { - + + // issue 378 - time stamp of context creation for this Canvas + private long ctxTimeStamp; + // shaderProgramId use by native code. private ShaderProgramId shaderProgramId = null; @@ -1124,11 +1134,20 @@ abstract class ShaderProgramRetained extends NodeComponentRetained { } void reset() { + ctxTimeStamp = 0L; shaderProgramId = null; linked = false; attrNameInfoMap.clear(); } + long getCtxTimeStamp() { + return ctxTimeStamp; + } + + void setCtxTimeStamp(long ctxTimeStamp) { + this.ctxTimeStamp = ctxTimeStamp; + } + void setShaderProgramId(ShaderProgramId shaderProgramId) { this.shaderProgramId = shaderProgramId; } @@ -1154,7 +1173,6 @@ abstract class ShaderProgramRetained extends NodeComponentRetained { return (AttrNameInfo) attrNameInfoMap.get(shaderAttribute); } - } // Data associated with an attribute name diff --git a/src/classes/share/javax/media/j3d/ShaderRetained.java b/src/classes/share/javax/media/j3d/ShaderRetained.java index 37dc71f..f3622ca 100644 --- a/src/classes/share/javax/media/j3d/ShaderRetained.java +++ b/src/classes/share/javax/media/j3d/ShaderRetained.java @@ -25,9 +25,10 @@ abstract class ShaderRetained extends NodeComponentRetained { int shadingLanguage; int shaderType; + // Each element in the array corresponds to a unique renderer if shared + // context or a unique canvas otherwise. // shaderId use by native code. One per Canvas. - ShaderId[] shaderIds; - boolean[] compiled; + ShaderData[] shaderData; // Flag indicating whether a COMPILE_ERROR has occurred for this shader // object. It is set in updateNative to indicate that the compileShader @@ -52,12 +53,12 @@ abstract class ShaderRetained extends NodeComponentRetained { } void setLive(boolean inBackgroundGroup, int refCount) { - // System.out.println("SourceCodeShaderRetained.setLive()"); + // System.err.println("SourceCodeShaderRetained.setLive()"); super.setLive(inBackgroundGroup, refCount); } void clearLive(int refCount) { - // System.out.println("SourceCodeShaderRetained.clearLive()"); + // System.err.println("SourceCodeShaderRetained.clearLive()"); super.clearLive(refCount); } @@ -67,11 +68,85 @@ abstract class ShaderRetained extends NodeComponentRetained { * the changes to the users */ synchronized void updateMirrorObject(int component, Object value) { - System.out.println("Shader.updateMirrorObject not implemented yet!"); + System.err.println("Shader.updateMirrorObject not implemented yet!"); } void handleFrequencyChange(int bit) { - System.out.println("Shader.handleFrequencyChange not implemented yet!"); + System.err.println("Shader.handleFrequencyChange not implemented yet!"); + } + + void createShaderData(int cvRdrIndex, long ctxTimeStamp) { + // Create shaderProgram resources if it has not been done. + synchronized(resourceLock) { + if (shaderData == null) { + shaderData = new ShaderData[cvRdrIndex+1]; + } else if (shaderData.length <= cvRdrIndex) { + ShaderData[] tempSData = new ShaderData[cvRdrIndex+1]; + + System.arraycopy(shaderData, 0, + tempSData, 0, + shaderData.length); + shaderData = tempSData; + } + + if (shaderData[cvRdrIndex] == null) { + shaderData[cvRdrIndex] = new ShaderData(); + } else if (shaderData[cvRdrIndex].getCtxTimeStamp() != ctxTimeStamp) { + // Issue 378 - reset the shader data for this canvas / renderer + // if the context has been recreated + shaderData[cvRdrIndex].reset(); + } + shaderData[cvRdrIndex].setCtxTimeStamp(ctxTimeStamp); + } + } + + + // Per-context (canvas) data for this shader + class ShaderData extends Object { + + // Issue 378 - time stamp of context creation for this canvas + private long ctxTimeStamp; + + // shaderId use by native code + private ShaderId shaderId = null; + + // indicated that the shader has been compiled for this canvas + private boolean compiled = false; + + /** ShaderProgramData Constructor */ + ShaderData() { + } + + void reset() { + ctxTimeStamp = 0L; + shaderId = null; + compiled = false; + } + + long getCtxTimeStamp() { + return ctxTimeStamp; + } + + void setCtxTimeStamp(long ctxTimeStamp) { + this.ctxTimeStamp = ctxTimeStamp; + } + + ShaderId getShaderId() { + return shaderId; + } + + void setShaderId(ShaderId shaderId) { + this.shaderId = shaderId; + } + + boolean isCompiled() { + return compiled; + } + + void setCompiled(boolean compiled) { + this.compiled = compiled; + } + } } diff --git a/src/classes/share/javax/media/j3d/SourceCodeShaderRetained.java b/src/classes/share/javax/media/j3d/SourceCodeShaderRetained.java index 4624119..a7ae0d4 100644 --- a/src/classes/share/javax/media/j3d/SourceCodeShaderRetained.java +++ b/src/classes/share/javax/media/j3d/SourceCodeShaderRetained.java @@ -75,7 +75,7 @@ class SourceCodeShaderRetained extends ShaderRetained { mirror.source = source; ((SourceCodeShaderRetained) mirror).set(shadingLanguage, shaderType, shaderSource); - ((SourceCodeShaderRetained) mirror).shaderIds = null; + ((SourceCodeShaderRetained) mirror).shaderData = null; } synchronized void updateMirrorObject(int component, Object value) { |