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

Commit 8b60c745 authored by Sally Qi's avatar Sally Qi Committed by Android (Google) Code Review
Browse files

Merge "Add fence support in ImageWriter class."

parents 3e6933f1 d2087e77
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -17054,6 +17054,14 @@ package android.hardware {
    field public static final int MICROPHONE = 1; // 0x1
  }
  public final class SyncFence implements java.io.Closeable android.os.Parcelable {
    method public void close() throws java.io.IOException;
    method public int describeContents();
    method public boolean isValid();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.hardware.SyncFence> CREATOR;
  }
  public final class TriggerEvent {
    field public android.hardware.Sensor sensor;
    field public long timestamp;
@@ -20829,6 +20837,7 @@ package android.media {
    method public abstract void close();
    method public android.graphics.Rect getCropRect();
    method public long getDataSpace();
    method @NonNull public android.hardware.SyncFence getFence() throws java.io.IOException;
    method public abstract int getFormat();
    method @Nullable public android.hardware.HardwareBuffer getHardwareBuffer();
    method public abstract int getHeight();
@@ -20837,6 +20846,7 @@ package android.media {
    method public abstract int getWidth();
    method public void setCropRect(android.graphics.Rect);
    method public void setDataSpace(long);
    method public void setFence(@NonNull android.hardware.SyncFence) throws java.io.IOException;
    method public void setTimestamp(long);
  }
+141 −0
Original line number Diff line number Diff line
/**
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.hardware;

import android.annotation.NonNull;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.Parcelable;

import java.io.Closeable;
import java.io.IOException;

/**
 * A SyncFence represents a synchronization primitive which signals when hardware buffers have
 * completed work on a particular resource.
 *
 * <p>For example, a GPU rendering to a framebuffer may generate a synchronization fence,
 * e.g., a VkFence, which signals when rendering has completed.
 *
 * Once the fence signals, then the backing storage for the framebuffer may be safely read from,
 * such as for display or for media encoding.</p>
 *
 * @see <a href="https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkCreateFence.html">
 * VkFence</a>
 */
public final class SyncFence implements Closeable, Parcelable {
    private static final String TAG = "SyncFence";

    /**
     * Wrapped {@link android.os.ParcelFileDescriptor}.
     */
    private ParcelFileDescriptor mWrapped;

    private SyncFence(@NonNull ParcelFileDescriptor wrapped) {
        mWrapped = wrapped;
    }

    /***
     * Create an empty SyncFence
     *
     * @return a SyncFence with invalid fence
     * @hide
     */
    public static @NonNull SyncFence createEmpty() {
        return new SyncFence(ParcelFileDescriptor.adoptFd(-1));
    }

    /**
     * Create a new SyncFence wrapped around another descriptor. By default, all method calls are
     * delegated to the wrapped descriptor.
     *
     * @param wrapped The descriptor to be wrapped.
     * @hide
     */
    public static @NonNull SyncFence create(@NonNull ParcelFileDescriptor wrapped) {
        return new SyncFence(wrapped);
    }

    /**
     * Return a dup'd ParcelFileDescriptor from the SyncFence ParcelFileDescriptor.
     * @hide
     */
    public @NonNull ParcelFileDescriptor getFdDup() throws IOException {
        return mWrapped.dup();
    }

    /**
     * Checks if the SyncFile object is valid.
     *
     * @return {@code true} if the file descriptor represents a valid, open file;
     *         {@code false} otherwise.
     */
    public boolean isValid() {
        return mWrapped.getFileDescriptor().valid();
    }

    /**
     * Close the SyncFence. This implementation closes the underlying OS resources allocated
     * this stream.
     *
     * @throws IOException If an error occurs attempting to close this SyncFence.
     */
    @Override
    public void close() throws IOException {
        if (mWrapped != null) {
            try {
                mWrapped.close();
            } finally {
                // success
            }
        }
    }

    @Override
    public int describeContents() {
        return mWrapped.describeContents();
    }

    /**
     * Flatten this object into a Parcel.
     *
     * @param out The Parcel in which the object should be written.
     * @param flags Additional flags about how the object should be written.
     *              May be {@code 0} or {@link #PARCELABLE_WRITE_RETURN_VALUE}
     */
    @Override
    public void writeToParcel(@NonNull Parcel out, int flags) {
        try {
            mWrapped.writeToParcel(out, flags);
        } finally {
            // success
        }
    }

    public static final @NonNull Parcelable.Creator<SyncFence> CREATOR =
            new Parcelable.Creator<SyncFence>() {
        @Override
        public SyncFence createFromParcel(Parcel in) {
            return new SyncFence(ParcelFileDescriptor.CREATOR.createFromParcel(in));
        }

        @Override
        public SyncFence[] newArray(int size) {
            return new SyncFence[size];
        }
    };
}
+7 −6
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.annotation.RequiresPermission;
import android.content.Context;
import android.graphics.ImageFormat;
import android.graphics.SurfaceTexture;
import android.hardware.SyncFence;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
@@ -58,7 +59,6 @@ import android.media.ImageReader;
import android.os.Binder;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.util.Log;
import android.util.Size;
@@ -822,13 +822,14 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes

            ParcelImage parcelImage = new ParcelImage();
            parcelImage.buffer = img.getHardwareBuffer();
            if (img.getFenceFd() >= 0) {
            try {
                    parcelImage.fence = ParcelFileDescriptor.fromFd(img.getFenceFd());
                SyncFence fd = img.getFence();
                if (fd.isValid()) {
                    parcelImage.fence = fd.getFdDup();
                }
            } catch (IOException e) {
                Log.e(TAG, "Failed to parcel buffer fence!");
            }
            }
            parcelImage.width = img.getWidth();
            parcelImage.height = img.getHeight();
            parcelImage.format = img.getFormat();
+11 −10
Original line number Diff line number Diff line
@@ -16,10 +16,14 @@

package android.hardware.camera2.impl;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.content.Context;
import android.graphics.ImageFormat;
import android.graphics.SurfaceTexture;
import android.hardware.HardwareBuffer;
import android.hardware.SyncFence;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
@@ -30,6 +34,7 @@ import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CaptureFailure;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
import android.hardware.camera2.extension.CaptureBundle;
import android.hardware.camera2.extension.CaptureStageImpl;
import android.hardware.camera2.extension.ICaptureProcessorImpl;
@@ -39,7 +44,6 @@ import android.hardware.camera2.extension.IPreviewExtenderImpl;
import android.hardware.camera2.extension.IProcessResultImpl;
import android.hardware.camera2.extension.IRequestUpdateProcessorImpl;
import android.hardware.camera2.extension.ParcelImage;
import android.hardware.camera2.TotalCaptureResult;
import android.hardware.camera2.params.DynamicRangeProfiles;
import android.hardware.camera2.params.ExtensionSessionConfiguration;
import android.hardware.camera2.params.OutputConfiguration;
@@ -51,11 +55,7 @@ import android.media.ImageWriter;
import android.os.Binder;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.util.Log;
import android.util.LongSparseArray;
import android.util.Pair;
@@ -1768,13 +1768,14 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
    private static ParcelImage initializeParcelImage(Image img) {
        ParcelImage parcelImage = new ParcelImage();
        parcelImage.buffer = img.getHardwareBuffer();
        if (img.getFenceFd() >= 0) {
        try {
                parcelImage.fence = ParcelFileDescriptor.fromFd(img.getFenceFd());
            SyncFence fd = img.getFence();
            if (fd.isValid()) {
                parcelImage.fence = fd.getFdDup();
            }
        } catch (IOException e) {
            Log.e(TAG, "Failed to parcel buffer fence!");
        }
        }
        parcelImage.width = img.getWidth();
        parcelImage.height = img.getHeight();
        parcelImage.format = img.getFormat();
+24 −5
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.media;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.annotation.TestApi;
@@ -24,7 +25,9 @@ import android.graphics.Rect;
import android.hardware.DataSpace;
import android.hardware.DataSpace.NamedDataSpace;
import android.hardware.HardwareBuffer;
import android.hardware.SyncFence;

import java.io.IOException;
import java.nio.ByteBuffer;

/**
@@ -223,12 +226,17 @@ public abstract class Image implements AutoCloseable {
    public abstract int getScalingMode();

    /**
     * Get the fence file descriptor associated with this frame.
     * @return The fence file descriptor for this frame.
     * @hide
     * Get the SyncFence object associated with this frame.
     *
     * <p>This function returns an invalid SyncFence after {@link #getPlanes()} on the image
     * dequeued from {@link ImageWriter} via {@link ImageWriter#dequeueInputImage()}.</p>
     *
     * @return The SyncFence for this frame.
     * @throws IOException if there is an error when a SyncFence object returns.
     * @see android.hardware.SyncFence
     */
    public int getFenceFd() {
        return -1;
    public @NonNull SyncFence getFence() throws IOException {
        return SyncFence.createEmpty();
    }

    /**
@@ -283,6 +291,17 @@ public abstract class Image implements AutoCloseable {
        return;
    }

    /**
     * Set the fence file descriptor with this frame.
     * @param fence The fence file descriptor to be set for this frame.
     * @throws IOException if there is an error when setting a SyncFence.
     * @see android.hardware.SyncFence
     */
    public void setFence(@NonNull SyncFence fence) throws IOException {
        throwISEIfImageIsInvalid();
        return;
    }

    private @NamedDataSpace long mDataSpace = DataSpace.DATASPACE_UNKNOWN;

    /**
Loading