diff options
author | 2024-02-16 10:57:40 -0500 | |
---|---|---|
committer | 2024-03-06 15:40:25 -0500 | |
commit | efb131e3e11bfc12df020d4100b67c49be7c1f27 (patch) | |
tree | 3b8b8c3da5e5bbd70e8d12710b7072af9f58b181 | |
parent | 31dafa390a7b7aa399e8554fc1be7f9ab1b5cd30 (diff) |
SF: Remove StartPropertySetThread
Reimplement with std::async and std::future to cut the boilerplate, and
remove the dependency on the deprecated Thread class from libutils.
Bug: 324366212
Test: Boot.
Test: adb shell killall system_server
Change-Id: Id39dab356cc267f1575bba4010f3b161c1d0923c
-rw-r--r-- | services/surfaceflinger/Android.bp | 1 | ||||
-rw-r--r-- | services/surfaceflinger/StartPropertySetThread.cpp | 41 | ||||
-rw-r--r-- | services/surfaceflinger/StartPropertySetThread.h | 46 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 56 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 14 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp | 6 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlingerDefaultFactory.h | 1 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlingerFactory.h | 3 | ||||
-rw-r--r-- | services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h | 5 |
9 files changed, 39 insertions, 134 deletions
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp index d77180362b..2a4327f696 100644 --- a/services/surfaceflinger/Android.bp +++ b/services/surfaceflinger/Android.bp @@ -210,7 +210,6 @@ filegroup { "Scheduler/VsyncModulator.cpp", "Scheduler/VsyncSchedule.cpp", "ScreenCaptureOutput.cpp", - "StartPropertySetThread.cpp", "SurfaceFlinger.cpp", "SurfaceFlingerDefaultFactory.cpp", "Tracing/LayerDataSource.cpp", diff --git a/services/surfaceflinger/StartPropertySetThread.cpp b/services/surfaceflinger/StartPropertySetThread.cpp deleted file mode 100644 index f42cd53e0a..0000000000 --- a/services/surfaceflinger/StartPropertySetThread.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2017 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. - */ - -#include <cutils/properties.h> -#include "StartPropertySetThread.h" - -namespace android { - -StartPropertySetThread::StartPropertySetThread(bool timestampPropertyValue): - Thread(false), mTimestampPropertyValue(timestampPropertyValue) {} - -status_t StartPropertySetThread::Start() { - return run("SurfaceFlinger::StartPropertySetThread", PRIORITY_NORMAL); -} - -bool StartPropertySetThread::threadLoop() { - // Set property service.sf.present_timestamp, consumer need check its readiness - property_set(kTimestampProperty, mTimestampPropertyValue ? "1" : "0"); - // Clear BootAnimation exit flag - property_set("service.bootanim.exit", "0"); - property_set("service.bootanim.progress", "0"); - // Start BootAnimation if not started - property_set("ctl.start", "bootanim"); - // Exit immediately - return false; -} - -} // namespace android diff --git a/services/surfaceflinger/StartPropertySetThread.h b/services/surfaceflinger/StartPropertySetThread.h deleted file mode 100644 index bbdcde2809..0000000000 --- a/services/surfaceflinger/StartPropertySetThread.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2017 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. - */ - -#ifndef ANDROID_STARTBOOTANIMTHREAD_H -#define ANDROID_STARTBOOTANIMTHREAD_H - -#include <stddef.h> - -#include <utils/Mutex.h> -#include <utils/Thread.h> - -namespace android { - -class StartPropertySetThread : public Thread { -// Boot animation is triggered via calls to "property_set()" which can block -// if init's executing slow operation such as 'mount_all --late' (currently -// happening 1/10th with fsck) concurrently. Running in a separate thread -// allows to pursue the SurfaceFlinger's init process without blocking. -// see b/34499826. -// Any property_set() will block during init stage so need to be offloaded -// to this thread. see b/63844978. -public: - explicit StartPropertySetThread(bool timestampPropertyValue); - status_t Start(); -private: - virtual bool threadLoop(); - static constexpr const char* kTimestampProperty = "service.sf.present_timestamp"; - const bool mTimestampPropertyValue; -}; - -} - -#endif // ANDROID_STARTBOOTANIMTHREAD_H diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 2501f4b7f7..50cd45b012 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -153,7 +153,6 @@ #include "Scheduler/VsyncConfiguration.h" #include "Scheduler/VsyncModulator.h" #include "ScreenCaptureOutput.h" -#include "StartPropertySetThread.h" #include "SurfaceFlingerProperties.h" #include "TimeStats/TimeStats.h" #include "TunnelModeEnabledReporter.h" @@ -566,7 +565,14 @@ void SurfaceFlinger::binderDied(const wp<IBinder>&) { initializeDisplays(); })); - startBootAnim(); + std::lock_guard lock(mInitBootPropsFutureMutex); + if (!mInitBootPropsFuture.valid()) { + mInitBootPropsFuture = + std::async(std::launch::async, &SurfaceFlinger::initBootProperties, this); + } + + mInitBootPropsFuture.wait(); + mInitBootPropsFuture = {}; } void SurfaceFlinger::run() { @@ -722,13 +728,15 @@ void SurfaceFlinger::bootFinished() { } mBootFinished = true; FlagManager::getMutableInstance().markBootCompleted(); - if (mStartPropertySetThread->join() != NO_ERROR) { - ALOGE("Join StartPropertySetThread failed!"); - } + if (std::lock_guard lock(mInitBootPropsFutureMutex); mInitBootPropsFuture.valid()) { + mInitBootPropsFuture.wait(); + mInitBootPropsFuture = {}; + } if (mRenderEnginePrimeCacheFuture.valid()) { - mRenderEnginePrimeCacheFuture.get(); + mRenderEnginePrimeCacheFuture.wait(); } + const nsecs_t now = systemTime(); const nsecs_t duration = now - mBootTime; ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) ); @@ -816,8 +824,6 @@ void chooseRenderEngineType(renderengine::RenderEngineCreationArgs::Builder& bui } } -// Do not call property_set on main thread which will be blocked by init -// Use StartPropertySetThread instead. void SurfaceFlinger::init() FTL_FAKE_GUARD(kMainThreadContext) { ATRACE_CALL(); ALOGI( "SurfaceFlinger's main thread ready to run. " @@ -928,18 +934,28 @@ void SurfaceFlinger::init() FTL_FAKE_GUARD(kMainThreadContext) { } } - // Inform native graphics APIs whether the present timestamp is supported: - - mStartPropertySetThread = getFactory().createStartPropertySetThread(mHasReliablePresentFences); - - if (mStartPropertySetThread->Start() != NO_ERROR) { - ALOGE("Run StartPropertySetThread failed!"); + // Avoid blocking the main thread on `init` to set properties. + if (std::lock_guard lock(mInitBootPropsFutureMutex); !mInitBootPropsFuture.valid()) { + mInitBootPropsFuture = + std::async(std::launch::async, &SurfaceFlinger::initBootProperties, this); } initTransactionTraceWriter(); ALOGV("Done initializing"); } +// During boot, offload `initBootProperties` to another thread. `property_set` depends on +// `property_service`, which may be delayed by slow operations like `mount_all --late` in +// the `init` process. See b/34499826 and b/63844978. +void SurfaceFlinger::initBootProperties() { + property_set("service.sf.present_timestamp", mHasReliablePresentFences ? "1" : "0"); + + // Reset and (if needed) start BootAnimation. + property_set("service.bootanim.exit", "0"); + property_set("service.bootanim.progress", "0"); + property_set("ctl.start", "bootanim"); +} + void SurfaceFlinger::initTransactionTraceWriter() { if (!mTransactionTracing) { return; @@ -979,18 +995,6 @@ void SurfaceFlinger::readPersistentProperties() { static_cast<ui::ColorMode>(base::GetIntProperty("persist.sys.sf.color_mode"s, 0)); } -void SurfaceFlinger::startBootAnim() { - // Start boot animation service by setting a property mailbox - // if property setting thread is already running, Start() will be just a NOP - mStartPropertySetThread->Start(); - // Wait until property was set - if (mStartPropertySetThread->join() != NO_ERROR) { - ALOGE("Join StartPropertySetThread failed!"); - } -} - -// ---------------------------------------------------------------------------- - status_t SurfaceFlinger::getSupportedFrameTimestamps( std::vector<FrameEvent>* outSupported) const { *outSupported = { diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 005f2e6344..b9ea0c3c67 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -550,7 +550,7 @@ private: bool hasListenerCallbacks, const std::vector<ListenerCallbacks>& listenerCallbacks, uint64_t transactionId, const std::vector<uint64_t>& mergedTransactionIds) override; void bootFinished(); - virtual status_t getSupportedFrameTimestamps(std::vector<FrameEvent>* outSupported) const; + status_t getSupportedFrameTimestamps(std::vector<FrameEvent>* outSupported) const; sp<IDisplayEventConnection> createDisplayEventConnection( gui::ISurfaceComposer::VsyncSource vsyncSource = gui::ISurfaceComposer::VsyncSource::eVsyncSourceApp, @@ -871,9 +871,6 @@ private: // Traverse through all the layers and compute and cache its bounds. void computeLayerBounds(); - // Boot animation, on/off animations and screen capture - void startBootAnim(); - bool layersHasProtectedLayer(const std::vector<std::pair<Layer*, sp<LayerFE>>>& layers) const; void captureScreenCommon(RenderAreaFuture, GetLayerSnapshotsFunction, ui::Size bufferSize, @@ -1184,10 +1181,17 @@ private: ui::Rotation getPhysicalDisplayOrientation(DisplayId, bool isPrimary) const REQUIRES(mStateLock); void traverseLegacyLayers(const LayerVector::Visitor& visitor) const; + + void initBootProperties(); void initTransactionTraceWriter(); - sp<StartPropertySetThread> mStartPropertySetThread; + surfaceflinger::Factory& mFactory; pid_t mPid; + + // TODO: b/328459745 - Encapsulate in a SystemProperties object. + std::mutex mInitBootPropsFutureMutex; + std::future<void> mInitBootPropsFuture GUARDED_BY(mInitBootPropsFutureMutex); + std::future<void> mRenderEnginePrimeCacheFuture; // mStateLock has conventions related to the current thread, because only diff --git a/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp b/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp index 7e6894d3f7..50b167d5d7 100644 --- a/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp +++ b/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp @@ -26,7 +26,6 @@ #include "FrameTracer/FrameTracer.h" #include "Layer.h" #include "NativeWindowSurface.h" -#include "StartPropertySetThread.h" #include "SurfaceFlingerDefaultFactory.h" #include "SurfaceFlingerProperties.h" @@ -53,11 +52,6 @@ std::unique_ptr<scheduler::VsyncConfiguration> DefaultFactory::createVsyncConfig } } -sp<StartPropertySetThread> DefaultFactory::createStartPropertySetThread( - bool timestampPropertyValue) { - return sp<StartPropertySetThread>::make(timestampPropertyValue); -} - sp<DisplayDevice> DefaultFactory::createDisplayDevice(DisplayDeviceCreationArgs& creationArgs) { return sp<DisplayDevice>::make(creationArgs); } diff --git a/services/surfaceflinger/SurfaceFlingerDefaultFactory.h b/services/surfaceflinger/SurfaceFlingerDefaultFactory.h index 2c6de0e113..540dec832e 100644 --- a/services/surfaceflinger/SurfaceFlingerDefaultFactory.h +++ b/services/surfaceflinger/SurfaceFlingerDefaultFactory.h @@ -29,7 +29,6 @@ public: std::unique_ptr<HWComposer> createHWComposer(const std::string& serviceName) override; std::unique_ptr<scheduler::VsyncConfiguration> createVsyncConfiguration( Fps currentRefreshRate) override; - sp<StartPropertySetThread> createStartPropertySetThread(bool timestampPropertyValue) override; sp<DisplayDevice> createDisplayDevice(DisplayDeviceCreationArgs&) override; sp<GraphicBuffer> createGraphicBuffer(uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount, uint64_t usage, diff --git a/services/surfaceflinger/SurfaceFlingerFactory.h b/services/surfaceflinger/SurfaceFlingerFactory.h index f310c4ac53..f1fbf013c7 100644 --- a/services/surfaceflinger/SurfaceFlingerFactory.h +++ b/services/surfaceflinger/SurfaceFlingerFactory.h @@ -39,7 +39,6 @@ class IGraphicBufferConsumer; class IGraphicBufferProducer; class Layer; class LayerFE; -class StartPropertySetThread; class SurfaceFlinger; class TimeStats; @@ -71,8 +70,6 @@ public: virtual std::unique_ptr<scheduler::VsyncConfiguration> createVsyncConfiguration( Fps currentRefreshRate) = 0; - virtual sp<StartPropertySetThread> createStartPropertySetThread( - bool timestampPropertyValue) = 0; virtual sp<DisplayDevice> createDisplayDevice(DisplayDeviceCreationArgs&) = 0; virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount, diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h index bce7729d80..82023b092a 100644 --- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h +++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h @@ -43,7 +43,6 @@ #include "RenderArea.h" #include "Scheduler/MessageQueue.h" #include "Scheduler/RefreshRateSelector.h" -#include "StartPropertySetThread.h" #include "SurfaceFlinger.h" #include "TestableScheduler.h" #include "mock/DisplayHardware/MockComposer.h" @@ -94,10 +93,6 @@ public: return std::make_unique<scheduler::FakePhaseOffsets>(); } - sp<StartPropertySetThread> createStartPropertySetThread(bool timestampPropertyValue) override { - return sp<StartPropertySetThread>::make(timestampPropertyValue); - } - sp<DisplayDevice> createDisplayDevice(DisplayDeviceCreationArgs& creationArgs) override { return sp<DisplayDevice>::make(creationArgs); } |