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

Commit bd07f846 authored by Yin-Chia Yeh's avatar Yin-Chia Yeh Committed by Android (Google) Code Review
Browse files

Merge changes from topics 'cam-hidl-fence', 'camera-hidl-bufId'

* changes:
  Camera: make fence import agnostic to hidl transport
  Camera: add bufferId field to StreamBuffer
parents 879e6c56 a8f447d7
Loading
Loading
Loading
Loading
+14 −17
Original line number Diff line number Diff line
@@ -94,15 +94,7 @@ public:
        if (handle == nullptr || handle->numFds == 0) {
            fd = -1;
        } else if (handle->numFds == 1) {
//TODO(b/34110242): make this hidl transport agnostic
#ifdef BINDERIZED
            fd = dup(handle->data[0]);
            // TODO(b/34169301)
            // Camera service expect FD be closed by HAL process (in passthrough mode)
            // close(handle->data[0]);
#else
            fd = handle->data[0];
#endif
            if (fd < 0) {
                ALOGE("failed to dup fence fd %d", handle->data[0]);
                return false;
@@ -118,13 +110,9 @@ public:

    void closeFence(int fd)
    {
#ifdef BINDERIZED
        if (fd >= 0) {
            close(fd);
        }
#else
        (void) fd;
#endif
    }

private:
@@ -307,31 +295,40 @@ Status CameraDeviceSession::importRequest(
        hidl_vec<buffer_handle_t*>& allBufPtrs,
        hidl_vec<int>& allFences) {
    bool hasInputBuf = (request.inputBuffer.streamId != -1 &&
            request.inputBuffer.buffer.getNativeHandle() != nullptr);
            request.inputBuffer.bufferId != 0);
    size_t numOutputBufs = request.outputBuffers.size();
    size_t numBufs = numOutputBufs + (hasInputBuf ? 1 : 0);
    // Validate all I/O buffers
    hidl_vec<buffer_handle_t> allBufs;
    hidl_vec<uint64_t> allBufIds;
    allBufs.resize(numBufs);
    allBufIds.resize(numBufs);
    allBufPtrs.resize(numBufs);
    allFences.resize(numBufs);
    std::vector<int32_t> streamIds(numBufs);

    for (size_t i = 0; i < numOutputBufs; i++) {
        allBufs[i] = request.outputBuffers[i].buffer.getNativeHandle();
        allBufIds[i] = request.outputBuffers[i].bufferId;
        allBufPtrs[i] = &allBufs[i];
        streamIds[i] = request.outputBuffers[i].streamId;
    }
    if (hasInputBuf) {
        allBufs[numOutputBufs] = request.inputBuffer.buffer.getNativeHandle();
        allBufIds[numOutputBufs] = request.inputBuffer.bufferId;
        allBufPtrs[numOutputBufs] = &allBufs[numOutputBufs];
        streamIds[numOutputBufs] = request.inputBuffer.streamId;
    }

    for (size_t i = 0; i < numBufs; i++) {
        buffer_handle_t buf = allBufs[i];
        uint64_t bufId = allBufIds[i];
        CirculatingBuffers& cbs = mCirculatingBuffers[streamIds[i]];
        if (cbs.count(buf) == 0) {
        if (cbs.count(bufId) == 0) {
            if (buf == nullptr) {
                ALOGE("%s: bufferId %" PRIu64 " has null buffer handle!", __FUNCTION__, bufId);
                return Status::ILLEGAL_ARGUMENT;
            }
            // Register a newly seen buffer
            buffer_handle_t importedBuf = buf;
            sHandleImporter.importBuffer(importedBuf);
@@ -339,10 +336,10 @@ Status CameraDeviceSession::importRequest(
                ALOGE("%s: output buffer %zu is invalid!", __FUNCTION__, i);
                return Status::INTERNAL_ERROR;
            } else {
                cbs[buf] = importedBuf;
                cbs[bufId] = importedBuf;
            }
        }
        allBufPtrs[i] = &cbs[buf];
        allBufPtrs[i] = &cbs[bufId];
    }

    // All buffers are imported. Now validate output buffer acquire fences
@@ -509,7 +506,7 @@ Return<Status> CameraDeviceSession::processCaptureRequest(const CaptureRequest&
    hidl_vec<buffer_handle_t*> allBufPtrs;
    hidl_vec<int> allFences;
    bool hasInputBuf = (request.inputBuffer.streamId != -1 &&
            request.inputBuffer.buffer.getNativeHandle() != nullptr);
            request.inputBuffer.bufferId != 0);
    size_t numOutputBufs = request.outputBuffers.size();
    size_t numBufs = numOutputBufs + (hasInputBuf ? 1 : 0);
    status = importRequest(request, allBufPtrs, allFences);
+2 −34
Original line number Diff line number Diff line
@@ -100,44 +100,12 @@ private:
    // (streamID, frameNumber) -> inflight buffer cache
    std::map<std::pair<int, uint32_t>, camera3_stream_buffer_t>  mInflightBuffers;

    struct BufferHasher {
        size_t operator()(const buffer_handle_t& buf) const {
            if (buf == nullptr)
                return 0;

            size_t result = 1;
            result = 31 * result + buf->numFds;
            result = 31 * result + buf->numInts;
            int length = buf->numFds + buf->numInts;
            for (int i = 0; i < length; i++) {
                result = 31 * result + buf->data[i];
            }
            return result;
        }
    };

    struct BufferComparator {
        bool operator()(const buffer_handle_t& buf1, const buffer_handle_t& buf2) const {
            if (buf1->numFds == buf2->numFds && buf1->numInts == buf2->numInts) {
                int length = buf1->numFds + buf1->numInts;
                for (int i = 0; i < length; i++) {
                    if (buf1->data[i] != buf2->data[i]) {
                        return false;
                    }
                }
                return true;
            }
            return false;
        }
    };

    // buffers currently ciculating between HAL and camera service
    // key: buffer_handle_t sent via HIDL interface
    // key: bufferId sent via HIDL interface
    // value: imported buffer_handle_t
    // Buffer will be imported during process_capture_request and will be freed
    // when the its stream is deleted or camera device session is closed
    typedef std::unordered_map<buffer_handle_t, buffer_handle_t,
            BufferHasher, BufferComparator> CirculatingBuffers;
    typedef std::unordered_map<uint64_t, buffer_handle_t> CirculatingBuffers;
    // Stream ID -> circulating buffers map
    std::map<int, CirculatingBuffers> mCirculatingBuffers;

+20 −3
Original line number Diff line number Diff line
@@ -405,16 +405,33 @@ struct StreamBuffer {
    /**
     * The ID of the stream this buffer is associated with. -1 indicates an
     * invalid (empty) StreamBuffer, in which case buffer must also point to
     * null.
     * null and bufferId must be 0.
     */
    int32_t streamId;

    /**
     * The unique ID of the buffer within this StreamBuffer. 0 indicates this
     * StreamBuffer contains no buffer.
     * For StreamBuffers sent to the HAL in a CaptureRequest, this ID uniquely
     * identifies a buffer. When a buffer is sent to HAL for the first time,
     * both bufferId and buffer handle must be filled. HAL must keep track of
     * the mapping between bufferId and corresponding buffer until the
     * corresponding stream is removed from stream configuration or until camera
     * device session is closed. After the first time a buffer is introduced to
     * HAL, in the future camera service must refer to the same buffer using
     * only bufferId, and keep the buffer handle null.
     */
    uint64_t bufferId;

    /**
     * The graphics buffer handle to the buffer.
     *
     * For StreamBuffers sent to the HAL in a CaptureRequest, this must be a
     * For StreamBuffers sent to the HAL in a CaptureRequest, if the bufferId
     * is not seen by the HAL before, this buffer handle is guaranteed to be a
     * valid handle to a graphics buffer, with dimensions and format matching
     * that of the stream.
     * that of the stream. If the bufferId has been sent to the HAL before, this
     * buffer handle must be null and HAL must look up the actual buffer handle
     * to use from its own bufferId to buffer handle map.
     *
     * For StreamBuffers returned in a CaptureResult, this must be null, since
     * the handle to the buffer is already known to the client (since the client