SurfaceFlinger: Set property in StartPropertySetThread during init
This is similar to ag/1849505/ (see b/34499826), which by setting
property in a separate thread, that CL aims to avoid slow initialization
in SurfaceFlinger::init where SurfaceFlinger is waiting on
property_service.
There is new property_set() call added, and this CL is to move it to the
StartPropertySetThread.
Bug: 63844978
Test: on taimen with simulated delay ag/2562492/
Change-Id: I31547cb5e75f44eac635386b3cf345a44931c78f
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index 17ee3cb..38529b6 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -9,7 +9,7 @@
DisplayDevice.cpp \
DispSync.cpp \
EventControlThread.cpp \
- StartBootAnimThread.cpp \
+ StartPropertySetThread.cpp \
EventThread.cpp \
FrameTracker.cpp \
GpuService.cpp \
diff --git a/services/surfaceflinger/StartBootAnimThread.cpp b/services/surfaceflinger/StartBootAnimThread.cpp
deleted file mode 100644
index c3f7296..0000000
--- a/services/surfaceflinger/StartBootAnimThread.cpp
+++ /dev/null
@@ -1,37 +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 "StartBootAnimThread.h"
-
-namespace android {
-
-StartBootAnimThread::StartBootAnimThread():
- Thread(false) {
-}
-
-status_t StartBootAnimThread::Start() {
- return run("SurfaceFlinger::StartBootAnimThread", PRIORITY_NORMAL);
-}
-
-bool StartBootAnimThread::threadLoop() {
- property_set("service.bootanim.exit", "0");
- property_set("ctl.start", "bootanim");
- // Exit immediately
- return false;
-}
-
-} // namespace android
diff --git a/services/surfaceflinger/StartPropertySetThread.cpp b/services/surfaceflinger/StartPropertySetThread.cpp
new file mode 100644
index 0000000..db82772
--- /dev/null
+++ b/services/surfaceflinger/StartPropertySetThread.cpp
@@ -0,0 +1,40 @@
+/*
+ * 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");
+ // Start BootAnimation if not started
+ property_set("ctl.start", "bootanim");
+ // Exit immediately
+ return false;
+}
+
+} // namespace android
diff --git a/services/surfaceflinger/StartBootAnimThread.h b/services/surfaceflinger/StartPropertySetThread.h
similarity index 78%
rename from services/surfaceflinger/StartBootAnimThread.h
rename to services/surfaceflinger/StartPropertySetThread.h
index dba2bee..a64c21b 100644
--- a/services/surfaceflinger/StartBootAnimThread.h
+++ b/services/surfaceflinger/StartPropertySetThread.h
@@ -24,17 +24,21 @@
namespace android {
-class StartBootAnimThread : public Thread {
+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:
- StartBootAnimThread();
+ StartPropertySetThread(bool timestampPropertyValue);
status_t Start();
private:
virtual bool threadLoop();
+ static constexpr const char* kTimestampProperty = "service.sf.present_timestamp";
+ const bool mTimestampPropertyValue;
};
}
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index bd2441f..e137a78 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -346,8 +346,8 @@
void SurfaceFlinger::bootFinished()
{
- if (mStartBootAnimThread->join() != NO_ERROR) {
- ALOGE("Join StartBootAnimThread failed!");
+ if (mStartPropertySetThread->join() != NO_ERROR) {
+ ALOGE("Join StartPropertySetThread failed!");
}
const nsecs_t now = systemTime();
const nsecs_t duration = now - mBootTime;
@@ -531,6 +531,8 @@
sp<VSyncSource::Callback> mCallback;
};
+// Do not call property_set on main thread which will be blocked by init
+// Use StartPropertySetThread instead.
void SurfaceFlinger::init() {
ALOGI( "SurfaceFlinger's main thread ready to run. "
"Initializing graphics H/W...");
@@ -580,14 +582,6 @@
Mutex::Autolock _l(mStateLock);
- // Inform native graphics APIs whether the present timestamp is supported:
- if (getHwComposer().hasCapability(
- HWC2::Capability::PresentFenceIsNotReliable)) {
- property_set(kTimestampProperty, "0");
- } else {
- property_set(kTimestampProperty, "1");
- }
-
if (useVrFlinger) {
auto vrFlingerRequestDisplayCallback = [this] (bool requestDisplay) {
ALOGI("VR request display mode: requestDisplay=%d", requestDisplay);
@@ -622,9 +616,16 @@
mRenderEngine->primeCache();
- mStartBootAnimThread = new StartBootAnimThread();
- if (mStartBootAnimThread->Start() != NO_ERROR) {
- ALOGE("Run StartBootAnimThread failed!");
+ // Inform native graphics APIs whether the present timestamp is supported:
+ if (getHwComposer().hasCapability(
+ HWC2::Capability::PresentFenceIsNotReliable)) {
+ mStartPropertySetThread = new StartPropertySetThread(false);
+ } else {
+ mStartPropertySetThread = new StartPropertySetThread(true);
+ }
+
+ if (mStartPropertySetThread->Start() != NO_ERROR) {
+ ALOGE("Run StartPropertySetThread failed!");
}
ALOGV("Done initializing");
@@ -633,10 +634,10 @@
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
- mStartBootAnimThread->Start();
+ mStartPropertySetThread->Start();
// Wait until property was set
- if (mStartBootAnimThread->join() != NO_ERROR) {
- ALOGE("Join StartBootAnimThread failed!");
+ if (mStartPropertySetThread->join() != NO_ERROR) {
+ ALOGE("Join StartPropertySetThread failed!");
}
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 53c3823..dfdc424 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -58,7 +58,7 @@
#include "LayerVector.h"
#include "MessageQueue.h"
#include "SurfaceInterceptor.h"
-#include "StartBootAnimThread.h"
+#include "StartPropertySetThread.h"
#include "DisplayHardware/HWComposer.h"
#include "Effects/Daltonizer.h"
@@ -227,7 +227,6 @@
enum { LOG_FRAME_STATS_PERIOD = 30*60*60 };
static const size_t MAX_LAYERS = 4096;
- static constexpr const char* kTimestampProperty = "service.sf.present_timestamp";
// We're reference counted, never destroy SurfaceFlinger directly
virtual ~SurfaceFlinger();
@@ -434,7 +433,7 @@
bool isLocalScreenshot);
#endif
- sp<StartBootAnimThread> mStartBootAnimThread = nullptr;
+ sp<StartPropertySetThread> mStartPropertySetThread = nullptr;
/* ------------------------------------------------------------------------
* EGL
diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
index f8d1bb0..2b56928 100644
--- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
+++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
@@ -320,8 +320,8 @@
void SurfaceFlinger::bootFinished()
{
- if (mStartBootAnimThread->join() != NO_ERROR) {
- ALOGE("Join StartBootAnimThread failed!");
+ if (mStartPropertySetThread->join() != NO_ERROR) {
+ ALOGE("Join StartPropertySetThread failed!");
}
const nsecs_t now = systemTime();
const nsecs_t duration = now - mBootTime;
@@ -501,6 +501,8 @@
sp<VSyncSource::Callback> mCallback;
};
+// Do not call property_set on main thread which will be blocked by init
+// Use StartPropertySetThread instead.
void SurfaceFlinger::init() {
ALOGI( "SurfaceFlinger's main thread ready to run. "
"Initializing graphics H/W...");
@@ -545,9 +547,6 @@
LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
"couldn't create EGLContext");
- // Inform native graphics APIs that the present timestamp is NOT supported:
- property_set(kTimestampProperty, "0");
-
// initialize our non-virtual displays
for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);
@@ -600,9 +599,10 @@
mRenderEngine->primeCache();
- mStartBootAnimThread = new StartBootAnimThread();
- if (mStartBootAnimThread->Start() != NO_ERROR) {
- ALOGE("Run StartBootAnimThread failed!");
+ // Inform native graphics APIs that the present timestamp is NOT supported:
+ mStartPropertySetThread = new StartPropertySetThread(false);
+ if (mStartPropertySetThread->Start() != NO_ERROR) {
+ ALOGE("Run StartPropertySetThread failed!");
}
ALOGV("Done initializing");
@@ -616,10 +616,10 @@
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
- mStartBootAnimThread->Start();
+ mStartPropertySetThread->Start();
// Wait until property was set
- if (mStartBootAnimThread->join() != NO_ERROR) {
- ALOGE("Join StartBootAnimThread failed!");
+ if (mStartPropertySetThread->join() != NO_ERROR) {
+ ALOGE("Join StartPropertySetThread failed!");
}
}
diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp
index 7b985d1..947a2f7 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -31,6 +31,8 @@
#include <graphicsenv/GraphicsEnv.h>
#include <utils/Vector.h>
+#include "android-base/properties.h"
+
#include "driver.h"
#include "stubhal.h"
@@ -822,9 +824,9 @@
// conditionally add VK_GOOGLE_display_timing if present timestamps are
// supported by the driver:
- char timestamp_property[PROPERTY_VALUE_MAX];
- property_get("service.sf.present_timestamp", timestamp_property, "1");
- if (strcmp(timestamp_property, "1") == 0) {
+ const std::string timestamp_property("service.sf.present_timestamp");
+ android::base::WaitForPropertyCreation(timestamp_property);
+ if (android::base::GetBoolProperty(timestamp_property, true)) {
loader_extensions.push_back({
VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME,
VK_GOOGLE_DISPLAY_TIMING_SPEC_VERSION});