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

Commit 3b93acb2 authored by Emilian Peev's avatar Emilian Peev
Browse files

Camera: Cache and defer Surface binder IPC calls

Try to cache and defer Surface related IPC configuration
calls. Specifically:
1) Avoid retrieving the consumer name until dump
2) Cache and re-use the surface consumer usage value
3) Configure the producer max undequeued buffer count
   instead of the total buffer count
Additionally, raise the stream configuration thread
prioirty during the binder IPC intensive stream/surface
setup.

Bug: 323292530
Test: Manual using camera application,
adb shell dumpsys media.camera

Change-Id: Ibf4149a2b1fb8e5a5e357fa6e2360c70a743413d
parent 58935670
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -135,6 +135,16 @@ flag {
     bug: "282814430"
}

flag {
     namespace: "camera_platform"
     name: "surface_ipc"
     description: "Optimize Surface binder IPC"
     bug: "323292530"
     metadata {
       purpose: PURPOSE_BUGFIX
     }
}

flag {
     namespace: "camera_platform"
     name: "extension_10_bit"
+1 −0
Original line number Diff line number Diff line
@@ -5,5 +5,6 @@ service cameraserver /system/bin/cameraserver
    ioprio rt 4
    task_profiles CameraServiceCapacity MaxPerformance
    rlimit rtprio 10 10
    capabilities SYS_NICE
    onrestart class_restart cameraWatchdog
    interface aidl android.frameworks.cameraservice.service.ICameraService/default
+72 −27
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@
#include <utility>

#include <android-base/stringprintf.h>
#include <sched.h>
#include <utils/Log.h>
#include <utils/Trace.h>
#include <utils/Timers.h>
@@ -2387,6 +2388,42 @@ bool Camera3Device::reconfigureCamera(const CameraMetadata& sessionParams, int c
    return ret;
}

Camera3Device::RunThreadWithRealtimePriority::RunThreadWithRealtimePriority(int tid) : mTid(tid),
        mPreviousPolicy(sched_getscheduler(tid)) {
    if (flags::surface_ipc()) {
        auto res = sched_getparam(mTid, &mPreviousParams);
        if (res != OK) {
            ALOGE("Can't retrieve thread scheduler parameters: %s (%d)",
                    strerror(-res), res);
            return;
        }

        struct sched_param param = {0};
        param.sched_priority = kRequestThreadPriority;

        res = sched_setscheduler(mTid, SCHED_FIFO, &param);
        if (res != OK) {
            ALOGW("Can't set realtime priority for thread: %s (%d)",
                    strerror(-res), res);
        } else {
            ALOGD("Set real time priority for thread (tid %d)", mTid);
            mPolicyBumped = true;
        }
    }
}

Camera3Device::RunThreadWithRealtimePriority::~RunThreadWithRealtimePriority() {
    if (mPolicyBumped && flags::surface_ipc()) {
        auto res = sched_setscheduler(mTid, mPreviousPolicy, &mPreviousParams);
        if (res != OK) {
            ALOGE("Can't set regular priority for thread: %s (%d)",
                    strerror(-res), res);
        } else {
            ALOGD("Set regular priority for thread (tid %d)", mTid);
        }
    }
}

status_t Camera3Device::configureStreamsLocked(int operatingMode,
        const CameraMetadata& sessionParams, bool notifyRequestThread) {
    ATRACE_CALL();
@@ -2582,6 +2619,13 @@ status_t Camera3Device::configureStreamsLocked(int operatingMode,
        }
        mRequestThread->setHalBufferManagedStreams(mHalBufManagedStreamIds);
    }

    {
        // Stream/surface setup can include a lot of binder IPC. Raise the
        // thread priority when running the binder IPC heavy configuration
        // sequence.
        RunThreadWithRealtimePriority priorityBump;

        // Finish all stream configuration immediately.
        // TODO: Try to relax this later back to lazy completion, which should be
        // faster
@@ -2622,6 +2666,7 @@ status_t Camera3Device::configureStreamsLocked(int operatingMode,
                }
            }
        }
    }

    mRequestThread->setComposerSurface(mComposerOutput);

+29 −0
Original line number Diff line number Diff line
@@ -1610,6 +1610,35 @@ class Camera3Device :

    void overrideStreamUseCaseLocked();

    // An instance of this class will raise the scheduling policy of a given
    // given thread to real time and keep it this way throughout the lifetime
    // of the object. The thread scheduling policy will revert back to its original
    // state after the instances is released. By default the implementation will
    // raise the priority of the current thread unless clients explicitly specify
    // another thread id.
    // Client must avoid:
    //  - Keeping an instance of this class for extended and long running operations.
    //    This is only intended for short/temporarily priority bumps that mitigate
    //    scheduling delays within critical camera paths.
    //  - Allocating instances of this class on the memory heap unless clients have
    //    complete control over the object lifetime. It is preferable to allocate
    //    instances of this class on the stack instead.
    //  - Nesting multiple instances of this class using the same default or same thread id.
    class RunThreadWithRealtimePriority final {
        public:
            RunThreadWithRealtimePriority(int tid = gettid());
            ~RunThreadWithRealtimePriority();

            RunThreadWithRealtimePriority(const RunThreadWithRealtimePriority&) = delete;
            RunThreadWithRealtimePriority& operator=(const RunThreadWithRealtimePriority&) = delete;

        private:
            int mTid;
            int mPreviousPolicy;
            bool mPolicyBumped = false;
            struct sched_param mPreviousParams;
    };

}; // class Camera3Device

}; // namespace android
+3 −3
Original line number Diff line number Diff line
@@ -68,7 +68,7 @@ status_t Camera3FakeStream::returnBufferCheckedLocked(
    return INVALID_OPERATION;
}

void Camera3FakeStream::dump(int fd, [[maybe_unused]] const Vector<String16> &args) const {
void Camera3FakeStream::dump(int fd, [[maybe_unused]] const Vector<String16> &args) {
    std::string lines;
    lines += fmt::sprintf("    Stream[%d]: Fake\n", mId);
    write(fd, lines.c_str(), lines.size());
@@ -99,12 +99,12 @@ status_t Camera3FakeStream::disconnectLocked() {
    return OK;
}

status_t Camera3FakeStream::getEndpointUsage(uint64_t *usage) const {
status_t Camera3FakeStream::getEndpointUsage(uint64_t *usage) {
    *usage = FAKE_USAGE;
    return OK;
}

bool Camera3FakeStream::isVideoStream() const {
bool Camera3FakeStream::isVideoStream() {
    return false;
}

Loading