Skip to content

Commit

Permalink
Optimized streamReadFun() to cache it's read buff
Browse files Browse the repository at this point in the history
StreamContainer now can hold onto a byte buffer for the streamReadFunc
so a new one doesn't have to be alloced for every read op.

This had the consequence of requiring us to lock streamReadFunc() on a
mutex to remain thread safe since calls to it would be sharing the same
buffer.

I've seen only modest perf gains on average, a few ms at best. However,
there are certain "bad" frames in terms of render times, and those cases
saw a pretty good improvement. Since they are not the majority though,
it didn't effect the average framerate very much.
  • Loading branch information
Wavesonics committed Nov 18, 2013
1 parent e3a8440 commit 02745ad
Showing 1 changed file with 38 additions and 8 deletions.
46 changes: 38 additions & 8 deletions jni/gif.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,17 @@
#include <limits.h>
#include <stdlib.h>
//#include <android/log.h>
#include "giflib/gif_lib.h"
#include <malloc.h>

#include <stdbool.h>
#include <string.h>
#include <limits.h>

#include "giflib/gif_lib.h"

//#define LOG_TAG "libgif"
//#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
//#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)

JavaVM *g_jvm;

Expand Down Expand Up @@ -77,7 +79,7 @@ typedef struct {
jclass streamCls;
jmethodID readMID;
jmethodID resetMID;
//jbyteArray buffer;
jbyteArray buffer;
} StreamContainer;

static ColorMapObject* genDefColorMap() {
Expand Down Expand Up @@ -151,25 +153,44 @@ static int streamReadFun(GifFileType* gif, GifByteType* bytes, int size) {
StreamContainer* sc = gif->UserData;
JNIEnv* env = getEnv( gif );

jbyteArray buffer = (*env)->NewByteArray(env, size);
(*env)->MonitorEnter(env,sc->stream);

if( sc->buffer == NULL )
{
jbyteArray buffer = (*env)->NewByteArray(env, size);
sc->buffer = (*env)->NewGlobalRef(env, buffer);
}
else
{
jsize bufLen = (*env)->GetArrayLength(env, sc->buffer);
if( bufLen < size )
{
(*env)->DeleteGlobalRef(env,sc->buffer);
sc->buffer = NULL;

int len = (*env)->CallIntMethod(env, sc->stream, sc->readMID, buffer);
jbyteArray buffer = (*env)->NewByteArray(env, size);
sc->buffer = (*env)->NewGlobalRef(env, buffer);
}
}

int len = (*env)->CallIntMethod(env, sc->stream, sc->readMID, sc->buffer, 0, size);
if ((*env)->ExceptionOccurred(env))
{
(*env)->ExceptionClear(env);
len = 0;
}
else
{
jbyte* data = (*env)->GetByteArrayElements(env, buffer, NULL);
jbyte* data = (*env)->GetByteArrayElements(env, sc->buffer, NULL);

if( data != NULL )
{
memcpy( bytes, data, len );
(*env)->ReleaseByteArrayElements(env, buffer, data, JNI_ABORT);
(*env)->ReleaseByteArrayElements(env, sc->buffer, data, JNI_ABORT);
}
}

(*env)->DeleteLocalRef(env, buffer);
(*env)->MonitorExit(env,sc->stream);

return len >= 0 ? len : 0;
}
Expand Down Expand Up @@ -419,6 +440,7 @@ static jint open(GifFileType *GifFileIn, int Error, int startPos,

return (jint) info;
}

JNIEXPORT jint JNICALL Java_pl_droidsonroids_gif_GifDrawable_openFile(JNIEnv * env,
jobject obj, jintArray metaData, jstring jfname)
{
Expand Down Expand Up @@ -446,7 +468,7 @@ JNIEXPORT jint JNICALL Java_pl_droidsonroids_gif_GifDrawable_openStream(JNIEnv *
{
jclass streamCls = (*env)->NewGlobalRef(env,(*env)->GetObjectClass(env, stream));
jmethodID mid = (*env)->GetMethodID(env, streamCls, "mark", "(I)V");
jmethodID readMID = (*env)->GetMethodID(env, streamCls, "read", "([B)I");
jmethodID readMID = (*env)->GetMethodID(env, streamCls, "read", "([BII)I");
jmethodID resetMID = (*env)->GetMethodID(env, streamCls, "reset", "()V");

if (mid == 0||readMID==0||resetMID==0)
Expand All @@ -470,6 +492,7 @@ JNIEXPORT jint JNICALL Java_pl_droidsonroids_gif_GifDrawable_openStream(JNIEnv *
container->jvm=g_jvm;
container->stream=(*env)->NewGlobalRef(env,stream);
container->streamCls = streamCls;
container->buffer = NULL;

int Error=0;
GifFileType* GifFileIn = DGifOpen(container,&streamReadFun,&Error);
Expand Down Expand Up @@ -604,6 +627,7 @@ static void eraseColor(argb* bm, int w, int h, argb color) {
uint32_t* pColor = (uint32_t*) (&color);
memset((uint32_t*) bm, *pColor, w * h * sizeof(argb));
}

static inline void disposeFrameIfNeeded(argb* bm, GifInfo* info,
unsigned int idx, argb* backup, argb color) {
GifFileType* fGif = info->gifFilePtr;
Expand Down Expand Up @@ -716,6 +740,12 @@ JNIEXPORT void JNICALL Java_pl_droidsonroids_gif_GifDrawable_free(JNIEnv * env,
StreamContainer* sc= info->gifFilePtr->UserData;
(*env)->DeleteGlobalRef(env,sc->streamCls);
(*env)->DeleteGlobalRef(env,sc->stream);

if( sc->buffer != NULL )
{
(*env)->DeleteGlobalRef(env,sc->buffer);
}

free(sc);
}
else if (info->rewindFunc==fileRewindFun)
Expand Down

0 comments on commit 02745ad

Please sign in to comment.