summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mupdf/fitz/store.h12
-rw-r--r--platform/java/mupdf_native.c27
-rw-r--r--source/fitz/store.c11
3 files changed, 48 insertions, 2 deletions
diff --git a/include/mupdf/fitz/store.h b/include/mupdf/fitz/store.h
index 5b048ed0..7dff6c30 100644
--- a/include/mupdf/fitz/store.h
+++ b/include/mupdf/fitz/store.h
@@ -243,6 +243,18 @@ void fz_empty_store(fz_context *ctx);
int fz_store_scavenge(fz_context *ctx, size_t size, int *phase);
/*
+ fz_store_scavenge_external: External function for callers to use
+ to scavenge while trying allocations.
+
+ size: The number of bytes we are trying to have free.
+
+ phase: What phase of the scavenge we are in. Updated on exit.
+
+ Returns non zero if we managed to free any memory.
+*/
+int fz_store_scavenge_external(fz_context *ctx, size_t size, int *phase);
+
+/*
fz_shrink_store: Evict items from the store until the total size of
the objects in the store is reduced to a given percentage of its
current size.
diff --git a/platform/java/mupdf_native.c b/platform/java/mupdf_native.c
index 29c427b7..8af0b8a4 100644
--- a/platform/java/mupdf_native.c
+++ b/platform/java/mupdf_native.c
@@ -2556,6 +2556,7 @@ struct NativeDeviceInfo
int xOffset;
int yOffset;
int width;
+ int height;
};
static NativeDeviceInfo *lockNativeDevice(JNIEnv *env, jobject self, int *err)
@@ -3268,6 +3269,7 @@ newNativeAndroidDrawDevice(JNIEnv *env, jobject self, fz_context *ctx, jobject o
ninfo->xOffset = patchX0;
ninfo->yOffset = patchY0;
ninfo->width = width;
+ ninfo->height = height;
ninfo->object = obj;
(*env)->SetLongField(env, self, fid_NativeDevice_nativeInfo, jlong_cast(ninfo));
(*env)->SetObjectField(env, self, fid_NativeDevice_nativeResource, obj);
@@ -3301,11 +3303,22 @@ newNativeAndroidDrawDevice(JNIEnv *env, jobject self, fz_context *ctx, jobject o
static int androidDrawDevice_lock(JNIEnv *env, NativeDeviceInfo *info)
{
uint8_t *pixels;
+ int ret;
+ int phase = 0;
+ fz_context *ctx = get_context(env);
+ size_t size = info->width * info->height * 4;
assert(info);
assert(info->object);
- if (AndroidBitmap_lockPixels(env, info->object, (void **)&pixels) != ANDROID_BITMAP_RESULT_SUCCESS)
+ while (1) {
+ ret = AndroidBitmap_lockPixels(env, info->object, (void **)&pixels);
+ if (ret == ANDROID_BITMAP_RESULT_SUCCESS)
+ break;
+ if (!fz_store_scavenge_external(ctx, size, &phase))
+ break; /* Failed to free any */
+ }
+ if (ret != ANDROID_BITMAP_RESULT_SUCCESS)
{
info->pixmap->samples = NULL;
jni_throw(env, FZ_ERROR_GENERIC, "bitmap lock failed in DrawDevice call");
@@ -3386,8 +3399,18 @@ FUN(AndroidImage_newImageFromBitmap)(JNIEnv *env, jobject self, jobject jbitmap,
fz_try(ctx)
{
+ int ret;
+ int phase = 0;
+ size_t size = info.width * info.height * 4;
pixmap = fz_new_pixmap(ctx, fz_device_rgb(ctx), info.width, info.height, NULL, 1);
- if (AndroidBitmap_lockPixels(env, jbitmap, &pixels) != ANDROID_BITMAP_RESULT_SUCCESS)
+ while (1) {
+ ret = AndroidBitmap_lockPixels(env, jbitmap, (void **)&pixels);
+ if (ret == ANDROID_BITMAP_RESULT_SUCCESS)
+ break;
+ if (!fz_store_scavenge_external(ctx, size, &phase))
+ break; /* Failed to free any */
+ }
+ if (ret != ANDROID_BITMAP_RESULT_SUCCESS)
fz_throw(ctx, FZ_ERROR_GENERIC, "bitmap lock failed in new Image");
memcpy(pixmap->samples, pixels, info.width * info.height * 4);
if (AndroidBitmap_unlockPixels(env, jbitmap) != ANDROID_BITMAP_RESULT_SUCCESS)
diff --git a/source/fitz/store.c b/source/fitz/store.c
index f94a8aa2..f0d7c795 100644
--- a/source/fitz/store.c
+++ b/source/fitz/store.c
@@ -776,6 +776,17 @@ scavenge(fz_context *ctx, size_t tofree)
return count != 0;
}
+int fz_store_scavenge_external(fz_context *ctx, size_t size, int *phase)
+{
+ int ret;
+
+ fz_lock(ctx, FZ_LOCK_ALLOC);
+ ret = fz_store_scavenge(ctx, size, phase);
+ fz_unlock(ctx, FZ_LOCK_ALLOC);
+
+ return ret;
+}
+
int fz_store_scavenge(fz_context *ctx, size_t size, int *phase)
{
fz_store *store;