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