Skip to content

Commit

Permalink
surface rendering optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
koral-- committed Apr 15, 2015
1 parent 84ba5cb commit 4e438af
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 45 deletions.
2 changes: 2 additions & 0 deletions src/main/jni/bitmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ Java_pl_droidsonroids_gif_GifInfoHandle_renderFrame(JNIEnv *env, jclass __unused
return 0;
}
DDGifSlurp(info, true);
if (info->currentIndex == 0)
prepareCanvas(pixels, info);
const uint_fast32_t frameDuration = getBitmap((argb *) pixels, info);
unlockPixels(env, jbitmap);
return calculateInvalidationDelay(info, renderStartTime, frameDuration);
Expand Down
43 changes: 20 additions & 23 deletions src/main/jni/control.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,24 @@ Java_pl_droidsonroids_gif_GifInfoHandle_setSpeedFactor(JNIEnv __unused *env, jcl
info->speedFactor = factor;
}

static uint_fast32_t seek(GifInfo *info, JNIEnv *env, jint desiredIndex, jobject jbitmap) {
uint_fast32_t lastFrameDuration = info->infos[info->currentIndex].DelayTime;
if (info->currentIndex < desiredIndex) {
void *pixels;
if (lockPixels(env, jbitmap, info, &pixels) != 0) {
return 0;
}
if (info->currentIndex == 0)
prepareCanvas(pixels, info);
while (info->currentIndex < desiredIndex) {
DDGifSlurp(info, true);
lastFrameDuration = getBitmap((argb *) pixels, info);
}
unlockPixels(env, jbitmap);
}
return lastFrameDuration;
}

__unused JNIEXPORT void JNICALL
Java_pl_droidsonroids_gif_GifInfoHandle_seekToTime(JNIEnv *env, jclass __unused handleClass,
jlong gifInfo, jint desiredPos, jobject jbitmap) {
Expand Down Expand Up @@ -60,17 +78,7 @@ Java_pl_droidsonroids_gif_GifInfoHandle_seekToTime(JNIEnv *env, jclass __unused
info->lastFrameRemainder > info->infos[desiredIndex].DelayTime)
info->lastFrameRemainder = info->infos[desiredIndex].DelayTime;
}
if (info->currentIndex < desiredIndex) {
void *pixels;
if (lockPixels(env, jbitmap, info, &pixels) != 0) {
return;
}
while (info->currentIndex < desiredIndex) {
DDGifSlurp(info, true);
getBitmap((argb *) pixels, info);
}
unlockPixels(env, jbitmap);
}
seek(info, env, desiredIndex, jbitmap);

info->nextStartTime = getRealTime() + (long) (info->lastFrameRemainder / info->speedFactor);
}
Expand All @@ -90,18 +98,7 @@ Java_pl_droidsonroids_gif_GifInfoHandle_seekToFrame(JNIEnv *env, jclass __unused
if (desiredIndex >= info->gifFilePtr->ImageCount)
desiredIndex = (jint) (info->gifFilePtr->ImageCount - 1);

uint_fast32_t lastFrameDuration = info->infos[info->currentIndex].DelayTime;
if (info->currentIndex < desiredIndex) {
void *pixels;
if (lockPixels(env, jbitmap, info, &pixels) != 0) {
return;
}
while (info->currentIndex < desiredIndex) {
DDGifSlurp(info, true);
lastFrameDuration = getBitmap((argb *) pixels, info);
}
unlockPixels(env, jbitmap);
}
uint_fast32_t lastFrameDuration = seek(info, env, desiredIndex, jbitmap);

info->nextStartTime = getRealTime() + (long) (lastFrameDuration / info->speedFactor);
if (info->lastFrameRemainder != -1)
Expand Down
27 changes: 14 additions & 13 deletions src/main/jni/drawing.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#define MEMSET_ARGB(dst, value, count) memset(dst, value, count * sizeof(argb))
#endif

static void blitNormal(argb *bm, GifInfo *info, SavedImage *frame, ColorMapObject *cmap) {
static inline void blitNormal(argb *bm, GifInfo *info, SavedImage *frame, ColorMapObject *cmap) {
unsigned char *src = info->rasterBits;
argb *dst = GET_ADDR(bm, info->stride, frame->ImageDesc.Left, frame->ImageDesc.Top);

Expand Down Expand Up @@ -135,21 +135,22 @@ static inline void disposeFrameIfNeeded(argb *bm, GifInfo *info) {
memcpy(backup, bm, info->stride * fGif->SHeight * sizeof(argb));
}

uint_fast32_t const getBitmap(argb *bm, GifInfo *info) {
if (info->currentIndex == 0) {
if (info->gifFilePtr->SColorMap && info->infos[0].TransparentColor == NO_TRANSPARENT_COLOR) {
argb bgColArgb;
bgColArgb.rgb = info->gifFilePtr->SColorMap->Colors[info->gifFilePtr->SBackGroundColor];
bgColArgb.alpha = 0xFF;
MEMSET_ARGB((uint32_t *) bm, *(uint32_t *) &bgColArgb, info->stride * info->gifFilePtr->SHeight);
}
else {
MEMSET_ARGB((uint32_t *) bm, 0, info->stride * info->gifFilePtr->SHeight);
}
inline void prepareCanvas(argb *bm, GifInfo *info){
if (info->gifFilePtr->SColorMap && info->infos->TransparentColor == NO_TRANSPARENT_COLOR) {
argb bgColArgb;
bgColArgb.rgb = info->gifFilePtr->SColorMap->Colors[info->gifFilePtr->SBackGroundColor];
bgColArgb.alpha = 0xFF;
MEMSET_ARGB((uint32_t *) bm, *(uint32_t *) &bgColArgb, info->stride * info->gifFilePtr->SHeight);
}
else {
disposeFrameIfNeeded(bm, info);
MEMSET_ARGB((uint32_t *) bm, 0, info->stride * info->gifFilePtr->SHeight);
}
}

uint_fast32_t getBitmap(argb *bm, GifInfo *info) {
if (info->currentIndex > 0)
disposeFrameIfNeeded(bm, info);

drawFrame(bm, info, info->gifFilePtr->SavedImages + info->currentIndex);
uint_fast32_t frameDuration = info->infos[info->currentIndex].DelayTime;

Expand Down
6 changes: 3 additions & 3 deletions src/main/jni/gif.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ static uint_fast8_t streamReadFun(GifFileType *gif, GifByteType *bytes, uint_fas
(*env)->DeleteGlobalRef(env, sc->buffer);

jbyteArray buffer = (*env)->NewByteArray(env, size);
if (buffer == NULL){
if (buffer == NULL) {
sc->buffer = NULL;
return 0;
}
Expand Down Expand Up @@ -117,7 +117,7 @@ Java_pl_droidsonroids_gif_GifInfoHandle_openFile(JNIEnv *env, jclass __unused cl
return NULL;
}

const char *const filename = (*env)->GetStringUTFChars(env, jfname, 0);
const char *const filename = (*env)->GetStringUTFChars(env, jfname, NULL);
if (filename == NULL) {
throwException(env, ILLEGAL_STATE_EXCEPTION_BARE, "GetStringUTFChars failed");
return NULL;
Expand Down Expand Up @@ -360,7 +360,7 @@ JNI_OnLoad(JavaVM *vm, void *__unused reserved) {
defaultCmap = GifMakeMapObject(8, NULL);
if (defaultCmap != NULL) {
uint_fast16_t iColor;
for (iColor = 0; iColor < 256; iColor++) {
for (iColor = 1; iColor < 256; iColor++) {
defaultCmap->Colors[iColor].Red = (GifByteType) iColor;
defaultCmap->Colors[iColor].Green = (GifByteType) iColor;
defaultCmap->Colors[iColor].Blue = (GifByteType) iColor;
Expand Down
6 changes: 4 additions & 2 deletions src/main/jni/gif.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,15 +186,15 @@ void throwGifIOException(int errorCode, JNIEnv *env);

jobject createGifHandle(GifSourceDescriptor *descriptor, JNIEnv *env, jboolean justDecodeMetaData);

static void blitNormal(argb *bm, GifInfo *info, SavedImage *frame, ColorMapObject *cmap);
static inline void blitNormal(argb *bm, GifInfo *info, SavedImage *frame, ColorMapObject *cmap);

static void drawFrame(argb *bm, GifInfo *info, SavedImage *frame);

static bool checkIfCover(const SavedImage *target, const SavedImage *covered);

static void disposeFrameIfNeeded(argb *bm, GifInfo *info);

uint_fast32_t const getBitmap(argb *bm, GifInfo *info);
uint_fast32_t getBitmap(argb *bm, GifInfo *info);

bool reset(GifInfo *info);

Expand All @@ -207,3 +207,5 @@ long calculateInvalidationDelay(GifInfo *info, long renderStartTime, uint_fast32
jint restoreSavedState(GifInfo *info, JNIEnv *env, jlongArray state, void *pixels);

void releaseSurfaceDescriptor(SurfaceDescriptor *surfaceDescriptor, JNIEnv *pConst);

inline void prepareCanvas(argb *bm, GifInfo *info);
2 changes: 2 additions & 0 deletions src/main/jni/metadata.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ jint restoreSavedState(GifInfo *info, JNIEnv *env, jlongArray state, void *pixel

uint_fast32_t lastFrameDuration = info->infos[info->currentIndex].DelayTime;
if (info->currentIndex < savedIndex) {
if (info->currentIndex == 0)
prepareCanvas(pixels, info);
while (info->currentIndex < savedIndex) {
DDGifSlurp(info, true);
lastFrameDuration = getBitmap((argb *) pixels, info);
Expand Down
5 changes: 3 additions & 2 deletions src/main/jni/surface.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,10 @@ Java_pl_droidsonroids_gif_GifInfoHandle_bindSurface(JNIEnv *env, jclass __unused
oldBufferBits = buffer.bits;
THROW_AND_BREAK_ON_NONZERO_RESULT(ANativeWindow_lock(window, &buffer, NULL), "Window lock failed");

if (info->currentIndex > 0) {
if (info->currentIndex == 0)
prepareCanvas(buffer.bits, info);
else
memcpy(buffer.bits, oldBufferBits, bufferSize);
}

pthread_mutex_lock(&info->surfaceDescriptor->renderMutex);
while (info->surfaceDescriptor->renderHelper == 0) {
Expand Down
5 changes: 3 additions & 2 deletions src/main/jni/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ long calculateInvalidationDelay(GifInfo *info, long renderStartTime, uint_fast32
invalidationDelay /= info->speedFactor;
}
const long renderingTime = getRealTime() - renderStartTime;
invalidationDelay -= renderingTime;
if (invalidationDelay < 0)
if (renderingTime >= invalidationDelay)
invalidationDelay = 0;
else
invalidationDelay -= renderingTime;
info->nextStartTime = renderStartTime + invalidationDelay;
return invalidationDelay;
}
Expand Down

0 comments on commit 4e438af

Please sign in to comment.