1 /*
2 * Copyright 2022 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 #include "Display.h"
18
19 #include <android-base/parseint.h>
20 #include <android-base/unique_fd.h>
21 #include <pthread.h>
22 #include <sched.h>
23 #include <sync/sync.h>
24 #include <sys/types.h>
25
26 #include <algorithm>
27 #include <atomic>
28 #include <numeric>
29 #include <sstream>
30 #include <thread>
31
32 #include "Common.h"
33 #include "Device.h"
34
35 namespace aidl::android::hardware::graphics::composer3::impl {
36 namespace {
37
isValidColorMode(ColorMode mode)38 bool isValidColorMode(ColorMode mode) {
39 switch (mode) {
40 case ColorMode::NATIVE:
41 case ColorMode::STANDARD_BT601_625:
42 case ColorMode::STANDARD_BT601_625_UNADJUSTED:
43 case ColorMode::STANDARD_BT601_525:
44 case ColorMode::STANDARD_BT601_525_UNADJUSTED:
45 case ColorMode::STANDARD_BT709:
46 case ColorMode::DCI_P3:
47 case ColorMode::SRGB:
48 case ColorMode::ADOBE_RGB:
49 case ColorMode::DISPLAY_P3:
50 case ColorMode::BT2020:
51 case ColorMode::BT2100_PQ:
52 case ColorMode::BT2100_HLG:
53 case ColorMode::DISPLAY_BT2020:
54 return true;
55 default:
56 return false;
57 }
58 }
59
isValidRenderIntent(RenderIntent intent)60 bool isValidRenderIntent(RenderIntent intent) {
61 switch (intent) {
62 case RenderIntent::COLORIMETRIC:
63 case RenderIntent::ENHANCE:
64 case RenderIntent::TONE_MAP_COLORIMETRIC:
65 case RenderIntent::TONE_MAP_ENHANCE:
66 return true;
67 default:
68 return false;
69 }
70 }
71
isValidPowerMode(PowerMode mode)72 bool isValidPowerMode(PowerMode mode) {
73 switch (mode) {
74 case PowerMode::OFF:
75 case PowerMode::DOZE:
76 case PowerMode::DOZE_SUSPEND:
77 case PowerMode::ON:
78 case PowerMode::ON_SUSPEND:
79 return true;
80 default:
81 return false;
82 }
83 }
84
85 } // namespace
86
Display(FrameComposer * composer,int64_t id)87 Display::Display(FrameComposer* composer, int64_t id)
88 : mComposer(composer), mId(id), mVsyncThread(id) {
89 setLegacyEdid();
90 }
91
~Display()92 Display::~Display() {}
93
init(const std::vector<DisplayConfig> & configs,int32_t activeConfigId,const std::optional<std::vector<uint8_t>> & edid)94 HWC3::Error Display::init(const std::vector<DisplayConfig>& configs,
95 int32_t activeConfigId,
96 const std::optional<std::vector<uint8_t>>& edid) {
97 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
98
99 for (const DisplayConfig& config : configs) {
100 mConfigs.emplace(config.getId(), config);
101 }
102
103 mActiveConfigId = activeConfigId;
104
105 auto bootConfigIdOpt = getBootConfigId();
106 if (bootConfigIdOpt) {
107 mActiveConfigId = *bootConfigIdOpt;
108 }
109
110 if (edid.has_value()) {
111 mEdid = *edid;
112 }
113
114 auto it = mConfigs.find(activeConfigId);
115 if (it == mConfigs.end()) {
116 ALOGE("%s: display:%" PRId64 "missing config:%" PRId32, __FUNCTION__, mId,
117 activeConfigId);
118 return HWC3::Error::NoResources;
119 }
120
121 const auto& activeConfig = it->second;
122 const auto activeConfigString = activeConfig.toString();
123 ALOGD("%s display:%" PRId64 " with config:%s", __FUNCTION__, mId,
124 activeConfigString.c_str());
125
126 mVsyncThread.start(activeConfig.getVsyncPeriod());
127
128 return HWC3::Error::None;
129 }
130
updateParameters(uint32_t width,uint32_t height,uint32_t dpiX,uint32_t dpiY,uint32_t refreshRateHz,const std::optional<std::vector<uint8_t>> & edid)131 HWC3::Error Display::updateParameters(
132 uint32_t width, uint32_t height, uint32_t dpiX, uint32_t dpiY,
133 uint32_t refreshRateHz, const std::optional<std::vector<uint8_t>>& edid) {
134 DEBUG_LOG("%s: updating display:%" PRId64
135 " width:%d height:%d dpiX:%d dpiY:%d refreshRateHz:%d",
136 __FUNCTION__, mId, width, height, dpiX, dpiY, refreshRateHz);
137
138 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
139
140 auto it = mConfigs.find(*mActiveConfigId);
141 if (it == mConfigs.end()) {
142 ALOGE("%s: failed to find config %" PRId32, __func__, *mActiveConfigId);
143 return HWC3::Error::NoResources;
144 }
145 it->second.setAttribute(DisplayAttribute::VSYNC_PERIOD,
146 1000 * 1000 * 1000 / refreshRateHz);
147 it->second.setAttribute(DisplayAttribute::WIDTH, width);
148 it->second.setAttribute(DisplayAttribute::HEIGHT, height);
149 it->second.setAttribute(DisplayAttribute::DPI_X, dpiX);
150 it->second.setAttribute(DisplayAttribute::DPI_Y, dpiY);
151
152 if (edid.has_value()) {
153 mEdid = *edid;
154 }
155
156 return HWC3::Error::None;
157 }
158
createLayer(int64_t * outLayerId)159 HWC3::Error Display::createLayer(int64_t* outLayerId) {
160 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
161
162 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
163
164 auto layer = std::make_unique<Layer>();
165
166 const int64_t layerId = layer->getId();
167 DEBUG_LOG("%s: created layer:%" PRId64, __FUNCTION__, layerId);
168
169 mLayers.emplace(layerId, std::move(layer));
170
171 *outLayerId = layerId;
172
173 return HWC3::Error::None;
174 }
175
destroyLayer(int64_t layerId)176 HWC3::Error Display::destroyLayer(int64_t layerId) {
177 DEBUG_LOG("%s: destroy layer:%" PRId64, __FUNCTION__, layerId);
178
179 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
180
181 auto it = mLayers.find(layerId);
182 if (it == mLayers.end()) {
183 ALOGE("%s display:%" PRId64 " has no such layer:%." PRId64, __FUNCTION__,
184 mId, layerId);
185 return HWC3::Error::BadLayer;
186 }
187
188 mOrderedLayers.erase(std::remove_if(mOrderedLayers.begin(), //
189 mOrderedLayers.end(), //
190 [layerId](Layer* layer) {
191 return layer->getId() == layerId;
192 }),
193 mOrderedLayers.end());
194
195 mLayers.erase(it);
196
197 DEBUG_LOG("%s: destroyed layer:%" PRId64, __FUNCTION__, layerId);
198 return HWC3::Error::None;
199 }
200
getActiveConfig(int32_t * outConfig)201 HWC3::Error Display::getActiveConfig(int32_t* outConfig) {
202 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
203
204 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
205
206 if (!mActiveConfigId) {
207 ALOGW("%s: display:%" PRId64 " has no active config.", __FUNCTION__, mId);
208 return HWC3::Error::BadConfig;
209 }
210
211 *outConfig = *mActiveConfigId;
212 return HWC3::Error::None;
213 }
214
getDisplayAttribute(int32_t configId,DisplayAttribute attribute,int32_t * outValue)215 HWC3::Error Display::getDisplayAttribute(int32_t configId,
216 DisplayAttribute attribute,
217 int32_t* outValue) {
218 auto attributeString = toString(attribute);
219 DEBUG_LOG("%s: display:%" PRId64 " attribute:%s", __FUNCTION__, mId,
220 attributeString.c_str());
221
222 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
223
224 auto it = mConfigs.find(configId);
225 if (it == mConfigs.end()) {
226 ALOGW("%s: display:%" PRId64 " bad config:%" PRId32, __FUNCTION__, mId,
227 configId);
228 return HWC3::Error::BadConfig;
229 }
230
231 const DisplayConfig& config = it->second;
232 *outValue = config.getAttribute(attribute);
233 DEBUG_LOG("%s: display:%" PRId64 " attribute:%s value is %" PRIi32,
234 __FUNCTION__, mId, attributeString.c_str(), *outValue);
235 return HWC3::Error::None;
236 }
237
getColorModes(std::vector<ColorMode> * outModes)238 HWC3::Error Display::getColorModes(std::vector<ColorMode>* outModes) {
239 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
240
241 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
242
243 outModes->clear();
244 outModes->insert(outModes->end(), mColorModes.begin(), mColorModes.end());
245
246 return HWC3::Error::None;
247 }
248
getDisplayCapabilities(std::vector<DisplayCapability> * outCapabilities)249 HWC3::Error Display::getDisplayCapabilities(
250 std::vector<DisplayCapability>* outCapabilities) {
251 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
252
253 outCapabilities->clear();
254 outCapabilities->push_back(DisplayCapability::SKIP_CLIENT_COLOR_TRANSFORM);
255
256 return HWC3::Error::None;
257 }
258
getDisplayConfigs(std::vector<int32_t> * outConfigIds)259 HWC3::Error Display::getDisplayConfigs(std::vector<int32_t>* outConfigIds) {
260 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
261
262 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
263
264 outConfigIds->clear();
265 outConfigIds->reserve(mConfigs.size());
266 for (const auto& [configId, _] : mConfigs) {
267 outConfigIds->push_back(configId);
268 }
269
270 return HWC3::Error::None;
271 }
272
getDisplayConnectionType(DisplayConnectionType * outType)273 HWC3::Error Display::getDisplayConnectionType(DisplayConnectionType* outType) {
274 if (IsCuttlefishFoldable() || IsAutoDevice()) {
275 // Android Auto OS needs to set all displays to INTERNAL since they're used
276 // for the passenger displays.
277 // Workaround to force all displays to INTERNAL for cf_x86_64_foldable.
278 // TODO(b/193568008): Allow configuring internal/external per display.
279 *outType = DisplayConnectionType::INTERNAL;
280 } else {
281 // Other devices default to the first display INTERNAL, others EXTERNAL.
282 *outType = mId == 0 ? DisplayConnectionType::INTERNAL
283 : DisplayConnectionType::EXTERNAL;
284 }
285 return HWC3::Error::None;
286 }
287
getDisplayIdentificationData(DisplayIdentification * outIdentification)288 HWC3::Error Display::getDisplayIdentificationData(
289 DisplayIdentification* outIdentification) {
290 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
291
292 if (outIdentification == nullptr) {
293 return HWC3::Error::BadParameter;
294 }
295
296 outIdentification->port = mId;
297 outIdentification->data = mEdid;
298
299 return HWC3::Error::None;
300 }
301
getDisplayName(std::string * outName)302 HWC3::Error Display::getDisplayName(std::string* outName) {
303 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
304
305 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
306
307 *outName = mName;
308 return HWC3::Error::None;
309 }
310
getDisplayVsyncPeriod(int32_t * outVsyncPeriod)311 HWC3::Error Display::getDisplayVsyncPeriod(int32_t* outVsyncPeriod) {
312 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
313
314 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
315
316 if (!mActiveConfigId) {
317 ALOGE("%s : display:%" PRId64 " no active config", __FUNCTION__, mId);
318 return HWC3::Error::BadConfig;
319 }
320
321 const auto it = mConfigs.find(*mActiveConfigId);
322 if (it == mConfigs.end()) {
323 ALOGE("%s : display:%" PRId64 " failed to find active config:%" PRId32,
324 __FUNCTION__, mId, *mActiveConfigId);
325 return HWC3::Error::BadConfig;
326 }
327 const DisplayConfig& activeConfig = it->second;
328
329 *outVsyncPeriod = activeConfig.getAttribute(DisplayAttribute::VSYNC_PERIOD);
330 return HWC3::Error::None;
331 }
332
getDisplayedContentSample(int64_t,int64_t,DisplayContentSample *)333 HWC3::Error Display::getDisplayedContentSample(
334 int64_t /*maxFrames*/, int64_t /*timestamp*/,
335 DisplayContentSample* /*samples*/) {
336 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
337
338 return HWC3::Error::Unsupported;
339 }
340
getDisplayedContentSamplingAttributes(DisplayContentSamplingAttributes *)341 HWC3::Error Display::getDisplayedContentSamplingAttributes(
342 DisplayContentSamplingAttributes* /*outAttributes*/) {
343 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
344
345 return HWC3::Error::Unsupported;
346 }
347
getDisplayPhysicalOrientation(common::Transform * outOrientation)348 HWC3::Error Display::getDisplayPhysicalOrientation(
349 common::Transform* outOrientation) {
350 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
351
352 *outOrientation = common::Transform::NONE;
353
354 return HWC3::Error::None;
355 }
356
getHdrCapabilities(HdrCapabilities * outCapabilities)357 HWC3::Error Display::getHdrCapabilities(HdrCapabilities* outCapabilities) {
358 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
359
360 // No supported types.
361 outCapabilities->types.clear();
362
363 return HWC3::Error::None;
364 }
365
getPerFrameMetadataKeys(std::vector<PerFrameMetadataKey> * outKeys)366 HWC3::Error Display::getPerFrameMetadataKeys(
367 std::vector<PerFrameMetadataKey>* outKeys) {
368 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
369
370 outKeys->clear();
371
372 return HWC3::Error::Unsupported;
373 }
374
getReadbackBufferAttributes(ReadbackBufferAttributes * outAttributes)375 HWC3::Error Display::getReadbackBufferAttributes(
376 ReadbackBufferAttributes* outAttributes) {
377 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
378
379 outAttributes->format = common::PixelFormat::RGBA_8888;
380 outAttributes->dataspace = common::Dataspace::UNKNOWN;
381
382 return HWC3::Error::Unsupported;
383 }
384
getReadbackBufferFence(ndk::ScopedFileDescriptor *)385 HWC3::Error Display::getReadbackBufferFence(
386 ndk::ScopedFileDescriptor* /*outAcquireFence*/) {
387 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
388
389 return HWC3::Error::Unsupported;
390 }
391
getRenderIntents(ColorMode mode,std::vector<RenderIntent> * outIntents)392 HWC3::Error Display::getRenderIntents(ColorMode mode,
393 std::vector<RenderIntent>* outIntents) {
394 const auto modeString = toString(mode);
395 DEBUG_LOG("%s: display:%" PRId64 "for mode:%s", __FUNCTION__, mId,
396 modeString.c_str());
397
398 outIntents->clear();
399
400 if (!isValidColorMode(mode)) {
401 DEBUG_LOG("%s: display:%" PRId64 "invalid mode:%s", __FUNCTION__, mId,
402 modeString.c_str());
403 return HWC3::Error::BadParameter;
404 }
405
406 outIntents->push_back(RenderIntent::COLORIMETRIC);
407
408 return HWC3::Error::None;
409 }
410
getSupportedContentTypes(std::vector<ContentType> * outTypes)411 HWC3::Error Display::getSupportedContentTypes(
412 std::vector<ContentType>* outTypes) {
413 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
414
415 outTypes->clear();
416
417 return HWC3::Error::None;
418 }
419
getDecorationSupport(std::optional<common::DisplayDecorationSupport> * outSupport)420 HWC3::Error Display::getDecorationSupport(
421 std::optional<common::DisplayDecorationSupport>* outSupport) {
422 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
423
424 outSupport->reset();
425
426 return HWC3::Error::Unsupported;
427 }
428
registerCallback(const std::shared_ptr<IComposerCallback> & callback)429 HWC3::Error Display::registerCallback(
430 const std::shared_ptr<IComposerCallback>& callback) {
431 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
432
433 mVsyncThread.setCallbacks(callback);
434
435 return HWC3::Error::Unsupported;
436 }
437
setActiveConfig(int32_t configId)438 HWC3::Error Display::setActiveConfig(int32_t configId) {
439 DEBUG_LOG("%s: display:%" PRId64 " setting active config to %" PRId32,
440 __FUNCTION__, mId, configId);
441
442 VsyncPeriodChangeConstraints constraints;
443 constraints.desiredTimeNanos = 0;
444 constraints.seamlessRequired = false;
445
446 VsyncPeriodChangeTimeline timeline;
447
448 return setActiveConfigWithConstraints(configId, constraints, &timeline);
449 }
450
setActiveConfigWithConstraints(int32_t configId,const VsyncPeriodChangeConstraints & constraints,VsyncPeriodChangeTimeline * outTimeline)451 HWC3::Error Display::setActiveConfigWithConstraints(
452 int32_t configId, const VsyncPeriodChangeConstraints& constraints,
453 VsyncPeriodChangeTimeline* outTimeline) {
454 DEBUG_LOG("%s: display:%" PRId64 " config:%" PRId32, __FUNCTION__, mId,
455 configId);
456
457 if (outTimeline == nullptr) {
458 return HWC3::Error::BadParameter;
459 }
460
461 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
462
463 if (mActiveConfigId == configId) {
464 return HWC3::Error::None;
465 }
466
467 DisplayConfig* newConfig = getConfig(configId);
468 if (newConfig == nullptr) {
469 ALOGE("%s: display:%" PRId64 " bad config:%" PRId32, __FUNCTION__, mId,
470 configId);
471 return HWC3::Error::BadConfig;
472 }
473
474 if (constraints.seamlessRequired) {
475 if (mActiveConfigId) {
476 DisplayConfig* oldConfig = getConfig(*mActiveConfigId);
477 if (oldConfig == nullptr) {
478 ALOGE("%s: display:%" PRId64 " missing config:%" PRId32, __FUNCTION__,
479 mId, *mActiveConfigId);
480 return HWC3::Error::NoResources;
481 }
482
483 const int32_t newConfigGroup = newConfig->getConfigGroup();
484 const int32_t oldConfigGroup = oldConfig->getConfigGroup();
485 if (newConfigGroup != oldConfigGroup) {
486 DEBUG_LOG("%s: display:%" PRId64 " config:%" PRId32
487 " seamless not supported between different config groups "
488 "old:%d vs new:%d",
489 __FUNCTION__, mId, configId, oldConfigGroup, newConfigGroup);
490 return HWC3::Error::SeamlessNotAllowed;
491 }
492 }
493 }
494
495 mActiveConfigId = configId;
496
497 if (mComposer == nullptr) {
498 ALOGE("%s: display:%" PRId64 " missing composer", __FUNCTION__, mId);
499 return HWC3::Error::NoResources;
500 }
501
502 HWC3::Error error = mComposer->onActiveConfigChange(this);
503 if (error != HWC3::Error::None) {
504 ALOGE("%s: display:%" PRId64 " composer failed to handle config change",
505 __FUNCTION__, mId);
506 return error;
507 }
508
509 int32_t vsyncPeriod;
510 error = getDisplayVsyncPeriod(&vsyncPeriod);
511 if (error != HWC3::Error::None) {
512 ALOGE("%s: display:%" PRId64 " composer failed to handle config change",
513 __FUNCTION__, mId);
514 return error;
515 }
516
517 return mVsyncThread.scheduleVsyncUpdate(vsyncPeriod, constraints,
518 outTimeline);
519 }
520
getBootConfigId()521 std::optional<int32_t> Display::getBootConfigId() {
522 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
523
524 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
525
526 std::string val;
527 HWC3::Error error = Device::getInstance().getPersistentKeyValue(
528 std::to_string(mId), "", &val);
529 if (error != HWC3::Error::None) {
530 ALOGE("%s: display:%" PRId64 " failed to get persistent boot config",
531 __FUNCTION__, mId);
532 return std::nullopt;
533 }
534
535 if (val.empty()) {
536 return std::nullopt;
537 }
538
539 int32_t configId = 0;
540 if (!::android::base::ParseInt(val, &configId)) {
541 ALOGE("%s: display:%" PRId64
542 " failed to parse persistent boot config from: %s",
543 __FUNCTION__, mId, val.c_str());
544 return std::nullopt;
545 }
546
547 if (!hasConfig(configId)) {
548 ALOGE("%s: display:%" PRId64 " invalid persistent boot config:%" PRId32,
549 __FUNCTION__, mId, configId);
550 return std::nullopt;
551 }
552
553 return configId;
554 }
555
setBootConfig(int32_t configId)556 HWC3::Error Display::setBootConfig(int32_t configId) {
557 DEBUG_LOG("%s: display:%" PRId64 " config:%" PRId32, __FUNCTION__, mId,
558 configId);
559
560 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
561
562 DisplayConfig* newConfig = getConfig(configId);
563 if (newConfig == nullptr) {
564 ALOGE("%s: display:%" PRId64 " bad config:%" PRId32, __FUNCTION__, mId,
565 configId);
566 return HWC3::Error::BadConfig;
567 }
568
569 const std::string key = std::to_string(mId);
570 const std::string val = std::to_string(configId);
571 HWC3::Error error = Device::getInstance().setPersistentKeyValue(key, val);
572 if (error != HWC3::Error::None) {
573 ALOGE("%s: display:%" PRId64 " failed to save persistent boot config",
574 __FUNCTION__, mId);
575 return error;
576 }
577
578 return HWC3::Error::None;
579 }
580
clearBootConfig()581 HWC3::Error Display::clearBootConfig() {
582 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
583
584 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
585
586 const std::string key = std::to_string(mId);
587 const std::string val = "";
588 HWC3::Error error = Device::getInstance().setPersistentKeyValue(key, val);
589 if (error != HWC3::Error::None) {
590 ALOGE("%s: display:%" PRId64 " failed to save persistent boot config",
591 __FUNCTION__, mId);
592 return error;
593 }
594
595 return HWC3::Error::None;
596 }
597
getPreferredBootConfig(int32_t * outConfigId)598 HWC3::Error Display::getPreferredBootConfig(int32_t* outConfigId) {
599 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
600
601 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
602
603 std::vector<int32_t> configIds;
604 for (const auto [configId, _] : mConfigs) {
605 configIds.push_back(configId);
606 }
607 *outConfigId = *std::min_element(configIds.begin(), configIds.end());
608
609 return HWC3::Error::None;
610 }
611
setAutoLowLatencyMode(bool)612 HWC3::Error Display::setAutoLowLatencyMode(bool /*on*/) {
613 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
614
615 return HWC3::Error::Unsupported;
616 }
617
setColorMode(ColorMode mode,RenderIntent intent)618 HWC3::Error Display::setColorMode(ColorMode mode, RenderIntent intent) {
619 const std::string modeString = toString(mode);
620 const std::string intentString = toString(intent);
621 DEBUG_LOG("%s: display:%" PRId64 " setting color mode:%s intent:%s",
622 __FUNCTION__, mId, modeString.c_str(), intentString.c_str());
623
624 if (!isValidColorMode(mode)) {
625 ALOGE("%s: display:%" PRId64 " invalid color mode:%s", __FUNCTION__, mId,
626 modeString.c_str());
627 return HWC3::Error::BadParameter;
628 }
629
630 if (!isValidRenderIntent(intent)) {
631 ALOGE("%s: display:%" PRId64 " invalid intent:%s", __FUNCTION__, mId,
632 intentString.c_str());
633 return HWC3::Error::BadParameter;
634 }
635
636 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
637
638 if (mColorModes.count(mode) == 0) {
639 ALOGE("%s: display %" PRId64 " mode %s not supported", __FUNCTION__, mId,
640 modeString.c_str());
641 return HWC3::Error::Unsupported;
642 }
643
644 mActiveColorMode = mode;
645 return HWC3::Error::None;
646 }
647
setContentType(ContentType contentType)648 HWC3::Error Display::setContentType(ContentType contentType) {
649 auto contentTypeString = toString(contentType);
650 DEBUG_LOG("%s: display:%" PRId64 " content type:%s", __FUNCTION__, mId,
651 contentTypeString.c_str());
652
653 if (contentType != ContentType::NONE) {
654 return HWC3::Error::Unsupported;
655 }
656
657 return HWC3::Error::None;
658 }
659
setDisplayedContentSamplingEnabled(bool,FormatColorComponent,int64_t)660 HWC3::Error Display::setDisplayedContentSamplingEnabled(
661 bool /*enable*/, FormatColorComponent /*componentMask*/,
662 int64_t /*maxFrames*/) {
663 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
664
665 return HWC3::Error::Unsupported;
666 }
667
setPowerMode(PowerMode mode)668 HWC3::Error Display::setPowerMode(PowerMode mode) {
669 auto modeString = toString(mode);
670 DEBUG_LOG("%s: display:%" PRId64 " to mode:%s", __FUNCTION__, mId,
671 modeString.c_str());
672
673 if (!isValidPowerMode(mode)) {
674 ALOGE("%s: display:%" PRId64 " invalid mode:%s", __FUNCTION__, mId,
675 modeString.c_str());
676 return HWC3::Error::BadParameter;
677 }
678
679 if (mode == PowerMode::DOZE || mode == PowerMode::DOZE_SUSPEND ||
680 mode == PowerMode::ON_SUSPEND) {
681 ALOGE("%s display %" PRId64 " mode:%s not supported", __FUNCTION__, mId,
682 modeString.c_str());
683 return HWC3::Error::Unsupported;
684 }
685
686 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
687
688 if (IsCuttlefish()) {
689 if (int fd = open("/dev/kmsg", O_WRONLY | O_CLOEXEC); fd != -1) {
690 std::ostringstream stream;
691 stream << "VIRTUAL_DEVICE_DISPLAY_POWER_MODE_CHANGED display=" << mId
692 << " mode=" << modeString;
693 std::string message = stream.str();
694 write(fd, message.c_str(), message.length());
695 close(fd);
696 }
697 }
698
699 mPowerMode = mode;
700 return HWC3::Error::None;
701 }
702
setReadbackBuffer(const buffer_handle_t buffer,const ndk::ScopedFileDescriptor & fence)703 HWC3::Error Display::setReadbackBuffer(const buffer_handle_t buffer,
704 const ndk::ScopedFileDescriptor& fence) {
705 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
706
707 mReadbackBuffer.set(buffer, fence);
708
709 return HWC3::Error::Unsupported;
710 }
711
setVsyncEnabled(bool enabled)712 HWC3::Error Display::setVsyncEnabled(bool enabled) {
713 DEBUG_LOG("%s: display:%" PRId64 " setting vsync %s", __FUNCTION__, mId,
714 (enabled ? "on" : "off"));
715
716 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
717
718 return mVsyncThread.setVsyncEnabled(enabled);
719 }
720
setIdleTimerEnabled(int32_t timeoutMs)721 HWC3::Error Display::setIdleTimerEnabled(int32_t timeoutMs) {
722 DEBUG_LOG("%s: display:%" PRId64 " timeout:%" PRId32, __FUNCTION__, mId,
723 timeoutMs);
724
725 (void)timeoutMs;
726
727 return HWC3::Error::Unsupported;
728 }
729
setColorTransform(const std::vector<float> & transformMatrix)730 HWC3::Error Display::setColorTransform(
731 const std::vector<float>& transformMatrix) {
732 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
733
734 if (transformMatrix.size() < 16) {
735 ALOGE("%s: display:%" PRId64 " has non 4x4 matrix, size:%zu", __FUNCTION__,
736 mId, transformMatrix.size());
737 return HWC3::Error::BadParameter;
738 }
739
740 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
741
742 auto& colorTransform = mColorTransform.emplace();
743 std::copy_n(transformMatrix.data(), colorTransform.size(),
744 colorTransform.begin());
745
746 return HWC3::Error::None;
747 }
748
setBrightness(float brightness)749 HWC3::Error Display::setBrightness(float brightness) {
750 DEBUG_LOG("%s: display:%" PRId64 " brightness:%f", __FUNCTION__, mId,
751 brightness);
752
753 if (brightness < 0.0f) {
754 ALOGE("%s: display:%" PRId64 " invalid brightness:%f", __FUNCTION__, mId,
755 brightness);
756 return HWC3::Error::BadParameter;
757 }
758
759 return HWC3::Error::Unsupported;
760 }
761
setClientTarget(buffer_handle_t buffer,const ndk::ScopedFileDescriptor & fence,common::Dataspace,const std::vector<common::Rect> &)762 HWC3::Error Display::setClientTarget(
763 buffer_handle_t buffer, const ndk::ScopedFileDescriptor& fence,
764 common::Dataspace /*dataspace*/,
765 const std::vector<common::Rect>& /*damage*/) {
766 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
767
768 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
769
770 mClientTarget.set(buffer, fence);
771
772 mComposer->onDisplayClientTargetSet(this);
773 return HWC3::Error::None;
774 }
775
setOutputBuffer(buffer_handle_t,const ndk::ScopedFileDescriptor &)776 HWC3::Error Display::setOutputBuffer(
777 buffer_handle_t /*buffer*/, const ndk::ScopedFileDescriptor& /*fence*/) {
778 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
779
780 // TODO: for virtual display
781 return HWC3::Error::None;
782 }
783
setExpectedPresentTime(const std::optional<ClockMonotonicTimestamp> & expectedPresentTime)784 HWC3::Error Display::setExpectedPresentTime(
785 const std::optional<ClockMonotonicTimestamp>& expectedPresentTime) {
786 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
787
788 if (!expectedPresentTime.has_value()) {
789 return HWC3::Error::None;
790 }
791
792 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
793
794 mExpectedPresentTime.emplace(
795 asTimePoint(expectedPresentTime->timestampNanos));
796
797 return HWC3::Error::None;
798 }
799
validate(DisplayChanges * outChanges)800 HWC3::Error Display::validate(DisplayChanges* outChanges) {
801 ATRACE_CALL();
802
803 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
804
805 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
806
807 mPendingChanges.reset();
808
809 mOrderedLayers.clear();
810 mOrderedLayers.reserve(mLayers.size());
811 for (auto& [_, layerPtr] : mLayers) {
812 mOrderedLayers.push_back(layerPtr.get());
813 }
814 std::sort(mOrderedLayers.begin(), mOrderedLayers.end(),
815 [](const Layer* layerA, const Layer* layerB) {
816 const auto zA = layerA->getZOrder();
817 const auto zB = layerB->getZOrder();
818 if (zA != zB) {
819 return zA < zB;
820 }
821 return layerA->getId() < layerB->getId();
822 });
823
824 if (mComposer == nullptr) {
825 ALOGE("%s: display:%" PRId64 " missing composer", __FUNCTION__, mId);
826 return HWC3::Error::NoResources;
827 }
828
829 HWC3::Error error = mComposer->validateDisplay(this, &mPendingChanges);
830 if (error != HWC3::Error::None) {
831 ALOGE("%s: display:%" PRId64 " failed to validate", __FUNCTION__, mId);
832 return error;
833 }
834
835 if (mPendingChanges.hasAnyChanges()) {
836 mPresentFlowState = PresentFlowState::WAITING_FOR_ACCEPT;
837 DEBUG_LOG("%s: display:%" PRId64 " now WAITING_FOR_ACCEPT", __FUNCTION__,
838 mId);
839 } else {
840 mPresentFlowState = PresentFlowState::WAITING_FOR_PRESENT;
841 DEBUG_LOG("%s: display:%" PRId64 " now WAITING_FOR_PRESENT", __FUNCTION__,
842 mId);
843 }
844
845 *outChanges = mPendingChanges;
846 return HWC3::Error::None;
847 }
848
acceptChanges()849 HWC3::Error Display::acceptChanges() {
850 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
851
852 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
853
854 switch (mPresentFlowState) {
855 case PresentFlowState::WAITING_FOR_VALIDATE: {
856 ALOGE("%s: display %" PRId64 " failed, not validated", __FUNCTION__, mId);
857 return HWC3::Error::NotValidated;
858 }
859 case PresentFlowState::WAITING_FOR_ACCEPT:
860 case PresentFlowState::WAITING_FOR_PRESENT: {
861 break;
862 }
863 }
864
865 if (mPendingChanges.compositionChanges) {
866 const ChangedCompositionTypes& compositionChanges =
867 *mPendingChanges.compositionChanges;
868 for (const ChangedCompositionLayer& compositionChange :
869 compositionChanges.layers) {
870 const auto layerId = compositionChange.layer;
871 const auto layerComposition = compositionChange.composition;
872 auto* layer = getLayer(layerId);
873 if (layer == nullptr) {
874 ALOGE("%s: display:%" PRId64 " layer:%" PRId64
875 " dropped before acceptChanges()?",
876 __FUNCTION__, mId, layerId);
877 continue;
878 }
879
880 layer->setCompositionType(layerComposition);
881 }
882 }
883 mPendingChanges.reset();
884
885 mPresentFlowState = PresentFlowState::WAITING_FOR_PRESENT;
886 DEBUG_LOG("%s: display:%" PRId64 " now WAITING_FOR_PRESENT", __FUNCTION__,
887 mId);
888
889 return HWC3::Error::None;
890 }
891
present(::android::base::unique_fd * outDisplayFence,std::unordered_map<int64_t,::android::base::unique_fd> * outLayerFences)892 HWC3::Error Display::present(
893 ::android::base::unique_fd* outDisplayFence,
894 std::unordered_map<int64_t, ::android::base::unique_fd>* outLayerFences) {
895 ATRACE_CALL();
896
897 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
898
899 outDisplayFence->reset();
900 outLayerFences->clear();
901
902 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
903
904 switch (mPresentFlowState) {
905 case PresentFlowState::WAITING_FOR_VALIDATE: {
906 ALOGE("%s: display %" PRId64 " failed, not validated", __FUNCTION__, mId);
907 return HWC3::Error::NotValidated;
908 }
909 case PresentFlowState::WAITING_FOR_ACCEPT: {
910 ALOGE("%s: display %" PRId64 " failed, changes not accepted",
911 __FUNCTION__, mId);
912 return HWC3::Error::NotValidated;
913 }
914 case PresentFlowState::WAITING_FOR_PRESENT: {
915 break;
916 }
917 }
918 mPresentFlowState = PresentFlowState::WAITING_FOR_VALIDATE;
919 DEBUG_LOG("%s: display:%" PRId64 " now WAITING_FOR_VALIDATE", __FUNCTION__,
920 mId);
921
922 if (mComposer == nullptr) {
923 ALOGE("%s: display:%" PRId64 " missing composer", __FUNCTION__, mId);
924 return HWC3::Error::NoResources;
925 }
926
927 return mComposer->presentDisplay(this, outDisplayFence, outLayerFences);
928 }
929
hasConfig(int32_t configId) const930 bool Display::hasConfig(int32_t configId) const {
931 return mConfigs.find(configId) != mConfigs.end();
932 }
933
getConfig(int32_t configId)934 DisplayConfig* Display::getConfig(int32_t configId) {
935 auto it = mConfigs.find(configId);
936 if (it != mConfigs.end()) {
937 return &it->second;
938 }
939 return nullptr;
940 }
941
setEdid(std::vector<uint8_t> edid)942 HWC3::Error Display::setEdid(std::vector<uint8_t> edid) {
943 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
944
945 mEdid = edid;
946 return HWC3::Error::None;
947 }
948
setLegacyEdid()949 void Display::setLegacyEdid() {
950 // thess EDIDs are carefully generated according to the EDID spec version 1.3,
951 // more info can be found from the following file:
952 // frameworks/native/services/surfaceflinger/DisplayHardware/DisplayIdentification.cpp
953 // approved pnp ids can be found here: https://uefi.org/pnp_id_list
954 // pnp id: GGL, name: EMU_display_0, last byte is checksum
955 // display id is local:8141603649153536
956 static constexpr const std::array<uint8_t, 128> kEdid0 = {
957 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1c, 0xec, 0x01, 0x00,
958 0x01, 0x00, 0x00, 0x00, 0x1b, 0x10, 0x01, 0x03, 0x80, 0x50, 0x2d, 0x78,
959 0x0a, 0x0d, 0xc9, 0xa0, 0x57, 0x47, 0x98, 0x27, 0x12, 0x48, 0x4c, 0x00,
960 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
961 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38,
962 0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
963 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
964 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
965 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
966 0x00, 0x00, 0x00, 0xfc, 0x00, 0x45, 0x4d, 0x55, 0x5f, 0x64, 0x69, 0x73,
967 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x30, 0x00, 0x4b};
968
969 // pnp id: GGL, name: EMU_display_1
970 // display id is local:8140900251843329
971 static constexpr const std::array<uint8_t, 128> kEdid1 = {
972 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1c, 0xec, 0x01, 0x00,
973 0x01, 0x00, 0x00, 0x00, 0x1b, 0x10, 0x01, 0x03, 0x80, 0x50, 0x2d, 0x78,
974 0x0a, 0x0d, 0xc9, 0xa0, 0x57, 0x47, 0x98, 0x27, 0x12, 0x48, 0x4c, 0x00,
975 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
976 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38,
977 0x2d, 0x40, 0x58, 0x2c, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
978 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
979 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
980 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
981 0x00, 0x00, 0x00, 0xfc, 0x00, 0x45, 0x4d, 0x55, 0x5f, 0x64, 0x69, 0x73,
982 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x31, 0x00, 0x3b};
983
984 // pnp id: GGL, name: EMU_display_2
985 // display id is local:8140940453066754
986 static constexpr const std::array<uint8_t, 128> kEdid2 = {
987 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1c, 0xec, 0x01, 0x00,
988 0x01, 0x00, 0x00, 0x00, 0x1b, 0x10, 0x01, 0x03, 0x80, 0x50, 0x2d, 0x78,
989 0x0a, 0x0d, 0xc9, 0xa0, 0x57, 0x47, 0x98, 0x27, 0x12, 0x48, 0x4c, 0x00,
990 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
991 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38,
992 0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
993 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
994 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
995 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
996 0x00, 0x00, 0x00, 0xfc, 0x00, 0x45, 0x4d, 0x55, 0x5f, 0x64, 0x69, 0x73,
997 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x32, 0x00, 0x49};
998
999 mEdid.clear();
1000 switch (mId) {
1001 case 0: {
1002 mEdid.insert(mEdid.end(), kEdid0.begin(), kEdid0.end());
1003 break;
1004 }
1005 case 1: {
1006 mEdid.insert(mEdid.end(), kEdid1.begin(), kEdid1.end());
1007 break;
1008 }
1009 case 2: {
1010 mEdid.insert(mEdid.end(), kEdid2.begin(), kEdid2.end());
1011 break;
1012 }
1013 default: {
1014 mEdid.insert(mEdid.end(), kEdid2.begin(), kEdid2.end());
1015 const uint32_t size = mEdid.size();
1016 // Update the name to EMU_display_<mID>
1017 mEdid[size - 3] = '0' + (uint8_t)mId;
1018 // Update the checksum byte
1019 uint8_t checksum = -(uint8_t)std::accumulate(
1020 mEdid.data(), mEdid.data() + size - 1, static_cast<uint8_t>(0));
1021 mEdid[size - 1] = checksum;
1022 break;
1023 }
1024 }
1025 }
1026
getLayer(int64_t layerId)1027 Layer* Display::getLayer(int64_t layerId) {
1028 auto it = mLayers.find(layerId);
1029 if (it == mLayers.end()) {
1030 ALOGE("%s Unknown layer:%" PRId64, __FUNCTION__, layerId);
1031 return nullptr;
1032 }
1033
1034 return it->second.get();
1035 }
1036
waitAndGetClientTargetBuffer()1037 buffer_handle_t Display::waitAndGetClientTargetBuffer() {
1038 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
1039
1040 ::android::base::unique_fd fence = mClientTarget.getFence();
1041 if (fence.ok()) {
1042 int err = sync_wait(fence.get(), 3000);
1043 if (err < 0 && errno == ETIME) {
1044 ALOGE("%s waited on fence %" PRId32 " for 3000 ms", __FUNCTION__,
1045 fence.get());
1046 }
1047 }
1048
1049 return mClientTarget.getBuffer();
1050 }
1051
1052 } // namespace aidl::android::hardware::graphics::composer3::impl
1053