SF: Defer setDisplayBrightness to Binder thread
setDisplayBrightness blocks for a long time so cannot run on the main
thread. Keep display lookup on the main thread, but return a deferred
future to the Binder thread and run it there.
Bug: 154202427
Bug: 123715322
Test: systrace with backdoor to set brightness
Change-Id: I88e60c95db5fdcaa1bf5ebb9711e3bf5ab6539a1
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
index 27266b7..75a4fec 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
+++ b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
@@ -74,7 +74,7 @@
MOCK_METHOD4(setDisplayContentSamplingEnabled, status_t(DisplayId, bool, uint8_t, uint64_t));
MOCK_METHOD4(getDisplayedContentSample,
status_t(DisplayId, uint64_t, uint64_t, DisplayedFrameStats*));
- MOCK_METHOD2(setDisplayBrightness, status_t(DisplayId, float));
+ MOCK_METHOD2(setDisplayBrightness, std::future<status_t>(DisplayId, float));
MOCK_METHOD2(getDisplayBrightnessSupport, status_t(DisplayId, bool*));
MOCK_METHOD2(onHotplug,
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index d6dbd57..0ea3340 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -25,7 +25,6 @@
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
#include "HWC2.h"
-#include "ComposerHal.h"
#include <ui/Fence.h>
#include <ui/FloatRect.h>
@@ -38,6 +37,9 @@
#include <iterator>
#include <set>
+#include "../Promise.h"
+#include "ComposerHal.h"
+
namespace android {
using android::Fence;
@@ -640,12 +642,14 @@
return error;
}
-Error Display::setDisplayBrightness(float brightness) const {
- const auto intError = mComposer.setDisplayBrightness(mId, brightness);
- return static_cast<Error>(intError);
+std::future<Error> Display::setDisplayBrightness(float brightness) {
+ return promise::defer([composer = &mComposer, id = mId, brightness] {
+ const auto intError = composer->setDisplayBrightness(id, brightness);
+ return static_cast<Error>(intError);
+ });
}
-Error Display::setAutoLowLatencyMode(bool on) const {
+Error Display::setAutoLowLatencyMode(bool on) {
auto intError = mComposer.setAutoLowLatencyMode(mId, on);
return static_cast<Error>(intError);
}
@@ -659,7 +663,7 @@
return static_cast<Error>(intError);
}
-Error Display::setContentType(ContentType contentType) const {
+Error Display::setContentType(ContentType contentType) {
auto intError = mComposer.setContentType(mId, contentType);
return static_cast<Error>(intError);
}
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index af31df8..f4c7fdd 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -27,6 +27,7 @@
#include <utils/Timers.h>
#include <functional>
+#include <future>
#include <string>
#include <unordered_map>
#include <unordered_set>
@@ -221,18 +222,18 @@
[[clang::warn_unused_result]] virtual hal::Error presentOrValidate(
uint32_t* outNumTypes, uint32_t* outNumRequests,
android::sp<android::Fence>* outPresentFence, uint32_t* state) = 0;
- [[clang::warn_unused_result]] virtual hal::Error setDisplayBrightness(
- float brightness) const = 0;
+ [[clang::warn_unused_result]] virtual std::future<hal::Error> setDisplayBrightness(
+ float brightness) = 0;
[[clang::warn_unused_result]] virtual hal::Error getDisplayVsyncPeriod(
nsecs_t* outVsyncPeriod) const = 0;
[[clang::warn_unused_result]] virtual hal::Error setActiveConfigWithConstraints(
const std::shared_ptr<const HWC2::Display::Config>& config,
const hal::VsyncPeriodChangeConstraints& constraints,
hal::VsyncPeriodChangeTimeline* outTimeline) = 0;
- [[clang::warn_unused_result]] virtual hal::Error setAutoLowLatencyMode(bool on) const = 0;
+ [[clang::warn_unused_result]] virtual hal::Error setAutoLowLatencyMode(bool on) = 0;
[[clang::warn_unused_result]] virtual hal::Error getSupportedContentTypes(
std::vector<hal::ContentType>*) const = 0;
- [[clang::warn_unused_result]] virtual hal::Error setContentType(hal::ContentType) const = 0;
+ [[clang::warn_unused_result]] virtual hal::Error setContentType(hal::ContentType) = 0;
};
namespace impl {
@@ -294,16 +295,16 @@
hal::Error presentOrValidate(uint32_t* outNumTypes, uint32_t* outNumRequests,
android::sp<android::Fence>* outPresentFence,
uint32_t* state) override;
- hal::Error setDisplayBrightness(float brightness) const override;
+ std::future<hal::Error> setDisplayBrightness(float brightness) override;
hal::Error getDisplayVsyncPeriod(nsecs_t* outVsyncPeriod) const override;
hal::Error setActiveConfigWithConstraints(
const std::shared_ptr<const HWC2::Display::Config>& config,
const hal::VsyncPeriodChangeConstraints& constraints,
hal::VsyncPeriodChangeTimeline* outTimeline) override;
- hal::Error setAutoLowLatencyMode(bool on) const override;
+ hal::Error setAutoLowLatencyMode(bool on) override;
hal::Error getSupportedContentTypes(
std::vector<hal::ContentType>* outSupportedContentTypes) const override;
- hal::Error setContentType(hal::ContentType contentType) const override;
+ hal::Error setContentType(hal::ContentType) override;
// Other Display methods
hal::HWDisplayId getId() const override { return mId; }
bool isConnected() const override { return mIsConnected; }
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 4344a8d..038cec4 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -36,6 +36,7 @@
#include <utils/Trace.h>
#include "../Layer.h" // needed only for debugging
+#include "../Promise.h"
#include "../SurfaceFlinger.h"
#include "ComposerHal.h"
#include "HWC2.h"
@@ -794,17 +795,21 @@
return NO_ERROR;
}
-status_t HWComposer::setDisplayBrightness(DisplayId displayId, float brightness) {
- RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
- const auto error = mDisplayData[displayId].hwcDisplay->setDisplayBrightness(brightness);
- if (error == hal::Error::UNSUPPORTED) {
- RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
- }
- if (error == hal::Error::BAD_PARAMETER) {
- RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
- }
- RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
- return NO_ERROR;
+std::future<status_t> HWComposer::setDisplayBrightness(DisplayId displayId, float brightness) {
+ RETURN_IF_INVALID_DISPLAY(displayId, promise::yield<status_t>(BAD_INDEX));
+ auto& display = mDisplayData[displayId].hwcDisplay;
+
+ return promise::chain(display->setDisplayBrightness(brightness))
+ .then([displayId](hal::Error error) -> status_t {
+ if (error == hal::Error::UNSUPPORTED) {
+ RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
+ }
+ if (error == hal::Error::BAD_PARAMETER) {
+ RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
+ }
+ RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
+ return NO_ERROR;
+ });
}
bool HWComposer::isUsingVrComposer() const {
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index cfa2193..b7e9f3a 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -18,6 +18,7 @@
#define ANDROID_SF_HWCOMPOSER_H
#include <cstdint>
+#include <future>
#include <memory>
#include <mutex>
#include <optional>
@@ -163,7 +164,7 @@
DisplayedFrameStats* outStats) = 0;
// Sets the brightness of a display.
- virtual status_t setDisplayBrightness(DisplayId displayId, float brightness) = 0;
+ virtual std::future<status_t> setDisplayBrightness(DisplayId displayId, float brightness) = 0;
// Events handling ---------------------------------------------------------
@@ -305,7 +306,7 @@
uint8_t componentMask, uint64_t maxFrames) override;
status_t getDisplayedContentSample(DisplayId displayId, uint64_t maxFrames, uint64_t timestamp,
DisplayedFrameStats* outStats) override;
- status_t setDisplayBrightness(DisplayId displayId, float brightness) override;
+ std::future<status_t> setDisplayBrightness(DisplayId displayId, float brightness) override;
// Events handling ---------------------------------------------------------
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 2943499..794e8a7 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -108,6 +108,7 @@
#include "LayerVector.h"
#include "MonitoredProducer.h"
#include "NativeWindowSurface.h"
+#include "Promise.h"
#include "RefreshRateOverlay.h"
#include "RegionSamplingThread.h"
#include "Scheduler/DispSync.h"
@@ -1491,14 +1492,15 @@
return BAD_VALUE;
}
- return schedule([=]() -> status_t {
+ return promise::chain(schedule([=] {
if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
return getHwComposer().setDisplayBrightness(*displayId, brightness);
} else {
ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
- return NAME_NOT_FOUND;
+ return promise::yield<status_t>(NAME_NOT_FOUND);
}
- })
+ }))
+ .then([](std::future<status_t> task) { return task; })
.get();
}
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h
index 67d3e1c..dade9fc 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h
@@ -84,15 +84,15 @@
MOCK_METHOD2(validate, hal::Error(uint32_t*, uint32_t*));
MOCK_METHOD4(presentOrValidate,
hal::Error(uint32_t*, uint32_t*, android::sp<android::Fence>*, uint32_t*));
- MOCK_CONST_METHOD1(setDisplayBrightness, hal::Error(float));
+ MOCK_METHOD1(setDisplayBrightness, std::future<hal::Error>(float));
MOCK_CONST_METHOD1(getDisplayVsyncPeriod, hal::Error(nsecs_t*));
MOCK_METHOD3(setActiveConfigWithConstraints,
hal::Error(const std::shared_ptr<const HWC2::Display::Config>&,
const hal::VsyncPeriodChangeConstraints&,
hal::VsyncPeriodChangeTimeline*));
- MOCK_CONST_METHOD1(setAutoLowLatencyMode, hal::Error(bool on));
+ MOCK_METHOD1(setAutoLowLatencyMode, hal::Error(bool on));
MOCK_CONST_METHOD1(getSupportedContentTypes, hal::Error(std::vector<hal::ContentType>*));
- MOCK_CONST_METHOD1(setContentType, hal::Error(hal::ContentType));
+ MOCK_METHOD1(setContentType, hal::Error(hal::ContentType));
MOCK_CONST_METHOD1(getConnectionType, hal::Error(android::DisplayConnectionType*));
MOCK_CONST_METHOD0(isVsyncPeriodSwitchSupported, bool());
};