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 <compositionengine/Output.h>
30 #include <compositionengine/OutputLayer.h>
31 #include <compositionengine/impl/OutputLayerCompositionState.h>
32 #include <log/log.h>
33 #include <ui/DebugUtils.h>
34 #include <ui/GraphicBuffer.h>
35 #include <utils/Errors.h>
36 #include <utils/Trace.h>
37
38 #include "../Layer.h" // needed only for debugging
39 #include "../Promise.h"
40 #include "../SurfaceFlinger.h"
41 #include "ComposerHal.h"
42 #include "HWC2.h"
43
44 #define LOG_HWC_DISPLAY_ERROR(hwcDisplayId, msg) \
45 ALOGE("%s failed for HWC display %" PRIu64 ": %s", __FUNCTION__, hwcDisplayId, msg)
46
47 #define LOG_DISPLAY_ERROR(displayId, msg) \
48 ALOGE("%s failed for display %s: %s", __FUNCTION__, to_string(displayId).c_str(), msg)
49
50 #define LOG_HWC_ERROR(what, error, displayId) \
51 ALOGE("%s: %s failed for display %s: %s (%d)", __FUNCTION__, what, \
52 to_string(displayId).c_str(), to_string(error).c_str(), static_cast<int32_t>(error))
53
54 #define RETURN_IF_INVALID_DISPLAY(displayId, ...) \
55 do { \
56 if (mDisplayData.count(displayId) == 0) { \
57 LOG_DISPLAY_ERROR(displayId, "Invalid display"); \
58 return __VA_ARGS__; \
59 } \
60 } while (false)
61
62 #define RETURN_IF_HWC_ERROR_FOR(what, error, displayId, ...) \
63 do { \
64 if (error != hal::Error::NONE) { \
65 LOG_HWC_ERROR(what, error, displayId); \
66 return __VA_ARGS__; \
67 } \
68 } while (false)
69
70 #define RETURN_IF_HWC_ERROR(error, displayId, ...) \
71 RETURN_IF_HWC_ERROR_FOR(__FUNCTION__, error, displayId, __VA_ARGS__)
72
73 namespace hal = android::hardware::graphics::composer::hal;
74
75 namespace {
76
77 using android::hardware::Return;
78 using android::hardware::Void;
79 using android::HWC2::ComposerCallback;
80
81 class ComposerCallbackBridge : public hal::IComposerCallback {
82 public:
ComposerCallbackBridge(ComposerCallback * callback,int32_t sequenceId,bool vsyncSwitchingSupported)83 ComposerCallbackBridge(ComposerCallback* callback, int32_t sequenceId,
84 bool vsyncSwitchingSupported)
85 : mCallback(callback),
86 mSequenceId(sequenceId),
87 mVsyncSwitchingSupported(vsyncSwitchingSupported) {}
88
onHotplug(hal::HWDisplayId display,hal::Connection conn)89 android::hardware::Return<void> onHotplug(hal::HWDisplayId display,
90 hal::Connection conn) override {
91 mCallback->onHotplugReceived(mSequenceId, display, conn);
92 return android::hardware::Void();
93 }
94
onRefresh(hal::HWDisplayId display)95 android::hardware::Return<void> onRefresh(hal::HWDisplayId display) override {
96 mCallback->onRefreshReceived(mSequenceId, display);
97 return android::hardware::Void();
98 }
99
onVsync(hal::HWDisplayId display,int64_t timestamp)100 android::hardware::Return<void> onVsync(hal::HWDisplayId display, int64_t timestamp) override {
101 if (!mVsyncSwitchingSupported) {
102 mCallback->onVsyncReceived(mSequenceId, display, timestamp, std::nullopt);
103 } else {
104 ALOGW("Unexpected onVsync callback on composer >= 2.4, ignoring.");
105 }
106 return android::hardware::Void();
107 }
108
onVsync_2_4(hal::HWDisplayId display,int64_t timestamp,hal::VsyncPeriodNanos vsyncPeriodNanos)109 android::hardware::Return<void> onVsync_2_4(hal::HWDisplayId display, int64_t timestamp,
110 hal::VsyncPeriodNanos vsyncPeriodNanos) override {
111 if (mVsyncSwitchingSupported) {
112 mCallback->onVsyncReceived(mSequenceId, display, timestamp,
113 std::make_optional(vsyncPeriodNanos));
114 } else {
115 ALOGW("Unexpected onVsync_2_4 callback on composer <= 2.3, ignoring.");
116 }
117 return android::hardware::Void();
118 }
119
onVsyncPeriodTimingChanged(hal::HWDisplayId display,const hal::VsyncPeriodChangeTimeline & updatedTimeline)120 android::hardware::Return<void> onVsyncPeriodTimingChanged(
121 hal::HWDisplayId display,
122 const hal::VsyncPeriodChangeTimeline& updatedTimeline) override {
123 mCallback->onVsyncPeriodTimingChangedReceived(mSequenceId, display, updatedTimeline);
124 return android::hardware::Void();
125 }
126
onSeamlessPossible(hal::HWDisplayId display)127 android::hardware::Return<void> onSeamlessPossible(hal::HWDisplayId display) override {
128 mCallback->onSeamlessPossible(mSequenceId, display);
129 return android::hardware::Void();
130 }
131
132 private:
133 ComposerCallback* mCallback;
134 const int32_t mSequenceId;
135 const bool mVsyncSwitchingSupported;
136 };
137
138 } // namespace
139
140 namespace android {
141
142 HWComposer::~HWComposer() = default;
143
144 namespace impl {
145
HWComposer(std::unique_ptr<Hwc2::Composer> composer)146 HWComposer::HWComposer(std::unique_ptr<Hwc2::Composer> composer) : mComposer(std::move(composer)) {
147 }
148
HWComposer(const std::string & composerServiceName)149 HWComposer::HWComposer(const std::string& composerServiceName)
150 : mComposer(std::make_unique<Hwc2::impl::Composer>(composerServiceName)) {
151 }
152
~HWComposer()153 HWComposer::~HWComposer() {
154 mDisplayData.clear();
155 }
156
setConfiguration(HWC2::ComposerCallback * callback,int32_t sequenceId)157 void HWComposer::setConfiguration(HWC2::ComposerCallback* callback, int32_t sequenceId) {
158 loadCapabilities();
159 loadLayerMetadataSupport();
160
161 if (mRegisteredCallback) {
162 ALOGW("Callback already registered. Ignored extra registration attempt.");
163 return;
164 }
165 mRegisteredCallback = true;
166 sp<ComposerCallbackBridge> callbackBridge(
167 new ComposerCallbackBridge(callback, sequenceId,
168 mComposer->isVsyncPeriodSwitchSupported()));
169 mComposer->registerCallback(callbackBridge);
170 }
171
getDisplayIdentificationData(hal::HWDisplayId hwcDisplayId,uint8_t * outPort,DisplayIdentificationData * outData) const172 bool HWComposer::getDisplayIdentificationData(hal::HWDisplayId hwcDisplayId, uint8_t* outPort,
173 DisplayIdentificationData* outData) const {
174 const auto error = static_cast<hal::Error>(
175 mComposer->getDisplayIdentificationData(hwcDisplayId, outPort, outData));
176 if (error != hal::Error::NONE) {
177 if (error != hal::Error::UNSUPPORTED) {
178 LOG_HWC_DISPLAY_ERROR(hwcDisplayId, to_string(error).c_str());
179 }
180 return false;
181 }
182 return true;
183 }
184
hasCapability(hal::Capability capability) const185 bool HWComposer::hasCapability(hal::Capability capability) const {
186 return mCapabilities.count(capability) > 0;
187 }
188
hasDisplayCapability(DisplayId displayId,hal::DisplayCapability capability) const189 bool HWComposer::hasDisplayCapability(DisplayId displayId,
190 hal::DisplayCapability capability) const {
191 RETURN_IF_INVALID_DISPLAY(displayId, false);
192 return mDisplayData.at(displayId).hwcDisplay->getCapabilities().count(capability) > 0;
193 }
194
onHotplug(hal::HWDisplayId hwcDisplayId,hal::Connection connection)195 std::optional<DisplayIdentificationInfo> HWComposer::onHotplug(hal::HWDisplayId hwcDisplayId,
196 hal::Connection connection) {
197 switch (connection) {
198 case hal::Connection::CONNECTED:
199 return onHotplugConnect(hwcDisplayId);
200 case hal::Connection::DISCONNECTED:
201 return onHotplugDisconnect(hwcDisplayId);
202 case hal::Connection::INVALID:
203 return {};
204 }
205 }
206
onVsync(hal::HWDisplayId hwcDisplayId,int64_t timestamp)207 bool HWComposer::onVsync(hal::HWDisplayId hwcDisplayId, int64_t timestamp) {
208 const auto displayId = toPhysicalDisplayId(hwcDisplayId);
209 if (!displayId) {
210 LOG_HWC_DISPLAY_ERROR(hwcDisplayId, "Invalid HWC display");
211 return false;
212 }
213
214 RETURN_IF_INVALID_DISPLAY(*displayId, false);
215
216 auto& displayData = mDisplayData[*displayId];
217 if (displayData.isVirtual) {
218 LOG_DISPLAY_ERROR(*displayId, "Invalid operation on virtual display");
219 return false;
220 }
221
222 {
223 std::lock_guard lock(displayData.lastHwVsyncLock);
224
225 // There have been reports of HWCs that signal several vsync events
226 // with the same timestamp when turning the display off and on. This
227 // is a bug in the HWC implementation, but filter the extra events
228 // out here so they don't cause havoc downstream.
229 if (timestamp == displayData.lastHwVsync) {
230 ALOGW("Ignoring duplicate VSYNC event from HWC for display %s (t=%" PRId64 ")",
231 to_string(*displayId).c_str(), timestamp);
232 return false;
233 }
234
235 displayData.lastHwVsync = timestamp;
236 }
237
238 const auto tag = "HW_VSYNC_" + to_string(*displayId);
239 ATRACE_INT(tag.c_str(), displayData.vsyncTraceToggle);
240 displayData.vsyncTraceToggle = !displayData.vsyncTraceToggle;
241
242 return true;
243 }
244
allocateVirtualDisplay(uint32_t width,uint32_t height,ui::PixelFormat * format)245 std::optional<DisplayId> HWComposer::allocateVirtualDisplay(uint32_t width, uint32_t height,
246 ui::PixelFormat* format) {
247 if (mRemainingHwcVirtualDisplays == 0) {
248 ALOGE("%s: No remaining virtual displays", __FUNCTION__);
249 return {};
250 }
251
252 if (SurfaceFlinger::maxVirtualDisplaySize != 0 &&
253 (width > SurfaceFlinger::maxVirtualDisplaySize ||
254 height > SurfaceFlinger::maxVirtualDisplaySize)) {
255 ALOGE("%s: Display size %ux%u exceeds maximum dimension of %" PRIu64, __FUNCTION__, width,
256 height, SurfaceFlinger::maxVirtualDisplaySize);
257 return {};
258 }
259 hal::HWDisplayId hwcDisplayId = 0;
260 const auto error = static_cast<hal::Error>(
261 mComposer->createVirtualDisplay(width, height, format, &hwcDisplayId));
262 if (error != hal::Error::NONE) {
263 ALOGE("%s: Failed to create HWC virtual display", __FUNCTION__);
264 return {};
265 }
266
267 auto display = std::make_unique<HWC2::impl::Display>(*mComposer.get(), mCapabilities,
268 hwcDisplayId, hal::DisplayType::VIRTUAL);
269 display->setConnected(true);
270
271 DisplayId displayId;
272 if (mFreeVirtualDisplayIds.empty()) {
273 displayId = getVirtualDisplayId(mNextVirtualDisplayId++);
274 } else {
275 displayId = *mFreeVirtualDisplayIds.begin();
276 mFreeVirtualDisplayIds.erase(displayId);
277 }
278
279 auto& displayData = mDisplayData[displayId];
280 displayData.hwcDisplay = std::move(display);
281 displayData.isVirtual = true;
282
283 --mRemainingHwcVirtualDisplays;
284 return displayId;
285 }
286
allocatePhysicalDisplay(hal::HWDisplayId hwcDisplayId,DisplayId displayId)287 void HWComposer::allocatePhysicalDisplay(hal::HWDisplayId hwcDisplayId, DisplayId displayId) {
288 if (!mInternalHwcDisplayId) {
289 mInternalHwcDisplayId = hwcDisplayId;
290 } else if (mInternalHwcDisplayId != hwcDisplayId && !mExternalHwcDisplayId) {
291 mExternalHwcDisplayId = hwcDisplayId;
292 }
293
294 auto& displayData = mDisplayData[displayId];
295 auto newDisplay =
296 std::make_unique<HWC2::impl::Display>(*mComposer.get(), mCapabilities, hwcDisplayId,
297 hal::DisplayType::PHYSICAL);
298 newDisplay->setConnected(true);
299 displayData.hwcDisplay = std::move(newDisplay);
300 mPhysicalDisplayIdMap[hwcDisplayId] = displayId;
301 }
302
createLayer(DisplayId displayId)303 HWC2::Layer* HWComposer::createLayer(DisplayId displayId) {
304 RETURN_IF_INVALID_DISPLAY(displayId, nullptr);
305
306 HWC2::Layer* layer;
307 auto error = mDisplayData[displayId].hwcDisplay->createLayer(&layer);
308 RETURN_IF_HWC_ERROR(error, displayId, nullptr);
309 return layer;
310 }
311
destroyLayer(DisplayId displayId,HWC2::Layer * layer)312 void HWComposer::destroyLayer(DisplayId displayId, HWC2::Layer* layer) {
313 RETURN_IF_INVALID_DISPLAY(displayId);
314
315 auto error = mDisplayData[displayId].hwcDisplay->destroyLayer(layer);
316 RETURN_IF_HWC_ERROR(error, displayId);
317 }
318
getRefreshTimestamp(DisplayId displayId) const319 nsecs_t HWComposer::getRefreshTimestamp(DisplayId displayId) const {
320 RETURN_IF_INVALID_DISPLAY(displayId, 0);
321 const auto& displayData = mDisplayData.at(displayId);
322 // this returns the last refresh timestamp.
323 // if the last one is not available, we estimate it based on
324 // the refresh period and whatever closest timestamp we have.
325 std::lock_guard lock(displayData.lastHwVsyncLock);
326 nsecs_t now = systemTime(CLOCK_MONOTONIC);
327 auto vsyncPeriodNanos = getDisplayVsyncPeriod(displayId);
328 return now - ((now - displayData.lastHwVsync) % vsyncPeriodNanos);
329 }
330
isConnected(DisplayId displayId) const331 bool HWComposer::isConnected(DisplayId displayId) const {
332 RETURN_IF_INVALID_DISPLAY(displayId, false);
333 return mDisplayData.at(displayId).hwcDisplay->isConnected();
334 }
335
getConfigs(DisplayId displayId) const336 std::vector<std::shared_ptr<const HWC2::Display::Config>> HWComposer::getConfigs(
337 DisplayId displayId) const {
338 RETURN_IF_INVALID_DISPLAY(displayId, {});
339
340 const auto& displayData = mDisplayData.at(displayId);
341 auto configs = displayData.hwcDisplay->getConfigs();
342 if (displayData.configMap.empty()) {
343 for (size_t i = 0; i < configs.size(); ++i) {
344 displayData.configMap[i] = configs[i];
345 }
346 }
347 return configs;
348 }
349
getActiveConfig(DisplayId displayId) const350 std::shared_ptr<const HWC2::Display::Config> HWComposer::getActiveConfig(
351 DisplayId displayId) const {
352 RETURN_IF_INVALID_DISPLAY(displayId, nullptr);
353
354 std::shared_ptr<const HWC2::Display::Config> config;
355 auto error = mDisplayData.at(displayId).hwcDisplay->getActiveConfig(&config);
356 if (error == hal::Error::BAD_CONFIG) {
357 LOG_DISPLAY_ERROR(displayId, "No active config");
358 return nullptr;
359 }
360
361 RETURN_IF_HWC_ERROR(error, displayId, nullptr);
362
363 if (!config) {
364 LOG_DISPLAY_ERROR(displayId, "Unknown config");
365 return nullptr;
366 }
367
368 return config;
369 }
370
371 // Composer 2.4
372
getDisplayConnectionType(DisplayId displayId) const373 DisplayConnectionType HWComposer::getDisplayConnectionType(DisplayId displayId) const {
374 RETURN_IF_INVALID_DISPLAY(displayId, DisplayConnectionType::Internal);
375 const auto& hwcDisplay = mDisplayData.at(displayId).hwcDisplay;
376
377 DisplayConnectionType type;
378 const auto error = hwcDisplay->getConnectionType(&type);
379
380 const auto FALLBACK_TYPE = hwcDisplay->getId() == mInternalHwcDisplayId
381 ? DisplayConnectionType::Internal
382 : DisplayConnectionType::External;
383
384 RETURN_IF_HWC_ERROR(error, displayId, FALLBACK_TYPE);
385 return type;
386 }
387
isVsyncPeriodSwitchSupported(DisplayId displayId) const388 bool HWComposer::isVsyncPeriodSwitchSupported(DisplayId displayId) const {
389 RETURN_IF_INVALID_DISPLAY(displayId, false);
390 return mDisplayData.at(displayId).hwcDisplay->isVsyncPeriodSwitchSupported();
391 }
392
getDisplayVsyncPeriod(DisplayId displayId) const393 nsecs_t HWComposer::getDisplayVsyncPeriod(DisplayId displayId) const {
394 RETURN_IF_INVALID_DISPLAY(displayId, 0);
395
396 nsecs_t vsyncPeriodNanos;
397 auto error = mDisplayData.at(displayId).hwcDisplay->getDisplayVsyncPeriod(&vsyncPeriodNanos);
398 RETURN_IF_HWC_ERROR(error, displayId, 0);
399 return vsyncPeriodNanos;
400 }
401
getActiveConfigIndex(DisplayId displayId) const402 int HWComposer::getActiveConfigIndex(DisplayId displayId) const {
403 RETURN_IF_INVALID_DISPLAY(displayId, -1);
404
405 int index;
406 auto error = mDisplayData.at(displayId).hwcDisplay->getActiveConfigIndex(&index);
407 if (error == hal::Error::BAD_CONFIG) {
408 LOG_DISPLAY_ERROR(displayId, "No active config");
409 return -1;
410 }
411
412 RETURN_IF_HWC_ERROR(error, displayId, -1);
413
414 if (index < 0) {
415 LOG_DISPLAY_ERROR(displayId, "Unknown config");
416 return -1;
417 }
418
419 return index;
420 }
421
getColorModes(DisplayId displayId) const422 std::vector<ui::ColorMode> HWComposer::getColorModes(DisplayId displayId) const {
423 RETURN_IF_INVALID_DISPLAY(displayId, {});
424
425 std::vector<ui::ColorMode> modes;
426 auto error = mDisplayData.at(displayId).hwcDisplay->getColorModes(&modes);
427 RETURN_IF_HWC_ERROR(error, displayId, {});
428 return modes;
429 }
430
setActiveColorMode(DisplayId displayId,ui::ColorMode mode,ui::RenderIntent renderIntent)431 status_t HWComposer::setActiveColorMode(DisplayId displayId, ui::ColorMode mode,
432 ui::RenderIntent renderIntent) {
433 RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
434
435 auto& displayData = mDisplayData[displayId];
436 auto error = displayData.hwcDisplay->setColorMode(mode, renderIntent);
437 RETURN_IF_HWC_ERROR_FOR(("setColorMode(" + decodeColorMode(mode) + ", " +
438 decodeRenderIntent(renderIntent) + ")")
439 .c_str(),
440 error, displayId, UNKNOWN_ERROR);
441
442 return NO_ERROR;
443 }
444
setVsyncEnabled(DisplayId displayId,hal::Vsync enabled)445 void HWComposer::setVsyncEnabled(DisplayId displayId, hal::Vsync enabled) {
446 RETURN_IF_INVALID_DISPLAY(displayId);
447 auto& displayData = mDisplayData[displayId];
448
449 if (displayData.isVirtual) {
450 LOG_DISPLAY_ERROR(displayId, "Invalid operation on virtual display");
451 return;
452 }
453
454 // NOTE: we use our own internal lock here because we have to call
455 // into the HWC with the lock held, and we want to make sure
456 // that even if HWC blocks (which it shouldn't), it won't
457 // affect other threads.
458 std::lock_guard lock(displayData.vsyncEnabledLock);
459 if (enabled == displayData.vsyncEnabled) {
460 return;
461 }
462
463 ATRACE_CALL();
464 auto error = displayData.hwcDisplay->setVsyncEnabled(enabled);
465 RETURN_IF_HWC_ERROR(error, displayId);
466
467 displayData.vsyncEnabled = enabled;
468
469 const auto tag = "HW_VSYNC_ON_" + to_string(displayId);
470 ATRACE_INT(tag.c_str(), enabled == hal::Vsync::ENABLE ? 1 : 0);
471 }
472
setClientTarget(DisplayId displayId,uint32_t slot,const sp<Fence> & acquireFence,const sp<GraphicBuffer> & target,ui::Dataspace dataspace)473 status_t HWComposer::setClientTarget(DisplayId displayId, uint32_t slot,
474 const sp<Fence>& acquireFence, const sp<GraphicBuffer>& target,
475 ui::Dataspace dataspace) {
476 RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
477
478 ALOGV("%s for display %s", __FUNCTION__, to_string(displayId).c_str());
479 auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
480 auto error = hwcDisplay->setClientTarget(slot, target, acquireFence, dataspace);
481 RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
482 return NO_ERROR;
483 }
484
getDeviceCompositionChanges(DisplayId displayId,bool frameUsesClientComposition,std::optional<android::HWComposer::DeviceRequestedChanges> * outChanges)485 status_t HWComposer::getDeviceCompositionChanges(
486 DisplayId displayId, bool frameUsesClientComposition,
487 std::optional<android::HWComposer::DeviceRequestedChanges>* outChanges) {
488 ATRACE_CALL();
489
490 RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
491
492 auto& displayData = mDisplayData[displayId];
493 auto& hwcDisplay = displayData.hwcDisplay;
494 if (!hwcDisplay->isConnected()) {
495 return NO_ERROR;
496 }
497
498 uint32_t numTypes = 0;
499 uint32_t numRequests = 0;
500
501 hal::Error error = hal::Error::NONE;
502
503 // First try to skip validate altogether when there is no client
504 // composition. When there is client composition, since we haven't
505 // rendered to the client target yet, we should not attempt to skip
506 // validate.
507 displayData.validateWasSkipped = false;
508 if (!frameUsesClientComposition) {
509 sp<Fence> outPresentFence;
510 uint32_t state = UINT32_MAX;
511 error = hwcDisplay->presentOrValidate(&numTypes, &numRequests, &outPresentFence , &state);
512 if (!hasChangesError(error)) {
513 RETURN_IF_HWC_ERROR_FOR("presentOrValidate", error, displayId, UNKNOWN_ERROR);
514 }
515 if (state == 1) { //Present Succeeded.
516 std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
517 error = hwcDisplay->getReleaseFences(&releaseFences);
518 displayData.releaseFences = std::move(releaseFences);
519 displayData.lastPresentFence = outPresentFence;
520 displayData.validateWasSkipped = true;
521 displayData.presentError = error;
522 return NO_ERROR;
523 }
524 // Present failed but Validate ran.
525 } else {
526 error = hwcDisplay->validate(&numTypes, &numRequests);
527 }
528 ALOGV("SkipValidate failed, Falling back to SLOW validate/present");
529 if (!hasChangesError(error)) {
530 RETURN_IF_HWC_ERROR_FOR("validate", error, displayId, BAD_INDEX);
531 }
532
533 android::HWComposer::DeviceRequestedChanges::ChangedTypes changedTypes;
534 changedTypes.reserve(numTypes);
535 error = hwcDisplay->getChangedCompositionTypes(&changedTypes);
536 RETURN_IF_HWC_ERROR_FOR("getChangedCompositionTypes", error, displayId, BAD_INDEX);
537
538 auto displayRequests = static_cast<hal::DisplayRequest>(0);
539 android::HWComposer::DeviceRequestedChanges::LayerRequests layerRequests;
540 layerRequests.reserve(numRequests);
541 error = hwcDisplay->getRequests(&displayRequests, &layerRequests);
542 RETURN_IF_HWC_ERROR_FOR("getRequests", error, displayId, BAD_INDEX);
543
544 DeviceRequestedChanges::ClientTargetProperty clientTargetProperty;
545 error = hwcDisplay->getClientTargetProperty(&clientTargetProperty);
546
547 outChanges->emplace(DeviceRequestedChanges{std::move(changedTypes), std::move(displayRequests),
548 std::move(layerRequests),
549 std::move(clientTargetProperty)});
550 error = hwcDisplay->acceptChanges();
551 RETURN_IF_HWC_ERROR_FOR("acceptChanges", error, displayId, BAD_INDEX);
552
553 return NO_ERROR;
554 }
555
getPresentFence(DisplayId displayId) const556 sp<Fence> HWComposer::getPresentFence(DisplayId displayId) const {
557 RETURN_IF_INVALID_DISPLAY(displayId, Fence::NO_FENCE);
558 return mDisplayData.at(displayId).lastPresentFence;
559 }
560
getLayerReleaseFence(DisplayId displayId,HWC2::Layer * layer) const561 sp<Fence> HWComposer::getLayerReleaseFence(DisplayId displayId, HWC2::Layer* layer) const {
562 RETURN_IF_INVALID_DISPLAY(displayId, Fence::NO_FENCE);
563 const auto& displayFences = mDisplayData.at(displayId).releaseFences;
564 auto fence = displayFences.find(layer);
565 if (fence == displayFences.end()) {
566 ALOGV("getLayerReleaseFence: Release fence not found");
567 return Fence::NO_FENCE;
568 }
569 return fence->second;
570 }
571
presentAndGetReleaseFences(DisplayId displayId)572 status_t HWComposer::presentAndGetReleaseFences(DisplayId displayId) {
573 ATRACE_CALL();
574
575 RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
576
577 auto& displayData = mDisplayData[displayId];
578 auto& hwcDisplay = displayData.hwcDisplay;
579
580 if (displayData.validateWasSkipped) {
581 // explicitly flush all pending commands
582 auto error = static_cast<hal::Error>(mComposer->executeCommands());
583 RETURN_IF_HWC_ERROR_FOR("executeCommands", error, displayId, UNKNOWN_ERROR);
584 RETURN_IF_HWC_ERROR_FOR("present", displayData.presentError, displayId, UNKNOWN_ERROR);
585 return NO_ERROR;
586 }
587
588 auto error = hwcDisplay->present(&displayData.lastPresentFence);
589 RETURN_IF_HWC_ERROR_FOR("present", error, displayId, UNKNOWN_ERROR);
590
591 std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
592 error = hwcDisplay->getReleaseFences(&releaseFences);
593 RETURN_IF_HWC_ERROR_FOR("getReleaseFences", error, displayId, UNKNOWN_ERROR);
594
595 displayData.releaseFences = std::move(releaseFences);
596
597 return NO_ERROR;
598 }
599
setPowerMode(DisplayId displayId,hal::PowerMode mode)600 status_t HWComposer::setPowerMode(DisplayId displayId, hal::PowerMode mode) {
601 RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
602
603 const auto& displayData = mDisplayData[displayId];
604 if (displayData.isVirtual) {
605 LOG_DISPLAY_ERROR(displayId, "Invalid operation on virtual display");
606 return INVALID_OPERATION;
607 }
608
609 if (mode == hal::PowerMode::OFF) {
610 setVsyncEnabled(displayId, hal::Vsync::DISABLE);
611 }
612
613 auto& hwcDisplay = displayData.hwcDisplay;
614 switch (mode) {
615 case hal::PowerMode::OFF:
616 case hal::PowerMode::ON:
617 ALOGV("setPowerMode: Calling HWC %s", to_string(mode).c_str());
618 {
619 auto error = hwcDisplay->setPowerMode(mode);
620 if (error != hal::Error::NONE) {
621 LOG_HWC_ERROR(("setPowerMode(" + to_string(mode) + ")").c_str(), error,
622 displayId);
623 }
624 }
625 break;
626 case hal::PowerMode::DOZE:
627 case hal::PowerMode::DOZE_SUSPEND:
628 ALOGV("setPowerMode: Calling HWC %s", to_string(mode).c_str());
629 {
630 bool supportsDoze = false;
631 auto error = hwcDisplay->supportsDoze(&supportsDoze);
632 if (error != hal::Error::NONE) {
633 LOG_HWC_ERROR("supportsDoze", error, displayId);
634 }
635
636 if (!supportsDoze) {
637 mode = hal::PowerMode::ON;
638 }
639
640 error = hwcDisplay->setPowerMode(mode);
641 if (error != hal::Error::NONE) {
642 LOG_HWC_ERROR(("setPowerMode(" + to_string(mode) + ")").c_str(), error,
643 displayId);
644 }
645 }
646 break;
647 default:
648 ALOGV("setPowerMode: Not calling HWC");
649 break;
650 }
651
652 return NO_ERROR;
653 }
654
setActiveConfigWithConstraints(DisplayId displayId,size_t configId,const hal::VsyncPeriodChangeConstraints & constraints,hal::VsyncPeriodChangeTimeline * outTimeline)655 status_t HWComposer::setActiveConfigWithConstraints(
656 DisplayId displayId, size_t configId, const hal::VsyncPeriodChangeConstraints& constraints,
657 hal::VsyncPeriodChangeTimeline* outTimeline) {
658 RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
659
660 auto& displayData = mDisplayData[displayId];
661 if (displayData.configMap.count(configId) == 0) {
662 LOG_DISPLAY_ERROR(displayId, ("Invalid config " + std::to_string(configId)).c_str());
663 return BAD_INDEX;
664 }
665
666 auto error =
667 displayData.hwcDisplay->setActiveConfigWithConstraints(displayData.configMap[configId],
668 constraints, outTimeline);
669 RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
670 return NO_ERROR;
671 }
672
setColorTransform(DisplayId displayId,const mat4 & transform)673 status_t HWComposer::setColorTransform(DisplayId displayId, const mat4& transform) {
674 RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
675
676 auto& displayData = mDisplayData[displayId];
677 bool isIdentity = transform == mat4();
678 auto error = displayData.hwcDisplay
679 ->setColorTransform(transform,
680 isIdentity ? hal::ColorTransform::IDENTITY
681 : hal::ColorTransform::ARBITRARY_MATRIX);
682 RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
683 return NO_ERROR;
684 }
685
disconnectDisplay(DisplayId displayId)686 void HWComposer::disconnectDisplay(DisplayId displayId) {
687 RETURN_IF_INVALID_DISPLAY(displayId);
688 auto& displayData = mDisplayData[displayId];
689
690 // If this was a virtual display, add its slot back for reuse by future
691 // virtual displays
692 if (displayData.isVirtual) {
693 mFreeVirtualDisplayIds.insert(displayId);
694 ++mRemainingHwcVirtualDisplays;
695 }
696
697 const auto hwcDisplayId = displayData.hwcDisplay->getId();
698
699 // TODO(b/74619554): Select internal/external display from remaining displays.
700 if (hwcDisplayId == mInternalHwcDisplayId) {
701 mInternalHwcDisplayId.reset();
702 } else if (hwcDisplayId == mExternalHwcDisplayId) {
703 mExternalHwcDisplayId.reset();
704 }
705 mPhysicalDisplayIdMap.erase(hwcDisplayId);
706 mDisplayData.erase(displayId);
707 }
708
setOutputBuffer(DisplayId displayId,const sp<Fence> & acquireFence,const sp<GraphicBuffer> & buffer)709 status_t HWComposer::setOutputBuffer(DisplayId displayId, const sp<Fence>& acquireFence,
710 const sp<GraphicBuffer>& buffer) {
711 RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
712 const auto& displayData = mDisplayData[displayId];
713
714 if (!displayData.isVirtual) {
715 LOG_DISPLAY_ERROR(displayId, "Invalid operation on physical display");
716 return INVALID_OPERATION;
717 }
718
719 auto error = displayData.hwcDisplay->setOutputBuffer(buffer, acquireFence);
720 RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
721 return NO_ERROR;
722 }
723
clearReleaseFences(DisplayId displayId)724 void HWComposer::clearReleaseFences(DisplayId displayId) {
725 RETURN_IF_INVALID_DISPLAY(displayId);
726 mDisplayData[displayId].releaseFences.clear();
727 }
728
getHdrCapabilities(DisplayId displayId,HdrCapabilities * outCapabilities)729 status_t HWComposer::getHdrCapabilities(DisplayId displayId, HdrCapabilities* outCapabilities) {
730 RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
731
732 auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
733 auto error = hwcDisplay->getHdrCapabilities(outCapabilities);
734 RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
735 return NO_ERROR;
736 }
737
getSupportedPerFrameMetadata(DisplayId displayId) const738 int32_t HWComposer::getSupportedPerFrameMetadata(DisplayId displayId) const {
739 RETURN_IF_INVALID_DISPLAY(displayId, 0);
740 return mDisplayData.at(displayId).hwcDisplay->getSupportedPerFrameMetadata();
741 }
742
getRenderIntents(DisplayId displayId,ui::ColorMode colorMode) const743 std::vector<ui::RenderIntent> HWComposer::getRenderIntents(DisplayId displayId,
744 ui::ColorMode colorMode) const {
745 RETURN_IF_INVALID_DISPLAY(displayId, {});
746
747 std::vector<ui::RenderIntent> renderIntents;
748 auto error = mDisplayData.at(displayId).hwcDisplay->getRenderIntents(colorMode, &renderIntents);
749 RETURN_IF_HWC_ERROR(error, displayId, {});
750 return renderIntents;
751 }
752
getDataspaceSaturationMatrix(DisplayId displayId,ui::Dataspace dataspace)753 mat4 HWComposer::getDataspaceSaturationMatrix(DisplayId displayId, ui::Dataspace dataspace) {
754 RETURN_IF_INVALID_DISPLAY(displayId, {});
755
756 mat4 matrix;
757 auto error = mDisplayData[displayId].hwcDisplay->getDataspaceSaturationMatrix(dataspace,
758 &matrix);
759 RETURN_IF_HWC_ERROR(error, displayId, {});
760 return matrix;
761 }
762
getDisplayedContentSamplingAttributes(DisplayId displayId,ui::PixelFormat * outFormat,ui::Dataspace * outDataspace,uint8_t * outComponentMask)763 status_t HWComposer::getDisplayedContentSamplingAttributes(DisplayId displayId,
764 ui::PixelFormat* outFormat,
765 ui::Dataspace* outDataspace,
766 uint8_t* outComponentMask) {
767 RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
768 const auto error =
769 mDisplayData[displayId]
770 .hwcDisplay->getDisplayedContentSamplingAttributes(outFormat, outDataspace,
771 outComponentMask);
772 if (error == hal::Error::UNSUPPORTED) RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
773 RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
774 return NO_ERROR;
775 }
776
setDisplayContentSamplingEnabled(DisplayId displayId,bool enabled,uint8_t componentMask,uint64_t maxFrames)777 status_t HWComposer::setDisplayContentSamplingEnabled(DisplayId displayId, bool enabled,
778 uint8_t componentMask, uint64_t maxFrames) {
779 RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
780 const auto error =
781 mDisplayData[displayId].hwcDisplay->setDisplayContentSamplingEnabled(enabled,
782 componentMask,
783 maxFrames);
784
785 if (error == hal::Error::UNSUPPORTED) RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
786 if (error == hal::Error::BAD_PARAMETER) RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
787 RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
788 return NO_ERROR;
789 }
790
getDisplayedContentSample(DisplayId displayId,uint64_t maxFrames,uint64_t timestamp,DisplayedFrameStats * outStats)791 status_t HWComposer::getDisplayedContentSample(DisplayId displayId, uint64_t maxFrames,
792 uint64_t timestamp, DisplayedFrameStats* outStats) {
793 RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
794 const auto error =
795 mDisplayData[displayId].hwcDisplay->getDisplayedContentSample(maxFrames, timestamp,
796 outStats);
797 RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
798 return NO_ERROR;
799 }
800
setDisplayBrightness(DisplayId displayId,float brightness)801 std::future<status_t> HWComposer::setDisplayBrightness(DisplayId displayId, float brightness) {
802 RETURN_IF_INVALID_DISPLAY(displayId, promise::yield<status_t>(BAD_INDEX));
803 auto& display = mDisplayData[displayId].hwcDisplay;
804
805 return promise::chain(display->setDisplayBrightness(brightness))
806 .then([displayId](hal::Error error) -> status_t {
807 if (error == hal::Error::UNSUPPORTED) {
808 RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
809 }
810 if (error == hal::Error::BAD_PARAMETER) {
811 RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
812 }
813 RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
814 return NO_ERROR;
815 });
816 }
817
isUsingVrComposer() const818 bool HWComposer::isUsingVrComposer() const {
819 return getComposer()->isUsingVrComposer();
820 }
821
setAutoLowLatencyMode(DisplayId displayId,bool on)822 status_t HWComposer::setAutoLowLatencyMode(DisplayId displayId, bool on) {
823 RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
824 const auto error = mDisplayData[displayId].hwcDisplay->setAutoLowLatencyMode(on);
825 if (error == hal::Error::UNSUPPORTED) {
826 RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
827 }
828 if (error == hal::Error::BAD_PARAMETER) {
829 RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
830 }
831 RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
832 return NO_ERROR;
833 }
834
getSupportedContentTypes(DisplayId displayId,std::vector<hal::ContentType> * outSupportedContentTypes)835 status_t HWComposer::getSupportedContentTypes(
836 DisplayId displayId, std::vector<hal::ContentType>* outSupportedContentTypes) {
837 RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
838 const auto error =
839 mDisplayData[displayId].hwcDisplay->getSupportedContentTypes(outSupportedContentTypes);
840
841 RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
842
843 return NO_ERROR;
844 }
845
setContentType(DisplayId displayId,hal::ContentType contentType)846 status_t HWComposer::setContentType(DisplayId displayId, hal::ContentType contentType) {
847 RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
848 const auto error = mDisplayData[displayId].hwcDisplay->setContentType(contentType);
849 if (error == hal::Error::UNSUPPORTED) {
850 RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
851 }
852 if (error == hal::Error::BAD_PARAMETER) {
853 RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
854 }
855 RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
856
857 return NO_ERROR;
858 }
859
getSupportedLayerGenericMetadata() const860 const std::unordered_map<std::string, bool>& HWComposer::getSupportedLayerGenericMetadata() const {
861 return mSupportedLayerGenericMetadata;
862 }
863
dump(std::string & result) const864 void HWComposer::dump(std::string& result) const {
865 result.append(mComposer->dumpDebugInfo());
866 }
867
toPhysicalDisplayId(hal::HWDisplayId hwcDisplayId) const868 std::optional<DisplayId> HWComposer::toPhysicalDisplayId(hal::HWDisplayId hwcDisplayId) const {
869 if (const auto it = mPhysicalDisplayIdMap.find(hwcDisplayId);
870 it != mPhysicalDisplayIdMap.end()) {
871 return it->second;
872 }
873 return {};
874 }
875
fromPhysicalDisplayId(DisplayId displayId) const876 std::optional<hal::HWDisplayId> HWComposer::fromPhysicalDisplayId(DisplayId displayId) const {
877 if (const auto it = mDisplayData.find(displayId);
878 it != mDisplayData.end() && !it->second.isVirtual) {
879 return it->second.hwcDisplay->getId();
880 }
881 return {};
882 }
883
shouldIgnoreHotplugConnect(hal::HWDisplayId hwcDisplayId,bool hasDisplayIdentificationData) const884 bool HWComposer::shouldIgnoreHotplugConnect(hal::HWDisplayId hwcDisplayId,
885 bool hasDisplayIdentificationData) const {
886 if (isUsingVrComposer() && mInternalHwcDisplayId) {
887 ALOGE("Ignoring connection of external display %" PRIu64 " in VR mode", hwcDisplayId);
888 return true;
889 }
890
891 if (mHasMultiDisplaySupport && !hasDisplayIdentificationData) {
892 ALOGE("Ignoring connection of display %" PRIu64 " without identification data",
893 hwcDisplayId);
894 return true;
895 }
896
897 if (!mHasMultiDisplaySupport && mInternalHwcDisplayId && mExternalHwcDisplayId) {
898 ALOGE("Ignoring connection of tertiary display %" PRIu64, hwcDisplayId);
899 return true;
900 }
901
902 return false;
903 }
904
onHotplugConnect(hal::HWDisplayId hwcDisplayId)905 std::optional<DisplayIdentificationInfo> HWComposer::onHotplugConnect(
906 hal::HWDisplayId hwcDisplayId) {
907 std::optional<DisplayIdentificationInfo> info;
908 if (const auto displayId = toPhysicalDisplayId(hwcDisplayId)) {
909 info = DisplayIdentificationInfo{.id = *displayId,
910 .name = std::string(),
911 .deviceProductInfo = std::nullopt};
912 } else {
913 uint8_t port;
914 DisplayIdentificationData data;
915 const bool hasDisplayIdentificationData =
916 getDisplayIdentificationData(hwcDisplayId, &port, &data);
917 if (mPhysicalDisplayIdMap.empty()) {
918 mHasMultiDisplaySupport = hasDisplayIdentificationData;
919 ALOGI("Switching to %s multi-display mode",
920 mHasMultiDisplaySupport ? "generalized" : "legacy");
921 }
922
923 if (shouldIgnoreHotplugConnect(hwcDisplayId, hasDisplayIdentificationData)) {
924 return {};
925 }
926
927 info = [this, hwcDisplayId, &port, &data, hasDisplayIdentificationData] {
928 const bool isPrimary = !mInternalHwcDisplayId;
929 if (mHasMultiDisplaySupport) {
930 if (const auto info = parseDisplayIdentificationData(port, data)) {
931 return *info;
932 }
933 ALOGE("Failed to parse identification data for display %" PRIu64, hwcDisplayId);
934 } else {
935 ALOGW_IF(hasDisplayIdentificationData,
936 "Ignoring identification data for display %" PRIu64, hwcDisplayId);
937 port = isPrimary ? LEGACY_DISPLAY_TYPE_PRIMARY : LEGACY_DISPLAY_TYPE_EXTERNAL;
938 }
939
940 return DisplayIdentificationInfo{.id = getFallbackDisplayId(port),
941 .name = isPrimary ? "Internal display"
942 : "External display",
943 .deviceProductInfo = std::nullopt};
944 }();
945 }
946
947 if (!isConnected(info->id)) {
948 allocatePhysicalDisplay(hwcDisplayId, info->id);
949 }
950 return info;
951 }
952
onHotplugDisconnect(hal::HWDisplayId hwcDisplayId)953 std::optional<DisplayIdentificationInfo> HWComposer::onHotplugDisconnect(
954 hal::HWDisplayId hwcDisplayId) {
955 const auto displayId = toPhysicalDisplayId(hwcDisplayId);
956 if (!displayId) {
957 ALOGE("Ignoring disconnection of invalid HWC display %" PRIu64, hwcDisplayId);
958 return {};
959 }
960
961 // The display will later be destroyed by a call to
962 // destroyDisplay(). For now we just mark it disconnected.
963 if (isConnected(*displayId)) {
964 mDisplayData[*displayId].hwcDisplay->setConnected(false);
965 } else {
966 ALOGW("Attempted to disconnect unknown display %" PRIu64, hwcDisplayId);
967 }
968 // The cleanup of Disconnect is handled through HWComposer::disconnectDisplay
969 // via SurfaceFlinger's onHotplugReceived callback handling
970 return DisplayIdentificationInfo{.id = *displayId,
971 .name = std::string(),
972 .deviceProductInfo = std::nullopt};
973 }
974
loadCapabilities()975 void HWComposer::loadCapabilities() {
976 static_assert(sizeof(hal::Capability) == sizeof(int32_t), "Capability size has changed");
977 auto capabilities = mComposer->getCapabilities();
978 for (auto capability : capabilities) {
979 mCapabilities.emplace(static_cast<hal::Capability>(capability));
980 }
981 }
982
loadLayerMetadataSupport()983 void HWComposer::loadLayerMetadataSupport() {
984 mSupportedLayerGenericMetadata.clear();
985
986 std::vector<Hwc2::IComposerClient::LayerGenericMetadataKey> supportedMetadataKeyInfo;
987 const auto error = mComposer->getLayerGenericMetadataKeys(&supportedMetadataKeyInfo);
988 if (error != hardware::graphics::composer::V2_4::Error::NONE) {
989 ALOGE("%s: %s failed: %s (%d)", __FUNCTION__, "getLayerGenericMetadataKeys",
990 toString(error).c_str(), static_cast<int32_t>(error));
991 return;
992 }
993
994 for (const auto& [name, mandatory] : supportedMetadataKeyInfo) {
995 mSupportedLayerGenericMetadata.emplace(name, mandatory);
996 }
997 }
998
getMaxVirtualDisplayCount() const999 uint32_t HWComposer::getMaxVirtualDisplayCount() const {
1000 return mComposer->getMaxVirtualDisplayCount();
1001 }
1002
1003 } // namespace impl
1004 } // namespace android
1005
1006 // TODO(b/129481165): remove the #pragma below and fix conversion issues
1007 #pragma clang diagnostic pop // ignored "-Wconversion"
1008