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