Loading camera/camera_platform.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -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 } } services/camera/libcameraservice/CameraService.cpp +5 −3 Original line number Diff line number Diff line Loading @@ -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"; Loading Loading @@ -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; Loading services/camera/libcameraservice/device3/Camera3Device.cpp +33 −71 Original line number Diff line number Diff line Loading @@ -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, ¶m); 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"); Loading Loading @@ -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 Loading @@ -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; Loading @@ -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; Loading @@ -2666,7 +2629,6 @@ status_t Camera3Device::configureStreamsLocked(int operatingMode, } } } } mRequestThread->setComposerSurface(mComposerOutput); Loading @@ -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); Loading services/camera/libcameraservice/device3/Camera3Device.h +0 −30 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading services/camera/libcameraservice/utils/Utils.cpp +39 −3 Original line number Diff line number Diff line Loading @@ -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"; Loading Loading @@ -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, ¶m); 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
camera/camera_platform.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -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 } }
services/camera/libcameraservice/CameraService.cpp +5 −3 Original line number Diff line number Diff line Loading @@ -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"; Loading Loading @@ -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; Loading
services/camera/libcameraservice/device3/Camera3Device.cpp +33 −71 Original line number Diff line number Diff line Loading @@ -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, ¶m); 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"); Loading Loading @@ -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 Loading @@ -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; Loading @@ -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; Loading @@ -2666,7 +2629,6 @@ status_t Camera3Device::configureStreamsLocked(int operatingMode, } } } } mRequestThread->setComposerSurface(mComposerOutput); Loading @@ -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); Loading
services/camera/libcameraservice/device3/Camera3Device.h +0 −30 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading
services/camera/libcameraservice/utils/Utils.cpp +39 −3 Original line number Diff line number Diff line Loading @@ -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"; Loading Loading @@ -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, ¶m); 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