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