From 9f29bb02627691061dd5eccacfcbc4895cef7b61 Mon Sep 17 00:00:00 2001 From: Kevin Rushforth Date: Wed, 10 Jan 2007 04:03:16 +0000 Subject: 1. Fixed issue 357: Memory leak when using textures with multiple views 2. Fixed a related off-by-one error (thanks, mcneilk) which turned out to be harmless in this case, but fixing it may prevent future bugs git-svn-id: https://svn.java.net/svn/j3d-core~svn/trunk@767 ba19aa83-45c5-6ac9-afd3-db810772062c --- src/classes/share/javax/media/j3d/Canvas3D.java | 4 +-- src/classes/share/javax/media/j3d/Renderer.java | 2 +- src/classes/share/javax/media/j3d/TextureBin.java | 5 ++-- .../share/javax/media/j3d/TextureRetained.java | 29 +++++++++++++++++++--- 4 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/classes/share/javax/media/j3d/Canvas3D.java b/src/classes/share/javax/media/j3d/Canvas3D.java index 653747d..060a3bc 100644 --- a/src/classes/share/javax/media/j3d/Canvas3D.java +++ b/src/classes/share/javax/media/j3d/Canvas3D.java @@ -3845,7 +3845,7 @@ public class Canvas3D extends Canvas { graphics2D.objectId = -1; } - for (int id = textureIDResourceTable.size()-1; id > 0; id--) { + for (int id = textureIDResourceTable.size()-1; id >= 0; id--) { obj = textureIDResourceTable.get(id); if (obj != null) { if (obj instanceof TextureRetained) { @@ -4771,7 +4771,7 @@ public class Canvas3D extends Canvas { } } - for (int id = textureIDResourceTable.size()-1; id > 0; id--) { + for (int id = textureIDResourceTable.size()-1; id >= 0; id--) { obj = textureIDResourceTable.get(id); if (obj == null) { continue; diff --git a/src/classes/share/javax/media/j3d/Renderer.java b/src/classes/share/javax/media/j3d/Renderer.java index 3c73a7e..6564071 100644 --- a/src/classes/share/javax/media/j3d/Renderer.java +++ b/src/classes/share/javax/media/j3d/Renderer.java @@ -1753,7 +1753,7 @@ class Renderer extends J3dThread { Object obj; TextureRetained tex; - for (int id = textureIDResourceTable.size()-1; id > 0; id--) { + for (int id = textureIDResourceTable.size()-1; id >= 0; id--) { obj = textureIDResourceTable.get(id); if (obj == null) { continue; diff --git a/src/classes/share/javax/media/j3d/TextureBin.java b/src/classes/share/javax/media/j3d/TextureBin.java index 75c5229..d5c5e78 100644 --- a/src/classes/share/javax/media/j3d/TextureBin.java +++ b/src/classes/share/javax/media/j3d/TextureBin.java @@ -193,7 +193,6 @@ class TextureBin extends Object implements ObjectUpdate { TextureRetained prevFirstTexture = null; TextureRetained tex; - tbFlag |= TextureBin.CONTIGUOUS_ACTIVE_UNITS; if (state != null) { @@ -241,7 +240,7 @@ class TextureBin extends Object implements ObjectUpdate { if (tex != null) { tex.decTextureBinRefCount(this); if (soleUser && - (tex.textureBinRefCount == 0) && + (tex.getTextureBinRefCount(this) == 0) && (tex != state[i].texture)) { // In this case texture change but // TextureBin will not invoke clear() to reset. @@ -404,7 +403,7 @@ class TextureBin extends Object implements ObjectUpdate { tex = texUnitState[i].texture; tex.decTextureBinRefCount(this); - if (tex.textureBinRefCount == 0) { + if (tex.getTextureBinRefCount(this) == 0) { renderBin.addTextureResourceFreeList(tex); } diff --git a/src/classes/share/javax/media/j3d/TextureRetained.java b/src/classes/share/javax/media/j3d/TextureRetained.java index 4a70508..811141d 100644 --- a/src/classes/share/javax/media/j3d/TextureRetained.java +++ b/src/classes/share/javax/media/j3d/TextureRetained.java @@ -152,9 +152,12 @@ abstract class TextureRetained extends NodeComponentRetained { int imageUpdatePruneMask[]; - + // Issue 357 - we need a separate reference counter per RenderBin, since + // each RenderBin keeps an independent list of Texture objects to be freed. + // Since this is accessed infrequently, we will use a HashMap for the // textureBin reference counter - int textureBinRefCount = 0; + private HashMap textureBinRefCount = + new HashMap(); // This is used for D3D only to check whether texture need to // resend down @@ -2360,7 +2363,7 @@ abstract class TextureRetained extends NodeComponentRetained { ImageComponentRetained image; - textureBinRefCount++; + setTextureBinRefCount(tb, getTextureBinRefCount(tb) + 1); // check to see if there is any modifiable images, // if yes, add those images to nodeComponentList in RenderBin @@ -2391,7 +2394,7 @@ abstract class TextureRetained extends NodeComponentRetained { ImageComponentRetained image; - textureBinRefCount--; + setTextureBinRefCount(tb, getTextureBinRefCount(tb) - 1); // remove any modifiable images from RenderBin nodeComponentList @@ -2468,4 +2471,22 @@ abstract class TextureRetained extends NodeComponentRetained { return this.useAsRaster; } + // Issue 357 - {get/set}TextureBinRefCount now uses a separate reference + // counter per RenderBin. The absence of the RenderBin key in the hash map + // is used to indicate a value of 0. This makes initialization easier, and + // prevents a small amount of garbage accumulating for inactive RenderBins. + + int getTextureBinRefCount(TextureBin tb) { + Integer i = textureBinRefCount.get(tb.renderBin); + return i == null ? 0 : i.intValue(); + } + + private void setTextureBinRefCount(TextureBin tb, int refCount) { + if (refCount == 0) { + textureBinRefCount.remove(tb.renderBin); + } else { + textureBinRefCount.put(tb.renderBin, new Integer(refCount)); + } + } + } -- cgit v1.2.3