Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cc217e3b authored by Clément Julliard's avatar Clément Julliard
Browse files

Pass WRITE usage flag to the mapper if ImageReader was created with a

WRITE usage flag.

Since some producers rely on these buffers being unchanged (eg. for
partial rendering), this feature should be used with caution. A warning
to this effect was added in the Javadoc.

Bug: 162287616
Test: built emulator, confirmed no SIGSEGV anymore (b/162287616 fixed).
Change-Id: Ia1f8b8754b0d6ae75a2af33147645e744d593d82
parent a38a7a16
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -198,7 +198,10 @@ public class ImageReader implements AutoCloseable {
     *   {@link HardwareBuffer#USAGE_GPU_SAMPLED_IMAGE}, or combined</td>
     * </tr>
     * </table>
     * Using other combinations may result in {@link IllegalArgumentException}.
     * Using other combinations may result in {@link IllegalArgumentException}. Additionally,
     * specifying {@link HardwareBuffer#USAGE_CPU_WRITE_RARELY} or
     * {@link HardwareBuffer#USAGE_CPU_WRITE_OFTEN} and writing to the ImageReader's buffers
     * might break assumptions made by some producers, and should be used with caution.
     * </p>
     * <p>
     * If the {@link ImageReader} is used as an output target for a {@link
@@ -255,6 +258,7 @@ public class ImageReader implements AutoCloseable {
        mWidth = width;
        mHeight = height;
        mFormat = format;
        mUsage = usage;
        mMaxImages = maxImages;

        if (width < 1 || height < 1) {
@@ -768,6 +772,7 @@ public class ImageReader implements AutoCloseable {
    private final int mWidth;
    private final int mHeight;
    private final int mFormat;
    private final long mUsage;
    private final int mMaxImages;
    private final int mNumPlanes;
    private final Surface mSurface;
@@ -909,7 +914,8 @@ public class ImageReader implements AutoCloseable {
            throwISEIfImageIsInvalid();

            if (mPlanes == null) {
                mPlanes = nativeCreatePlanes(ImageReader.this.mNumPlanes, ImageReader.this.mFormat);
                mPlanes = nativeCreatePlanes(ImageReader.this.mNumPlanes, ImageReader.this.mFormat,
                        ImageReader.this.mUsage);
            }
            // Shallow copy is fine.
            return mPlanes.clone();
@@ -1038,7 +1044,7 @@ public class ImageReader implements AutoCloseable {
        private AtomicBoolean mIsDetached = new AtomicBoolean(false);

        private synchronized native SurfacePlane[] nativeCreatePlanes(int numPlanes,
                int readerFormat);
                int readerFormat, long readerUsage);
        private synchronized native int nativeGetWidth();
        private synchronized native int nativeGetHeight();
        private synchronized native int nativeGetFormat(int readerFormat);
+15 −6
Original line number Diff line number Diff line
@@ -675,7 +675,8 @@ static jobject ImageReader_getSurface(JNIEnv* env, jobject thiz)
    return android_view_Surface_createFromIGraphicBufferProducer(env, gbp);
}

static void Image_getLockedImage(JNIEnv* env, jobject thiz, LockedImage *image) {
static void Image_getLockedImage(JNIEnv* env, jobject thiz, LockedImage *image,
        uint64_t ndkReaderUsage) {
    ALOGV("%s", __FUNCTION__);
    BufferItem* buffer = Image_getBufferItem(env, thiz);
    if (buffer == NULL) {
@@ -684,8 +685,16 @@ static void Image_getLockedImage(JNIEnv* env, jobject thiz, LockedImage *image)
        return;
    }

    status_t res = lockImageFromBuffer(buffer,
            GRALLOC_USAGE_SW_READ_OFTEN, buffer->mFence->dup(), image);
    uint32_t lockUsage;
    if ((ndkReaderUsage & (AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY
            | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN)) != 0) {
        lockUsage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;
    } else {
        lockUsage = GRALLOC_USAGE_SW_READ_OFTEN;
    }

    status_t res = lockImageFromBuffer(buffer, lockUsage, buffer->mFence->dup(), image);

    if (res != OK) {
        jniThrowExceptionFmt(env, "java/lang/RuntimeException",
                "lock buffer failed for format 0x%x",
@@ -721,7 +730,7 @@ static bool Image_getLockedImageInfo(JNIEnv* env, LockedImage* buffer, int idx,
}

static jobjectArray Image_createSurfacePlanes(JNIEnv* env, jobject thiz,
        int numPlanes, int readerFormat)
        int numPlanes, int readerFormat, uint64_t ndkReaderUsage)
{
    ALOGV("%s: create SurfacePlane array with size %d", __FUNCTION__, numPlanes);
    int rowStride = 0;
@@ -754,7 +763,7 @@ static jobjectArray Image_createSurfacePlanes(JNIEnv* env, jobject thiz,
    }

    LockedImage lockedImg = LockedImage();
    Image_getLockedImage(env, thiz, &lockedImg);
    Image_getLockedImage(env, thiz, &lockedImg, ndkReaderUsage);
    if (env->ExceptionCheck()) {
        return NULL;
    }
@@ -839,7 +848,7 @@ static const JNINativeMethod gImageReaderMethods[] = {
};

static const JNINativeMethod gImageMethods[] = {
    {"nativeCreatePlanes",      "(II)[Landroid/media/ImageReader$SurfaceImage$SurfacePlane;",
    {"nativeCreatePlanes",      "(IIJ)[Landroid/media/ImageReader$SurfaceImage$SurfacePlane;",
                                                             (void*)Image_createSurfacePlanes },
    {"nativeGetWidth",          "()I",                       (void*)Image_getWidth },
    {"nativeGetHeight",         "()I",                       (void*)Image_getHeight },