* Andrid - AndroidLocator now follows spec when regards to multiple call support with AssetInfo.openStream()
* Android - fix exception with recycled bitmaps that occurs when jME3 application is restored/maximized after pause git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9144 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
3fa629053a
commit
a64db6fc7b
@ -37,8 +37,6 @@ import com.jme3.audio.plugins.AndroidAudioLoader;
|
||||
import com.jme3.texture.Texture;
|
||||
import com.jme3.texture.plugins.AndroidImageLoader;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
@ -49,7 +47,6 @@ import java.util.logging.Logger;
|
||||
public class AndroidAssetManager extends DesktopAssetManager {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(AndroidAssetManager.class.getName());
|
||||
private List<ClassLoader> classLoaders;
|
||||
|
||||
public AndroidAssetManager() {
|
||||
this(null);
|
||||
@ -67,10 +64,8 @@ public class AndroidAssetManager extends DesktopAssetManager {
|
||||
* @param configFile
|
||||
*/
|
||||
public AndroidAssetManager(URL configFile) {
|
||||
|
||||
System.setProperty("org.xml.sax.driver", "org.xmlpull.v1.sax2.Driver");
|
||||
|
||||
|
||||
// Set Default Android config
|
||||
this.registerLocator("", AndroidLocator.class);
|
||||
this.registerLocator("", ClasspathLocator.class);
|
||||
@ -92,25 +87,9 @@ public class AndroidAssetManager extends DesktopAssetManager {
|
||||
this.registerLoader(com.jme3.scene.plugins.ogre.SceneLoader.class, "scene");
|
||||
this.registerLoader(com.jme3.shader.plugins.GLSLLoader.class, "vert", "frag", "glsl", "glsllib");
|
||||
|
||||
|
||||
logger.info("AndroidAssetManager created.");
|
||||
}
|
||||
|
||||
public void addClassLoader(ClassLoader loader){
|
||||
if(classLoaders == null)
|
||||
classLoaders = new ArrayList<ClassLoader>();
|
||||
classLoaders.add(loader);
|
||||
}
|
||||
|
||||
public void removeClassLoader(ClassLoader loader){
|
||||
if(classLoaders != null)
|
||||
classLoaders.remove(loader);
|
||||
}
|
||||
|
||||
public List<ClassLoader> getClassLoaders(){
|
||||
return classLoaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a texture.
|
||||
*
|
||||
@ -120,7 +99,10 @@ public class AndroidAssetManager extends DesktopAssetManager {
|
||||
public Texture loadTexture(TextureKey key) {
|
||||
Texture tex = (Texture) loadAsset(key);
|
||||
|
||||
// Needed for Android
|
||||
// XXX: This will improve performance on some really
|
||||
// low end GPUs (e.g. ones with OpenGL ES 1 support only)
|
||||
// but otherwise won't help on the higher ones.
|
||||
// Strongly consider removing this.
|
||||
tex.setMagFilter(Texture.MagFilter.Nearest);
|
||||
tex.setAnisotropicFilter(0);
|
||||
if (tex.getMinFilter().usesMipMapLevels()) {
|
||||
|
@ -1,74 +1,90 @@
|
||||
package com.jme3.asset.plugins;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import com.jme3.asset.AssetInfo;
|
||||
import com.jme3.asset.AssetKey;
|
||||
import com.jme3.asset.AssetLocator;
|
||||
import com.jme3.asset.*;
|
||||
import com.jme3.system.android.JmeAndroidSystem;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class AndroidLocator implements AssetLocator {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(AndroidLocator.class.getName());
|
||||
private Resources resources;
|
||||
|
||||
private android.content.res.AssetManager androidManager;
|
||||
private String rootPath = "";
|
||||
|
||||
private class AndroidAssetInfo extends AssetInfo {
|
||||
|
||||
private final InputStream in;
|
||||
private InputStream in;
|
||||
private final String assetPath;
|
||||
|
||||
public AndroidAssetInfo(com.jme3.asset.AssetManager manager, AssetKey<?> key, InputStream in)
|
||||
{
|
||||
super(manager, key);
|
||||
public AndroidAssetInfo(com.jme3.asset.AssetManager assetManager, AssetKey<?> key, String assetPath, InputStream in) {
|
||||
super(assetManager, key);
|
||||
this.assetPath = assetPath;
|
||||
this.in = in;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream openStream() {
|
||||
return in;
|
||||
if (in != null){
|
||||
// Reuse the already existing stream (only once)
|
||||
InputStream in2 = in;
|
||||
in = null;
|
||||
return in2;
|
||||
}else{
|
||||
// Create a new stream for subsequent invocations.
|
||||
try {
|
||||
return androidManager.open(assetPath);
|
||||
} catch (IOException ex) {
|
||||
throw new AssetLoadException("Failed to open asset " + assetPath, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public AndroidLocator()
|
||||
{
|
||||
resources = JmeAndroidSystem.getResources();
|
||||
androidManager = resources.getAssets();
|
||||
private AndroidAssetInfo create(AssetManager assetManager, AssetKey key, String assetPath) throws IOException {
|
||||
try {
|
||||
InputStream in = androidManager.open(assetPath);
|
||||
if (in == null){
|
||||
return null;
|
||||
}else{
|
||||
return new AndroidAssetInfo(assetManager, key, assetPath, in);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
// XXX: Prefer to show warning here?
|
||||
// Should only surpress exceptions for "file missing" type errors.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setRootPath(String rootPath)
|
||||
{
|
||||
public AndroidLocator() {
|
||||
androidManager = JmeAndroidSystem.getResources().getAssets();
|
||||
}
|
||||
|
||||
public void setRootPath(String rootPath) {
|
||||
this.rootPath = rootPath;
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
public AssetInfo locate(com.jme3.asset.AssetManager manager, AssetKey key)
|
||||
{
|
||||
InputStream in = null;
|
||||
String sAssetPath = rootPath + key.getName();
|
||||
public AssetInfo locate(com.jme3.asset.AssetManager manager, AssetKey key) {
|
||||
String assetPath = rootPath + key.getName();
|
||||
// Fix path issues
|
||||
if (sAssetPath.startsWith("/"))
|
||||
{
|
||||
if (assetPath.startsWith("/")) {
|
||||
// Remove leading /
|
||||
sAssetPath = sAssetPath.substring(1);
|
||||
assetPath = assetPath.substring(1);
|
||||
}
|
||||
sAssetPath = sAssetPath.replace("//", "/");
|
||||
assetPath = assetPath.replace("//", "/");
|
||||
try {
|
||||
in = androidManager.open(sAssetPath);
|
||||
if (in == null)
|
||||
return null;
|
||||
|
||||
return new AndroidAssetInfo(manager, key, in);
|
||||
return create(manager, key, assetPath);
|
||||
}catch (IOException ex){
|
||||
// This is different handling than URL locator
|
||||
// since classpath locating would return null at the getResource()
|
||||
// call, otherwise there's a more critical error...
|
||||
throw new AssetLoadException("Failed to open asset " + assetPath, ex);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
//logger.log(Level.WARNING, "Failed to locate {0} ", sAssetPath);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ import android.opengl.GLES10;
|
||||
import android.opengl.GLES11;
|
||||
import android.opengl.GLES20;
|
||||
import android.os.Build;
|
||||
import com.jme3.asset.AndroidImageInfo;
|
||||
import com.jme3.light.LightList;
|
||||
import com.jme3.material.RenderState;
|
||||
import com.jme3.math.*;
|
||||
@ -1915,7 +1916,7 @@ public class OGLESShaderRenderer implements Renderer {
|
||||
if (target == GLES20.GL_TEXTURE_CUBE_MAP) {
|
||||
// Upload a cube map / sky box
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Bitmap> bmps = (List<Bitmap>) img.getEfficentData();
|
||||
List<AndroidImageInfo> bmps = (List<AndroidImageInfo>) img.getEfficentData();
|
||||
if (bmps != null) {
|
||||
// Native android bitmap
|
||||
if (bmps.size() != 6) {
|
||||
@ -1923,7 +1924,7 @@ public class OGLESShaderRenderer implements Renderer {
|
||||
+ "Cubemap textures must contain 6 data units.");
|
||||
}
|
||||
for (int i = 0; i < 6; i++) {
|
||||
TextureUtil.uploadTextureBitmap(GLES20.GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, bmps.get(i), false, powerOf2);
|
||||
TextureUtil.uploadTextureBitmap(GLES20.GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, bmps.get(i).getBitmap(), false, powerOf2);
|
||||
}
|
||||
} else {
|
||||
// Standard jme3 image data
|
||||
|
@ -3,6 +3,7 @@ package com.jme3.renderer.android;
|
||||
import android.graphics.Bitmap;
|
||||
import android.opengl.GLES20;
|
||||
import android.opengl.GLUtils;
|
||||
import com.jme3.asset.AndroidImageInfo;
|
||||
import com.jme3.math.FastMath;
|
||||
import com.jme3.texture.Image;
|
||||
import com.jme3.texture.Image.Format;
|
||||
@ -118,12 +119,16 @@ public class TextureUtil {
|
||||
boolean generateMips,
|
||||
boolean powerOf2){
|
||||
|
||||
if (img.getEfficentData() instanceof Bitmap){
|
||||
Bitmap bitmap = (Bitmap) img.getEfficentData();
|
||||
uploadTextureBitmap(target, bitmap, generateMips, powerOf2);
|
||||
if (img.getEfficentData() instanceof AndroidImageInfo){
|
||||
// If image was loaded from asset manager, use fast path
|
||||
AndroidImageInfo imageInfo = (AndroidImageInfo) img.getEfficentData();
|
||||
uploadTextureBitmap(target, imageInfo.getBitmap(), generateMips, powerOf2);
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise upload image directly.
|
||||
// Prefer to only use power of 2 textures here to avoid errors.
|
||||
|
||||
Image.Format fmt = img.getFormat();
|
||||
ByteBuffer data;
|
||||
if (index >= 0 || img.getData() != null && img.getData().size() > 0){
|
||||
|
@ -1,78 +1,20 @@
|
||||
package com.jme3.texture.plugins;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Matrix;
|
||||
import com.jme3.asset.AndroidImageInfo;
|
||||
import com.jme3.asset.AssetInfo;
|
||||
import com.jme3.asset.AssetLoader;
|
||||
import com.jme3.asset.TextureKey;
|
||||
import com.jme3.texture.Image;
|
||||
import com.jme3.texture.Image.Format;
|
||||
import com.jme3.util.BufferUtils;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class AndroidImageLoader implements AssetLoader {
|
||||
|
||||
public Object load2(AssetInfo info) throws IOException {
|
||||
ByteBuffer bb = BufferUtils.createByteBuffer(1 * 1 * 2);
|
||||
bb.put((byte) 0xff).put((byte) 0xff);
|
||||
bb.clear();
|
||||
return new Image(Format.RGB5A1, 1, 1, bb);
|
||||
}
|
||||
|
||||
public Object load(AssetInfo info) throws IOException {
|
||||
InputStream in = null;
|
||||
Bitmap bitmap = null;
|
||||
try {
|
||||
in = info.openStream();
|
||||
bitmap = BitmapFactory.decodeStream(in);
|
||||
if (bitmap == null) {
|
||||
throw new IOException("Failed to load image: " + info.getKey().getName());
|
||||
}
|
||||
} finally {
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
AndroidImageInfo imageInfo = new AndroidImageInfo(info);
|
||||
Bitmap bitmap = imageInfo.getBitmap();
|
||||
|
||||
int width = bitmap.getWidth();
|
||||
int height = bitmap.getHeight();
|
||||
Format fmt;
|
||||
|
||||
switch (bitmap.getConfig()) {
|
||||
case ALPHA_8:
|
||||
fmt = Format.Alpha8;
|
||||
break;
|
||||
case ARGB_4444:
|
||||
fmt = Format.ARGB4444;
|
||||
break;
|
||||
case ARGB_8888:
|
||||
fmt = Format.RGBA8;
|
||||
break;
|
||||
case RGB_565:
|
||||
fmt = Format.RGB565;
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
if (((TextureKey) info.getKey()).isFlipY()) {
|
||||
Bitmap newBitmap = null;
|
||||
Matrix flipMat = new Matrix();
|
||||
flipMat.preScale(1.0f, -1.0f);
|
||||
newBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), flipMat, false);
|
||||
bitmap.recycle();
|
||||
bitmap = newBitmap;
|
||||
|
||||
if (bitmap == null) {
|
||||
throw new IOException("Failed to flip image: " + info.getKey().getName());
|
||||
}
|
||||
}
|
||||
|
||||
Image image = new Image(fmt, width, height, null);
|
||||
image.setEfficentData(bitmap);
|
||||
Image image = new Image(imageInfo.getFormat(), bitmap.getWidth(), bitmap.getHeight(), null);
|
||||
image.setEfficentData(imageInfo);
|
||||
return image;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user