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