• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #pragma clang diagnostic push
19 #pragma clang diagnostic ignored "-Wconversion"
20 
21 // #define LOG_NDEBUG 0
22 
23 #undef LOG_TAG
24 #define LOG_TAG "HWComposer"
25 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
26 
27 #include "HWComposer.h"
28 
29 #include <android-base/properties.h>
30 #include <compositionengine/Output.h>
31 #include <compositionengine/OutputLayer.h>
32 #include <compositionengine/impl/OutputLayerCompositionState.h>
33 #include <ftl/concat.h>
34 #include <log/log.h>
35 #include <ui/DebugUtils.h>
36 #include <ui/GraphicBuffer.h>
37 #include <utils/Errors.h>
38 #include <utils/Trace.h>
39 
40 #include "../Layer.h" // needed only for debugging
41 #include "../SurfaceFlingerProperties.h"
42 #include "ComposerHal.h"
43 #include "HWC2.h"
44 
45 #define LOG_HWC_DISPLAY_ERROR(hwcDisplayId, msg) \
46     ALOGE("%s failed for HWC display %" PRIu64 ": %s", __FUNCTION__, hwcDisplayId, msg)
47 
48 #define LOG_DISPLAY_ERROR(displayId, msg) \
49     ALOGE("%s failed for display %s: %s", __FUNCTION__, to_string(displayId).c_str(), msg)
50 
51 #define LOG_HWC_ERROR(what, error, displayId)                          \
52     ALOGE("%s: %s failed for display %s: %s (%d)", __FUNCTION__, what, \
53           to_string(displayId).c_str(), to_string(error).c_str(), static_cast<int32_t>(error))
54 
55 #define RETURN_IF_INVALID_DISPLAY(displayId, ...)            \
56     do {                                                     \
57         if (mDisplayData.count(displayId) == 0) {            \
58             LOG_DISPLAY_ERROR(displayId, "Invalid display"); \
59             return __VA_ARGS__;                              \
60         }                                                    \
61     } while (false)
62 
63 #define RETURN_IF_HWC_ERROR_FOR(what, error, displayId, ...) \
64     do {                                                     \
65         if (error != hal::Error::NONE) {                     \
66             LOG_HWC_ERROR(what, error, displayId);           \
67             return __VA_ARGS__;                              \
68         }                                                    \
69     } while (false)
70 
71 #define RETURN_IF_HWC_ERROR(error, displayId, ...) \
72     RETURN_IF_HWC_ERROR_FOR(__FUNCTION__, error, displayId, __VA_ARGS__)
73 
74 using aidl::android::hardware::graphics::common::HdrConversionCapability;
75 using aidl::android::hardware::graphics::common::HdrConversionStrategy;
76 using aidl::android::hardware::graphics::composer3::Capability;
77 using aidl::android::hardware::graphics::composer3::DisplayCapability;
78 namespace hal = android::hardware::graphics::composer::hal;
79 
80 namespace android {
81 
82 HWComposer::~HWComposer() = default;
83 
84 namespace impl {
85 
HWComposer(std::unique_ptr<Hwc2::Composer> composer)86 HWComposer::HWComposer(std::unique_ptr<Hwc2::Composer> composer)
87       : mComposer(std::move(composer)),
88         mMaxVirtualDisplayDimension(static_cast<size_t>(sysprop::max_virtual_display_dimension(0))),
89         mUpdateDeviceProductInfoOnHotplugReconnect(
90                 sysprop::update_device_product_info_on_hotplug_reconnect(false)) {}
91 
HWComposer(const std::string & composerServiceName)92 HWComposer::HWComposer(const std::string& composerServiceName)
93       : HWComposer(Hwc2::Composer::create(composerServiceName)) {}
94 
~HWComposer()95 HWComposer::~HWComposer() {
96     mDisplayData.clear();
97 }
98 
setCallback(HWC2::ComposerCallback & callback)99 void HWComposer::setCallback(HWC2::ComposerCallback& callback) {
100     loadCapabilities();
101     loadLayerMetadataSupport();
102     loadOverlayProperties();
103     loadHdrConversionCapabilities();
104 
105     if (mRegisteredCallback) {
106         ALOGW("Callback already registered. Ignored extra registration attempt.");
107         return;
108     }
109     mRegisteredCallback = true;
110 
111     mComposer->registerCallback(callback);
112 }
113 
getDisplayIdentificationData(hal::HWDisplayId hwcDisplayId,uint8_t * outPort,DisplayIdentificationData * outData) const114 bool HWComposer::getDisplayIdentificationData(hal::HWDisplayId hwcDisplayId, uint8_t* outPort,
115                                               DisplayIdentificationData* outData) const {
116     const auto error = static_cast<hal::Error>(
117             mComposer->getDisplayIdentificationData(hwcDisplayId, outPort, outData));
118     if (error != hal::Error::NONE) {
119         if (error != hal::Error::UNSUPPORTED) {
120             LOG_HWC_DISPLAY_ERROR(hwcDisplayId, to_string(error).c_str());
121         }
122         return false;
123     }
124     return true;
125 }
126 
hasCapability(Capability capability) const127 bool HWComposer::hasCapability(Capability capability) const {
128     return mCapabilities.count(capability) > 0;
129 }
130 
hasDisplayCapability(HalDisplayId displayId,DisplayCapability capability) const131 bool HWComposer::hasDisplayCapability(HalDisplayId displayId, DisplayCapability capability) const {
132     RETURN_IF_INVALID_DISPLAY(displayId, false);
133     return mDisplayData.at(displayId).hwcDisplay->hasCapability(capability);
134 }
135 
onHotplug(hal::HWDisplayId hwcDisplayId,hal::Connection connection)136 std::optional<DisplayIdentificationInfo> HWComposer::onHotplug(hal::HWDisplayId hwcDisplayId,
137                                                                hal::Connection connection) {
138     switch (connection) {
139         case hal::Connection::CONNECTED:
140             return onHotplugConnect(hwcDisplayId);
141         case hal::Connection::DISCONNECTED:
142             return onHotplugDisconnect(hwcDisplayId);
143         case hal::Connection::INVALID:
144             return {};
145     }
146 }
147 
updatesDeviceProductInfoOnHotplugReconnect() const148 bool HWComposer::updatesDeviceProductInfoOnHotplugReconnect() const {
149     return mUpdateDeviceProductInfoOnHotplugReconnect;
150 }
151 
onVsync(hal::HWDisplayId hwcDisplayId,nsecs_t timestamp)152 std::optional<PhysicalDisplayId> HWComposer::onVsync(hal::HWDisplayId hwcDisplayId,
153                                                      nsecs_t timestamp) {
154     const auto displayIdOpt = toPhysicalDisplayId(hwcDisplayId);
155     if (!displayIdOpt) {
156         LOG_HWC_DISPLAY_ERROR(hwcDisplayId, "Invalid HWC display");
157         return {};
158     }
159 
160     RETURN_IF_INVALID_DISPLAY(*displayIdOpt, {});
161 
162     auto& displayData = mDisplayData[*displayIdOpt];
163 
164     {
165         // There have been reports of HWCs that signal several vsync events
166         // with the same timestamp when turning the display off and on. This
167         // is a bug in the HWC implementation, but filter the extra events
168         // out here so they don't cause havoc downstream.
169         if (timestamp == displayData.lastPresentTimestamp) {
170             ALOGW("Ignoring duplicate VSYNC event from HWC for display %s (t=%" PRId64 ")",
171                   to_string(*displayIdOpt).c_str(), timestamp);
172             return {};
173         }
174 
175         displayData.lastPresentTimestamp = timestamp;
176     }
177 
178     ATRACE_INT(ftl::Concat("HW_VSYNC_", displayIdOpt->value).c_str(),
179                displayData.vsyncTraceToggle);
180     displayData.vsyncTraceToggle = !displayData.vsyncTraceToggle;
181 
182     return displayIdOpt;
183 }
184 
getMaxVirtualDisplayCount() const185 size_t HWComposer::getMaxVirtualDisplayCount() const {
186     return mComposer->getMaxVirtualDisplayCount();
187 }
188 
getMaxVirtualDisplayDimension() const189 size_t HWComposer::getMaxVirtualDisplayDimension() const {
190     return mMaxVirtualDisplayDimension;
191 }
192 
allocateVirtualDisplay(HalVirtualDisplayId displayId,ui::Size resolution,ui::PixelFormat * format)193 bool HWComposer::allocateVirtualDisplay(HalVirtualDisplayId displayId, ui::Size resolution,
194                                         ui::PixelFormat* format) {
195     if (!resolution.isValid()) {
196         ALOGE("%s: Invalid resolution %dx%d", __func__, resolution.width, resolution.height);
197         return false;
198     }
199 
200     const uint32_t width = static_cast<uint32_t>(resolution.width);
201     const uint32_t height = static_cast<uint32_t>(resolution.height);
202 
203     if (mMaxVirtualDisplayDimension > 0 &&
204         (width > mMaxVirtualDisplayDimension || height > mMaxVirtualDisplayDimension)) {
205         ALOGE("%s: Resolution %ux%u exceeds maximum dimension %zu", __func__, width, height,
206               mMaxVirtualDisplayDimension);
207         return false;
208     }
209 
210     hal::HWDisplayId hwcDisplayId;
211     const auto error = static_cast<hal::Error>(
212             mComposer->createVirtualDisplay(width, height, format, &hwcDisplayId));
213     RETURN_IF_HWC_ERROR_FOR("createVirtualDisplay", error, displayId, false);
214 
215     auto display = std::make_unique<HWC2::impl::Display>(*mComposer.get(), mCapabilities,
216                                                          hwcDisplayId, hal::DisplayType::VIRTUAL);
217     display->setConnected(true);
218     auto& displayData = mDisplayData[displayId];
219     displayData.hwcDisplay = std::move(display);
220     return true;
221 }
222 
allocatePhysicalDisplay(hal::HWDisplayId hwcDisplayId,PhysicalDisplayId displayId)223 void HWComposer::allocatePhysicalDisplay(hal::HWDisplayId hwcDisplayId,
224                                          PhysicalDisplayId displayId) {
225     mPhysicalDisplayIdMap[hwcDisplayId] = displayId;
226 
227     if (!mPrimaryHwcDisplayId) {
228         mPrimaryHwcDisplayId = hwcDisplayId;
229     }
230 
231     auto& displayData = mDisplayData[displayId];
232     auto newDisplay =
233             std::make_unique<HWC2::impl::Display>(*mComposer.get(), mCapabilities, hwcDisplayId,
234                                                   hal::DisplayType::PHYSICAL);
235     newDisplay->setConnected(true);
236     displayData.hwcDisplay = std::move(newDisplay);
237 }
238 
getAttribute(hal::HWDisplayId hwcDisplayId,hal::HWConfigId configId,hal::Attribute attribute) const239 int32_t HWComposer::getAttribute(hal::HWDisplayId hwcDisplayId, hal::HWConfigId configId,
240                                  hal::Attribute attribute) const {
241     int32_t value = 0;
242     auto error = static_cast<hal::Error>(
243             mComposer->getDisplayAttribute(hwcDisplayId, configId, attribute, &value));
244 
245     RETURN_IF_HWC_ERROR_FOR("getDisplayAttribute", error, *toPhysicalDisplayId(hwcDisplayId), -1);
246     return value;
247 }
248 
createLayer(HalDisplayId displayId)249 std::shared_ptr<HWC2::Layer> HWComposer::createLayer(HalDisplayId displayId) {
250     RETURN_IF_INVALID_DISPLAY(displayId, nullptr);
251 
252     auto expected = mDisplayData[displayId].hwcDisplay->createLayer();
253     if (!expected.has_value()) {
254         auto error = std::move(expected).error();
255         RETURN_IF_HWC_ERROR(error, displayId, nullptr);
256     }
257     return std::move(expected).value();
258 }
259 
isConnected(PhysicalDisplayId displayId) const260 bool HWComposer::isConnected(PhysicalDisplayId displayId) const {
261     return mDisplayData.count(displayId) && mDisplayData.at(displayId).hwcDisplay->isConnected();
262 }
263 
getModes(PhysicalDisplayId displayId) const264 std::vector<HWComposer::HWCDisplayMode> HWComposer::getModes(PhysicalDisplayId displayId) const {
265     RETURN_IF_INVALID_DISPLAY(displayId, {});
266 
267     const auto hwcDisplayId = mDisplayData.at(displayId).hwcDisplay->getId();
268     std::vector<hal::HWConfigId> configIds;
269     auto error = static_cast<hal::Error>(mComposer->getDisplayConfigs(hwcDisplayId, &configIds));
270     RETURN_IF_HWC_ERROR_FOR("getDisplayConfigs", error, *toPhysicalDisplayId(hwcDisplayId), {});
271 
272     std::vector<HWCDisplayMode> modes;
273     modes.reserve(configIds.size());
274     for (auto configId : configIds) {
275         modes.push_back(HWCDisplayMode{
276                 .hwcId = configId,
277                 .width = getAttribute(hwcDisplayId, configId, hal::Attribute::WIDTH),
278                 .height = getAttribute(hwcDisplayId, configId, hal::Attribute::HEIGHT),
279                 .vsyncPeriod = getAttribute(hwcDisplayId, configId, hal::Attribute::VSYNC_PERIOD),
280                 .dpiX = getAttribute(hwcDisplayId, configId, hal::Attribute::DPI_X),
281                 .dpiY = getAttribute(hwcDisplayId, configId, hal::Attribute::DPI_Y),
282                 .configGroup = getAttribute(hwcDisplayId, configId, hal::Attribute::CONFIG_GROUP),
283         });
284     }
285 
286     return modes;
287 }
288 
getActiveMode(PhysicalDisplayId displayId) const289 std::optional<hal::HWConfigId> HWComposer::getActiveMode(PhysicalDisplayId displayId) const {
290     RETURN_IF_INVALID_DISPLAY(displayId, std::nullopt);
291     const auto hwcId = *fromPhysicalDisplayId(displayId);
292 
293     hal::HWConfigId configId;
294     const auto error = static_cast<hal::Error>(mComposer->getActiveConfig(hwcId, &configId));
295 
296     RETURN_IF_HWC_ERROR_FOR("getActiveConfig", error, displayId, std::nullopt);
297     return configId;
298 }
299 
300 // Composer 2.4
301 
getDisplayConnectionType(PhysicalDisplayId displayId) const302 ui::DisplayConnectionType HWComposer::getDisplayConnectionType(PhysicalDisplayId displayId) const {
303     RETURN_IF_INVALID_DISPLAY(displayId, ui::DisplayConnectionType::Internal);
304     const auto& hwcDisplay = mDisplayData.at(displayId).hwcDisplay;
305 
306     ui::DisplayConnectionType type;
307     const auto error = hwcDisplay->getConnectionType(&type);
308 
309     const auto FALLBACK_TYPE = hwcDisplay->getId() == mPrimaryHwcDisplayId
310             ? ui::DisplayConnectionType::Internal
311             : ui::DisplayConnectionType::External;
312 
313     RETURN_IF_HWC_ERROR(error, displayId, FALLBACK_TYPE);
314     return type;
315 }
316 
isVsyncPeriodSwitchSupported(PhysicalDisplayId displayId) const317 bool HWComposer::isVsyncPeriodSwitchSupported(PhysicalDisplayId displayId) const {
318     RETURN_IF_INVALID_DISPLAY(displayId, false);
319     return mDisplayData.at(displayId).hwcDisplay->isVsyncPeriodSwitchSupported();
320 }
321 
getDisplayVsyncPeriod(PhysicalDisplayId displayId,nsecs_t * outVsyncPeriod) const322 status_t HWComposer::getDisplayVsyncPeriod(PhysicalDisplayId displayId,
323                                            nsecs_t* outVsyncPeriod) const {
324     RETURN_IF_INVALID_DISPLAY(displayId, 0);
325 
326     if (!isVsyncPeriodSwitchSupported(displayId)) {
327         return INVALID_OPERATION;
328     }
329     const auto hwcId = *fromPhysicalDisplayId(displayId);
330     Hwc2::VsyncPeriodNanos vsyncPeriodNanos = 0;
331     auto error =
332             static_cast<hal::Error>(mComposer->getDisplayVsyncPeriod(hwcId, &vsyncPeriodNanos));
333     RETURN_IF_HWC_ERROR(error, displayId, 0);
334     *outVsyncPeriod = static_cast<nsecs_t>(vsyncPeriodNanos);
335     return NO_ERROR;
336 }
337 
getColorModes(PhysicalDisplayId displayId) const338 std::vector<ui::ColorMode> HWComposer::getColorModes(PhysicalDisplayId displayId) const {
339     RETURN_IF_INVALID_DISPLAY(displayId, {});
340 
341     std::vector<ui::ColorMode> modes;
342     auto error = mDisplayData.at(displayId).hwcDisplay->getColorModes(&modes);
343     RETURN_IF_HWC_ERROR(error, displayId, {});
344     return modes;
345 }
346 
setActiveColorMode(PhysicalDisplayId displayId,ui::ColorMode mode,ui::RenderIntent renderIntent)347 status_t HWComposer::setActiveColorMode(PhysicalDisplayId displayId, ui::ColorMode mode,
348                                         ui::RenderIntent renderIntent) {
349     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
350 
351     auto& displayData = mDisplayData[displayId];
352     auto error = displayData.hwcDisplay->setColorMode(mode, renderIntent);
353     RETURN_IF_HWC_ERROR_FOR(("setColorMode(" + decodeColorMode(mode) + ", " +
354                              decodeRenderIntent(renderIntent) + ")")
355                                     .c_str(),
356                             error, displayId, UNKNOWN_ERROR);
357 
358     return NO_ERROR;
359 }
360 
setVsyncEnabled(PhysicalDisplayId displayId,hal::Vsync enabled)361 void HWComposer::setVsyncEnabled(PhysicalDisplayId displayId, hal::Vsync enabled) {
362     RETURN_IF_INVALID_DISPLAY(displayId);
363     auto& displayData = mDisplayData[displayId];
364 
365     // NOTE: we use our own internal lock here because we have to call
366     // into the HWC with the lock held, and we want to make sure
367     // that even if HWC blocks (which it shouldn't), it won't
368     // affect other threads.
369     std::lock_guard lock(displayData.vsyncEnabledLock);
370     if (enabled == displayData.vsyncEnabled) {
371         return;
372     }
373 
374     ATRACE_CALL();
375     auto error = displayData.hwcDisplay->setVsyncEnabled(enabled);
376     RETURN_IF_HWC_ERROR(error, displayId);
377 
378     displayData.vsyncEnabled = enabled;
379 
380     ATRACE_INT(ftl::Concat("HW_VSYNC_ON_", displayId.value).c_str(),
381                enabled == hal::Vsync::ENABLE ? 1 : 0);
382 }
383 
setClientTarget(HalDisplayId displayId,uint32_t slot,const sp<Fence> & acquireFence,const sp<GraphicBuffer> & target,ui::Dataspace dataspace)384 status_t HWComposer::setClientTarget(HalDisplayId displayId, uint32_t slot,
385                                      const sp<Fence>& acquireFence, const sp<GraphicBuffer>& target,
386                                      ui::Dataspace dataspace) {
387     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
388 
389     ALOGV("%s for display %s", __FUNCTION__, to_string(displayId).c_str());
390     auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
391     auto error = hwcDisplay->setClientTarget(slot, target, acquireFence, dataspace);
392     RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
393     return NO_ERROR;
394 }
395 
getDeviceCompositionChanges(HalDisplayId displayId,bool frameUsesClientComposition,std::optional<std::chrono::steady_clock::time_point> earliestPresentTime,nsecs_t expectedPresentTime,std::optional<android::HWComposer::DeviceRequestedChanges> * outChanges)396 status_t HWComposer::getDeviceCompositionChanges(
397         HalDisplayId displayId, bool frameUsesClientComposition,
398         std::optional<std::chrono::steady_clock::time_point> earliestPresentTime,
399         nsecs_t expectedPresentTime,
400         std::optional<android::HWComposer::DeviceRequestedChanges>* outChanges) {
401     ATRACE_CALL();
402 
403     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
404 
405     auto& displayData = mDisplayData[displayId];
406     auto& hwcDisplay = displayData.hwcDisplay;
407     if (!hwcDisplay->isConnected()) {
408         return NO_ERROR;
409     }
410 
411     uint32_t numTypes = 0;
412     uint32_t numRequests = 0;
413 
414     hal::Error error = hal::Error::NONE;
415 
416     // First try to skip validate altogether. We can do that when
417     // 1. The previous frame has not been presented yet or already passed the
418     // earliest time to present. Otherwise, we may present a frame too early.
419     // 2. There is no client composition. Otherwise, we first need to render the
420     // client target buffer.
421     const bool canSkipValidate = [&] {
422         // We must call validate if we have client composition
423         if (frameUsesClientComposition) {
424             return false;
425         }
426 
427         // If composer supports getting the expected present time, we can skip
428         // as composer will make sure to prevent early presentation
429         if (!earliestPresentTime) {
430             return true;
431         }
432 
433         // composer doesn't support getting the expected present time. We can only
434         // skip validate if we know that we are not going to present early.
435         return std::chrono::steady_clock::now() >= *earliestPresentTime;
436     }();
437 
438     displayData.validateWasSkipped = false;
439     if (canSkipValidate) {
440         sp<Fence> outPresentFence;
441         uint32_t state = UINT32_MAX;
442         error = hwcDisplay->presentOrValidate(expectedPresentTime, &numTypes, &numRequests,
443                                               &outPresentFence, &state);
444         if (!hasChangesError(error)) {
445             RETURN_IF_HWC_ERROR_FOR("presentOrValidate", error, displayId, UNKNOWN_ERROR);
446         }
447         if (state == 1) { //Present Succeeded.
448             std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
449             error = hwcDisplay->getReleaseFences(&releaseFences);
450             displayData.releaseFences = std::move(releaseFences);
451             displayData.lastPresentFence = outPresentFence;
452             displayData.validateWasSkipped = true;
453             displayData.presentError = error;
454             return NO_ERROR;
455         }
456         // Present failed but Validate ran.
457     } else {
458         error = hwcDisplay->validate(expectedPresentTime, &numTypes, &numRequests);
459     }
460     ALOGV("SkipValidate failed, Falling back to SLOW validate/present");
461     if (!hasChangesError(error)) {
462         RETURN_IF_HWC_ERROR_FOR("validate", error, displayId, BAD_INDEX);
463     }
464 
465     android::HWComposer::DeviceRequestedChanges::ChangedTypes changedTypes;
466     changedTypes.reserve(numTypes);
467     error = hwcDisplay->getChangedCompositionTypes(&changedTypes);
468     RETURN_IF_HWC_ERROR_FOR("getChangedCompositionTypes", error, displayId, BAD_INDEX);
469 
470     auto displayRequests = static_cast<hal::DisplayRequest>(0);
471     android::HWComposer::DeviceRequestedChanges::LayerRequests layerRequests;
472     layerRequests.reserve(numRequests);
473     error = hwcDisplay->getRequests(&displayRequests, &layerRequests);
474     RETURN_IF_HWC_ERROR_FOR("getRequests", error, displayId, BAD_INDEX);
475 
476     DeviceRequestedChanges::ClientTargetProperty clientTargetProperty;
477     error = hwcDisplay->getClientTargetProperty(&clientTargetProperty);
478 
479     outChanges->emplace(DeviceRequestedChanges{std::move(changedTypes), std::move(displayRequests),
480                                                std::move(layerRequests),
481                                                std::move(clientTargetProperty)});
482     error = hwcDisplay->acceptChanges();
483     RETURN_IF_HWC_ERROR_FOR("acceptChanges", error, displayId, BAD_INDEX);
484 
485     return NO_ERROR;
486 }
487 
getPresentFence(HalDisplayId displayId) const488 sp<Fence> HWComposer::getPresentFence(HalDisplayId displayId) const {
489     RETURN_IF_INVALID_DISPLAY(displayId, Fence::NO_FENCE);
490     return mDisplayData.at(displayId).lastPresentFence;
491 }
492 
getPresentTimestamp(PhysicalDisplayId displayId) const493 nsecs_t HWComposer::getPresentTimestamp(PhysicalDisplayId displayId) const {
494     RETURN_IF_INVALID_DISPLAY(displayId, 0);
495     return mDisplayData.at(displayId).lastPresentTimestamp;
496 }
497 
getLayerReleaseFence(HalDisplayId displayId,HWC2::Layer * layer) const498 sp<Fence> HWComposer::getLayerReleaseFence(HalDisplayId displayId, HWC2::Layer* layer) const {
499     RETURN_IF_INVALID_DISPLAY(displayId, Fence::NO_FENCE);
500     const auto& displayFences = mDisplayData.at(displayId).releaseFences;
501     auto fence = displayFences.find(layer);
502     if (fence == displayFences.end()) {
503         ALOGV("getLayerReleaseFence: Release fence not found");
504         return Fence::NO_FENCE;
505     }
506     return fence->second;
507 }
508 
presentAndGetReleaseFences(HalDisplayId displayId,std::optional<std::chrono::steady_clock::time_point> earliestPresentTime)509 status_t HWComposer::presentAndGetReleaseFences(
510         HalDisplayId displayId,
511         std::optional<std::chrono::steady_clock::time_point> earliestPresentTime) {
512     ATRACE_CALL();
513 
514     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
515 
516     auto& displayData = mDisplayData[displayId];
517     auto& hwcDisplay = displayData.hwcDisplay;
518 
519     if (displayData.validateWasSkipped) {
520         // explicitly flush all pending commands
521         auto error = static_cast<hal::Error>(mComposer->executeCommands(hwcDisplay->getId()));
522         RETURN_IF_HWC_ERROR_FOR("executeCommands", error, displayId, UNKNOWN_ERROR);
523         RETURN_IF_HWC_ERROR_FOR("present", displayData.presentError, displayId, UNKNOWN_ERROR);
524         return NO_ERROR;
525     }
526 
527     if (earliestPresentTime) {
528         ATRACE_NAME("wait for earliest present time");
529         std::this_thread::sleep_until(*earliestPresentTime);
530     }
531 
532     auto error = hwcDisplay->present(&displayData.lastPresentFence);
533     RETURN_IF_HWC_ERROR_FOR("present", error, displayId, UNKNOWN_ERROR);
534 
535     std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
536     error = hwcDisplay->getReleaseFences(&releaseFences);
537     RETURN_IF_HWC_ERROR_FOR("getReleaseFences", error, displayId, UNKNOWN_ERROR);
538 
539     displayData.releaseFences = std::move(releaseFences);
540 
541     return NO_ERROR;
542 }
543 
setPowerMode(PhysicalDisplayId displayId,hal::PowerMode mode)544 status_t HWComposer::setPowerMode(PhysicalDisplayId displayId, hal::PowerMode mode) {
545     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
546 
547     if (mode == hal::PowerMode::OFF) {
548         setVsyncEnabled(displayId, hal::Vsync::DISABLE);
549     }
550 
551     const auto& displayData = mDisplayData[displayId];
552     auto& hwcDisplay = displayData.hwcDisplay;
553     switch (mode) {
554         case hal::PowerMode::OFF:
555         case hal::PowerMode::ON:
556             ALOGV("setPowerMode: Calling HWC %s", to_string(mode).c_str());
557             {
558                 auto error = hwcDisplay->setPowerMode(mode);
559                 if (error != hal::Error::NONE) {
560                     LOG_HWC_ERROR(("setPowerMode(" + to_string(mode) + ")").c_str(), error,
561                                   displayId);
562                 }
563             }
564             break;
565         case hal::PowerMode::DOZE:
566         case hal::PowerMode::DOZE_SUSPEND:
567             ALOGV("setPowerMode: Calling HWC %s", to_string(mode).c_str());
568             {
569                 bool supportsDoze = false;
570                 auto error = hwcDisplay->supportsDoze(&supportsDoze);
571                 if (error != hal::Error::NONE) {
572                     LOG_HWC_ERROR("supportsDoze", error, displayId);
573                 }
574 
575                 if (!supportsDoze) {
576                     mode = hal::PowerMode::ON;
577                 }
578 
579                 error = hwcDisplay->setPowerMode(mode);
580                 if (error != hal::Error::NONE) {
581                     LOG_HWC_ERROR(("setPowerMode(" + to_string(mode) + ")").c_str(), error,
582                                   displayId);
583                 }
584             }
585             break;
586         default:
587             ALOGV("setPowerMode: Not calling HWC");
588             break;
589     }
590 
591     return NO_ERROR;
592 }
593 
setActiveModeWithConstraints(PhysicalDisplayId displayId,hal::HWConfigId hwcModeId,const hal::VsyncPeriodChangeConstraints & constraints,hal::VsyncPeriodChangeTimeline * outTimeline)594 status_t HWComposer::setActiveModeWithConstraints(
595         PhysicalDisplayId displayId, hal::HWConfigId hwcModeId,
596         const hal::VsyncPeriodChangeConstraints& constraints,
597         hal::VsyncPeriodChangeTimeline* outTimeline) {
598     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
599 
600     auto error = mDisplayData[displayId].hwcDisplay->setActiveConfigWithConstraints(hwcModeId,
601                                                                                     constraints,
602                                                                                     outTimeline);
603     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
604     return NO_ERROR;
605 }
606 
setColorTransform(HalDisplayId displayId,const mat4 & transform)607 status_t HWComposer::setColorTransform(HalDisplayId displayId, const mat4& transform) {
608     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
609 
610     auto& displayData = mDisplayData[displayId];
611     auto error = displayData.hwcDisplay->setColorTransform(transform);
612     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
613     return NO_ERROR;
614 }
615 
disconnectDisplay(HalDisplayId displayId)616 void HWComposer::disconnectDisplay(HalDisplayId displayId) {
617     RETURN_IF_INVALID_DISPLAY(displayId);
618     auto& displayData = mDisplayData[displayId];
619     const auto hwcDisplayId = displayData.hwcDisplay->getId();
620 
621     mPhysicalDisplayIdMap.erase(hwcDisplayId);
622     mDisplayData.erase(displayId);
623 
624     // Reset the primary display ID if we're disconnecting it.
625     // This way isHeadless() will return false, which is necessary
626     // because getPrimaryDisplayId() will crash.
627     if (mPrimaryHwcDisplayId == hwcDisplayId) {
628         mPrimaryHwcDisplayId.reset();
629     }
630 }
631 
setOutputBuffer(HalVirtualDisplayId displayId,const sp<Fence> & acquireFence,const sp<GraphicBuffer> & buffer)632 status_t HWComposer::setOutputBuffer(HalVirtualDisplayId displayId, const sp<Fence>& acquireFence,
633                                      const sp<GraphicBuffer>& buffer) {
634     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
635     const auto& displayData = mDisplayData[displayId];
636 
637     auto error = displayData.hwcDisplay->setOutputBuffer(buffer, acquireFence);
638     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
639     return NO_ERROR;
640 }
641 
clearReleaseFences(HalDisplayId displayId)642 void HWComposer::clearReleaseFences(HalDisplayId displayId) {
643     RETURN_IF_INVALID_DISPLAY(displayId);
644     mDisplayData[displayId].releaseFences.clear();
645 }
646 
getHdrCapabilities(HalDisplayId displayId,HdrCapabilities * outCapabilities)647 status_t HWComposer::getHdrCapabilities(HalDisplayId displayId, HdrCapabilities* outCapabilities) {
648     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
649 
650     auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
651     auto error = hwcDisplay->getHdrCapabilities(outCapabilities);
652     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
653     return NO_ERROR;
654 }
655 
656 const aidl::android::hardware::graphics::composer3::OverlayProperties&
getOverlaySupport() const657 HWComposer::getOverlaySupport() const {
658     return mOverlayProperties;
659 }
660 
getSupportedPerFrameMetadata(HalDisplayId displayId) const661 int32_t HWComposer::getSupportedPerFrameMetadata(HalDisplayId displayId) const {
662     RETURN_IF_INVALID_DISPLAY(displayId, 0);
663     return mDisplayData.at(displayId).hwcDisplay->getSupportedPerFrameMetadata();
664 }
665 
getRenderIntents(HalDisplayId displayId,ui::ColorMode colorMode) const666 std::vector<ui::RenderIntent> HWComposer::getRenderIntents(HalDisplayId displayId,
667                                                            ui::ColorMode colorMode) const {
668     RETURN_IF_INVALID_DISPLAY(displayId, {});
669 
670     std::vector<ui::RenderIntent> renderIntents;
671     auto error = mDisplayData.at(displayId).hwcDisplay->getRenderIntents(colorMode, &renderIntents);
672     RETURN_IF_HWC_ERROR(error, displayId, {});
673     return renderIntents;
674 }
675 
getDataspaceSaturationMatrix(HalDisplayId displayId,ui::Dataspace dataspace)676 mat4 HWComposer::getDataspaceSaturationMatrix(HalDisplayId displayId, ui::Dataspace dataspace) {
677     RETURN_IF_INVALID_DISPLAY(displayId, {});
678 
679     mat4 matrix;
680     auto error = mDisplayData[displayId].hwcDisplay->getDataspaceSaturationMatrix(dataspace,
681             &matrix);
682     RETURN_IF_HWC_ERROR(error, displayId, {});
683     return matrix;
684 }
685 
getDisplayedContentSamplingAttributes(HalDisplayId displayId,ui::PixelFormat * outFormat,ui::Dataspace * outDataspace,uint8_t * outComponentMask)686 status_t HWComposer::getDisplayedContentSamplingAttributes(HalDisplayId displayId,
687                                                            ui::PixelFormat* outFormat,
688                                                            ui::Dataspace* outDataspace,
689                                                            uint8_t* outComponentMask) {
690     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
691     const auto error =
692             mDisplayData[displayId]
693                     .hwcDisplay->getDisplayedContentSamplingAttributes(outFormat, outDataspace,
694                                                                        outComponentMask);
695     if (error == hal::Error::UNSUPPORTED) RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
696     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
697     return NO_ERROR;
698 }
699 
setDisplayContentSamplingEnabled(HalDisplayId displayId,bool enabled,uint8_t componentMask,uint64_t maxFrames)700 status_t HWComposer::setDisplayContentSamplingEnabled(HalDisplayId displayId, bool enabled,
701                                                       uint8_t componentMask, uint64_t maxFrames) {
702     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
703     const auto error =
704             mDisplayData[displayId].hwcDisplay->setDisplayContentSamplingEnabled(enabled,
705                                                                                  componentMask,
706                                                                                  maxFrames);
707 
708     if (error == hal::Error::UNSUPPORTED) RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
709     if (error == hal::Error::BAD_PARAMETER) RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
710     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
711     return NO_ERROR;
712 }
713 
getDisplayedContentSample(HalDisplayId displayId,uint64_t maxFrames,uint64_t timestamp,DisplayedFrameStats * outStats)714 status_t HWComposer::getDisplayedContentSample(HalDisplayId displayId, uint64_t maxFrames,
715                                                uint64_t timestamp, DisplayedFrameStats* outStats) {
716     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
717     const auto error =
718             mDisplayData[displayId].hwcDisplay->getDisplayedContentSample(maxFrames, timestamp,
719                                                                           outStats);
720     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
721     return NO_ERROR;
722 }
723 
setDisplayBrightness(PhysicalDisplayId displayId,float brightness,float brightnessNits,const Hwc2::Composer::DisplayBrightnessOptions & options)724 ftl::Future<status_t> HWComposer::setDisplayBrightness(
725         PhysicalDisplayId displayId, float brightness, float brightnessNits,
726         const Hwc2::Composer::DisplayBrightnessOptions& options) {
727     RETURN_IF_INVALID_DISPLAY(displayId, ftl::yield<status_t>(BAD_INDEX));
728     auto& display = mDisplayData[displayId].hwcDisplay;
729 
730     return display->setDisplayBrightness(brightness, brightnessNits, options)
731             .then([displayId](hal::Error error) -> status_t {
732                 if (error == hal::Error::UNSUPPORTED) {
733                     RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
734                 }
735                 if (error == hal::Error::BAD_PARAMETER) {
736                     RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
737                 }
738                 RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
739                 return NO_ERROR;
740             });
741 }
742 
getValidateSkipped(HalDisplayId displayId) const743 bool HWComposer::getValidateSkipped(HalDisplayId displayId) const {
744     if (mDisplayData.count(displayId) == 0) {
745         return false;
746     }
747     return mDisplayData.at(displayId).validateWasSkipped;
748 }
749 
setBootDisplayMode(PhysicalDisplayId displayId,hal::HWConfigId displayModeId)750 status_t HWComposer::setBootDisplayMode(PhysicalDisplayId displayId,
751                                         hal::HWConfigId displayModeId) {
752     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
753     const auto error = mDisplayData[displayId].hwcDisplay->setBootDisplayConfig(displayModeId);
754     if (error == hal::Error::UNSUPPORTED) {
755         RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
756     }
757     if (error == hal::Error::BAD_PARAMETER) {
758         RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
759     }
760     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
761     return NO_ERROR;
762 }
763 
clearBootDisplayMode(PhysicalDisplayId displayId)764 status_t HWComposer::clearBootDisplayMode(PhysicalDisplayId displayId) {
765     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
766     const auto error = mDisplayData[displayId].hwcDisplay->clearBootDisplayConfig();
767     if (error == hal::Error::UNSUPPORTED) {
768         RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
769     }
770     if (error == hal::Error::BAD_PARAMETER) {
771         RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
772     }
773     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
774     return NO_ERROR;
775 }
776 
getPreferredBootDisplayMode(PhysicalDisplayId displayId)777 std::optional<hal::HWConfigId> HWComposer::getPreferredBootDisplayMode(
778         PhysicalDisplayId displayId) {
779     RETURN_IF_INVALID_DISPLAY(displayId, std::nullopt);
780     hal::HWConfigId displayModeId;
781     const auto error =
782             mDisplayData[displayId].hwcDisplay->getPreferredBootDisplayConfig(&displayModeId);
783     if (error != hal::Error::NONE) {
784         LOG_DISPLAY_ERROR(displayId, to_string(error).c_str());
785         return std::nullopt;
786     }
787     return displayModeId;
788 }
789 
getHdrConversionCapabilities() const790 std::vector<HdrConversionCapability> HWComposer::getHdrConversionCapabilities() const {
791     return mHdrConversionCapabilities;
792 }
793 
setHdrConversionStrategy(HdrConversionStrategy hdrConversionStrategy,aidl::android::hardware::graphics::common::Hdr * outPreferredHdrOutputType)794 status_t HWComposer::setHdrConversionStrategy(
795         HdrConversionStrategy hdrConversionStrategy,
796         aidl::android::hardware::graphics::common::Hdr* outPreferredHdrOutputType) {
797     const auto error =
798             mComposer->setHdrConversionStrategy(hdrConversionStrategy, outPreferredHdrOutputType);
799     if (error != hal::Error::NONE) {
800         ALOGE("Error in setting HDR conversion strategy %s", to_string(error).c_str());
801         return INVALID_OPERATION;
802     }
803     return NO_ERROR;
804 }
805 
setRefreshRateChangedCallbackDebugEnabled(PhysicalDisplayId displayId,bool enabled)806 status_t HWComposer::setRefreshRateChangedCallbackDebugEnabled(PhysicalDisplayId displayId,
807                                                                bool enabled) {
808     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
809     const auto error =
810             mComposer->setRefreshRateChangedCallbackDebugEnabled(mDisplayData[displayId]
811                                                                          .hwcDisplay->getId(),
812                                                                  enabled);
813     if (error != hal::Error::NONE) {
814         ALOGE("Error in setting refresh refresh rate change callback debug enabled %s",
815               to_string(error).c_str());
816         return INVALID_OPERATION;
817     }
818     return NO_ERROR;
819 }
820 
getDisplayDecorationSupport(PhysicalDisplayId displayId,std::optional<aidl::android::hardware::graphics::common::DisplayDecorationSupport> * support)821 status_t HWComposer::getDisplayDecorationSupport(
822         PhysicalDisplayId displayId,
823         std::optional<aidl::android::hardware::graphics::common::DisplayDecorationSupport>*
824                 support) {
825     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
826     const auto error = mDisplayData[displayId].hwcDisplay->getDisplayDecorationSupport(support);
827     if (error == hal::Error::UNSUPPORTED) {
828         RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
829     }
830     if (error == hal::Error::BAD_PARAMETER) {
831         RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
832     }
833     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
834     return NO_ERROR;
835 }
836 
setAutoLowLatencyMode(PhysicalDisplayId displayId,bool on)837 status_t HWComposer::setAutoLowLatencyMode(PhysicalDisplayId displayId, bool on) {
838     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
839     const auto error = mDisplayData[displayId].hwcDisplay->setAutoLowLatencyMode(on);
840     if (error == hal::Error::UNSUPPORTED) {
841         RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
842     }
843     if (error == hal::Error::BAD_PARAMETER) {
844         RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
845     }
846     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
847     return NO_ERROR;
848 }
849 
getSupportedContentTypes(PhysicalDisplayId displayId,std::vector<hal::ContentType> * outSupportedContentTypes) const850 status_t HWComposer::getSupportedContentTypes(
851         PhysicalDisplayId displayId,
852         std::vector<hal::ContentType>* outSupportedContentTypes) const {
853     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
854     const auto error = mDisplayData.at(displayId).hwcDisplay->getSupportedContentTypes(
855             outSupportedContentTypes);
856 
857     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
858 
859     return NO_ERROR;
860 }
861 
setContentType(PhysicalDisplayId displayId,hal::ContentType contentType)862 status_t HWComposer::setContentType(PhysicalDisplayId displayId, hal::ContentType contentType) {
863     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
864     const auto error = mDisplayData[displayId].hwcDisplay->setContentType(contentType);
865     if (error == hal::Error::UNSUPPORTED) {
866         RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
867     }
868     if (error == hal::Error::BAD_PARAMETER) {
869         RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
870     }
871     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
872 
873     return NO_ERROR;
874 }
875 
getSupportedLayerGenericMetadata() const876 const std::unordered_map<std::string, bool>& HWComposer::getSupportedLayerGenericMetadata() const {
877     return mSupportedLayerGenericMetadata;
878 }
879 
dump(std::string & result) const880 void HWComposer::dump(std::string& result) const {
881     result.append(mComposer->dumpDebugInfo());
882 }
883 
toPhysicalDisplayId(hal::HWDisplayId hwcDisplayId) const884 std::optional<PhysicalDisplayId> HWComposer::toPhysicalDisplayId(
885         hal::HWDisplayId hwcDisplayId) const {
886     if (const auto it = mPhysicalDisplayIdMap.find(hwcDisplayId);
887         it != mPhysicalDisplayIdMap.end()) {
888         return it->second;
889     }
890     return {};
891 }
892 
fromPhysicalDisplayId(PhysicalDisplayId displayId) const893 std::optional<hal::HWDisplayId> HWComposer::fromPhysicalDisplayId(
894         PhysicalDisplayId displayId) const {
895     if (const auto it = mDisplayData.find(displayId); it != mDisplayData.end()) {
896         return it->second.hwcDisplay->getId();
897     }
898     return {};
899 }
900 
shouldIgnoreHotplugConnect(hal::HWDisplayId hwcDisplayId,bool hasDisplayIdentificationData) const901 bool HWComposer::shouldIgnoreHotplugConnect(hal::HWDisplayId hwcDisplayId,
902                                             bool hasDisplayIdentificationData) const {
903     if (mHasMultiDisplaySupport && !hasDisplayIdentificationData) {
904         ALOGE("Ignoring connection of display %" PRIu64 " without identification data",
905               hwcDisplayId);
906         return true;
907     }
908 
909     // Legacy mode only supports IDs LEGACY_DISPLAY_TYPE_PRIMARY and LEGACY_DISPLAY_TYPE_EXTERNAL.
910     if (!mHasMultiDisplaySupport && mPhysicalDisplayIdMap.size() == 2) {
911         ALOGE("Ignoring connection of tertiary display %" PRIu64, hwcDisplayId);
912         return true;
913     }
914 
915     return false;
916 }
917 
onHotplugConnect(hal::HWDisplayId hwcDisplayId)918 std::optional<DisplayIdentificationInfo> HWComposer::onHotplugConnect(
919         hal::HWDisplayId hwcDisplayId) {
920     std::optional<DisplayIdentificationInfo> info;
921     if (const auto displayId = toPhysicalDisplayId(hwcDisplayId)) {
922         info = DisplayIdentificationInfo{.id = *displayId,
923                                          .name = std::string(),
924                                          .deviceProductInfo = std::nullopt};
925         if (mUpdateDeviceProductInfoOnHotplugReconnect) {
926             uint8_t port;
927             DisplayIdentificationData data;
928             getDisplayIdentificationData(hwcDisplayId, &port, &data);
929             if (auto newInfo = parseDisplayIdentificationData(port, data)) {
930                 info->deviceProductInfo = std::move(newInfo->deviceProductInfo);
931             } else {
932                 ALOGE("Failed to parse identification data for display %" PRIu64, hwcDisplayId);
933             }
934         }
935     } else {
936         uint8_t port;
937         DisplayIdentificationData data;
938         const bool hasDisplayIdentificationData =
939                 getDisplayIdentificationData(hwcDisplayId, &port, &data);
940         if (mPhysicalDisplayIdMap.empty()) {
941             mHasMultiDisplaySupport = hasDisplayIdentificationData;
942             ALOGI("Switching to %s multi-display mode",
943                   mHasMultiDisplaySupport ? "generalized" : "legacy");
944         }
945 
946         if (shouldIgnoreHotplugConnect(hwcDisplayId, hasDisplayIdentificationData)) {
947             return {};
948         }
949 
950         info = [this, hwcDisplayId, &port, &data, hasDisplayIdentificationData] {
951             const bool isPrimary = !mPrimaryHwcDisplayId;
952             if (mHasMultiDisplaySupport) {
953                 if (const auto info = parseDisplayIdentificationData(port, data)) {
954                     return *info;
955                 }
956                 ALOGE("Failed to parse identification data for display %" PRIu64, hwcDisplayId);
957             } else {
958                 ALOGW_IF(hasDisplayIdentificationData,
959                          "Ignoring identification data for display %" PRIu64, hwcDisplayId);
960                 port = isPrimary ? LEGACY_DISPLAY_TYPE_PRIMARY : LEGACY_DISPLAY_TYPE_EXTERNAL;
961             }
962 
963             return DisplayIdentificationInfo{.id = PhysicalDisplayId::fromPort(port),
964                                              .name = isPrimary ? "Primary display"
965                                                                : "Secondary display",
966                                              .deviceProductInfo = std::nullopt};
967         }();
968 
969         mComposer->onHotplugConnect(hwcDisplayId);
970     }
971 
972     if (!isConnected(info->id)) {
973         allocatePhysicalDisplay(hwcDisplayId, info->id);
974     }
975     return info;
976 }
977 
onHotplugDisconnect(hal::HWDisplayId hwcDisplayId)978 std::optional<DisplayIdentificationInfo> HWComposer::onHotplugDisconnect(
979         hal::HWDisplayId hwcDisplayId) {
980     LOG_ALWAYS_FATAL_IF(hwcDisplayId == mPrimaryHwcDisplayId,
981                         "Primary display cannot be disconnected.");
982 
983     const auto displayId = toPhysicalDisplayId(hwcDisplayId);
984     if (!displayId) {
985         LOG_HWC_DISPLAY_ERROR(hwcDisplayId, "Invalid HWC display");
986         return {};
987     }
988 
989     if (!isConnected(*displayId)) {
990         LOG_HWC_DISPLAY_ERROR(hwcDisplayId, "Already disconnected");
991         return {};
992     }
993 
994     // The display will later be destroyed by a call to HWComposer::disconnectDisplay. For now, mark
995     // it as disconnected.
996     mDisplayData.at(*displayId).hwcDisplay->setConnected(false);
997     mComposer->onHotplugDisconnect(hwcDisplayId);
998     return DisplayIdentificationInfo{.id = *displayId};
999 }
1000 
loadCapabilities()1001 void HWComposer::loadCapabilities() {
1002     static_assert(sizeof(hal::Capability) == sizeof(int32_t), "Capability size has changed");
1003     auto capabilities = mComposer->getCapabilities();
1004     for (auto capability : capabilities) {
1005         mCapabilities.emplace(capability);
1006     }
1007 }
1008 
loadOverlayProperties()1009 void HWComposer::loadOverlayProperties() {
1010     mComposer->getOverlaySupport(&mOverlayProperties);
1011 }
1012 
loadHdrConversionCapabilities()1013 void HWComposer::loadHdrConversionCapabilities() {
1014     const auto error = mComposer->getHdrConversionCapabilities(&mHdrConversionCapabilities);
1015     if (error != hal::Error::NONE) {
1016         ALOGE("Error in fetching HDR conversion capabilities %s", to_string(error).c_str());
1017         mHdrConversionCapabilities = {};
1018     }
1019 }
1020 
setIdleTimerEnabled(PhysicalDisplayId displayId,std::chrono::milliseconds timeout)1021 status_t HWComposer::setIdleTimerEnabled(PhysicalDisplayId displayId,
1022                                          std::chrono::milliseconds timeout) {
1023     ATRACE_CALL();
1024     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
1025     const auto error = mDisplayData[displayId].hwcDisplay->setIdleTimerEnabled(timeout);
1026     if (error == hal::Error::UNSUPPORTED) {
1027         RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
1028     }
1029     if (error == hal::Error::BAD_PARAMETER) {
1030         RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
1031     }
1032     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
1033     return NO_ERROR;
1034 }
1035 
hasDisplayIdleTimerCapability(PhysicalDisplayId displayId) const1036 bool HWComposer::hasDisplayIdleTimerCapability(PhysicalDisplayId displayId) const {
1037     RETURN_IF_INVALID_DISPLAY(displayId, false);
1038     return mDisplayData.at(displayId).hwcDisplay->hasDisplayIdleTimerCapability();
1039 }
1040 
getPhysicalDisplayOrientation(PhysicalDisplayId displayId) const1041 Hwc2::AidlTransform HWComposer::getPhysicalDisplayOrientation(PhysicalDisplayId displayId) const {
1042     ATRACE_CALL();
1043     RETURN_IF_INVALID_DISPLAY(displayId, Hwc2::AidlTransform::NONE);
1044     Hwc2::AidlTransform outTransform;
1045     const auto& hwcDisplay = mDisplayData.at(displayId).hwcDisplay;
1046     const auto error = hwcDisplay->getPhysicalDisplayOrientation(&outTransform);
1047     RETURN_IF_HWC_ERROR(error, displayId, Hwc2::AidlTransform::NONE);
1048     return outTransform;
1049 }
1050 
loadLayerMetadataSupport()1051 void HWComposer::loadLayerMetadataSupport() {
1052     mSupportedLayerGenericMetadata.clear();
1053 
1054     std::vector<Hwc2::IComposerClient::LayerGenericMetadataKey> supportedMetadataKeyInfo;
1055     const auto error = mComposer->getLayerGenericMetadataKeys(&supportedMetadataKeyInfo);
1056     if (error != hardware::graphics::composer::V2_4::Error::NONE) {
1057         if (error != hardware::graphics::composer::V2_4::Error::UNSUPPORTED) {
1058             ALOGE("%s: %s failed: %s (%d)", __FUNCTION__, "getLayerGenericMetadataKeys",
1059                   toString(error).c_str(), static_cast<int32_t>(error));
1060         }
1061         return;
1062     }
1063 
1064     for (const auto& [name, mandatory] : supportedMetadataKeyInfo) {
1065         mSupportedLayerGenericMetadata.emplace(name, mandatory);
1066     }
1067 }
1068 
1069 } // namespace impl
1070 } // namespace android
1071 
1072 // TODO(b/129481165): remove the #pragma below and fix conversion issues
1073 #pragma clang diagnostic pop // ignored "-Wconversion"
1074