summaryrefslogtreecommitdiff
path: root/platform/android/jni
diff options
context:
space:
mode:
authorMatt Holgate <matt@emobix.co.uk>2014-06-20 10:21:40 +0100
committerMatt Holgate <matt@emobix.co.uk>2014-06-20 10:21:40 +0100
commitd7ece4132d6219ee10ba9ed85a9f2a052a6bb92c (patch)
tree47b751a13321ad9d7fe4fa8261b41ff29587a353 /platform/android/jni
parent7ba8c60c5af8ff745336c50c7504bec4f9b22a76 (diff)
downloadmupdf-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.c91
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;
+}