Merge "SurfaceFlinger: Only block calling thread on sync transactions." into rvc-dev
diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp
index bf487c4..d929cc3 100644
--- a/libs/ui/Region.cpp
+++ b/libs/ui/Region.cpp
@@ -306,6 +306,10 @@
// ----------------------------------------------------------------------------
Region& Region::orSelf(const Rect& r) {
+ if (isEmpty()) {
+ set(r);
+ return *this;
+ }
return operationSelf(r, op_or);
}
Region& Region::xorSelf(const Rect& r) {
@@ -326,6 +330,10 @@
// ----------------------------------------------------------------------------
Region& Region::orSelf(const Region& rhs) {
+ if (isEmpty()) {
+ *this = rhs;
+ return *this;
+ }
return operationSelf(rhs, op_or);
}
Region& Region::xorSelf(const Region& rhs) {
diff --git a/opengl/libs/Android.bp b/opengl/libs/Android.bp
index 19b8a58..3997134 100644
--- a/opengl/libs/Android.bp
+++ b/opengl/libs/Android.bp
@@ -75,7 +75,6 @@
"bionic_libc_platform_headers",
"gl_headers",
"libsystem_headers",
- "libhardware_headers",
"libnativebase_headers",
],
export_header_lib_headers: ["gl_headers"],
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index 0581708..d5d57d7 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -16,8 +16,6 @@
#include <stdlib.h>
-#include <hardware/gralloc.h>
-
#include <EGL/egl.h>
#include <cutils/properties.h>
diff --git a/opengl/libs/EGL/egl_platform_entries.cpp b/opengl/libs/EGL/egl_platform_entries.cpp
index 1b75b20..c976c60 100644
--- a/opengl/libs/EGL/egl_platform_entries.cpp
+++ b/opengl/libs/EGL/egl_platform_entries.cpp
@@ -23,8 +23,6 @@
#include <stdlib.h>
#include <string.h>
-#include <hardware/gralloc1.h>
-
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <EGL/eglext_angle.h>
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 7f65943..79ea97b 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();
}
@@ -1782,11 +1784,10 @@
return false;
}
- if (graceTimeMs > 0 && fence->getStatus() == Fence::Status::Unsignaled) {
- fence->wait(graceTimeMs);
- }
-
- return (fence->getStatus() == Fence::Status::Unsignaled);
+ const status_t status = fence->wait(graceTimeMs);
+ // This is the same as Fence::Status::Unsignaled, but it saves a getStatus() call,
+ // which calls wait(0) again internally
+ return status == -ETIME;
}
nsecs_t SurfaceFlinger::previousFramePresentTime() NO_THREAD_SAFETY_ANALYSIS {
@@ -1812,184 +1813,188 @@
ATRACE_CALL();
switch (what) {
case MessageQueue::INVALIDATE: {
- const nsecs_t frameStart = systemTime();
- // calculate the expected present time once and use the cached
- // value throughout this frame to make sure all layers are
- // seeing this same value.
- const nsecs_t lastExpectedPresentTime = mExpectedPresentTime.load();
- mExpectedPresentTime = expectedVSyncTime;
-
- // When Backpressure propagation is enabled we want to give a small grace period
- // for the present fence to fire instead of just giving up on this frame to handle cases
- // where present fence is just about to get signaled.
- const int graceTimeForPresentFenceMs =
- (mPropagateBackpressure &&
- (mPropagateBackpressureClientComposition || !mHadClientComposition))
- ? 1
- : 0;
-
- // Pending frames may trigger backpressure propagation.
- const TracedOrdinal<bool> framePending = {"PrevFramePending",
- previousFramePending(
- graceTimeForPresentFenceMs)};
-
- // Frame missed counts for metrics tracking.
- // A frame is missed if the prior frame is still pending. If no longer pending,
- // then we still count the frame as missed if the predicted present time
- // was further in the past than when the fence actually fired.
-
- // Add some slop to correct for drift. This should generally be
- // smaller than a typical frame duration, but should not be so small
- // that it reports reasonable drift as a missed frame.
- DisplayStatInfo stats;
- mScheduler->getDisplayStatInfo(&stats);
- const nsecs_t frameMissedSlop = stats.vsyncPeriod / 2;
- const nsecs_t previousPresentTime = previousFramePresentTime();
- const TracedOrdinal<bool> frameMissed =
- {"PrevFrameMissed",
- framePending ||
- (previousPresentTime >= 0 &&
- (lastExpectedPresentTime < previousPresentTime - frameMissedSlop))};
- const TracedOrdinal<bool> hwcFrameMissed = {"PrevHwcFrameMissed",
- mHadDeviceComposition && frameMissed};
- const TracedOrdinal<bool> gpuFrameMissed = {"PrevGpuFrameMissed",
- mHadClientComposition && frameMissed};
-
- if (frameMissed) {
- mFrameMissedCount++;
- mTimeStats->incrementMissedFrames();
- if (mMissedFrameJankCount == 0) {
- mMissedFrameJankStart = systemTime();
- }
- mMissedFrameJankCount++;
- }
-
- if (hwcFrameMissed) {
- mHwcFrameMissedCount++;
- }
-
- if (gpuFrameMissed) {
- mGpuFrameMissedCount++;
- }
-
- // If we are in the middle of a config change and the fence hasn't
- // fired yet just wait for the next invalidate
- if (mSetActiveConfigPending) {
- if (framePending) {
- mEventQueue->invalidate();
- break;
- }
-
- // We received the present fence from the HWC, so we assume it successfully updated
- // the config, hence we update SF.
- mSetActiveConfigPending = false;
- setActiveConfigInternal();
- }
-
- if (framePending && mPropagateBackpressure) {
- if ((hwcFrameMissed && !gpuFrameMissed) ||
- mPropagateBackpressureClientComposition) {
- signalLayerUpdate();
- break;
- }
- }
-
- // Our jank window is always at least 100ms since we missed a
- // frame...
- static constexpr nsecs_t kMinJankyDuration =
- std::chrono::duration_cast<std::chrono::nanoseconds>(100ms).count();
- // ...but if it's larger than 1s then we missed the trace cutoff.
- static constexpr nsecs_t kMaxJankyDuration =
- std::chrono::duration_cast<std::chrono::nanoseconds>(1s).count();
- // If we're in a user build then don't push any atoms
- if (!mIsUserBuild && mMissedFrameJankCount > 0) {
- const auto displayDevice = getDefaultDisplayDeviceLocked();
- // Only report jank when the display is on, as displays in DOZE
- // power mode may operate at a different frame rate than is
- // reported in their config, which causes noticeable (but less
- // severe) jank.
- if (displayDevice && displayDevice->getPowerMode() == hal::PowerMode::ON) {
- const nsecs_t currentTime = systemTime();
- const nsecs_t jankDuration = currentTime - mMissedFrameJankStart;
- if (jankDuration > kMinJankyDuration && jankDuration < kMaxJankyDuration) {
- ATRACE_NAME("Jank detected");
- ALOGD("Detected janky event. Missed frames: %d", mMissedFrameJankCount);
- const int32_t jankyDurationMillis = jankDuration / (1000 * 1000);
- android::util::stats_write(android::util::DISPLAY_JANK_REPORTED,
- jankyDurationMillis, mMissedFrameJankCount);
- }
-
- // We either reported a jank event or we missed the trace
- // window, so clear counters here.
- if (jankDuration > kMinJankyDuration) {
- mMissedFrameJankCount = 0;
- mMissedFrameJankStart = 0;
- }
- }
- }
-
- // Now that we're going to make it to the handleMessageTransaction()
- // call below it's safe to call updateVrFlinger(), which will
- // potentially trigger a display handoff.
- updateVrFlinger();
-
- if (mTracingEnabledChanged) {
- mTracingEnabled = mTracing.isEnabled();
- mTracingEnabledChanged = false;
- }
-
- bool refreshNeeded;
- {
- ConditionalLockGuard<std::mutex> lock(mTracingLock, mTracingEnabled);
-
- refreshNeeded = handleMessageTransaction();
- refreshNeeded |= handleMessageInvalidate();
- if (mTracingEnabled) {
- mAddCompositionStateToTrace =
- mTracing.flagIsSetLocked(SurfaceTracing::TRACE_COMPOSITION);
- if (mVisibleRegionsDirty && !mAddCompositionStateToTrace) {
- mTracing.notifyLocked("visibleRegionsDirty");
- }
- }
- }
-
- // Layers need to get updated (in the previous line) before we can use them for
- // choosing the refresh rate.
- // Hold mStateLock as chooseRefreshRateForContent promotes wp<Layer> to sp<Layer>
- // and may eventually call to ~Layer() if it holds the last reference
- {
- Mutex::Autolock _l(mStateLock);
- mScheduler->chooseRefreshRateForContent();
- }
-
- performSetActiveConfig();
-
- updateCursorAsync();
- updateInputFlinger();
-
- refreshNeeded |= mRepaintEverything;
- if (refreshNeeded && CC_LIKELY(mBootStage != BootStage::BOOTLOADER)) {
- // Signal a refresh if a transaction modified the window state,
- // a new buffer was latched, or if HWC has requested a full
- // repaint
- if (mFrameStartTime <= 0) {
- // We should only use the time of the first invalidate
- // message that signals a refresh as the beginning of the
- // frame. Otherwise the real frame time will be
- // underestimated.
- mFrameStartTime = frameStart;
- }
- signalRefresh();
- }
+ onMessageInvalidate(expectedVSyncTime);
break;
}
case MessageQueue::REFRESH: {
- handleMessageRefresh();
+ onMessageRefresh();
break;
}
}
}
+void SurfaceFlinger::onMessageInvalidate(nsecs_t expectedVSyncTime) NO_THREAD_SAFETY_ANALYSIS {
+ ATRACE_CALL();
+
+ const nsecs_t frameStart = systemTime();
+ // calculate the expected present time once and use the cached
+ // value throughout this frame to make sure all layers are
+ // seeing this same value.
+ const nsecs_t lastExpectedPresentTime = mExpectedPresentTime.load();
+ mExpectedPresentTime = expectedVSyncTime;
+
+ // When Backpressure propagation is enabled we want to give a small grace period
+ // for the present fence to fire instead of just giving up on this frame to handle cases
+ // where present fence is just about to get signaled.
+ const int graceTimeForPresentFenceMs =
+ (mPropagateBackpressure &&
+ (mPropagateBackpressureClientComposition || !mHadClientComposition))
+ ? 1
+ : 0;
+
+ // Pending frames may trigger backpressure propagation.
+ const TracedOrdinal<bool> framePending = {"PrevFramePending",
+ previousFramePending(graceTimeForPresentFenceMs)};
+
+ // Frame missed counts for metrics tracking.
+ // A frame is missed if the prior frame is still pending. If no longer pending,
+ // then we still count the frame as missed if the predicted present time
+ // was further in the past than when the fence actually fired.
+
+ // Add some slop to correct for drift. This should generally be
+ // smaller than a typical frame duration, but should not be so small
+ // that it reports reasonable drift as a missed frame.
+ DisplayStatInfo stats;
+ mScheduler->getDisplayStatInfo(&stats);
+ const nsecs_t frameMissedSlop = stats.vsyncPeriod / 2;
+ const nsecs_t previousPresentTime = previousFramePresentTime();
+ const TracedOrdinal<bool> frameMissed = {"PrevFrameMissed",
+ framePending ||
+ (previousPresentTime >= 0 &&
+ (lastExpectedPresentTime <
+ previousPresentTime - frameMissedSlop))};
+ const TracedOrdinal<bool> hwcFrameMissed = {"PrevHwcFrameMissed",
+ mHadDeviceComposition && frameMissed};
+ const TracedOrdinal<bool> gpuFrameMissed = {"PrevGpuFrameMissed",
+ mHadClientComposition && frameMissed};
+
+ if (frameMissed) {
+ mFrameMissedCount++;
+ mTimeStats->incrementMissedFrames();
+ if (mMissedFrameJankCount == 0) {
+ mMissedFrameJankStart = systemTime();
+ }
+ mMissedFrameJankCount++;
+ }
+
+ if (hwcFrameMissed) {
+ mHwcFrameMissedCount++;
+ }
+
+ if (gpuFrameMissed) {
+ mGpuFrameMissedCount++;
+ }
+
+ // If we are in the middle of a config change and the fence hasn't
+ // fired yet just wait for the next invalidate
+ if (mSetActiveConfigPending) {
+ if (framePending) {
+ mEventQueue->invalidate();
+ return;
+ }
+
+ // We received the present fence from the HWC, so we assume it successfully updated
+ // the config, hence we update SF.
+ mSetActiveConfigPending = false;
+ setActiveConfigInternal();
+ }
+
+ if (framePending && mPropagateBackpressure) {
+ if ((hwcFrameMissed && !gpuFrameMissed) || mPropagateBackpressureClientComposition) {
+ signalLayerUpdate();
+ return;
+ }
+ }
+
+ // Our jank window is always at least 100ms since we missed a
+ // frame...
+ static constexpr nsecs_t kMinJankyDuration =
+ std::chrono::duration_cast<std::chrono::nanoseconds>(100ms).count();
+ // ...but if it's larger than 1s then we missed the trace cutoff.
+ static constexpr nsecs_t kMaxJankyDuration =
+ std::chrono::duration_cast<std::chrono::nanoseconds>(1s).count();
+ // If we're in a user build then don't push any atoms
+ if (!mIsUserBuild && mMissedFrameJankCount > 0) {
+ const auto displayDevice = getDefaultDisplayDeviceLocked();
+ // Only report jank when the display is on, as displays in DOZE
+ // power mode may operate at a different frame rate than is
+ // reported in their config, which causes noticeable (but less
+ // severe) jank.
+ if (displayDevice && displayDevice->getPowerMode() == hal::PowerMode::ON) {
+ const nsecs_t currentTime = systemTime();
+ const nsecs_t jankDuration = currentTime - mMissedFrameJankStart;
+ if (jankDuration > kMinJankyDuration && jankDuration < kMaxJankyDuration) {
+ ATRACE_NAME("Jank detected");
+ ALOGD("Detected janky event. Missed frames: %d", mMissedFrameJankCount);
+ const int32_t jankyDurationMillis = jankDuration / (1000 * 1000);
+ android::util::stats_write(android::util::DISPLAY_JANK_REPORTED,
+ jankyDurationMillis, mMissedFrameJankCount);
+ }
+
+ // We either reported a jank event or we missed the trace
+ // window, so clear counters here.
+ if (jankDuration > kMinJankyDuration) {
+ mMissedFrameJankCount = 0;
+ mMissedFrameJankStart = 0;
+ }
+ }
+ }
+
+ // Now that we're going to make it to the handleMessageTransaction()
+ // call below it's safe to call updateVrFlinger(), which will
+ // potentially trigger a display handoff.
+ updateVrFlinger();
+
+ if (mTracingEnabledChanged) {
+ mTracingEnabled = mTracing.isEnabled();
+ mTracingEnabledChanged = false;
+ }
+
+ bool refreshNeeded;
+ {
+ ConditionalLockGuard<std::mutex> lock(mTracingLock, mTracingEnabled);
+
+ refreshNeeded = handleMessageTransaction();
+ refreshNeeded |= handleMessageInvalidate();
+ if (mTracingEnabled) {
+ mAddCompositionStateToTrace =
+ mTracing.flagIsSetLocked(SurfaceTracing::TRACE_COMPOSITION);
+ if (mVisibleRegionsDirty && !mAddCompositionStateToTrace) {
+ mTracing.notifyLocked("visibleRegionsDirty");
+ }
+ }
+ }
+
+ // Layers need to get updated (in the previous line) before we can use them for
+ // choosing the refresh rate.
+ // Hold mStateLock as chooseRefreshRateForContent promotes wp<Layer> to sp<Layer>
+ // and may eventually call to ~Layer() if it holds the last reference
+ {
+ Mutex::Autolock _l(mStateLock);
+ mScheduler->chooseRefreshRateForContent();
+ }
+
+ performSetActiveConfig();
+
+ updateCursorAsync();
+ updateInputFlinger();
+
+ refreshNeeded |= mRepaintEverything;
+ if (refreshNeeded && CC_LIKELY(mBootStage != BootStage::BOOTLOADER)) {
+ // Signal a refresh if a transaction modified the window state,
+ // a new buffer was latched, or if HWC has requested a full
+ // repaint
+ if (mFrameStartTime <= 0) {
+ // We should only use the time of the first invalidate
+ // message that signals a refresh as the beginning of the
+ // frame. Otherwise the real frame time will be
+ // underestimated.
+ mFrameStartTime = frameStart;
+ }
+ signalRefresh();
+ }
+}
+
bool SurfaceFlinger::handleMessageTransaction() {
ATRACE_CALL();
uint32_t transactionFlags = peekTransactionFlags();
@@ -2012,7 +2017,7 @@
return runHandleTransaction;
}
-void SurfaceFlinger::handleMessageRefresh() {
+void SurfaceFlinger::onMessageRefresh() {
ATRACE_CALL();
mRefreshPending = false;
@@ -2110,7 +2115,6 @@
}
}
-
bool SurfaceFlinger::handleMessageInvalidate() {
ATRACE_CALL();
bool refreshNeeded = handlePageFlip();
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index b65e4f6..294a52f 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -580,14 +580,20 @@
const std::optional<scheduler::RefreshRateConfigs::Policy>& policy, bool overridePolicy)
EXCLUDES(mStateLock);
+ // Handle the INVALIDATE message queue event, latching new buffers and applying
+ // incoming transactions
+ void onMessageInvalidate(nsecs_t expectedVSyncTime);
+
// Returns whether the transaction actually modified any state
bool handleMessageTransaction();
+ // Handle the REFRESH message queue event, sending the current frame down to RenderEngine and
+ // the Composer HAL for presentation
+ void onMessageRefresh();
+
// Returns whether a new buffer has been latched (see handlePageFlip())
bool handleMessageInvalidate();
- void handleMessageRefresh();
-
void handleTransaction(uint32_t transactionFlags);
void handleTransactionLocked(uint32_t transactionFlags) REQUIRES(mStateLock);
diff --git a/services/surfaceflinger/TracedOrdinal.h b/services/surfaceflinger/TracedOrdinal.h
index c145a39..4e7f67d 100644
--- a/services/surfaceflinger/TracedOrdinal.h
+++ b/services/surfaceflinger/TracedOrdinal.h
@@ -16,10 +16,13 @@
#pragma once
#include <android-base/stringprintf.h>
+#include <cutils/compiler.h>
#include <utils/Trace.h>
#include <cmath>
#include <string>
+namespace android {
+
template <typename T>
class TracedOrdinal {
public:
@@ -27,9 +30,8 @@
"Type is not supported. Please test it with systrace before adding "
"it to the list.");
- TracedOrdinal(const std::string& name, T initialValue)
- : mName(name),
- mNameNegative(android::base::StringPrintf("%sNegative", name.c_str())),
+ TracedOrdinal(std::string name, T initialValue)
+ : mName(std::move(name)),
mHasGoneNegative(std::signbit(initialValue)),
mData(initialValue) {
trace();
@@ -46,6 +48,14 @@
private:
void trace() {
+ if (CC_LIKELY(!ATRACE_ENABLED())) {
+ return;
+ }
+
+ if (mNameNegative.empty()) {
+ mNameNegative = base::StringPrintf("%sNegative", mName.c_str());
+ }
+
if (!std::signbit(mData)) {
ATRACE_INT64(mName.c_str(), int64_t(mData));
if (mHasGoneNegative) {
@@ -58,7 +68,9 @@
}
const std::string mName;
- const std::string mNameNegative;
+ std::string mNameNegative;
bool mHasGoneNegative;
T mData;
};
+
+} // namespace android
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());
};