Merge "SF: default display is active display" into sc-v2-dev
diff --git a/libs/renderengine/gl/GLESRenderEngine.h b/libs/renderengine/gl/GLESRenderEngine.h
index 915dba3..95d58ab 100644
--- a/libs/renderengine/gl/GLESRenderEngine.h
+++ b/libs/renderengine/gl/GLESRenderEngine.h
@@ -71,7 +71,7 @@
void cleanupPostRender() override;
int getContextPriority() override;
bool supportsBackgroundBlur() override { return mBlurFilter != nullptr; }
- void onPrimaryDisplaySizeChanged(ui::Size size) override {}
+ void onActiveDisplaySizeChanged(ui::Size size) override {}
EGLDisplay getEGLDisplay() const { return mEGLDisplay; }
// Creates an output image for rendering to
diff --git a/libs/renderengine/include/renderengine/RenderEngine.h b/libs/renderengine/include/renderengine/RenderEngine.h
index ac0affb..9fdf4d1 100644
--- a/libs/renderengine/include/renderengine/RenderEngine.h
+++ b/libs/renderengine/include/renderengine/RenderEngine.h
@@ -129,9 +129,9 @@
// Attempt to switch RenderEngine into and out of protectedContext mode
virtual bool useProtectedContext(bool useProtectedContext) = 0;
- // Notify RenderEngine of changes to the dimensions of the primary display
+ // Notify RenderEngine of changes to the dimensions of the active display
// so that it can configure its internal caches accordingly.
- virtual void onPrimaryDisplaySizeChanged(ui::Size size) = 0;
+ virtual void onActiveDisplaySizeChanged(ui::Size size) = 0;
// Renders layers for a particular display via GPU composition. This method
// should be called for every display that needs to be rendered via the GPU.
diff --git a/libs/renderengine/include/renderengine/mock/RenderEngine.h b/libs/renderengine/include/renderengine/mock/RenderEngine.h
index 0175af3..c0b1c6f 100644
--- a/libs/renderengine/include/renderengine/mock/RenderEngine.h
+++ b/libs/renderengine/include/renderengine/mock/RenderEngine.h
@@ -54,7 +54,7 @@
MOCK_METHOD0(cleanFramebufferCache, void());
MOCK_METHOD0(getContextPriority, int());
MOCK_METHOD0(supportsBackgroundBlur, bool());
- MOCK_METHOD1(onPrimaryDisplaySizeChanged, void(ui::Size));
+ MOCK_METHOD1(onActiveDisplaySizeChanged, void(ui::Size));
protected:
// mock renderengine still needs to implement these, but callers should never need to call them.
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
index c7356ea..a963819 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
@@ -1401,7 +1401,7 @@
return value;
}
-void SkiaGLRenderEngine::onPrimaryDisplaySizeChanged(ui::Size size) {
+void SkiaGLRenderEngine::onActiveDisplaySizeChanged(ui::Size size) {
// This cache multiplier was selected based on review of cache sizes relative
// to the screen resolution. Looking at the worst case memory needed by blur (~1.5x),
// shadows (~1x), and general data structures (e.g. vertex buffers) we selected this as a
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.h b/libs/renderengine/skia/SkiaGLRenderEngine.h
index b30355b..48aa276 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.h
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.h
@@ -67,7 +67,7 @@
bool useProtectedContext(bool useProtectedContext) override;
bool supportsBackgroundBlur() override { return mBlurFilter != nullptr; }
void assertShadersCompiled(int numShaders) override;
- void onPrimaryDisplaySizeChanged(ui::Size size) override;
+ void onActiveDisplaySizeChanged(ui::Size size) override;
int reportShadersCompiled() override;
protected:
diff --git a/libs/renderengine/threaded/RenderEngineThreaded.cpp b/libs/renderengine/threaded/RenderEngineThreaded.cpp
index ea3871f..c09ea9c 100644
--- a/libs/renderengine/threaded/RenderEngineThreaded.cpp
+++ b/libs/renderengine/threaded/RenderEngineThreaded.cpp
@@ -354,14 +354,14 @@
return mRenderEngine->supportsBackgroundBlur();
}
-void RenderEngineThreaded::onPrimaryDisplaySizeChanged(ui::Size size) {
+void RenderEngineThreaded::onActiveDisplaySizeChanged(ui::Size size) {
// This function is designed so it can run asynchronously, so we do not need to wait
// for the futures.
{
std::lock_guard lock(mThreadMutex);
mFunctionCalls.push([size](renderengine::RenderEngine& instance) {
- ATRACE_NAME("REThreaded::onPrimaryDisplaySizeChanged");
- instance.onPrimaryDisplaySizeChanged(size);
+ ATRACE_NAME("REThreaded::onActiveDisplaySizeChanged");
+ instance.onActiveDisplaySizeChanged(size);
});
}
mCondition.notify_one();
diff --git a/libs/renderengine/threaded/RenderEngineThreaded.h b/libs/renderengine/threaded/RenderEngineThreaded.h
index 9b523b2..71d46c1 100644
--- a/libs/renderengine/threaded/RenderEngineThreaded.h
+++ b/libs/renderengine/threaded/RenderEngineThreaded.h
@@ -65,7 +65,7 @@
void cleanFramebufferCache() override;
int getContextPriority() override;
bool supportsBackgroundBlur() override;
- void onPrimaryDisplaySizeChanged(ui::Size size) override;
+ void onActiveDisplaySizeChanged(ui::Size size) override;
protected:
void mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer, bool isRenderable) override;
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index c391901..517f848 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -217,7 +217,7 @@
}
void DisplayDevice::setLayerStack(ui::LayerStack stack) {
- mCompositionDisplay->setLayerStackFilter(stack, isPrimary());
+ mCompositionDisplay->setLayerStackFilter(stack, isInternal());
}
void DisplayDevice::setFlags(uint32_t flags) {
@@ -266,7 +266,7 @@
std::string DisplayDevice::getDebugName() const {
const char* type = "virtual";
if (mConnectionType) {
- type = *mConnectionType == ui::DisplayConnectionType::Internal ? "internal" : "external";
+ type = isInternal() ? "internal" : "external";
}
return base::StringPrintf("DisplayDevice{%s, %s%s, \"%s\"}", to_string(getId()).c_str(), type,
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 70dcc1e..e5fe067 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -79,6 +79,9 @@
bool isVirtual() const { return !mConnectionType; }
bool isPrimary() const { return mIsPrimary; }
+ bool isInternal() const {
+ return !isVirtual() && mConnectionType == ui::DisplayConnectionType::Internal;
+ }
// isSecure indicates whether this display can be trusted to display
// secure surfaces.
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 6d6e3c2..384e4e9 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -893,7 +893,7 @@
}
}
-void Scheduler::onPrimaryDisplayAreaChanged(uint32_t displayArea) {
+void Scheduler::onActiveDisplayAreaChanged(uint32_t displayArea) {
mLayerHistory->setDisplayArea(displayArea);
}
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index 30a3253..7a2fdb5 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -165,7 +165,7 @@
void onDisplayRefreshed(nsecs_t timestamp);
// Notifies the scheduler when the display size has changed. Called from SF's main thread
- void onPrimaryDisplayAreaChanged(uint32_t displayArea);
+ void onActiveDisplayAreaChanged(uint32_t displayArea);
size_t getEventThreadConnectionCount(ConnectionHandle handle);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 194e698..18cb0c2 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -632,9 +632,7 @@
mVirtualDisplayIdGenerators.gpu.releaseId(*id);
}
-std::vector<PhysicalDisplayId> SurfaceFlinger::getPhysicalDisplayIds() const {
- Mutex::Autolock lock(mStateLock);
-
+std::vector<PhysicalDisplayId> SurfaceFlinger::getPhysicalDisplayIdsLocked() const {
const auto internalDisplayId = getInternalDisplayIdLocked();
if (!internalDisplayId) {
return {};
@@ -837,7 +835,7 @@
}
}
- getRenderEngine().onPrimaryDisplaySizeChanged(display->getSize());
+ onActiveDisplaySizeChanged(display);
// Inform native graphics APIs whether the present timestamp is supported:
@@ -2335,7 +2333,7 @@
mTransactionCallbackInvoker.addPresentFence(mPreviousPresentFences[0].fence);
mTransactionCallbackInvoker.sendCallbacks();
- if (display && display->isPrimary() && display->getPowerMode() == hal::PowerMode::ON &&
+ if (display && display->isInternal() && display->getPowerMode() == hal::PowerMode::ON &&
mPreviousPresentFences[0].fenceTime->isValid()) {
mScheduler->addPresentFence(mPreviousPresentFences[0].fenceTime);
}
@@ -2785,11 +2783,6 @@
if (!state.isVirtual()) {
dispatchDisplayHotplugEvent(display->getPhysicalId(), true);
}
-
- if (display->isPrimary()) {
- mScheduler->onPrimaryDisplayAreaChanged(display->getWidth() * display->getHeight());
- getRenderEngine().onPrimaryDisplaySizeChanged(display->getSize());
- }
}
void SurfaceFlinger::processDisplayRemoved(const wp<IBinder>& displayToken) {
@@ -2854,16 +2847,8 @@
// TODO(b/175678251) Call a listener instead.
if (currentState.physical->hwcDisplayId == getHwComposer().getInternalHwcDisplayId()) {
- mRefreshRateConfigs->updateDisplayModes(currentState.physical->supportedModes,
- currentState.physical->activeMode->getId());
- mVsyncConfiguration->reset();
- const Fps refreshRate = currentState.physical->activeMode->getFps();
- updatePhaseConfiguration(refreshRate);
- mRefreshRateStats->setRefreshRate(refreshRate);
-
- if (mRefreshRateOverlay) {
- mRefreshRateOverlay->reset();
- }
+ updateInternalDisplayVsyncLocked(currentState.physical->supportedModes,
+ currentState.physical->activeMode->getId());
}
}
return;
@@ -2889,8 +2874,8 @@
currentState.height != drawingState.height) {
display->setDisplaySize(currentState.width, currentState.height);
- if (display->isPrimary()) {
- mScheduler->onPrimaryDisplayAreaChanged(currentState.width * currentState.height);
+ if (isDisplayActiveLocked(display)) {
+ onActiveDisplaySizeChanged(display);
}
if (mRefreshRateOverlay) {
@@ -2899,6 +2884,17 @@
}
}
}
+void SurfaceFlinger::updateInternalDisplayVsyncLocked(const DisplayModes& modes,
+ DisplayModeId currentModeId) {
+ mRefreshRateConfigs->updateDisplayModes(modes, currentModeId);
+ mVsyncConfiguration->reset();
+ const Fps refreshRate = mRefreshRateConfigs->getCurrentRefreshRate().getFps();
+ updatePhaseConfiguration(refreshRate);
+ mRefreshRateStats->setRefreshRate(refreshRate);
+ if (mRefreshRateOverlay) {
+ mRefreshRateOverlay->reset();
+ }
+}
void SurfaceFlinger::processDisplayChangesLocked() {
// here we take advantage of Vector's copy-on-write semantics to
@@ -4555,6 +4551,11 @@
}
const auto vsyncPeriod = mRefreshRateConfigs->getCurrentRefreshRate().getVsyncPeriod();
if (currentMode == hal::PowerMode::OFF) {
+ const auto activeDisplay = getDisplayDeviceLocked(mActiveDisplayToken);
+ if (display->isInternal() && (!activeDisplay || !activeDisplay->isPoweredOn())) {
+ mActiveDisplayToken = display->getDisplayToken();
+ onActiveDisplayChangedLocked(getDisplayDeviceLocked(mActiveDisplayToken));
+ }
// Keep uclamp in a separate syscall and set it before changing to RT due to b/190237315.
// We can merge the syscall later.
if (SurfaceFlinger::setSchedAttr(true) != NO_ERROR) {
@@ -4564,7 +4565,7 @@
ALOGW("Couldn't set SCHED_FIFO on display on: %s\n", strerror(errno));
}
getHwComposer().setPowerMode(displayId, mode);
- if (display->isPrimary() && mode != hal::PowerMode::DOZE_SUSPEND) {
+ if (display->isInternal() && mode != hal::PowerMode::DOZE_SUSPEND) {
getHwComposer().setVsyncEnabled(displayId, mHWCVsyncPendingState);
mScheduler->onScreenAcquired(mAppConnectionHandle);
mScheduler->resyncToHardwareVsync(true, vsyncPeriod);
@@ -4581,7 +4582,7 @@
if (SurfaceFlinger::setSchedAttr(false) != NO_ERROR) {
ALOGW("Couldn't set uclamp.min on display off: %s\n", strerror(errno));
}
- if (display->isPrimary() && currentMode != hal::PowerMode::DOZE_SUSPEND) {
+ if (display->isInternal() && currentMode != hal::PowerMode::DOZE_SUSPEND) {
mScheduler->disableHardwareVsync(true);
mScheduler->onScreenReleased(mAppConnectionHandle);
}
@@ -4595,13 +4596,13 @@
} else if (mode == hal::PowerMode::DOZE || mode == hal::PowerMode::ON) {
// Update display while dozing
getHwComposer().setPowerMode(displayId, mode);
- if (display->isPrimary() && currentMode == hal::PowerMode::DOZE_SUSPEND) {
+ if (display->isInternal() && currentMode == hal::PowerMode::DOZE_SUSPEND) {
mScheduler->onScreenAcquired(mAppConnectionHandle);
mScheduler->resyncToHardwareVsync(true, vsyncPeriod);
}
} else if (mode == hal::PowerMode::DOZE_SUSPEND) {
// Leave display going to doze
- if (display->isPrimary()) {
+ if (display->isInternal()) {
mScheduler->disableHardwareVsync(true);
mScheduler->onScreenReleased(mAppConnectionHandle);
}
@@ -4611,7 +4612,7 @@
getHwComposer().setPowerMode(displayId, mode);
}
- if (display->isPrimary()) {
+ if (display->isInternal()) {
mTimeStats->setPowerMode(mode);
mRefreshRateStats->setPowerMode(mode);
mScheduler->setDisplayPowerState(mode == hal::PowerMode::ON);
@@ -5686,7 +5687,7 @@
return std::make_optional<PhysicalDisplayId>(inputDisplayId);
}
- return getInternalDisplayId();
+ return getDefaultDisplayDevice()->getPhysicalId();
}();
if (!displayId) {
@@ -6459,8 +6460,10 @@
const std::optional<scheduler::RefreshRateConfigs::Policy>& policy, bool overridePolicy) {
Mutex::Autolock lock(mStateLock);
- LOG_ALWAYS_FATAL_IF(!display->isPrimary() && overridePolicy,
- "Can only set override policy on the primary display");
+ const bool isDefaultDisplay = display == getDefaultDisplayDeviceLocked();
+
+ LOG_ALWAYS_FATAL_IF(!isDefaultDisplay && overridePolicy,
+ "Can only set override policy on the default display");
LOG_ALWAYS_FATAL_IF(!policy && !overridePolicy, "Can only clear the override policy");
if (mDebugDisplayModeSetByBackdoor) {
@@ -6468,11 +6471,11 @@
return NO_ERROR;
}
- if (!display->isPrimary()) {
- // TODO(b/144711714): For non-primary displays we should be able to set an active mode
+ if (!isDefaultDisplay) {
+ // TODO(b/144711714): For non-default displays we should be able to set an active mode
// as well. For now, just call directly to initiateModeChange but ideally
// it should go thru setDesiredActiveMode, similar to primary display.
- ALOGV("%s for non-primary display", __func__);
+ ALOGV("%s for non-default display", __func__);
const auto displayId = display->getPhysicalId();
hal::VsyncPeriodChangeConstraints constraints;
@@ -6590,7 +6593,7 @@
return NAME_NOT_FOUND;
}
- if (display->isPrimary()) {
+ if (display == getDefaultDisplayDeviceLocked()) {
scheduler::RefreshRateConfigs::Policy policy =
mRefreshRateConfigs->getDisplayManagerPolicy();
*outDefaultMode = policy.defaultMode.value();
@@ -6984,6 +6987,27 @@
mRegionSamplingThread->onCompositionComplete(mEventQueue->nextExpectedInvalidate());
}
+void SurfaceFlinger::onActiveDisplaySizeChanged(const sp<DisplayDevice>& activeDisplay) {
+ mScheduler->onActiveDisplayAreaChanged(activeDisplay->getWidth() * activeDisplay->getHeight());
+ getRenderEngine().onActiveDisplaySizeChanged(activeDisplay->getSize());
+}
+
+void SurfaceFlinger::onActiveDisplayChangedLocked(const sp<DisplayDevice>& activeDisplay) {
+ ATRACE_CALL();
+
+ if (!activeDisplay) {
+ ALOGE("%s: activeDisplay is null", __func__);
+ return;
+ }
+ updateInternalDisplayVsyncLocked(activeDisplay->getSupportedModes(),
+ activeDisplay->getActiveMode()->getId());
+ onActiveDisplaySizeChanged(activeDisplay);
+ if (mRefreshRateOverlay) {
+ mRefreshRateOverlay->setViewport(activeDisplay->getSize());
+ mRefreshRateOverlay->changeRefreshRate(activeDisplay->getActiveMode()->getFps());
+ }
+}
+
} // namespace android
#if defined(__gl_h_)
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 6d9767e..338aa18 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -609,7 +609,10 @@
sp<ISurfaceComposerClient> createConnection() override;
sp<IBinder> createDisplay(const String8& displayName, bool secure) override;
void destroyDisplay(const sp<IBinder>& displayToken) override;
- std::vector<PhysicalDisplayId> getPhysicalDisplayIds() const override;
+ std::vector<PhysicalDisplayId> getPhysicalDisplayIds() const override EXCLUDES(mStateLock) {
+ Mutex::Autolock lock(mStateLock);
+ return getPhysicalDisplayIdsLocked();
+ }
sp<IBinder> getPhysicalDisplayToken(PhysicalDisplayId displayId) const override;
status_t setTransactionState(const FrameTimelineInfo& frameTimelineInfo,
const Vector<ComposerState>& state,
@@ -961,6 +964,11 @@
}
sp<DisplayDevice> getDefaultDisplayDeviceLocked() REQUIRES(mStateLock) {
+ if (const auto display = getDisplayDeviceLocked(mActiveDisplayToken)) {
+ return display;
+ }
+ // The active display is outdated, fall back to the internal display
+ mActiveDisplayToken.clear();
if (const auto token = getInternalDisplayTokenLocked()) {
return getDisplayDeviceLocked(token);
}
@@ -986,12 +994,18 @@
return findDisplay([id](const auto& display) { return display.getId() == id; });
}
+ std::vector<PhysicalDisplayId> getPhysicalDisplayIdsLocked() const REQUIRES(mStateLock);
+
// mark a region of a layer stack dirty. this updates the dirty
// region of all screens presenting this layer stack.
void invalidateLayerStack(const sp<const Layer>& layer, const Region& dirty);
sp<DisplayDevice> getDisplayWithInputByLayer(Layer* layer) const REQUIRES(mStateLock);
+ bool isDisplayActiveLocked(const sp<const DisplayDevice>& display) REQUIRES(mStateLock) {
+ return display->getDisplayToken() == mActiveDisplayToken;
+ }
+
/*
* H/W composer
*/
@@ -1114,6 +1128,10 @@
REQUIRES(mStateLock);
void releaseVirtualDisplay(VirtualDisplayId);
+ void onActiveDisplayChangedLocked(const sp<DisplayDevice>& activeDisplay) REQUIRES(mStateLock);
+
+ void onActiveDisplaySizeChanged(const sp<DisplayDevice>& activeDisplay);
+
/*
* Debugging & dumpsys
*/
@@ -1193,6 +1211,9 @@
std::chrono::nanoseconds presentLatency);
int getMaxAcquiredBufferCountForRefreshRate(Fps refreshRate) const;
+ void updateInternalDisplayVsyncLocked(const DisplayModes& modes, DisplayModeId currentModeId)
+ REQUIRES(mStateLock);
+
sp<StartPropertySetThread> mStartPropertySetThread;
surfaceflinger::Factory& mFactory;
@@ -1481,6 +1502,8 @@
void scheduleRegionSamplingThread();
void notifyRegionSamplingThread();
+
+ wp<IBinder> mActiveDisplayToken GUARDED_BY(mStateLock);
};
} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
index f680d80..e51db84 100644
--- a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
@@ -171,7 +171,7 @@
mScheduler->setDisplayPowerState(kPowerStateNormal);
constexpr uint32_t kDisplayArea = 999'999;
- mScheduler->onPrimaryDisplayAreaChanged(kDisplayArea);
+ mScheduler->onActiveDisplayAreaChanged(kDisplayArea);
EXPECT_CALL(mSchedulerCallback, changeRefreshRate(_, _)).Times(0);
mScheduler->chooseRefreshRateForContent();
@@ -235,7 +235,7 @@
mScheduler->setDisplayPowerState(kPowerStateNormal);
constexpr uint32_t kDisplayArea = 999'999;
- mScheduler->onPrimaryDisplayAreaChanged(kDisplayArea);
+ mScheduler->onActiveDisplayAreaChanged(kDisplayArea);
EXPECT_CALL(mSchedulerCallback, changeRefreshRate(Is120Hz(), _)).Times(1);
mScheduler->chooseRefreshRateForContent();