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()) {
275 // Workaround to force all displays to INTERNAL for cf_x86_64_foldable.
276 // TODO(b/193568008): Allow configuring internal/external per display.
277 *outType = DisplayConnectionType::INTERNAL;
278 } else {
279 // Other devices default to the first display INTERNAL, others EXTERNAL.
280 *outType = mId == 0 ? DisplayConnectionType::INTERNAL
281 : DisplayConnectionType::EXTERNAL;
282 }
283 return HWC3::Error::None;
284 }
285
getDisplayIdentificationData(DisplayIdentification * outIdentification)286 HWC3::Error Display::getDisplayIdentificationData(
287 DisplayIdentification* outIdentification) {
288 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
289
290 if (outIdentification == nullptr) {
291 return HWC3::Error::BadParameter;
292 }
293
294 outIdentification->port = mId;
295 outIdentification->data = mEdid;
296
297 return HWC3::Error::None;
298 }
299
getDisplayName(std::string * outName)300 HWC3::Error Display::getDisplayName(std::string* outName) {
301 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
302
303 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
304
305 *outName = mName;
306 return HWC3::Error::None;
307 }
308
getDisplayVsyncPeriod(int32_t * outVsyncPeriod)309 HWC3::Error Display::getDisplayVsyncPeriod(int32_t* outVsyncPeriod) {
310 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
311
312 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
313
314 if (!mActiveConfigId) {
315 ALOGE("%s : display:%" PRId64 " no active config", __FUNCTION__, mId);
316 return HWC3::Error::BadConfig;
317 }
318
319 const auto it = mConfigs.find(*mActiveConfigId);
320 if (it == mConfigs.end()) {
321 ALOGE("%s : display:%" PRId64 " failed to find active config:%" PRId32,
322 __FUNCTION__, mId, *mActiveConfigId);
323 return HWC3::Error::BadConfig;
324 }
325 const DisplayConfig& activeConfig = it->second;
326
327 *outVsyncPeriod = activeConfig.getAttribute(DisplayAttribute::VSYNC_PERIOD);
328 return HWC3::Error::None;
329 }
330
getDisplayedContentSample(int64_t,int64_t,DisplayContentSample *)331 HWC3::Error Display::getDisplayedContentSample(
332 int64_t /*maxFrames*/, int64_t /*timestamp*/,
333 DisplayContentSample* /*samples*/) {
334 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
335
336 return HWC3::Error::Unsupported;
337 }
338
getDisplayedContentSamplingAttributes(DisplayContentSamplingAttributes *)339 HWC3::Error Display::getDisplayedContentSamplingAttributes(
340 DisplayContentSamplingAttributes* /*outAttributes*/) {
341 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
342
343 return HWC3::Error::Unsupported;
344 }
345
getDisplayPhysicalOrientation(common::Transform * outOrientation)346 HWC3::Error Display::getDisplayPhysicalOrientation(
347 common::Transform* outOrientation) {
348 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
349
350 *outOrientation = common::Transform::NONE;
351
352 return HWC3::Error::None;
353 }
354
getHdrCapabilities(HdrCapabilities * outCapabilities)355 HWC3::Error Display::getHdrCapabilities(HdrCapabilities* outCapabilities) {
356 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
357
358 // No supported types.
359 outCapabilities->types.clear();
360
361 return HWC3::Error::None;
362 }
363
getPerFrameMetadataKeys(std::vector<PerFrameMetadataKey> * outKeys)364 HWC3::Error Display::getPerFrameMetadataKeys(
365 std::vector<PerFrameMetadataKey>* outKeys) {
366 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
367
368 outKeys->clear();
369
370 return HWC3::Error::Unsupported;
371 }
372
getReadbackBufferAttributes(ReadbackBufferAttributes * outAttributes)373 HWC3::Error Display::getReadbackBufferAttributes(
374 ReadbackBufferAttributes* outAttributes) {
375 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
376
377 outAttributes->format = common::PixelFormat::RGBA_8888;
378 outAttributes->dataspace = common::Dataspace::UNKNOWN;
379
380 return HWC3::Error::Unsupported;
381 }
382
getReadbackBufferFence(ndk::ScopedFileDescriptor *)383 HWC3::Error Display::getReadbackBufferFence(
384 ndk::ScopedFileDescriptor* /*outAcquireFence*/) {
385 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
386
387 return HWC3::Error::Unsupported;
388 }
389
getRenderIntents(ColorMode mode,std::vector<RenderIntent> * outIntents)390 HWC3::Error Display::getRenderIntents(ColorMode mode,
391 std::vector<RenderIntent>* outIntents) {
392 const auto modeString = toString(mode);
393 DEBUG_LOG("%s: display:%" PRId64 "for mode:%s", __FUNCTION__, mId,
394 modeString.c_str());
395
396 outIntents->clear();
397
398 if (!isValidColorMode(mode)) {
399 DEBUG_LOG("%s: display:%" PRId64 "invalid mode:%s", __FUNCTION__, mId,
400 modeString.c_str());
401 return HWC3::Error::BadParameter;
402 }
403
404 outIntents->push_back(RenderIntent::COLORIMETRIC);
405
406 return HWC3::Error::None;
407 }
408
getSupportedContentTypes(std::vector<ContentType> * outTypes)409 HWC3::Error Display::getSupportedContentTypes(
410 std::vector<ContentType>* outTypes) {
411 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
412
413 outTypes->clear();
414
415 return HWC3::Error::None;
416 }
417
getDecorationSupport(std::optional<common::DisplayDecorationSupport> * outSupport)418 HWC3::Error Display::getDecorationSupport(
419 std::optional<common::DisplayDecorationSupport>* outSupport) {
420 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
421
422 outSupport->reset();
423
424 return HWC3::Error::Unsupported;
425 }
426
registerCallback(const std::shared_ptr<IComposerCallback> & callback)427 HWC3::Error Display::registerCallback(
428 const std::shared_ptr<IComposerCallback>& callback) {
429 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
430
431 mVsyncThread.setCallbacks(callback);
432
433 return HWC3::Error::Unsupported;
434 }
435
setActiveConfig(int32_t configId)436 HWC3::Error Display::setActiveConfig(int32_t configId) {
437 DEBUG_LOG("%s: display:%" PRId64 " setting active config to %" PRId32,
438 __FUNCTION__, mId, configId);
439
440 VsyncPeriodChangeConstraints constraints;
441 constraints.desiredTimeNanos = 0;
442 constraints.seamlessRequired = false;
443
444 VsyncPeriodChangeTimeline timeline;
445
446 return setActiveConfigWithConstraints(configId, constraints, &timeline);
447 }
448
setActiveConfigWithConstraints(int32_t configId,const VsyncPeriodChangeConstraints & constraints,VsyncPeriodChangeTimeline * outTimeline)449 HWC3::Error Display::setActiveConfigWithConstraints(
450 int32_t configId, const VsyncPeriodChangeConstraints& constraints,
451 VsyncPeriodChangeTimeline* outTimeline) {
452 DEBUG_LOG("%s: display:%" PRId64 " config:%" PRId32, __FUNCTION__, mId,
453 configId);
454
455 if (outTimeline == nullptr) {
456 return HWC3::Error::BadParameter;
457 }
458
459 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
460
461 if (mActiveConfigId == configId) {
462 return HWC3::Error::None;
463 }
464
465 DisplayConfig* newConfig = getConfig(configId);
466 if (newConfig == nullptr) {
467 ALOGE("%s: display:%" PRId64 " bad config:%" PRId32, __FUNCTION__, mId,
468 configId);
469 return HWC3::Error::BadConfig;
470 }
471
472 if (constraints.seamlessRequired) {
473 if (mActiveConfigId) {
474 DisplayConfig* oldConfig = getConfig(*mActiveConfigId);
475 if (oldConfig == nullptr) {
476 ALOGE("%s: display:%" PRId64 " missing config:%" PRId32, __FUNCTION__,
477 mId, *mActiveConfigId);
478 return HWC3::Error::NoResources;
479 }
480
481 const int32_t newConfigGroup = newConfig->getConfigGroup();
482 const int32_t oldConfigGroup = oldConfig->getConfigGroup();
483 if (newConfigGroup != oldConfigGroup) {
484 DEBUG_LOG("%s: display:%" PRId64 " config:%" PRId32
485 " seamless not supported between different config groups "
486 "old:%d vs new:%d",
487 __FUNCTION__, mId, configId, oldConfigGroup, newConfigGroup);
488 return HWC3::Error::SeamlessNotAllowed;
489 }
490 }
491 }
492
493 mActiveConfigId = configId;
494
495 if (mComposer == nullptr) {
496 ALOGE("%s: display:%" PRId64 " missing composer", __FUNCTION__, mId);
497 return HWC3::Error::NoResources;
498 }
499
500 HWC3::Error error = mComposer->onActiveConfigChange(this);
501 if (error != HWC3::Error::None) {
502 ALOGE("%s: display:%" PRId64 " composer failed to handle config change",
503 __FUNCTION__, mId);
504 return error;
505 }
506
507 int32_t vsyncPeriod;
508 error = getDisplayVsyncPeriod(&vsyncPeriod);
509 if (error != HWC3::Error::None) {
510 ALOGE("%s: display:%" PRId64 " composer failed to handle config change",
511 __FUNCTION__, mId);
512 return error;
513 }
514
515 return mVsyncThread.scheduleVsyncUpdate(vsyncPeriod, constraints,
516 outTimeline);
517 }
518
getBootConfigId()519 std::optional<int32_t> Display::getBootConfigId() {
520 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
521
522 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
523
524 std::string val;
525 HWC3::Error error = Device::getInstance().getPersistentKeyValue(
526 std::to_string(mId), "", &val);
527 if (error != HWC3::Error::None) {
528 ALOGE("%s: display:%" PRId64 " failed to get persistent boot config",
529 __FUNCTION__, mId);
530 return std::nullopt;
531 }
532
533 if (val.empty()) {
534 return std::nullopt;
535 }
536
537 int32_t configId = 0;
538 if (!::android::base::ParseInt(val, &configId)) {
539 ALOGE("%s: display:%" PRId64
540 " failed to parse persistent boot config from: %s",
541 __FUNCTION__, mId, val.c_str());
542 return std::nullopt;
543 }
544
545 if (!hasConfig(configId)) {
546 ALOGE("%s: display:%" PRId64 " invalid persistent boot config:%" PRId32,
547 __FUNCTION__, mId, configId);
548 return std::nullopt;
549 }
550
551 return configId;
552 }
553
setBootConfig(int32_t configId)554 HWC3::Error Display::setBootConfig(int32_t configId) {
555 DEBUG_LOG("%s: display:%" PRId64 " config:%" PRId32, __FUNCTION__, mId,
556 configId);
557
558 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
559
560 DisplayConfig* newConfig = getConfig(configId);
561 if (newConfig == nullptr) {
562 ALOGE("%s: display:%" PRId64 " bad config:%" PRId32, __FUNCTION__, mId,
563 configId);
564 return HWC3::Error::BadConfig;
565 }
566
567 const std::string key = std::to_string(mId);
568 const std::string val = std::to_string(configId);
569 HWC3::Error error = Device::getInstance().setPersistentKeyValue(key, val);
570 if (error != HWC3::Error::None) {
571 ALOGE("%s: display:%" PRId64 " failed to save persistent boot config",
572 __FUNCTION__, mId);
573 return error;
574 }
575
576 return HWC3::Error::None;
577 }
578
clearBootConfig()579 HWC3::Error Display::clearBootConfig() {
580 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
581
582 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
583
584 const std::string key = std::to_string(mId);
585 const std::string val = "";
586 HWC3::Error error = Device::getInstance().setPersistentKeyValue(key, val);
587 if (error != HWC3::Error::None) {
588 ALOGE("%s: display:%" PRId64 " failed to save persistent boot config",
589 __FUNCTION__, mId);
590 return error;
591 }
592
593 return HWC3::Error::None;
594 }
595
getPreferredBootConfig(int32_t * outConfigId)596 HWC3::Error Display::getPreferredBootConfig(int32_t* outConfigId) {
597 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
598
599 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
600
601 std::vector<int32_t> configIds;
602 for (const auto [configId, _] : mConfigs) {
603 configIds.push_back(configId);
604 }
605 *outConfigId = *std::min_element(configIds.begin(), configIds.end());
606
607 return HWC3::Error::None;
608 }
609
setAutoLowLatencyMode(bool)610 HWC3::Error Display::setAutoLowLatencyMode(bool /*on*/) {
611 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
612
613 return HWC3::Error::Unsupported;
614 }
615
setColorMode(ColorMode mode,RenderIntent intent)616 HWC3::Error Display::setColorMode(ColorMode mode, RenderIntent intent) {
617 const std::string modeString = toString(mode);
618 const std::string intentString = toString(intent);
619 DEBUG_LOG("%s: display:%" PRId64 " setting color mode:%s intent:%s",
620 __FUNCTION__, mId, modeString.c_str(), intentString.c_str());
621
622 if (!isValidColorMode(mode)) {
623 ALOGE("%s: display:%" PRId64 " invalid color mode:%s", __FUNCTION__, mId,
624 modeString.c_str());
625 return HWC3::Error::BadParameter;
626 }
627
628 if (!isValidRenderIntent(intent)) {
629 ALOGE("%s: display:%" PRId64 " invalid intent:%s", __FUNCTION__, mId,
630 intentString.c_str());
631 return HWC3::Error::BadParameter;
632 }
633
634 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
635
636 if (mColorModes.count(mode) == 0) {
637 ALOGE("%s: display %" PRId64 " mode %s not supported", __FUNCTION__, mId,
638 modeString.c_str());
639 return HWC3::Error::Unsupported;
640 }
641
642 mActiveColorMode = mode;
643 return HWC3::Error::None;
644 }
645
setContentType(ContentType contentType)646 HWC3::Error Display::setContentType(ContentType contentType) {
647 auto contentTypeString = toString(contentType);
648 DEBUG_LOG("%s: display:%" PRId64 " content type:%s", __FUNCTION__, mId,
649 contentTypeString.c_str());
650
651 if (contentType != ContentType::NONE) {
652 return HWC3::Error::Unsupported;
653 }
654
655 return HWC3::Error::None;
656 }
657
setDisplayedContentSamplingEnabled(bool,FormatColorComponent,int64_t)658 HWC3::Error Display::setDisplayedContentSamplingEnabled(
659 bool /*enable*/, FormatColorComponent /*componentMask*/,
660 int64_t /*maxFrames*/) {
661 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
662
663 return HWC3::Error::Unsupported;
664 }
665
setPowerMode(PowerMode mode)666 HWC3::Error Display::setPowerMode(PowerMode mode) {
667 auto modeString = toString(mode);
668 DEBUG_LOG("%s: display:%" PRId64 " to mode:%s", __FUNCTION__, mId,
669 modeString.c_str());
670
671 if (!isValidPowerMode(mode)) {
672 ALOGE("%s: display:%" PRId64 " invalid mode:%s", __FUNCTION__, mId,
673 modeString.c_str());
674 return HWC3::Error::BadParameter;
675 }
676
677 if (mode == PowerMode::DOZE || mode == PowerMode::DOZE_SUSPEND ||
678 mode == PowerMode::ON_SUSPEND) {
679 ALOGE("%s display %" PRId64 " mode:%s not supported", __FUNCTION__, mId,
680 modeString.c_str());
681 return HWC3::Error::Unsupported;
682 }
683
684 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
685
686 if (IsCuttlefish()) {
687 if (int fd = open("/dev/kmsg", O_WRONLY | O_CLOEXEC); fd != -1) {
688 std::ostringstream stream;
689 stream << "VIRTUAL_DEVICE_DISPLAY_POWER_MODE_CHANGED display=" << mId
690 << " mode=" << modeString;
691 std::string message = stream.str();
692 write(fd, message.c_str(), message.length());
693 close(fd);
694 }
695 }
696
697 mPowerMode = mode;
698 return HWC3::Error::None;
699 }
700
setReadbackBuffer(const buffer_handle_t buffer,const ndk::ScopedFileDescriptor & fence)701 HWC3::Error Display::setReadbackBuffer(const buffer_handle_t buffer,
702 const ndk::ScopedFileDescriptor& fence) {
703 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
704
705 mReadbackBuffer.set(buffer, fence);
706
707 return HWC3::Error::Unsupported;
708 }
709
setVsyncEnabled(bool enabled)710 HWC3::Error Display::setVsyncEnabled(bool enabled) {
711 DEBUG_LOG("%s: display:%" PRId64 " setting vsync %s", __FUNCTION__, mId,
712 (enabled ? "on" : "off"));
713
714 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
715
716 return mVsyncThread.setVsyncEnabled(enabled);
717 }
718
setIdleTimerEnabled(int32_t timeoutMs)719 HWC3::Error Display::setIdleTimerEnabled(int32_t timeoutMs) {
720 DEBUG_LOG("%s: display:%" PRId64 " timeout:%" PRId32, __FUNCTION__, mId,
721 timeoutMs);
722
723 (void)timeoutMs;
724
725 return HWC3::Error::Unsupported;
726 }
727
setColorTransform(const std::vector<float> & transformMatrix)728 HWC3::Error Display::setColorTransform(
729 const std::vector<float>& transformMatrix) {
730 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
731
732 if (transformMatrix.size() < 16) {
733 ALOGE("%s: display:%" PRId64 " has non 4x4 matrix, size:%zu", __FUNCTION__,
734 mId, transformMatrix.size());
735 return HWC3::Error::BadParameter;
736 }
737
738 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
739
740 auto& colorTransform = mColorTransform.emplace();
741 std::copy_n(transformMatrix.data(), colorTransform.size(),
742 colorTransform.begin());
743
744 return HWC3::Error::None;
745 }
746
setBrightness(float brightness)747 HWC3::Error Display::setBrightness(float brightness) {
748 DEBUG_LOG("%s: display:%" PRId64 " brightness:%f", __FUNCTION__, mId,
749 brightness);
750
751 if (brightness < 0.0f) {
752 ALOGE("%s: display:%" PRId64 " invalid brightness:%f", __FUNCTION__, mId,
753 brightness);
754 return HWC3::Error::BadParameter;
755 }
756
757 return HWC3::Error::Unsupported;
758 }
759
setClientTarget(buffer_handle_t buffer,const ndk::ScopedFileDescriptor & fence,common::Dataspace,const std::vector<common::Rect> &)760 HWC3::Error Display::setClientTarget(
761 buffer_handle_t buffer, const ndk::ScopedFileDescriptor& fence,
762 common::Dataspace /*dataspace*/,
763 const std::vector<common::Rect>& /*damage*/) {
764 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
765
766 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
767
768 mClientTarget.set(buffer, fence);
769
770 mComposer->onDisplayClientTargetSet(this);
771 return HWC3::Error::None;
772 }
773
setOutputBuffer(buffer_handle_t,const ndk::ScopedFileDescriptor &)774 HWC3::Error Display::setOutputBuffer(
775 buffer_handle_t /*buffer*/, const ndk::ScopedFileDescriptor& /*fence*/) {
776 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
777
778 // TODO: for virtual display
779 return HWC3::Error::None;
780 }
781
setExpectedPresentTime(const std::optional<ClockMonotonicTimestamp> & expectedPresentTime)782 HWC3::Error Display::setExpectedPresentTime(
783 const std::optional<ClockMonotonicTimestamp>& expectedPresentTime) {
784 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
785
786 if (!expectedPresentTime.has_value()) {
787 return HWC3::Error::None;
788 }
789
790 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
791
792 mExpectedPresentTime.emplace(
793 asTimePoint(expectedPresentTime->timestampNanos));
794
795 return HWC3::Error::None;
796 }
797
validate(DisplayChanges * outChanges)798 HWC3::Error Display::validate(DisplayChanges* outChanges) {
799 ATRACE_CALL();
800
801 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
802
803 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
804
805 mPendingChanges.reset();
806
807 mOrderedLayers.clear();
808 mOrderedLayers.reserve(mLayers.size());
809 for (auto& [_, layerPtr] : mLayers) {
810 mOrderedLayers.push_back(layerPtr.get());
811 }
812 std::sort(mOrderedLayers.begin(), mOrderedLayers.end(),
813 [](const Layer* layerA, const Layer* layerB) {
814 const auto zA = layerA->getZOrder();
815 const auto zB = layerB->getZOrder();
816 if (zA != zB) {
817 return zA < zB;
818 }
819 return layerA->getId() < layerB->getId();
820 });
821
822 if (mComposer == nullptr) {
823 ALOGE("%s: display:%" PRId64 " missing composer", __FUNCTION__, mId);
824 return HWC3::Error::NoResources;
825 }
826
827 HWC3::Error error = mComposer->validateDisplay(this, &mPendingChanges);
828 if (error != HWC3::Error::None) {
829 ALOGE("%s: display:%" PRId64 " failed to validate", __FUNCTION__, mId);
830 return error;
831 }
832
833 if (mPendingChanges.hasAnyChanges()) {
834 mPresentFlowState = PresentFlowState::WAITING_FOR_ACCEPT;
835 DEBUG_LOG("%s: display:%" PRId64 " now WAITING_FOR_ACCEPT", __FUNCTION__,
836 mId);
837 } else {
838 mPresentFlowState = PresentFlowState::WAITING_FOR_PRESENT;
839 DEBUG_LOG("%s: display:%" PRId64 " now WAITING_FOR_PRESENT", __FUNCTION__,
840 mId);
841 }
842
843 *outChanges = mPendingChanges;
844 return HWC3::Error::None;
845 }
846
acceptChanges()847 HWC3::Error Display::acceptChanges() {
848 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
849
850 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
851
852 switch (mPresentFlowState) {
853 case PresentFlowState::WAITING_FOR_VALIDATE: {
854 ALOGE("%s: display %" PRId64 " failed, not validated", __FUNCTION__, mId);
855 return HWC3::Error::NotValidated;
856 }
857 case PresentFlowState::WAITING_FOR_ACCEPT:
858 case PresentFlowState::WAITING_FOR_PRESENT: {
859 break;
860 }
861 }
862
863 if (mPendingChanges.compositionChanges) {
864 const ChangedCompositionTypes& compositionChanges =
865 *mPendingChanges.compositionChanges;
866 for (const ChangedCompositionLayer& compositionChange :
867 compositionChanges.layers) {
868 const auto layerId = compositionChange.layer;
869 const auto layerComposition = compositionChange.composition;
870 auto* layer = getLayer(layerId);
871 if (layer == nullptr) {
872 ALOGE("%s: display:%" PRId64 " layer:%" PRId64
873 " dropped before acceptChanges()?",
874 __FUNCTION__, mId, layerId);
875 continue;
876 }
877
878 layer->setCompositionType(layerComposition);
879 }
880 }
881 mPendingChanges.reset();
882
883 mPresentFlowState = PresentFlowState::WAITING_FOR_PRESENT;
884 DEBUG_LOG("%s: display:%" PRId64 " now WAITING_FOR_PRESENT", __FUNCTION__,
885 mId);
886
887 return HWC3::Error::None;
888 }
889
present(::android::base::unique_fd * outDisplayFence,std::unordered_map<int64_t,::android::base::unique_fd> * outLayerFences)890 HWC3::Error Display::present(
891 ::android::base::unique_fd* outDisplayFence,
892 std::unordered_map<int64_t, ::android::base::unique_fd>* outLayerFences) {
893 ATRACE_CALL();
894
895 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
896
897 outDisplayFence->reset();
898 outLayerFences->clear();
899
900 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
901
902 switch (mPresentFlowState) {
903 case PresentFlowState::WAITING_FOR_VALIDATE: {
904 ALOGE("%s: display %" PRId64 " failed, not validated", __FUNCTION__, mId);
905 return HWC3::Error::NotValidated;
906 }
907 case PresentFlowState::WAITING_FOR_ACCEPT: {
908 ALOGE("%s: display %" PRId64 " failed, changes not accepted",
909 __FUNCTION__, mId);
910 return HWC3::Error::NotValidated;
911 }
912 case PresentFlowState::WAITING_FOR_PRESENT: {
913 break;
914 }
915 }
916 mPresentFlowState = PresentFlowState::WAITING_FOR_VALIDATE;
917 DEBUG_LOG("%s: display:%" PRId64 " now WAITING_FOR_VALIDATE", __FUNCTION__,
918 mId);
919
920 if (mComposer == nullptr) {
921 ALOGE("%s: display:%" PRId64 " missing composer", __FUNCTION__, mId);
922 return HWC3::Error::NoResources;
923 }
924
925 return mComposer->presentDisplay(this, outDisplayFence, outLayerFences);
926 }
927
hasConfig(int32_t configId) const928 bool Display::hasConfig(int32_t configId) const {
929 return mConfigs.find(configId) != mConfigs.end();
930 }
931
getConfig(int32_t configId)932 DisplayConfig* Display::getConfig(int32_t configId) {
933 auto it = mConfigs.find(configId);
934 if (it != mConfigs.end()) {
935 return &it->second;
936 }
937 return nullptr;
938 }
939
setEdid(std::vector<uint8_t> edid)940 HWC3::Error Display::setEdid(std::vector<uint8_t> edid) {
941 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
942
943 mEdid = edid;
944 return HWC3::Error::None;
945 }
946
setLegacyEdid()947 void Display::setLegacyEdid() {
948 // thess EDIDs are carefully generated according to the EDID spec version 1.3,
949 // more info can be found from the following file:
950 // frameworks/native/services/surfaceflinger/DisplayHardware/DisplayIdentification.cpp
951 // approved pnp ids can be found here: https://uefi.org/pnp_id_list
952 // pnp id: GGL, name: EMU_display_0, last byte is checksum
953 // display id is local:8141603649153536
954 static constexpr const std::array<uint8_t, 128> kEdid0 = {
955 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1c, 0xec, 0x01, 0x00,
956 0x01, 0x00, 0x00, 0x00, 0x1b, 0x10, 0x01, 0x03, 0x80, 0x50, 0x2d, 0x78,
957 0x0a, 0x0d, 0xc9, 0xa0, 0x57, 0x47, 0x98, 0x27, 0x12, 0x48, 0x4c, 0x00,
958 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
959 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38,
960 0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
961 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
962 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
963 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
964 0x00, 0x00, 0x00, 0xfc, 0x00, 0x45, 0x4d, 0x55, 0x5f, 0x64, 0x69, 0x73,
965 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x30, 0x00, 0x4b};
966
967 // pnp id: GGL, name: EMU_display_1
968 // display id is local:8140900251843329
969 static constexpr const std::array<uint8_t, 128> kEdid1 = {
970 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1c, 0xec, 0x01, 0x00,
971 0x01, 0x00, 0x00, 0x00, 0x1b, 0x10, 0x01, 0x03, 0x80, 0x50, 0x2d, 0x78,
972 0x0a, 0x0d, 0xc9, 0xa0, 0x57, 0x47, 0x98, 0x27, 0x12, 0x48, 0x4c, 0x00,
973 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
974 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38,
975 0x2d, 0x40, 0x58, 0x2c, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
976 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
977 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
978 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
979 0x00, 0x00, 0x00, 0xfc, 0x00, 0x45, 0x4d, 0x55, 0x5f, 0x64, 0x69, 0x73,
980 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x31, 0x00, 0x3b};
981
982 // pnp id: GGL, name: EMU_display_2
983 // display id is local:8140940453066754
984 static constexpr const std::array<uint8_t, 128> kEdid2 = {
985 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1c, 0xec, 0x01, 0x00,
986 0x01, 0x00, 0x00, 0x00, 0x1b, 0x10, 0x01, 0x03, 0x80, 0x50, 0x2d, 0x78,
987 0x0a, 0x0d, 0xc9, 0xa0, 0x57, 0x47, 0x98, 0x27, 0x12, 0x48, 0x4c, 0x00,
988 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
989 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38,
990 0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
991 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
992 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
993 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
994 0x00, 0x00, 0x00, 0xfc, 0x00, 0x45, 0x4d, 0x55, 0x5f, 0x64, 0x69, 0x73,
995 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x32, 0x00, 0x49};
996
997 mEdid.clear();
998 switch (mId) {
999 case 0: {
1000 mEdid.insert(mEdid.end(), kEdid0.begin(), kEdid0.end());
1001 break;
1002 }
1003 case 1: {
1004 mEdid.insert(mEdid.end(), kEdid1.begin(), kEdid1.end());
1005 break;
1006 }
1007 case 2: {
1008 mEdid.insert(mEdid.end(), kEdid2.begin(), kEdid2.end());
1009 break;
1010 }
1011 default: {
1012 mEdid.insert(mEdid.end(), kEdid2.begin(), kEdid2.end());
1013 const uint32_t size = mEdid.size();
1014 // Update the name to EMU_display_<mID>
1015 mEdid[size - 3] = '0' + (uint8_t)mId;
1016 // Update the checksum byte
1017 uint8_t checksum = -(uint8_t)std::accumulate(
1018 mEdid.data(), mEdid.data() + size - 1, static_cast<uint8_t>(0));
1019 mEdid[size - 1] = checksum;
1020 break;
1021 }
1022 }
1023 }
1024
getLayer(int64_t layerId)1025 Layer* Display::getLayer(int64_t layerId) {
1026 auto it = mLayers.find(layerId);
1027 if (it == mLayers.end()) {
1028 ALOGE("%s Unknown layer:%" PRId64, __FUNCTION__, layerId);
1029 return nullptr;
1030 }
1031
1032 return it->second.get();
1033 }
1034
waitAndGetClientTargetBuffer()1035 buffer_handle_t Display::waitAndGetClientTargetBuffer() {
1036 DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);
1037
1038 ::android::base::unique_fd fence = mClientTarget.getFence();
1039 if (fence.ok()) {
1040 int err = sync_wait(fence.get(), 3000);
1041 if (err < 0 && errno == ETIME) {
1042 ALOGE("%s waited on fence %" PRId32 " for 3000 ms", __FUNCTION__,
1043 fence.get());
1044 }
1045 }
1046
1047 return mClientTarget.getBuffer();
1048 }
1049
1050 } // namespace aidl::android::hardware::graphics::composer3::impl
1051