TextureItem: allow cloning uninitialized textures

- TextureRegion: use texture handle, not atlas.texture
- update SymbolLayer

- TextureAtlas: remove depth
This commit is contained in:
Hannes Janetzek 2014-09-11 15:12:54 +02:00
parent 5a0f10559d
commit 707769f124
5 changed files with 66 additions and 72 deletions

View File

@ -83,26 +83,12 @@ public class TextureAtlas extends Inlist<TextureAtlas> {
final int mHeight; final int mHeight;
/** Depth (in bytes) of the underlying texture */ /** Depth (in bytes) of the underlying texture */
final int mDepth;
/** Allocated surface size */ /** Allocated surface size */
int mUsed; int mUsed;
public TextureItem texture; public TextureItem texture;
/**
* only call in GL-Thread
*/
public TextureItem loadTexture() {
if (texture != null) {
texture.upload();
return texture;
}
log.debug("Missing atlas texture");
return null;
}
public static class Slot extends Inlist<Slot> { public static class Slot extends Inlist<Slot> {
public int x, y, w; public int x, y, w;
@ -122,17 +108,20 @@ public class TextureAtlas extends Inlist<TextureAtlas> {
} }
public int x, y, w, h; public int x, y, w, h;
@Override
public String toString() {
return x + ":" + y + " " + w + "x" + h;
}
} }
TextureAtlas(int width, int height, int depth) { public TextureAtlas(int width, int height) {
mWidth = width; mWidth = width;
mHeight = height; mHeight = height;
mDepth = depth;
mSlots = new Slot(1, 1, width - 2); mSlots = new Slot(1, 1, width - 2);
} }
public TextureAtlas(Bitmap bitmap) { public TextureAtlas(Bitmap bitmap) {
mDepth = 0;
texture = new TextureItem(bitmap); texture = new TextureItem(bitmap);
mWidth = texture.width; mWidth = texture.width;
mHeight = texture.height; mHeight = texture.height;
@ -144,7 +133,7 @@ public class TextureAtlas extends Inlist<TextureAtlas> {
public void addTextureRegion(Object key, Rect r) { public void addTextureRegion(Object key, Rect r) {
mRegions.put(key, new TextureRegion(this, r)); mRegions.put(key, new TextureRegion(this.texture, r));
} }
@ -251,7 +240,7 @@ public class TextureAtlas extends Inlist<TextureAtlas> {
if (!(depth == 1 || depth == 3 || depth == 4)) if (!(depth == 1 || depth == 3 || depth == 4))
throw new IllegalArgumentException("invalid depth"); throw new IllegalArgumentException("invalid depth");
return new TextureAtlas(width, height, depth); return new TextureAtlas(width, height);
} }
// /// FIXME // /// FIXME

View File

@ -17,14 +17,15 @@
package org.oscim.renderer.atlas; package org.oscim.renderer.atlas;
import org.oscim.renderer.atlas.TextureAtlas.Rect; import org.oscim.renderer.atlas.TextureAtlas.Rect;
import org.oscim.renderer.elements.TextureItem;
public class TextureRegion { public class TextureRegion {
public TextureRegion(TextureAtlas textureAtlas, Rect r) { public TextureRegion(TextureItem texture, Rect r) {
this.atlas = textureAtlas; this.texture = texture;
this.rect = r; this.rect = r;
} }
public final TextureAtlas atlas;
public final Rect rect; public final Rect rect;
public final TextureItem texture;
} }

View File

@ -82,10 +82,9 @@ public final class SymbolLayer extends TextureLayer {
if (it.texRegion != null) { if (it.texRegion != null) {
/* FIXME this work only with one TextureAtlas per SymbolLayer */ /* FIXME this work only with one TextureAtlas per SymbolLayer */
if (textures == null) { if (textures == null) {
t = it.texRegion.atlas.loadTexture();
/* clone TextureItem to use same texID with /* clone TextureItem to use same texID with
* multiple TextureItem */ * multiple TextureItem */
t = TextureItem.clone(t); t = TextureItem.clone(it.texRegion.texture);
textures = Inlist.appendItem(textures, t); textures = Inlist.appendItem(textures, t);
} }
@ -101,8 +100,6 @@ public final class SymbolLayer extends TextureLayer {
if (t == null) { if (t == null) {
t = new TextureItem(it.bitmap); t = new TextureItem(it.bitmap);
textures = Inlist.appendItem(textures, t); textures = Inlist.appendItem(textures, t);
t.upload();
t.offset = numIndices; t.offset = numIndices;
t.indices = 0; t.indices = 0;
} }

View File

@ -34,8 +34,10 @@ import org.slf4j.LoggerFactory;
public class TextureItem extends Inlist<TextureItem> { public class TextureItem extends Inlist<TextureItem> {
static final Logger log = LoggerFactory.getLogger(TextureItem.class); static final Logger log = LoggerFactory.getLogger(TextureItem.class);
static final boolean dbg = false;
/** texture ID */ /** texture ID */
public int id; private int id;
/** current settings */ /** current settings */
public final int width; public final int width;
@ -43,6 +45,7 @@ public class TextureItem extends Inlist<TextureItem> {
public final boolean repeat; public final boolean repeat;
/** vertex offset from which this texture is referenced */ /** vertex offset from which this texture is referenced */
/* FIXME dont put this here! */
public short offset; public short offset;
public short indices; public short indices;
@ -50,58 +53,44 @@ public class TextureItem extends Inlist<TextureItem> {
public Bitmap bitmap; public Bitmap bitmap;
/** do not release the texture when TextureItem is released. */ /** do not release the texture when TextureItem is released. */
private boolean ref; private TextureItem ref;
private int used = 0;
/** texture data is ready */ /** texture data is ready */
private boolean ready; boolean loaded;
final TexturePool pool; final TexturePool pool;
private TextureItem(TexturePool pool, int id) { private TextureItem(TexturePool pool, int id) {
this.id = id; this(pool, id, pool.mWidth, pool.mHeight, false);
this.width = pool.mWidth;
this.height = pool.mHeight;
this.pool = pool;
this.repeat = false;
} }
public TextureItem(Bitmap bitmap) { public TextureItem(Bitmap bitmap) {
this.bitmap = bitmap; this(bitmap, false);
this.id = -1;
this.width = bitmap.getWidth();
this.height = bitmap.getHeight();
this.pool = NOPOOL;
this.repeat = false;
} }
public TextureItem(Bitmap bitmap, boolean repeat) { public TextureItem(Bitmap bitmap, boolean repeat) {
this(NOPOOL, -1, bitmap.getWidth(), bitmap.getHeight(), repeat);
this.bitmap = bitmap; this.bitmap = bitmap;
this.id = -1;
this.width = bitmap.getWidth();
this.height = bitmap.getHeight();
this.repeat = repeat;
this.pool = NOPOOL;
} }
private TextureItem(TexturePool pool, int id, int width, int height) { private TextureItem(TexturePool pool, int id, int width, int height, boolean repeat) {
this.id = id; this.id = id;
this.width = width; this.width = width;
this.height = height; this.height = height;
this.pool = pool; this.pool = pool;
this.repeat = false; this.repeat = repeat;
} }
public static TextureItem clone(TextureItem ti) { public static TextureItem clone(TextureItem ti) {
// original texture needs to be loaded
if (!ti.ready)
throw new IllegalStateException();
TextureItem clone = new TextureItem(ti.pool, ti.id, ti.width, ti.height); TextureItem clone = new TextureItem(NOPOOL, ti.id, ti.width, ti.height, ti.repeat);
clone.id = ti.id; clone.id = ti.id;
clone.ref = true; clone.ref = (ti.ref == null) ? ti : ti.ref;
clone.ready = true; clone.loaded = ti.loaded;
clone.ref.used++;
return clone; return clone;
} }
@ -110,10 +99,19 @@ public class TextureItem extends Inlist<TextureItem> {
* [on GL-Thread] * [on GL-Thread]
*/ */
public void upload() { public void upload() {
if (!ready) { if (loaded)
return;
if (ref == null) {
pool.uploadTexture(this); pool.uploadTexture(this);
ready = true;
} else {
/* load referenced texture */
ref.upload();
id = ref.id;
} }
loaded = true;
} }
/** /**
@ -121,12 +119,10 @@ public class TextureItem extends Inlist<TextureItem> {
* [on GL-Thread] * [on GL-Thread]
*/ */
public void bind() { public void bind() {
if (!ready) { if (loaded)
pool.uploadTexture(this);
ready = true;
} else {
GLState.bindTex2D(id); GLState.bindTex2D(id);
} else
upload();
} }
/** /**
@ -211,10 +207,20 @@ public class TextureItem extends Inlist<TextureItem> {
@Override @Override
protected boolean clearItem(TextureItem t) { protected boolean clearItem(TextureItem t) {
if (t.ref) if (t.used > 0)
return false; return false;
t.ready = false; if (t.ref != null) {
/* dispose texture if this clone holds the last handle */
if (t.ref.used == 0) {
t.ref.dispose();
return false;
}
t.ref.used--;
return false;
}
t.loaded = false;
if (mUseBitmapPool) if (mUseBitmapPool)
releaseBitmap(t); releaseBitmap(t);
@ -224,7 +230,8 @@ public class TextureItem extends Inlist<TextureItem> {
@Override @Override
protected void freeItem(TextureItem t) { protected void freeItem(TextureItem t) {
if (!t.ref && t.id >= 0) {
if (t.ref == null && t.used == 0 && t.id >= 0) {
mTexCnt--; mTexCnt--;
synchronized (disposedTextures) { synchronized (disposedTextures) {
disposedTextures.add(Integer.valueOf(t.id)); disposedTextures.add(Integer.valueOf(t.id));
@ -255,7 +262,7 @@ public class TextureItem extends Inlist<TextureItem> {
initTexture(t); initTexture(t);
if (TextureLayer.Renderer.debug) if (dbg)
log.debug("fill:" + getFill() log.debug("fill:" + getFill()
+ " count:" + mTexCnt + " count:" + mTexCnt
+ " new texture " + t.id); + " new texture " + t.id);
@ -265,11 +272,12 @@ public class TextureItem extends Inlist<TextureItem> {
t.bitmap.uploadToTexture(false); t.bitmap.uploadToTexture(false);
} else { } else {
GLState.bindTex2D(t.id); GLState.bindTex2D(t.id);
// use faster subimage upload
/* use faster subimage upload */
t.bitmap.uploadToTexture(true); t.bitmap.uploadToTexture(true);
} }
if (TextureLayer.Renderer.debug) if (dbg)
GLUtils.checkGlError(TextureItem.class.getName()); GLUtils.checkGlError(TextureItem.class.getName());
if (mUseBitmapPool) if (mUseBitmapPool)
@ -309,7 +317,9 @@ public class TextureItem extends Inlist<TextureItem> {
GL = gl; GL = gl;
} }
/** disposed textures are released by MapRenderer after each frame */ /**
* Disposed textures are released by MapRenderer after each frame
*/
public static void disposeTextures() { public static void disposeTextures() {
synchronized (disposedTextures) { synchronized (disposedTextures) {
@ -321,7 +331,6 @@ public class TextureItem extends Inlist<TextureItem> {
disposedTextures.clear(); disposedTextures.clear();
GLUtils.glDeleteTextures(size, tmp); GLUtils.glDeleteTextures(size, tmp);
//mTexCnt -= size;
} }
} }
} }

View File

@ -103,8 +103,6 @@ public abstract class TextureLayer extends RenderElement {
public static final class Renderer { public static final class Renderer {
public final static boolean debug = false;
private static Shader shader; private static Shader shader;
static void init() { static void init() {