Fixed icon loading

This commit is contained in:
Alexey Pelykh 2012-03-03 18:47:28 +02:00
parent cc336ed49b
commit 14bbbb000a
6 changed files with 59 additions and 39 deletions

View file

@ -54,11 +54,25 @@ LOCAL_CFLAGS += \
endif
ifneq ($(LOCAL_ARM_NEON),true)
LOCAL_STATIC_LIBRARIES := proto skia
LOCAL_STATIC_LIBRARIES := \
proto \
libjpeg \
libft2_static \
libpng \
libgif \
libexpat_static
LOCAL_WHOLE_STATIC_LIBRARIES := skia
else
LOCAL_STATIC_LIBRARIES := proto_neon skia_neon
LOCAL_STATIC_LIBRARIES := \
proto_neon \
libjpeg_neon \
libft2_static_neon \
libpng_neon \
libgif_neon \
libexpat_static_neon
LOCAL_WHOLE_STATIC_LIBRARIES := skia_neon
endif
LOCAL_LDLIBS := -llog -ljnigraphics
LOCAL_LDLIBS := -lz -llog -ljnigraphics
include $(BUILD_SHARED_LIBRARY)

View file

@ -120,7 +120,7 @@ std::string getStringMethod(jobject o, jmethodID fid, int i)
jclass jclass_RenderingContext = NULL;
jfieldID jfield_RenderingContext_interrupted = NULL;
jclass jclass_RenderingIcons = NULL;
jmethodID jmethod_RenderingIcons_getIconAsByteBuffer = NULL;
jmethodID jmethod_RenderingIcons_getIconRawData = NULL;
jfieldID jfield_RenderingContext_leftX = NULL;
jfieldID jfield_RenderingContext_topY = NULL;
jfieldID jfield_RenderingContext_width = NULL;
@ -172,9 +172,9 @@ void loadJniCommon()
jfield_RenderingContext_lastRenderedKey = getFid( jclass_RenderingContext, "lastRenderedKey", "I" );
jclass_RenderingIcons = findClass("net/osmand/plus/render/RenderingIcons");
jmethod_RenderingIcons_getIconAsByteBuffer = getGlobalJniEnv()->GetStaticMethodID(jclass_RenderingIcons,
"getIconAsByteBuffer",
"(Landroid/content/Context;Ljava/lang/String;)Ljava/nio/ByteBuffer;");
jmethod_RenderingIcons_getIconRawData = getGlobalJniEnv()->GetStaticMethodID(jclass_RenderingIcons,
"getIconRawData",
"(Landroid/content/Context;Ljava/lang/String;)[B");
}
//TODO: Dead code
@ -321,9 +321,11 @@ int ElapsedTimer::getElapsedTime()
}
std::hash_map<std::string, SkBitmap*> cachedBitmaps;
SkBitmap* getCachedBitmap(RenderingContext* rc, std::string bitmapResource)
SkBitmap* getCachedBitmap(RenderingContext* rc, const std::string& bitmapResource)
{
if(bitmapResource.size() == 0)
return NULL;
// Try to find previously cached
std::hash_map<std::string, SkBitmap*>::iterator itPreviouslyCachedBitmap = cachedBitmaps.find(bitmapResource);
if (itPreviouslyCachedBitmap != cachedBitmaps.end())
@ -331,15 +333,20 @@ SkBitmap* getCachedBitmap(RenderingContext* rc, std::string bitmapResource)
rc->nativeOperations.pause();
__android_log_print(ANDROID_LOG_INFO, LOG_TAG, "getCachedBitmap : %s", bitmapResource.c_str());
jstring jstr = getGlobalJniEnv()->NewStringUTF(bitmapResource.c_str());
jobject javaIconByteBuffer = getGlobalJniEnv()->CallStaticObjectMethod(jclass_RenderingIcons, jmethod_RenderingIcons_getIconAsByteBuffer, rc->androidContext, jstr);
if(!javaIconByteBuffer)
jbyteArray javaIconRawData = (jbyteArray)getGlobalJniEnv()->CallStaticObjectMethod(jclass_RenderingIcons, jmethod_RenderingIcons_getIconRawData, rc->androidContext, jstr);
if(!javaIconRawData)
return NULL;
jbyte* bitmapBuffer = getGlobalJniEnv()->GetByteArrayElements(javaIconRawData, NULL);
size_t bufferLen = getGlobalJniEnv()->GetArrayLength(javaIconRawData);
__android_log_print(ANDROID_LOG_INFO, LOG_TAG, "getCachedBitmap : bitmap buffer len %d at %p", bufferLen, bitmapBuffer);
// Decode bitmap
SkBitmap* iconBitmap = new SkBitmap();
void* bitmapBuffer = getGlobalJniEnv()->GetDirectBufferAddress(javaIconByteBuffer);
size_t bufferLen = getGlobalJniEnv()->GetDirectBufferCapacity(javaIconByteBuffer);
//TODO: JPEG is badly supported! At the moment it needs sdcard to be present (sic). Patch that
if(!SkImageDecoder::DecodeMemory(bitmapBuffer, bufferLen, iconBitmap))
{
@ -347,7 +354,8 @@ SkBitmap* getCachedBitmap(RenderingContext* rc, std::string bitmapResource)
delete iconBitmap;
rc->nativeOperations.start();
getGlobalJniEnv()->DeleteLocalRef(javaIconByteBuffer);
getGlobalJniEnv()->ReleaseByteArrayElements(javaIconRawData, bitmapBuffer, JNI_ABORT);
getGlobalJniEnv()->DeleteLocalRef(javaIconRawData);
getGlobalJniEnv()->DeleteLocalRef(jstr);
throwNewException((std::string("Failed to decode ") + bitmapResource).c_str());
@ -358,7 +366,8 @@ SkBitmap* getCachedBitmap(RenderingContext* rc, std::string bitmapResource)
rc->nativeOperations.start();
getGlobalJniEnv()->DeleteLocalRef(javaIconByteBuffer);
getGlobalJniEnv()->ReleaseByteArrayElements(javaIconRawData, bitmapBuffer, JNI_ABORT);
getGlobalJniEnv()->DeleteLocalRef(javaIconRawData);
getGlobalJniEnv()->DeleteLocalRef(jstr);
return iconBitmap;

View file

@ -143,6 +143,6 @@ struct RenderingContext
float getDensityValue(RenderingContext* rc, float val);
SkBitmap* getCachedBitmap(RenderingContext* rc, std::string bitmapResource);
SkBitmap* getCachedBitmap(RenderingContext* rc, const std::string& bitmapResource);
#endif /*_OSMAND_COMMON_H*/

View file

@ -493,13 +493,11 @@ void drawPoint(MapDataObject* mObj, RenderingRuleSearchRequest* req, SkCanvas* c
std::string resId = req->getStringPropertyValue(req-> props()-> R_ICON);
SkBitmap* bmp = getCachedBitmap(rc, resId);
std::string name;
if (renderText) {
if (renderText)
name = mObj->name;
}
if (!bmp && name.length() == 0) {
return;
}
if (!bmp && name.length() == 0)
return;
jint length = mObj->points.size();
rc->visible++;

View file

@ -200,6 +200,7 @@ LOCAL_SRC_FILES := \
$(OSMAND_SKIA_LOC)/src/images/SkImageRef.cpp \
$(OSMAND_SKIA_LOC)/src/images/SkImageRefPool.cpp \
$(OSMAND_SKIA_LOC)/src/images/SkImageRef_GlobalPool.cpp \
$(OSMAND_SKIA_LOC)/src/images/SkJpegUtility.cpp \
$(OSMAND_SKIA_LOC)/src/images/SkMovie.cpp \
$(OSMAND_SKIA_LOC)/src/images/SkMovie_gif.cpp \
$(OSMAND_SKIA_LOC)/src/images/SkPageFlipper.cpp \

View file

@ -5,6 +5,7 @@ import java.util.LinkedHashMap;
import java.util.Map;
import java.nio.ByteBuffer;
import java.io.InputStream;
import java.io.ByteArrayOutputStream;
import org.apache.commons.logging.Log;
@ -29,7 +30,7 @@ public class RenderingIcons {
return icons.containsKey(s);
}
public static ByteBuffer getIconAsByteBuffer(Context ctx, String s) {
public static byte[] getIconRawData(Context ctx, String s) {
Integer resId = icons.get(s);
// Quite bad error
@ -37,23 +38,20 @@ public class RenderingIcons {
return null;
try {
final AssetFileDescriptor iconAssetFd = ctx.getResources().openRawResourceFd(resId.intValue());
if(iconAssetFd == null)
return null;
final long iconAssetLen = iconAssetFd.getLength();
final ByteBuffer iconByteBuffer = ByteBuffer.allocate((int)iconAssetLen);
final InputStream inputStream = iconAssetFd.createInputStream();
if(inputStream == null)
return null;
long consumedBytes = 0;
while(consumedBytes < iconAssetLen) {
consumedBytes += inputStream.read(iconByteBuffer.array(), (int)(iconByteBuffer.arrayOffset() + consumedBytes), (int)(iconAssetLen - consumedBytes));
final InputStream inputStream = ctx.getResources().openRawResource(resId.intValue());
final ByteArrayOutputStream proxyOutputStream = new ByteArrayOutputStream(1024);
final byte[] ioBuffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(ioBuffer)) >= 0) {
proxyOutputStream.write(ioBuffer, 0, bytesRead);
}
inputStream.close();
final byte[] bitmapData = proxyOutputStream.toByteArray();
log.info("Icon data length is " + bitmapData.length); //$NON-NLS-1$
iconAssetFd.close();
return iconByteBuffer;
//if(android.graphics.BitmapFactory.decodeByteArray(bitmapData, 0, bitmapData.length) == null)
// throw new Exception();
return bitmapData;
} catch(Throwable e) {
log.error("Failed to get byte stream from icon", e); //$NON-NLS-1$
return null;