Revert "archive: Use memfd instead"

* It sucks, seems simplify the conditions, but more syscalls are
  made(read/seek/write), more context switch, futhermore AImageDecoder itself does support
  read raw buffer, and we are not intend to support multi-process decoding

This reverts commit f4826ea727.
This commit is contained in:
tarsin committed 2022-08-07 19:14:25 +08:00
1 parent f4826ea727
commit a0fe6f0d7d
6 files changed
+63 -25

No files matched your search

+14 -8
View File
@@ -21,7 +21,6 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <syscall.h>
#include <sys/mman.h>
#include <jni.h>
@@ -104,7 +103,6 @@ JNIEXPORT jint JNICALL
Java_com_hippo_UriArchiveAccessor_openArchive(JNIEnv *_, jobject thiz, jint fd, jlong size) {
archiveAddr = mmap64(0, size, PROT_READ, MAP_PRIVATE, fd, 0);
if (archiveAddr == MAP_FAILED) {
archiveAddr = NULL;
LOGE("%s%d", "mmap64 failed with errno ", errno);
return 0;
}
@@ -145,27 +143,35 @@ Java_com_hippo_UriArchiveAccessor_openArchive(JNIEnv *_, jobject thiz, jint fd,
return r;
}
JNIEXPORT jint JNICALL
Java_com_hippo_UriArchiveAccessor_extractToMemfd(JNIEnv *_, jobject thiz, jint index) {
typedef struct Memarea {
void *buffer;
long size;
} Memarea;
JNIEXPORT jlong JNICALL
Java_com_hippo_UriArchiveAccessor_extracttoOutputStream(JNIEnv *_, jobject thiz, jint index) {
struct archive_entry *entry;
int ret;
if (!arc || index < cur_index) {
archive_alloc();
cur_index = 0;
}
int memfd = syscall(SYS_memfd_create, "ArchiveMemFD", 0);
Memarea *memarea = malloc(sizeof(Memarea));
while (archive_read_next_header(arc, &entry) == ARCHIVE_OK) {
if (!filename_is_playable_file(archive_entry_pathname(entry)))
continue;
if (cur_index++ == index) {
ret = archive_read_data_into_fd(arc, memfd);
memarea->size = (long) archive_entry_size(entry);
memarea->buffer = malloc(memarea->size);
ret = archive_read_data(arc, memarea->buffer, memarea->size);
if (ret != memarea->size)
LOGE("%s", "No enough data read, WTF?");
if (ret < 0)
LOGE("%s%s", "Archive read failed:", archive_error_string(arc));
break;
}
}
lseek64(memfd, 0, SEEK_SET);
return memfd;
return (jlong) memarea;
}
JNIEXPORT void JNICALL
+26 -4
View File
@@ -19,10 +19,8 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <android/data_space.h>
#include <android/fdsan.h>
#include <android/imagedecoder.h>
#include <android/log.h>
@@ -54,6 +52,7 @@ void image_onUnload() {
typedef struct {
AImageDecoder *decoder;
void *srcBuffer;
size_t stride;
int fd;
} SOURCE;
@@ -73,8 +72,7 @@ static void recycleSource(SOURCE *src) {
if (!src)
return;
AImageDecoder_delete(src->decoder);
if (!android_fdsan_get_owner_tag(src->fd))
close(src->fd);
free(src->srcBuffer);
free(src);
}
@@ -86,6 +84,11 @@ static void recycle(IMAGE *image) {
free(image);
}
typedef struct Memarea {
void *buffer;
long size;
} Memarea;
bool copy_pixels(const void *src, int src_w, int src_h, int src_x, int src_y,
void *dst, int dst_w, int dst_h, int dst_x, int dst_y,
int width, int height) {
@@ -213,6 +216,17 @@ IMAGE *createFromFd(int fd) {
return image;
}
IMAGE *createFromAddr(void *addr, long size) {
AImageDecoder *decoder;
AImageDecoder_createFromBuffer((const void *) addr, size, &decoder);
IMAGE *image = calloc(1, sizeof(IMAGE));
SOURCE *src = calloc(1, sizeof(SOURCE));
src->decoder = decoder;
src->srcBuffer = addr;
decodeCommon(image, src);
return image;
}
IMAGE *create(int32_t width, int32_t height, const void *data) {
IMAGE *plain = calloc(1, sizeof(IMAGE));
void *buffer = NULL;
@@ -342,6 +356,14 @@ Java_com_hippo_image_Image_nativeRecycle(JNIEnv *env, jclass clazz, jlong ptr) {
recycle((IMAGE *) ptr);
}
JNIEXPORT jlong JNICALL
Java_com_hippo_image_Image_nativeDecodeAddr(JNIEnv *env, jclass clazz, jlong addr) {
Memarea *memarea = (Memarea *) addr;
IMAGE *image = createFromAddr(memarea->buffer, memarea->size);
free(memarea);
return (jlong) image;
}
JNIEXPORT jint JNICALL
Java_com_hippo_image_Image_nativeGetFormat(JNIEnv *env, jclass clazz, jlong native_ptr) {
return ((IMAGE *) native_ptr)->isAnimated;
-4
View File
@@ -23,8 +23,6 @@
#include <zlib.h>
#include <nettle/config.h>
#include <android/fdsan.h>
#include "image.h"
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
@@ -38,8 +36,6 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
return JNI_ERR;
}
android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE);
return JNI_VERSION_1_6;
}
@@ -21,6 +21,10 @@ package com.hippo;
import android.content.Context;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.system.Os;
import android.system.OsConstants;
import java.io.FileDescriptor;
public class UriArchiveAccessor {
ParcelFileDescriptor pfd;
@@ -39,7 +43,7 @@ public class UriArchiveAccessor {
private native int openArchive(int fd, long size);
public native int extractToMemfd(int index);
public native long extracttoOutputStream(int index);
public native boolean needPassword();
@@ -49,7 +49,7 @@ public class ArchiveGalleryProvider extends GalleryProvider2 {
private final UriArchiveAccessor archiveAccessor;
private final Stack<Integer> requests = new Stack<>();
private final AtomicInteger extractingIndex = new AtomicInteger(GalleryPageView.INVALID_INDEX);
private final LinkedHashMap<Integer, Integer> streams = new LinkedHashMap<>();
private final LinkedHashMap<Integer, Long> streams = new LinkedHashMap<>();
private final AtomicInteger decodingIndex = new AtomicInteger(GalleryPageView.INVALID_INDEX);
private Thread archiveThread;
private Thread decodeThread;
@@ -255,10 +255,10 @@ public class ArchiveGalleryProvider extends GalleryProvider2 {
}
}
int fd = archiveAccessor.extractToMemfd(index);
long addr = archiveAccessor.extracttoOutputStream(index);
synchronized (streams) {
streams.put(index, fd);
streams.put(index, addr);
streams.notify();
}
}
@@ -270,7 +270,7 @@ public class ArchiveGalleryProvider extends GalleryProvider2 {
public void run() {
while (!Thread.currentThread().isInterrupted()) {
int index;
int fd;
Long addr;
synchronized (streams) {
if (streams.isEmpty()) {
try {
@@ -282,16 +282,16 @@ public class ArchiveGalleryProvider extends GalleryProvider2 {
continue;
}
Iterator<Map.Entry<Integer, Integer>> iterator = streams.entrySet().iterator();
Map.Entry<Integer, Integer> entry = iterator.next();
Iterator<Map.Entry<Integer, Long>> iterator = streams.entrySet().iterator();
Map.Entry<Integer, Long> entry = iterator.next();
iterator.remove();
index = entry.getKey();
fd = entry.getValue();
addr = entry.getValue();
decodingIndex.lazySet(index);
}
try {
Image image = Image.decode(fd, false);
Image image = Image.decodeAddr(addr, true);
if (image != null) {
notifyPageSucceed(index, image);
} else {
@@ -71,6 +71,14 @@ public final class Image {
return newFromAddr(nativeDecodeFdInt(fd));
}
/**
* Decode image from {@code InputStream}
*/
@Nullable
public static Image decodeAddr(Long addr, boolean partially) {
return newFromAddr(nativeDecodeAddr(addr));
}
/**
* Create a plain image from Bitmap
*/
@@ -91,6 +99,8 @@ public final class Image {
private static native long nativeDecodeFdInt(int fd);
private static native long nativeDecodeAddr(long addr);
private static native long nativeCreate(Bitmap bitmap);
private static native void nativeRender(long nativePtr,