Merge "Enable backpressure for BufferStateLayer" into sc-dev
diff --git a/data/etc/car_core_hardware.xml b/data/etc/car_core_hardware.xml
index ccf4dc8..cc0ee82 100644
--- a/data/etc/car_core_hardware.xml
+++ b/data/etc/car_core_hardware.xml
@@ -34,6 +34,8 @@
<feature name="android.hardware.microphone" />
<!-- Feature to specify if the device is a car -->
<feature name="android.hardware.type.automotive" />
+ <!-- Indicate support for the Android security model per the CDD. -->
+ <feature name="android.hardware.security.model.compatible" />
<!-- basic system services -->
<feature name="android.software.connectionservice" />
diff --git a/data/etc/go_handheld_core_hardware.xml b/data/etc/go_handheld_core_hardware.xml
index 915e579..3aa2797 100644
--- a/data/etc/go_handheld_core_hardware.xml
+++ b/data/etc/go_handheld_core_hardware.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+u<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2018 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
@@ -33,6 +33,8 @@
<feature name="android.hardware.microphone" />
<feature name="android.hardware.screen.portrait" />
<feature name="android.hardware.screen.landscape" />
+ <!-- Indicate support for the Android security model per the CDD. -->
+ <feature name="android.hardware.security.model.compatible" />
<!-- basic system services -->
<feature name="android.software.connectionservice" />
diff --git a/data/etc/handheld_core_hardware.xml b/data/etc/handheld_core_hardware.xml
index 2c34047..c3c3a7f 100644
--- a/data/etc/handheld_core_hardware.xml
+++ b/data/etc/handheld_core_hardware.xml
@@ -37,6 +37,8 @@
<feature name="android.hardware.microphone" />
<feature name="android.hardware.screen.portrait" />
<feature name="android.hardware.screen.landscape" />
+ <!-- Indicate support for the Android security model per the CDD. -->
+ <feature name="android.hardware.security.model.compatible" />
<!-- basic system services -->
<feature name="android.software.app_widgets" />
diff --git a/data/etc/pc_core_hardware.xml b/data/etc/pc_core_hardware.xml
index c62da0a..b490ba0 100644
--- a/data/etc/pc_core_hardware.xml
+++ b/data/etc/pc_core_hardware.xml
@@ -33,6 +33,8 @@
<feature name="android.hardware.screen.landscape" />
<feature name="android.hardware.location" />
<feature name="android.hardware.location.network" />
+ <!-- Indicate support for the Android security model per the CDD. -->
+ <feature name="android.hardware.security.model.compatible" />
<!-- basic system services -->
<feature name="android.software.app_widgets" />
diff --git a/data/etc/tablet_core_hardware.xml b/data/etc/tablet_core_hardware.xml
index 873b5b7..4b565fd 100644
--- a/data/etc/tablet_core_hardware.xml
+++ b/data/etc/tablet_core_hardware.xml
@@ -38,6 +38,8 @@
<feature name="android.hardware.microphone" />
<feature name="android.hardware.screen.portrait" />
<feature name="android.hardware.screen.landscape" />
+ <!-- Indicate support for the Android security model per the CDD. -->
+ <feature name="android.hardware.security.model.compatible" />
<!-- basic system services -->
<feature name="android.software.app_widgets" />
diff --git a/data/etc/wearable_core_hardware.xml b/data/etc/wearable_core_hardware.xml
index 0f364c1..855b110 100644
--- a/data/etc/wearable_core_hardware.xml
+++ b/data/etc/wearable_core_hardware.xml
@@ -32,6 +32,8 @@
<feature name="android.hardware.bluetooth" />
<feature name="android.hardware.touchscreen" />
<feature name="android.hardware.microphone" />
+ <!-- Indicate support for the Android security model per the CDD. -->
+ <feature name="android.hardware.security.model.compatible" />
<!-- basic system services -->
<feature name="android.software.home_screen" />
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index 4904955..42d2895 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -261,7 +261,7 @@
mPendingReleaseItem.item = std::move(mSubmitted.front());
mSubmitted.pop();
- processNextBufferLocked(false);
+ processNextBufferLocked(false /* useNextTransaction */);
currFrameNumber = mPendingReleaseItem.item.mFrameNumber;
if (mTransactionCompleteCallback && mTransactionCompleteFrameNumber == currFrameNumber) {
@@ -282,9 +282,10 @@
ATRACE_CALL();
BQA_LOGV("processNextBufferLocked useNextTransaction=%s", toString(useNextTransaction));
- // Wait to acquire a buffer if there are no frames available or we have acquired the max
- // number of buffers.
- if (mNumFrameAvailable == 0 || maxBuffersAcquired()) {
+ // If the next transaction is set, we want to guarantee the our acquire will not fail, so don't
+ // include the extra buffer when checking if we can acquire the next buffer.
+ const bool includeExtraAcquire = !useNextTransaction;
+ if (mNumFrameAvailable == 0 || maxBuffersAcquired(includeExtraAcquire)) {
BQA_LOGV("processNextBufferLocked waiting for frame available or callback");
mCallbackCV.notify_all();
return;
@@ -308,7 +309,10 @@
status_t status =
mBufferItemConsumer->acquireBuffer(&bufferItem, 0 /* expectedPresent */, false);
- if (status != OK) {
+ if (status == BufferQueue::NO_BUFFER_AVAILABLE) {
+ BQA_LOGV("Failed to acquire a buffer, err=NO_BUFFER_AVAILABLE");
+ return;
+ } else if (status != OK) {
BQA_LOGE("Failed to acquire a buffer, err=%s", statusToString(status).c_str());
return;
}
@@ -427,7 +431,7 @@
item.mFrameNumber, toString(nextTransactionSet), toString(mFlushShadowQueue));
if (nextTransactionSet || mFlushShadowQueue) {
- while (mNumFrameAvailable > 0 || maxBuffersAcquired()) {
+ while (mNumFrameAvailable > 0 || maxBuffersAcquired(false /* includeExtraAcquire */)) {
BQA_LOGV("waiting in onFrameAvailable...");
mCallbackCV.wait(_lock);
}
@@ -435,7 +439,7 @@
mFlushShadowQueue = false;
// add to shadow queue
mNumFrameAvailable++;
- processNextBufferLocked(true);
+ processNextBufferLocked(nextTransactionSet /* useNextTransaction */);
}
void BLASTBufferQueue::onFrameReplaced(const BufferItem& item) {
@@ -495,9 +499,12 @@
// Check if we have acquired the maximum number of buffers.
// As a special case, we wait for the first callback before acquiring the second buffer so we
// can ensure the first buffer is presented if multiple buffers are queued in succession.
-bool BLASTBufferQueue::maxBuffersAcquired() const {
- return mNumAcquired == MAX_ACQUIRED_BUFFERS + 1 ||
- (!mInitialCallbackReceived && mNumAcquired == 1);
+// Consumer can acquire an additional buffer if that buffer is not droppable. Set
+// includeExtraAcquire is true to include this buffer to the count. Since this depends on the state
+// of the buffer, the next acquire may return with NO_BUFFER_AVAILABLE.
+bool BLASTBufferQueue::maxBuffersAcquired(bool includeExtraAcquire) const {
+ int maxAcquiredBuffers = MAX_ACQUIRED_BUFFERS + (includeExtraAcquire ? 2 : 1);
+ return mNumAcquired == maxAcquiredBuffers || (!mInitialCallbackReceived && mNumAcquired == 1);
}
class BBQSurface : public Surface {
@@ -667,7 +674,8 @@
LOG_ALWAYS_FATAL_IF(producer == nullptr,
"BLASTBufferQueue: failed to create BBQBufferQueueProducer");
- sp<IGraphicBufferConsumer> consumer(new BufferQueueConsumer(core));
+ sp<BufferQueueConsumer> consumer(new BufferQueueConsumer(core));
+ consumer->setAllowExtraAcquire(true);
LOG_ALWAYS_FATAL_IF(consumer == nullptr,
"BLASTBufferQueue: failed to create BufferQueueConsumer");
diff --git a/libs/gui/BufferQueueConsumer.cpp b/libs/gui/BufferQueueConsumer.cpp
index da6143c..7f7a043 100644
--- a/libs/gui/BufferQueueConsumer.cpp
+++ b/libs/gui/BufferQueueConsumer.cpp
@@ -94,7 +94,10 @@
++numAcquiredBuffers;
}
}
- if (numAcquiredBuffers >= mCore->mMaxAcquiredBufferCount + 1) {
+ const bool acquireNonDroppableBuffer = mCore->mAllowExtraAcquire &&
+ numAcquiredBuffers == mCore->mMaxAcquiredBufferCount + 1;
+ if (numAcquiredBuffers >= mCore->mMaxAcquiredBufferCount + 1 &&
+ !acquireNonDroppableBuffer) {
BQ_LOGE("acquireBuffer: max acquired buffer count reached: %d (max %d)",
numAcquiredBuffers, mCore->mMaxAcquiredBufferCount);
return INVALID_OPERATION;
@@ -254,6 +257,9 @@
outBuffer->mIsStale = false;
outBuffer->mAutoRefresh = mCore->mSharedBufferMode &&
mCore->mAutoRefresh;
+ } else if (acquireNonDroppableBuffer && front->mIsDroppable) {
+ BQ_LOGV("acquireBuffer: front buffer is not droppable");
+ return NO_BUFFER_AVAILABLE;
} else {
slot = front->mSlot;
*outBuffer = *front;
@@ -824,4 +830,9 @@
return NO_ERROR;
}
+void BufferQueueConsumer::setAllowExtraAcquire(bool allow) {
+ std::lock_guard<std::mutex> lock(mCore->mMutex);
+ mCore->mAllowExtraAcquire = allow;
+}
+
} // namespace android
diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h
index 411526e..7f69bc4 100644
--- a/libs/gui/include/gui/BLASTBufferQueue.h
+++ b/libs/gui/include/gui/BLASTBufferQueue.h
@@ -109,7 +109,7 @@
Rect computeCrop(const BufferItem& item) REQUIRES(mMutex);
// Return true if we need to reject the buffer based on the scaling mode and the buffer size.
bool rejectBuffer(const BufferItem& item) REQUIRES(mMutex);
- bool maxBuffersAcquired() const REQUIRES(mMutex);
+ bool maxBuffersAcquired(bool includeExtraAcquire) const REQUIRES(mMutex);
std::string mName;
sp<SurfaceControl> mSurfaceControl;
diff --git a/libs/gui/include/gui/BufferQueueConsumer.h b/libs/gui/include/gui/BufferQueueConsumer.h
index 7db69ec..6aa801a 100644
--- a/libs/gui/include/gui/BufferQueueConsumer.h
+++ b/libs/gui/include/gui/BufferQueueConsumer.h
@@ -174,6 +174,10 @@
// Value used to determine if present time is valid.
constexpr static int MAX_REASONABLE_NSEC = 1'000'000'000ULL; // 1 second
+ // This allows the consumer to acquire an additional buffer if that buffer is not droppable and
+ // will eventually be released or acquired by the consumer.
+ void setAllowExtraAcquire(bool /* allow */);
+
private:
sp<BufferQueueCore> mCore;
diff --git a/libs/gui/include/gui/BufferQueueCore.h b/libs/gui/include/gui/BufferQueueCore.h
index 557c28b..8d0828d 100644
--- a/libs/gui/include/gui/BufferQueueCore.h
+++ b/libs/gui/include/gui/BufferQueueCore.h
@@ -354,6 +354,9 @@
// mTransformHintInUse is to cache the mTransformHint used by the producer.
uint32_t mTransformHintInUse;
+ // This allows the consumer to acquire an additional buffer if that buffer is not droppable and
+ // will eventually be released or acquired by the consumer.
+ bool mAllowExtraAcquire = false;
}; // class BufferQueueCore
} // namespace android
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
index 4d36f0c..3133e90 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
+++ b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
@@ -96,7 +96,7 @@
MOCK_CONST_METHOD1(isVsyncPeriodSwitchSupported, bool(PhysicalDisplayId));
MOCK_CONST_METHOD1(getDisplayVsyncPeriod, nsecs_t(PhysicalDisplayId));
MOCK_METHOD4(setActiveModeWithConstraints,
- status_t(PhysicalDisplayId, DisplayModeId,
+ status_t(PhysicalDisplayId, hal::HWConfigId,
const hal::VsyncPeriodChangeConstraints&,
hal::VsyncPeriodChangeTimeline*));
MOCK_METHOD2(setAutoLowLatencyMode, status_t(PhysicalDisplayId, bool));
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index fe9db5a..b4a3ed1 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -51,17 +51,22 @@
ui::Transform::RotationFlags DisplayDevice::sPrimaryDisplayRotationFlags = ui::Transform::ROT_0;
DisplayDeviceCreationArgs::DisplayDeviceCreationArgs(
- const sp<SurfaceFlinger>& flinger, const wp<IBinder>& displayToken,
+ const sp<SurfaceFlinger>& flinger, HWComposer& hwComposer, const wp<IBinder>& displayToken,
std::shared_ptr<compositionengine::Display> compositionDisplay)
- : flinger(flinger), displayToken(displayToken), compositionDisplay(compositionDisplay) {}
+ : flinger(flinger),
+ hwComposer(hwComposer),
+ displayToken(displayToken),
+ compositionDisplay(compositionDisplay) {}
DisplayDevice::DisplayDevice(DisplayDeviceCreationArgs& args)
: mFlinger(args.flinger),
+ mHwComposer(args.hwComposer),
mDisplayToken(args.displayToken),
mSequenceId(args.sequenceId),
mConnectionType(args.connectionType),
mCompositionDisplay{args.compositionDisplay},
mPhysicalOrientation(args.physicalOrientation),
+ mSupportedModes(std::move(args.supportedModes)),
mIsPrimary(args.isPrimary) {
mCompositionDisplay->editState().isSecure = args.isSecure;
mCompositionDisplay->createRenderSurface(
@@ -139,12 +144,39 @@
return mPowerMode != hal::PowerMode::OFF;
}
-void DisplayDevice::setActiveMode(DisplayModeId mode) {
- mActiveMode = mode;
+void DisplayDevice::setActiveMode(DisplayModeId id) {
+ LOG_FATAL_IF(id.value() >= mSupportedModes.size(),
+ "Cannot set active mode which is not supported.");
+ mActiveModeId = id;
}
-DisplayModeId DisplayDevice::getActiveMode() const {
- return mActiveMode;
+status_t DisplayDevice::initiateModeChange(DisplayModeId modeId,
+ const hal::VsyncPeriodChangeConstraints& constraints,
+ hal::VsyncPeriodChangeTimeline* outTimeline) const {
+ const auto mode = getMode(modeId);
+ if (!mode) {
+ ALOGE("Trying to initiate a mode change to invalid mode %s on display %s",
+ std::to_string(modeId.value()).c_str(), to_string(getId()).c_str());
+ return BAD_VALUE;
+ }
+ return mHwComposer.setActiveModeWithConstraints(getPhysicalId(), mode->getHwcId(), constraints,
+ outTimeline);
+}
+
+const DisplayModePtr& DisplayDevice::getActiveMode() const {
+ return mSupportedModes[mActiveModeId.value()];
+}
+
+const DisplayModes& DisplayDevice::getSupportedModes() const {
+ return mSupportedModes;
+}
+
+DisplayModePtr DisplayDevice::getMode(DisplayModeId modeId) const {
+ const auto id = modeId.value();
+ if (id < mSupportedModes.size()) {
+ return mSupportedModes[id];
+ }
+ return nullptr;
}
ui::Dataspace DisplayDevice::getCompositionDataSpace() const {
@@ -206,17 +238,24 @@
void DisplayDevice::dump(std::string& result) const {
StringAppendF(&result, "+ %s\n", getDebugName().c_str());
-
- result.append(" ");
- StringAppendF(&result, "powerMode=%s (%d), ", to_string(mPowerMode).c_str(),
+ StringAppendF(&result, " powerMode=%s (%d)\n", to_string(mPowerMode).c_str(),
static_cast<int32_t>(mPowerMode));
- StringAppendF(&result, "activeConfig=%zu, ", mActiveMode.value());
- StringAppendF(&result, "deviceProductInfo=");
+ StringAppendF(&result, " activeMode=%s\n", to_string(*getActiveMode()).c_str());
+
+ result.append(" supportedModes=\n");
+
+ for (const auto& mode : mSupportedModes) {
+ result.append(" ");
+ result.append(to_string(*mode));
+ result.append("\n");
+ }
+ StringAppendF(&result, " deviceProductInfo=");
if (mDeviceProductInfo) {
mDeviceProductInfo->dump(result);
} else {
result.append("{}");
}
+ result.append("\n");
getCompositionDisplay()->dump(result);
}
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index d29f97d..85f2f3b 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -34,6 +34,7 @@
#include <ui/HdrCapabilities.h>
#include <ui/Region.h>
#include <ui/Transform.h>
+#include <utils/Errors.h>
#include <utils/Mutex.h>
#include <utils/RefBase.h>
#include <utils/Timers.h>
@@ -157,10 +158,23 @@
ui::Dataspace getCompositionDataSpace() const;
/* ------------------------------------------------------------------------
- * Display active config management.
+ * Display mode management.
*/
- DisplayModeId getActiveMode() const;
- void setActiveMode(DisplayModeId mode);
+ const DisplayModePtr& getActiveMode() const;
+ void setActiveMode(DisplayModeId);
+ status_t initiateModeChange(DisplayModeId modeId,
+ const hal::VsyncPeriodChangeConstraints& constraints,
+ hal::VsyncPeriodChangeTimeline* outTimeline) const;
+
+ // Return the immutable list of supported display modes. The HWC may report different modes
+ // after a hotplug reconnect event, in which case the DisplayDevice object will be recreated.
+ // Hotplug reconnects are common for external displays.
+ const DisplayModes& getSupportedModes() const;
+
+ // Returns nullptr if the given mode ID is not supported. A previously
+ // supported mode may be no longer supported for some devices like TVs and
+ // set-top boxes after a hotplug reconnect.
+ DisplayModePtr getMode(DisplayModeId) const;
// release HWC resources (if any) for removable displays
void disconnect();
@@ -174,6 +188,7 @@
private:
const sp<SurfaceFlinger> mFlinger;
+ HWComposer& mHwComposer;
const wp<IBinder> mDisplayToken;
const int32_t mSequenceId;
const std::optional<DisplayConnectionType> mConnectionType;
@@ -189,7 +204,8 @@
hardware::graphics::composer::hal::PowerMode mPowerMode =
hardware::graphics::composer::hal::PowerMode::OFF;
- DisplayModeId mActiveMode;
+ DisplayModeId mActiveModeId;
+ const DisplayModes mSupportedModes;
// TODO(b/74619554): Remove special cases for primary display.
const bool mIsPrimary;
@@ -229,9 +245,11 @@
struct DisplayDeviceCreationArgs {
// We use a constructor to ensure some of the values are set, without
// assuming a default value.
- DisplayDeviceCreationArgs(const sp<SurfaceFlinger>&, const wp<IBinder>& displayToken,
+ DisplayDeviceCreationArgs(const sp<SurfaceFlinger>&, HWComposer& hwComposer,
+ const wp<IBinder>& displayToken,
std::shared_ptr<compositionengine::Display>);
const sp<SurfaceFlinger> flinger;
+ HWComposer& hwComposer;
const wp<IBinder> displayToken;
const std::shared_ptr<compositionengine::Display> compositionDisplay;
@@ -248,6 +266,7 @@
hardware::graphics::composer::hal::PowerMode initialPowerMode{
hardware::graphics::composer::hal::PowerMode::ON};
bool isPrimary{false};
+ DisplayModes supportedModes;
};
} // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/DisplayMode.h b/services/surfaceflinger/DisplayHardware/DisplayMode.h
index 7ae54f1..61c1b61 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayMode.h
+++ b/services/surfaceflinger/DisplayHardware/DisplayMode.h
@@ -17,8 +17,10 @@
#pragma once
#include "DisplayHardware/Hal.h"
+#include "Fps.h"
#include "Scheduler/StrongTyping.h"
+#include <android-base/stringprintf.h>
#include <android/configuration.h>
#include <utils/Timers.h>
@@ -61,7 +63,7 @@
}
Builder& setVsyncPeriod(int32_t vsyncPeriod) {
- mDisplayMode->mVsyncPeriod = vsyncPeriod;
+ mDisplayMode->mFps = Fps::fromPeriodNsecs(vsyncPeriod);
return *this;
}
@@ -111,7 +113,8 @@
int32_t getWidth() const { return mWidth; }
int32_t getHeight() const { return mHeight; }
- nsecs_t getVsyncPeriod() const { return mVsyncPeriod; }
+ Fps getFps() const { return mFps; }
+ nsecs_t getVsyncPeriod() const { return mFps.getPeriodNsecs(); }
float getDpiX() const { return mDpiX; }
float getDpiY() const { return mDpiY; }
int32_t getConfigGroup() const { return mConfigGroup; }
@@ -124,10 +127,18 @@
int32_t mWidth = -1;
int32_t mHeight = -1;
- nsecs_t mVsyncPeriod = -1;
+ Fps mFps;
float mDpiX = -1;
float mDpiY = -1;
int32_t mConfigGroup = -1;
};
+inline std::string to_string(const DisplayMode& mode) {
+ return base::StringPrintf("{id=%zu, hwcId=%d, width=%d, height=%d, refreshRate=%s, "
+ "dpiX=%.2f, dpiY=%.2f, configGroup=%d}",
+ mode.getId().value(), mode.getHwcId(), mode.getWidth(),
+ mode.getHeight(), to_string(mode.getFps()).c_str(), mode.getDpiX(),
+ mode.getDpiY(), mode.getConfigGroup());
+}
+
} // namespace android
\ No newline at end of file
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 6350144..46dc54e 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -674,20 +674,14 @@
}
status_t HWComposer::setActiveModeWithConstraints(
- PhysicalDisplayId displayId, DisplayModeId modeId,
+ PhysicalDisplayId displayId, hal::HWConfigId hwcModeId,
const hal::VsyncPeriodChangeConstraints& constraints,
hal::VsyncPeriodChangeTimeline* outTimeline) {
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
- auto& displayData = mDisplayData[displayId];
- if (modeId.value() >= displayData.modes.size()) {
- LOG_DISPLAY_ERROR(displayId, ("Invalid mode " + std::to_string(modeId.value())).c_str());
- return BAD_INDEX;
- }
-
- const auto hwcConfigId = displayData.modes[modeId.value()]->getHwcId();
- auto error = displayData.hwcDisplay->setActiveConfigWithConstraints(hwcConfigId, constraints,
- outTimeline);
+ auto error = mDisplayData[displayId].hwcDisplay->setActiveConfigWithConstraints(hwcModeId,
+ constraints,
+ outTimeline);
RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
return NO_ERROR;
}
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 59c3699..1ffe276 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -198,7 +198,7 @@
virtual DisplayConnectionType getDisplayConnectionType(PhysicalDisplayId) const = 0;
virtual bool isVsyncPeriodSwitchSupported(PhysicalDisplayId) const = 0;
virtual nsecs_t getDisplayVsyncPeriod(PhysicalDisplayId) const = 0;
- virtual status_t setActiveModeWithConstraints(PhysicalDisplayId, DisplayModeId,
+ virtual status_t setActiveModeWithConstraints(PhysicalDisplayId, hal::HWConfigId,
const hal::VsyncPeriodChangeConstraints&,
hal::VsyncPeriodChangeTimeline* outTimeline) = 0;
virtual status_t setAutoLowLatencyMode(PhysicalDisplayId, bool on) = 0;
@@ -329,7 +329,7 @@
DisplayConnectionType getDisplayConnectionType(PhysicalDisplayId) const override;
bool isVsyncPeriodSwitchSupported(PhysicalDisplayId) const override;
nsecs_t getDisplayVsyncPeriod(PhysicalDisplayId displayId) const override;
- status_t setActiveModeWithConstraints(PhysicalDisplayId, DisplayModeId,
+ status_t setActiveModeWithConstraints(PhysicalDisplayId, hal::HWConfigId,
const hal::VsyncPeriodChangeConstraints&,
hal::VsyncPeriodChangeTimeline* outTimeline) override;
status_t setAutoLowLatencyMode(PhysicalDisplayId, bool) override;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index bf0c2d6..4225e92 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -900,16 +900,14 @@
Mutex::Autolock lock(mStateLock);
- const auto displayId = getPhysicalDisplayIdLocked(displayToken);
- if (!displayId) {
+ const auto display = getDisplayDeviceLocked(displayToken);
+ if (!display) {
return NAME_NOT_FOUND;
}
- const bool isInternal = (displayId == getInternalDisplayIdLocked());
-
configs->clear();
- for (const auto& mode : getHwComposer().getModes(*displayId)) {
+ for (const auto& mode : display->getSupportedModes()) {
DisplayConfig config;
auto width = mode->getWidth();
@@ -918,7 +916,7 @@
auto xDpi = mode->getDpiX();
auto yDpi = mode->getDpiY();
- if (isInternal &&
+ if (display->isPrimary() &&
(internalDisplayOrientation == ui::ROTATION_90 ||
internalDisplayOrientation == ui::ROTATION_270)) {
std::swap(width, height);
@@ -981,7 +979,7 @@
Mutex::Autolock lock(mStateLock);
if (const auto display = getDisplayDeviceLocked(displayToken)) {
- activeConfig = display->getActiveMode().value();
+ activeConfig = display->getActiveMode()->getId().value();
isPrimary = display->isPrimary();
} else {
ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
@@ -1011,9 +1009,9 @@
mDesiredActiveConfig = info;
mDesiredActiveConfig.event = mDesiredActiveConfig.event | prevConfig;
} else {
- // Check is we are already at the desired config
+ // Check if we are already at the desired config
const auto display = getDefaultDisplayDeviceLocked();
- if (!display || display->getActiveMode() == refreshRate.getConfigId()) {
+ if (!display || display->getActiveMode()->getId() == refreshRate.getConfigId()) {
return;
}
@@ -1030,7 +1028,7 @@
// VsyncController model is locked.
modulateVsync(&VsyncModulator::onRefreshRateChangeInitiated);
- updatePhaseConfiguration(refreshRate);
+ updatePhaseConfiguration(refreshRate.getFps());
mScheduler->setConfigChangePending(true);
}
@@ -1039,7 +1037,7 @@
}
}
-status_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& displayToken, int mode) {
+status_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& displayToken, int modeId) {
ATRACE_CALL();
if (!displayToken) {
@@ -1052,22 +1050,29 @@
ALOGE("Attempt to set allowed display configs for invalid display token %p",
displayToken.get());
return NAME_NOT_FOUND;
- } else if (display->isVirtual()) {
+ }
+
+ if (display->isVirtual()) {
ALOGW("Attempt to set allowed display configs for virtual display");
return INVALID_OPERATION;
- } else {
- const DisplayModeId config(mode);
- const auto fps = mRefreshRateConfigs->getRefreshRateFromConfigId(config).getFps();
- // Keep the old switching type.
- const auto allowGroupSwitching =
- mRefreshRateConfigs->getCurrentPolicy().allowGroupSwitching;
- const scheduler::RefreshRateConfigs::Policy policy{config,
- allowGroupSwitching,
- {fps, fps}};
- constexpr bool kOverridePolicy = false;
-
- return setDesiredDisplayConfigSpecsInternal(display, policy, kOverridePolicy);
}
+
+ const auto mode = display->getMode(DisplayModeId{modeId});
+ if (!mode) {
+ ALOGW("Attempt to switch to an unsupported mode %d.", modeId);
+ return BAD_VALUE;
+ }
+
+ const auto fps = mode->getFps();
+ // Keep the old switching type.
+ const auto allowGroupSwitching =
+ mRefreshRateConfigs->getCurrentPolicy().allowGroupSwitching;
+ const scheduler::RefreshRateConfigs::Policy policy{mode->getId(),
+ allowGroupSwitching,
+ {fps, fps}};
+ constexpr bool kOverridePolicy = false;
+
+ return setDesiredDisplayConfigSpecsInternal(display, policy, kOverridePolicy);
});
return future.get();
@@ -1081,48 +1086,58 @@
return;
}
- auto oldRefreshRate = mRefreshRateConfigs->getRefreshRateFromConfigId(display->getActiveMode());
+ const auto upcomingConfig = display->getMode(mUpcomingActiveConfig.configId);
+ if (!upcomingConfig) {
+ ALOGW("Upcoming active config is no longer supported. ConfigId = %zu",
+ mUpcomingActiveConfig.configId.value());
+ // TODO(b/159590486) Handle the error better. Some parts of SurfaceFlinger may
+ // have been already updated with the upcoming active config.
+ return;
+ }
+ const Fps oldRefreshRate = display->getActiveMode()->getFps();
std::lock_guard<std::mutex> lock(mActiveConfigLock);
mRefreshRateConfigs->setCurrentConfigId(mUpcomingActiveConfig.configId);
display->setActiveMode(mUpcomingActiveConfig.configId);
- auto refreshRate =
- mRefreshRateConfigs->getRefreshRateFromConfigId(mUpcomingActiveConfig.configId);
- mRefreshRateStats->setRefreshRate(refreshRate.getFps());
+ const Fps refreshRate = upcomingConfig->getFps();
- if (refreshRate.getVsyncPeriod() != oldRefreshRate.getVsyncPeriod()) {
+ mRefreshRateStats->setRefreshRate(refreshRate);
+
+ if (!refreshRate.equalsWithMargin(oldRefreshRate)) {
mTimeStats->incrementRefreshRateSwitches();
}
updatePhaseConfiguration(refreshRate);
- ATRACE_INT("ActiveConfigFPS", refreshRate.getFps().getValue());
+ ATRACE_INT("ActiveConfigFPS", refreshRate.getValue());
if (mUpcomingActiveConfig.event != Scheduler::ConfigEvent::None) {
- const nsecs_t vsyncPeriod =
- mRefreshRateConfigs->getRefreshRateFromConfigId(mUpcomingActiveConfig.configId)
- .getVsyncPeriod();
+ const nsecs_t vsyncPeriod = refreshRate.getPeriodNsecs();
const auto physicalId = display->getPhysicalId();
mScheduler->onPrimaryDisplayConfigChanged(mAppConnectionHandle, physicalId,
mUpcomingActiveConfig.configId, vsyncPeriod);
}
}
-void SurfaceFlinger::desiredActiveConfigChangeDone() {
+void SurfaceFlinger::clearDesiredActiveConfigState() {
std::lock_guard<std::mutex> lock(mActiveConfigLock);
mDesiredActiveConfig.event = Scheduler::ConfigEvent::None;
mDesiredActiveConfigChanged = false;
-
- const auto& refreshRate =
- mRefreshRateConfigs->getRefreshRateFromConfigId(mDesiredActiveConfig.configId);
-
- mScheduler->resyncToHardwareVsync(true, refreshRate.getVsyncPeriod());
- updatePhaseConfiguration(refreshRate);
mScheduler->setConfigChangePending(false);
}
+void SurfaceFlinger::desiredActiveConfigChangeDone() {
+ const auto modeId = getDesiredActiveConfig()->configId;
+
+ clearDesiredActiveConfigState();
+
+ const auto& refreshRate = getDefaultDisplayDeviceLocked()->getMode(modeId)->getFps();
+ mScheduler->resyncToHardwareVsync(true, refreshRate.getPeriodNsecs());
+ updatePhaseConfiguration(refreshRate);
+}
+
void SurfaceFlinger::performSetActiveConfig() {
ATRACE_CALL();
- ALOGV("performSetActiveConfig");
+ ALOGV("%s", __FUNCTION__);
// Store the local variable to release the lock.
const auto desiredActiveConfig = getDesiredActiveConfig();
if (!desiredActiveConfig) {
@@ -1130,12 +1145,19 @@
return;
}
- auto refreshRate =
- mRefreshRateConfigs->getRefreshRateFromConfigId(desiredActiveConfig->configId);
- ALOGV("performSetActiveConfig changing active config to %zu(%s)",
- refreshRate.getConfigId().value(), refreshRate.getName().c_str());
const auto display = getDefaultDisplayDeviceLocked();
- if (!display || display->getActiveMode() == desiredActiveConfig->configId) {
+ const auto desiredConfig = display->getMode(desiredActiveConfig->configId);
+ if (!desiredConfig) {
+ ALOGW("Desired display config is no longer supported. Config ID = %zu",
+ desiredActiveConfig->configId.value());
+ clearDesiredActiveConfigState();
+ return;
+ }
+ const auto refreshRate = desiredConfig->getFps();
+ ALOGV("performSetActiveConfig changing active config to %zu(%s)",
+ desiredConfig->getId().value(), to_string(refreshRate).c_str());
+
+ if (!display || display->getActiveMode()->getId() == desiredActiveConfig->configId) {
// display is not valid or we are already in the requested mode
// on both cases there is nothing left to do
desiredActiveConfigChangeDone();
@@ -1143,7 +1165,7 @@
}
// Desired active config was set, it is different than the config currently in use, however
- // allowed configs might have change by the time we process the refresh.
+ // allowed configs might have changed by the time we process the refresh.
// Make sure the desired config is still allowed
if (!isDisplayConfigAllowed(desiredActiveConfig->configId)) {
desiredActiveConfigChangeDone();
@@ -1151,9 +1173,8 @@
}
mUpcomingActiveConfig = *desiredActiveConfig;
- const auto displayId = display->getPhysicalId();
- ATRACE_INT("ActiveConfigFPS_HWC", refreshRate.getFps().getValue());
+ ATRACE_INT("ActiveConfigFPS_HWC", refreshRate.getValue());
// TODO(b/142753666) use constrains
hal::VsyncPeriodChangeConstraints constraints;
@@ -1161,13 +1182,12 @@
constraints.seamlessRequired = false;
hal::VsyncPeriodChangeTimeline outTimeline;
- auto status =
- getHwComposer().setActiveModeWithConstraints(displayId, mUpcomingActiveConfig.configId,
- constraints, &outTimeline);
+ const auto status =
+ display->initiateModeChange(mUpcomingActiveConfig.configId, constraints, &outTimeline);
if (status != NO_ERROR) {
- // setActiveModeWithConstraints may fail if a hotplug event is just about
+ // initiateModeChange may fail if a hotplug event is just about
// to be sent. We just log the error in this case.
- ALOGW("setActiveModeWithConstraints failed: %d", status);
+ ALOGW("initiateModeChange failed: %d", status);
return;
}
@@ -2409,8 +2429,9 @@
const DisplayDeviceState& state,
const sp<compositionengine::DisplaySurface>& displaySurface,
const sp<IGraphicBufferProducer>& producer) {
- DisplayDeviceCreationArgs creationArgs(this, displayToken, compositionDisplay);
+ DisplayDeviceCreationArgs creationArgs(this, getHwComposer(), displayToken, compositionDisplay);
creationArgs.sequenceId = state.sequenceId;
+ creationArgs.hwComposer = getHwComposer();
creationArgs.isSecure = state.isSecure;
creationArgs.displaySurface = displaySurface;
creationArgs.hasWideColorGamut = false;
@@ -2422,6 +2443,7 @@
if (const auto id = PhysicalDisplayId::tryCast(compositionDisplay->getId())) {
creationArgs.isPrimary = id == getInternalDisplayIdLocked();
+ creationArgs.supportedModes = getHwComposer().getModes(*id);
if (useColorManagement) {
std::vector<ColorMode> modes = getHwComposer().getColorModes(*id);
@@ -2629,7 +2651,7 @@
// TODO(b/175678215) Handle the case when currentConfig is not in configs
mRefreshRateConfigs->updateDisplayConfigs(configs, currentConfig);
mVsyncConfiguration->reset();
- updatePhaseConfiguration(mRefreshRateConfigs->getCurrentRefreshRate());
+ updatePhaseConfiguration(mRefreshRateConfigs->getCurrentRefreshRate().getFps());
if (mRefreshRateOverlay) {
mRefreshRateOverlay->reset();
}
@@ -2970,10 +2992,10 @@
getHwComposer().hasCapability(hal::Capability::PRESENT_FENCE_IS_NOT_RELIABLE));
}
-void SurfaceFlinger::updatePhaseConfiguration(const RefreshRate& refreshRate) {
- mVsyncConfiguration->setRefreshRateFps(refreshRate.getFps());
+void SurfaceFlinger::updatePhaseConfiguration(const Fps& refreshRate) {
+ mVsyncConfiguration->setRefreshRateFps(refreshRate);
setVsyncConfig(mVsyncModulator->setVsyncConfigSet(mVsyncConfiguration->getCurrentConfigs()),
- refreshRate.getVsyncPeriod());
+ refreshRate.getPeriodNsecs());
}
void SurfaceFlinger::setVsyncConfig(const VsyncModulator::VsyncConfig& config,
@@ -5337,22 +5359,22 @@
return NO_ERROR;
}
case 1035: {
- const int newConfigId = data.readInt32();
+ const int modeId = data.readInt32();
mDebugDisplayConfigSetByBackdoor = false;
+
const auto displayId = getInternalDisplayId();
if (!displayId) {
ALOGE("No internal display found.");
return NO_ERROR;
}
- const auto numConfigs = getHwComposer().getModes(*displayId).size();
- if (newConfigId >= 0 && newConfigId < numConfigs) {
- const auto displayToken = getInternalDisplayToken();
- status_t result = setActiveConfig(displayToken, newConfigId);
- if (result != NO_ERROR) {
- return result;
- }
- mDebugDisplayConfigSetByBackdoor = true;
+
+ status_t result = setActiveConfig(getPhysicalDisplayToken(*displayId), modeId);
+ if (result != NO_ERROR) {
+ return result;
}
+
+ mDebugDisplayConfigSetByBackdoor = true;
+
return NO_ERROR;
}
case 1036: {
@@ -6034,7 +6056,7 @@
if (!display->isPrimary()) {
// TODO(b/144711714): For non-primary displays we should be able to set an active config
- // as well. For now, just call directly to setActiveModeWithConstraints but ideally
+ // as well. For now, just call directly to initiateModeChange but ideally
// it should go thru setDesiredActiveConfig, similar to primary display.
ALOGV("setAllowedDisplayConfigsInternal for non-primary display");
const auto displayId = display->getPhysicalId();
@@ -6044,8 +6066,8 @@
constraints.seamlessRequired = false;
hal::VsyncPeriodChangeTimeline timeline = {0, 0, 0};
- if (getHwComposer().setActiveModeWithConstraints(displayId, policy->defaultConfig,
- constraints, &timeline) < 0) {
+ if (display->initiateModeChange(policy->defaultConfig, constraints, &timeline) !=
+ NO_ERROR) {
return BAD_VALUE;
}
if (timeline.refreshRequired) {
@@ -6053,9 +6075,7 @@
}
display->setActiveMode(policy->defaultConfig);
- const nsecs_t vsyncPeriod = getHwComposer()
- .getModes(displayId)[policy->defaultConfig.value()]
- ->getVsyncPeriod();
+ const nsecs_t vsyncPeriod = display->getMode(policy->defaultConfig)->getVsyncPeriod();
mScheduler->onNonPrimaryDisplayConfigChanged(mAppConnectionHandle, displayId,
policy->defaultConfig, vsyncPeriod);
return NO_ERROR;
@@ -6081,12 +6101,11 @@
// TODO(b/140204874): Leave the event in until we do proper testing with all apps that might
// be depending in this callback.
- const nsecs_t vsyncPeriod =
- mRefreshRateConfigs->getRefreshRateFromConfigId(display->getActiveMode())
- .getVsyncPeriod();
+ const auto activeConfig = display->getActiveMode();
+ const nsecs_t vsyncPeriod = activeConfig->getVsyncPeriod();
const auto physicalId = display->getPhysicalId();
mScheduler->onPrimaryDisplayConfigChanged(mAppConnectionHandle, physicalId,
- display->getActiveMode(), vsyncPeriod);
+ activeConfig->getId(), vsyncPeriod);
toggleKernelIdleTimer();
auto configId = mScheduler->getPreferredConfigId();
@@ -6174,8 +6193,7 @@
} else if (display->isVirtual()) {
return INVALID_OPERATION;
} else {
- const auto displayId = display->getPhysicalId();
- const auto activeMode = getHwComposer().getActiveMode(displayId);
+ const auto activeMode = display->getActiveMode();
*outDefaultConfig = activeMode->getId().value();
*outAllowGroupSwitching = false;
auto vsyncPeriod = activeMode->getVsyncPeriod();
@@ -6395,10 +6413,8 @@
if (const auto display = getDefaultDisplayDeviceLocked()) {
mRefreshRateOverlay->setViewport(display->getSize());
+ mRefreshRateOverlay->changeRefreshRate(display->getActiveMode()->getFps());
}
-
- mRefreshRateOverlay->changeRefreshRate(
- mRefreshRateConfigs->getCurrentRefreshRate().getFps());
}
}));
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 194131d..1deef6e 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -54,6 +54,7 @@
#include "DisplayHardware/PowerAdvisor.h"
#include "DisplayIdGenerator.h"
#include "Effects/Daltonizer.h"
+#include "Fps.h"
#include "FrameTracker.h"
#include "LayerVector.h"
#include "Scheduler/RefreshRateConfigs.h"
@@ -667,7 +668,7 @@
void signalLayerUpdate();
void signalRefresh();
- // called on the main thread in response to initializeDisplays()
+ // Called on the main thread in response to initializeDisplays()
void onInitializeDisplays() REQUIRES(mStateLock);
// Sets the desired active config bit. It obtains the lock, and sets mDesiredActiveConfig.
void setDesiredActiveConfig(const ActiveConfigInfo& info) REQUIRES(mStateLock);
@@ -678,9 +679,10 @@
// Calls to setActiveConfig on the main thread if there is a pending config
// that needs to be applied.
void performSetActiveConfig() REQUIRES(mStateLock);
+ void clearDesiredActiveConfigState() REQUIRES(mStateLock) EXCLUDES(mActiveConfigLock);
// Called when active config is no longer is progress
void desiredActiveConfigChangeDone() REQUIRES(mStateLock);
- // called on the main thread in response to setPowerMode()
+ // Called on the main thread in response to setPowerMode()
void setPowerModeInternal(const sp<DisplayDevice>& display, hal::PowerMode mode)
REQUIRES(mStateLock);
@@ -712,8 +714,8 @@
void commitInputWindowCommands() REQUIRES(mStateLock);
void updateCursorAsync();
- void initScheduler(PhysicalDisplayId primaryDisplayId);
- void updatePhaseConfiguration(const RefreshRate&);
+ void initScheduler(PhysicalDisplayId primaryDisplayId) REQUIRES(mStateLock);
+ void updatePhaseConfiguration(const Fps&) REQUIRES(mStateLock);
void setVsyncConfig(const VsyncModulator::VsyncConfig&, nsecs_t vsyncPeriod);
/* handlePageFlip - latch a new buffer if available and compute the dirty
diff --git a/services/surfaceflinger/TimeStats/TimeStats.h b/services/surfaceflinger/TimeStats/TimeStats.h
index 8fac8e9..df40ef6 100644
--- a/services/surfaceflinger/TimeStats/TimeStats.h
+++ b/services/surfaceflinger/TimeStats/TimeStats.h
@@ -315,8 +315,9 @@
static const size_t MAX_NUM_LAYER_RECORDS = 200;
static const size_t MAX_NUM_LAYER_STATS = 200;
+ static const size_t MAX_NUM_PULLED_LAYERS = MAX_NUM_LAYER_STATS;
std::unique_ptr<StatsEventDelegate> mStatsDelegate = std::make_unique<StatsEventDelegate>();
- size_t mMaxPulledLayers = 8;
+ size_t mMaxPulledLayers = MAX_NUM_PULLED_LAYERS;
size_t mMaxPulledHistogramBuckets = 6;
};
diff --git a/services/surfaceflinger/tests/unittests/HWComposerTest.cpp b/services/surfaceflinger/tests/unittests/HWComposerTest.cpp
index 71986fe..1e24c0a 100644
--- a/services/surfaceflinger/tests/unittests/HWComposerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/HWComposerTest.cpp
@@ -35,6 +35,7 @@
#include "DisplayHardware/DisplayMode.h"
#include "DisplayHardware/HWComposer.h"
+#include "DisplayHardware/Hal.h"
#include "mock/DisplayHardware/MockComposer.h"
// TODO(b/129481165): remove the #pragma below and fix conversion issues
@@ -230,7 +231,7 @@
constraints.seamlessRequired = false;
hal::VsyncPeriodChangeTimeline timeline = {0, 0, 0};
- constexpr DisplayModeId kConfigIndex(0);
+ constexpr Config kConfigIndex = 0;
const auto status =
hwc.setActiveModeWithConstraints(physicalId, kConfigIndex, constraints, &timeline);
EXPECT_EQ(NO_ERROR, status);
@@ -243,8 +244,10 @@
hwc.allocatePhysicalDisplay(hwcId, physicalId);
for (size_t configIndex = 0; configIndex < kConfigs.size(); configIndex++) {
- const auto status = hwc.setActiveModeWithConstraints(physicalId, DisplayModeId(configIndex),
- constraints, &timeline);
+ const auto status =
+ hwc.setActiveModeWithConstraints(physicalId,
+ static_cast<hal::HWConfigId>(configIndex),
+ constraints, &timeline);
EXPECT_EQ(NO_ERROR, status) << "Error when switching to config " << configIndex;
}
}
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetupNewDisplayDeviceInternalTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetupNewDisplayDeviceInternalTest.cpp
index ca7c755..9a95ab4 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetupNewDisplayDeviceInternalTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetupNewDisplayDeviceInternalTest.cpp
@@ -262,12 +262,14 @@
EXPECT_EQ(Case::HdrSupport::HDR10_SUPPORTED, device->hasHDR10Support());
EXPECT_EQ(Case::HdrSupport::HDR_HLG_SUPPORTED, device->hasHLGSupport());
EXPECT_EQ(Case::HdrSupport::HDR_DOLBY_VISION_SUPPORTED, device->hasDolbyVisionSupport());
- // Note: This is not Case::Display::HWC_ACTIVE_CONFIG_ID as the ids are
- // remapped, and the test only ever sets up one config. If there were an error
- // looking up the remapped index, device->getActiveMode() would be -1 instead.
- EXPECT_EQ(0, device->getActiveMode().value());
EXPECT_EQ(Case::PerFrameMetadataSupport::PER_FRAME_METADATA_KEYS,
device->getSupportedPerFrameMetadata());
+
+ if constexpr (Case::Display::CONNECTION_TYPE::value) {
+ EXPECT_EQ(1, device->getSupportedModes().size());
+ EXPECT_NE(nullptr, device->getActiveMode());
+ EXPECT_EQ(Case::Display::HWC_ACTIVE_CONFIG_ID, device->getActiveMode()->getHwcId());
+ }
}
TEST_F(SetupNewDisplayDeviceInternalTest, createSimplePrimaryDisplay) {
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 9a9eeab..fc284ff 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -598,7 +598,8 @@
std::optional<DisplayConnectionType> connectionType,
std::optional<hal::HWDisplayId> hwcDisplayId, bool isPrimary)
: mFlinger(flinger),
- mCreationArgs(flinger.mFlinger.get(), mDisplayToken, compositionDisplay),
+ mCreationArgs(flinger.mFlinger.get(), flinger.mFlinger->getHwComposer(),
+ mDisplayToken, compositionDisplay),
mHwcDisplayId(hwcDisplayId) {
mCreationArgs.connectionType = connectionType;
mCreationArgs.isPrimary = isPrimary;