summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/surfaceflinger/Android.mk1
-rw-r--r--services/surfaceflinger/EventControlThread.h2
-rw-r--r--services/surfaceflinger/StartBootAnimThread.cpp37
-rw-r--r--services/surfaceflinger/StartBootAnimThread.h42
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp19
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h3
-rw-r--r--services/surfaceflinger/SurfaceFlinger_hwc1.cpp21
7 files changed, 114 insertions, 11 deletions
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index 6f5947a19f..0e05d544e2 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -9,6 +9,7 @@ LOCAL_SRC_FILES := \
DisplayDevice.cpp \
DispSync.cpp \
EventControlThread.cpp \
+ StartBootAnimThread.cpp \
EventThread.cpp \
FrameTracker.cpp \
GpuService.cpp \
diff --git a/services/surfaceflinger/EventControlThread.h b/services/surfaceflinger/EventControlThread.h
index 9368db6fc8..1b1ef75b9d 100644
--- a/services/surfaceflinger/EventControlThread.h
+++ b/services/surfaceflinger/EventControlThread.h
@@ -45,4 +45,4 @@ private:
}
-#endif // ANDROID_DISPSYNC_H
+#endif // ANDROID_EVENTCONTROLTHREAD_H
diff --git a/services/surfaceflinger/StartBootAnimThread.cpp b/services/surfaceflinger/StartBootAnimThread.cpp
new file mode 100644
index 0000000000..c3f72967b9
--- /dev/null
+++ b/services/surfaceflinger/StartBootAnimThread.cpp
@@ -0,0 +1,37 @@
+/*
+ * 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/StartBootAnimThread.h b/services/surfaceflinger/StartBootAnimThread.h
new file mode 100644
index 0000000000..dba2bee4a1
--- /dev/null
+++ b/services/surfaceflinger/StartBootAnimThread.h
@@ -0,0 +1,42 @@
+/*
+ * 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 StartBootAnimThread : 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.
+public:
+ StartBootAnimThread();
+ status_t Start();
+private:
+ virtual bool threadLoop();
+};
+
+}
+
+#endif // ANDROID_STARTBOOTANIMTHREAD_H
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index c9445e7b16..9e25e0739d 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -338,6 +338,9 @@ sp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
void SurfaceFlinger::bootFinished()
{
+ if (mStartBootAnimThread->join() != NO_ERROR) {
+ ALOGE("Join StartBootAnimThread failed!");
+ }
const nsecs_t now = systemTime();
const nsecs_t duration = now - mBootTime;
ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
@@ -579,16 +582,22 @@ void SurfaceFlinger::init() {
mRenderEngine->primeCache();
- // start boot animation
- startBootAnim();
+ mStartBootAnimThread = new StartBootAnimThread();
+ if (mStartBootAnimThread->Start() != NO_ERROR) {
+ ALOGE("Run StartBootAnimThread failed!");
+ }
ALOGV("Done initializing");
}
void SurfaceFlinger::startBootAnim() {
- // start boot animation
- property_set("service.bootanim.exit", "0");
- property_set("ctl.start", "bootanim");
+ // Start boot animation service by setting a property mailbox
+ // if property setting thread is already running, Start() will be just a NOP
+ mStartBootAnimThread->Start();
+ // Wait until property was set
+ if (mStartBootAnimThread->join() != NO_ERROR) {
+ ALOGE("Join StartBootAnimThread failed!");
+ }
}
size_t SurfaceFlinger::getMaxTextureSize() const {
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 75c1920d52..55735b13b9 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -58,6 +58,7 @@
#include "LayerVector.h"
#include "MessageQueue.h"
#include "SurfaceInterceptor.h"
+#include "StartBootAnimThread.h"
#include "DisplayHardware/HWComposer.h"
#include "Effects/Daltonizer.h"
@@ -345,6 +346,8 @@ private:
bool useIdentityTransform, Transform::orientation_flags rotation,
bool isLocalScreenshot);
+ sp<StartBootAnimThread> mStartBootAnimThread = nullptr;
+
/* ------------------------------------------------------------------------
* EGL
*/
diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
index f8a1f34060..aaad0f87fe 100644
--- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
+++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
@@ -317,6 +317,9 @@ sp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
void SurfaceFlinger::bootFinished()
{
+ if (mStartBootAnimThread->join() != NO_ERROR) {
+ ALOGE("Join StartBootAnimThread failed!");
+ }
const nsecs_t now = systemTime();
const nsecs_t duration = now - mBootTime;
ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
@@ -589,8 +592,12 @@ void SurfaceFlinger::init() {
mRenderEngine->primeCache();
- // start boot animation
- startBootAnim();
+ mStartBootAnimThread = new StartBootAnimThread();
+ if (mStartBootAnimThread->Start() != NO_ERROR) {
+ ALOGE("Run StartBootAnimThread failed!");
+ }
+
+ ALOGV("Done initializing");
}
int32_t SurfaceFlinger::allocateHwcDisplayId(DisplayDevice::DisplayType type) {
@@ -599,9 +606,13 @@ int32_t SurfaceFlinger::allocateHwcDisplayId(DisplayDevice::DisplayType type) {
}
void SurfaceFlinger::startBootAnim() {
- // start boot animation
- property_set("service.bootanim.exit", "0");
- property_set("ctl.start", "bootanim");
+ // Start boot animation service by setting a property mailbox
+ // if property setting thread is already running, Start() will be just a NOP
+ mStartBootAnimThread->Start();
+ // Wait until property was set
+ if (mStartBootAnimThread->join() != NO_ERROR) {
+ ALOGE("Join StartBootAnimThread failed!");
+ }
}
size_t SurfaceFlinger::getMaxTextureSize() const {