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

Commit b721b3f2 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Camera: Bump the thread priority during stream configuration and open" into 24D1-dev

parents 55d842d8 1eeb251f
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -143,3 +143,13 @@ flag {
     description: "Enables 10-bit support in the camera extensions."
     bug: "316375635"
}

flag {
     namespace: "camera_platform"
     name: "realtime_priority_bump"
     description: "Bump the scheduling priority of performance critical code paths"
     bug: "336628522"
     metadata {
       purpose: PURPOSE_BUGFIX
     }
}
+5 −3
Original line number Diff line number Diff line
@@ -80,11 +80,12 @@
#include "CameraService.h"
#include "api1/Camera2Client.h"
#include "api2/CameraDeviceClient.h"
#include "utils/CameraTraces.h"
#include "utils/TagMonitor.h"
#include "utils/CameraThreadState.h"
#include "utils/CameraServiceProxyWrapper.h"
#include "utils/CameraThreadState.h"
#include "utils/CameraTraces.h"
#include "utils/SessionConfigurationUtils.h"
#include "utils/TagMonitor.h"
#include "utils/Utils.h"

namespace {
    const char* kPermissionServiceName = "permission";
@@ -2306,6 +2307,7 @@ Status CameraService::connectDevice(
        sp<hardware::camera2::ICameraDeviceUser>* device) {

    ATRACE_CALL();
    RunThreadWithRealtimePriority priorityBump;
    Status ret = Status::ok();
    sp<CameraDeviceClient> client = nullptr;
    std::string clientPackageNameAdj = clientPackageName;
+33 −71
Original line number Diff line number Diff line
@@ -2388,46 +2388,15 @@ 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();
    status_t res;
    // Stream/surface setup can include a lot of binder IPC. Raise the
    // thread priority when running the binder IPC heavy configuration
    // sequence.
    RunThreadWithRealtimePriority priorityBump;

    if (mStatus != STATUS_UNCONFIGURED && mStatus != STATUS_CONFIGURED) {
        CLOGE("Not idle");
@@ -2620,12 +2589,6 @@ 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
@@ -2634,8 +2597,8 @@ status_t Camera3Device::configureStreamsLocked(int operatingMode,
        bool streamReConfigured = false;
        res = mInputStream->finishConfiguration(&streamReConfigured);
        if (res != OK) {
                CLOGE("Can't finish configuring input stream %d: %s (%d)",
                        mInputStream->getId(), strerror(-res), res);
            CLOGE("Can't finish configuring input stream %d: %s (%d)", mInputStream->getId(),
                  strerror(-res), res);
            cancelStreamsConfigurationLocked();
            if ((res == NO_INIT || res == DEAD_OBJECT) && mInputStream->isAbandoned()) {
                return DEAD_OBJECT;
@@ -2653,8 +2616,8 @@ status_t Camera3Device::configureStreamsLocked(int operatingMode,
            bool streamReConfigured = false;
            res = outputStream->finishConfiguration(&streamReConfigured);
            if (res != OK) {
                    CLOGE("Can't finish configuring output stream %d: %s (%d)",
                            outputStream->getId(), strerror(-res), res);
                CLOGE("Can't finish configuring output stream %d: %s (%d)", outputStream->getId(),
                      strerror(-res), res);
                cancelStreamsConfigurationLocked();
                if ((res == NO_INIT || res == DEAD_OBJECT) && outputStream->isAbandoned()) {
                    return DEAD_OBJECT;
@@ -2666,7 +2629,6 @@ status_t Camera3Device::configureStreamsLocked(int operatingMode,
            }
        }
    }
    }

    mRequestThread->setComposerSurface(mComposerOutput);

@@ -2683,8 +2645,8 @@ status_t Camera3Device::configureStreamsLocked(int operatingMode,
    if (disableFifo != 1) {
        // Boost priority of request thread to SCHED_FIFO.
        pid_t requestThreadTid = mRequestThread->getTid();
        res = SchedulingPolicyUtils::requestPriorityDirect(getpid(), requestThreadTid,
                kRequestThreadPriority);
        res = SchedulingPolicyUtils::requestPriorityDirect(
                getpid(), requestThreadTid, RunThreadWithRealtimePriority::kRequestThreadPriority);
        if (res != OK) {
            ALOGW("Can't set realtime priority for request processing thread: %s (%d)",
                    strerror(-res), res);
+0 −30
Original line number Diff line number Diff line
@@ -361,8 +361,6 @@ class Camera3Device :
    static const size_t        kInFlightWarnLimitHighSpeed = 256; // batch size 32 * pipe depth 8
    static const nsecs_t       kMinInflightDuration = 5000000000; // 5 s
    static const nsecs_t       kBaseGetBufferWait = 3000000000; // 3 sec.
    // SCHED_FIFO priority for request submission thread in HFR mode
    static const int           kRequestThreadPriority = 1;

    struct                     RequestTrigger;
    // minimal jpeg buffer size: 256KB + blob header
@@ -1610,34 +1608,6 @@ 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

+39 −3
Original line number Diff line number Diff line
@@ -14,14 +14,17 @@
 * limitations under the License.
 */

#define LOG_TAG "Camera3-Utils"

#include "Utils.h"
#include <android-base/properties.h>
#include <com_android_internal_camera_flags.h>

#include <utils/Errors.h>
#include <utils/Log.h>

namespace android {

using namespace com::android::internal::camera::flags;
namespace flags = com::android::internal::camera::flags;

constexpr const char *LEGACY_VNDK_VERSION_PROP = "ro.vndk.version";
constexpr const char *BOARD_API_LEVEL_PROP = "ro.board.api_level";
@@ -52,4 +55,37 @@ int getVNDKVersionFromProp(int defaultVersion) {
    return __ANDROID_API_V__ + vndkVersion;
}

RunThreadWithRealtimePriority::RunThreadWithRealtimePriority(int tid)
    : mTid(tid), mPreviousPolicy(sched_getscheduler(tid)) {
    if (flags::realtime_priority_bump()) {
        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;
        }
    }
}

RunThreadWithRealtimePriority::~RunThreadWithRealtimePriority() {
    if (mPolicyBumped && flags::realtime_priority_bump()) {
        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);
        }
    }
}

}  // namespace android
Loading