Merge "SF: Don't cache display modes in HWComposer" into sc-dev
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index 39ae2fd..ec81ff7 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -377,7 +377,7 @@
displayId && mFlinger->getHwComposer().isConnected(*displayId)) {
// The HWC doesn't support present fences, so use the refresh
// timestamp instead.
- const nsecs_t actualPresentTime = mFlinger->getHwComposer().getRefreshTimestamp(*displayId);
+ const nsecs_t actualPresentTime = display->getRefreshTimestamp();
mFlinger->mTimeStats->setPresentTime(layerId, mCurrentFrameNumber, actualPresentTime);
mFlinger->mFrameTracer->traceTimestamp(layerId, getCurrentBufferId(), mCurrentFrameNumber,
actualPresentTime,
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplaySurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplaySurface.h
index 6559ed8..4502eee 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplaySurface.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplaySurface.h
@@ -16,6 +16,7 @@
#pragma once
+#include <ui/Size.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
#include <utils/StrongPointer.h>
@@ -71,7 +72,7 @@
virtual void dumpAsString(String8& result) const = 0;
- virtual void resizeBuffers(const uint32_t w, const uint32_t h) = 0;
+ virtual void resizeBuffers(const ui::Size&) = 0;
virtual const sp<Fence>& getClientTargetAcquireFence() const = 0;
};
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/DisplaySurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/DisplaySurface.h
index 31b5f95..168e433 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/DisplaySurface.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/DisplaySurface.h
@@ -18,6 +18,7 @@
#include <compositionengine/DisplaySurface.h>
#include <gmock/gmock.h>
+#include <ui/Size.h>
#include <utils/String8.h>
namespace android::compositionengine::mock {
@@ -32,7 +33,7 @@
MOCK_METHOD0(advanceFrame, status_t());
MOCK_METHOD0(onFrameCommitted, void());
MOCK_CONST_METHOD1(dumpAsString, void(String8& result));
- MOCK_METHOD2(resizeBuffers, void(uint32_t, uint32_t));
+ MOCK_METHOD1(resizeBuffers, void(const ui::Size&));
MOCK_CONST_METHOD0(getClientTargetAcquireFence, const sp<Fence>&());
};
diff --git a/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp b/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
index b47f7fd..3bef77d 100644
--- a/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
@@ -96,8 +96,7 @@
}
void RenderSurface::setDisplaySize(const ui::Size& size) {
- mDisplaySurface->resizeBuffers(static_cast<uint32_t>(size.width),
- static_cast<uint32_t>(size.height));
+ mDisplaySurface->resizeBuffers(size);
mSize = size;
}
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
index 3133e90..ab00385 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
+++ b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
@@ -85,16 +85,15 @@
MOCK_CONST_METHOD0(updatesDeviceProductInfoOnHotplugReconnect, bool());
MOCK_METHOD2(onVsync, bool(hal::HWDisplayId, int64_t));
MOCK_METHOD2(setVsyncEnabled, void(PhysicalDisplayId, hal::Vsync));
- MOCK_CONST_METHOD1(getRefreshTimestamp, nsecs_t(PhysicalDisplayId));
MOCK_CONST_METHOD1(isConnected, bool(PhysicalDisplayId));
- MOCK_CONST_METHOD1(getModes, DisplayModes(PhysicalDisplayId));
- MOCK_CONST_METHOD1(getActiveMode, DisplayModePtr(PhysicalDisplayId));
+ MOCK_CONST_METHOD1(getModes, std::vector<HWComposer::HWCDisplayMode>(PhysicalDisplayId));
+ MOCK_CONST_METHOD1(getActiveMode, std::optional<hal::HWConfigId>(PhysicalDisplayId));
MOCK_CONST_METHOD1(getColorModes, std::vector<ui::ColorMode>(PhysicalDisplayId));
MOCK_METHOD3(setActiveColorMode, status_t(PhysicalDisplayId, ui::ColorMode, ui::RenderIntent));
MOCK_CONST_METHOD0(isUsingVrComposer, bool());
MOCK_CONST_METHOD1(getDisplayConnectionType, DisplayConnectionType(PhysicalDisplayId));
MOCK_CONST_METHOD1(isVsyncPeriodSwitchSupported, bool(PhysicalDisplayId));
- MOCK_CONST_METHOD1(getDisplayVsyncPeriod, nsecs_t(PhysicalDisplayId));
+ MOCK_CONST_METHOD2(getDisplayVsyncPeriod, status_t(PhysicalDisplayId, nsecs_t*));
MOCK_METHOD4(setActiveModeWithConstraints,
status_t(PhysicalDisplayId, hal::HWConfigId,
const hal::VsyncPeriodChangeConstraints&,
diff --git a/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp b/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
index cd39733..5ef5d7b 100644
--- a/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
@@ -119,9 +119,10 @@
*/
TEST_F(RenderSurfaceTest, setDisplaySizeAppliesChange) {
- EXPECT_CALL(*mDisplaySurface, resizeBuffers(640, 480)).Times(1);
+ const ui::Size size(640, 480);
+ EXPECT_CALL(*mDisplaySurface, resizeBuffers(size)).Times(1);
- mSurface.setDisplaySize(ui::Size(640, 480));
+ mSurface.setDisplaySize(size);
}
/*
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index b4a3ed1..a785968 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -179,6 +179,31 @@
return nullptr;
}
+nsecs_t DisplayDevice::getVsyncPeriodFromHWC() const {
+ const auto physicalId = getPhysicalId();
+ if (!mHwComposer.isConnected(physicalId)) {
+ return 0;
+ }
+
+ nsecs_t vsyncPeriod;
+ const auto status = mHwComposer.getDisplayVsyncPeriod(physicalId, &vsyncPeriod);
+ if (status == NO_ERROR) {
+ return vsyncPeriod;
+ }
+
+ return getActiveMode()->getFps().getPeriodNsecs();
+}
+
+nsecs_t DisplayDevice::getRefreshTimestamp() const {
+ const nsecs_t now = systemTime(CLOCK_MONOTONIC);
+ const auto vsyncPeriodNanos = getVsyncPeriodFromHWC();
+ return now - ((now - mLastHwVsync) % vsyncPeriodNanos);
+}
+
+void DisplayDevice::onVsync(nsecs_t timestamp) {
+ mLastHwVsync = timestamp;
+}
+
ui::Dataspace DisplayDevice::getCompositionDataSpace() const {
return mCompositionDisplay->getState().dataspace;
}
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 6f07964..b4db933 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -176,6 +176,10 @@
// set-top boxes after a hotplug reconnect.
DisplayModePtr getMode(DisplayModeId) const;
+ void onVsync(nsecs_t timestamp);
+ nsecs_t getVsyncPeriodFromHWC() const;
+ nsecs_t getRefreshTimestamp() const;
+
// release HWC resources (if any) for removable displays
void disconnect();
@@ -207,6 +211,8 @@
DisplayModeId mActiveModeId;
const DisplayModes mSupportedModes;
+ std::atomic<nsecs_t> mLastHwVsync = 0;
+
// TODO(b/74619554): Remove special cases for primary display.
const bool mIsPrimary;
diff --git a/services/surfaceflinger/DisplayHardware/DisplayMode.h b/services/surfaceflinger/DisplayHardware/DisplayMode.h
index 61c1b61..31d1245 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayMode.h
+++ b/services/surfaceflinger/DisplayHardware/DisplayMode.h
@@ -22,6 +22,7 @@
#include <android-base/stringprintf.h>
#include <android/configuration.h>
+#include <ui/Size.h>
#include <utils/Timers.h>
#include <cstddef>
@@ -113,6 +114,7 @@
int32_t getWidth() const { return mWidth; }
int32_t getHeight() const { return mHeight; }
+ ui::Size getSize() const { return {mWidth, mHeight}; }
Fps getFps() const { return mFps; }
nsecs_t getVsyncPeriod() const { return mFps.getPeriodNsecs(); }
float getDpiX() const { return mDpiX; }
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
index 3e856bb..f7fc162 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
@@ -58,11 +58,10 @@
FramebufferSurface::FramebufferSurface(HWComposer& hwc, PhysicalDisplayId displayId,
const sp<IGraphicBufferConsumer>& consumer,
- uint32_t maxWidth, uint32_t maxHeight)
+ const ui::Size& size, const ui::Size& maxSize)
: ConsumerBase(consumer),
mDisplayId(displayId),
- mMaxWidth(maxWidth),
- mMaxHeight(maxHeight),
+ mMaxSize(maxSize),
mCurrentBufferSlot(-1),
mCurrentBuffer(),
mCurrentFence(Fence::NO_FENCE),
@@ -77,15 +76,14 @@
mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_FB |
GRALLOC_USAGE_HW_RENDER |
GRALLOC_USAGE_HW_COMPOSER);
- const auto& activeMode = mHwc.getActiveMode(displayId);
- ui::Size limitedSize = limitFramebufferSize(activeMode->getWidth(), activeMode->getHeight());
+ const auto limitedSize = limitFramebufferSize(size);
mConsumer->setDefaultBufferSize(limitedSize.width, limitedSize.height);
mConsumer->setMaxAcquiredBufferCount(
SurfaceFlinger::maxFrameBufferAcquiredBuffers - 1);
}
-void FramebufferSurface::resizeBuffers(uint32_t width, uint32_t height) {
- ui::Size limitedSize = limitFramebufferSize(width, height);
+void FramebufferSurface::resizeBuffers(const ui::Size& newSize) {
+ const auto limitedSize = limitFramebufferSize(newSize);
mConsumer->setDefaultBufferSize(limitedSize.width, limitedSize.height);
}
@@ -181,24 +179,24 @@
}
}
-ui::Size FramebufferSurface::limitFramebufferSize(uint32_t width, uint32_t height) {
- ui::Size framebufferSize(width, height);
- bool wasLimited = true;
- if (width > mMaxWidth && mMaxWidth != 0) {
- float aspectRatio = float(width) / float(height);
- framebufferSize.height = mMaxWidth / aspectRatio;
- framebufferSize.width = mMaxWidth;
+ui::Size FramebufferSurface::limitFramebufferSize(const ui::Size& size) {
+ ui::Size limitedSize = size;
+ bool wasLimited = false;
+ if (size.width > mMaxSize.width && mMaxSize.width != 0) {
+ const float aspectRatio = static_cast<float>(size.width) / size.height;
+ limitedSize.height = mMaxSize.width / aspectRatio;
+ limitedSize.width = mMaxSize.width;
wasLimited = true;
}
- if (height > mMaxHeight && mMaxHeight != 0) {
- float aspectRatio = float(width) / float(height);
- framebufferSize.height = mMaxHeight;
- framebufferSize.width = mMaxHeight * aspectRatio;
+ if (size.height > mMaxSize.height && mMaxSize.height != 0) {
+ const float aspectRatio = static_cast<float>(size.width) / size.height;
+ limitedSize.height = mMaxSize.height;
+ limitedSize.width = mMaxSize.height * aspectRatio;
wasLimited = true;
}
ALOGI_IF(wasLimited, "framebuffer size has been limited to [%dx%d] from [%dx%d]",
- framebufferSize.width, framebufferSize.height, width, height);
- return framebufferSize;
+ limitedSize.width, limitedSize.height, size.width, size.height);
+ return limitedSize;
}
void FramebufferSurface::dumpAsString(String8& result) const {
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
index 759943a..5d1e131 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
@@ -41,8 +41,8 @@
class FramebufferSurface : public ConsumerBase, public compositionengine::DisplaySurface {
public:
FramebufferSurface(HWComposer& hwc, PhysicalDisplayId displayId,
- const sp<IGraphicBufferConsumer>& consumer, uint32_t maxWidth,
- uint32_t maxHeight);
+ const sp<IGraphicBufferConsumer>& consumer, const ui::Size& size,
+ const ui::Size& maxSize);
virtual status_t beginFrame(bool mustRecompose);
virtual status_t prepareFrame(CompositionType compositionType);
@@ -50,7 +50,7 @@
virtual void onFrameCommitted();
virtual void dumpAsString(String8& result) const;
- virtual void resizeBuffers(uint32_t width, uint32_t height);
+ virtual void resizeBuffers(const ui::Size&) override;
virtual const sp<Fence>& getClientTargetAcquireFence() const override;
@@ -62,7 +62,7 @@
virtual void dumpLocked(String8& result, const char* prefix) const;
// Limits the width and height by the maximum width specified in the constructor.
- ui::Size limitFramebufferSize(uint32_t width, uint32_t height);
+ ui::Size limitFramebufferSize(const ui::Size&);
// nextBuffer waits for and then latches the next buffer from the
// BufferQueue and releases the previously latched buffer to the
@@ -74,11 +74,7 @@
// Framebuffer size has a dimension limitation in pixels based on the graphics capabilities of
// the device.
- const uint32_t mMaxWidth;
-
- // Framebuffer size has a dimension limitation in pixels based on the graphics capabilities of
- // the device.
- const uint32_t mMaxHeight;
+ const ui::Size mMaxSize;
// mCurrentBufferIndex is the slot index of the current buffer or
// INVALID_BUFFER_SLOT to indicate that either there is no current buffer
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 46dc54e..b9a8e4b 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -223,8 +223,6 @@
__FUNCTION__, to_string(*displayId).c_str());
{
- std::lock_guard lock(displayData.lastHwVsyncLock);
-
// There have been reports of HWCs that signal several vsync events
// with the same timestamp when turning the display off and on. This
// is a bug in the HWC implementation, but filter the extra events
@@ -295,11 +293,10 @@
hal::DisplayType::PHYSICAL);
newDisplay->setConnected(true);
displayData.hwcDisplay = std::move(newDisplay);
- loadModes(displayData, hwcDisplayId);
}
int32_t HWComposer::getAttribute(hal::HWDisplayId hwcDisplayId, hal::HWConfigId configId,
- hal::Attribute attribute) {
+ hal::Attribute attribute) const {
int32_t value = 0;
auto error = static_cast<hal::Error>(
mComposer->getDisplayAttribute(hwcDisplayId, configId, attribute, &value));
@@ -308,30 +305,6 @@
return value;
}
-void HWComposer::loadModes(DisplayData& displayData, hal::HWDisplayId hwcDisplayId) {
- ALOGV("[HWC display %" PRIu64 "] %s", hwcDisplayId, __FUNCTION__);
-
- std::vector<hal::HWConfigId> configIds;
- auto error = static_cast<hal::Error>(mComposer->getDisplayConfigs(hwcDisplayId, &configIds));
- RETURN_IF_HWC_ERROR_FOR("getDisplayConfigs", error, *toPhysicalDisplayId(hwcDisplayId));
-
- displayData.modes.clear();
- for (auto configId : configIds) {
- auto mode = DisplayMode::Builder(configId)
- .setId(DisplayModeId(displayData.modes.size()))
- .setWidth(getAttribute(hwcDisplayId, configId, hal::Attribute::WIDTH))
- .setHeight(getAttribute(hwcDisplayId, configId, hal::Attribute::HEIGHT))
- .setVsyncPeriod(getAttribute(hwcDisplayId, configId,
- hal::Attribute::VSYNC_PERIOD))
- .setDpiX(getAttribute(hwcDisplayId, configId, hal::Attribute::DPI_X))
- .setDpiY(getAttribute(hwcDisplayId, configId, hal::Attribute::DPI_Y))
- .setConfigGroup(getAttribute(hwcDisplayId, configId,
- hal::Attribute::CONFIG_GROUP))
- .build();
- displayData.modes.push_back(std::move(mode));
- }
-}
-
HWC2::Layer* HWComposer::createLayer(HalDisplayId displayId) {
RETURN_IF_INVALID_DISPLAY(displayId, nullptr);
@@ -348,55 +321,50 @@
RETURN_IF_HWC_ERROR(error, displayId);
}
-nsecs_t HWComposer::getRefreshTimestamp(PhysicalDisplayId displayId) const {
- RETURN_IF_INVALID_DISPLAY(displayId, 0);
- const auto& displayData = mDisplayData.at(displayId);
- // this returns the last refresh timestamp.
- // if the last one is not available, we estimate it based on
- // the refresh period and whatever closest timestamp we have.
- std::lock_guard lock(displayData.lastHwVsyncLock);
- nsecs_t now = systemTime(CLOCK_MONOTONIC);
- auto vsyncPeriodNanos = getDisplayVsyncPeriod(displayId);
- return now - ((now - displayData.lastHwVsync) % vsyncPeriodNanos);
-}
-
bool HWComposer::isConnected(PhysicalDisplayId displayId) const {
RETURN_IF_INVALID_DISPLAY(displayId, false);
return mDisplayData.at(displayId).hwcDisplay->isConnected();
}
-DisplayModes HWComposer::getModes(PhysicalDisplayId displayId) const {
+std::vector<HWComposer::HWCDisplayMode> HWComposer::getModes(PhysicalDisplayId displayId) const {
RETURN_IF_INVALID_DISPLAY(displayId, {});
- // We cache the modes when the DisplayData is created on hotplug. If the modes need to
- // change HWC will send a hotplug event which will recreate displayData.
- return mDisplayData.at(displayId).modes;
+ const auto hwcDisplayId = mDisplayData.at(displayId).hwcDisplay->getId();
+ std::vector<hal::HWConfigId> configIds;
+ auto error = static_cast<hal::Error>(mComposer->getDisplayConfigs(hwcDisplayId, &configIds));
+ RETURN_IF_HWC_ERROR_FOR("getDisplayConfigs", error, *toPhysicalDisplayId(hwcDisplayId), {});
+
+ std::vector<HWCDisplayMode> modes;
+ modes.reserve(configIds.size());
+ for (auto configId : configIds) {
+ modes.push_back(HWCDisplayMode{
+ .hwcId = configId,
+ .width = getAttribute(hwcDisplayId, configId, hal::Attribute::WIDTH),
+ .height = getAttribute(hwcDisplayId, configId, hal::Attribute::HEIGHT),
+ .vsyncPeriod = getAttribute(hwcDisplayId, configId, hal::Attribute::VSYNC_PERIOD),
+ .dpiX = getAttribute(hwcDisplayId, configId, hal::Attribute::DPI_X),
+ .dpiY = getAttribute(hwcDisplayId, configId, hal::Attribute::DPI_Y),
+ .configGroup = getAttribute(hwcDisplayId, configId, hal::Attribute::CONFIG_GROUP),
+ });
+ }
+
+ return modes;
}
-DisplayModePtr HWComposer::getActiveMode(PhysicalDisplayId displayId) const {
- RETURN_IF_INVALID_DISPLAY(displayId, nullptr);
+std::optional<hal::HWConfigId> HWComposer::getActiveMode(PhysicalDisplayId displayId) const {
+ RETURN_IF_INVALID_DISPLAY(displayId, std::nullopt);
const auto hwcId = *fromPhysicalDisplayId(displayId);
ALOGV("[%" PRIu64 "] getActiveMode", hwcId);
hal::HWConfigId configId;
auto error = static_cast<hal::Error>(mComposer->getActiveConfig(hwcId, &configId));
- const auto& modes = mDisplayData.at(displayId).modes;
if (error == hal::Error::BAD_CONFIG) {
LOG_DISPLAY_ERROR(displayId, "No active mode");
- return nullptr;
+ return std::nullopt;
}
- RETURN_IF_HWC_ERROR(error, displayId, nullptr);
-
- const auto it = std::find_if(modes.begin(), modes.end(),
- [configId](auto mode) { return mode->getHwcId() == configId; });
- if (it == modes.end()) {
- LOG_DISPLAY_ERROR(displayId, "Unknown mode");
- return nullptr;
- }
-
- return *it;
+ return configId;
}
// Composer 2.4
@@ -421,27 +389,20 @@
return mDisplayData.at(displayId).hwcDisplay->isVsyncPeriodSwitchSupported();
}
-nsecs_t HWComposer::getDisplayVsyncPeriod(PhysicalDisplayId displayId) const {
+status_t HWComposer::getDisplayVsyncPeriod(PhysicalDisplayId displayId,
+ nsecs_t* outVsyncPeriod) const {
RETURN_IF_INVALID_DISPLAY(displayId, 0);
- if (isVsyncPeriodSwitchSupported(displayId)) {
- const auto hwcId = *fromPhysicalDisplayId(displayId);
- Hwc2::VsyncPeriodNanos vsyncPeriodNanos = 0;
- auto error =
- static_cast<hal::Error>(mComposer->getDisplayVsyncPeriod(hwcId, &vsyncPeriodNanos));
- RETURN_IF_HWC_ERROR(error, displayId, 0);
- return static_cast<nsecs_t>(vsyncPeriodNanos);
+ if (!isVsyncPeriodSwitchSupported(displayId)) {
+ return INVALID_OPERATION;
}
-
- // Get the default vsync period
- auto mode = getActiveMode(displayId);
-
- if (!mode) {
- // HWC has updated the display modes and hasn't notified us yet.
- RETURN_IF_HWC_ERROR(hal::Error::BAD_CONFIG, displayId, 0);
- }
-
- return mode->getVsyncPeriod();
+ const auto hwcId = *fromPhysicalDisplayId(displayId);
+ Hwc2::VsyncPeriodNanos vsyncPeriodNanos = 0;
+ auto error =
+ static_cast<hal::Error>(mComposer->getDisplayVsyncPeriod(hwcId, &vsyncPeriodNanos));
+ RETURN_IF_HWC_ERROR(error, displayId, 0);
+ *outVsyncPeriod = static_cast<nsecs_t>(vsyncPeriodNanos);
+ return NO_ERROR;
}
std::vector<ui::ColorMode> HWComposer::getColorModes(PhysicalDisplayId displayId) const {
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 1ffe276..f9c8e2e 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -83,6 +83,16 @@
ClientTargetProperty clientTargetProperty;
};
+ struct HWCDisplayMode {
+ hal::HWConfigId hwcId;
+ int32_t width = -1;
+ int32_t height = -1;
+ nsecs_t vsyncPeriod = -1;
+ int32_t dpiX = -1;
+ int32_t dpiY = -1;
+ int32_t configGroup = -1;
+ };
+
virtual ~HWComposer();
virtual void setConfiguration(HWC2::ComposerCallback* callback, int32_t sequenceId) = 0;
@@ -182,12 +192,11 @@
virtual bool onVsync(hal::HWDisplayId, int64_t timestamp) = 0;
virtual void setVsyncEnabled(PhysicalDisplayId, hal::Vsync enabled) = 0;
- virtual nsecs_t getRefreshTimestamp(PhysicalDisplayId) const = 0;
virtual bool isConnected(PhysicalDisplayId) const = 0;
- virtual DisplayModes getModes(PhysicalDisplayId) const = 0;
+ virtual std::vector<HWCDisplayMode> getModes(PhysicalDisplayId) const = 0;
- virtual DisplayModePtr getActiveMode(PhysicalDisplayId) const = 0;
+ virtual std::optional<hal::HWConfigId> getActiveMode(PhysicalDisplayId) const = 0;
virtual std::vector<ui::ColorMode> getColorModes(PhysicalDisplayId) const = 0;
@@ -197,7 +206,8 @@
// Composer 2.4
virtual DisplayConnectionType getDisplayConnectionType(PhysicalDisplayId) const = 0;
virtual bool isVsyncPeriodSwitchSupported(PhysicalDisplayId) const = 0;
- virtual nsecs_t getDisplayVsyncPeriod(PhysicalDisplayId) const = 0;
+ virtual status_t getDisplayVsyncPeriod(PhysicalDisplayId displayId,
+ nsecs_t* outVsyncPeriod) const = 0;
virtual status_t setActiveModeWithConstraints(PhysicalDisplayId, hal::HWConfigId,
const hal::VsyncPeriodChangeConstraints&,
hal::VsyncPeriodChangeTimeline* outTimeline) = 0;
@@ -314,12 +324,11 @@
bool onVsync(hal::HWDisplayId, int64_t timestamp) override;
void setVsyncEnabled(PhysicalDisplayId, hal::Vsync enabled) override;
- nsecs_t getRefreshTimestamp(PhysicalDisplayId) const override;
bool isConnected(PhysicalDisplayId) const override;
- DisplayModes getModes(PhysicalDisplayId) const override;
+ std::vector<HWCDisplayMode> getModes(PhysicalDisplayId) const override;
- DisplayModePtr getActiveMode(PhysicalDisplayId) const override;
+ std::optional<hal::HWConfigId> getActiveMode(PhysicalDisplayId) const override;
std::vector<ui::ColorMode> getColorModes(PhysicalDisplayId) const override;
@@ -328,7 +337,8 @@
// Composer 2.4
DisplayConnectionType getDisplayConnectionType(PhysicalDisplayId) const override;
bool isVsyncPeriodSwitchSupported(PhysicalDisplayId) const override;
- nsecs_t getDisplayVsyncPeriod(PhysicalDisplayId displayId) const override;
+ status_t getDisplayVsyncPeriod(PhysicalDisplayId displayId,
+ nsecs_t* outVsyncPeriod) const override;
status_t setActiveModeWithConstraints(PhysicalDisplayId, hal::HWConfigId,
const hal::VsyncPeriodChangeConstraints&,
hal::VsyncPeriodChangeTimeline* outTimeline) override;
@@ -365,7 +375,6 @@
std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
buffer_handle_t outbufHandle = nullptr;
sp<Fence> outbufAcquireFence = Fence::NO_FENCE;
- DisplayModes modes;
bool validateWasSkipped;
hal::Error presentError;
@@ -375,8 +384,7 @@
std::mutex vsyncEnabledLock;
hal::Vsync vsyncEnabled GUARDED_BY(vsyncEnabledLock) = hal::Vsync::DISABLE;
- mutable std::mutex lastHwVsyncLock;
- nsecs_t lastHwVsync GUARDED_BY(lastHwVsyncLock) = 0;
+ nsecs_t lastHwVsync = 0;
};
std::optional<DisplayIdentificationInfo> onHotplugConnect(hal::HWDisplayId);
@@ -384,8 +392,7 @@
bool shouldIgnoreHotplugConnect(hal::HWDisplayId, bool hasDisplayIdentificationData) const;
int32_t getAttribute(hal::HWDisplayId hwcDisplayId, hal::HWConfigId configId,
- hal::Attribute attribute);
- void loadModes(DisplayData& displayData, hal::HWDisplayId hwcDisplayId);
+ hal::Attribute attribute) const;
void loadCapabilities();
void loadLayerMetadataSupport();
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
index 2ac67cb..e26ab11 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
@@ -291,11 +291,11 @@
void VirtualDisplaySurface::dumpAsString(String8& /* result */) const {
}
-void VirtualDisplaySurface::resizeBuffers(const uint32_t w, const uint32_t h) {
- mQueueBufferOutput.width = w;
- mQueueBufferOutput.height = h;
- mSinkBufferWidth = w;
- mSinkBufferHeight = h;
+void VirtualDisplaySurface::resizeBuffers(const ui::Size& newSize) {
+ mQueueBufferOutput.width = newSize.width;
+ mQueueBufferOutput.height = newSize.height;
+ mSinkBufferWidth = newSize.width;
+ mSinkBufferHeight = newSize.height;
}
const sp<Fence>& VirtualDisplaySurface::getClientTargetAcquireFence() const {
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
index fba0e3b..bbb6306 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
@@ -90,7 +90,7 @@
virtual status_t advanceFrame();
virtual void onFrameCommitted();
virtual void dumpAsString(String8& result) const;
- virtual void resizeBuffers(const uint32_t w, const uint32_t h);
+ virtual void resizeBuffers(const ui::Size&) override;
virtual const sp<Fence>& getClientTargetAcquireFence() const override;
private:
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index d06f247..e9b5875 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -68,6 +68,7 @@
#include <ui/ColorSpace.h>
#include <ui/DebugUtils.h>
#include <ui/DisplayConfig.h>
+#include <ui/DisplayId.h>
#include <ui/DisplayInfo.h>
#include <ui/DisplayStatInfo.h>
#include <ui/DisplayState.h>
@@ -1581,12 +1582,11 @@
}
nsecs_t SurfaceFlinger::getVsyncPeriodFromHWC() const {
- const auto displayId = getInternalDisplayIdLocked();
- if (!displayId || !getHwComposer().isConnected(*displayId)) {
- return 0;
+ if (const auto display = getDefaultDisplayDeviceLocked()) {
+ return display->getVsyncPeriodFromHWC();
}
- return getHwComposer().getDisplayVsyncPeriod(*displayId);
+ return 0;
}
void SurfaceFlinger::onVsyncReceived(int32_t sequenceId, hal::HWDisplayId hwcDisplayId,
@@ -1600,6 +1600,12 @@
return;
}
+ if (const auto displayId = getHwComposer().toPhysicalDisplayId(hwcDisplayId)) {
+ auto token = getPhysicalDisplayTokenLocked(*displayId);
+ auto display = getDisplayDeviceLocked(token);
+ display->onVsync(timestamp);
+ }
+
if (!getHwComposer().onVsync(hwcDisplayId, timestamp)) {
return;
}
@@ -2215,8 +2221,7 @@
} else if (isDisplayConnected) {
// The HWC doesn't support present fences, so use the refresh
// timestamp instead.
- const nsecs_t presentTime =
- getHwComposer().getRefreshTimestamp(display->getPhysicalId());
+ const nsecs_t presentTime = display->getRefreshTimestamp();
mAnimFrameTracker.setActualPresentTime(presentTime);
}
mAnimFrameTracker.advanceFrame();
@@ -2353,6 +2358,24 @@
// here the transaction has been committed
}
+DisplayModes SurfaceFlinger::loadSupportedDisplayModes(PhysicalDisplayId displayId) const {
+ const auto hwcModes = getHwComposer().getModes(displayId);
+ DisplayModes modes;
+ size_t nextModeId = 0;
+ for (const auto& hwcMode : hwcModes) {
+ modes.push_back(DisplayMode::Builder(hwcMode.hwcId)
+ .setId(DisplayModeId{nextModeId++})
+ .setWidth(hwcMode.width)
+ .setHeight(hwcMode.height)
+ .setVsyncPeriod(hwcMode.vsyncPeriod)
+ .setDpiX(hwcMode.dpiX)
+ .setDpiY(hwcMode.dpiY)
+ .setConfigGroup(hwcMode.configGroup)
+ .build());
+ }
+ return modes;
+}
+
void SurfaceFlinger::processDisplayHotplugEventsLocked() {
for (const auto& event : mPendingHotplugEvents) {
std::optional<DisplayIdentificationInfo> info =
@@ -2366,8 +2389,14 @@
const auto it = mPhysicalDisplayTokens.find(displayId);
if (event.connection == hal::Connection::CONNECTED) {
- auto supportedModes = getHwComposer().getModes(displayId);
- const auto activeMode = getHwComposer().getActiveMode(displayId);
+ auto supportedModes = loadSupportedDisplayModes(displayId);
+ const auto activeModeHwcId = getHwComposer().getActiveMode(displayId);
+ LOG_ALWAYS_FATAL_IF(!activeModeHwcId, "HWC returned no active config");
+
+ const auto activeMode = *std::find_if(supportedModes.begin(), supportedModes.end(),
+ [activeModeHwcId](const DisplayModePtr& mode) {
+ return mode->getHwcId() == *activeModeHwcId;
+ });
// TODO(b/175678215) Handle the case when activeMode is not in supportedModes
if (it == mPhysicalDisplayTokens.end()) {
@@ -2518,17 +2547,15 @@
void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken,
const DisplayDeviceState& state) {
- int width = 0;
- int height = 0;
+ ui::Size resolution(0, 0);
ui::PixelFormat pixelFormat = static_cast<ui::PixelFormat>(PIXEL_FORMAT_UNKNOWN);
if (state.physical) {
- width = state.physical->activeMode->getWidth();
- height = state.physical->activeMode->getHeight();
+ resolution = state.physical->activeMode->getSize();
pixelFormat = static_cast<ui::PixelFormat>(PIXEL_FORMAT_RGBA_8888);
} else if (state.surface != nullptr) {
- int status = state.surface->query(NATIVE_WINDOW_WIDTH, &width);
+ int status = state.surface->query(NATIVE_WINDOW_WIDTH, &resolution.width);
ALOGE_IF(status != NO_ERROR, "Unable to query width (%d)", status);
- status = state.surface->query(NATIVE_WINDOW_HEIGHT, &height);
+ status = state.surface->query(NATIVE_WINDOW_HEIGHT, &resolution.height);
ALOGE_IF(status != NO_ERROR, "Unable to query height (%d)", status);
int intPixelFormat;
status = state.surface->query(NATIVE_WINDOW_FORMAT, &intPixelFormat);
@@ -2545,7 +2572,7 @@
if (const auto& physical = state.physical) {
builder.setPhysical({physical->id, physical->type});
}
- builder.setPixels(ui::Size(width, height));
+ builder.setPixels(resolution);
builder.setPixelFormat(pixelFormat);
builder.setIsSecure(state.isSecure);
builder.setLayerStackId(state.layerStack);
@@ -2580,7 +2607,8 @@
const auto physicalId = PhysicalDisplayId::tryCast(displayId);
LOG_FATAL_IF(!physicalId);
displaySurface = new FramebufferSurface(getHwComposer(), *physicalId, bqConsumer,
- maxGraphicsWidth, maxGraphicsHeight);
+ state.physical->activeMode->getSize(),
+ ui::Size(maxGraphicsWidth, maxGraphicsHeight));
producer = bqProducer;
}
@@ -4823,15 +4851,12 @@
" gpu_to_cpu_unsupported : %d\n",
mTransactionFlags.load(), !mGpuToCpuSupported);
- if (const auto displayId = getInternalDisplayIdLocked();
- displayId && getHwComposer().isConnected(*displayId)) {
- const auto activeConfig = getHwComposer().getActiveMode(*displayId);
+ if (const auto display = getDefaultDisplayDeviceLocked()) {
std::string fps, xDpi, yDpi;
- if (activeConfig) {
- const auto vsyncPeriod = getHwComposer().getDisplayVsyncPeriod(*displayId);
- fps = base::StringPrintf("%s", to_string(Fps::fromPeriodNsecs(vsyncPeriod)).c_str());
- xDpi = base::StringPrintf("%.2f", activeConfig->getDpiX());
- yDpi = base::StringPrintf("%.2f", activeConfig->getDpiY());
+ if (const auto activeMode = display->getActiveMode()) {
+ fps = to_string(activeMode->getFps());
+ xDpi = base::StringPrintf("%.2f", activeMode->getDpiX());
+ yDpi = base::StringPrintf("%.2f", activeMode->getDpiY());
} else {
fps = "unknown";
xDpi = "unknown";
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 8c26c9b..66fc4f0 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -902,6 +902,7 @@
/*
* Display management
*/
+ DisplayModes loadSupportedDisplayModes(PhysicalDisplayId) const;
sp<DisplayDevice> setupNewDisplayDeviceInternal(
const wp<IBinder>& displayToken,
std::shared_ptr<compositionengine::Display> compositionDisplay,
diff --git a/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp b/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp
index 4d7b396..efa15f1 100644
--- a/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp
+++ b/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp
@@ -63,9 +63,7 @@
// Mock test helpers
using ::testing::_;
-using ::testing::AtLeast;
using ::testing::DoAll;
-using ::testing::Invoke;
using ::testing::Return;
using ::testing::SetArgPointee;
@@ -74,9 +72,11 @@
using Display = V2_1::Display;
///////////////////////////////////////////////
-
-constexpr PhysicalDisplayId kPrimaryDisplayId = PhysicalDisplayId::fromPort(PRIMARY_DISPLAY);
-constexpr PhysicalDisplayId kExternalDisplayId = PhysicalDisplayId::fromPort(EXTERNAL_DISPLAY);
+constexpr PhysicalDisplayId physicalIdFromHwcDisplayId(Display hwcId) {
+ return PhysicalDisplayId::fromPort(hwcId);
+}
+constexpr PhysicalDisplayId kPrimaryDisplayId = physicalIdFromHwcDisplayId(PRIMARY_DISPLAY);
+constexpr PhysicalDisplayId kExternalDisplayId = physicalIdFromHwcDisplayId(EXTERNAL_DISPLAY);
struct TestColor {
public:
@@ -158,7 +158,7 @@
self->mReceivedDisplayEvents.push_back(buffer[i]);
}
}
- ALOGD_IF(n < 0, "Error reading events (%s)\n", strerror(-n));
+ ALOGD_IF(n < 0, "Error reading events (%s)", strerror(-n));
return 1;
}
@@ -174,7 +174,7 @@
void setExpectationsForConfigs(Display display, std::vector<TestConfig> testConfigs,
Config activeConfig, V2_4::VsyncPeriodNanos defaultVsyncPeriod) {
std::vector<Config> configIds;
- for (int i = 0; i < testConfigs.size(); i++) {
+ for (size_t i = 0; i < testConfigs.size(); i++) {
configIds.push_back(testConfigs[i].id);
EXPECT_CALL(*mMockComposer,
@@ -269,10 +269,10 @@
mMockComposer = nullptr;
}
- void waitForDisplayTransaction() {
+ void waitForDisplayTransaction(Display display) {
// Both a refresh and a vsync event are needed to apply pending display
// transactions.
- mFakeComposerClient->refreshDisplay(EXTERNAL_DISPLAY);
+ mFakeComposerClient->refreshDisplay(display);
mFakeComposerClient->runVSyncAndWait();
// Extra vsync and wait to avoid a 10% flake due to a race.
@@ -291,7 +291,7 @@
mReceivedDisplayEvents.pop_front();
ALOGV_IF(event.header.type == DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG,
- "event hotplug: displayId %s, connected %d\t",
+ "event hotplug: displayId %s, connected %d",
to_string(event.header.displayId).c_str(), event.hotplug.connected);
if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG &&
@@ -314,7 +314,7 @@
mReceivedDisplayEvents.pop_front();
ALOGV_IF(event.header.type == DisplayEventReceiver::DISPLAY_EVENT_CONFIG_CHANGED,
- "event config: displayId %s, configId %d\t",
+ "event config: displayId %s, configId %d",
to_string(event.header.displayId).c_str(), event.config.configId);
if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_CONFIG_CHANGED &&
@@ -341,7 +341,7 @@
mFakeComposerClient->hotplugDisplay(EXTERNAL_DISPLAY,
V2_1::IComposerCallback::Connection::CONNECTED);
- waitForDisplayTransaction();
+ waitForDisplayTransaction(EXTERNAL_DISPLAY);
EXPECT_TRUE(waitForHotplugEvent(EXTERNAL_DISPLAY, true));
{
@@ -372,7 +372,7 @@
mFakeComposerClient->hotplugDisplay(EXTERNAL_DISPLAY,
V2_1::IComposerCallback::Connection::DISCONNECTED);
- waitForDisplayTransaction();
+ waitForDisplayTransaction(EXTERNAL_DISPLAY);
mFakeComposerClient->clearFrames();
EXPECT_TRUE(waitForHotplugEvent(EXTERNAL_DISPLAY, false));
@@ -403,7 +403,7 @@
mFakeComposerClient->hotplugDisplay(EXTERNAL_DISPLAY,
V2_1::IComposerCallback::Connection::CONNECTED);
- waitForDisplayTransaction();
+ waitForDisplayTransaction(EXTERNAL_DISPLAY);
EXPECT_TRUE(waitForHotplugEvent(EXTERNAL_DISPLAY, true));
const auto display = SurfaceComposerClient::getPhysicalDisplayToken(kExternalDisplayId);
@@ -456,7 +456,7 @@
config.refreshRate,
config.refreshRate,
config.refreshRate));
- waitForDisplayTransaction();
+ waitForDisplayTransaction(EXTERNAL_DISPLAY);
EXPECT_TRUE(waitForConfigChangedEvent(EXTERNAL_DISPLAY, i));
break;
}
@@ -487,7 +487,7 @@
mFakeComposerClient->hotplugDisplay(EXTERNAL_DISPLAY,
V2_1::IComposerCallback::Connection::DISCONNECTED);
- waitForDisplayTransaction();
+ waitForDisplayTransaction(EXTERNAL_DISPLAY);
mFakeComposerClient->clearFrames();
EXPECT_TRUE(waitForHotplugEvent(EXTERNAL_DISPLAY, false));
}
@@ -510,7 +510,7 @@
mFakeComposerClient->hotplugDisplay(EXTERNAL_DISPLAY,
V2_1::IComposerCallback::Connection::CONNECTED);
- waitForDisplayTransaction();
+ waitForDisplayTransaction(EXTERNAL_DISPLAY);
EXPECT_TRUE(waitForHotplugEvent(EXTERNAL_DISPLAY, true));
const auto display = SurfaceComposerClient::getPhysicalDisplayToken(kExternalDisplayId);
@@ -562,7 +562,7 @@
config.refreshRate,
config.refreshRate,
config.refreshRate));
- waitForDisplayTransaction();
+ waitForDisplayTransaction(EXTERNAL_DISPLAY);
EXPECT_TRUE(waitForConfigChangedEvent(EXTERNAL_DISPLAY, i));
break;
}
@@ -593,7 +593,7 @@
mFakeComposerClient->hotplugDisplay(EXTERNAL_DISPLAY,
V2_1::IComposerCallback::Connection::DISCONNECTED);
- waitForDisplayTransaction();
+ waitForDisplayTransaction(EXTERNAL_DISPLAY);
mFakeComposerClient->clearFrames();
EXPECT_TRUE(waitForHotplugEvent(EXTERNAL_DISPLAY, false));
}
@@ -626,7 +626,7 @@
mFakeComposerClient->hotplugDisplay(EXTERNAL_DISPLAY,
V2_1::IComposerCallback::Connection::CONNECTED);
- waitForDisplayTransaction();
+ waitForDisplayTransaction(EXTERNAL_DISPLAY);
EXPECT_TRUE(waitForHotplugEvent(EXTERNAL_DISPLAY, true));
const auto display = SurfaceComposerClient::getPhysicalDisplayToken(kExternalDisplayId);
@@ -669,7 +669,7 @@
.WillOnce(Return(V2_1::Error::NONE));
}
- for (int i = 0; i < configs.size(); i++) {
+ for (size_t i = 0; i < configs.size(); i++) {
const auto& config = configs[i];
if (config.resolution.getWidth() == 800 && config.refreshRate == 1e9f / 11'111'111) {
EXPECT_EQ(NO_ERROR,
@@ -679,7 +679,7 @@
configs[i].refreshRate,
configs[i].refreshRate,
configs[i].refreshRate));
- waitForDisplayTransaction();
+ waitForDisplayTransaction(EXTERNAL_DISPLAY);
EXPECT_TRUE(waitForConfigChangedEvent(EXTERNAL_DISPLAY, i));
break;
}
@@ -726,7 +726,7 @@
config.refreshRate,
config.refreshRate,
config.refreshRate));
- waitForDisplayTransaction();
+ waitForDisplayTransaction(EXTERNAL_DISPLAY);
EXPECT_TRUE(waitForConfigChangedEvent(EXTERNAL_DISPLAY, i));
break;
}
@@ -773,7 +773,7 @@
config.refreshRate,
config.refreshRate,
config.refreshRate));
- waitForDisplayTransaction();
+ waitForDisplayTransaction(EXTERNAL_DISPLAY);
EXPECT_TRUE(waitForConfigChangedEvent(EXTERNAL_DISPLAY, i));
break;
}
@@ -804,7 +804,7 @@
mFakeComposerClient->hotplugDisplay(EXTERNAL_DISPLAY,
V2_1::IComposerCallback::Connection::DISCONNECTED);
- waitForDisplayTransaction();
+ waitForDisplayTransaction(EXTERNAL_DISPLAY);
mFakeComposerClient->clearFrames();
EXPECT_TRUE(waitForHotplugEvent(EXTERNAL_DISPLAY, false));
}
@@ -815,7 +815,7 @@
mFakeComposerClient->hotplugDisplay(PRIMARY_DISPLAY,
V2_1::IComposerCallback::Connection::DISCONNECTED);
- waitForDisplayTransaction();
+ waitForDisplayTransaction(PRIMARY_DISPLAY);
EXPECT_TRUE(waitForHotplugEvent(PRIMARY_DISPLAY, false));
{
@@ -840,7 +840,7 @@
mFakeComposerClient->hotplugDisplay(PRIMARY_DISPLAY,
V2_1::IComposerCallback::Connection::CONNECTED);
- waitForDisplayTransaction();
+ waitForDisplayTransaction(PRIMARY_DISPLAY);
EXPECT_TRUE(waitForHotplugEvent(PRIMARY_DISPLAY, true));
@@ -856,6 +856,121 @@
}
}
+ void Test_SubsequentHotplugConnectUpdatesDisplay(Display hwcDisplayId) {
+ ALOGD("DisplayTest::Test_SubsequentHotplugConnectUpdatesDisplay");
+
+ // Send a hotplug connected event to set up the initial display modes.
+ // The primary display is already connected so this will update it.
+ // If we're running the test of an external display this will create it.
+ setExpectationsForConfigs(hwcDisplayId,
+ {{.id = 1,
+ .w = 800,
+ .h = 1600,
+ .vsyncPeriod = 11'111'111,
+ .group = 1}},
+ /* activeConfig */ 1, 11'111'111);
+
+ mFakeComposerClient->hotplugDisplay(hwcDisplayId,
+ V2_1::IComposerCallback::Connection::CONNECTED);
+ waitForDisplayTransaction(hwcDisplayId);
+ EXPECT_TRUE(waitForHotplugEvent(hwcDisplayId, true));
+
+ const auto displayId = physicalIdFromHwcDisplayId(hwcDisplayId);
+ const auto display = SurfaceComposerClient::getPhysicalDisplayToken(displayId);
+ EXPECT_FALSE(display == nullptr);
+
+ // Verify that the active mode and the supported moded are updated
+ {
+ DisplayConfig config;
+ EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayConfig(display, &config));
+ EXPECT_EQ(ui::Size(800, 1600), config.resolution);
+ EXPECT_EQ(1e9f / 11'111'111, config.refreshRate);
+
+ Vector<DisplayConfig> configs;
+ EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayConfigs(display, &configs));
+ EXPECT_EQ(configs.size(), 1);
+ }
+
+ // Send another hotplug connected event
+ setExpectationsForConfigs(hwcDisplayId,
+ {
+ {.id = 1,
+ .w = 800,
+ .h = 1600,
+ .vsyncPeriod = 16'666'666,
+ .group = 1},
+ {.id = 2,
+ .w = 800,
+ .h = 1600,
+ .vsyncPeriod = 11'111'111,
+ .group = 1},
+ {.id = 3,
+ .w = 800,
+ .h = 1600,
+ .vsyncPeriod = 8'333'333,
+ .group = 1},
+ },
+ /* activeConfig */ 1, 16'666'666);
+
+ mFakeComposerClient->hotplugDisplay(hwcDisplayId,
+ V2_1::IComposerCallback::Connection::CONNECTED);
+ waitForDisplayTransaction(hwcDisplayId);
+ EXPECT_TRUE(waitForHotplugEvent(hwcDisplayId, true));
+
+ // Verify that the active mode and the supported moded are updated
+ {
+ DisplayConfig config;
+ EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayConfig(display, &config));
+ EXPECT_EQ(ui::Size(800, 1600), config.resolution);
+ EXPECT_EQ(1e9f / 16'666'666, config.refreshRate);
+ }
+
+ Vector<DisplayConfig> configs;
+ EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayConfigs(display, &configs));
+ EXPECT_EQ(configs.size(), 3);
+
+ EXPECT_EQ(ui::Size(800, 1600), configs[0].resolution);
+ EXPECT_EQ(1e9f / 16'666'666, configs[0].refreshRate);
+
+ EXPECT_EQ(ui::Size(800, 1600), configs[1].resolution);
+ EXPECT_EQ(1e9f / 11'111'111, configs[1].refreshRate);
+
+ EXPECT_EQ(ui::Size(800, 1600), configs[2].resolution);
+ EXPECT_EQ(1e9f / 8'333'333, configs[2].refreshRate);
+
+ // Verify that we are able to switch to any of the modes
+ for (int i = configs.size() - 1; i >= 0; i--) {
+ const auto hwcId = i + 1;
+ // Set up HWC expectations for the mode change
+ if (mIs2_4Client) {
+ EXPECT_CALL(*mMockComposer,
+ setActiveConfigWithConstraints(hwcDisplayId, hwcId, _, _))
+ .WillOnce(Return(V2_4::Error::NONE));
+ } else {
+ EXPECT_CALL(*mMockComposer, setActiveConfig(hwcDisplayId, hwcId))
+ .WillOnce(Return(V2_1::Error::NONE));
+ }
+
+ EXPECT_EQ(NO_ERROR,
+ SurfaceComposerClient::setDesiredDisplayConfigSpecs(display, i, false,
+ configs[i].refreshRate,
+ configs[i].refreshRate,
+ configs[i].refreshRate,
+ configs[i].refreshRate));
+ // We need to refresh twice - once to apply the pending mode change request,
+ // and once to process the change.
+ waitForDisplayTransaction(hwcDisplayId);
+ waitForDisplayTransaction(hwcDisplayId);
+ EXPECT_TRUE(waitForConfigChangedEvent(hwcDisplayId, i))
+ << "Failure while switching to mode " << i;
+
+ DisplayConfig config;
+ EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayConfig(display, &config));
+ EXPECT_EQ(ui::Size(800, 1600), config.resolution);
+ EXPECT_EQ(configs[i].refreshRate, config.refreshRate);
+ }
+ }
+
sp<V2_1::IComposer> mFakeService;
sp<SurfaceComposerClient> mComposerClient;
@@ -911,6 +1026,14 @@
Test_HotplugPrimaryDisplay();
}
+TEST_F(DisplayTest_2_1, SubsequentHotplugConnectUpdatesPrimaryDisplay) {
+ Test_SubsequentHotplugConnectUpdatesDisplay(PRIMARY_DISPLAY);
+}
+
+TEST_F(DisplayTest_2_1, SubsequentHotplugConnectUpdatesExternalDisplay) {
+ Test_SubsequentHotplugConnectUpdatesDisplay(EXTERNAL_DISPLAY);
+}
+
using DisplayTest_2_2 = DisplayTest<FakeComposerService_2_2>;
TEST_F(DisplayTest_2_2, HotplugOneConfig) {
@@ -933,6 +1056,14 @@
Test_HotplugPrimaryDisplay();
}
+TEST_F(DisplayTest_2_2, SubsequentHotplugConnectUpdatesPrimaryDisplay) {
+ Test_SubsequentHotplugConnectUpdatesDisplay(PRIMARY_DISPLAY);
+}
+
+TEST_F(DisplayTest_2_2, SubsequentHotplugConnectUpdatesExternalDisplay) {
+ Test_SubsequentHotplugConnectUpdatesDisplay(EXTERNAL_DISPLAY);
+}
+
using DisplayTest_2_3 = DisplayTest<FakeComposerService_2_3>;
TEST_F(DisplayTest_2_3, HotplugOneConfig) {
@@ -955,6 +1086,14 @@
Test_HotplugPrimaryDisplay();
}
+TEST_F(DisplayTest_2_3, SubsequentHotplugConnectUpdatesPrimaryDisplay) {
+ Test_SubsequentHotplugConnectUpdatesDisplay(PRIMARY_DISPLAY);
+}
+
+TEST_F(DisplayTest_2_3, SubsequentHotplugConnectUpdatesExternalDisplay) {
+ Test_SubsequentHotplugConnectUpdatesDisplay(EXTERNAL_DISPLAY);
+}
+
using DisplayTest_2_4 = DisplayTest<FakeComposerService_2_4>;
TEST_F(DisplayTest_2_4, HotplugOneConfig) {
@@ -977,6 +1116,14 @@
Test_HotplugPrimaryDisplay();
}
+TEST_F(DisplayTest_2_4, SubsequentHotplugConnectUpdatesPrimaryDisplay) {
+ Test_SubsequentHotplugConnectUpdatesDisplay(PRIMARY_DISPLAY);
+}
+
+TEST_F(DisplayTest_2_4, SubsequentHotplugConnectUpdatesExternalDisplay) {
+ Test_SubsequentHotplugConnectUpdatesDisplay(EXTERNAL_DISPLAY);
+}
+
////////////////////////////////////////////////
template <typename FakeComposerService>
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index f2051d9..b696a6d 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -62,15 +62,9 @@
using testing::_;
using testing::AtLeast;
-using testing::Between;
-using testing::ByMove;
using testing::DoAll;
-using testing::Field;
-using testing::Invoke;
using testing::IsNull;
using testing::Mock;
-using testing::NotNull;
-using testing::Ref;
using testing::Return;
using testing::ReturnRef;
using testing::SetArgPointee;
@@ -86,7 +80,6 @@
constexpr int DEFAULT_DISPLAY_WIDTH = 1920;
constexpr int DEFAULT_DISPLAY_HEIGHT = 1024;
-constexpr int DEFAULT_CONFIG_ID = 0;
constexpr int DEFAULT_TEXTURE_ID = 6000;
constexpr int DEFAULT_LAYER_STACK = 7000;
@@ -147,7 +140,7 @@
EXPECT_CALL(*vsyncTracker, nextAnticipatedVSyncTimeFrom(_)).WillRepeatedly(Return(0));
EXPECT_CALL(*vsyncTracker, currentPeriod())
- .WillRepeatedly(Return(FakeHwcDisplayInjector::DEFAULT_REFRESH_RATE));
+ .WillRepeatedly(Return(FakeHwcDisplayInjector::DEFAULT_VSYNC_PERIOD));
EXPECT_CALL(*vsyncTracker, nextAnticipatedVSyncTimeFrom(_)).WillRepeatedly(Return(0));
constexpr ISchedulerCallback* kCallback = nullptr;
@@ -548,12 +541,6 @@
setupLatchedBuffer(test, layer);
}
- static void setupBufferLayerPostFrameCallExpectations(CompositionTest* test) {
- // BufferLayer::onPostComposition(), when there is no present fence
- EXPECT_CALL(*test->mComposer, getActiveConfig(HWC_DISPLAY, _))
- .WillOnce(DoAll(SetArgPointee<1>(DEFAULT_CONFIG_ID), Return(Error::NONE)));
- }
-
static void setupHwcSetGeometryCallExpectations(CompositionTest* test) {
if (!test->mDisplayOff) {
// TODO: Coverage of other values
@@ -632,8 +619,6 @@
.Times(1);
EXPECT_CALL(*test->mComposer, setLayerBuffer(HWC_DISPLAY, HWC_LAYER, _, _, _)).Times(1);
}
-
- setupBufferLayerPostFrameCallExpectations(test);
}
static void setupREBufferCompositionCommonCallExpectations(CompositionTest* test) {
@@ -793,7 +778,6 @@
static void setupInsecureREBufferCompositionCallExpectations(CompositionTest* test) {
setupInsecureREBufferCompositionCommonCallExpectations(test);
- Base::setupBufferLayerPostFrameCallExpectations(test);
}
static void setupInsecureREBufferScreenshotCompositionCallExpectations(CompositionTest* test) {
diff --git a/services/surfaceflinger/tests/unittests/HWComposerTest.cpp b/services/surfaceflinger/tests/unittests/HWComposerTest.cpp
index 1e24c0a..6b82170 100644
--- a/services/surfaceflinger/tests/unittests/HWComposerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/HWComposerTest.cpp
@@ -175,90 +175,5 @@
EXPECT_EQ(hal::Error::UNSUPPORTED, result);
}
-class HWComposerConfigsTest : public testing::Test {
-public:
- Hwc2::mock::Composer* mHal = new StrictMock<Hwc2::mock::Composer>();
- MockHWC2ComposerCallback mCallback;
-
- void setActiveConfig(Config config) {
- EXPECT_CALL(*mHal, getActiveConfig(_, _))
- .WillRepeatedly(DoAll(SetArgPointee<1>(config), Return(V2_1::Error::NONE)));
- }
-
- void setDisplayConfigs(std::vector<Config> configs) {
- EXPECT_CALL(*mHal, getDisplayConfigs(_, _))
- .WillOnce(DoAll(SetArgPointee<1>(configs), Return(V2_1::Error::NONE)));
- EXPECT_CALL(*mHal, getDisplayAttribute(_, _, _, _))
- .WillRepeatedly(DoAll(SetArgPointee<3>(1), Return(V2_1::Error::NONE)));
- }
-
- void testSetActiveModeWithConstraintsCommon(bool isVsyncPeriodSwitchSupported);
-};
-
-void HWComposerConfigsTest::testSetActiveModeWithConstraintsCommon(
- bool isVsyncPeriodSwitchSupported) {
- EXPECT_CALL(*mHal, getMaxVirtualDisplayCount()).WillOnce(Return(0));
- EXPECT_CALL(*mHal, getCapabilities()).WillOnce(Return(std::vector<hal::Capability>{}));
- EXPECT_CALL(*mHal, getLayerGenericMetadataKeys(_)).WillOnce(Return(V2_4::Error::UNSUPPORTED));
- EXPECT_CALL(*mHal, registerCallback(_));
- EXPECT_CALL(*mHal, setVsyncEnabled(_, _)).WillRepeatedly(Return(V2_1::Error::NONE));
- EXPECT_CALL(*mHal, getDisplayIdentificationData(_, _, _))
- .WillRepeatedly(Return(V2_1::Error::UNSUPPORTED));
- EXPECT_CALL(*mHal, setClientTargetSlotCount(_)).WillRepeatedly(Return(V2_1::Error::NONE));
-
- EXPECT_CALL(*mHal, isVsyncPeriodSwitchSupported())
- .WillRepeatedly(Return(isVsyncPeriodSwitchSupported));
-
- if (isVsyncPeriodSwitchSupported) {
- EXPECT_CALL(*mHal, setActiveConfigWithConstraints(_, _, _, _))
- .WillRepeatedly(Return(V2_4::Error::NONE));
- } else {
- EXPECT_CALL(*mHal, setActiveConfig(_, _)).WillRepeatedly(Return(V2_1::Error::NONE));
- }
-
- impl::HWComposer hwc{std::unique_ptr<Hwc2::Composer>(mHal)};
- hwc.setConfiguration(&mCallback, 123);
-
- setDisplayConfigs({15});
- setActiveConfig(15);
-
- const auto physicalId = PhysicalDisplayId::fromPort(0);
- const hal::HWDisplayId hwcId = 0;
- hwc.allocatePhysicalDisplay(hwcId, physicalId);
-
- hal::VsyncPeriodChangeConstraints constraints;
- constraints.desiredTimeNanos = systemTime();
- constraints.seamlessRequired = false;
-
- hal::VsyncPeriodChangeTimeline timeline = {0, 0, 0};
- constexpr Config kConfigIndex = 0;
- const auto status =
- hwc.setActiveModeWithConstraints(physicalId, kConfigIndex, constraints, &timeline);
- EXPECT_EQ(NO_ERROR, status);
-
- const std::vector<Config> kConfigs{7, 8, 9, 10, 11};
- // Change the set of supported modes.
- setDisplayConfigs(kConfigs);
- setActiveConfig(11);
- hwc.onHotplug(hwcId, hal::Connection::CONNECTED);
- hwc.allocatePhysicalDisplay(hwcId, physicalId);
-
- for (size_t configIndex = 0; configIndex < kConfigs.size(); configIndex++) {
- const auto status =
- hwc.setActiveModeWithConstraints(physicalId,
- static_cast<hal::HWConfigId>(configIndex),
- constraints, &timeline);
- EXPECT_EQ(NO_ERROR, status) << "Error when switching to config " << configIndex;
- }
-}
-
-TEST_F(HWComposerConfigsTest, setActiveModeWithConstraintsWithVsyncSwitchingSupported) {
- testSetActiveModeWithConstraintsCommon(/*supported=*/true);
-}
-
-TEST_F(HWComposerConfigsTest, setActiveModeWithConstraintsWithVsyncSwitchingNotSupported) {
- testSetActiveModeWithConstraintsCommon(/*supported=*/false);
-}
-
} // namespace
} // namespace android
\ No newline at end of file
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp
index c5deb7c..abecd4b 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp
@@ -144,7 +144,7 @@
EXPECT_CALL(*vsyncTracker, nextAnticipatedVSyncTimeFrom(_)).WillRepeatedly(Return(0));
EXPECT_CALL(*vsyncTracker, currentPeriod())
- .WillRepeatedly(Return(FakeHwcDisplayInjector::DEFAULT_REFRESH_RATE));
+ .WillRepeatedly(Return(FakeHwcDisplayInjector::DEFAULT_VSYNC_PERIOD));
EXPECT_CALL(*vsyncTracker, nextAnticipatedVSyncTimeFrom(_)).WillRepeatedly(Return(0));
mFlinger.setupScheduler(std::move(vsyncController), std::move(vsyncTracker),
std::move(eventThread), std::move(sfEventThread));
diff --git a/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp b/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp
index e060df2..a6d07d0 100644
--- a/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp
@@ -185,7 +185,7 @@
EXPECT_CALL(*vsyncTracker, nextAnticipatedVSyncTimeFrom(_)).WillRepeatedly(Return(0));
EXPECT_CALL(*vsyncTracker, currentPeriod())
- .WillRepeatedly(Return(FakeHwcDisplayInjector::DEFAULT_REFRESH_RATE));
+ .WillRepeatedly(Return(FakeHwcDisplayInjector::DEFAULT_VSYNC_PERIOD));
EXPECT_CALL(*vsyncTracker, nextAnticipatedVSyncTimeFrom(_)).WillRepeatedly(Return(0));
mFlinger.setupScheduler(std::move(vsyncController), std::move(vsyncTracker),
std::move(eventThread), std::move(sfEventThread));
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_HandleTransactionLockedTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_HandleTransactionLockedTest.cpp
index 8552e15..b713334 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_HandleTransactionLockedTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_HandleTransactionLockedTest.cpp
@@ -669,7 +669,7 @@
// --------------------------------------------------------------------
// Call Expectations
- EXPECT_CALL(*displaySurface, resizeBuffers(newWidth, oldHeight)).Times(1);
+ EXPECT_CALL(*displaySurface, resizeBuffers(ui::Size(newWidth, oldHeight))).Times(1);
// --------------------------------------------------------------------
// Invocation
@@ -714,7 +714,7 @@
// --------------------------------------------------------------------
// Call Expectations
- EXPECT_CALL(*displaySurface, resizeBuffers(oldWidth, newHeight)).Times(1);
+ EXPECT_CALL(*displaySurface, resizeBuffers(ui::Size(oldWidth, newHeight))).Times(1);
// --------------------------------------------------------------------
// Invocation
@@ -764,7 +764,7 @@
// --------------------------------------------------------------------
// Call Expectations
- EXPECT_CALL(*displaySurface, resizeBuffers(kNewWidth, kNewHeight)).Times(1);
+ EXPECT_CALL(*displaySurface, resizeBuffers(kNewSize.getSize())).Times(1);
// --------------------------------------------------------------------
// Invocation
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 6b5109f..3787c43 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -41,6 +41,7 @@
#include "SurfaceFlingerDefaultFactory.h"
#include "SurfaceInterceptor.h"
#include "TestableScheduler.h"
+#include "mock/DisplayHardware/MockComposer.h"
#include "mock/MockDisplayIdGenerator.h"
#include "mock/MockFrameTimeline.h"
#include "mock/MockFrameTracer.h"
@@ -478,7 +479,7 @@
static constexpr hal::HWDisplayId DEFAULT_HWC_DISPLAY_ID = 1000;
static constexpr int32_t DEFAULT_WIDTH = 1920;
static constexpr int32_t DEFAULT_HEIGHT = 1280;
- static constexpr int32_t DEFAULT_REFRESH_RATE = 16'666'666;
+ static constexpr int32_t DEFAULT_VSYNC_PERIOD = 16'666'666;
static constexpr int32_t DEFAULT_CONFIG_GROUP = 7;
static constexpr int32_t DEFAULT_DPI = 320;
static constexpr hal::HWConfigId DEFAULT_ACTIVE_CONFIG = 0;
@@ -503,8 +504,8 @@
return *this;
}
- auto& setRefreshRate(int32_t refreshRate) {
- mRefreshRate = refreshRate;
+ auto& setVsyncPeriod(int32_t vsyncPeriod) {
+ mVsyncPeriod = vsyncPeriod;
return *this;
}
@@ -533,7 +534,12 @@
return *this;
}
- void inject(TestableSurfaceFlinger* flinger, Hwc2::Composer* composer) {
+ void inject(TestableSurfaceFlinger* flinger, Hwc2::mock::Composer* composer) {
+ using ::testing::_;
+ using ::testing::DoAll;
+ using ::testing::Return;
+ using ::testing::SetArgPointee;
+
static const std::unordered_set<hal::Capability> defaultCapabilities;
if (mCapabilities == nullptr) mCapabilities = &defaultCapabilities;
@@ -548,15 +554,39 @@
display->setPowerMode(mPowerMode);
flinger->mutableHwcDisplayData()[mDisplayId].hwcDisplay = std::move(display);
- auto config = DisplayMode::Builder(mActiveConfig)
- .setWidth(mWidth)
- .setHeight(mHeight)
- .setVsyncPeriod(mRefreshRate)
- .setDpiX(mDpiX)
- .setDpiY(mDpiY)
- .setConfigGroup(mConfigGroup)
- .build();
- flinger->mutableHwcDisplayData()[mDisplayId].modes.push_back(config);
+ EXPECT_CALL(*composer, getDisplayConfigs(mHwcDisplayId, _))
+ .WillRepeatedly(
+ DoAll(SetArgPointee<1>(std::vector<hal::HWConfigId>{mActiveConfig}),
+ Return(hal::Error::NONE)));
+
+ EXPECT_CALL(*composer,
+ getDisplayAttribute(mHwcDisplayId, mActiveConfig, hal::Attribute::WIDTH, _))
+ .WillRepeatedly(DoAll(SetArgPointee<3>(mWidth), Return(hal::Error::NONE)));
+
+ EXPECT_CALL(*composer,
+ getDisplayAttribute(mHwcDisplayId, mActiveConfig, hal::Attribute::HEIGHT,
+ _))
+ .WillRepeatedly(DoAll(SetArgPointee<3>(mHeight), Return(hal::Error::NONE)));
+
+ EXPECT_CALL(*composer,
+ getDisplayAttribute(mHwcDisplayId, mActiveConfig,
+ hal::Attribute::VSYNC_PERIOD, _))
+ .WillRepeatedly(
+ DoAll(SetArgPointee<3>(mVsyncPeriod), Return(hal::Error::NONE)));
+
+ EXPECT_CALL(*composer,
+ getDisplayAttribute(mHwcDisplayId, mActiveConfig, hal::Attribute::DPI_X, _))
+ .WillRepeatedly(DoAll(SetArgPointee<3>(mDpiX), Return(hal::Error::NONE)));
+
+ EXPECT_CALL(*composer,
+ getDisplayAttribute(mHwcDisplayId, mActiveConfig, hal::Attribute::DPI_Y, _))
+ .WillRepeatedly(DoAll(SetArgPointee<3>(mDpiY), Return(hal::Error::NONE)));
+
+ EXPECT_CALL(*composer,
+ getDisplayAttribute(mHwcDisplayId, mActiveConfig,
+ hal::Attribute::CONFIG_GROUP, _))
+ .WillRepeatedly(
+ DoAll(SetArgPointee<3>(mConfigGroup), Return(hal::Error::NONE)));
if (mHwcDisplayType == hal::DisplayType::PHYSICAL) {
const auto physicalId = PhysicalDisplayId::tryCast(mDisplayId);
@@ -582,10 +612,10 @@
hal::HWDisplayId mHwcDisplayId = DEFAULT_HWC_DISPLAY_ID;
int32_t mWidth = DEFAULT_WIDTH;
int32_t mHeight = DEFAULT_HEIGHT;
- int32_t mRefreshRate = DEFAULT_REFRESH_RATE;
+ int32_t mVsyncPeriod = DEFAULT_VSYNC_PERIOD;
int32_t mDpiX = DEFAULT_DPI;
- int32_t mConfigGroup = DEFAULT_CONFIG_GROUP;
int32_t mDpiY = DEFAULT_DPI;
+ int32_t mConfigGroup = DEFAULT_CONFIG_GROUP;
hal::HWConfigId mActiveConfig = DEFAULT_ACTIVE_CONFIG;
hal::PowerMode mPowerMode = DEFAULT_POWER_MODE;
const std::unordered_set<hal::Capability>* mCapabilities = nullptr;
@@ -603,6 +633,21 @@
mHwcDisplayId(hwcDisplayId) {
mCreationArgs.connectionType = connectionType;
mCreationArgs.isPrimary = isPrimary;
+
+ mActiveModeId = DisplayModeId(0);
+ DisplayModePtr activeMode =
+ DisplayMode::Builder(FakeHwcDisplayInjector::DEFAULT_ACTIVE_CONFIG)
+ .setId(mActiveModeId)
+ .setWidth(FakeHwcDisplayInjector::DEFAULT_WIDTH)
+ .setHeight(FakeHwcDisplayInjector::DEFAULT_HEIGHT)
+ .setVsyncPeriod(FakeHwcDisplayInjector::DEFAULT_VSYNC_PERIOD)
+ .setDpiX(FakeHwcDisplayInjector::DEFAULT_DPI)
+ .setDpiY(FakeHwcDisplayInjector::DEFAULT_DPI)
+ .setConfigGroup(0)
+ .build();
+
+ DisplayModes modes{activeMode};
+ mCreationArgs.supportedModes = modes;
}
sp<IBinder> token() const { return mDisplayToken; }
@@ -625,6 +670,16 @@
auto& mutableDisplayDevice() { return mFlinger.mutableDisplays()[mDisplayToken]; }
+ auto& setActiveMode(DisplayModeId mode) {
+ mActiveModeId = mode;
+ return *this;
+ }
+
+ auto& setSupportedModes(DisplayModes mode) {
+ mCreationArgs.supportedModes = mode;
+ return *this;
+ }
+
auto& setNativeWindow(const sp<ANativeWindow>& nativeWindow) {
mCreationArgs.nativeWindow = nativeWindow;
return *this;
@@ -677,6 +732,9 @@
state.isSecure = mCreationArgs.isSecure;
sp<DisplayDevice> device = new DisplayDevice(mCreationArgs);
+ if (!device->isVirtual()) {
+ device->setActiveMode(mActiveModeId);
+ }
mFlinger.mutableDisplays().emplace(mDisplayToken, device);
mFlinger.mutableCurrentState().displays.add(mDisplayToken, state);
mFlinger.mutableDrawingState().displays.add(mDisplayToken, state);
@@ -693,6 +751,7 @@
sp<BBinder> mDisplayToken = new BBinder();
DisplayDeviceCreationArgs mCreationArgs;
const std::optional<hal::HWDisplayId> mHwcDisplayId;
+ DisplayModeId mActiveModeId;
};
private:
diff --git a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
index 0ac5845..eb2c1ba 100644
--- a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
@@ -72,7 +72,7 @@
EXPECT_CALL(*mVSyncTracker, nextAnticipatedVSyncTimeFrom(_)).WillRepeatedly(Return(0));
EXPECT_CALL(*mVSyncTracker, currentPeriod())
- .WillRepeatedly(Return(FakeHwcDisplayInjector::DEFAULT_REFRESH_RATE));
+ .WillRepeatedly(Return(FakeHwcDisplayInjector::DEFAULT_VSYNC_PERIOD));
mFlinger.setupScheduler(std::unique_ptr<mock::VsyncController>(mVsyncController),
std::unique_ptr<mock::VSyncTracker>(mVSyncTracker),