Merge "Hold mMutex lock and check abandoned when accessing mLayer" into rvc-dev
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h
index 5ce2fdc..f680460 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h
@@ -63,6 +63,12 @@
// Sets the dataspace used for rendering the surface
virtual void setBufferDataspace(ui::Dataspace) = 0;
+ // Sets the pixel format used for rendering the surface.
+ // Changing the pixel format of the buffer will result in buffer
+ // reallocation as well as some reconfiguration of the graphics context,
+ // which are both expensive operations.
+ virtual void setBufferPixelFormat(ui::PixelFormat) = 0;
+
// Configures the protected rendering on the surface
virtual void setProtected(bool useProtected) = 0;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
index 9ca7d2f..7a4f738 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
@@ -70,11 +70,13 @@
using ChangedTypes = android::HWComposer::DeviceRequestedChanges::ChangedTypes;
using DisplayRequests = android::HWComposer::DeviceRequestedChanges::DisplayRequests;
using LayerRequests = android::HWComposer::DeviceRequestedChanges::LayerRequests;
+ using ClientTargetProperty = android::HWComposer::DeviceRequestedChanges::ClientTargetProperty;
virtual bool anyLayersRequireClientComposition() const;
virtual bool allLayersRequireClientComposition() const;
virtual void applyChangedTypesToLayers(const ChangedTypes&);
virtual void applyDisplayRequests(const DisplayRequests&);
virtual void applyLayerRequestsToLayers(const LayerRequests&);
+ virtual void applyClientTargetRequests(const ClientTargetProperty&);
// Internal
virtual void setConfiguration(const compositionengine::DisplayCreationArgs&);
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h
index 692d78d..5127a6f 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h
@@ -49,6 +49,7 @@
const sp<Fence>& getClientTargetAcquireFence() const override;
void setBufferDataspace(ui::Dataspace) override;
+ void setBufferPixelFormat(ui::PixelFormat) override;
void setDisplaySize(const ui::Size&) override;
void setProtected(bool useProtected) override;
status_t beginFrame(bool mustRecompose) override;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h
index ed4d492..a0cae6f 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h
@@ -36,6 +36,7 @@
MOCK_METHOD1(setDisplaySize, void(const ui::Size&));
MOCK_METHOD1(setProtected, void(bool));
MOCK_METHOD1(setBufferDataspace, void(ui::Dataspace));
+ MOCK_METHOD1(setBufferPixelFormat, void(ui::PixelFormat));
MOCK_METHOD1(beginFrame, status_t(bool mustRecompose));
MOCK_METHOD2(prepareFrame, void(bool, bool));
MOCK_METHOD1(dequeueBuffer, sp<GraphicBuffer>(base::unique_fd*));
diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp
index ab26939..d201104 100644
--- a/services/surfaceflinger/CompositionEngine/src/Display.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp
@@ -259,6 +259,7 @@
applyChangedTypesToLayers(changes->changedTypes);
applyDisplayRequests(changes->displayRequests);
applyLayerRequestsToLayers(changes->layerRequests);
+ applyClientTargetRequests(changes->clientTargetProperty);
}
// Determine what type of composition we are doing from the final state
@@ -326,6 +327,16 @@
}
}
+void Display::applyClientTargetRequests(const ClientTargetProperty& clientTargetProperty) {
+ if (clientTargetProperty.dataspace == ui::Dataspace::UNKNOWN) {
+ return;
+ }
+ auto outputState = editState();
+ outputState.dataspace = clientTargetProperty.dataspace;
+ getRenderSurface()->setBufferDataspace(clientTargetProperty.dataspace);
+ getRenderSurface()->setBufferPixelFormat(clientTargetProperty.pixelFormat);
+}
+
compositionengine::Output::FrameFences Display::presentAndGetFrameFences() {
auto result = impl::Output::presentAndGetFrameFences();
diff --git a/services/surfaceflinger/CompositionEngine/src/OutputCompositionState.cpp b/services/surfaceflinger/CompositionEngine/src/OutputCompositionState.cpp
index ca5be48..4835aef 100644
--- a/services/surfaceflinger/CompositionEngine/src/OutputCompositionState.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/OutputCompositionState.cpp
@@ -38,6 +38,7 @@
out.append("\n ");
+ dumpVal(out, "bounds", bounds);
dumpVal(out, "frame", frame);
dumpVal(out, "viewport", viewport);
dumpVal(out, "sourceClip", sourceClip);
diff --git a/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp b/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
index 4084653..2773fd3 100644
--- a/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
@@ -104,6 +104,10 @@
static_cast<android_dataspace>(dataspace));
}
+void RenderSurface::setBufferPixelFormat(ui::PixelFormat pixelFormat) {
+ native_window_set_buffers_format(mNativeWindow.get(), static_cast<int32_t>(pixelFormat));
+}
+
void RenderSurface::setProtected(bool useProtected) {
uint64_t usageFlags = GRALLOC_USAGE_HW_RENDER;
if (useProtected) {
diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
index 62977a4..09f37fb 100644
--- a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
@@ -654,6 +654,7 @@
{{nullptr, hal::Composition::CLIENT}},
hal::DisplayRequest::FLIP_CLIENT_TARGET,
{{nullptr, hal::LayerRequest::CLEAR_CLIENT_TARGET}},
+ {hal::PixelFormat::RGBA_8888, hal::Dataspace::UNKNOWN},
};
// Since two calls are made to anyLayersRequireClientComposition with different return
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 0c8aafc..730f297 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -227,6 +227,8 @@
if (destinationClip.isEmpty()) {
destinationClip = displayBounds;
}
+ // Make sure the destination clip is contained in the display bounds
+ destinationClip.intersect(displayBounds, &destinationClip);
uint32_t transformOrientation;
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
index 97eeea2..dbdffec 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
@@ -1354,6 +1354,12 @@
return error;
}
+Error Composer::getClientTargetProperty(
+ Display display, IComposerClient::ClientTargetProperty* outClientTargetProperty) {
+ mReader.takeClientTargetProperty(display, outClientTargetProperty);
+ return Error::NONE;
+}
+
CommandReader::~CommandReader()
{
resetData();
@@ -1662,10 +1668,22 @@
*state = data.presentOrValidateState;
}
+void CommandReader::takeClientTargetProperty(
+ Display display, IComposerClient::ClientTargetProperty* outClientTargetProperty) {
+ auto found = mReturnData.find(display);
+
+ // If not found, return the default values.
+ if (found == mReturnData.end()) {
+ outClientTargetProperty->pixelFormat = PixelFormat::RGBA_8888;
+ outClientTargetProperty->dataspace = Dataspace::UNKNOWN;
+ }
+
+ ReturnData& data = found->second;
+ *outClientTargetProperty = data.clientTargetProperty;
+}
+
} // namespace impl
-
} // namespace Hwc2
-
} // namespace android
// TODO(b/129481165): remove the #pragma below and fix conversion issues
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h
index aa43f09..00ef782 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h
@@ -240,6 +240,8 @@
const std::vector<uint8_t>& value) = 0;
virtual V2_4::Error getLayerGenericMetadataKeys(
std::vector<IComposerClient::LayerGenericMetadataKey>* outKeys) = 0;
+ virtual Error getClientTargetProperty(
+ Display display, IComposerClient::ClientTargetProperty* outClientTargetProperty) = 0;
};
namespace impl {
@@ -282,6 +284,10 @@
// Get what stage succeeded during PresentOrValidate: Present or Validate
void takePresentOrValidateStage(Display display, uint32_t * state);
+ // Get the client target properties requested by hardware composer.
+ void takeClientTargetProperty(Display display,
+ IComposerClient::ClientTargetProperty* outClientTargetProperty);
+
private:
void resetData();
@@ -479,6 +485,9 @@
bool mandatory, const std::vector<uint8_t>& value) override;
V2_4::Error getLayerGenericMetadataKeys(
std::vector<IComposerClient::LayerGenericMetadataKey>* outKeys) override;
+ Error getClientTargetProperty(
+ Display display,
+ IComposerClient::ClientTargetProperty* outClientTargetProperty) override;
private:
#if defined(USE_VR_COMPOSER) && USE_VR_COMPOSER
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index fb82033..af76b81 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -668,6 +668,11 @@
return static_cast<Error>(intError);
}
+Error Display::getClientTargetProperty(ClientTargetProperty* outClientTargetProperty) {
+ const auto error = mComposer.getClientTargetProperty(mId, outClientTargetProperty);
+ return static_cast<Error>(error);
+}
+
// For use by Device
void Display::setConnected(bool connected) {
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index f4c7fdd..6819ff4 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -234,6 +234,8 @@
[[clang::warn_unused_result]] virtual hal::Error getSupportedContentTypes(
std::vector<hal::ContentType>*) const = 0;
[[clang::warn_unused_result]] virtual hal::Error setContentType(hal::ContentType) = 0;
+ [[clang::warn_unused_result]] virtual hal::Error getClientTargetProperty(
+ hal::ClientTargetProperty* outClientTargetProperty) = 0;
};
namespace impl {
@@ -305,6 +307,8 @@
hal::Error getSupportedContentTypes(
std::vector<hal::ContentType>* outSupportedContentTypes) const override;
hal::Error setContentType(hal::ContentType) override;
+ hal::Error getClientTargetProperty(hal::ClientTargetProperty* outClientTargetProperty) override;
+
// Other Display methods
hal::HWDisplayId getId() const override { return mId; }
bool isConnected() const override { return mIsConnected; }
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 038cec4..7a2f0f3 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -541,9 +541,12 @@
error = hwcDisplay->getRequests(&displayRequests, &layerRequests);
RETURN_IF_HWC_ERROR_FOR("getRequests", error, displayId, BAD_INDEX);
- outChanges->emplace(DeviceRequestedChanges{std::move(changedTypes), std::move(displayRequests),
- std::move(layerRequests)});
+ DeviceRequestedChanges::ClientTargetProperty clientTargetProperty;
+ error = hwcDisplay->getClientTargetProperty(&clientTargetProperty);
+ outChanges->emplace(DeviceRequestedChanges{std::move(changedTypes), std::move(displayRequests),
+ std::move(layerRequests),
+ std::move(clientTargetProperty)});
error = hwcDisplay->acceptChanges();
RETURN_IF_HWC_ERROR_FOR("acceptChanges", error, displayId, BAD_INDEX);
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index b7e9f3a..c355ebd 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -66,6 +66,18 @@
class HWComposer {
public:
+ struct DeviceRequestedChanges {
+ using ChangedTypes = std::unordered_map<HWC2::Layer*, hal::Composition>;
+ using ClientTargetProperty = hal::ClientTargetProperty;
+ using DisplayRequests = hal::DisplayRequest;
+ using LayerRequests = std::unordered_map<HWC2::Layer*, hal::LayerRequest>;
+
+ ChangedTypes changedTypes;
+ DisplayRequests displayRequests;
+ LayerRequests layerRequests;
+ ClientTargetProperty clientTargetProperty;
+ };
+
virtual ~HWComposer();
virtual void setConfiguration(HWC2::ComposerCallback* callback, int32_t sequenceId) = 0;
@@ -88,16 +100,6 @@
// Destroy a previously created layer
virtual void destroyLayer(DisplayId displayId, HWC2::Layer* layer) = 0;
- struct DeviceRequestedChanges {
- using ChangedTypes = std::unordered_map<HWC2::Layer*, hal::Composition>;
- using DisplayRequests = hal::DisplayRequest;
- using LayerRequests = std::unordered_map<HWC2::Layer*, hal::LayerRequest>;
-
- ChangedTypes changedTypes;
- DisplayRequests displayRequests;
- LayerRequests layerRequests;
- };
-
// Gets any required composition change requests from the HWC device.
//
// Note that frameUsesClientComposition must be set correctly based on
diff --git a/services/surfaceflinger/DisplayHardware/Hal.h b/services/surfaceflinger/DisplayHardware/Hal.h
index 66ee425..bb2888e 100644
--- a/services/surfaceflinger/DisplayHardware/Hal.h
+++ b/services/surfaceflinger/DisplayHardware/Hal.h
@@ -53,6 +53,7 @@
using Connection = IComposerCallback::Connection;
using ContentType = IComposerClient::ContentType;
using Capability = IComposer::Capability;
+using ClientTargetProperty = IComposerClient::ClientTargetProperty;
using DisplayCapability = IComposerClient::DisplayCapability;
using DisplayRequest = IComposerClient::DisplayRequest;
using DisplayType = IComposerClient::DisplayType;
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
index 4a4f9c8..e181c12 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
@@ -128,15 +128,24 @@
}
}
+ const bool hasExplicitVoteLayers =
+ explicitDefaultVoteLayers > 0 || explicitExactOrMultipleVoteLayers > 0;
+
// Consider the touch event if there are no Explicit* layers. Otherwise wait until after we've
// selected a refresh rate to see if we should apply touch boost.
- if (touchActive && explicitDefaultVoteLayers == 0 && explicitExactOrMultipleVoteLayers == 0) {
+ if (touchActive && !hasExplicitVoteLayers) {
ALOGV("TouchBoost - choose %s", getMaxRefreshRateByPolicyLocked().getName().c_str());
if (touchConsidered) *touchConsidered = true;
return getMaxRefreshRateByPolicyLocked();
}
- if (!touchActive && idle) {
+ // If the primary range consists of a single refresh rate then we can only
+ // move out the of range if layers explicitly request a different refresh
+ // rate.
+ const Policy* policy = getCurrentPolicyLocked();
+ const bool primaryRangeIsSingleRate = policy->primaryRange.min == policy->primaryRange.max;
+
+ if (!touchActive && idle && !(primaryRangeIsSingleRate && hasExplicitVoteLayers)) {
return getMinRefreshRateByPolicyLocked();
}
@@ -150,8 +159,6 @@
return getMinRefreshRateByPolicyLocked();
}
- const Policy* policy = getCurrentPolicyLocked();
-
// Find the best refresh rate based on score
std::vector<std::pair<const RefreshRate*, float>> scores;
scores.reserve(mAppRequestRefreshRates.size());
@@ -171,7 +178,8 @@
for (auto i = 0u; i < scores.size(); i++) {
bool inPrimaryRange =
scores[i].first->inPolicy(policy->primaryRange.min, policy->primaryRange.max);
- if (!inPrimaryRange && layer.vote != LayerVoteType::ExplicitDefault &&
+ if ((primaryRangeIsSingleRate || !inPrimaryRange) &&
+ layer.vote != LayerVoteType::ExplicitDefault &&
layer.vote != LayerVoteType::ExplicitExactOrMultiple) {
// Only layers with explicit frame rate settings are allowed to score refresh rates
// outside the primary range.
@@ -263,11 +271,23 @@
? getBestRefreshRate(scores.rbegin(), scores.rend())
: getBestRefreshRate(scores.begin(), scores.end());
+ if (primaryRangeIsSingleRate) {
+ // If we never scored any layers, then choose the rate from the primary
+ // range instead of picking a random score from the app range.
+ if (std::all_of(scores.begin(), scores.end(),
+ [](std::pair<const RefreshRate*, float> p) { return p.second == 0; })) {
+ return getMaxRefreshRateByPolicyLocked();
+ } else {
+ return *bestRefreshRate;
+ }
+ }
+
// Consider the touch event if there are no ExplicitDefault layers. ExplicitDefault are mostly
// interactive (as opposed to ExplicitExactOrMultiple) and therefore if those posted an explicit
// vote we should not change it if we get a touch event. Only apply touch boost if it will
// actually increase the refresh rate over the normal selection.
const RefreshRate& touchRefreshRate = getMaxRefreshRateByPolicyLocked();
+
if (touchActive && explicitDefaultVoteLayers == 0 &&
bestRefreshRate->fps < touchRefreshRate.fps) {
if (touchConsidered) *touchConsidered = true;
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
index 692f71f..c919e93 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
@@ -1205,6 +1205,121 @@
}
}
+TEST_F(RefreshRateConfigsTest,
+ getBestRefreshRate_withDisplayManagerRequestingSingleRate_ignoresTouchFlag) {
+ auto refreshRateConfigs =
+ std::make_unique<RefreshRateConfigs>(m60_90Device,
+ /*currentConfigId=*/HWC_CONFIG_ID_90);
+
+ ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(
+ {HWC_CONFIG_ID_90, {90.f, 90.f}, {60.f, 90.f}}),
+ 0);
+
+ auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
+ auto& lr = layers[0];
+
+ bool touchConsidered = false;
+ lr.vote = LayerVoteType::ExplicitExactOrMultiple;
+ lr.desiredRefreshRate = 60.0f;
+ lr.name = "60Hz ExplicitExactOrMultiple";
+ EXPECT_EQ(mExpected60Config,
+ refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ true, /*idle*/ false,
+ &touchConsidered));
+ EXPECT_EQ(false, touchConsidered);
+
+ lr.vote = LayerVoteType::ExplicitDefault;
+ lr.desiredRefreshRate = 60.0f;
+ lr.name = "60Hz ExplicitDefault";
+ EXPECT_EQ(mExpected60Config,
+ refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ true, /*idle*/ false,
+ &touchConsidered));
+ EXPECT_EQ(false, touchConsidered);
+}
+
+TEST_F(RefreshRateConfigsTest,
+ getBestRefreshRate_withDisplayManagerRequestingSingleRate_ignoresIdleFlag) {
+ auto refreshRateConfigs =
+ std::make_unique<RefreshRateConfigs>(m60_90Device,
+ /*currentConfigId=*/HWC_CONFIG_ID_60);
+
+ ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(
+ {HWC_CONFIG_ID_60, {60.f, 60.f}, {60.f, 90.f}}),
+ 0);
+
+ auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
+ auto& lr = layers[0];
+
+ bool touchConsidered = false;
+ lr.vote = LayerVoteType::ExplicitExactOrMultiple;
+ lr.desiredRefreshRate = 90.0f;
+ lr.name = "90Hz ExplicitExactOrMultiple";
+ EXPECT_EQ(mExpected90Config,
+ refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false, /*idle*/ true,
+ &touchConsidered));
+
+ lr.vote = LayerVoteType::ExplicitDefault;
+ lr.desiredRefreshRate = 90.0f;
+ lr.name = "90Hz ExplicitDefault";
+ EXPECT_EQ(mExpected90Config,
+ refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false, /*idle*/ true,
+ &touchConsidered));
+}
+
+TEST_F(RefreshRateConfigsTest,
+ getBestRefreshRate_withDisplayManagerRequestingSingleRate_onlySwitchesRatesForExplicitLayers) {
+ auto refreshRateConfigs =
+ std::make_unique<RefreshRateConfigs>(m60_90Device,
+ /*currentConfigId=*/HWC_CONFIG_ID_90);
+
+ ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(
+ {HWC_CONFIG_ID_90, {90.f, 90.f}, {60.f, 90.f}}),
+ 0);
+
+ bool touchConsidered = false;
+ EXPECT_EQ(mExpected90Config,
+ refreshRateConfigs->getBestRefreshRate({}, /*touchActive*/ false, /*idle*/ false,
+ &touchConsidered));
+ EXPECT_EQ(false, touchConsidered);
+
+ auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
+ auto& lr = layers[0];
+
+ lr.vote = LayerVoteType::ExplicitExactOrMultiple;
+ lr.desiredRefreshRate = 60.0f;
+ lr.name = "60Hz ExplicitExactOrMultiple";
+ EXPECT_EQ(mExpected60Config,
+ refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false, /*idle*/ false,
+ &touchConsidered));
+
+ lr.vote = LayerVoteType::ExplicitDefault;
+ lr.desiredRefreshRate = 60.0f;
+ lr.name = "60Hz ExplicitDefault";
+ EXPECT_EQ(mExpected60Config,
+ refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false, /*idle*/ false,
+ &touchConsidered));
+
+ lr.vote = LayerVoteType::Heuristic;
+ lr.desiredRefreshRate = 60.0f;
+ lr.name = "60Hz Heuristic";
+ EXPECT_EQ(mExpected90Config,
+ refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false, /*idle*/ false,
+ &touchConsidered));
+
+ lr.vote = LayerVoteType::Max;
+ lr.desiredRefreshRate = 60.0f;
+ lr.name = "60Hz Max";
+ EXPECT_EQ(mExpected90Config,
+ refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false, /*idle*/ false,
+ &touchConsidered));
+
+ lr.vote = LayerVoteType::Min;
+ lr.desiredRefreshRate = 60.0f;
+ lr.name = "60Hz Min";
+ EXPECT_EQ(mExpected90Config,
+ refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false, /*idle*/ false,
+ &touchConsidered));
+}
+
TEST_F(RefreshRateConfigsTest, groupSwitching) {
auto refreshRateConfigs =
std::make_unique<RefreshRateConfigs>(m60_90DeviceWithDifferentGroups,
@@ -1234,7 +1349,7 @@
TEST_F(RefreshRateConfigsTest, primaryVsAppRequestPolicy) {
auto refreshRateConfigs =
- std::make_unique<RefreshRateConfigs>(m60_90Device,
+ std::make_unique<RefreshRateConfigs>(m30_60_90Device,
/*currentConfigId=*/HWC_CONFIG_ID_60);
auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
@@ -1253,7 +1368,7 @@
};
ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(
- {HWC_CONFIG_ID_60, {60.f, 60.f}, {60.f, 90.f}}),
+ {HWC_CONFIG_ID_60, {30.f, 60.f}, {30.f, 90.f}}),
0);
bool touchConsidered;
EXPECT_EQ(HWC_CONFIG_ID_60,
@@ -1262,7 +1377,7 @@
&touchConsidered)
.getConfigId());
EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::NoVote, 90.f));
- EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::Min, 90.f));
+ EXPECT_EQ(HWC_CONFIG_ID_30, getFrameRate(LayerVoteType::Min, 90.f));
EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::Max, 90.f));
EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::Heuristic, 90.f));
EXPECT_EQ(HWC_CONFIG_ID_90, getFrameRate(LayerVoteType::ExplicitDefault, 90.f));
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
index 2a31078..c2c5072 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
@@ -140,6 +140,7 @@
const std::vector<uint8_t>&));
MOCK_METHOD1(getLayerGenericMetadataKeys,
V2_4::Error(std::vector<IComposerClient::LayerGenericMetadataKey>*));
+ MOCK_METHOD2(getClientTargetProperty, Error(Display, IComposerClient::ClientTargetProperty*));
};
} // namespace mock
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h
index dade9fc..fe99e77 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h
@@ -93,6 +93,7 @@
MOCK_METHOD1(setAutoLowLatencyMode, hal::Error(bool on));
MOCK_CONST_METHOD1(getSupportedContentTypes, hal::Error(std::vector<hal::ContentType>*));
MOCK_METHOD1(setContentType, hal::Error(hal::ContentType));
+ MOCK_METHOD1(getClientTargetProperty, hal::Error(hal::ClientTargetProperty*));
MOCK_CONST_METHOD1(getConnectionType, hal::Error(android::DisplayConnectionType*));
MOCK_CONST_METHOD0(isVsyncPeriodSwitchSupported, bool());
};