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;
};
}
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;
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...");
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);
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");
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!");
}
}
#include "LayerVector.h"
#include "MessageQueue.h"
#include "SurfaceInterceptor.h"
-#include "StartBootAnimThread.h"
+#include "StartPropertySetThread.h"
#include "DisplayHardware/HWComposer.h"
#include "Effects/Daltonizer.h"
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();
bool isLocalScreenshot);
#endif
- sp<StartBootAnimThread> mStartBootAnimThread = nullptr;
+ sp<StartPropertySetThread> mStartPropertySetThread = nullptr;
/* ------------------------------------------------------------------------
* EGL
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;
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...");
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);
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");
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!");
}
}
#include <graphicsenv/GraphicsEnv.h>
#include <utils/Vector.h>
+#include "android-base/properties.h"
+
#include "driver.h"
#include "stubhal.h"
// 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});