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