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

Commit 07ad459c authored by Eino-Ville Talvala's avatar Eino-Ville Talvala
Browse files

ImageWriter: Attach non-opaque Images as well.

With all the work under the hood of ImageReader/Writer in the last few
releases, this is much more straightforward to enable.

Only trick is to ensure that the Image detached from the ImageReader
correctly clears out its planes, if present.

Bug: 19962027
Test: Camera CTS still passes on angler, sailfish, ryu
Change-Id: Ic8a1f3e2f45cf15971d76e308a5af25eb2fd66f1
parent e2445740
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -705,6 +705,8 @@ public class ImageReader implements AutoCloseable {
        }

        nativeDetachImage(image);
        si.clearSurfacePlanes();
        si.mPlanes = null;
        si.setDetached(true);
    }

+8 −22
Original line number Diff line number Diff line
@@ -359,12 +359,7 @@ public class ImageWriter implements AutoCloseable {
            }

            ImageReader prevOwner = (ImageReader) image.getOwner();
            // Only do the image attach for PRIVATE format images for now. Do the image
            // copy for other formats. TODO: use attach for other formats to
            // improve the performance, and fall back to copy when attach/detach
            // fails. Right now, detach is guaranteed to fail as the buffer is
            // locked when ImageReader#acquireNextImage is called. See bug 19962027.
            if (image.getFormat() == ImageFormat.PRIVATE) {

            prevOwner.detachImage(image);
            attachAndQueueInputImage(image);
            // This clears the native reference held by the original owner.
@@ -372,15 +367,6 @@ public class ImageWriter implements AutoCloseable {
            // native memory won't be leaked.
            image.close();
            return;
            } else {
                Image inputImage = dequeueInputImage();
                inputImage.setTimestamp(image.getTimestamp());
                inputImage.setCropRect(image.getCropRect());
                ImageUtils.imageCopy(image, inputImage);
                image.close();
                image = inputImage;
                ownedByMe = true;
            }
        }

        Rect crop = image.getCropRect();
+6 −14
Original line number Diff line number Diff line
@@ -499,30 +499,23 @@ static jint ImageWriter_attachAndQueueImage(JNIEnv* env, jobject thiz, jlong nat

    sp<Surface> surface = ctx->getProducer();
    status_t res = OK;
    if (!isFormatOpaque(imageFormat)) {
        // TODO: need implement, see b/19962027
        jniThrowRuntimeException(env,
                "nativeAttachImage for non-opaque image is not implement yet!!!");
        return -1;
    }

    if (!isFormatOpaque(ctx->getBufferFormat())) {
    if (isFormatOpaque(imageFormat) != isFormatOpaque(ctx->getBufferFormat())) {
        jniThrowException(env, "java/lang/IllegalStateException",
                "Trying to attach an opaque image into a non-opaque ImageWriter");
                "Trying to attach an opaque image into a non-opaque ImageWriter, or vice versa");
        return -1;
    }

    // Image is guaranteed to be from ImageReader at this point, so it is safe to
    // cast to BufferItem pointer.
    BufferItem* opaqueBuffer = reinterpret_cast<BufferItem*>(nativeBuffer);
    if (opaqueBuffer == NULL) {
    BufferItem* buffer = reinterpret_cast<BufferItem*>(nativeBuffer);
    if (buffer == NULL) {
        jniThrowException(env, "java/lang/IllegalStateException",
                "Image is not initialized or already closed");
        return -1;
    }

    // Step 1. Attach Image
    res = surface->attachBuffer(opaqueBuffer->mGraphicBuffer.get());
    res = surface->attachBuffer(buffer->mGraphicBuffer.get());
    if (res != OK) {
        ALOGE("Attach image failed: %s (%d)", strerror(-res), res);
        switch (res) {
@@ -559,7 +552,7 @@ static jint ImageWriter_attachAndQueueImage(JNIEnv* env, jobject thiz, jlong nat
    }

    // Step 3. Queue Image.
    res = anw->queueBuffer(anw.get(), opaqueBuffer->mGraphicBuffer.get(), /*fenceFd*/
    res = anw->queueBuffer(anw.get(), buffer->mGraphicBuffer.get(), /*fenceFd*/
            -1);
    if (res != OK) {
        ALOGE("%s: Queue buffer failed: %s (%d)", __FUNCTION__, strerror(-res), res);
@@ -817,4 +810,3 @@ int register_android_media_ImageWriter(JNIEnv *env) {

    return (ret1 || ret2);
}