• 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 #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,HotplugEvent event)140 std::optional<DisplayIdentificationInfo> HWComposer::onHotplug(hal::HWDisplayId hwcDisplayId,
141                                                                HotplugEvent event) {
142     switch (event) {
143         case HotplugEvent::Connected:
144             return onHotplugConnect(hwcDisplayId);
145         case HotplugEvent::Disconnected:
146             return onHotplugDisconnect(hwcDisplayId);
147         case HotplugEvent::LinkUnstable:
148             return onHotplugLinkTrainingFailure(hwcDisplayId);
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,uint8_t port,std::optional<ui::Size> physicalSize)227 void HWComposer::allocatePhysicalDisplay(hal::HWDisplayId hwcDisplayId, PhysicalDisplayId displayId,
228                                          uint8_t port, std::optional<ui::Size> physicalSize) {
229     LOG_ALWAYS_FATAL_IF(!mActivePorts.try_emplace(port).second,
230                         "Cannot attach display %" PRIu64 " to an already active port %" PRIu8 ".",
231                         hwcDisplayId, port);
232 
233     mPhysicalDisplayIdMap[hwcDisplayId] = displayId;
234 
235     if (!mPrimaryHwcDisplayId) {
236         mPrimaryHwcDisplayId = hwcDisplayId;
237     }
238 
239     auto& displayData = mDisplayData[displayId];
240     auto newDisplay =
241             std::make_unique<HWC2::impl::Display>(*mComposer.get(), mCapabilities, hwcDisplayId,
242                                                   hal::DisplayType::PHYSICAL);
243     newDisplay->setConnected(true);
244     newDisplay->setPhysicalSizeInMm(physicalSize);
245     displayData.hwcDisplay = std::move(newDisplay);
246     displayData.port = port;
247 }
248 
getAttribute(hal::HWDisplayId hwcDisplayId,hal::HWConfigId configId,hal::Attribute attribute) const249 int32_t HWComposer::getAttribute(hal::HWDisplayId hwcDisplayId, hal::HWConfigId configId,
250                                  hal::Attribute attribute) const {
251     int32_t value = 0;
252     auto error = static_cast<hal::Error>(
253             mComposer->getDisplayAttribute(hwcDisplayId, configId, attribute, &value));
254 
255     RETURN_IF_HWC_ERROR_FOR("getDisplayAttribute", error, *toPhysicalDisplayId(hwcDisplayId), -1);
256     return value;
257 }
258 
createLayer(HalDisplayId displayId)259 std::shared_ptr<HWC2::Layer> HWComposer::createLayer(HalDisplayId displayId) {
260     RETURN_IF_INVALID_DISPLAY(displayId, nullptr);
261 
262     auto expected = mDisplayData[displayId].hwcDisplay->createLayer();
263     if (!expected.has_value()) {
264         auto error = std::move(expected).error();
265         RETURN_IF_HWC_ERROR(error, displayId, nullptr);
266     }
267     return std::move(expected).value();
268 }
269 
isConnected(PhysicalDisplayId displayId) const270 bool HWComposer::isConnected(PhysicalDisplayId displayId) const {
271     return mDisplayData.count(displayId) && mDisplayData.at(displayId).hwcDisplay->isConnected();
272 }
273 
getModes(PhysicalDisplayId displayId,int32_t maxFrameIntervalNs) const274 std::vector<HWComposer::HWCDisplayMode> HWComposer::getModes(PhysicalDisplayId displayId,
275                                                              int32_t maxFrameIntervalNs) const {
276     RETURN_IF_INVALID_DISPLAY(displayId, {});
277 
278     const auto hwcDisplayId = mDisplayData.at(displayId).hwcDisplay->getId();
279 
280     if (mComposer->isVrrSupported()) {
281         return getModesFromDisplayConfigurations(hwcDisplayId, maxFrameIntervalNs);
282     }
283 
284     return getModesFromLegacyDisplayConfigs(hwcDisplayId);
285 }
286 
getEstimatedDotsPerInchFromSize(uint64_t hwcDisplayId,const HWCDisplayMode & hwcMode) const287 DisplayConfiguration::Dpi HWComposer::getEstimatedDotsPerInchFromSize(
288         uint64_t hwcDisplayId, const HWCDisplayMode& hwcMode) const {
289     if (!FlagManager::getInstance().correct_dpi_with_display_size()) {
290         return {-1, -1};
291     }
292     if (const auto displayId = toPhysicalDisplayId(hwcDisplayId)) {
293         if (const auto it = mDisplayData.find(displayId.value());
294             it != mDisplayData.end() && it->second.hwcDisplay->getPhysicalSizeInMm()) {
295             ui::Size size = it->second.hwcDisplay->getPhysicalSizeInMm().value();
296             if (hwcMode.width > 0 && hwcMode.height > 0 && size.width > 0 && size.height > 0) {
297                 static constexpr float kMmPerInch = 25.4f;
298                 return {hwcMode.width * kMmPerInch / size.width,
299                         hwcMode.height * kMmPerInch / size.height};
300             }
301         }
302     }
303     return {-1, -1};
304 }
305 
correctedDpiIfneeded(DisplayConfiguration::Dpi dpi,DisplayConfiguration::Dpi estimatedDpi) const306 DisplayConfiguration::Dpi HWComposer::correctedDpiIfneeded(
307         DisplayConfiguration::Dpi dpi, DisplayConfiguration::Dpi estimatedDpi) const {
308     // hwc can be unreliable when it comes to dpi. A rough estimated dpi may yield better
309     // results. For instance, libdrm and bad edid may result in a dpi of {350, 290} for a
310     // 16:9 3840x2160 display, which would match a 4:3 aspect ratio.
311     // The logic here checks if hwc was able to provide some dpi, and if so if the dpi
312     // disparity between the axes is more reasonable than a rough estimate, otherwise use
313     // the estimated dpi as a corrected value.
314     if (estimatedDpi.x == -1 || estimatedDpi.y == -1) {
315         return dpi;
316     }
317     if (dpi.x == -1 || dpi.y == -1) {
318         return estimatedDpi;
319     }
320     if (std::min(dpi.x, dpi.y) != 0 && std::min(estimatedDpi.x, estimatedDpi.y) != 0 &&
321         abs(dpi.x - dpi.y) / std::min(dpi.x, dpi.y) >
322                 abs(estimatedDpi.x - estimatedDpi.y) / std::min(estimatedDpi.x, estimatedDpi.y)) {
323         return estimatedDpi;
324     }
325     return dpi;
326 }
327 
getModesFromDisplayConfigurations(uint64_t hwcDisplayId,int32_t maxFrameIntervalNs) const328 std::vector<HWComposer::HWCDisplayMode> HWComposer::getModesFromDisplayConfigurations(
329         uint64_t hwcDisplayId, int32_t maxFrameIntervalNs) const {
330     std::vector<hal::DisplayConfiguration> configs;
331     auto error = static_cast<hal::Error>(
332             mComposer->getDisplayConfigurations(hwcDisplayId, maxFrameIntervalNs, &configs));
333     RETURN_IF_HWC_ERROR_FOR("getDisplayConfigurations", error, *toPhysicalDisplayId(hwcDisplayId),
334                             {});
335 
336     std::vector<HWCDisplayMode> modes;
337     modes.reserve(configs.size());
338     for (auto config : configs) {
339         auto hwcMode = HWCDisplayMode{.hwcId = static_cast<hal::HWConfigId>(config.configId),
340                                       .width = config.width,
341                                       .height = config.height,
342                                       .vsyncPeriod = config.vsyncPeriod,
343                                       .configGroup = config.configGroup,
344                                       .vrrConfig = config.vrrConfig,
345                                       .hdrOutputType = config.hdrOutputType};
346 
347         const DisplayConfiguration::Dpi estimatedDPI =
348                 getEstimatedDotsPerInchFromSize(hwcDisplayId, hwcMode);
349         if (config.dpi) {
350             const DisplayConfiguration::Dpi dpi =
351                     correctedDpiIfneeded(config.dpi.value(), estimatedDPI);
352             hwcMode.dpiX = dpi.x;
353             hwcMode.dpiY = dpi.y;
354         } else if (estimatedDPI.x != -1 && estimatedDPI.y != -1) {
355             hwcMode.dpiX = estimatedDPI.x;
356             hwcMode.dpiY = estimatedDPI.y;
357         }
358 
359         if (!mEnableVrrTimeout) {
360             hwcMode.vrrConfig->notifyExpectedPresentConfig = {};
361         }
362 
363         modes.push_back(hwcMode);
364     }
365 
366     return modes;
367 }
368 
getModesFromLegacyDisplayConfigs(uint64_t hwcDisplayId) const369 std::vector<HWComposer::HWCDisplayMode> HWComposer::getModesFromLegacyDisplayConfigs(
370         uint64_t hwcDisplayId) const {
371     std::vector<hal::HWConfigId> configIds;
372     auto error = static_cast<hal::Error>(mComposer->getDisplayConfigs(hwcDisplayId, &configIds));
373     RETURN_IF_HWC_ERROR_FOR("getDisplayConfigs", error, *toPhysicalDisplayId(hwcDisplayId), {});
374 
375     std::vector<HWCDisplayMode> modes;
376     modes.reserve(configIds.size());
377     for (auto configId : configIds) {
378         auto hwcMode = HWCDisplayMode{
379                 .hwcId = configId,
380                 .width = getAttribute(hwcDisplayId, configId, hal::Attribute::WIDTH),
381                 .height = getAttribute(hwcDisplayId, configId, hal::Attribute::HEIGHT),
382                 .vsyncPeriod = getAttribute(hwcDisplayId, configId, hal::Attribute::VSYNC_PERIOD),
383                 .configGroup = getAttribute(hwcDisplayId, configId, hal::Attribute::CONFIG_GROUP),
384         };
385 
386         const int32_t dpiX = getAttribute(hwcDisplayId, configId, hal::Attribute::DPI_X);
387         const int32_t dpiY = getAttribute(hwcDisplayId, configId, hal::Attribute::DPI_Y);
388         const DisplayConfiguration::Dpi hwcDpi =
389                 DisplayConfiguration::Dpi{dpiX == -1 ? dpiX : dpiX / 1000.f,
390                                           dpiY == -1 ? dpiY : dpiY / 1000.f};
391         const DisplayConfiguration::Dpi estimatedDPI =
392                 getEstimatedDotsPerInchFromSize(hwcDisplayId, hwcMode);
393         const DisplayConfiguration::Dpi dpi = correctedDpiIfneeded(hwcDpi, estimatedDPI);
394         hwcMode.dpiX = dpi.x;
395         hwcMode.dpiY = dpi.y;
396 
397         modes.push_back(hwcMode);
398     }
399     return modes;
400 }
401 
getActiveMode(PhysicalDisplayId displayId) const402 ftl::Expected<hal::HWConfigId, status_t> HWComposer::getActiveMode(
403         PhysicalDisplayId displayId) const {
404     RETURN_IF_INVALID_DISPLAY(displayId, ftl::Unexpected(BAD_INDEX));
405     const auto hwcId = *fromPhysicalDisplayId(displayId);
406 
407     hal::HWConfigId configId;
408     const auto error = static_cast<hal::Error>(mComposer->getActiveConfig(hwcId, &configId));
409     if (error == hal::Error::BAD_CONFIG) {
410         return ftl::Unexpected(NO_INIT);
411     }
412 
413     RETURN_IF_HWC_ERROR_FOR("getActiveConfig", error, displayId, ftl::Unexpected(UNKNOWN_ERROR));
414     return configId;
415 }
416 
417 // Composer 2.4
418 
getDisplayConnectionType(PhysicalDisplayId displayId) const419 ui::DisplayConnectionType HWComposer::getDisplayConnectionType(PhysicalDisplayId displayId) const {
420     RETURN_IF_INVALID_DISPLAY(displayId, ui::DisplayConnectionType::Internal);
421     const auto& hwcDisplay = mDisplayData.at(displayId).hwcDisplay;
422 
423     if (const auto connectionType = hwcDisplay->getConnectionType()) {
424         return connectionType.value();
425     } else {
426         LOG_HWC_ERROR(__func__, connectionType.error(), displayId);
427         return hwcDisplay->getId() == mPrimaryHwcDisplayId ? ui::DisplayConnectionType::Internal
428                                                            : ui::DisplayConnectionType::External;
429     }
430 }
431 
isVsyncPeriodSwitchSupported(PhysicalDisplayId displayId) const432 bool HWComposer::isVsyncPeriodSwitchSupported(PhysicalDisplayId displayId) const {
433     RETURN_IF_INVALID_DISPLAY(displayId, false);
434     return mDisplayData.at(displayId).hwcDisplay->isVsyncPeriodSwitchSupported();
435 }
436 
getDisplayVsyncPeriod(PhysicalDisplayId displayId) const437 ftl::Expected<nsecs_t, status_t> HWComposer::getDisplayVsyncPeriod(
438         PhysicalDisplayId displayId) const {
439     RETURN_IF_INVALID_DISPLAY(displayId, ftl::Unexpected(BAD_INDEX));
440 
441     if (!isVsyncPeriodSwitchSupported(displayId)) {
442         return ftl::Unexpected(INVALID_OPERATION);
443     }
444 
445     const auto hwcId = *fromPhysicalDisplayId(displayId);
446     Hwc2::VsyncPeriodNanos vsyncPeriodNanos = 0;
447     const auto error =
448             static_cast<hal::Error>(mComposer->getDisplayVsyncPeriod(hwcId, &vsyncPeriodNanos));
449     RETURN_IF_HWC_ERROR(error, displayId, ftl::Unexpected(UNKNOWN_ERROR));
450     return static_cast<nsecs_t>(vsyncPeriodNanos);
451 }
452 
getColorModes(PhysicalDisplayId displayId) const453 std::vector<ui::ColorMode> HWComposer::getColorModes(PhysicalDisplayId displayId) const {
454     RETURN_IF_INVALID_DISPLAY(displayId, {});
455 
456     std::vector<ui::ColorMode> modes;
457     auto error = mDisplayData.at(displayId).hwcDisplay->getColorModes(&modes);
458     RETURN_IF_HWC_ERROR(error, displayId, {});
459     return modes;
460 }
461 
setActiveColorMode(PhysicalDisplayId displayId,ui::ColorMode mode,ui::RenderIntent renderIntent)462 status_t HWComposer::setActiveColorMode(PhysicalDisplayId displayId, ui::ColorMode mode,
463                                         ui::RenderIntent renderIntent) {
464     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
465 
466     auto& displayData = mDisplayData[displayId];
467     auto error = displayData.hwcDisplay->setColorMode(mode, renderIntent);
468     RETURN_IF_HWC_ERROR_FOR(("setColorMode(" + decodeColorMode(mode) + ", " +
469                              decodeRenderIntent(renderIntent) + ")")
470                                     .c_str(),
471                             error, displayId, UNKNOWN_ERROR);
472 
473     return NO_ERROR;
474 }
475 
setVsyncEnabled(PhysicalDisplayId displayId,hal::Vsync enabled)476 void HWComposer::setVsyncEnabled(PhysicalDisplayId displayId, hal::Vsync enabled) {
477     RETURN_IF_INVALID_DISPLAY(displayId);
478     auto& displayData = mDisplayData[displayId];
479 
480     // NOTE: we use our own internal lock here because we have to call
481     // into the HWC with the lock held, and we want to make sure
482     // that even if HWC blocks (which it shouldn't), it won't
483     // affect other threads.
484     std::lock_guard lock(displayData.vsyncEnabledLock);
485     if (enabled == displayData.vsyncEnabled) {
486         return;
487     }
488 
489     SFTRACE_CALL();
490     auto error = displayData.hwcDisplay->setVsyncEnabled(enabled);
491     RETURN_IF_HWC_ERROR(error, displayId);
492 
493     displayData.vsyncEnabled = enabled;
494 
495     SFTRACE_INT(ftl::Concat("HW_VSYNC_ON_", displayId.value).c_str(),
496                 enabled == hal::Vsync::ENABLE ? 1 : 0);
497 }
498 
setClientTarget(HalDisplayId displayId,uint32_t slot,const sp<Fence> & acquireFence,const sp<GraphicBuffer> & target,ui::Dataspace dataspace,float hdrSdrRatio)499 status_t HWComposer::setClientTarget(HalDisplayId displayId, uint32_t slot,
500                                      const sp<Fence>& acquireFence, const sp<GraphicBuffer>& target,
501                                      ui::Dataspace dataspace, float hdrSdrRatio) {
502     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
503 
504     ALOGV("%s for display %s", __FUNCTION__, to_string(displayId).c_str());
505     auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
506     auto error = hwcDisplay->setClientTarget(slot, target, acquireFence, dataspace, hdrSdrRatio);
507     RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
508     return NO_ERROR;
509 }
510 
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)511 status_t HWComposer::getDeviceCompositionChanges(
512         HalDisplayId displayId, bool frameUsesClientComposition,
513         std::optional<std::chrono::steady_clock::time_point> earliestPresentTime,
514         nsecs_t expectedPresentTime, Fps frameInterval,
515         std::optional<android::HWComposer::DeviceRequestedChanges>* outChanges) {
516     SFTRACE_CALL();
517 
518     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
519 
520     auto& displayData = mDisplayData[displayId];
521     auto& hwcDisplay = displayData.hwcDisplay;
522     if (!hwcDisplay->isConnected()) {
523         return NO_ERROR;
524     }
525 
526     uint32_t numTypes = 0;
527     uint32_t numRequests = 0;
528 
529     hal::Error error = hal::Error::NONE;
530 
531     // First try to skip validate altogether. We can do that when
532     // 1. The previous frame has not been presented yet or already passed the
533     // earliest time to present. Otherwise, we may present a frame too early.
534     // 2. There is no client composition. Otherwise, we first need to render the
535     // client target buffer.
536     const bool canSkipValidate = [&] {
537         // We must call validate if we have client composition
538         if (frameUsesClientComposition) {
539             return false;
540         }
541 
542         // If composer supports getting the expected present time, we can skip
543         // as composer will make sure to prevent early presentation
544         if (!earliestPresentTime) {
545             return true;
546         }
547 
548         // composer doesn't support getting the expected present time. We can only
549         // skip validate if we know that we are not going to present early.
550         return std::chrono::steady_clock::now() >= *earliestPresentTime;
551     }();
552 
553     displayData.validateWasSkipped = false;
554     SFTRACE_FORMAT("NextFrameInterval %d_Hz", frameInterval.getIntValue());
555     if (canSkipValidate) {
556         sp<Fence> outPresentFence = Fence::NO_FENCE;
557         uint32_t state = UINT32_MAX;
558         error = hwcDisplay->presentOrValidate(expectedPresentTime, frameInterval.getPeriodNsecs(),
559                                               &numTypes, &numRequests, &outPresentFence, &state);
560         if (!hasChangesError(error)) {
561             RETURN_IF_HWC_ERROR_FOR("presentOrValidate", error, displayId, UNKNOWN_ERROR);
562         }
563         if (state == 1) { // Present Succeeded.
564             std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
565             error = hwcDisplay->getReleaseFences(&releaseFences);
566             displayData.releaseFences = std::move(releaseFences);
567             displayData.lastPresentFence = outPresentFence;
568             displayData.validateWasSkipped = true;
569             displayData.presentError = error;
570             return NO_ERROR;
571         }
572         // Present failed but Validate ran.
573     } else {
574         error = hwcDisplay->validate(expectedPresentTime, frameInterval.getPeriodNsecs(), &numTypes,
575                                      &numRequests);
576     }
577     ALOGV("SkipValidate failed, Falling back to SLOW validate/present");
578     if (!hasChangesError(error)) {
579         RETURN_IF_HWC_ERROR_FOR("validate", error, displayId, BAD_INDEX);
580     }
581 
582     android::HWComposer::DeviceRequestedChanges::ChangedTypes changedTypes;
583     changedTypes.reserve(numTypes);
584     error = hwcDisplay->getChangedCompositionTypes(&changedTypes);
585     RETURN_IF_HWC_ERROR_FOR("getChangedCompositionTypes", error, displayId, BAD_INDEX);
586 
587     auto displayRequests = static_cast<hal::DisplayRequest>(0);
588     android::HWComposer::DeviceRequestedChanges::LayerRequests layerRequests;
589     layerRequests.reserve(numRequests);
590     error = hwcDisplay->getRequests(&displayRequests, &layerRequests);
591     RETURN_IF_HWC_ERROR_FOR("getRequests", error, displayId, BAD_INDEX);
592 
593     DeviceRequestedChanges::ClientTargetProperty clientTargetProperty;
594     error = hwcDisplay->getClientTargetProperty(&clientTargetProperty);
595     RETURN_IF_HWC_ERROR_FOR("getClientTargetProperty", error, displayId, BAD_INDEX);
596 
597     DeviceRequestedChanges::LayerLuts layerLuts;
598     error = hwcDisplay->getRequestedLuts(&layerLuts, mLutFileDescriptorMapper);
599     RETURN_IF_HWC_ERROR_FOR("getRequestedLuts", error, displayId, BAD_INDEX);
600 
601     outChanges->emplace(DeviceRequestedChanges{std::move(changedTypes), std::move(displayRequests),
602                                                std::move(layerRequests),
603                                                std::move(clientTargetProperty),
604                                                std::move(layerLuts)});
605     error = hwcDisplay->acceptChanges();
606     RETURN_IF_HWC_ERROR_FOR("acceptChanges", error, displayId, BAD_INDEX);
607 
608     return NO_ERROR;
609 }
610 
getPresentFence(HalDisplayId displayId) const611 sp<Fence> HWComposer::getPresentFence(HalDisplayId displayId) const {
612     RETURN_IF_INVALID_DISPLAY(displayId, Fence::NO_FENCE);
613     return mDisplayData.at(displayId).lastPresentFence;
614 }
615 
getPresentTimestamp(PhysicalDisplayId displayId) const616 nsecs_t HWComposer::getPresentTimestamp(PhysicalDisplayId displayId) const {
617     RETURN_IF_INVALID_DISPLAY(displayId, 0);
618     return mDisplayData.at(displayId).lastPresentTimestamp;
619 }
620 
getLayerReleaseFence(HalDisplayId displayId,HWC2::Layer * layer) const621 sp<Fence> HWComposer::getLayerReleaseFence(HalDisplayId displayId, HWC2::Layer* layer) const {
622     RETURN_IF_INVALID_DISPLAY(displayId, Fence::NO_FENCE);
623     const auto& displayFences = mDisplayData.at(displayId).releaseFences;
624     auto fence = displayFences.find(layer);
625     if (fence == displayFences.end()) {
626         ALOGV("getLayerReleaseFence: Release fence not found");
627         return Fence::NO_FENCE;
628     }
629     return fence->second;
630 }
631 
presentAndGetReleaseFences(HalDisplayId displayId,std::optional<std::chrono::steady_clock::time_point> earliestPresentTime)632 status_t HWComposer::presentAndGetReleaseFences(
633         HalDisplayId displayId,
634         std::optional<std::chrono::steady_clock::time_point> earliestPresentTime) {
635     SFTRACE_CALL();
636 
637     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
638 
639     auto& displayData = mDisplayData[displayId];
640     auto& hwcDisplay = displayData.hwcDisplay;
641 
642     if (displayData.validateWasSkipped) {
643         // explicitly flush all pending commands
644         auto error = static_cast<hal::Error>(mComposer->executeCommands(hwcDisplay->getId()));
645         RETURN_IF_HWC_ERROR_FOR("executeCommands", error, displayId, UNKNOWN_ERROR);
646         RETURN_IF_HWC_ERROR_FOR("present", displayData.presentError, displayId, UNKNOWN_ERROR);
647         return NO_ERROR;
648     }
649 
650     if (earliestPresentTime) {
651         SFTRACE_NAME("wait for earliest present time");
652         std::this_thread::sleep_until(*earliestPresentTime);
653     }
654 
655     auto error = hwcDisplay->present(&displayData.lastPresentFence);
656     RETURN_IF_HWC_ERROR_FOR("present", error, displayId, UNKNOWN_ERROR);
657 
658     std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
659     error = hwcDisplay->getReleaseFences(&releaseFences);
660     RETURN_IF_HWC_ERROR_FOR("getReleaseFences", error, displayId, UNKNOWN_ERROR);
661 
662     displayData.releaseFences = std::move(releaseFences);
663 
664     return NO_ERROR;
665 }
666 
executeCommands(HalDisplayId displayId)667 status_t HWComposer::executeCommands(HalDisplayId displayId) {
668     auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
669     auto error = static_cast<hal::Error>(mComposer->executeCommands(hwcDisplay->getId()));
670     RETURN_IF_HWC_ERROR_FOR("executeCommands", error, displayId, UNKNOWN_ERROR);
671     return NO_ERROR;
672 }
673 
setPowerMode(PhysicalDisplayId displayId,hal::PowerMode mode)674 status_t HWComposer::setPowerMode(PhysicalDisplayId displayId, hal::PowerMode mode) {
675     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
676 
677     if (mode == hal::PowerMode::OFF) {
678         setVsyncEnabled(displayId, hal::Vsync::DISABLE);
679     }
680 
681     const auto& displayData = mDisplayData[displayId];
682     auto& hwcDisplay = displayData.hwcDisplay;
683     switch (mode) {
684         case hal::PowerMode::OFF:
685         case hal::PowerMode::ON:
686             ALOGV("setPowerMode: Calling HWC %s", to_string(mode).c_str());
687             {
688                 auto error = hwcDisplay->setPowerMode(mode);
689                 if (error != hal::Error::NONE) {
690                     LOG_HWC_ERROR(("setPowerMode(" + to_string(mode) + ")").c_str(), error,
691                                   displayId);
692                 }
693             }
694             break;
695         case hal::PowerMode::DOZE:
696         case hal::PowerMode::DOZE_SUSPEND:
697             ALOGV("setPowerMode: Calling HWC %s", to_string(mode).c_str());
698             {
699                 bool supportsDoze = false;
700                 const auto queryDozeError = hwcDisplay->supportsDoze(&supportsDoze);
701 
702                 // queryDozeError might be NO_RESOURCES, in the case of a display that has never
703                 // been turned on. In that case, attempt to set to DOZE anyway.
704                 if (!supportsDoze && queryDozeError == hal::Error::NONE) {
705                     mode = hal::PowerMode::ON;
706                 }
707 
708                 auto error = hwcDisplay->setPowerMode(mode);
709                 if (error != hal::Error::NONE) {
710                     LOG_HWC_ERROR(("setPowerMode(" + to_string(mode) + ")").c_str(), error,
711                                   displayId);
712                     // If the display had never been turned on, so its doze
713                     // support was unknown, it may truly not support doze. Try
714                     // switching it to ON instead.
715                     if (queryDozeError == hal::Error::NO_RESOURCES) {
716                         ALOGD("%s: failed to set %s to %s. Trying again with ON", __func__,
717                               to_string(displayId).c_str(), to_string(mode).c_str());
718                         error = hwcDisplay->setPowerMode(hal::PowerMode::ON);
719                         if (error != hal::Error::NONE) {
720                             LOG_HWC_ERROR("setPowerMode(ON)", error, displayId);
721                         }
722                     }
723                 }
724             }
725             break;
726         default:
727             ALOGV("setPowerMode: Not calling HWC");
728             break;
729     }
730 
731     return NO_ERROR;
732 }
733 
setActiveModeWithConstraints(PhysicalDisplayId displayId,hal::HWConfigId hwcModeId,const hal::VsyncPeriodChangeConstraints & constraints,hal::VsyncPeriodChangeTimeline * outTimeline)734 status_t HWComposer::setActiveModeWithConstraints(
735         PhysicalDisplayId displayId, hal::HWConfigId hwcModeId,
736         const hal::VsyncPeriodChangeConstraints& constraints,
737         hal::VsyncPeriodChangeTimeline* outTimeline) {
738     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
739 
740     auto error = mDisplayData[displayId].hwcDisplay->setActiveConfigWithConstraints(hwcModeId,
741                                                                                     constraints,
742                                                                                     outTimeline);
743     if (error == hal::Error::CONFIG_FAILED) {
744         RETURN_IF_HWC_ERROR_FOR("setActiveConfigWithConstraints", error, displayId,
745                                 FAILED_TRANSACTION);
746     }
747     RETURN_IF_HWC_ERROR_FOR("setActiveConfigWithConstraints", error, displayId, UNKNOWN_ERROR);
748     return NO_ERROR;
749 }
750 
setColorTransform(HalDisplayId displayId,const mat4 & transform)751 status_t HWComposer::setColorTransform(HalDisplayId displayId, const mat4& transform) {
752     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
753 
754     auto& displayData = mDisplayData[displayId];
755     auto error = displayData.hwcDisplay->setColorTransform(transform);
756     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
757     return NO_ERROR;
758 }
759 
disconnectDisplay(HalDisplayId displayId)760 void HWComposer::disconnectDisplay(HalDisplayId displayId) {
761     RETURN_IF_INVALID_DISPLAY(displayId);
762     auto& displayData = mDisplayData[displayId];
763     const auto hwcDisplayId = displayData.hwcDisplay->getId();
764 
765     mPhysicalDisplayIdMap.erase(hwcDisplayId);
766     if (const auto port = displayData.port) {
767         mActivePorts.erase(port.value());
768     }
769     mDisplayData.erase(displayId);
770 
771     // Reset the primary display ID if we're disconnecting it.
772     // This way isHeadless() will return false, which is necessary
773     // because getPrimaryDisplayId() will crash.
774     if (mPrimaryHwcDisplayId == hwcDisplayId) {
775         mPrimaryHwcDisplayId.reset();
776     }
777 }
778 
setOutputBuffer(HalVirtualDisplayId displayId,const sp<Fence> & acquireFence,const sp<GraphicBuffer> & buffer)779 status_t HWComposer::setOutputBuffer(HalVirtualDisplayId displayId, const sp<Fence>& acquireFence,
780                                      const sp<GraphicBuffer>& buffer) {
781     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
782     const auto& displayData = mDisplayData[displayId];
783 
784     auto error = displayData.hwcDisplay->setOutputBuffer(buffer, acquireFence);
785     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
786     return NO_ERROR;
787 }
788 
clearReleaseFences(HalDisplayId displayId)789 void HWComposer::clearReleaseFences(HalDisplayId displayId) {
790     RETURN_IF_INVALID_DISPLAY(displayId);
791     mDisplayData[displayId].releaseFences.clear();
792 }
793 
getHdrCapabilities(HalDisplayId displayId,HdrCapabilities * outCapabilities)794 status_t HWComposer::getHdrCapabilities(HalDisplayId displayId, HdrCapabilities* outCapabilities) {
795     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
796 
797     auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
798     auto error = hwcDisplay->getHdrCapabilities(outCapabilities);
799     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
800     return NO_ERROR;
801 }
802 
803 const aidl::android::hardware::graphics::composer3::OverlayProperties&
getOverlaySupport() const804 HWComposer::getOverlaySupport() const {
805     return mOverlayProperties;
806 }
807 
getSupportedPerFrameMetadata(HalDisplayId displayId) const808 int32_t HWComposer::getSupportedPerFrameMetadata(HalDisplayId displayId) const {
809     RETURN_IF_INVALID_DISPLAY(displayId, 0);
810     return mDisplayData.at(displayId).hwcDisplay->getSupportedPerFrameMetadata();
811 }
812 
getRenderIntents(HalDisplayId displayId,ui::ColorMode colorMode) const813 std::vector<ui::RenderIntent> HWComposer::getRenderIntents(HalDisplayId displayId,
814                                                            ui::ColorMode colorMode) const {
815     RETURN_IF_INVALID_DISPLAY(displayId, {});
816 
817     std::vector<ui::RenderIntent> renderIntents;
818     auto error = mDisplayData.at(displayId).hwcDisplay->getRenderIntents(colorMode, &renderIntents);
819     RETURN_IF_HWC_ERROR(error, displayId, {});
820     return renderIntents;
821 }
822 
getDataspaceSaturationMatrix(HalDisplayId displayId,ui::Dataspace dataspace)823 mat4 HWComposer::getDataspaceSaturationMatrix(HalDisplayId displayId, ui::Dataspace dataspace) {
824     RETURN_IF_INVALID_DISPLAY(displayId, {});
825 
826     mat4 matrix;
827     auto error =
828             mDisplayData[displayId].hwcDisplay->getDataspaceSaturationMatrix(dataspace, &matrix);
829     RETURN_IF_HWC_ERROR(error, displayId, {});
830     return matrix;
831 }
832 
getDisplayedContentSamplingAttributes(HalDisplayId displayId,ui::PixelFormat * outFormat,ui::Dataspace * outDataspace,uint8_t * outComponentMask)833 status_t HWComposer::getDisplayedContentSamplingAttributes(HalDisplayId displayId,
834                                                            ui::PixelFormat* outFormat,
835                                                            ui::Dataspace* outDataspace,
836                                                            uint8_t* outComponentMask) {
837     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
838     const auto error =
839             mDisplayData[displayId]
840                     .hwcDisplay->getDisplayedContentSamplingAttributes(outFormat, outDataspace,
841                                                                        outComponentMask);
842     if (error == hal::Error::UNSUPPORTED) RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
843     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
844     return NO_ERROR;
845 }
846 
setDisplayContentSamplingEnabled(HalDisplayId displayId,bool enabled,uint8_t componentMask,uint64_t maxFrames)847 status_t HWComposer::setDisplayContentSamplingEnabled(HalDisplayId displayId, bool enabled,
848                                                       uint8_t componentMask, uint64_t maxFrames) {
849     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
850     const auto error =
851             mDisplayData[displayId].hwcDisplay->setDisplayContentSamplingEnabled(enabled,
852                                                                                  componentMask,
853                                                                                  maxFrames);
854 
855     if (error == hal::Error::UNSUPPORTED) RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
856     if (error == hal::Error::BAD_PARAMETER) RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
857     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
858     return NO_ERROR;
859 }
860 
getDisplayedContentSample(HalDisplayId displayId,uint64_t maxFrames,uint64_t timestamp,DisplayedFrameStats * outStats)861 status_t HWComposer::getDisplayedContentSample(HalDisplayId displayId, uint64_t maxFrames,
862                                                uint64_t timestamp, DisplayedFrameStats* outStats) {
863     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
864     const auto error =
865             mDisplayData[displayId].hwcDisplay->getDisplayedContentSample(maxFrames, timestamp,
866                                                                           outStats);
867     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
868     return NO_ERROR;
869 }
870 
setDisplayBrightness(PhysicalDisplayId displayId,float brightness,float brightnessNits,const Hwc2::Composer::DisplayBrightnessOptions & options)871 ftl::Future<status_t> HWComposer::setDisplayBrightness(
872         PhysicalDisplayId displayId, float brightness, float brightnessNits,
873         const Hwc2::Composer::DisplayBrightnessOptions& options) {
874     RETURN_IF_INVALID_DISPLAY(displayId, ftl::yield<status_t>(BAD_INDEX));
875     auto& display = mDisplayData[displayId].hwcDisplay;
876 
877     return display->setDisplayBrightness(brightness, brightnessNits, options)
878             .then([displayId](hal::Error error) -> status_t {
879                 if (error == hal::Error::UNSUPPORTED) {
880                     RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
881                 }
882                 if (error == hal::Error::BAD_PARAMETER) {
883                     RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
884                 }
885                 RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
886                 return NO_ERROR;
887             });
888 }
889 
getValidateSkipped(HalDisplayId displayId) const890 bool HWComposer::getValidateSkipped(HalDisplayId displayId) const {
891     if (mDisplayData.count(displayId) == 0) {
892         return false;
893     }
894     return mDisplayData.at(displayId).validateWasSkipped;
895 }
896 
setBootDisplayMode(PhysicalDisplayId displayId,hal::HWConfigId displayModeId)897 status_t HWComposer::setBootDisplayMode(PhysicalDisplayId displayId,
898                                         hal::HWConfigId displayModeId) {
899     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
900     const auto error = mDisplayData[displayId].hwcDisplay->setBootDisplayConfig(displayModeId);
901     if (error == hal::Error::UNSUPPORTED) {
902         RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
903     }
904     if (error == hal::Error::BAD_PARAMETER) {
905         RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
906     }
907     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
908     return NO_ERROR;
909 }
910 
clearBootDisplayMode(PhysicalDisplayId displayId)911 status_t HWComposer::clearBootDisplayMode(PhysicalDisplayId displayId) {
912     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
913     const auto error = mDisplayData[displayId].hwcDisplay->clearBootDisplayConfig();
914     if (error == hal::Error::UNSUPPORTED) {
915         RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
916     }
917     if (error == hal::Error::BAD_PARAMETER) {
918         RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
919     }
920     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
921     return NO_ERROR;
922 }
923 
getPreferredBootDisplayMode(PhysicalDisplayId displayId)924 std::optional<hal::HWConfigId> HWComposer::getPreferredBootDisplayMode(
925         PhysicalDisplayId displayId) {
926     RETURN_IF_INVALID_DISPLAY(displayId, std::nullopt);
927     hal::HWConfigId displayModeId;
928     const auto error =
929             mDisplayData[displayId].hwcDisplay->getPreferredBootDisplayConfig(&displayModeId);
930     if (error != hal::Error::NONE) {
931         LOG_DISPLAY_ERROR(displayId, to_string(error).c_str());
932         return std::nullopt;
933     }
934     return displayModeId;
935 }
936 
getHdrConversionCapabilities() const937 std::vector<HdrConversionCapability> HWComposer::getHdrConversionCapabilities() const {
938     return mHdrConversionCapabilities;
939 }
940 
setHdrConversionStrategy(HdrConversionStrategy hdrConversionStrategy,aidl::android::hardware::graphics::common::Hdr * outPreferredHdrOutputType)941 status_t HWComposer::setHdrConversionStrategy(
942         HdrConversionStrategy hdrConversionStrategy,
943         aidl::android::hardware::graphics::common::Hdr* outPreferredHdrOutputType) {
944     const auto error =
945             mComposer->setHdrConversionStrategy(hdrConversionStrategy, outPreferredHdrOutputType);
946     if (error != hal::Error::NONE) {
947         ALOGE("Error in setting HDR conversion strategy %s", to_string(error).c_str());
948         return INVALID_OPERATION;
949     }
950     return NO_ERROR;
951 }
952 
setRefreshRateChangedCallbackDebugEnabled(PhysicalDisplayId displayId,bool enabled)953 status_t HWComposer::setRefreshRateChangedCallbackDebugEnabled(PhysicalDisplayId displayId,
954                                                                bool enabled) {
955     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
956     const auto error =
957             mComposer->setRefreshRateChangedCallbackDebugEnabled(mDisplayData[displayId]
958                                                                          .hwcDisplay->getId(),
959                                                                  enabled);
960     if (error != hal::Error::NONE) {
961         ALOGE("Error in setting refresh refresh rate change callback debug enabled %s",
962               to_string(error).c_str());
963         return INVALID_OPERATION;
964     }
965     return NO_ERROR;
966 }
967 
notifyExpectedPresent(PhysicalDisplayId displayId,TimePoint expectedPresentTime,Fps frameInterval)968 status_t HWComposer::notifyExpectedPresent(PhysicalDisplayId displayId,
969                                            TimePoint expectedPresentTime, Fps frameInterval) {
970     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
971     SFTRACE_FORMAT("%s ExpectedPresentTime in %.2fms frameInterval %.2fms", __func__,
972                    ticks<std::milli, float>(expectedPresentTime - TimePoint::now()),
973                    ticks<std::milli, float>(Duration::fromNs(frameInterval.getPeriodNsecs())));
974     const auto error = mComposer->notifyExpectedPresent(mDisplayData[displayId].hwcDisplay->getId(),
975                                                         expectedPresentTime.ns(),
976                                                         frameInterval.getPeriodNsecs());
977     if (error != hal::Error::NONE) {
978         ALOGE("Error in notifyExpectedPresent call %s", to_string(error).c_str());
979         return INVALID_OPERATION;
980     }
981     return NO_ERROR;
982 }
983 
getDisplayDecorationSupport(PhysicalDisplayId displayId,std::optional<aidl::android::hardware::graphics::common::DisplayDecorationSupport> * support)984 status_t HWComposer::getDisplayDecorationSupport(
985         PhysicalDisplayId displayId,
986         std::optional<aidl::android::hardware::graphics::common::DisplayDecorationSupport>*
987                 support) {
988     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
989     const auto error = mDisplayData[displayId].hwcDisplay->getDisplayDecorationSupport(support);
990     if (error == hal::Error::UNSUPPORTED) {
991         RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
992     }
993     if (error == hal::Error::BAD_PARAMETER) {
994         RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
995     }
996     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
997     return NO_ERROR;
998 }
999 
setAutoLowLatencyMode(PhysicalDisplayId displayId,bool on)1000 status_t HWComposer::setAutoLowLatencyMode(PhysicalDisplayId displayId, bool on) {
1001     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
1002     const auto error = mDisplayData[displayId].hwcDisplay->setAutoLowLatencyMode(on);
1003     if (error == hal::Error::UNSUPPORTED) {
1004         RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
1005     }
1006     if (error == hal::Error::BAD_PARAMETER) {
1007         RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
1008     }
1009     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
1010     return NO_ERROR;
1011 }
1012 
getSupportedContentTypes(PhysicalDisplayId displayId,std::vector<hal::ContentType> * outSupportedContentTypes) const1013 status_t HWComposer::getSupportedContentTypes(
1014         PhysicalDisplayId displayId,
1015         std::vector<hal::ContentType>* outSupportedContentTypes) const {
1016     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
1017     const auto error = mDisplayData.at(displayId).hwcDisplay->getSupportedContentTypes(
1018             outSupportedContentTypes);
1019 
1020     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
1021 
1022     return NO_ERROR;
1023 }
1024 
setContentType(PhysicalDisplayId displayId,hal::ContentType contentType)1025 status_t HWComposer::setContentType(PhysicalDisplayId displayId, hal::ContentType contentType) {
1026     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
1027     const auto error = mDisplayData[displayId].hwcDisplay->setContentType(contentType);
1028     if (error == hal::Error::UNSUPPORTED) {
1029         RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
1030     }
1031     if (error == hal::Error::BAD_PARAMETER) {
1032         RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
1033     }
1034     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
1035 
1036     return NO_ERROR;
1037 }
1038 
getMaxLayerPictureProfiles(PhysicalDisplayId displayId)1039 int32_t HWComposer::getMaxLayerPictureProfiles(PhysicalDisplayId displayId) {
1040     int32_t maxProfiles = 0;
1041     RETURN_IF_INVALID_DISPLAY(displayId, 0);
1042     const auto error = mDisplayData[displayId].hwcDisplay->getMaxLayerPictureProfiles(&maxProfiles);
1043     RETURN_IF_HWC_ERROR(error, displayId, 0);
1044     return maxProfiles;
1045 }
1046 
setDisplayPictureProfileHandle(PhysicalDisplayId displayId,const PictureProfileHandle & handle)1047 status_t HWComposer::setDisplayPictureProfileHandle(PhysicalDisplayId displayId,
1048                                                     const PictureProfileHandle& handle) {
1049     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
1050     const auto error = mDisplayData[displayId].hwcDisplay->setPictureProfileHandle(handle);
1051     if (error != hal::Error::UNSUPPORTED) {
1052         RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
1053     }
1054     return NO_ERROR;
1055 }
1056 
startHdcpNegotiation(PhysicalDisplayId displayId,const aidl::android::hardware::drm::HdcpLevels & levels)1057 status_t HWComposer::startHdcpNegotiation(PhysicalDisplayId displayId,
1058                                           const aidl::android::hardware::drm::HdcpLevels& levels) {
1059     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
1060     auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
1061     auto error = hwcDisplay->startHdcpNegotiation(levels);
1062     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
1063     return NO_ERROR;
1064 }
1065 
getLuts(PhysicalDisplayId displayId,const std::vector<sp<GraphicBuffer>> & buffers,std::vector<aidl::android::hardware::graphics::composer3::Luts> * luts)1066 status_t HWComposer::getLuts(
1067         PhysicalDisplayId displayId, const std::vector<sp<GraphicBuffer>>& buffers,
1068         std::vector<aidl::android::hardware::graphics::composer3::Luts>* luts) {
1069     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
1070     auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
1071     auto error = hwcDisplay->getLuts(buffers, luts);
1072     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
1073     return NO_ERROR;
1074 }
1075 
getSupportedLayerGenericMetadata() const1076 const std::unordered_map<std::string, bool>& HWComposer::getSupportedLayerGenericMetadata() const {
1077     return mSupportedLayerGenericMetadata;
1078 }
1079 
1080 ftl::SmallMap<HWC2::Layer*, ::android::base::unique_fd, 20>&
getLutFileDescriptorMapper()1081 HWComposer::getLutFileDescriptorMapper() {
1082     return mLutFileDescriptorMapper;
1083 }
1084 
dumpOverlayProperties(std::string & result) const1085 void HWComposer::dumpOverlayProperties(std::string& result) const {
1086     // dump overlay properties
1087     result.append("OverlayProperties:\n");
1088     base::StringAppendF(&result, "supportMixedColorSpaces: %d\n",
1089                         mOverlayProperties.supportMixedColorSpaces);
1090     base::StringAppendF(&result, "SupportedBufferCombinations(%zu entries)\n",
1091                         mOverlayProperties.combinations.size());
1092     for (const auto& combination : mOverlayProperties.combinations) {
1093         result.append("    pixelFormats=\n");
1094         for (const auto& pixelFormat : combination.pixelFormats) {
1095             base::StringAppendF(&result, "        %s (%d)\n",
1096                                 decodePixelFormat(static_cast<PixelFormat>(pixelFormat)).c_str(),
1097                                 static_cast<uint32_t>(pixelFormat));
1098         }
1099         result.append("    standards=\n");
1100         for (const auto& standard : combination.standards) {
1101             base::StringAppendF(&result, "        %s (%d)\n",
1102                                 decodeStandardOnly(static_cast<uint32_t>(standard)).c_str(),
1103                                 static_cast<uint32_t>(standard));
1104         }
1105         result.append("    transfers=\n");
1106         for (const auto& transfer : combination.transfers) {
1107             base::StringAppendF(&result, "        %s (%d)\n",
1108                                 decodeTransferOnly(static_cast<uint32_t>(transfer)).c_str(),
1109                                 static_cast<uint32_t>(transfer));
1110         }
1111         result.append("    ranges=\n");
1112         for (const auto& range : combination.ranges) {
1113             base::StringAppendF(&result, "        %s (%d)\n",
1114                                 decodeRangeOnly(static_cast<uint32_t>(range)).c_str(),
1115                                 static_cast<uint32_t>(range));
1116         }
1117         result.append("\n");
1118     }
1119 }
1120 
dump(std::string & result) const1121 void HWComposer::dump(std::string& result) const {
1122     result.append(mComposer->dumpDebugInfo());
1123     dumpOverlayProperties(result);
1124 }
1125 
toPhysicalDisplayId(hal::HWDisplayId hwcDisplayId) const1126 std::optional<PhysicalDisplayId> HWComposer::toPhysicalDisplayId(
1127         hal::HWDisplayId hwcDisplayId) const {
1128     if (const auto it = mPhysicalDisplayIdMap.find(hwcDisplayId);
1129         it != mPhysicalDisplayIdMap.end()) {
1130         return it->second;
1131     }
1132     return {};
1133 }
1134 
fromPhysicalDisplayId(PhysicalDisplayId displayId) const1135 std::optional<hal::HWDisplayId> HWComposer::fromPhysicalDisplayId(
1136         PhysicalDisplayId displayId) const {
1137     if (const auto it = mDisplayData.find(displayId); it != mDisplayData.end()) {
1138         return it->second.hwcDisplay->getId();
1139     }
1140     return {};
1141 }
1142 
shouldIgnoreHotplugConnect(hal::HWDisplayId hwcDisplayId,uint8_t port,bool hasDisplayIdentificationData) const1143 bool HWComposer::shouldIgnoreHotplugConnect(hal::HWDisplayId hwcDisplayId, uint8_t port,
1144                                             bool hasDisplayIdentificationData) const {
1145     if (mActivePorts.contains(port)) {
1146         ALOGE("Ignoring connection of display %" PRIu64 ". Port %" PRIu8
1147               " is already in active use.",
1148               hwcDisplayId, port);
1149         return true;
1150     }
1151 
1152     if (mHasMultiDisplaySupport && !hasDisplayIdentificationData) {
1153         ALOGE("Ignoring connection of display %" PRIu64 " without identification data",
1154               hwcDisplayId);
1155         return true;
1156     }
1157 
1158     // Legacy mode only supports IDs LEGACY_DISPLAY_TYPE_PRIMARY and LEGACY_DISPLAY_TYPE_EXTERNAL.
1159     if (!mHasMultiDisplaySupport && mPhysicalDisplayIdMap.size() == 2) {
1160         ALOGE("Ignoring connection of tertiary display %" PRIu64, hwcDisplayId);
1161         return true;
1162     }
1163 
1164     return false;
1165 }
1166 
onHotplugConnect(hal::HWDisplayId hwcDisplayId)1167 std::optional<DisplayIdentificationInfo> HWComposer::onHotplugConnect(
1168         hal::HWDisplayId hwcDisplayId) {
1169     std::optional<DisplayIdentificationInfo> info;
1170     if (const auto displayId = toPhysicalDisplayId(hwcDisplayId)) {
1171         info = DisplayIdentificationInfo{.id = *displayId,
1172                                          .name = std::string(),
1173                                          .deviceProductInfo = std::nullopt};
1174         if (mUpdateDeviceProductInfoOnHotplugReconnect) {
1175             uint8_t port;
1176             DisplayIdentificationData data;
1177             getDisplayIdentificationData(hwcDisplayId, &port, &data);
1178             if (auto newInfo = parseDisplayIdentificationData(port, data)) {
1179                 info->deviceProductInfo = std::move(newInfo->deviceProductInfo);
1180                 info->preferredDetailedTimingDescriptor =
1181                         std::move(newInfo->preferredDetailedTimingDescriptor);
1182             } else {
1183                 ALOGE("Failed to parse identification data for display %" PRIu64, hwcDisplayId);
1184             }
1185         }
1186     } else {
1187         uint8_t port;
1188         DisplayIdentificationData data;
1189         const bool hasDisplayIdentificationData =
1190                 getDisplayIdentificationData(hwcDisplayId, &port, &data);
1191         if (mPhysicalDisplayIdMap.empty()) {
1192             mHasMultiDisplaySupport = hasDisplayIdentificationData;
1193             ALOGI("Switching to %s multi-display mode",
1194                   mHasMultiDisplaySupport ? "generalized" : "legacy");
1195         }
1196 
1197         if (shouldIgnoreHotplugConnect(hwcDisplayId, port, hasDisplayIdentificationData)) {
1198             return {};
1199         }
1200 
1201         info = [this, hwcDisplayId, &port, &data, hasDisplayIdentificationData] {
1202             const bool isPrimary = !mPrimaryHwcDisplayId;
1203             if (mHasMultiDisplaySupport) {
1204                 if (const auto info = parseDisplayIdentificationData(port, data)) {
1205                     return *info;
1206                 }
1207                 ALOGE("Failed to parse identification data for display %" PRIu64, hwcDisplayId);
1208             } else {
1209                 ALOGW_IF(hasDisplayIdentificationData,
1210                          "Ignoring identification data for display %" PRIu64, hwcDisplayId);
1211                 port = isPrimary ? LEGACY_DISPLAY_TYPE_PRIMARY : LEGACY_DISPLAY_TYPE_EXTERNAL;
1212             }
1213 
1214             return DisplayIdentificationInfo{.id = PhysicalDisplayId::fromPort(port),
1215                                              .name = isPrimary ? "Primary display"
1216                                                                : "Secondary display",
1217                                              .port = port,
1218                                              .deviceProductInfo = std::nullopt};
1219         }();
1220 
1221         mComposer->onHotplugConnect(hwcDisplayId);
1222     }
1223 
1224     if (!isConnected(info->id)) {
1225         std::optional<ui::Size> size = std::nullopt;
1226         if (info->preferredDetailedTimingDescriptor) {
1227             size = info->preferredDetailedTimingDescriptor->physicalSizeInMm;
1228         }
1229         allocatePhysicalDisplay(hwcDisplayId, info->id, info->port, size);
1230     }
1231     return info;
1232 }
1233 
onHotplugDisconnect(hal::HWDisplayId hwcDisplayId)1234 std::optional<DisplayIdentificationInfo> HWComposer::onHotplugDisconnect(
1235         hal::HWDisplayId hwcDisplayId) {
1236     LOG_ALWAYS_FATAL_IF(hwcDisplayId == mPrimaryHwcDisplayId,
1237                         "Primary display cannot be disconnected.");
1238 
1239     const auto displayId = toPhysicalDisplayId(hwcDisplayId);
1240     if (!displayId) {
1241         LOG_HWC_DISPLAY_ERROR(hwcDisplayId, "Invalid HWC display");
1242         return {};
1243     }
1244 
1245     if (!isConnected(*displayId)) {
1246         LOG_HWC_DISPLAY_ERROR(hwcDisplayId, "Already disconnected");
1247         return {};
1248     }
1249 
1250     // The display will later be destroyed by a call to HWComposer::disconnectDisplay. For now, mark
1251     // it as disconnected.
1252     mDisplayData.at(*displayId).hwcDisplay->setConnected(false);
1253     mComposer->onHotplugDisconnect(hwcDisplayId);
1254     return DisplayIdentificationInfo{.id = *displayId};
1255 }
1256 
onHotplugLinkTrainingFailure(hal::HWDisplayId hwcDisplayId)1257 std::optional<DisplayIdentificationInfo> HWComposer::onHotplugLinkTrainingFailure(
1258         hal::HWDisplayId hwcDisplayId) {
1259     const auto displayId = toPhysicalDisplayId(hwcDisplayId);
1260     if (!displayId) {
1261         LOG_HWC_DISPLAY_ERROR(hwcDisplayId, "Invalid HWC display");
1262         return {};
1263     }
1264     return DisplayIdentificationInfo{.id = *displayId};
1265 }
1266 
loadCapabilities()1267 void HWComposer::loadCapabilities() {
1268     static_assert(sizeof(hal::Capability) == sizeof(int32_t), "Capability size has changed");
1269     auto capabilities = mComposer->getCapabilities();
1270     for (auto capability : capabilities) {
1271         mCapabilities.emplace(capability);
1272     }
1273 }
1274 
loadOverlayProperties()1275 void HWComposer::loadOverlayProperties() {
1276     mComposer->getOverlaySupport(&mOverlayProperties);
1277 }
1278 
loadHdrConversionCapabilities()1279 void HWComposer::loadHdrConversionCapabilities() {
1280     const auto error = mComposer->getHdrConversionCapabilities(&mHdrConversionCapabilities);
1281     if (error != hal::Error::NONE) {
1282         ALOGE("Error in fetching HDR conversion capabilities %s", to_string(error).c_str());
1283         mHdrConversionCapabilities = {};
1284     }
1285 }
1286 
setIdleTimerEnabled(PhysicalDisplayId displayId,std::chrono::milliseconds timeout)1287 status_t HWComposer::setIdleTimerEnabled(PhysicalDisplayId displayId,
1288                                          std::chrono::milliseconds timeout) {
1289     SFTRACE_CALL();
1290     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
1291     const auto error = mDisplayData[displayId].hwcDisplay->setIdleTimerEnabled(timeout);
1292     if (error == hal::Error::UNSUPPORTED) {
1293         RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
1294     }
1295     if (error == hal::Error::BAD_PARAMETER) {
1296         RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
1297     }
1298     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
1299     return NO_ERROR;
1300 }
1301 
hasDisplayIdleTimerCapability(PhysicalDisplayId displayId) const1302 bool HWComposer::hasDisplayIdleTimerCapability(PhysicalDisplayId displayId) const {
1303     RETURN_IF_INVALID_DISPLAY(displayId, false);
1304     return mDisplayData.at(displayId).hwcDisplay->hasDisplayIdleTimerCapability();
1305 }
1306 
getPhysicalDisplayOrientation(PhysicalDisplayId displayId) const1307 Hwc2::AidlTransform HWComposer::getPhysicalDisplayOrientation(PhysicalDisplayId displayId) const {
1308     SFTRACE_CALL();
1309     RETURN_IF_INVALID_DISPLAY(displayId, Hwc2::AidlTransform::NONE);
1310     Hwc2::AidlTransform outTransform;
1311     const auto& hwcDisplay = mDisplayData.at(displayId).hwcDisplay;
1312     const auto error = hwcDisplay->getPhysicalDisplayOrientation(&outTransform);
1313     RETURN_IF_HWC_ERROR(error, displayId, Hwc2::AidlTransform::NONE);
1314     return outTransform;
1315 }
1316 
loadLayerMetadataSupport()1317 void HWComposer::loadLayerMetadataSupport() {
1318     mSupportedLayerGenericMetadata.clear();
1319 
1320     std::vector<Hwc2::IComposerClient::LayerGenericMetadataKey> supportedMetadataKeyInfo;
1321     const auto error = mComposer->getLayerGenericMetadataKeys(&supportedMetadataKeyInfo);
1322     if (error != hardware::graphics::composer::V2_4::Error::NONE) {
1323         if (error != hardware::graphics::composer::V2_4::Error::UNSUPPORTED) {
1324             ALOGE("%s: %s failed: %s (%d)", __FUNCTION__, "getLayerGenericMetadataKeys",
1325                   toString(error).c_str(), static_cast<int32_t>(error));
1326         }
1327         return;
1328     }
1329 
1330     for (const auto& [name, mandatory] : supportedMetadataKeyInfo) {
1331         mSupportedLayerGenericMetadata.emplace(name, mandatory);
1332     }
1333 }
1334 
1335 } // namespace impl
1336 } // namespace android
1337 
1338 // TODO(b/129481165): remove the #pragma below and fix conversion issues
1339 #pragma clang diagnostic pop // ignored "-Wconversion"
1340