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