diff options
author | Matt Holgate <matt@emobix.co.uk> | 2014-06-20 10:21:40 +0100 |
---|---|---|
committer | Matt Holgate <matt@emobix.co.uk> | 2014-06-20 10:21:40 +0100 |
commit | d7ece4132d6219ee10ba9ed85a9f2a052a6bb92c (patch) | |
tree | 47b751a13321ad9d7fe4fa8261b41ff29587a353 /platform/android/jni | |
parent | 7ba8c60c5af8ff745336c50c7504bec4f9b22a76 (diff) | |
download | mupdf-d7ece4132d6219ee10ba9ed85a9f2a052a6bb92c.tar.xz |
Improvement which should hopefully help with bug #693607 - MupdfActivity crash when rotating the device.
When cancelling a render async task, we now wait for it to actually finish
before continuing. The benefit of this is that we should be able to guarantee
that its Bitmap becomes eligible for GC before we continue to create any
new bitmaps.
This should hopefully help with the OOM errors seen when rotating
the device and trying to create the new bitmaps.
To prevent the UI thread from being blocked for too long while we're waiting
for the async task to finish, we use a fz_cookie and set the 'abort' flag to
request the render be stopped as soon as possible.
Diffstat (limited to 'platform/android/jni')
-rw-r--r-- | platform/android/jni/mupdf.c | 91 |
1 files changed, 80 insertions, 11 deletions
diff --git a/platform/android/jni/mupdf.c b/platform/android/jni/mupdf.c index 53cb7b3a..c7965702 100644 --- a/platform/android/jni/mupdf.c +++ b/platform/android/jni/mupdf.c @@ -623,7 +623,7 @@ static void update_changed_rects(globals *glo, page_cache *pc, pdf_document *ido JNIEXPORT jboolean JNICALL JNI_FN(MuPDFCore_drawPage)(JNIEnv *env, jobject thiz, jobject bitmap, - int pageW, int pageH, int patchX, int patchY, int patchW, int patchH) + int pageW, int pageH, int patchX, int patchY, int patchW, int patchH, jlong cookiePtr) { AndroidBitmapInfo info; void *pixels; @@ -641,6 +641,7 @@ JNI_FN(MuPDFCore_drawPage)(JNIEnv *env, jobject thiz, jobject bitmap, page_cache *pc = &glo->pages[glo->current]; int hq = (patchW < pageW || patchH < pageH); fz_matrix scale; + fz_cookie *cookie = (fz_cookie *)(unsigned int)cookiePtr; if (pc->page == NULL) return 0; @@ -690,9 +691,15 @@ JNI_FN(MuPDFCore_drawPage)(JNIEnv *env, jobject thiz, jobject bitmap, /* Render to list */ pc->page_list = fz_new_display_list(ctx); dev = fz_new_list_device(ctx, pc->page_list); - fz_run_page_contents(doc, pc->page, dev, &fz_identity, NULL); + fz_run_page_contents(doc, pc->page, dev, &fz_identity, cookie); fz_free_device(dev); dev = NULL; + if (cookie != NULL && cookie->abort) + { + fz_drop_display_list(ctx, pc->page_list); + pc->page_list = NULL; + fz_throw(ctx, FZ_ERROR_GENERIC, "Render aborted"); + } } if (pc->annot_list == NULL) { @@ -700,9 +707,15 @@ JNI_FN(MuPDFCore_drawPage)(JNIEnv *env, jobject thiz, jobject bitmap, pc->annot_list = fz_new_display_list(ctx); dev = fz_new_list_device(ctx, pc->annot_list); for (annot = fz_first_annot(doc, pc->page); annot; annot = fz_next_annot(doc, annot)) - fz_run_annot(doc, pc->page, annot, dev, &fz_identity, NULL); + fz_run_annot(doc, pc->page, annot, dev, &fz_identity, cookie); fz_free_device(dev); dev = NULL; + if (cookie != NULL && cookie->abort) + { + fz_drop_display_list(ctx, pc->annot_list); + pc->annot_list = NULL; + fz_throw(ctx, FZ_ERROR_GENERIC, "Render aborted"); + } } bbox.x0 = patchX; bbox.y0 = patchY; @@ -742,9 +755,15 @@ JNI_FN(MuPDFCore_drawPage)(JNIEnv *env, jobject thiz, jobject bitmap, for (i=0; i<100;i++) { #endif if (pc->page_list) - fz_run_display_list(pc->page_list, dev, &ctm, &rect, NULL); + fz_run_display_list(pc->page_list, dev, &ctm, &rect, cookie); + if (cookie != NULL && cookie->abort) + fz_throw(ctx, FZ_ERROR_GENERIC, "Render aborted"); + if (pc->annot_list) - fz_run_display_list(pc->annot_list, dev, &ctm, &rect, NULL); + fz_run_display_list(pc->annot_list, dev, &ctm, &rect, cookie); + if (cookie != NULL && cookie->abort) + fz_throw(ctx, FZ_ERROR_GENERIC, "Render aborted"); + #ifdef TIME_DISPLAY_LIST } time = clock() - time; @@ -787,7 +806,7 @@ static char *widget_type_string(int t) } JNIEXPORT jboolean JNICALL JNI_FN(MuPDFCore_updatePageInternal)(JNIEnv *env, jobject thiz, jobject bitmap, int page, - int pageW, int pageH, int patchX, int patchY, int patchW, int patchH) + int pageW, int pageH, int patchX, int patchY, int patchW, int patchH, jlong cookiePtr) { AndroidBitmapInfo info; void *pixels; @@ -808,6 +827,7 @@ JNI_FN(MuPDFCore_updatePageInternal)(JNIEnv *env, jobject thiz, jobject bitmap, fz_document *doc = glo->doc; rect_node *crect; fz_matrix scale; + fz_cookie *cookie = (fz_cookie *)(unsigned int)cookiePtr; for (i = 0; i < NUM_CACHE; i++) { @@ -823,7 +843,7 @@ JNI_FN(MuPDFCore_updatePageInternal)(JNIEnv *env, jobject thiz, jobject bitmap, /* Without a cached page object we cannot perform a partial update so render the entire bitmap instead */ JNI_FN(MuPDFCore_gotoPageInternal)(env, thiz, page); - return JNI_FN(MuPDFCore_drawPage)(env, thiz, bitmap, pageW, pageH, patchX, patchY, patchW, patchH); + return JNI_FN(MuPDFCore_drawPage)(env, thiz, bitmap, pageW, pageH, patchX, patchY, patchW, patchH, (jlong)(unsigned int)cookie); } idoc = pdf_specifics(doc); @@ -869,18 +889,30 @@ JNI_FN(MuPDFCore_updatePageInternal)(JNIEnv *env, jobject thiz, jobject bitmap, /* Render to list */ pc->page_list = fz_new_display_list(ctx); dev = fz_new_list_device(ctx, pc->page_list); - fz_run_page_contents(doc, pc->page, dev, &fz_identity, NULL); + fz_run_page_contents(doc, pc->page, dev, &fz_identity, cookie); fz_free_device(dev); dev = NULL; + if (cookie != NULL && cookie->abort) + { + fz_drop_display_list(ctx, pc->page_list); + pc->page_list = NULL; + fz_throw(ctx, FZ_ERROR_GENERIC, "Render aborted"); + } } if (pc->annot_list == NULL) { pc->annot_list = fz_new_display_list(ctx); dev = fz_new_list_device(ctx, pc->annot_list); for (annot = fz_first_annot(doc, pc->page); annot; annot = fz_next_annot(doc, annot)) - fz_run_annot(doc, pc->page, annot, dev, &fz_identity, NULL); + fz_run_annot(doc, pc->page, annot, dev, &fz_identity, cookie); fz_free_device(dev); dev = NULL; + if (cookie != NULL && cookie->abort) + { + fz_drop_display_list(ctx, pc->annot_list); + pc->annot_list = NULL; + fz_throw(ctx, FZ_ERROR_GENERIC, "Render aborted"); + } } bbox.x0 = patchX; @@ -920,9 +952,15 @@ JNI_FN(MuPDFCore_updatePageInternal)(JNIEnv *env, jobject thiz, jobject bitmap, fz_clear_pixmap_rect_with_value(ctx, pix, 0xff, &abox); dev = fz_new_draw_device_with_bbox(ctx, pix, &abox); if (pc->page_list) - fz_run_display_list(pc->page_list, dev, &ctm, &arect, NULL); + fz_run_display_list(pc->page_list, dev, &ctm, &arect, cookie); + if (cookie != NULL && cookie->abort) + fz_throw(ctx, FZ_ERROR_GENERIC, "Render aborted"); + if (pc->annot_list) - fz_run_display_list(pc->annot_list, dev, &ctm, &arect, NULL); + fz_run_display_list(pc->annot_list, dev, &ctm, &arect, cookie); + if (cookie != NULL && cookie->abort) + fz_throw(ctx, FZ_ERROR_GENERIC, "Render aborted"); + fz_free_device(dev); dev = NULL; } @@ -2550,3 +2588,34 @@ JNI_FN(MuPDFCore_dumpMemoryInternal)(JNIEnv * env, jobject thiz) LOGE("dumpMemoryInternal end"); #endif } + +JNIEXPORT jlong JNICALL +JNI_FN(MuPDFCore_createCookie)(JNIEnv * env, jobject thiz) +{ + globals *glo = get_globals(env, thiz); + if (glo == NULL) + return 0; + fz_context *ctx = glo->ctx; + + return (jlong) (unsigned int) fz_calloc_no_throw(ctx,1, sizeof(fz_cookie)); +} + +JNIEXPORT void JNICALL +JNI_FN(MuPDFCore_destroyCookie)(JNIEnv * env, jobject thiz, jlong cookiePtr) +{ + fz_cookie *cookie = (fz_cookie *) (unsigned int) cookiePtr; + globals *glo = get_globals(env, thiz); + if (glo == NULL) + return; + fz_context *ctx = glo->ctx; + + fz_free(ctx, cookie); +} + +JNIEXPORT void JNICALL +JNI_FN(MuPDFCore_abortCookie)(JNIEnv * env, jobject thiz, jlong cookiePtr) +{ + fz_cookie *cookie = (fz_cookie *) (unsigned int) cookiePtr; + if (cookie != NULL) + cookie->abort = 1; +} |