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