1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker * Copyright (C) 2010 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker *
4*38e8c45fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker *
8*38e8c45fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker *
10*38e8c45fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker */
16*38e8c45fSAndroid Build Coastguard Worker
17*38e8c45fSAndroid Build Coastguard Worker // TODO(b/129481165): remove the #pragma below and fix conversion issues
18*38e8c45fSAndroid Build Coastguard Worker #include <chrono>
19*38e8c45fSAndroid Build Coastguard Worker #pragma clang diagnostic push
20*38e8c45fSAndroid Build Coastguard Worker #pragma clang diagnostic ignored "-Wconversion"
21*38e8c45fSAndroid Build Coastguard Worker
22*38e8c45fSAndroid Build Coastguard Worker // #define LOG_NDEBUG 0
23*38e8c45fSAndroid Build Coastguard Worker
24*38e8c45fSAndroid Build Coastguard Worker #undef LOG_TAG
25*38e8c45fSAndroid Build Coastguard Worker #define LOG_TAG "HWComposer"
26*38e8c45fSAndroid Build Coastguard Worker #define ATRACE_TAG ATRACE_TAG_GRAPHICS
27*38e8c45fSAndroid Build Coastguard Worker
28*38e8c45fSAndroid Build Coastguard Worker #include "HWComposer.h"
29*38e8c45fSAndroid Build Coastguard Worker
30*38e8c45fSAndroid Build Coastguard Worker #include <aidl/android/hardware/graphics/composer3/IComposerClient.h>
31*38e8c45fSAndroid Build Coastguard Worker #include <android-base/properties.h>
32*38e8c45fSAndroid Build Coastguard Worker #include <common/trace.h>
33*38e8c45fSAndroid Build Coastguard Worker #include <compositionengine/Output.h>
34*38e8c45fSAndroid Build Coastguard Worker #include <compositionengine/OutputLayer.h>
35*38e8c45fSAndroid Build Coastguard Worker #include <compositionengine/impl/OutputLayerCompositionState.h>
36*38e8c45fSAndroid Build Coastguard Worker #include <ftl/concat.h>
37*38e8c45fSAndroid Build Coastguard Worker #include <log/log.h>
38*38e8c45fSAndroid Build Coastguard Worker #include <ui/DebugUtils.h>
39*38e8c45fSAndroid Build Coastguard Worker #include <ui/GraphicBuffer.h>
40*38e8c45fSAndroid Build Coastguard Worker #include <utils/Errors.h>
41*38e8c45fSAndroid Build Coastguard Worker
42*38e8c45fSAndroid Build Coastguard Worker #include "../Layer.h" // needed only for debugging
43*38e8c45fSAndroid Build Coastguard Worker #include "../SurfaceFlingerProperties.h"
44*38e8c45fSAndroid Build Coastguard Worker #include "ComposerHal.h"
45*38e8c45fSAndroid Build Coastguard Worker #include "HWC2.h"
46*38e8c45fSAndroid Build Coastguard Worker
47*38e8c45fSAndroid Build Coastguard Worker #define LOG_HWC_DISPLAY_ERROR(hwcDisplayId, msg) \
48*38e8c45fSAndroid Build Coastguard Worker ALOGE("%s failed for HWC display %" PRIu64 ": %s", __FUNCTION__, hwcDisplayId, msg)
49*38e8c45fSAndroid Build Coastguard Worker
50*38e8c45fSAndroid Build Coastguard Worker #define LOG_DISPLAY_ERROR(displayId, msg) \
51*38e8c45fSAndroid Build Coastguard Worker ALOGE("%s failed for display %s: %s", __FUNCTION__, to_string(displayId).c_str(), msg)
52*38e8c45fSAndroid Build Coastguard Worker
53*38e8c45fSAndroid Build Coastguard Worker #define LOG_HWC_ERROR(what, error, displayId) \
54*38e8c45fSAndroid Build Coastguard Worker ALOGE("%s: %s failed for display %s: %s (%d)", __FUNCTION__, what, \
55*38e8c45fSAndroid Build Coastguard Worker to_string(displayId).c_str(), to_string(error).c_str(), static_cast<int32_t>(error))
56*38e8c45fSAndroid Build Coastguard Worker
57*38e8c45fSAndroid Build Coastguard Worker #define RETURN_IF_INVALID_DISPLAY(displayId, ...) \
58*38e8c45fSAndroid Build Coastguard Worker do { \
59*38e8c45fSAndroid Build Coastguard Worker if (mDisplayData.count(displayId) == 0) { \
60*38e8c45fSAndroid Build Coastguard Worker LOG_DISPLAY_ERROR(displayId, "Invalid display"); \
61*38e8c45fSAndroid Build Coastguard Worker return __VA_ARGS__; \
62*38e8c45fSAndroid Build Coastguard Worker } \
63*38e8c45fSAndroid Build Coastguard Worker } while (false)
64*38e8c45fSAndroid Build Coastguard Worker
65*38e8c45fSAndroid Build Coastguard Worker #define RETURN_IF_HWC_ERROR_FOR(what, error, displayId, ...) \
66*38e8c45fSAndroid Build Coastguard Worker do { \
67*38e8c45fSAndroid Build Coastguard Worker if (error != hal::Error::NONE) { \
68*38e8c45fSAndroid Build Coastguard Worker LOG_HWC_ERROR(what, error, displayId); \
69*38e8c45fSAndroid Build Coastguard Worker return __VA_ARGS__; \
70*38e8c45fSAndroid Build Coastguard Worker } \
71*38e8c45fSAndroid Build Coastguard Worker } while (false)
72*38e8c45fSAndroid Build Coastguard Worker
73*38e8c45fSAndroid Build Coastguard Worker #define RETURN_IF_HWC_ERROR(error, displayId, ...) \
74*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR_FOR(__FUNCTION__, error, displayId, __VA_ARGS__)
75*38e8c45fSAndroid Build Coastguard Worker
76*38e8c45fSAndroid Build Coastguard Worker using aidl::android::hardware::graphics::common::HdrConversionCapability;
77*38e8c45fSAndroid Build Coastguard Worker using aidl::android::hardware::graphics::common::HdrConversionStrategy;
78*38e8c45fSAndroid Build Coastguard Worker using aidl::android::hardware::graphics::composer3::Capability;
79*38e8c45fSAndroid Build Coastguard Worker using aidl::android::hardware::graphics::composer3::DisplayCapability;
80*38e8c45fSAndroid Build Coastguard Worker using aidl::android::hardware::graphics::composer3::DisplayConfiguration;
81*38e8c45fSAndroid Build Coastguard Worker using namespace std::string_literals;
82*38e8c45fSAndroid Build Coastguard Worker
83*38e8c45fSAndroid Build Coastguard Worker namespace android {
84*38e8c45fSAndroid Build Coastguard Worker
85*38e8c45fSAndroid Build Coastguard Worker HWComposer::~HWComposer() = default;
86*38e8c45fSAndroid Build Coastguard Worker
87*38e8c45fSAndroid Build Coastguard Worker namespace impl {
88*38e8c45fSAndroid Build Coastguard Worker
HWComposer(std::unique_ptr<Hwc2::Composer> composer)89*38e8c45fSAndroid Build Coastguard Worker HWComposer::HWComposer(std::unique_ptr<Hwc2::Composer> composer)
90*38e8c45fSAndroid Build Coastguard Worker : mComposer(std::move(composer)),
91*38e8c45fSAndroid Build Coastguard Worker mMaxVirtualDisplayDimension(static_cast<size_t>(sysprop::max_virtual_display_dimension(0))),
92*38e8c45fSAndroid Build Coastguard Worker mUpdateDeviceProductInfoOnHotplugReconnect(
93*38e8c45fSAndroid Build Coastguard Worker sysprop::update_device_product_info_on_hotplug_reconnect(false)),
94*38e8c45fSAndroid Build Coastguard Worker mEnableVrrTimeout(base::GetBoolProperty("debug.sf.vrr_timeout_hint_enabled"s, true)) {}
95*38e8c45fSAndroid Build Coastguard Worker
HWComposer(const std::string & composerServiceName)96*38e8c45fSAndroid Build Coastguard Worker HWComposer::HWComposer(const std::string& composerServiceName)
97*38e8c45fSAndroid Build Coastguard Worker : HWComposer(Hwc2::Composer::create(composerServiceName)) {}
98*38e8c45fSAndroid Build Coastguard Worker
~HWComposer()99*38e8c45fSAndroid Build Coastguard Worker HWComposer::~HWComposer() {
100*38e8c45fSAndroid Build Coastguard Worker mDisplayData.clear();
101*38e8c45fSAndroid Build Coastguard Worker }
102*38e8c45fSAndroid Build Coastguard Worker
setCallback(HWC2::ComposerCallback & callback)103*38e8c45fSAndroid Build Coastguard Worker void HWComposer::setCallback(HWC2::ComposerCallback& callback) {
104*38e8c45fSAndroid Build Coastguard Worker loadCapabilities();
105*38e8c45fSAndroid Build Coastguard Worker loadLayerMetadataSupport();
106*38e8c45fSAndroid Build Coastguard Worker loadOverlayProperties();
107*38e8c45fSAndroid Build Coastguard Worker loadHdrConversionCapabilities();
108*38e8c45fSAndroid Build Coastguard Worker
109*38e8c45fSAndroid Build Coastguard Worker if (mRegisteredCallback) {
110*38e8c45fSAndroid Build Coastguard Worker ALOGW("Callback already registered. Ignored extra registration attempt.");
111*38e8c45fSAndroid Build Coastguard Worker return;
112*38e8c45fSAndroid Build Coastguard Worker }
113*38e8c45fSAndroid Build Coastguard Worker mRegisteredCallback = true;
114*38e8c45fSAndroid Build Coastguard Worker
115*38e8c45fSAndroid Build Coastguard Worker mComposer->registerCallback(callback);
116*38e8c45fSAndroid Build Coastguard Worker }
117*38e8c45fSAndroid Build Coastguard Worker
getDisplayIdentificationData(hal::HWDisplayId hwcDisplayId,uint8_t * outPort,DisplayIdentificationData * outData) const118*38e8c45fSAndroid Build Coastguard Worker bool HWComposer::getDisplayIdentificationData(hal::HWDisplayId hwcDisplayId, uint8_t* outPort,
119*38e8c45fSAndroid Build Coastguard Worker DisplayIdentificationData* outData) const {
120*38e8c45fSAndroid Build Coastguard Worker const auto error = static_cast<hal::Error>(
121*38e8c45fSAndroid Build Coastguard Worker mComposer->getDisplayIdentificationData(hwcDisplayId, outPort, outData));
122*38e8c45fSAndroid Build Coastguard Worker if (error != hal::Error::NONE) {
123*38e8c45fSAndroid Build Coastguard Worker if (error != hal::Error::UNSUPPORTED) {
124*38e8c45fSAndroid Build Coastguard Worker LOG_HWC_DISPLAY_ERROR(hwcDisplayId, to_string(error).c_str());
125*38e8c45fSAndroid Build Coastguard Worker }
126*38e8c45fSAndroid Build Coastguard Worker return false;
127*38e8c45fSAndroid Build Coastguard Worker }
128*38e8c45fSAndroid Build Coastguard Worker return true;
129*38e8c45fSAndroid Build Coastguard Worker }
130*38e8c45fSAndroid Build Coastguard Worker
hasCapability(Capability capability) const131*38e8c45fSAndroid Build Coastguard Worker bool HWComposer::hasCapability(Capability capability) const {
132*38e8c45fSAndroid Build Coastguard Worker return mCapabilities.count(capability) > 0;
133*38e8c45fSAndroid Build Coastguard Worker }
134*38e8c45fSAndroid Build Coastguard Worker
hasDisplayCapability(HalDisplayId displayId,DisplayCapability capability) const135*38e8c45fSAndroid Build Coastguard Worker bool HWComposer::hasDisplayCapability(HalDisplayId displayId, DisplayCapability capability) const {
136*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, false);
137*38e8c45fSAndroid Build Coastguard Worker return mDisplayData.at(displayId).hwcDisplay->hasCapability(capability);
138*38e8c45fSAndroid Build Coastguard Worker }
139*38e8c45fSAndroid Build Coastguard Worker
onHotplug(hal::HWDisplayId hwcDisplayId,hal::Connection connection)140*38e8c45fSAndroid Build Coastguard Worker std::optional<DisplayIdentificationInfo> HWComposer::onHotplug(hal::HWDisplayId hwcDisplayId,
141*38e8c45fSAndroid Build Coastguard Worker hal::Connection connection) {
142*38e8c45fSAndroid Build Coastguard Worker switch (connection) {
143*38e8c45fSAndroid Build Coastguard Worker case hal::Connection::CONNECTED:
144*38e8c45fSAndroid Build Coastguard Worker return onHotplugConnect(hwcDisplayId);
145*38e8c45fSAndroid Build Coastguard Worker case hal::Connection::DISCONNECTED:
146*38e8c45fSAndroid Build Coastguard Worker return onHotplugDisconnect(hwcDisplayId);
147*38e8c45fSAndroid Build Coastguard Worker case hal::Connection::INVALID:
148*38e8c45fSAndroid Build Coastguard Worker return {};
149*38e8c45fSAndroid Build Coastguard Worker }
150*38e8c45fSAndroid Build Coastguard Worker }
151*38e8c45fSAndroid Build Coastguard Worker
updatesDeviceProductInfoOnHotplugReconnect() const152*38e8c45fSAndroid Build Coastguard Worker bool HWComposer::updatesDeviceProductInfoOnHotplugReconnect() const {
153*38e8c45fSAndroid Build Coastguard Worker return mUpdateDeviceProductInfoOnHotplugReconnect;
154*38e8c45fSAndroid Build Coastguard Worker }
155*38e8c45fSAndroid Build Coastguard Worker
onVsync(hal::HWDisplayId hwcDisplayId,nsecs_t timestamp)156*38e8c45fSAndroid Build Coastguard Worker std::optional<PhysicalDisplayId> HWComposer::onVsync(hal::HWDisplayId hwcDisplayId,
157*38e8c45fSAndroid Build Coastguard Worker nsecs_t timestamp) {
158*38e8c45fSAndroid Build Coastguard Worker const auto displayIdOpt = toPhysicalDisplayId(hwcDisplayId);
159*38e8c45fSAndroid Build Coastguard Worker if (!displayIdOpt) {
160*38e8c45fSAndroid Build Coastguard Worker LOG_HWC_DISPLAY_ERROR(hwcDisplayId, "Invalid HWC display");
161*38e8c45fSAndroid Build Coastguard Worker return {};
162*38e8c45fSAndroid Build Coastguard Worker }
163*38e8c45fSAndroid Build Coastguard Worker
164*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(*displayIdOpt, {});
165*38e8c45fSAndroid Build Coastguard Worker
166*38e8c45fSAndroid Build Coastguard Worker auto& displayData = mDisplayData[*displayIdOpt];
167*38e8c45fSAndroid Build Coastguard Worker
168*38e8c45fSAndroid Build Coastguard Worker {
169*38e8c45fSAndroid Build Coastguard Worker // There have been reports of HWCs that signal several vsync events
170*38e8c45fSAndroid Build Coastguard Worker // with the same timestamp when turning the display off and on. This
171*38e8c45fSAndroid Build Coastguard Worker // is a bug in the HWC implementation, but filter the extra events
172*38e8c45fSAndroid Build Coastguard Worker // out here so they don't cause havoc downstream.
173*38e8c45fSAndroid Build Coastguard Worker if (timestamp == displayData.lastPresentTimestamp) {
174*38e8c45fSAndroid Build Coastguard Worker ALOGW("Ignoring duplicate VSYNC event from HWC for display %s (t=%" PRId64 ")",
175*38e8c45fSAndroid Build Coastguard Worker to_string(*displayIdOpt).c_str(), timestamp);
176*38e8c45fSAndroid Build Coastguard Worker return {};
177*38e8c45fSAndroid Build Coastguard Worker }
178*38e8c45fSAndroid Build Coastguard Worker
179*38e8c45fSAndroid Build Coastguard Worker displayData.lastPresentTimestamp = timestamp;
180*38e8c45fSAndroid Build Coastguard Worker }
181*38e8c45fSAndroid Build Coastguard Worker
182*38e8c45fSAndroid Build Coastguard Worker SFTRACE_INT(ftl::Concat("HW_VSYNC_", displayIdOpt->value).c_str(),
183*38e8c45fSAndroid Build Coastguard Worker displayData.vsyncTraceToggle);
184*38e8c45fSAndroid Build Coastguard Worker displayData.vsyncTraceToggle = !displayData.vsyncTraceToggle;
185*38e8c45fSAndroid Build Coastguard Worker
186*38e8c45fSAndroid Build Coastguard Worker return displayIdOpt;
187*38e8c45fSAndroid Build Coastguard Worker }
188*38e8c45fSAndroid Build Coastguard Worker
getMaxVirtualDisplayCount() const189*38e8c45fSAndroid Build Coastguard Worker size_t HWComposer::getMaxVirtualDisplayCount() const {
190*38e8c45fSAndroid Build Coastguard Worker return mComposer->getMaxVirtualDisplayCount();
191*38e8c45fSAndroid Build Coastguard Worker }
192*38e8c45fSAndroid Build Coastguard Worker
getMaxVirtualDisplayDimension() const193*38e8c45fSAndroid Build Coastguard Worker size_t HWComposer::getMaxVirtualDisplayDimension() const {
194*38e8c45fSAndroid Build Coastguard Worker return mMaxVirtualDisplayDimension;
195*38e8c45fSAndroid Build Coastguard Worker }
196*38e8c45fSAndroid Build Coastguard Worker
allocateVirtualDisplay(HalVirtualDisplayId displayId,ui::Size resolution,ui::PixelFormat * format)197*38e8c45fSAndroid Build Coastguard Worker bool HWComposer::allocateVirtualDisplay(HalVirtualDisplayId displayId, ui::Size resolution,
198*38e8c45fSAndroid Build Coastguard Worker ui::PixelFormat* format) {
199*38e8c45fSAndroid Build Coastguard Worker if (!resolution.isValid()) {
200*38e8c45fSAndroid Build Coastguard Worker ALOGE("%s: Invalid resolution %dx%d", __func__, resolution.width, resolution.height);
201*38e8c45fSAndroid Build Coastguard Worker return false;
202*38e8c45fSAndroid Build Coastguard Worker }
203*38e8c45fSAndroid Build Coastguard Worker
204*38e8c45fSAndroid Build Coastguard Worker const uint32_t width = static_cast<uint32_t>(resolution.width);
205*38e8c45fSAndroid Build Coastguard Worker const uint32_t height = static_cast<uint32_t>(resolution.height);
206*38e8c45fSAndroid Build Coastguard Worker
207*38e8c45fSAndroid Build Coastguard Worker if (mMaxVirtualDisplayDimension > 0 &&
208*38e8c45fSAndroid Build Coastguard Worker (width > mMaxVirtualDisplayDimension || height > mMaxVirtualDisplayDimension)) {
209*38e8c45fSAndroid Build Coastguard Worker ALOGE("%s: Resolution %ux%u exceeds maximum dimension %zu", __func__, width, height,
210*38e8c45fSAndroid Build Coastguard Worker mMaxVirtualDisplayDimension);
211*38e8c45fSAndroid Build Coastguard Worker return false;
212*38e8c45fSAndroid Build Coastguard Worker }
213*38e8c45fSAndroid Build Coastguard Worker
214*38e8c45fSAndroid Build Coastguard Worker hal::HWDisplayId hwcDisplayId;
215*38e8c45fSAndroid Build Coastguard Worker const auto error = static_cast<hal::Error>(
216*38e8c45fSAndroid Build Coastguard Worker mComposer->createVirtualDisplay(width, height, format, &hwcDisplayId));
217*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR_FOR("createVirtualDisplay", error, displayId, false);
218*38e8c45fSAndroid Build Coastguard Worker
219*38e8c45fSAndroid Build Coastguard Worker auto display = std::make_unique<HWC2::impl::Display>(*mComposer.get(), mCapabilities,
220*38e8c45fSAndroid Build Coastguard Worker hwcDisplayId, hal::DisplayType::VIRTUAL);
221*38e8c45fSAndroid Build Coastguard Worker display->setConnected(true);
222*38e8c45fSAndroid Build Coastguard Worker auto& displayData = mDisplayData[displayId];
223*38e8c45fSAndroid Build Coastguard Worker displayData.hwcDisplay = std::move(display);
224*38e8c45fSAndroid Build Coastguard Worker return true;
225*38e8c45fSAndroid Build Coastguard Worker }
226*38e8c45fSAndroid Build Coastguard Worker
allocatePhysicalDisplay(hal::HWDisplayId hwcDisplayId,PhysicalDisplayId displayId,std::optional<ui::Size> physicalSize)227*38e8c45fSAndroid Build Coastguard Worker void HWComposer::allocatePhysicalDisplay(hal::HWDisplayId hwcDisplayId, PhysicalDisplayId displayId,
228*38e8c45fSAndroid Build Coastguard Worker std::optional<ui::Size> physicalSize) {
229*38e8c45fSAndroid Build Coastguard Worker mPhysicalDisplayIdMap[hwcDisplayId] = displayId;
230*38e8c45fSAndroid Build Coastguard Worker
231*38e8c45fSAndroid Build Coastguard Worker if (!mPrimaryHwcDisplayId) {
232*38e8c45fSAndroid Build Coastguard Worker mPrimaryHwcDisplayId = hwcDisplayId;
233*38e8c45fSAndroid Build Coastguard Worker }
234*38e8c45fSAndroid Build Coastguard Worker
235*38e8c45fSAndroid Build Coastguard Worker auto& displayData = mDisplayData[displayId];
236*38e8c45fSAndroid Build Coastguard Worker auto newDisplay =
237*38e8c45fSAndroid Build Coastguard Worker std::make_unique<HWC2::impl::Display>(*mComposer.get(), mCapabilities, hwcDisplayId,
238*38e8c45fSAndroid Build Coastguard Worker hal::DisplayType::PHYSICAL);
239*38e8c45fSAndroid Build Coastguard Worker newDisplay->setConnected(true);
240*38e8c45fSAndroid Build Coastguard Worker newDisplay->setPhysicalSizeInMm(physicalSize);
241*38e8c45fSAndroid Build Coastguard Worker displayData.hwcDisplay = std::move(newDisplay);
242*38e8c45fSAndroid Build Coastguard Worker }
243*38e8c45fSAndroid Build Coastguard Worker
getAttribute(hal::HWDisplayId hwcDisplayId,hal::HWConfigId configId,hal::Attribute attribute) const244*38e8c45fSAndroid Build Coastguard Worker int32_t HWComposer::getAttribute(hal::HWDisplayId hwcDisplayId, hal::HWConfigId configId,
245*38e8c45fSAndroid Build Coastguard Worker hal::Attribute attribute) const {
246*38e8c45fSAndroid Build Coastguard Worker int32_t value = 0;
247*38e8c45fSAndroid Build Coastguard Worker auto error = static_cast<hal::Error>(
248*38e8c45fSAndroid Build Coastguard Worker mComposer->getDisplayAttribute(hwcDisplayId, configId, attribute, &value));
249*38e8c45fSAndroid Build Coastguard Worker
250*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR_FOR("getDisplayAttribute", error, *toPhysicalDisplayId(hwcDisplayId), -1);
251*38e8c45fSAndroid Build Coastguard Worker return value;
252*38e8c45fSAndroid Build Coastguard Worker }
253*38e8c45fSAndroid Build Coastguard Worker
createLayer(HalDisplayId displayId)254*38e8c45fSAndroid Build Coastguard Worker std::shared_ptr<HWC2::Layer> HWComposer::createLayer(HalDisplayId displayId) {
255*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, nullptr);
256*38e8c45fSAndroid Build Coastguard Worker
257*38e8c45fSAndroid Build Coastguard Worker auto expected = mDisplayData[displayId].hwcDisplay->createLayer();
258*38e8c45fSAndroid Build Coastguard Worker if (!expected.has_value()) {
259*38e8c45fSAndroid Build Coastguard Worker auto error = std::move(expected).error();
260*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR(error, displayId, nullptr);
261*38e8c45fSAndroid Build Coastguard Worker }
262*38e8c45fSAndroid Build Coastguard Worker return std::move(expected).value();
263*38e8c45fSAndroid Build Coastguard Worker }
264*38e8c45fSAndroid Build Coastguard Worker
isConnected(PhysicalDisplayId displayId) const265*38e8c45fSAndroid Build Coastguard Worker bool HWComposer::isConnected(PhysicalDisplayId displayId) const {
266*38e8c45fSAndroid Build Coastguard Worker return mDisplayData.count(displayId) && mDisplayData.at(displayId).hwcDisplay->isConnected();
267*38e8c45fSAndroid Build Coastguard Worker }
268*38e8c45fSAndroid Build Coastguard Worker
getModes(PhysicalDisplayId displayId,int32_t maxFrameIntervalNs) const269*38e8c45fSAndroid Build Coastguard Worker std::vector<HWComposer::HWCDisplayMode> HWComposer::getModes(PhysicalDisplayId displayId,
270*38e8c45fSAndroid Build Coastguard Worker int32_t maxFrameIntervalNs) const {
271*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, {});
272*38e8c45fSAndroid Build Coastguard Worker
273*38e8c45fSAndroid Build Coastguard Worker const auto hwcDisplayId = mDisplayData.at(displayId).hwcDisplay->getId();
274*38e8c45fSAndroid Build Coastguard Worker
275*38e8c45fSAndroid Build Coastguard Worker if (mComposer->isVrrSupported()) {
276*38e8c45fSAndroid Build Coastguard Worker return getModesFromDisplayConfigurations(hwcDisplayId, maxFrameIntervalNs);
277*38e8c45fSAndroid Build Coastguard Worker }
278*38e8c45fSAndroid Build Coastguard Worker
279*38e8c45fSAndroid Build Coastguard Worker return getModesFromLegacyDisplayConfigs(hwcDisplayId);
280*38e8c45fSAndroid Build Coastguard Worker }
281*38e8c45fSAndroid Build Coastguard Worker
getEstimatedDotsPerInchFromSize(uint64_t hwcDisplayId,const HWCDisplayMode & hwcMode) const282*38e8c45fSAndroid Build Coastguard Worker DisplayConfiguration::Dpi HWComposer::getEstimatedDotsPerInchFromSize(
283*38e8c45fSAndroid Build Coastguard Worker uint64_t hwcDisplayId, const HWCDisplayMode& hwcMode) const {
284*38e8c45fSAndroid Build Coastguard Worker if (!FlagManager::getInstance().correct_dpi_with_display_size()) {
285*38e8c45fSAndroid Build Coastguard Worker return {-1, -1};
286*38e8c45fSAndroid Build Coastguard Worker }
287*38e8c45fSAndroid Build Coastguard Worker if (const auto displayId = toPhysicalDisplayId(hwcDisplayId)) {
288*38e8c45fSAndroid Build Coastguard Worker if (const auto it = mDisplayData.find(displayId.value());
289*38e8c45fSAndroid Build Coastguard Worker it != mDisplayData.end() && it->second.hwcDisplay->getPhysicalSizeInMm()) {
290*38e8c45fSAndroid Build Coastguard Worker ui::Size size = it->second.hwcDisplay->getPhysicalSizeInMm().value();
291*38e8c45fSAndroid Build Coastguard Worker if (hwcMode.width > 0 && hwcMode.height > 0 && size.width > 0 && size.height > 0) {
292*38e8c45fSAndroid Build Coastguard Worker static constexpr float kMmPerInch = 25.4f;
293*38e8c45fSAndroid Build Coastguard Worker return {hwcMode.width * kMmPerInch / size.width,
294*38e8c45fSAndroid Build Coastguard Worker hwcMode.height * kMmPerInch / size.height};
295*38e8c45fSAndroid Build Coastguard Worker }
296*38e8c45fSAndroid Build Coastguard Worker }
297*38e8c45fSAndroid Build Coastguard Worker }
298*38e8c45fSAndroid Build Coastguard Worker return {-1, -1};
299*38e8c45fSAndroid Build Coastguard Worker }
300*38e8c45fSAndroid Build Coastguard Worker
correctedDpiIfneeded(DisplayConfiguration::Dpi dpi,DisplayConfiguration::Dpi estimatedDpi) const301*38e8c45fSAndroid Build Coastguard Worker DisplayConfiguration::Dpi HWComposer::correctedDpiIfneeded(
302*38e8c45fSAndroid Build Coastguard Worker DisplayConfiguration::Dpi dpi, DisplayConfiguration::Dpi estimatedDpi) const {
303*38e8c45fSAndroid Build Coastguard Worker // hwc can be unreliable when it comes to dpi. A rough estimated dpi may yield better
304*38e8c45fSAndroid Build Coastguard Worker // results. For instance, libdrm and bad edid may result in a dpi of {350, 290} for a
305*38e8c45fSAndroid Build Coastguard Worker // 16:9 3840x2160 display, which would match a 4:3 aspect ratio.
306*38e8c45fSAndroid Build Coastguard Worker // The logic here checks if hwc was able to provide some dpi, and if so if the dpi
307*38e8c45fSAndroid Build Coastguard Worker // disparity between the axes is more reasonable than a rough estimate, otherwise use
308*38e8c45fSAndroid Build Coastguard Worker // the estimated dpi as a corrected value.
309*38e8c45fSAndroid Build Coastguard Worker if (estimatedDpi.x == -1 || estimatedDpi.y == -1) {
310*38e8c45fSAndroid Build Coastguard Worker return dpi;
311*38e8c45fSAndroid Build Coastguard Worker }
312*38e8c45fSAndroid Build Coastguard Worker if (dpi.x == -1 || dpi.y == -1) {
313*38e8c45fSAndroid Build Coastguard Worker return estimatedDpi;
314*38e8c45fSAndroid Build Coastguard Worker }
315*38e8c45fSAndroid Build Coastguard Worker if (std::min(dpi.x, dpi.y) != 0 && std::min(estimatedDpi.x, estimatedDpi.y) != 0 &&
316*38e8c45fSAndroid Build Coastguard Worker abs(dpi.x - dpi.y) / std::min(dpi.x, dpi.y) >
317*38e8c45fSAndroid Build Coastguard Worker abs(estimatedDpi.x - estimatedDpi.y) / std::min(estimatedDpi.x, estimatedDpi.y)) {
318*38e8c45fSAndroid Build Coastguard Worker return estimatedDpi;
319*38e8c45fSAndroid Build Coastguard Worker }
320*38e8c45fSAndroid Build Coastguard Worker return dpi;
321*38e8c45fSAndroid Build Coastguard Worker }
322*38e8c45fSAndroid Build Coastguard Worker
getModesFromDisplayConfigurations(uint64_t hwcDisplayId,int32_t maxFrameIntervalNs) const323*38e8c45fSAndroid Build Coastguard Worker std::vector<HWComposer::HWCDisplayMode> HWComposer::getModesFromDisplayConfigurations(
324*38e8c45fSAndroid Build Coastguard Worker uint64_t hwcDisplayId, int32_t maxFrameIntervalNs) const {
325*38e8c45fSAndroid Build Coastguard Worker std::vector<hal::DisplayConfiguration> configs;
326*38e8c45fSAndroid Build Coastguard Worker auto error = static_cast<hal::Error>(
327*38e8c45fSAndroid Build Coastguard Worker mComposer->getDisplayConfigurations(hwcDisplayId, maxFrameIntervalNs, &configs));
328*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR_FOR("getDisplayConfigurations", error, *toPhysicalDisplayId(hwcDisplayId),
329*38e8c45fSAndroid Build Coastguard Worker {});
330*38e8c45fSAndroid Build Coastguard Worker
331*38e8c45fSAndroid Build Coastguard Worker std::vector<HWCDisplayMode> modes;
332*38e8c45fSAndroid Build Coastguard Worker modes.reserve(configs.size());
333*38e8c45fSAndroid Build Coastguard Worker for (auto config : configs) {
334*38e8c45fSAndroid Build Coastguard Worker auto hwcMode = HWCDisplayMode{.hwcId = static_cast<hal::HWConfigId>(config.configId),
335*38e8c45fSAndroid Build Coastguard Worker .width = config.width,
336*38e8c45fSAndroid Build Coastguard Worker .height = config.height,
337*38e8c45fSAndroid Build Coastguard Worker .vsyncPeriod = config.vsyncPeriod,
338*38e8c45fSAndroid Build Coastguard Worker .configGroup = config.configGroup,
339*38e8c45fSAndroid Build Coastguard Worker .vrrConfig = config.vrrConfig,
340*38e8c45fSAndroid Build Coastguard Worker .hdrOutputType = config.hdrOutputType};
341*38e8c45fSAndroid Build Coastguard Worker
342*38e8c45fSAndroid Build Coastguard Worker const DisplayConfiguration::Dpi estimatedDPI =
343*38e8c45fSAndroid Build Coastguard Worker getEstimatedDotsPerInchFromSize(hwcDisplayId, hwcMode);
344*38e8c45fSAndroid Build Coastguard Worker if (config.dpi) {
345*38e8c45fSAndroid Build Coastguard Worker const DisplayConfiguration::Dpi dpi =
346*38e8c45fSAndroid Build Coastguard Worker correctedDpiIfneeded(config.dpi.value(), estimatedDPI);
347*38e8c45fSAndroid Build Coastguard Worker hwcMode.dpiX = dpi.x;
348*38e8c45fSAndroid Build Coastguard Worker hwcMode.dpiY = dpi.y;
349*38e8c45fSAndroid Build Coastguard Worker } else if (estimatedDPI.x != -1 && estimatedDPI.y != -1) {
350*38e8c45fSAndroid Build Coastguard Worker hwcMode.dpiX = estimatedDPI.x;
351*38e8c45fSAndroid Build Coastguard Worker hwcMode.dpiY = estimatedDPI.y;
352*38e8c45fSAndroid Build Coastguard Worker }
353*38e8c45fSAndroid Build Coastguard Worker
354*38e8c45fSAndroid Build Coastguard Worker if (!mEnableVrrTimeout) {
355*38e8c45fSAndroid Build Coastguard Worker hwcMode.vrrConfig->notifyExpectedPresentConfig = {};
356*38e8c45fSAndroid Build Coastguard Worker }
357*38e8c45fSAndroid Build Coastguard Worker
358*38e8c45fSAndroid Build Coastguard Worker modes.push_back(hwcMode);
359*38e8c45fSAndroid Build Coastguard Worker }
360*38e8c45fSAndroid Build Coastguard Worker
361*38e8c45fSAndroid Build Coastguard Worker return modes;
362*38e8c45fSAndroid Build Coastguard Worker }
363*38e8c45fSAndroid Build Coastguard Worker
getModesFromLegacyDisplayConfigs(uint64_t hwcDisplayId) const364*38e8c45fSAndroid Build Coastguard Worker std::vector<HWComposer::HWCDisplayMode> HWComposer::getModesFromLegacyDisplayConfigs(
365*38e8c45fSAndroid Build Coastguard Worker uint64_t hwcDisplayId) const {
366*38e8c45fSAndroid Build Coastguard Worker std::vector<hal::HWConfigId> configIds;
367*38e8c45fSAndroid Build Coastguard Worker auto error = static_cast<hal::Error>(mComposer->getDisplayConfigs(hwcDisplayId, &configIds));
368*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR_FOR("getDisplayConfigs", error, *toPhysicalDisplayId(hwcDisplayId), {});
369*38e8c45fSAndroid Build Coastguard Worker
370*38e8c45fSAndroid Build Coastguard Worker std::vector<HWCDisplayMode> modes;
371*38e8c45fSAndroid Build Coastguard Worker modes.reserve(configIds.size());
372*38e8c45fSAndroid Build Coastguard Worker for (auto configId : configIds) {
373*38e8c45fSAndroid Build Coastguard Worker auto hwcMode = HWCDisplayMode{
374*38e8c45fSAndroid Build Coastguard Worker .hwcId = configId,
375*38e8c45fSAndroid Build Coastguard Worker .width = getAttribute(hwcDisplayId, configId, hal::Attribute::WIDTH),
376*38e8c45fSAndroid Build Coastguard Worker .height = getAttribute(hwcDisplayId, configId, hal::Attribute::HEIGHT),
377*38e8c45fSAndroid Build Coastguard Worker .vsyncPeriod = getAttribute(hwcDisplayId, configId, hal::Attribute::VSYNC_PERIOD),
378*38e8c45fSAndroid Build Coastguard Worker .configGroup = getAttribute(hwcDisplayId, configId, hal::Attribute::CONFIG_GROUP),
379*38e8c45fSAndroid Build Coastguard Worker };
380*38e8c45fSAndroid Build Coastguard Worker
381*38e8c45fSAndroid Build Coastguard Worker const int32_t dpiX = getAttribute(hwcDisplayId, configId, hal::Attribute::DPI_X);
382*38e8c45fSAndroid Build Coastguard Worker const int32_t dpiY = getAttribute(hwcDisplayId, configId, hal::Attribute::DPI_Y);
383*38e8c45fSAndroid Build Coastguard Worker const DisplayConfiguration::Dpi hwcDpi =
384*38e8c45fSAndroid Build Coastguard Worker DisplayConfiguration::Dpi{dpiX == -1 ? dpiX : dpiX / 1000.f,
385*38e8c45fSAndroid Build Coastguard Worker dpiY == -1 ? dpiY : dpiY / 1000.f};
386*38e8c45fSAndroid Build Coastguard Worker const DisplayConfiguration::Dpi estimatedDPI =
387*38e8c45fSAndroid Build Coastguard Worker getEstimatedDotsPerInchFromSize(hwcDisplayId, hwcMode);
388*38e8c45fSAndroid Build Coastguard Worker const DisplayConfiguration::Dpi dpi = correctedDpiIfneeded(hwcDpi, estimatedDPI);
389*38e8c45fSAndroid Build Coastguard Worker hwcMode.dpiX = dpi.x;
390*38e8c45fSAndroid Build Coastguard Worker hwcMode.dpiY = dpi.y;
391*38e8c45fSAndroid Build Coastguard Worker
392*38e8c45fSAndroid Build Coastguard Worker modes.push_back(hwcMode);
393*38e8c45fSAndroid Build Coastguard Worker }
394*38e8c45fSAndroid Build Coastguard Worker return modes;
395*38e8c45fSAndroid Build Coastguard Worker }
396*38e8c45fSAndroid Build Coastguard Worker
getActiveMode(PhysicalDisplayId displayId) const397*38e8c45fSAndroid Build Coastguard Worker ftl::Expected<hal::HWConfigId, status_t> HWComposer::getActiveMode(
398*38e8c45fSAndroid Build Coastguard Worker PhysicalDisplayId displayId) const {
399*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, ftl::Unexpected(BAD_INDEX));
400*38e8c45fSAndroid Build Coastguard Worker const auto hwcId = *fromPhysicalDisplayId(displayId);
401*38e8c45fSAndroid Build Coastguard Worker
402*38e8c45fSAndroid Build Coastguard Worker hal::HWConfigId configId;
403*38e8c45fSAndroid Build Coastguard Worker const auto error = static_cast<hal::Error>(mComposer->getActiveConfig(hwcId, &configId));
404*38e8c45fSAndroid Build Coastguard Worker if (error == hal::Error::BAD_CONFIG) {
405*38e8c45fSAndroid Build Coastguard Worker return ftl::Unexpected(NO_INIT);
406*38e8c45fSAndroid Build Coastguard Worker }
407*38e8c45fSAndroid Build Coastguard Worker
408*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR_FOR("getActiveConfig", error, displayId, ftl::Unexpected(UNKNOWN_ERROR));
409*38e8c45fSAndroid Build Coastguard Worker return configId;
410*38e8c45fSAndroid Build Coastguard Worker }
411*38e8c45fSAndroid Build Coastguard Worker
412*38e8c45fSAndroid Build Coastguard Worker // Composer 2.4
413*38e8c45fSAndroid Build Coastguard Worker
getDisplayConnectionType(PhysicalDisplayId displayId) const414*38e8c45fSAndroid Build Coastguard Worker ui::DisplayConnectionType HWComposer::getDisplayConnectionType(PhysicalDisplayId displayId) const {
415*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, ui::DisplayConnectionType::Internal);
416*38e8c45fSAndroid Build Coastguard Worker const auto& hwcDisplay = mDisplayData.at(displayId).hwcDisplay;
417*38e8c45fSAndroid Build Coastguard Worker
418*38e8c45fSAndroid Build Coastguard Worker if (const auto connectionType = hwcDisplay->getConnectionType()) {
419*38e8c45fSAndroid Build Coastguard Worker return connectionType.value();
420*38e8c45fSAndroid Build Coastguard Worker } else {
421*38e8c45fSAndroid Build Coastguard Worker LOG_HWC_ERROR(__func__, connectionType.error(), displayId);
422*38e8c45fSAndroid Build Coastguard Worker return hwcDisplay->getId() == mPrimaryHwcDisplayId ? ui::DisplayConnectionType::Internal
423*38e8c45fSAndroid Build Coastguard Worker : ui::DisplayConnectionType::External;
424*38e8c45fSAndroid Build Coastguard Worker }
425*38e8c45fSAndroid Build Coastguard Worker }
426*38e8c45fSAndroid Build Coastguard Worker
isVsyncPeriodSwitchSupported(PhysicalDisplayId displayId) const427*38e8c45fSAndroid Build Coastguard Worker bool HWComposer::isVsyncPeriodSwitchSupported(PhysicalDisplayId displayId) const {
428*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, false);
429*38e8c45fSAndroid Build Coastguard Worker return mDisplayData.at(displayId).hwcDisplay->isVsyncPeriodSwitchSupported();
430*38e8c45fSAndroid Build Coastguard Worker }
431*38e8c45fSAndroid Build Coastguard Worker
getDisplayVsyncPeriod(PhysicalDisplayId displayId) const432*38e8c45fSAndroid Build Coastguard Worker ftl::Expected<nsecs_t, status_t> HWComposer::getDisplayVsyncPeriod(
433*38e8c45fSAndroid Build Coastguard Worker PhysicalDisplayId displayId) const {
434*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, ftl::Unexpected(BAD_INDEX));
435*38e8c45fSAndroid Build Coastguard Worker
436*38e8c45fSAndroid Build Coastguard Worker if (!isVsyncPeriodSwitchSupported(displayId)) {
437*38e8c45fSAndroid Build Coastguard Worker return ftl::Unexpected(INVALID_OPERATION);
438*38e8c45fSAndroid Build Coastguard Worker }
439*38e8c45fSAndroid Build Coastguard Worker
440*38e8c45fSAndroid Build Coastguard Worker const auto hwcId = *fromPhysicalDisplayId(displayId);
441*38e8c45fSAndroid Build Coastguard Worker Hwc2::VsyncPeriodNanos vsyncPeriodNanos = 0;
442*38e8c45fSAndroid Build Coastguard Worker const auto error =
443*38e8c45fSAndroid Build Coastguard Worker static_cast<hal::Error>(mComposer->getDisplayVsyncPeriod(hwcId, &vsyncPeriodNanos));
444*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR(error, displayId, ftl::Unexpected(UNKNOWN_ERROR));
445*38e8c45fSAndroid Build Coastguard Worker return static_cast<nsecs_t>(vsyncPeriodNanos);
446*38e8c45fSAndroid Build Coastguard Worker }
447*38e8c45fSAndroid Build Coastguard Worker
getColorModes(PhysicalDisplayId displayId) const448*38e8c45fSAndroid Build Coastguard Worker std::vector<ui::ColorMode> HWComposer::getColorModes(PhysicalDisplayId displayId) const {
449*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, {});
450*38e8c45fSAndroid Build Coastguard Worker
451*38e8c45fSAndroid Build Coastguard Worker std::vector<ui::ColorMode> modes;
452*38e8c45fSAndroid Build Coastguard Worker auto error = mDisplayData.at(displayId).hwcDisplay->getColorModes(&modes);
453*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR(error, displayId, {});
454*38e8c45fSAndroid Build Coastguard Worker return modes;
455*38e8c45fSAndroid Build Coastguard Worker }
456*38e8c45fSAndroid Build Coastguard Worker
setActiveColorMode(PhysicalDisplayId displayId,ui::ColorMode mode,ui::RenderIntent renderIntent)457*38e8c45fSAndroid Build Coastguard Worker status_t HWComposer::setActiveColorMode(PhysicalDisplayId displayId, ui::ColorMode mode,
458*38e8c45fSAndroid Build Coastguard Worker ui::RenderIntent renderIntent) {
459*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
460*38e8c45fSAndroid Build Coastguard Worker
461*38e8c45fSAndroid Build Coastguard Worker auto& displayData = mDisplayData[displayId];
462*38e8c45fSAndroid Build Coastguard Worker auto error = displayData.hwcDisplay->setColorMode(mode, renderIntent);
463*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR_FOR(("setColorMode(" + decodeColorMode(mode) + ", " +
464*38e8c45fSAndroid Build Coastguard Worker decodeRenderIntent(renderIntent) + ")")
465*38e8c45fSAndroid Build Coastguard Worker .c_str(),
466*38e8c45fSAndroid Build Coastguard Worker error, displayId, UNKNOWN_ERROR);
467*38e8c45fSAndroid Build Coastguard Worker
468*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
469*38e8c45fSAndroid Build Coastguard Worker }
470*38e8c45fSAndroid Build Coastguard Worker
setVsyncEnabled(PhysicalDisplayId displayId,hal::Vsync enabled)471*38e8c45fSAndroid Build Coastguard Worker void HWComposer::setVsyncEnabled(PhysicalDisplayId displayId, hal::Vsync enabled) {
472*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId);
473*38e8c45fSAndroid Build Coastguard Worker auto& displayData = mDisplayData[displayId];
474*38e8c45fSAndroid Build Coastguard Worker
475*38e8c45fSAndroid Build Coastguard Worker // NOTE: we use our own internal lock here because we have to call
476*38e8c45fSAndroid Build Coastguard Worker // into the HWC with the lock held, and we want to make sure
477*38e8c45fSAndroid Build Coastguard Worker // that even if HWC blocks (which it shouldn't), it won't
478*38e8c45fSAndroid Build Coastguard Worker // affect other threads.
479*38e8c45fSAndroid Build Coastguard Worker std::lock_guard lock(displayData.vsyncEnabledLock);
480*38e8c45fSAndroid Build Coastguard Worker if (enabled == displayData.vsyncEnabled) {
481*38e8c45fSAndroid Build Coastguard Worker return;
482*38e8c45fSAndroid Build Coastguard Worker }
483*38e8c45fSAndroid Build Coastguard Worker
484*38e8c45fSAndroid Build Coastguard Worker SFTRACE_CALL();
485*38e8c45fSAndroid Build Coastguard Worker auto error = displayData.hwcDisplay->setVsyncEnabled(enabled);
486*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR(error, displayId);
487*38e8c45fSAndroid Build Coastguard Worker
488*38e8c45fSAndroid Build Coastguard Worker displayData.vsyncEnabled = enabled;
489*38e8c45fSAndroid Build Coastguard Worker
490*38e8c45fSAndroid Build Coastguard Worker SFTRACE_INT(ftl::Concat("HW_VSYNC_ON_", displayId.value).c_str(),
491*38e8c45fSAndroid Build Coastguard Worker enabled == hal::Vsync::ENABLE ? 1 : 0);
492*38e8c45fSAndroid Build Coastguard Worker }
493*38e8c45fSAndroid Build Coastguard Worker
setClientTarget(HalDisplayId displayId,uint32_t slot,const sp<Fence> & acquireFence,const sp<GraphicBuffer> & target,ui::Dataspace dataspace,float hdrSdrRatio)494*38e8c45fSAndroid Build Coastguard Worker status_t HWComposer::setClientTarget(HalDisplayId displayId, uint32_t slot,
495*38e8c45fSAndroid Build Coastguard Worker const sp<Fence>& acquireFence, const sp<GraphicBuffer>& target,
496*38e8c45fSAndroid Build Coastguard Worker ui::Dataspace dataspace, float hdrSdrRatio) {
497*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
498*38e8c45fSAndroid Build Coastguard Worker
499*38e8c45fSAndroid Build Coastguard Worker ALOGV("%s for display %s", __FUNCTION__, to_string(displayId).c_str());
500*38e8c45fSAndroid Build Coastguard Worker auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
501*38e8c45fSAndroid Build Coastguard Worker auto error = hwcDisplay->setClientTarget(slot, target, acquireFence, dataspace, hdrSdrRatio);
502*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
503*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
504*38e8c45fSAndroid Build Coastguard Worker }
505*38e8c45fSAndroid Build Coastguard Worker
getDeviceCompositionChanges(HalDisplayId displayId,bool frameUsesClientComposition,std::optional<std::chrono::steady_clock::time_point> earliestPresentTime,nsecs_t expectedPresentTime,Fps frameInterval,std::optional<android::HWComposer::DeviceRequestedChanges> * outChanges)506*38e8c45fSAndroid Build Coastguard Worker status_t HWComposer::getDeviceCompositionChanges(
507*38e8c45fSAndroid Build Coastguard Worker HalDisplayId displayId, bool frameUsesClientComposition,
508*38e8c45fSAndroid Build Coastguard Worker std::optional<std::chrono::steady_clock::time_point> earliestPresentTime,
509*38e8c45fSAndroid Build Coastguard Worker nsecs_t expectedPresentTime, Fps frameInterval,
510*38e8c45fSAndroid Build Coastguard Worker std::optional<android::HWComposer::DeviceRequestedChanges>* outChanges) {
511*38e8c45fSAndroid Build Coastguard Worker SFTRACE_CALL();
512*38e8c45fSAndroid Build Coastguard Worker
513*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
514*38e8c45fSAndroid Build Coastguard Worker
515*38e8c45fSAndroid Build Coastguard Worker auto& displayData = mDisplayData[displayId];
516*38e8c45fSAndroid Build Coastguard Worker auto& hwcDisplay = displayData.hwcDisplay;
517*38e8c45fSAndroid Build Coastguard Worker if (!hwcDisplay->isConnected()) {
518*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
519*38e8c45fSAndroid Build Coastguard Worker }
520*38e8c45fSAndroid Build Coastguard Worker
521*38e8c45fSAndroid Build Coastguard Worker uint32_t numTypes = 0;
522*38e8c45fSAndroid Build Coastguard Worker uint32_t numRequests = 0;
523*38e8c45fSAndroid Build Coastguard Worker
524*38e8c45fSAndroid Build Coastguard Worker hal::Error error = hal::Error::NONE;
525*38e8c45fSAndroid Build Coastguard Worker
526*38e8c45fSAndroid Build Coastguard Worker // First try to skip validate altogether. We can do that when
527*38e8c45fSAndroid Build Coastguard Worker // 1. The previous frame has not been presented yet or already passed the
528*38e8c45fSAndroid Build Coastguard Worker // earliest time to present. Otherwise, we may present a frame too early.
529*38e8c45fSAndroid Build Coastguard Worker // 2. There is no client composition. Otherwise, we first need to render the
530*38e8c45fSAndroid Build Coastguard Worker // client target buffer.
531*38e8c45fSAndroid Build Coastguard Worker const bool canSkipValidate = [&] {
532*38e8c45fSAndroid Build Coastguard Worker // We must call validate if we have client composition
533*38e8c45fSAndroid Build Coastguard Worker if (frameUsesClientComposition) {
534*38e8c45fSAndroid Build Coastguard Worker return false;
535*38e8c45fSAndroid Build Coastguard Worker }
536*38e8c45fSAndroid Build Coastguard Worker
537*38e8c45fSAndroid Build Coastguard Worker // If composer supports getting the expected present time, we can skip
538*38e8c45fSAndroid Build Coastguard Worker // as composer will make sure to prevent early presentation
539*38e8c45fSAndroid Build Coastguard Worker if (!earliestPresentTime) {
540*38e8c45fSAndroid Build Coastguard Worker return true;
541*38e8c45fSAndroid Build Coastguard Worker }
542*38e8c45fSAndroid Build Coastguard Worker
543*38e8c45fSAndroid Build Coastguard Worker // composer doesn't support getting the expected present time. We can only
544*38e8c45fSAndroid Build Coastguard Worker // skip validate if we know that we are not going to present early.
545*38e8c45fSAndroid Build Coastguard Worker return std::chrono::steady_clock::now() >= *earliestPresentTime;
546*38e8c45fSAndroid Build Coastguard Worker }();
547*38e8c45fSAndroid Build Coastguard Worker
548*38e8c45fSAndroid Build Coastguard Worker displayData.validateWasSkipped = false;
549*38e8c45fSAndroid Build Coastguard Worker SFTRACE_FORMAT("NextFrameInterval %d_Hz", frameInterval.getIntValue());
550*38e8c45fSAndroid Build Coastguard Worker if (canSkipValidate) {
551*38e8c45fSAndroid Build Coastguard Worker sp<Fence> outPresentFence = Fence::NO_FENCE;
552*38e8c45fSAndroid Build Coastguard Worker uint32_t state = UINT32_MAX;
553*38e8c45fSAndroid Build Coastguard Worker error = hwcDisplay->presentOrValidate(expectedPresentTime, frameInterval.getPeriodNsecs(),
554*38e8c45fSAndroid Build Coastguard Worker &numTypes, &numRequests, &outPresentFence, &state);
555*38e8c45fSAndroid Build Coastguard Worker if (!hasChangesError(error)) {
556*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR_FOR("presentOrValidate", error, displayId, UNKNOWN_ERROR);
557*38e8c45fSAndroid Build Coastguard Worker }
558*38e8c45fSAndroid Build Coastguard Worker if (state == 1) { //Present Succeeded.
559*38e8c45fSAndroid Build Coastguard Worker std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
560*38e8c45fSAndroid Build Coastguard Worker error = hwcDisplay->getReleaseFences(&releaseFences);
561*38e8c45fSAndroid Build Coastguard Worker displayData.releaseFences = std::move(releaseFences);
562*38e8c45fSAndroid Build Coastguard Worker displayData.lastPresentFence = outPresentFence;
563*38e8c45fSAndroid Build Coastguard Worker displayData.validateWasSkipped = true;
564*38e8c45fSAndroid Build Coastguard Worker displayData.presentError = error;
565*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
566*38e8c45fSAndroid Build Coastguard Worker }
567*38e8c45fSAndroid Build Coastguard Worker // Present failed but Validate ran.
568*38e8c45fSAndroid Build Coastguard Worker } else {
569*38e8c45fSAndroid Build Coastguard Worker error = hwcDisplay->validate(expectedPresentTime, frameInterval.getPeriodNsecs(), &numTypes,
570*38e8c45fSAndroid Build Coastguard Worker &numRequests);
571*38e8c45fSAndroid Build Coastguard Worker }
572*38e8c45fSAndroid Build Coastguard Worker ALOGV("SkipValidate failed, Falling back to SLOW validate/present");
573*38e8c45fSAndroid Build Coastguard Worker if (!hasChangesError(error)) {
574*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR_FOR("validate", error, displayId, BAD_INDEX);
575*38e8c45fSAndroid Build Coastguard Worker }
576*38e8c45fSAndroid Build Coastguard Worker
577*38e8c45fSAndroid Build Coastguard Worker android::HWComposer::DeviceRequestedChanges::ChangedTypes changedTypes;
578*38e8c45fSAndroid Build Coastguard Worker changedTypes.reserve(numTypes);
579*38e8c45fSAndroid Build Coastguard Worker error = hwcDisplay->getChangedCompositionTypes(&changedTypes);
580*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR_FOR("getChangedCompositionTypes", error, displayId, BAD_INDEX);
581*38e8c45fSAndroid Build Coastguard Worker
582*38e8c45fSAndroid Build Coastguard Worker auto displayRequests = static_cast<hal::DisplayRequest>(0);
583*38e8c45fSAndroid Build Coastguard Worker android::HWComposer::DeviceRequestedChanges::LayerRequests layerRequests;
584*38e8c45fSAndroid Build Coastguard Worker layerRequests.reserve(numRequests);
585*38e8c45fSAndroid Build Coastguard Worker error = hwcDisplay->getRequests(&displayRequests, &layerRequests);
586*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR_FOR("getRequests", error, displayId, BAD_INDEX);
587*38e8c45fSAndroid Build Coastguard Worker
588*38e8c45fSAndroid Build Coastguard Worker DeviceRequestedChanges::ClientTargetProperty clientTargetProperty;
589*38e8c45fSAndroid Build Coastguard Worker error = hwcDisplay->getClientTargetProperty(&clientTargetProperty);
590*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR_FOR("getClientTargetProperty", error, displayId, BAD_INDEX);
591*38e8c45fSAndroid Build Coastguard Worker
592*38e8c45fSAndroid Build Coastguard Worker DeviceRequestedChanges::LayerLuts layerLuts;
593*38e8c45fSAndroid Build Coastguard Worker error = hwcDisplay->getRequestedLuts(&layerLuts, mLutFileDescriptorMapper);
594*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR_FOR("getRequestedLuts", error, displayId, BAD_INDEX);
595*38e8c45fSAndroid Build Coastguard Worker
596*38e8c45fSAndroid Build Coastguard Worker outChanges->emplace(DeviceRequestedChanges{std::move(changedTypes), std::move(displayRequests),
597*38e8c45fSAndroid Build Coastguard Worker std::move(layerRequests),
598*38e8c45fSAndroid Build Coastguard Worker std::move(clientTargetProperty),
599*38e8c45fSAndroid Build Coastguard Worker std::move(layerLuts)});
600*38e8c45fSAndroid Build Coastguard Worker error = hwcDisplay->acceptChanges();
601*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR_FOR("acceptChanges", error, displayId, BAD_INDEX);
602*38e8c45fSAndroid Build Coastguard Worker
603*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
604*38e8c45fSAndroid Build Coastguard Worker }
605*38e8c45fSAndroid Build Coastguard Worker
getPresentFence(HalDisplayId displayId) const606*38e8c45fSAndroid Build Coastguard Worker sp<Fence> HWComposer::getPresentFence(HalDisplayId displayId) const {
607*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, Fence::NO_FENCE);
608*38e8c45fSAndroid Build Coastguard Worker return mDisplayData.at(displayId).lastPresentFence;
609*38e8c45fSAndroid Build Coastguard Worker }
610*38e8c45fSAndroid Build Coastguard Worker
getPresentTimestamp(PhysicalDisplayId displayId) const611*38e8c45fSAndroid Build Coastguard Worker nsecs_t HWComposer::getPresentTimestamp(PhysicalDisplayId displayId) const {
612*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, 0);
613*38e8c45fSAndroid Build Coastguard Worker return mDisplayData.at(displayId).lastPresentTimestamp;
614*38e8c45fSAndroid Build Coastguard Worker }
615*38e8c45fSAndroid Build Coastguard Worker
getLayerReleaseFence(HalDisplayId displayId,HWC2::Layer * layer) const616*38e8c45fSAndroid Build Coastguard Worker sp<Fence> HWComposer::getLayerReleaseFence(HalDisplayId displayId, HWC2::Layer* layer) const {
617*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, Fence::NO_FENCE);
618*38e8c45fSAndroid Build Coastguard Worker const auto& displayFences = mDisplayData.at(displayId).releaseFences;
619*38e8c45fSAndroid Build Coastguard Worker auto fence = displayFences.find(layer);
620*38e8c45fSAndroid Build Coastguard Worker if (fence == displayFences.end()) {
621*38e8c45fSAndroid Build Coastguard Worker ALOGV("getLayerReleaseFence: Release fence not found");
622*38e8c45fSAndroid Build Coastguard Worker return Fence::NO_FENCE;
623*38e8c45fSAndroid Build Coastguard Worker }
624*38e8c45fSAndroid Build Coastguard Worker return fence->second;
625*38e8c45fSAndroid Build Coastguard Worker }
626*38e8c45fSAndroid Build Coastguard Worker
presentAndGetReleaseFences(HalDisplayId displayId,std::optional<std::chrono::steady_clock::time_point> earliestPresentTime)627*38e8c45fSAndroid Build Coastguard Worker status_t HWComposer::presentAndGetReleaseFences(
628*38e8c45fSAndroid Build Coastguard Worker HalDisplayId displayId,
629*38e8c45fSAndroid Build Coastguard Worker std::optional<std::chrono::steady_clock::time_point> earliestPresentTime) {
630*38e8c45fSAndroid Build Coastguard Worker SFTRACE_CALL();
631*38e8c45fSAndroid Build Coastguard Worker
632*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
633*38e8c45fSAndroid Build Coastguard Worker
634*38e8c45fSAndroid Build Coastguard Worker auto& displayData = mDisplayData[displayId];
635*38e8c45fSAndroid Build Coastguard Worker auto& hwcDisplay = displayData.hwcDisplay;
636*38e8c45fSAndroid Build Coastguard Worker
637*38e8c45fSAndroid Build Coastguard Worker if (displayData.validateWasSkipped) {
638*38e8c45fSAndroid Build Coastguard Worker // explicitly flush all pending commands
639*38e8c45fSAndroid Build Coastguard Worker auto error = static_cast<hal::Error>(mComposer->executeCommands(hwcDisplay->getId()));
640*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR_FOR("executeCommands", error, displayId, UNKNOWN_ERROR);
641*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR_FOR("present", displayData.presentError, displayId, UNKNOWN_ERROR);
642*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
643*38e8c45fSAndroid Build Coastguard Worker }
644*38e8c45fSAndroid Build Coastguard Worker
645*38e8c45fSAndroid Build Coastguard Worker if (earliestPresentTime) {
646*38e8c45fSAndroid Build Coastguard Worker SFTRACE_NAME("wait for earliest present time");
647*38e8c45fSAndroid Build Coastguard Worker std::this_thread::sleep_until(*earliestPresentTime);
648*38e8c45fSAndroid Build Coastguard Worker }
649*38e8c45fSAndroid Build Coastguard Worker
650*38e8c45fSAndroid Build Coastguard Worker auto error = hwcDisplay->present(&displayData.lastPresentFence);
651*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR_FOR("present", error, displayId, UNKNOWN_ERROR);
652*38e8c45fSAndroid Build Coastguard Worker
653*38e8c45fSAndroid Build Coastguard Worker std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
654*38e8c45fSAndroid Build Coastguard Worker error = hwcDisplay->getReleaseFences(&releaseFences);
655*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR_FOR("getReleaseFences", error, displayId, UNKNOWN_ERROR);
656*38e8c45fSAndroid Build Coastguard Worker
657*38e8c45fSAndroid Build Coastguard Worker displayData.releaseFences = std::move(releaseFences);
658*38e8c45fSAndroid Build Coastguard Worker
659*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
660*38e8c45fSAndroid Build Coastguard Worker }
661*38e8c45fSAndroid Build Coastguard Worker
executeCommands(HalDisplayId displayId)662*38e8c45fSAndroid Build Coastguard Worker status_t HWComposer::executeCommands(HalDisplayId displayId) {
663*38e8c45fSAndroid Build Coastguard Worker auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
664*38e8c45fSAndroid Build Coastguard Worker auto error = static_cast<hal::Error>(mComposer->executeCommands(hwcDisplay->getId()));
665*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR_FOR("executeCommands", error, displayId, UNKNOWN_ERROR);
666*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
667*38e8c45fSAndroid Build Coastguard Worker }
668*38e8c45fSAndroid Build Coastguard Worker
setPowerMode(PhysicalDisplayId displayId,hal::PowerMode mode)669*38e8c45fSAndroid Build Coastguard Worker status_t HWComposer::setPowerMode(PhysicalDisplayId displayId, hal::PowerMode mode) {
670*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
671*38e8c45fSAndroid Build Coastguard Worker
672*38e8c45fSAndroid Build Coastguard Worker if (mode == hal::PowerMode::OFF) {
673*38e8c45fSAndroid Build Coastguard Worker setVsyncEnabled(displayId, hal::Vsync::DISABLE);
674*38e8c45fSAndroid Build Coastguard Worker }
675*38e8c45fSAndroid Build Coastguard Worker
676*38e8c45fSAndroid Build Coastguard Worker const auto& displayData = mDisplayData[displayId];
677*38e8c45fSAndroid Build Coastguard Worker auto& hwcDisplay = displayData.hwcDisplay;
678*38e8c45fSAndroid Build Coastguard Worker switch (mode) {
679*38e8c45fSAndroid Build Coastguard Worker case hal::PowerMode::OFF:
680*38e8c45fSAndroid Build Coastguard Worker case hal::PowerMode::ON:
681*38e8c45fSAndroid Build Coastguard Worker ALOGV("setPowerMode: Calling HWC %s", to_string(mode).c_str());
682*38e8c45fSAndroid Build Coastguard Worker {
683*38e8c45fSAndroid Build Coastguard Worker auto error = hwcDisplay->setPowerMode(mode);
684*38e8c45fSAndroid Build Coastguard Worker if (error != hal::Error::NONE) {
685*38e8c45fSAndroid Build Coastguard Worker LOG_HWC_ERROR(("setPowerMode(" + to_string(mode) + ")").c_str(), error,
686*38e8c45fSAndroid Build Coastguard Worker displayId);
687*38e8c45fSAndroid Build Coastguard Worker }
688*38e8c45fSAndroid Build Coastguard Worker }
689*38e8c45fSAndroid Build Coastguard Worker break;
690*38e8c45fSAndroid Build Coastguard Worker case hal::PowerMode::DOZE:
691*38e8c45fSAndroid Build Coastguard Worker case hal::PowerMode::DOZE_SUSPEND:
692*38e8c45fSAndroid Build Coastguard Worker ALOGV("setPowerMode: Calling HWC %s", to_string(mode).c_str());
693*38e8c45fSAndroid Build Coastguard Worker {
694*38e8c45fSAndroid Build Coastguard Worker bool supportsDoze = false;
695*38e8c45fSAndroid Build Coastguard Worker const auto queryDozeError = hwcDisplay->supportsDoze(&supportsDoze);
696*38e8c45fSAndroid Build Coastguard Worker
697*38e8c45fSAndroid Build Coastguard Worker // queryDozeError might be NO_RESOURCES, in the case of a display that has never
698*38e8c45fSAndroid Build Coastguard Worker // been turned on. In that case, attempt to set to DOZE anyway.
699*38e8c45fSAndroid Build Coastguard Worker if (!supportsDoze && queryDozeError == hal::Error::NONE) {
700*38e8c45fSAndroid Build Coastguard Worker mode = hal::PowerMode::ON;
701*38e8c45fSAndroid Build Coastguard Worker }
702*38e8c45fSAndroid Build Coastguard Worker
703*38e8c45fSAndroid Build Coastguard Worker auto error = hwcDisplay->setPowerMode(mode);
704*38e8c45fSAndroid Build Coastguard Worker if (error != hal::Error::NONE) {
705*38e8c45fSAndroid Build Coastguard Worker LOG_HWC_ERROR(("setPowerMode(" + to_string(mode) + ")").c_str(), error,
706*38e8c45fSAndroid Build Coastguard Worker displayId);
707*38e8c45fSAndroid Build Coastguard Worker // If the display had never been turned on, so its doze
708*38e8c45fSAndroid Build Coastguard Worker // support was unknown, it may truly not support doze. Try
709*38e8c45fSAndroid Build Coastguard Worker // switching it to ON instead.
710*38e8c45fSAndroid Build Coastguard Worker if (queryDozeError == hal::Error::NO_RESOURCES) {
711*38e8c45fSAndroid Build Coastguard Worker ALOGD("%s: failed to set %s to %s. Trying again with ON", __func__,
712*38e8c45fSAndroid Build Coastguard Worker to_string(displayId).c_str(), to_string(mode).c_str());
713*38e8c45fSAndroid Build Coastguard Worker error = hwcDisplay->setPowerMode(hal::PowerMode::ON);
714*38e8c45fSAndroid Build Coastguard Worker if (error != hal::Error::NONE) {
715*38e8c45fSAndroid Build Coastguard Worker LOG_HWC_ERROR("setPowerMode(ON)", error, displayId);
716*38e8c45fSAndroid Build Coastguard Worker }
717*38e8c45fSAndroid Build Coastguard Worker }
718*38e8c45fSAndroid Build Coastguard Worker }
719*38e8c45fSAndroid Build Coastguard Worker }
720*38e8c45fSAndroid Build Coastguard Worker break;
721*38e8c45fSAndroid Build Coastguard Worker default:
722*38e8c45fSAndroid Build Coastguard Worker ALOGV("setPowerMode: Not calling HWC");
723*38e8c45fSAndroid Build Coastguard Worker break;
724*38e8c45fSAndroid Build Coastguard Worker }
725*38e8c45fSAndroid Build Coastguard Worker
726*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
727*38e8c45fSAndroid Build Coastguard Worker }
728*38e8c45fSAndroid Build Coastguard Worker
setActiveModeWithConstraints(PhysicalDisplayId displayId,hal::HWConfigId hwcModeId,const hal::VsyncPeriodChangeConstraints & constraints,hal::VsyncPeriodChangeTimeline * outTimeline)729*38e8c45fSAndroid Build Coastguard Worker status_t HWComposer::setActiveModeWithConstraints(
730*38e8c45fSAndroid Build Coastguard Worker PhysicalDisplayId displayId, hal::HWConfigId hwcModeId,
731*38e8c45fSAndroid Build Coastguard Worker const hal::VsyncPeriodChangeConstraints& constraints,
732*38e8c45fSAndroid Build Coastguard Worker hal::VsyncPeriodChangeTimeline* outTimeline) {
733*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
734*38e8c45fSAndroid Build Coastguard Worker
735*38e8c45fSAndroid Build Coastguard Worker auto error = mDisplayData[displayId].hwcDisplay->setActiveConfigWithConstraints(hwcModeId,
736*38e8c45fSAndroid Build Coastguard Worker constraints,
737*38e8c45fSAndroid Build Coastguard Worker outTimeline);
738*38e8c45fSAndroid Build Coastguard Worker if (error == hal::Error::CONFIG_FAILED) {
739*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR_FOR("setActiveConfigWithConstraints", error, displayId,
740*38e8c45fSAndroid Build Coastguard Worker FAILED_TRANSACTION);
741*38e8c45fSAndroid Build Coastguard Worker }
742*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR_FOR("setActiveConfigWithConstraints", error, displayId, UNKNOWN_ERROR);
743*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
744*38e8c45fSAndroid Build Coastguard Worker }
745*38e8c45fSAndroid Build Coastguard Worker
setColorTransform(HalDisplayId displayId,const mat4 & transform)746*38e8c45fSAndroid Build Coastguard Worker status_t HWComposer::setColorTransform(HalDisplayId displayId, const mat4& transform) {
747*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
748*38e8c45fSAndroid Build Coastguard Worker
749*38e8c45fSAndroid Build Coastguard Worker auto& displayData = mDisplayData[displayId];
750*38e8c45fSAndroid Build Coastguard Worker auto error = displayData.hwcDisplay->setColorTransform(transform);
751*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
752*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
753*38e8c45fSAndroid Build Coastguard Worker }
754*38e8c45fSAndroid Build Coastguard Worker
disconnectDisplay(HalDisplayId displayId)755*38e8c45fSAndroid Build Coastguard Worker void HWComposer::disconnectDisplay(HalDisplayId displayId) {
756*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId);
757*38e8c45fSAndroid Build Coastguard Worker auto& displayData = mDisplayData[displayId];
758*38e8c45fSAndroid Build Coastguard Worker const auto hwcDisplayId = displayData.hwcDisplay->getId();
759*38e8c45fSAndroid Build Coastguard Worker
760*38e8c45fSAndroid Build Coastguard Worker mPhysicalDisplayIdMap.erase(hwcDisplayId);
761*38e8c45fSAndroid Build Coastguard Worker mDisplayData.erase(displayId);
762*38e8c45fSAndroid Build Coastguard Worker
763*38e8c45fSAndroid Build Coastguard Worker // Reset the primary display ID if we're disconnecting it.
764*38e8c45fSAndroid Build Coastguard Worker // This way isHeadless() will return false, which is necessary
765*38e8c45fSAndroid Build Coastguard Worker // because getPrimaryDisplayId() will crash.
766*38e8c45fSAndroid Build Coastguard Worker if (mPrimaryHwcDisplayId == hwcDisplayId) {
767*38e8c45fSAndroid Build Coastguard Worker mPrimaryHwcDisplayId.reset();
768*38e8c45fSAndroid Build Coastguard Worker }
769*38e8c45fSAndroid Build Coastguard Worker }
770*38e8c45fSAndroid Build Coastguard Worker
setOutputBuffer(HalVirtualDisplayId displayId,const sp<Fence> & acquireFence,const sp<GraphicBuffer> & buffer)771*38e8c45fSAndroid Build Coastguard Worker status_t HWComposer::setOutputBuffer(HalVirtualDisplayId displayId, const sp<Fence>& acquireFence,
772*38e8c45fSAndroid Build Coastguard Worker const sp<GraphicBuffer>& buffer) {
773*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
774*38e8c45fSAndroid Build Coastguard Worker const auto& displayData = mDisplayData[displayId];
775*38e8c45fSAndroid Build Coastguard Worker
776*38e8c45fSAndroid Build Coastguard Worker auto error = displayData.hwcDisplay->setOutputBuffer(buffer, acquireFence);
777*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
778*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
779*38e8c45fSAndroid Build Coastguard Worker }
780*38e8c45fSAndroid Build Coastguard Worker
clearReleaseFences(HalDisplayId displayId)781*38e8c45fSAndroid Build Coastguard Worker void HWComposer::clearReleaseFences(HalDisplayId displayId) {
782*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId);
783*38e8c45fSAndroid Build Coastguard Worker mDisplayData[displayId].releaseFences.clear();
784*38e8c45fSAndroid Build Coastguard Worker }
785*38e8c45fSAndroid Build Coastguard Worker
getHdrCapabilities(HalDisplayId displayId,HdrCapabilities * outCapabilities)786*38e8c45fSAndroid Build Coastguard Worker status_t HWComposer::getHdrCapabilities(HalDisplayId displayId, HdrCapabilities* outCapabilities) {
787*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
788*38e8c45fSAndroid Build Coastguard Worker
789*38e8c45fSAndroid Build Coastguard Worker auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
790*38e8c45fSAndroid Build Coastguard Worker auto error = hwcDisplay->getHdrCapabilities(outCapabilities);
791*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
792*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
793*38e8c45fSAndroid Build Coastguard Worker }
794*38e8c45fSAndroid Build Coastguard Worker
795*38e8c45fSAndroid Build Coastguard Worker const aidl::android::hardware::graphics::composer3::OverlayProperties&
getOverlaySupport() const796*38e8c45fSAndroid Build Coastguard Worker HWComposer::getOverlaySupport() const {
797*38e8c45fSAndroid Build Coastguard Worker return mOverlayProperties;
798*38e8c45fSAndroid Build Coastguard Worker }
799*38e8c45fSAndroid Build Coastguard Worker
getSupportedPerFrameMetadata(HalDisplayId displayId) const800*38e8c45fSAndroid Build Coastguard Worker int32_t HWComposer::getSupportedPerFrameMetadata(HalDisplayId displayId) const {
801*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, 0);
802*38e8c45fSAndroid Build Coastguard Worker return mDisplayData.at(displayId).hwcDisplay->getSupportedPerFrameMetadata();
803*38e8c45fSAndroid Build Coastguard Worker }
804*38e8c45fSAndroid Build Coastguard Worker
getRenderIntents(HalDisplayId displayId,ui::ColorMode colorMode) const805*38e8c45fSAndroid Build Coastguard Worker std::vector<ui::RenderIntent> HWComposer::getRenderIntents(HalDisplayId displayId,
806*38e8c45fSAndroid Build Coastguard Worker ui::ColorMode colorMode) const {
807*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, {});
808*38e8c45fSAndroid Build Coastguard Worker
809*38e8c45fSAndroid Build Coastguard Worker std::vector<ui::RenderIntent> renderIntents;
810*38e8c45fSAndroid Build Coastguard Worker auto error = mDisplayData.at(displayId).hwcDisplay->getRenderIntents(colorMode, &renderIntents);
811*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR(error, displayId, {});
812*38e8c45fSAndroid Build Coastguard Worker return renderIntents;
813*38e8c45fSAndroid Build Coastguard Worker }
814*38e8c45fSAndroid Build Coastguard Worker
getDataspaceSaturationMatrix(HalDisplayId displayId,ui::Dataspace dataspace)815*38e8c45fSAndroid Build Coastguard Worker mat4 HWComposer::getDataspaceSaturationMatrix(HalDisplayId displayId, ui::Dataspace dataspace) {
816*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, {});
817*38e8c45fSAndroid Build Coastguard Worker
818*38e8c45fSAndroid Build Coastguard Worker mat4 matrix;
819*38e8c45fSAndroid Build Coastguard Worker auto error = mDisplayData[displayId].hwcDisplay->getDataspaceSaturationMatrix(dataspace,
820*38e8c45fSAndroid Build Coastguard Worker &matrix);
821*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR(error, displayId, {});
822*38e8c45fSAndroid Build Coastguard Worker return matrix;
823*38e8c45fSAndroid Build Coastguard Worker }
824*38e8c45fSAndroid Build Coastguard Worker
getDisplayedContentSamplingAttributes(HalDisplayId displayId,ui::PixelFormat * outFormat,ui::Dataspace * outDataspace,uint8_t * outComponentMask)825*38e8c45fSAndroid Build Coastguard Worker status_t HWComposer::getDisplayedContentSamplingAttributes(HalDisplayId displayId,
826*38e8c45fSAndroid Build Coastguard Worker ui::PixelFormat* outFormat,
827*38e8c45fSAndroid Build Coastguard Worker ui::Dataspace* outDataspace,
828*38e8c45fSAndroid Build Coastguard Worker uint8_t* outComponentMask) {
829*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
830*38e8c45fSAndroid Build Coastguard Worker const auto error =
831*38e8c45fSAndroid Build Coastguard Worker mDisplayData[displayId]
832*38e8c45fSAndroid Build Coastguard Worker .hwcDisplay->getDisplayedContentSamplingAttributes(outFormat, outDataspace,
833*38e8c45fSAndroid Build Coastguard Worker outComponentMask);
834*38e8c45fSAndroid Build Coastguard Worker if (error == hal::Error::UNSUPPORTED) RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
835*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
836*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
837*38e8c45fSAndroid Build Coastguard Worker }
838*38e8c45fSAndroid Build Coastguard Worker
setDisplayContentSamplingEnabled(HalDisplayId displayId,bool enabled,uint8_t componentMask,uint64_t maxFrames)839*38e8c45fSAndroid Build Coastguard Worker status_t HWComposer::setDisplayContentSamplingEnabled(HalDisplayId displayId, bool enabled,
840*38e8c45fSAndroid Build Coastguard Worker uint8_t componentMask, uint64_t maxFrames) {
841*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
842*38e8c45fSAndroid Build Coastguard Worker const auto error =
843*38e8c45fSAndroid Build Coastguard Worker mDisplayData[displayId].hwcDisplay->setDisplayContentSamplingEnabled(enabled,
844*38e8c45fSAndroid Build Coastguard Worker componentMask,
845*38e8c45fSAndroid Build Coastguard Worker maxFrames);
846*38e8c45fSAndroid Build Coastguard Worker
847*38e8c45fSAndroid Build Coastguard Worker if (error == hal::Error::UNSUPPORTED) RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
848*38e8c45fSAndroid Build Coastguard Worker if (error == hal::Error::BAD_PARAMETER) RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
849*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
850*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
851*38e8c45fSAndroid Build Coastguard Worker }
852*38e8c45fSAndroid Build Coastguard Worker
getDisplayedContentSample(HalDisplayId displayId,uint64_t maxFrames,uint64_t timestamp,DisplayedFrameStats * outStats)853*38e8c45fSAndroid Build Coastguard Worker status_t HWComposer::getDisplayedContentSample(HalDisplayId displayId, uint64_t maxFrames,
854*38e8c45fSAndroid Build Coastguard Worker uint64_t timestamp, DisplayedFrameStats* outStats) {
855*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
856*38e8c45fSAndroid Build Coastguard Worker const auto error =
857*38e8c45fSAndroid Build Coastguard Worker mDisplayData[displayId].hwcDisplay->getDisplayedContentSample(maxFrames, timestamp,
858*38e8c45fSAndroid Build Coastguard Worker outStats);
859*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
860*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
861*38e8c45fSAndroid Build Coastguard Worker }
862*38e8c45fSAndroid Build Coastguard Worker
setDisplayBrightness(PhysicalDisplayId displayId,float brightness,float brightnessNits,const Hwc2::Composer::DisplayBrightnessOptions & options)863*38e8c45fSAndroid Build Coastguard Worker ftl::Future<status_t> HWComposer::setDisplayBrightness(
864*38e8c45fSAndroid Build Coastguard Worker PhysicalDisplayId displayId, float brightness, float brightnessNits,
865*38e8c45fSAndroid Build Coastguard Worker const Hwc2::Composer::DisplayBrightnessOptions& options) {
866*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, ftl::yield<status_t>(BAD_INDEX));
867*38e8c45fSAndroid Build Coastguard Worker auto& display = mDisplayData[displayId].hwcDisplay;
868*38e8c45fSAndroid Build Coastguard Worker
869*38e8c45fSAndroid Build Coastguard Worker return display->setDisplayBrightness(brightness, brightnessNits, options)
870*38e8c45fSAndroid Build Coastguard Worker .then([displayId](hal::Error error) -> status_t {
871*38e8c45fSAndroid Build Coastguard Worker if (error == hal::Error::UNSUPPORTED) {
872*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
873*38e8c45fSAndroid Build Coastguard Worker }
874*38e8c45fSAndroid Build Coastguard Worker if (error == hal::Error::BAD_PARAMETER) {
875*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
876*38e8c45fSAndroid Build Coastguard Worker }
877*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
878*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
879*38e8c45fSAndroid Build Coastguard Worker });
880*38e8c45fSAndroid Build Coastguard Worker }
881*38e8c45fSAndroid Build Coastguard Worker
getValidateSkipped(HalDisplayId displayId) const882*38e8c45fSAndroid Build Coastguard Worker bool HWComposer::getValidateSkipped(HalDisplayId displayId) const {
883*38e8c45fSAndroid Build Coastguard Worker if (mDisplayData.count(displayId) == 0) {
884*38e8c45fSAndroid Build Coastguard Worker return false;
885*38e8c45fSAndroid Build Coastguard Worker }
886*38e8c45fSAndroid Build Coastguard Worker return mDisplayData.at(displayId).validateWasSkipped;
887*38e8c45fSAndroid Build Coastguard Worker }
888*38e8c45fSAndroid Build Coastguard Worker
setBootDisplayMode(PhysicalDisplayId displayId,hal::HWConfigId displayModeId)889*38e8c45fSAndroid Build Coastguard Worker status_t HWComposer::setBootDisplayMode(PhysicalDisplayId displayId,
890*38e8c45fSAndroid Build Coastguard Worker hal::HWConfigId displayModeId) {
891*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
892*38e8c45fSAndroid Build Coastguard Worker const auto error = mDisplayData[displayId].hwcDisplay->setBootDisplayConfig(displayModeId);
893*38e8c45fSAndroid Build Coastguard Worker if (error == hal::Error::UNSUPPORTED) {
894*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
895*38e8c45fSAndroid Build Coastguard Worker }
896*38e8c45fSAndroid Build Coastguard Worker if (error == hal::Error::BAD_PARAMETER) {
897*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
898*38e8c45fSAndroid Build Coastguard Worker }
899*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
900*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
901*38e8c45fSAndroid Build Coastguard Worker }
902*38e8c45fSAndroid Build Coastguard Worker
clearBootDisplayMode(PhysicalDisplayId displayId)903*38e8c45fSAndroid Build Coastguard Worker status_t HWComposer::clearBootDisplayMode(PhysicalDisplayId displayId) {
904*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
905*38e8c45fSAndroid Build Coastguard Worker const auto error = mDisplayData[displayId].hwcDisplay->clearBootDisplayConfig();
906*38e8c45fSAndroid Build Coastguard Worker if (error == hal::Error::UNSUPPORTED) {
907*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
908*38e8c45fSAndroid Build Coastguard Worker }
909*38e8c45fSAndroid Build Coastguard Worker if (error == hal::Error::BAD_PARAMETER) {
910*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
911*38e8c45fSAndroid Build Coastguard Worker }
912*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
913*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
914*38e8c45fSAndroid Build Coastguard Worker }
915*38e8c45fSAndroid Build Coastguard Worker
getPreferredBootDisplayMode(PhysicalDisplayId displayId)916*38e8c45fSAndroid Build Coastguard Worker std::optional<hal::HWConfigId> HWComposer::getPreferredBootDisplayMode(
917*38e8c45fSAndroid Build Coastguard Worker PhysicalDisplayId displayId) {
918*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, std::nullopt);
919*38e8c45fSAndroid Build Coastguard Worker hal::HWConfigId displayModeId;
920*38e8c45fSAndroid Build Coastguard Worker const auto error =
921*38e8c45fSAndroid Build Coastguard Worker mDisplayData[displayId].hwcDisplay->getPreferredBootDisplayConfig(&displayModeId);
922*38e8c45fSAndroid Build Coastguard Worker if (error != hal::Error::NONE) {
923*38e8c45fSAndroid Build Coastguard Worker LOG_DISPLAY_ERROR(displayId, to_string(error).c_str());
924*38e8c45fSAndroid Build Coastguard Worker return std::nullopt;
925*38e8c45fSAndroid Build Coastguard Worker }
926*38e8c45fSAndroid Build Coastguard Worker return displayModeId;
927*38e8c45fSAndroid Build Coastguard Worker }
928*38e8c45fSAndroid Build Coastguard Worker
getHdrConversionCapabilities() const929*38e8c45fSAndroid Build Coastguard Worker std::vector<HdrConversionCapability> HWComposer::getHdrConversionCapabilities() const {
930*38e8c45fSAndroid Build Coastguard Worker return mHdrConversionCapabilities;
931*38e8c45fSAndroid Build Coastguard Worker }
932*38e8c45fSAndroid Build Coastguard Worker
setHdrConversionStrategy(HdrConversionStrategy hdrConversionStrategy,aidl::android::hardware::graphics::common::Hdr * outPreferredHdrOutputType)933*38e8c45fSAndroid Build Coastguard Worker status_t HWComposer::setHdrConversionStrategy(
934*38e8c45fSAndroid Build Coastguard Worker HdrConversionStrategy hdrConversionStrategy,
935*38e8c45fSAndroid Build Coastguard Worker aidl::android::hardware::graphics::common::Hdr* outPreferredHdrOutputType) {
936*38e8c45fSAndroid Build Coastguard Worker const auto error =
937*38e8c45fSAndroid Build Coastguard Worker mComposer->setHdrConversionStrategy(hdrConversionStrategy, outPreferredHdrOutputType);
938*38e8c45fSAndroid Build Coastguard Worker if (error != hal::Error::NONE) {
939*38e8c45fSAndroid Build Coastguard Worker ALOGE("Error in setting HDR conversion strategy %s", to_string(error).c_str());
940*38e8c45fSAndroid Build Coastguard Worker return INVALID_OPERATION;
941*38e8c45fSAndroid Build Coastguard Worker }
942*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
943*38e8c45fSAndroid Build Coastguard Worker }
944*38e8c45fSAndroid Build Coastguard Worker
setRefreshRateChangedCallbackDebugEnabled(PhysicalDisplayId displayId,bool enabled)945*38e8c45fSAndroid Build Coastguard Worker status_t HWComposer::setRefreshRateChangedCallbackDebugEnabled(PhysicalDisplayId displayId,
946*38e8c45fSAndroid Build Coastguard Worker bool enabled) {
947*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
948*38e8c45fSAndroid Build Coastguard Worker const auto error =
949*38e8c45fSAndroid Build Coastguard Worker mComposer->setRefreshRateChangedCallbackDebugEnabled(mDisplayData[displayId]
950*38e8c45fSAndroid Build Coastguard Worker .hwcDisplay->getId(),
951*38e8c45fSAndroid Build Coastguard Worker enabled);
952*38e8c45fSAndroid Build Coastguard Worker if (error != hal::Error::NONE) {
953*38e8c45fSAndroid Build Coastguard Worker ALOGE("Error in setting refresh refresh rate change callback debug enabled %s",
954*38e8c45fSAndroid Build Coastguard Worker to_string(error).c_str());
955*38e8c45fSAndroid Build Coastguard Worker return INVALID_OPERATION;
956*38e8c45fSAndroid Build Coastguard Worker }
957*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
958*38e8c45fSAndroid Build Coastguard Worker }
959*38e8c45fSAndroid Build Coastguard Worker
notifyExpectedPresent(PhysicalDisplayId displayId,TimePoint expectedPresentTime,Fps frameInterval)960*38e8c45fSAndroid Build Coastguard Worker status_t HWComposer::notifyExpectedPresent(PhysicalDisplayId displayId,
961*38e8c45fSAndroid Build Coastguard Worker TimePoint expectedPresentTime, Fps frameInterval) {
962*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
963*38e8c45fSAndroid Build Coastguard Worker SFTRACE_FORMAT("%s ExpectedPresentTime in %.2fms frameInterval %.2fms", __func__,
964*38e8c45fSAndroid Build Coastguard Worker ticks<std::milli, float>(expectedPresentTime - TimePoint::now()),
965*38e8c45fSAndroid Build Coastguard Worker ticks<std::milli, float>(Duration::fromNs(frameInterval.getPeriodNsecs())));
966*38e8c45fSAndroid Build Coastguard Worker const auto error = mComposer->notifyExpectedPresent(mDisplayData[displayId].hwcDisplay->getId(),
967*38e8c45fSAndroid Build Coastguard Worker expectedPresentTime.ns(),
968*38e8c45fSAndroid Build Coastguard Worker frameInterval.getPeriodNsecs());
969*38e8c45fSAndroid Build Coastguard Worker if (error != hal::Error::NONE) {
970*38e8c45fSAndroid Build Coastguard Worker ALOGE("Error in notifyExpectedPresent call %s", to_string(error).c_str());
971*38e8c45fSAndroid Build Coastguard Worker return INVALID_OPERATION;
972*38e8c45fSAndroid Build Coastguard Worker }
973*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
974*38e8c45fSAndroid Build Coastguard Worker }
975*38e8c45fSAndroid Build Coastguard Worker
getDisplayDecorationSupport(PhysicalDisplayId displayId,std::optional<aidl::android::hardware::graphics::common::DisplayDecorationSupport> * support)976*38e8c45fSAndroid Build Coastguard Worker status_t HWComposer::getDisplayDecorationSupport(
977*38e8c45fSAndroid Build Coastguard Worker PhysicalDisplayId displayId,
978*38e8c45fSAndroid Build Coastguard Worker std::optional<aidl::android::hardware::graphics::common::DisplayDecorationSupport>*
979*38e8c45fSAndroid Build Coastguard Worker support) {
980*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
981*38e8c45fSAndroid Build Coastguard Worker const auto error = mDisplayData[displayId].hwcDisplay->getDisplayDecorationSupport(support);
982*38e8c45fSAndroid Build Coastguard Worker if (error == hal::Error::UNSUPPORTED) {
983*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
984*38e8c45fSAndroid Build Coastguard Worker }
985*38e8c45fSAndroid Build Coastguard Worker if (error == hal::Error::BAD_PARAMETER) {
986*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
987*38e8c45fSAndroid Build Coastguard Worker }
988*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
989*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
990*38e8c45fSAndroid Build Coastguard Worker }
991*38e8c45fSAndroid Build Coastguard Worker
setAutoLowLatencyMode(PhysicalDisplayId displayId,bool on)992*38e8c45fSAndroid Build Coastguard Worker status_t HWComposer::setAutoLowLatencyMode(PhysicalDisplayId displayId, bool on) {
993*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
994*38e8c45fSAndroid Build Coastguard Worker const auto error = mDisplayData[displayId].hwcDisplay->setAutoLowLatencyMode(on);
995*38e8c45fSAndroid Build Coastguard Worker if (error == hal::Error::UNSUPPORTED) {
996*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
997*38e8c45fSAndroid Build Coastguard Worker }
998*38e8c45fSAndroid Build Coastguard Worker if (error == hal::Error::BAD_PARAMETER) {
999*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
1000*38e8c45fSAndroid Build Coastguard Worker }
1001*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
1002*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
1003*38e8c45fSAndroid Build Coastguard Worker }
1004*38e8c45fSAndroid Build Coastguard Worker
getSupportedContentTypes(PhysicalDisplayId displayId,std::vector<hal::ContentType> * outSupportedContentTypes) const1005*38e8c45fSAndroid Build Coastguard Worker status_t HWComposer::getSupportedContentTypes(
1006*38e8c45fSAndroid Build Coastguard Worker PhysicalDisplayId displayId,
1007*38e8c45fSAndroid Build Coastguard Worker std::vector<hal::ContentType>* outSupportedContentTypes) const {
1008*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
1009*38e8c45fSAndroid Build Coastguard Worker const auto error = mDisplayData.at(displayId).hwcDisplay->getSupportedContentTypes(
1010*38e8c45fSAndroid Build Coastguard Worker outSupportedContentTypes);
1011*38e8c45fSAndroid Build Coastguard Worker
1012*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
1013*38e8c45fSAndroid Build Coastguard Worker
1014*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
1015*38e8c45fSAndroid Build Coastguard Worker }
1016*38e8c45fSAndroid Build Coastguard Worker
setContentType(PhysicalDisplayId displayId,hal::ContentType contentType)1017*38e8c45fSAndroid Build Coastguard Worker status_t HWComposer::setContentType(PhysicalDisplayId displayId, hal::ContentType contentType) {
1018*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
1019*38e8c45fSAndroid Build Coastguard Worker const auto error = mDisplayData[displayId].hwcDisplay->setContentType(contentType);
1020*38e8c45fSAndroid Build Coastguard Worker if (error == hal::Error::UNSUPPORTED) {
1021*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
1022*38e8c45fSAndroid Build Coastguard Worker }
1023*38e8c45fSAndroid Build Coastguard Worker if (error == hal::Error::BAD_PARAMETER) {
1024*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
1025*38e8c45fSAndroid Build Coastguard Worker }
1026*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
1027*38e8c45fSAndroid Build Coastguard Worker
1028*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
1029*38e8c45fSAndroid Build Coastguard Worker }
1030*38e8c45fSAndroid Build Coastguard Worker
getMaxLayerPictureProfiles(PhysicalDisplayId displayId)1031*38e8c45fSAndroid Build Coastguard Worker int32_t HWComposer::getMaxLayerPictureProfiles(PhysicalDisplayId displayId) {
1032*38e8c45fSAndroid Build Coastguard Worker int32_t maxProfiles = 0;
1033*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, 0);
1034*38e8c45fSAndroid Build Coastguard Worker const auto error = mDisplayData[displayId].hwcDisplay->getMaxLayerPictureProfiles(&maxProfiles);
1035*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR(error, displayId, 0);
1036*38e8c45fSAndroid Build Coastguard Worker return maxProfiles;
1037*38e8c45fSAndroid Build Coastguard Worker }
1038*38e8c45fSAndroid Build Coastguard Worker
setDisplayPictureProfileHandle(PhysicalDisplayId displayId,const PictureProfileHandle & handle)1039*38e8c45fSAndroid Build Coastguard Worker status_t HWComposer::setDisplayPictureProfileHandle(PhysicalDisplayId displayId,
1040*38e8c45fSAndroid Build Coastguard Worker const PictureProfileHandle& handle) {
1041*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
1042*38e8c45fSAndroid Build Coastguard Worker const auto error = mDisplayData[displayId].hwcDisplay->setPictureProfileHandle(handle);
1043*38e8c45fSAndroid Build Coastguard Worker if (error != hal::Error::UNSUPPORTED) {
1044*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
1045*38e8c45fSAndroid Build Coastguard Worker }
1046*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
1047*38e8c45fSAndroid Build Coastguard Worker }
1048*38e8c45fSAndroid Build Coastguard Worker
getSupportedLayerGenericMetadata() const1049*38e8c45fSAndroid Build Coastguard Worker const std::unordered_map<std::string, bool>& HWComposer::getSupportedLayerGenericMetadata() const {
1050*38e8c45fSAndroid Build Coastguard Worker return mSupportedLayerGenericMetadata;
1051*38e8c45fSAndroid Build Coastguard Worker }
1052*38e8c45fSAndroid Build Coastguard Worker
1053*38e8c45fSAndroid Build Coastguard Worker ftl::SmallMap<HWC2::Layer*, ndk::ScopedFileDescriptor, 20>&
getLutFileDescriptorMapper()1054*38e8c45fSAndroid Build Coastguard Worker HWComposer::getLutFileDescriptorMapper() {
1055*38e8c45fSAndroid Build Coastguard Worker return mLutFileDescriptorMapper;
1056*38e8c45fSAndroid Build Coastguard Worker }
1057*38e8c45fSAndroid Build Coastguard Worker
dumpOverlayProperties(std::string & result) const1058*38e8c45fSAndroid Build Coastguard Worker void HWComposer::dumpOverlayProperties(std::string& result) const {
1059*38e8c45fSAndroid Build Coastguard Worker // dump overlay properties
1060*38e8c45fSAndroid Build Coastguard Worker result.append("OverlayProperties:\n");
1061*38e8c45fSAndroid Build Coastguard Worker base::StringAppendF(&result, "supportMixedColorSpaces: %d\n",
1062*38e8c45fSAndroid Build Coastguard Worker mOverlayProperties.supportMixedColorSpaces);
1063*38e8c45fSAndroid Build Coastguard Worker base::StringAppendF(&result, "SupportedBufferCombinations(%zu entries)\n",
1064*38e8c45fSAndroid Build Coastguard Worker mOverlayProperties.combinations.size());
1065*38e8c45fSAndroid Build Coastguard Worker for (const auto& combination : mOverlayProperties.combinations) {
1066*38e8c45fSAndroid Build Coastguard Worker result.append(" pixelFormats=\n");
1067*38e8c45fSAndroid Build Coastguard Worker for (const auto& pixelFormat : combination.pixelFormats) {
1068*38e8c45fSAndroid Build Coastguard Worker base::StringAppendF(&result, " %s (%d)\n",
1069*38e8c45fSAndroid Build Coastguard Worker decodePixelFormat(static_cast<PixelFormat>(pixelFormat)).c_str(),
1070*38e8c45fSAndroid Build Coastguard Worker static_cast<uint32_t>(pixelFormat));
1071*38e8c45fSAndroid Build Coastguard Worker }
1072*38e8c45fSAndroid Build Coastguard Worker result.append(" standards=\n");
1073*38e8c45fSAndroid Build Coastguard Worker for (const auto& standard : combination.standards) {
1074*38e8c45fSAndroid Build Coastguard Worker base::StringAppendF(&result, " %s (%d)\n",
1075*38e8c45fSAndroid Build Coastguard Worker decodeStandardOnly(static_cast<uint32_t>(standard)).c_str(),
1076*38e8c45fSAndroid Build Coastguard Worker static_cast<uint32_t>(standard));
1077*38e8c45fSAndroid Build Coastguard Worker }
1078*38e8c45fSAndroid Build Coastguard Worker result.append(" transfers=\n");
1079*38e8c45fSAndroid Build Coastguard Worker for (const auto& transfer : combination.transfers) {
1080*38e8c45fSAndroid Build Coastguard Worker base::StringAppendF(&result, " %s (%d)\n",
1081*38e8c45fSAndroid Build Coastguard Worker decodeTransferOnly(static_cast<uint32_t>(transfer)).c_str(),
1082*38e8c45fSAndroid Build Coastguard Worker static_cast<uint32_t>(transfer));
1083*38e8c45fSAndroid Build Coastguard Worker }
1084*38e8c45fSAndroid Build Coastguard Worker result.append(" ranges=\n");
1085*38e8c45fSAndroid Build Coastguard Worker for (const auto& range : combination.ranges) {
1086*38e8c45fSAndroid Build Coastguard Worker base::StringAppendF(&result, " %s (%d)\n",
1087*38e8c45fSAndroid Build Coastguard Worker decodeRangeOnly(static_cast<uint32_t>(range)).c_str(),
1088*38e8c45fSAndroid Build Coastguard Worker static_cast<uint32_t>(range));
1089*38e8c45fSAndroid Build Coastguard Worker }
1090*38e8c45fSAndroid Build Coastguard Worker result.append("\n");
1091*38e8c45fSAndroid Build Coastguard Worker }
1092*38e8c45fSAndroid Build Coastguard Worker }
1093*38e8c45fSAndroid Build Coastguard Worker
dump(std::string & result) const1094*38e8c45fSAndroid Build Coastguard Worker void HWComposer::dump(std::string& result) const {
1095*38e8c45fSAndroid Build Coastguard Worker result.append(mComposer->dumpDebugInfo());
1096*38e8c45fSAndroid Build Coastguard Worker dumpOverlayProperties(result);
1097*38e8c45fSAndroid Build Coastguard Worker }
1098*38e8c45fSAndroid Build Coastguard Worker
toPhysicalDisplayId(hal::HWDisplayId hwcDisplayId) const1099*38e8c45fSAndroid Build Coastguard Worker std::optional<PhysicalDisplayId> HWComposer::toPhysicalDisplayId(
1100*38e8c45fSAndroid Build Coastguard Worker hal::HWDisplayId hwcDisplayId) const {
1101*38e8c45fSAndroid Build Coastguard Worker if (const auto it = mPhysicalDisplayIdMap.find(hwcDisplayId);
1102*38e8c45fSAndroid Build Coastguard Worker it != mPhysicalDisplayIdMap.end()) {
1103*38e8c45fSAndroid Build Coastguard Worker return it->second;
1104*38e8c45fSAndroid Build Coastguard Worker }
1105*38e8c45fSAndroid Build Coastguard Worker return {};
1106*38e8c45fSAndroid Build Coastguard Worker }
1107*38e8c45fSAndroid Build Coastguard Worker
fromPhysicalDisplayId(PhysicalDisplayId displayId) const1108*38e8c45fSAndroid Build Coastguard Worker std::optional<hal::HWDisplayId> HWComposer::fromPhysicalDisplayId(
1109*38e8c45fSAndroid Build Coastguard Worker PhysicalDisplayId displayId) const {
1110*38e8c45fSAndroid Build Coastguard Worker if (const auto it = mDisplayData.find(displayId); it != mDisplayData.end()) {
1111*38e8c45fSAndroid Build Coastguard Worker return it->second.hwcDisplay->getId();
1112*38e8c45fSAndroid Build Coastguard Worker }
1113*38e8c45fSAndroid Build Coastguard Worker return {};
1114*38e8c45fSAndroid Build Coastguard Worker }
1115*38e8c45fSAndroid Build Coastguard Worker
shouldIgnoreHotplugConnect(hal::HWDisplayId hwcDisplayId,bool hasDisplayIdentificationData) const1116*38e8c45fSAndroid Build Coastguard Worker bool HWComposer::shouldIgnoreHotplugConnect(hal::HWDisplayId hwcDisplayId,
1117*38e8c45fSAndroid Build Coastguard Worker bool hasDisplayIdentificationData) const {
1118*38e8c45fSAndroid Build Coastguard Worker if (mHasMultiDisplaySupport && !hasDisplayIdentificationData) {
1119*38e8c45fSAndroid Build Coastguard Worker ALOGE("Ignoring connection of display %" PRIu64 " without identification data",
1120*38e8c45fSAndroid Build Coastguard Worker hwcDisplayId);
1121*38e8c45fSAndroid Build Coastguard Worker return true;
1122*38e8c45fSAndroid Build Coastguard Worker }
1123*38e8c45fSAndroid Build Coastguard Worker
1124*38e8c45fSAndroid Build Coastguard Worker // Legacy mode only supports IDs LEGACY_DISPLAY_TYPE_PRIMARY and LEGACY_DISPLAY_TYPE_EXTERNAL.
1125*38e8c45fSAndroid Build Coastguard Worker if (!mHasMultiDisplaySupport && mPhysicalDisplayIdMap.size() == 2) {
1126*38e8c45fSAndroid Build Coastguard Worker ALOGE("Ignoring connection of tertiary display %" PRIu64, hwcDisplayId);
1127*38e8c45fSAndroid Build Coastguard Worker return true;
1128*38e8c45fSAndroid Build Coastguard Worker }
1129*38e8c45fSAndroid Build Coastguard Worker
1130*38e8c45fSAndroid Build Coastguard Worker return false;
1131*38e8c45fSAndroid Build Coastguard Worker }
1132*38e8c45fSAndroid Build Coastguard Worker
onHotplugConnect(hal::HWDisplayId hwcDisplayId)1133*38e8c45fSAndroid Build Coastguard Worker std::optional<DisplayIdentificationInfo> HWComposer::onHotplugConnect(
1134*38e8c45fSAndroid Build Coastguard Worker hal::HWDisplayId hwcDisplayId) {
1135*38e8c45fSAndroid Build Coastguard Worker std::optional<DisplayIdentificationInfo> info;
1136*38e8c45fSAndroid Build Coastguard Worker if (const auto displayId = toPhysicalDisplayId(hwcDisplayId)) {
1137*38e8c45fSAndroid Build Coastguard Worker info = DisplayIdentificationInfo{.id = *displayId,
1138*38e8c45fSAndroid Build Coastguard Worker .name = std::string(),
1139*38e8c45fSAndroid Build Coastguard Worker .deviceProductInfo = std::nullopt};
1140*38e8c45fSAndroid Build Coastguard Worker if (mUpdateDeviceProductInfoOnHotplugReconnect) {
1141*38e8c45fSAndroid Build Coastguard Worker uint8_t port;
1142*38e8c45fSAndroid Build Coastguard Worker DisplayIdentificationData data;
1143*38e8c45fSAndroid Build Coastguard Worker getDisplayIdentificationData(hwcDisplayId, &port, &data);
1144*38e8c45fSAndroid Build Coastguard Worker if (auto newInfo = parseDisplayIdentificationData(port, data)) {
1145*38e8c45fSAndroid Build Coastguard Worker info->deviceProductInfo = std::move(newInfo->deviceProductInfo);
1146*38e8c45fSAndroid Build Coastguard Worker info->preferredDetailedTimingDescriptor =
1147*38e8c45fSAndroid Build Coastguard Worker std::move(newInfo->preferredDetailedTimingDescriptor);
1148*38e8c45fSAndroid Build Coastguard Worker } else {
1149*38e8c45fSAndroid Build Coastguard Worker ALOGE("Failed to parse identification data for display %" PRIu64, hwcDisplayId);
1150*38e8c45fSAndroid Build Coastguard Worker }
1151*38e8c45fSAndroid Build Coastguard Worker }
1152*38e8c45fSAndroid Build Coastguard Worker } else {
1153*38e8c45fSAndroid Build Coastguard Worker uint8_t port;
1154*38e8c45fSAndroid Build Coastguard Worker DisplayIdentificationData data;
1155*38e8c45fSAndroid Build Coastguard Worker const bool hasDisplayIdentificationData =
1156*38e8c45fSAndroid Build Coastguard Worker getDisplayIdentificationData(hwcDisplayId, &port, &data);
1157*38e8c45fSAndroid Build Coastguard Worker if (mPhysicalDisplayIdMap.empty()) {
1158*38e8c45fSAndroid Build Coastguard Worker mHasMultiDisplaySupport = hasDisplayIdentificationData;
1159*38e8c45fSAndroid Build Coastguard Worker ALOGI("Switching to %s multi-display mode",
1160*38e8c45fSAndroid Build Coastguard Worker mHasMultiDisplaySupport ? "generalized" : "legacy");
1161*38e8c45fSAndroid Build Coastguard Worker }
1162*38e8c45fSAndroid Build Coastguard Worker
1163*38e8c45fSAndroid Build Coastguard Worker if (shouldIgnoreHotplugConnect(hwcDisplayId, hasDisplayIdentificationData)) {
1164*38e8c45fSAndroid Build Coastguard Worker return {};
1165*38e8c45fSAndroid Build Coastguard Worker }
1166*38e8c45fSAndroid Build Coastguard Worker
1167*38e8c45fSAndroid Build Coastguard Worker info = [this, hwcDisplayId, &port, &data, hasDisplayIdentificationData] {
1168*38e8c45fSAndroid Build Coastguard Worker const bool isPrimary = !mPrimaryHwcDisplayId;
1169*38e8c45fSAndroid Build Coastguard Worker if (mHasMultiDisplaySupport) {
1170*38e8c45fSAndroid Build Coastguard Worker if (const auto info = parseDisplayIdentificationData(port, data)) {
1171*38e8c45fSAndroid Build Coastguard Worker return *info;
1172*38e8c45fSAndroid Build Coastguard Worker }
1173*38e8c45fSAndroid Build Coastguard Worker ALOGE("Failed to parse identification data for display %" PRIu64, hwcDisplayId);
1174*38e8c45fSAndroid Build Coastguard Worker } else {
1175*38e8c45fSAndroid Build Coastguard Worker ALOGW_IF(hasDisplayIdentificationData,
1176*38e8c45fSAndroid Build Coastguard Worker "Ignoring identification data for display %" PRIu64, hwcDisplayId);
1177*38e8c45fSAndroid Build Coastguard Worker port = isPrimary ? LEGACY_DISPLAY_TYPE_PRIMARY : LEGACY_DISPLAY_TYPE_EXTERNAL;
1178*38e8c45fSAndroid Build Coastguard Worker }
1179*38e8c45fSAndroid Build Coastguard Worker
1180*38e8c45fSAndroid Build Coastguard Worker return DisplayIdentificationInfo{.id = PhysicalDisplayId::fromPort(port),
1181*38e8c45fSAndroid Build Coastguard Worker .name = isPrimary ? "Primary display"
1182*38e8c45fSAndroid Build Coastguard Worker : "Secondary display",
1183*38e8c45fSAndroid Build Coastguard Worker .deviceProductInfo = std::nullopt};
1184*38e8c45fSAndroid Build Coastguard Worker }();
1185*38e8c45fSAndroid Build Coastguard Worker
1186*38e8c45fSAndroid Build Coastguard Worker mComposer->onHotplugConnect(hwcDisplayId);
1187*38e8c45fSAndroid Build Coastguard Worker }
1188*38e8c45fSAndroid Build Coastguard Worker
1189*38e8c45fSAndroid Build Coastguard Worker if (!isConnected(info->id)) {
1190*38e8c45fSAndroid Build Coastguard Worker std::optional<ui::Size> size = std::nullopt;
1191*38e8c45fSAndroid Build Coastguard Worker if (info->preferredDetailedTimingDescriptor) {
1192*38e8c45fSAndroid Build Coastguard Worker size = info->preferredDetailedTimingDescriptor->physicalSizeInMm;
1193*38e8c45fSAndroid Build Coastguard Worker }
1194*38e8c45fSAndroid Build Coastguard Worker allocatePhysicalDisplay(hwcDisplayId, info->id, size);
1195*38e8c45fSAndroid Build Coastguard Worker }
1196*38e8c45fSAndroid Build Coastguard Worker return info;
1197*38e8c45fSAndroid Build Coastguard Worker }
1198*38e8c45fSAndroid Build Coastguard Worker
onHotplugDisconnect(hal::HWDisplayId hwcDisplayId)1199*38e8c45fSAndroid Build Coastguard Worker std::optional<DisplayIdentificationInfo> HWComposer::onHotplugDisconnect(
1200*38e8c45fSAndroid Build Coastguard Worker hal::HWDisplayId hwcDisplayId) {
1201*38e8c45fSAndroid Build Coastguard Worker LOG_ALWAYS_FATAL_IF(hwcDisplayId == mPrimaryHwcDisplayId,
1202*38e8c45fSAndroid Build Coastguard Worker "Primary display cannot be disconnected.");
1203*38e8c45fSAndroid Build Coastguard Worker
1204*38e8c45fSAndroid Build Coastguard Worker const auto displayId = toPhysicalDisplayId(hwcDisplayId);
1205*38e8c45fSAndroid Build Coastguard Worker if (!displayId) {
1206*38e8c45fSAndroid Build Coastguard Worker LOG_HWC_DISPLAY_ERROR(hwcDisplayId, "Invalid HWC display");
1207*38e8c45fSAndroid Build Coastguard Worker return {};
1208*38e8c45fSAndroid Build Coastguard Worker }
1209*38e8c45fSAndroid Build Coastguard Worker
1210*38e8c45fSAndroid Build Coastguard Worker if (!isConnected(*displayId)) {
1211*38e8c45fSAndroid Build Coastguard Worker LOG_HWC_DISPLAY_ERROR(hwcDisplayId, "Already disconnected");
1212*38e8c45fSAndroid Build Coastguard Worker return {};
1213*38e8c45fSAndroid Build Coastguard Worker }
1214*38e8c45fSAndroid Build Coastguard Worker
1215*38e8c45fSAndroid Build Coastguard Worker // The display will later be destroyed by a call to HWComposer::disconnectDisplay. For now, mark
1216*38e8c45fSAndroid Build Coastguard Worker // it as disconnected.
1217*38e8c45fSAndroid Build Coastguard Worker mDisplayData.at(*displayId).hwcDisplay->setConnected(false);
1218*38e8c45fSAndroid Build Coastguard Worker mComposer->onHotplugDisconnect(hwcDisplayId);
1219*38e8c45fSAndroid Build Coastguard Worker return DisplayIdentificationInfo{.id = *displayId};
1220*38e8c45fSAndroid Build Coastguard Worker }
1221*38e8c45fSAndroid Build Coastguard Worker
loadCapabilities()1222*38e8c45fSAndroid Build Coastguard Worker void HWComposer::loadCapabilities() {
1223*38e8c45fSAndroid Build Coastguard Worker static_assert(sizeof(hal::Capability) == sizeof(int32_t), "Capability size has changed");
1224*38e8c45fSAndroid Build Coastguard Worker auto capabilities = mComposer->getCapabilities();
1225*38e8c45fSAndroid Build Coastguard Worker for (auto capability : capabilities) {
1226*38e8c45fSAndroid Build Coastguard Worker mCapabilities.emplace(capability);
1227*38e8c45fSAndroid Build Coastguard Worker }
1228*38e8c45fSAndroid Build Coastguard Worker }
1229*38e8c45fSAndroid Build Coastguard Worker
loadOverlayProperties()1230*38e8c45fSAndroid Build Coastguard Worker void HWComposer::loadOverlayProperties() {
1231*38e8c45fSAndroid Build Coastguard Worker mComposer->getOverlaySupport(&mOverlayProperties);
1232*38e8c45fSAndroid Build Coastguard Worker }
1233*38e8c45fSAndroid Build Coastguard Worker
loadHdrConversionCapabilities()1234*38e8c45fSAndroid Build Coastguard Worker void HWComposer::loadHdrConversionCapabilities() {
1235*38e8c45fSAndroid Build Coastguard Worker const auto error = mComposer->getHdrConversionCapabilities(&mHdrConversionCapabilities);
1236*38e8c45fSAndroid Build Coastguard Worker if (error != hal::Error::NONE) {
1237*38e8c45fSAndroid Build Coastguard Worker ALOGE("Error in fetching HDR conversion capabilities %s", to_string(error).c_str());
1238*38e8c45fSAndroid Build Coastguard Worker mHdrConversionCapabilities = {};
1239*38e8c45fSAndroid Build Coastguard Worker }
1240*38e8c45fSAndroid Build Coastguard Worker }
1241*38e8c45fSAndroid Build Coastguard Worker
setIdleTimerEnabled(PhysicalDisplayId displayId,std::chrono::milliseconds timeout)1242*38e8c45fSAndroid Build Coastguard Worker status_t HWComposer::setIdleTimerEnabled(PhysicalDisplayId displayId,
1243*38e8c45fSAndroid Build Coastguard Worker std::chrono::milliseconds timeout) {
1244*38e8c45fSAndroid Build Coastguard Worker SFTRACE_CALL();
1245*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
1246*38e8c45fSAndroid Build Coastguard Worker const auto error = mDisplayData[displayId].hwcDisplay->setIdleTimerEnabled(timeout);
1247*38e8c45fSAndroid Build Coastguard Worker if (error == hal::Error::UNSUPPORTED) {
1248*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
1249*38e8c45fSAndroid Build Coastguard Worker }
1250*38e8c45fSAndroid Build Coastguard Worker if (error == hal::Error::BAD_PARAMETER) {
1251*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
1252*38e8c45fSAndroid Build Coastguard Worker }
1253*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
1254*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
1255*38e8c45fSAndroid Build Coastguard Worker }
1256*38e8c45fSAndroid Build Coastguard Worker
hasDisplayIdleTimerCapability(PhysicalDisplayId displayId) const1257*38e8c45fSAndroid Build Coastguard Worker bool HWComposer::hasDisplayIdleTimerCapability(PhysicalDisplayId displayId) const {
1258*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, false);
1259*38e8c45fSAndroid Build Coastguard Worker return mDisplayData.at(displayId).hwcDisplay->hasDisplayIdleTimerCapability();
1260*38e8c45fSAndroid Build Coastguard Worker }
1261*38e8c45fSAndroid Build Coastguard Worker
getPhysicalDisplayOrientation(PhysicalDisplayId displayId) const1262*38e8c45fSAndroid Build Coastguard Worker Hwc2::AidlTransform HWComposer::getPhysicalDisplayOrientation(PhysicalDisplayId displayId) const {
1263*38e8c45fSAndroid Build Coastguard Worker SFTRACE_CALL();
1264*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_INVALID_DISPLAY(displayId, Hwc2::AidlTransform::NONE);
1265*38e8c45fSAndroid Build Coastguard Worker Hwc2::AidlTransform outTransform;
1266*38e8c45fSAndroid Build Coastguard Worker const auto& hwcDisplay = mDisplayData.at(displayId).hwcDisplay;
1267*38e8c45fSAndroid Build Coastguard Worker const auto error = hwcDisplay->getPhysicalDisplayOrientation(&outTransform);
1268*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_HWC_ERROR(error, displayId, Hwc2::AidlTransform::NONE);
1269*38e8c45fSAndroid Build Coastguard Worker return outTransform;
1270*38e8c45fSAndroid Build Coastguard Worker }
1271*38e8c45fSAndroid Build Coastguard Worker
loadLayerMetadataSupport()1272*38e8c45fSAndroid Build Coastguard Worker void HWComposer::loadLayerMetadataSupport() {
1273*38e8c45fSAndroid Build Coastguard Worker mSupportedLayerGenericMetadata.clear();
1274*38e8c45fSAndroid Build Coastguard Worker
1275*38e8c45fSAndroid Build Coastguard Worker std::vector<Hwc2::IComposerClient::LayerGenericMetadataKey> supportedMetadataKeyInfo;
1276*38e8c45fSAndroid Build Coastguard Worker const auto error = mComposer->getLayerGenericMetadataKeys(&supportedMetadataKeyInfo);
1277*38e8c45fSAndroid Build Coastguard Worker if (error != hardware::graphics::composer::V2_4::Error::NONE) {
1278*38e8c45fSAndroid Build Coastguard Worker if (error != hardware::graphics::composer::V2_4::Error::UNSUPPORTED) {
1279*38e8c45fSAndroid Build Coastguard Worker ALOGE("%s: %s failed: %s (%d)", __FUNCTION__, "getLayerGenericMetadataKeys",
1280*38e8c45fSAndroid Build Coastguard Worker toString(error).c_str(), static_cast<int32_t>(error));
1281*38e8c45fSAndroid Build Coastguard Worker }
1282*38e8c45fSAndroid Build Coastguard Worker return;
1283*38e8c45fSAndroid Build Coastguard Worker }
1284*38e8c45fSAndroid Build Coastguard Worker
1285*38e8c45fSAndroid Build Coastguard Worker for (const auto& [name, mandatory] : supportedMetadataKeyInfo) {
1286*38e8c45fSAndroid Build Coastguard Worker mSupportedLayerGenericMetadata.emplace(name, mandatory);
1287*38e8c45fSAndroid Build Coastguard Worker }
1288*38e8c45fSAndroid Build Coastguard Worker }
1289*38e8c45fSAndroid Build Coastguard Worker
1290*38e8c45fSAndroid Build Coastguard Worker } // namespace impl
1291*38e8c45fSAndroid Build Coastguard Worker } // namespace android
1292*38e8c45fSAndroid Build Coastguard Worker
1293*38e8c45fSAndroid Build Coastguard Worker // TODO(b/129481165): remove the #pragma below and fix conversion issues
1294*38e8c45fSAndroid Build Coastguard Worker #pragma clang diagnostic pop // ignored "-Wconversion"
1295