OSDN Git Service

SurfaceFlinger: Set property in StartPropertySetThread during init
authorWei Wang <wvw@google.com>
Thu, 20 Jul 2017 03:59:39 +0000 (20:59 -0700)
committerWei Wang <wvw@google.com>
Thu, 20 Jul 2017 21:57:23 +0000 (14:57 -0700)
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

services/surfaceflinger/Android.mk
services/surfaceflinger/StartPropertySetThread.cpp [moved from services/surfaceflinger/StartBootAnimThread.cpp with 58% similarity]
services/surfaceflinger/StartPropertySetThread.h [moved from services/surfaceflinger/StartBootAnimThread.h with 78% similarity]
services/surfaceflinger/SurfaceFlinger.cpp
services/surfaceflinger/SurfaceFlinger.h
services/surfaceflinger/SurfaceFlinger_hwc1.cpp
vulkan/libvulkan/driver.cpp

index 17ee3cb..38529b6 100644 (file)
@@ -9,7 +9,7 @@ LOCAL_SRC_FILES := \
     DisplayDevice.cpp \
     DispSync.cpp \
     EventControlThread.cpp \
-    StartBootAnimThread.cpp \
+    StartPropertySetThread.cpp \
     EventThread.cpp \
     FrameTracker.cpp \
     GpuService.cpp \
  */
 
 #include <cutils/properties.h>
-#include "StartBootAnimThread.h"
+#include "StartPropertySetThread.h"
 
 namespace android {
 
-StartBootAnimThread::StartBootAnimThread():
-        Thread(false) {
-}
+StartPropertySetThread::StartPropertySetThread(bool timestampPropertyValue):
+        Thread(false), mTimestampPropertyValue(timestampPropertyValue) {}
 
-status_t StartBootAnimThread::Start() {
-    return run("SurfaceFlinger::StartBootAnimThread", PRIORITY_NORMAL);
+status_t StartPropertySetThread::Start() {
+    return run("SurfaceFlinger::StartPropertySetThread", PRIORITY_NORMAL);
 }
 
-bool StartBootAnimThread::threadLoop() {
+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 {
 
-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;
 };
 
 }
index bd2441f..e137a78 100644 (file)
@@ -346,8 +346,8 @@ sp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) {
 
 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 @@ private:
     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 @@ void SurfaceFlinger::init() {
 
     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 @@ void SurfaceFlinger::init() {
 
     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::init() {
 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!");
     }
 }
 
index 53c3823..dfdc424 100644 (file)
@@ -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 @@ private:
     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 @@ private:
             bool isLocalScreenshot);
 #endif
 
-    sp<StartBootAnimThread> mStartBootAnimThread = nullptr;
+    sp<StartPropertySetThread> mStartPropertySetThread = nullptr;
 
     /* ------------------------------------------------------------------------
      * EGL
index f8d1bb0..2b56928 100644 (file)
@@ -320,8 +320,8 @@ sp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) {
 
 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 @@ private:
     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 @@ void SurfaceFlinger::init() {
     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 @@ void SurfaceFlinger::init() {
 
     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 @@ int32_t SurfaceFlinger::allocateHwcDisplayId(DisplayDevice::DisplayType type) {
 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!");
     }
 }
 
index 7b985d1..947a2f7 100644 (file)
@@ -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 @@ VkResult EnumerateDeviceExtensionProperties(
 
     // 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});