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