- changed abstract SyncPool.clearItem() to return whether item should be put back to pool

- fix leak in TextureItem
This commit is contained in:
Hannes Janetzek 2013-07-01 03:53:58 +02:00
parent ae951dc4bd
commit 37781cad78
9 changed files with 81 additions and 67 deletions

View File

@ -47,7 +47,7 @@ public abstract class SpriteManager<T> {
protected TextureItem mTexture;
public SpriteManager() {
mTexture = TextureItem.get(true);
mTexture = TextureItem.get();
//mTexture.ownBitmap = true;
@ -74,7 +74,7 @@ public abstract class SpriteManager<T> {
items = null;
//mTexture.bitmap.eraseColor(Color.TRANSPARENT);
mTexture = TextureItem.get(true);
mTexture = TextureItem.get();
mCanvas.setBitmap(mTexture.bitmap);
}

View File

@ -36,8 +36,6 @@ public class BitmapLayer extends TextureLayer {
mReuseBitmap = reuseBitmap;
mVertices = new short[24];
textures = new TextureItem(-1);
// used for size calculation of Layers buffer.
verticesCnt = 4;
}
@ -47,12 +45,10 @@ public class BitmapLayer extends TextureLayer {
mHeight = h;
mBitmap = bitmap;
if (this.textures == null)
this.textures = new TextureItem(mBitmap);
TextureItem ti = this.textures;
ti.ownBitmap = true;
ti.width = mBitmap.getWidth();
ti.height = mBitmap.getHeight();
ti.bitmap = mBitmap;
ti.vertices = TextureRenderer.INDICES_PER_SPRITE;
}

View File

@ -31,11 +31,12 @@ public class SymbolItem extends Inlist<SymbolItem> {
}
@Override
protected void clearItem(SymbolItem it) {
protected boolean clearItem(SymbolItem it) {
// drop references
it.bitmap = null;
it.symbol = null;
it.offset = null;
return true;
}
};

View File

@ -86,7 +86,7 @@ public final class SymbolLayer extends TextureLayer {
to = it.symbol.atlas.compileTexture();
// clone TextureItem to use same texID with
// multiple TextureItem
to = new TextureItem(to);
to = TextureItem.clone(to);
textures = Inlist.append(textures, to);
}

View File

@ -30,12 +30,13 @@ public class TextItem extends Inlist<TextItem> {
}
@Override
protected void clearItem(TextItem ti) {
protected boolean clearItem(TextItem ti) {
// drop references
ti.string = null;
ti.text = null;
ti.n1 = null;
ti.n2 = null;
return true;
}
};

View File

@ -92,7 +92,7 @@ public final class TextLayer extends TextureLayer {
float y = 0;
float yy;
TextureItem to = TextureItem.get(true);
TextureItem to = TextureItem.get();
textures = to;
mCanvas.setBitmap(to.bitmap);
@ -114,7 +114,7 @@ public final class TextLayer extends TextureLayer {
to.vertices = (short) (numIndices - offsetIndices);
offsetIndices = numIndices;
to.next = TextureItem.get(true);
to.next = TextureItem.get();
to = to.next;
mCanvas.setBitmap(to.bitmap);

View File

@ -46,22 +46,24 @@ public class TextureItem extends Inlist<TextureItem> {
public Bitmap bitmap;
// external bitmap (not from pool)
boolean ownBitmap;
private boolean ownBitmap;
// is only referencing a textureId, does not
// release the texture when TextureItem is
// released.
boolean isClone;
private boolean isClone;
TextureItem(int id) {
private TextureItem(int id) {
this.id = id;
}
TextureItem(TextureItem ti) {
this.id = ti.id;
this.width = ti.width;
this.height = ti.height;
this.isClone = true;
public static TextureItem clone(TextureItem ti) {
TextureItem clone = new TextureItem(ti.id);
clone.id = ti.id;
clone.width = ti.width;
clone.height = ti.height;
clone.isClone = true;
return clone;
}
public TextureItem(Bitmap bitmap) {
@ -80,20 +82,19 @@ public class TextureItem extends Inlist<TextureItem> {
* Retrieve a TextureItem from pool with default Bitmap with dimension
* TextureRenderer.TEXTURE_WIDTH/HEIGHT.
*/
public synchronized static TextureItem get(boolean initBitmap) {
public synchronized static TextureItem get() {
TextureItem ti = pool.get();
Log.d(TAG, "get texture item " + ti.id);
if (initBitmap) {
ti.bitmap = getBitmap();
ti.bitmap.eraseColor(Color.TRANSPARENT);
ti.ownBitmap = false;
} else {
ti.ownBitmap = true;
}
ti.bitmap = getBitmap();
ti.bitmap.eraseColor(Color.TRANSPARENT);
return ti;
}
private final static SyncPool<TextureItem> pool = new SyncPool<TextureItem>(20) {
static class TextureItemPool extends SyncPool<TextureItem> {
public TextureItemPool() {
super(20);
}
@Override
public void init(int num) {
@ -104,30 +105,38 @@ public class TextureItem extends Inlist<TextureItem> {
TextureItem to = new TextureItem(textureIds[i]);
pool = Inlist.push(pool, to);
}
count = num;
fill = num;
}
public TextureItem get(int width, int height) {
return null;
}
@Override
protected TextureItem createItem() {
return new TextureItem(-1);
}
@Override
protected void clearItem(TextureItem it) {
protected boolean clearItem(TextureItem it) {
// Log.d(TAG, it.ownBitmap + " " + (it.bitmap == null));
if (it.ownBitmap)
return;
if (it.ownBitmap) {
it.bitmap = null;
it.ownBitmap = false;
return false;
}
if (it.isClone) {
it.isClone = false;
it.id = -1;
it.width = -1;
it.height = -1;
return;
return false;
}
releaseBitmap(it);
return true;
}
@Override
@ -140,6 +149,8 @@ public class TextureItem extends Inlist<TextureItem> {
}
};
private final static SyncPool<TextureItem> pool = new TextureItemPool();
private final static ArrayList<Integer> mTextures = new ArrayList<Integer>();
private final static ArrayList<Bitmap> mBitmaps = new ArrayList<Bitmap>(10);
@ -189,12 +200,13 @@ public class TextureItem extends Inlist<TextureItem> {
to.id = textureIds[0];
initTexture(to.id);
// if (TextureRenderer.debug)
Log.d(TAG, "poolCnt:" + pool.getCount() + " poolFill:" + pool.getFill()
+ " texCnt:" + mTexCnt + " new texture " + to.id);
Log.d(TAG, "poolFill:" + pool.getFill()
+ " texCnt:" + mTexCnt
+ " new texture " + to.id);
}
uploadTexture(to, to.bitmap, mBitmapFormat, mBitmapType,
TEXTURE_WIDTH, TEXTURE_HEIGHT);
TEXTURE_WIDTH, TEXTURE_HEIGHT);
if (!to.ownBitmap)
TextureItem.releaseBitmap(to);
@ -205,7 +217,7 @@ public class TextureItem extends Inlist<TextureItem> {
}
public static void uploadTexture(TextureItem to, Bitmap bitmap,
int format, int type, int w, int h) {
int format, int type, int w, int h) {
if (to == null) {
Log.d(TAG, "no texture!");
@ -213,7 +225,7 @@ public class TextureItem extends Inlist<TextureItem> {
}
GL.glBindTexture(GL20.GL_TEXTURE_2D, to.id);
Log.d(TAG, "upload " + to.id);
//Log.d(TAG, "upload " + to.id);
if (to.ownBitmap) {
bitmap.uploadToTexture(false);
// GLUtils.texImage2D(GL20.GL_TEXTURE_2D, 0, bitmap, 0);
@ -239,17 +251,19 @@ public class TextureItem extends Inlist<TextureItem> {
GL.glBindTexture(GL20.GL_TEXTURE_2D, id);
GL.glTexParameterf(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_MIN_FILTER,
GL20.GL_LINEAR);
GL20.GL_LINEAR);
GL.glTexParameterf(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_MAG_FILTER,
GL20.GL_LINEAR);
GL20.GL_LINEAR);
GL.glTexParameterf(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_WRAP_S,
GL20.GL_CLAMP_TO_EDGE); // Set U Wrapping
GL20.GL_CLAMP_TO_EDGE); // Set U Wrapping
GL.glTexParameterf(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_WRAP_T,
GL20.GL_CLAMP_TO_EDGE); // Set V Wrapping
GL20.GL_CLAMP_TO_EDGE); // Set V Wrapping
}
static void init(int num) {
pool.init(num);
mTexCnt = num;
mBitmaps.clear();
mTextures.clear();
@ -266,7 +280,6 @@ public class TextureItem extends Inlist<TextureItem> {
// mBitmapFormat = GLUtils.getInternalFormat(mBitmaps.get(0));
// mBitmapType = GLUtils.getType(mBitmaps.get(0));
mTexCnt = num;
}
static Bitmap getBitmap() {

View File

@ -29,8 +29,9 @@ public class VertexItem extends Inlist<VertexItem> {
}
@Override
protected void clearItem(VertexItem it) {
protected boolean clearItem(VertexItem it) {
it.used = 0;
return true;
}
};

View File

@ -17,24 +17,17 @@ package org.oscim.utils.pool;
public abstract class SyncPool<T extends Inlist<T>> {
protected final int maxFill;
protected int fill;
protected int count;
protected T pool;
public SyncPool() {
maxFill = 100;
fill = 0;
count = 0;
}
public SyncPool(int maxItemsInPool) {
maxFill = maxItemsInPool;
fill = 0;
count = 0;
}
public int getCount() {
return count;
}
public int getFill() {
@ -42,21 +35,25 @@ public abstract class SyncPool<T extends Inlist<T>> {
}
/**
* @param items number of initial items.
* NOTE: default does nothing!
* @param items
* number of initial items. NOTE: default does nothing!
*/
public void init(int items) {
}
/**
* @param item set initial state
* @param item
* set initial state
* @return true when item should be added back to pool
* when returning false freeItem will not be called.
*/
protected void clearItem(T item) {
protected boolean clearItem(T item) {
return true;
}
/**
* @param item release resources
* @param item
* release resources
*/
protected void freeItem(T item) {
@ -68,8 +65,11 @@ public abstract class SyncPool<T extends Inlist<T>> {
if (item == null)
return;
clearItem(item);
if (!clearItem(item)) {
// dont add back to pool
freeItem(item);
return;
}
if (fill < maxFill) {
synchronized (this) {
fill++;
@ -79,7 +79,6 @@ public abstract class SyncPool<T extends Inlist<T>> {
}
} else {
freeItem(item);
count--;
}
}
@ -91,8 +90,6 @@ public abstract class SyncPool<T extends Inlist<T>> {
while (item != null) {
clearItem(item);
freeItem(item);
count--;
item = item.next;
}
return;
@ -102,7 +99,13 @@ public abstract class SyncPool<T extends Inlist<T>> {
while (item != null) {
T next = item.next;
clearItem(item);
if (!clearItem(item)) {
// dont add back to pool
freeItem(item);
item = next;
continue;
}
fill++;
item.next = pool;
@ -117,7 +120,6 @@ public abstract class SyncPool<T extends Inlist<T>> {
synchronized (this) {
if (pool == null) {
count++;
return createItem();
}