• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 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 <sync/sync.h>
20 
21 #include <atomic>
22 #include <numeric>
23 
24 #include "Device.h"
25 
26 namespace android {
27 namespace {
28 
29 std::atomic<hwc2_config_t> sNextConfigId{0};
30 
IsValidColorMode(android_color_mode_t mode)31 bool IsValidColorMode(android_color_mode_t mode) {
32   switch (mode) {
33     case HAL_COLOR_MODE_NATIVE:                         // Fall-through
34     case HAL_COLOR_MODE_STANDARD_BT601_625:             // Fall-through
35     case HAL_COLOR_MODE_STANDARD_BT601_625_UNADJUSTED:  // Fall-through
36     case HAL_COLOR_MODE_STANDARD_BT601_525:             // Fall-through
37     case HAL_COLOR_MODE_STANDARD_BT601_525_UNADJUSTED:  // Fall-through
38     case HAL_COLOR_MODE_STANDARD_BT709:                 // Fall-through
39     case HAL_COLOR_MODE_DCI_P3:                         // Fall-through
40     case HAL_COLOR_MODE_SRGB:                           // Fall-through
41     case HAL_COLOR_MODE_ADOBE_RGB:                      // Fall-through
42     case HAL_COLOR_MODE_DISPLAY_P3:
43       return true;
44     default:
45       return false;
46   }
47 }
48 
isValidPowerMode(HWC2::PowerMode mode)49 bool isValidPowerMode(HWC2::PowerMode mode) {
50   switch (mode) {
51     case HWC2::PowerMode::Off:          // Fall-through
52     case HWC2::PowerMode::DozeSuspend:  // Fall-through
53     case HWC2::PowerMode::Doze:         // Fall-through
54     case HWC2::PowerMode::On:
55       return true;
56     default:
57       return false;
58   }
59 }
60 
61 }  // namespace
62 
Display(Device & device,Composer * composer,hwc2_display_t id)63 Display::Display(Device& device, Composer* composer, hwc2_display_t id)
64     : mDevice(device),
65       mComposer(composer),
66       mId(id),
67       mVsyncThread(new VsyncThread(*this)) {}
68 
~Display()69 Display::~Display() {}
70 
init(uint32_t width,uint32_t height,uint32_t dpiX,uint32_t dpiY,uint32_t refreshRateHz,const std::optional<std::vector<uint8_t>> & edid)71 HWC2::Error Display::init(uint32_t width, uint32_t height, uint32_t dpiX,
72                           uint32_t dpiY, uint32_t refreshRateHz,
73                           const std::optional<std::vector<uint8_t>>& edid) {
74   ALOGD("%s initializing display:%" PRIu64
75         " width:%d height:%d dpiX:%d dpiY:%d refreshRateHz:%d",
76         __FUNCTION__, mId, width, height, dpiX, dpiY, refreshRateHz);
77 
78   std::unique_lock<std::recursive_mutex> lock(mStateMutex);
79 
80   mVsyncPeriod = 1000 * 1000 * 1000 / refreshRateHz;
81   mVsyncThread->run("", ANDROID_PRIORITY_URGENT_DISPLAY);
82 
83   hwc2_config_t configId = sNextConfigId++;
84 
85   Config config(configId);
86   config.setAttribute(HWC2::Attribute::VsyncPeriod, mVsyncPeriod);
87   config.setAttribute(HWC2::Attribute::Width, width);
88   config.setAttribute(HWC2::Attribute::Height, height);
89   config.setAttribute(HWC2::Attribute::DpiX, dpiX * 1000);
90   config.setAttribute(HWC2::Attribute::DpiY, dpiY * 1000);
91   mConfigs.emplace(configId, config);
92 
93   mActiveConfigId = configId;
94   mActiveColorMode = HAL_COLOR_MODE_NATIVE;
95   mColorModes.emplace((android_color_mode_t)HAL_COLOR_MODE_NATIVE);
96   mEdid = edid;
97 
98   return HWC2::Error::None;
99 }
100 
updateParameters(uint32_t width,uint32_t height,uint32_t dpiX,uint32_t dpiY,uint32_t refreshRateHz,const std::optional<std::vector<uint8_t>> & edid)101 HWC2::Error Display::updateParameters(
102     uint32_t width, uint32_t height, uint32_t dpiX, uint32_t dpiY,
103     uint32_t refreshRateHz, const std::optional<std::vector<uint8_t>>& edid) {
104   DEBUG_LOG("%s updating display:%" PRIu64
105             " width:%d height:%d dpiX:%d dpiY:%d refreshRateHz:%d",
106             __FUNCTION__, mId, width, height, dpiX, dpiY, refreshRateHz);
107 
108   std::unique_lock<std::recursive_mutex> lock(mStateMutex);
109 
110   mVsyncPeriod = 1000 * 1000 * 1000 / refreshRateHz;
111 
112   auto it = mConfigs.find(*mActiveConfigId);
113   if (it == mConfigs.end()) {
114     ALOGE("%s: failed to find config %" PRIu32, __func__, *mActiveConfigId);
115     return HWC2::Error::NoResources;
116   }
117   it->second.setAttribute(HWC2::Attribute::VsyncPeriod, mVsyncPeriod);
118   it->second.setAttribute(HWC2::Attribute::Width, width);
119   it->second.setAttribute(HWC2::Attribute::Height, height);
120   it->second.setAttribute(HWC2::Attribute::DpiX, dpiX * 1000);
121   it->second.setAttribute(HWC2::Attribute::DpiY, dpiY * 1000);
122 
123   mEdid = edid;
124 
125   return HWC2::Error::None;
126 }
127 
getLayer(hwc2_layer_t layerId)128 Layer* Display::getLayer(hwc2_layer_t layerId) {
129   auto it = mLayers.find(layerId);
130   if (it == mLayers.end()) {
131     ALOGE("%s Unknown layer:%" PRIu64, __FUNCTION__, layerId);
132     return nullptr;
133   }
134 
135   return it->second.get();
136 }
137 
waitAndGetClientTargetBuffer()138 buffer_handle_t Display::waitAndGetClientTargetBuffer() {
139   DEBUG_LOG("%s: display:%" PRIu64, __FUNCTION__, mId);
140 
141   int fence = mClientTarget.getFence();
142   if (fence != -1) {
143     int err = sync_wait(fence, 3000);
144     if (err < 0 && errno == ETIME) {
145       ALOGE("%s waited on fence %" PRId32 " for 3000 ms", __FUNCTION__, fence);
146     }
147     close(fence);
148   }
149 
150   return mClientTarget.getBuffer();
151 }
152 
acceptChanges()153 HWC2::Error Display::acceptChanges() {
154   DEBUG_LOG("%s: display:%" PRIu64, __FUNCTION__, mId);
155 
156   std::unique_lock<std::recursive_mutex> lock(mStateMutex);
157 
158   if (!mChanges) {
159     ALOGE("%s: display %" PRIu64 " failed, not validated", __FUNCTION__, mId);
160     return HWC2::Error::NotValidated;
161   }
162 
163   for (auto& [layerId, layerCompositionType] : mChanges->getTypeChanges()) {
164     auto* layer = getLayer(layerId);
165     if (layer == nullptr) {
166       ALOGE("%s: display:%" PRIu64 " layer:%" PRIu64
167             " dropped before AcceptChanges?",
168             __FUNCTION__, mId, layerId);
169       continue;
170     }
171 
172     layer->setCompositionTypeEnum(layerCompositionType);
173   }
174   mChanges->clearTypeChanges();
175 
176   return HWC2::Error::None;
177 }
178 
createLayer(hwc2_layer_t * outLayerId)179 HWC2::Error Display::createLayer(hwc2_layer_t* outLayerId) {
180   DEBUG_LOG("%s: display:%" PRIu64, __FUNCTION__, mId);
181 
182   std::unique_lock<std::recursive_mutex> lock(mStateMutex);
183 
184   auto layer = std::make_unique<Layer>();
185   auto layerId = layer->getId();
186   DEBUG_LOG("%s created layer:%" PRIu64, __FUNCTION__, layerId);
187 
188   *outLayerId = layerId;
189 
190   mLayers.emplace(layerId, std::move(layer));
191 
192   return HWC2::Error::None;
193 }
194 
destroyLayer(hwc2_layer_t layerId)195 HWC2::Error Display::destroyLayer(hwc2_layer_t layerId) {
196   DEBUG_LOG("%s destroy layer:%" PRIu64, __FUNCTION__, layerId);
197 
198   std::unique_lock<std::recursive_mutex> lock(mStateMutex);
199 
200   auto it = mLayers.find(layerId);
201   if (it == mLayers.end()) {
202     ALOGE("%s display:%" PRIu64 " has no such layer:%." PRIu64, __FUNCTION__,
203           mId, layerId);
204     return HWC2::Error::BadLayer;
205   }
206 
207   mOrderedLayers.erase(std::remove_if(mOrderedLayers.begin(),  //
208                                       mOrderedLayers.end(),    //
209                                       [layerId](Layer* layer) {
210                                         return layer->getId() == layerId;
211                                       }),
212                        mOrderedLayers.end());
213 
214   mLayers.erase(it);
215 
216   DEBUG_LOG("%s destroyed layer:%" PRIu64, __FUNCTION__, layerId);
217   return HWC2::Error::None;
218 }
219 
getActiveConfig(hwc2_config_t * outConfig)220 HWC2::Error Display::getActiveConfig(hwc2_config_t* outConfig) {
221   DEBUG_LOG("%s: display:%" PRIu64, __FUNCTION__, mId);
222 
223   std::unique_lock<std::recursive_mutex> lock(mStateMutex);
224 
225   if (!mActiveConfigId) {
226     ALOGW("%s: display:%" PRIu64 " has no active config.", __FUNCTION__, mId);
227     return HWC2::Error::BadConfig;
228   }
229 
230   *outConfig = *mActiveConfigId;
231   return HWC2::Error::None;
232 }
233 
getDisplayAttributeEnum(hwc2_config_t configId,HWC2::Attribute attribute,int32_t * outValue)234 HWC2::Error Display::getDisplayAttributeEnum(hwc2_config_t configId,
235                                              HWC2::Attribute attribute,
236                                              int32_t* outValue) {
237   auto attributeString = to_string(attribute);
238   DEBUG_LOG("%s: display:%" PRIu64 " attribute:%s", __FUNCTION__, mId,
239             attributeString.c_str());
240 
241   std::unique_lock<std::recursive_mutex> lock(mStateMutex);
242 
243   auto it = mConfigs.find(configId);
244   if (it == mConfigs.end()) {
245     ALOGW("%s: display:%" PRIu64 "bad config:%" PRIu32, __FUNCTION__, mId,
246           configId);
247     return HWC2::Error::BadConfig;
248   }
249 
250   const Config& config = it->second;
251   *outValue = config.getAttribute(attribute);
252   DEBUG_LOG("%s: display:%" PRIu64 " attribute:%s value is %" PRIi32,
253             __FUNCTION__, mId, attributeString.c_str(), *outValue);
254   return HWC2::Error::None;
255 }
256 
getDisplayAttribute(hwc2_config_t configId,int32_t attribute,int32_t * outValue)257 HWC2::Error Display::getDisplayAttribute(hwc2_config_t configId,
258                                          int32_t attribute, int32_t* outValue) {
259   return getDisplayAttributeEnum(
260       configId, static_cast<HWC2::Attribute>(attribute), outValue);
261 }
262 
getChangedCompositionTypes(uint32_t * outNumElements,hwc2_layer_t * outLayers,int32_t * outTypes)263 HWC2::Error Display::getChangedCompositionTypes(uint32_t* outNumElements,
264                                                 hwc2_layer_t* outLayers,
265                                                 int32_t* outTypes) {
266   DEBUG_LOG("%s: display:%" PRIu64, __FUNCTION__, mId);
267 
268   std::unique_lock<std::recursive_mutex> lock(mStateMutex);
269 
270   if (!mChanges) {
271     ALOGE("%s: for display:%" PRIu64 " failed, display not validated",
272           __FUNCTION__, mId);
273     return HWC2::Error::NotValidated;
274   }
275 
276   if ((outLayers == nullptr) || (outTypes == nullptr)) {
277     *outNumElements = mChanges->getTypeChanges().size();
278     return HWC2::Error::None;
279   }
280 
281   uint32_t numWritten = 0;
282   for (const auto& element : mChanges->getTypeChanges()) {
283     if (numWritten == *outNumElements) {
284       break;
285     }
286 
287     auto layerId = element.first;
288     const auto layerCompositionType = element.second;
289     const auto layerCompositionTypeString = to_string(layerCompositionType);
290     DEBUG_LOG("%s: display:%" PRIu64 " layer:%" PRIu64 " changed to %s",
291               __FUNCTION__, mId, layerId, layerCompositionTypeString.c_str());
292 
293     outLayers[numWritten] = layerId;
294     outTypes[numWritten] = static_cast<int32_t>(layerCompositionType);
295     ++numWritten;
296   }
297   *outNumElements = numWritten;
298   return HWC2::Error::None;
299 }
300 
getColorModes(uint32_t * outNumModes,int32_t * outModes)301 HWC2::Error Display::getColorModes(uint32_t* outNumModes, int32_t* outModes) {
302   DEBUG_LOG("%s: display:%" PRIu64, __FUNCTION__, mId);
303 
304   std::unique_lock<std::recursive_mutex> lock(mStateMutex);
305 
306   if (!outModes) {
307     *outNumModes = mColorModes.size();
308     return HWC2::Error::None;
309   }
310 
311   // we only support HAL_COLOR_MODE_NATIVE so far
312   uint32_t numModes = std::min<uint32_t>(
313       *outNumModes, static_cast<uint32_t>(mColorModes.size()));
314   std::copy_n(mColorModes.cbegin(), numModes, outModes);
315   *outNumModes = numModes;
316   return HWC2::Error::None;
317 }
318 
getConfigs(uint32_t * outNumConfigs,hwc2_config_t * outConfigs)319 HWC2::Error Display::getConfigs(uint32_t* outNumConfigs,
320                                 hwc2_config_t* outConfigs) {
321   DEBUG_LOG("%s: display:%" PRIu64, __FUNCTION__, mId);
322 
323   std::unique_lock<std::recursive_mutex> lock(mStateMutex);
324 
325   if (!outConfigs) {
326     *outNumConfigs = mConfigs.size();
327     return HWC2::Error::None;
328   }
329 
330   uint32_t numWritten = 0;
331   for (const auto& [configId, config] : mConfigs) {
332     if (numWritten == *outNumConfigs) {
333       break;
334     }
335     outConfigs[numWritten] = configId;
336     ++numWritten;
337   }
338 
339   *outNumConfigs = numWritten;
340   return HWC2::Error::None;
341 }
342 
getDozeSupport(int32_t * outSupport)343 HWC2::Error Display::getDozeSupport(int32_t* outSupport) {
344   DEBUG_LOG("%s: display:%" PRIu64, __FUNCTION__, mId);
345 
346   // We don't support so far
347   *outSupport = 0;
348   return HWC2::Error::None;
349 }
350 
getHdrCapabilities(uint32_t * outNumTypes,int32_t *,float *,float *,float *)351 HWC2::Error Display::getHdrCapabilities(uint32_t* outNumTypes,
352                                         int32_t* /*outTypes*/,
353                                         float* /*outMaxLuminance*/,
354                                         float* /*outMaxAverageLuminance*/,
355                                         float* /*outMinLuminance*/) {
356   DEBUG_LOG("%s: display:%" PRIu64, __FUNCTION__, mId);
357 
358   // We don't support so far
359   *outNumTypes = 0;
360   return HWC2::Error::None;
361 }
362 
getName(uint32_t * outSize,char * outName)363 HWC2::Error Display::getName(uint32_t* outSize, char* outName) {
364   DEBUG_LOG("%s: display:%" PRIu64, __FUNCTION__, mId);
365 
366   std::unique_lock<std::recursive_mutex> lock(mStateMutex);
367 
368   if (!outName) {
369     *outSize = mName.size();
370     return HWC2::Error::None;
371   }
372   auto numCopied = mName.copy(outName, *outSize);
373   *outSize = numCopied;
374   return HWC2::Error::None;
375 }
376 
addReleaseFenceLocked(int32_t fence)377 HWC2::Error Display::addReleaseFenceLocked(int32_t fence) {
378   DEBUG_LOG("%s: display:%" PRIu64 " fence:%d", __FUNCTION__, mId, fence);
379 
380   mReleaseFences.push_back(fence);
381   return HWC2::Error::None;
382 }
383 
addReleaseLayerLocked(hwc2_layer_t layerId)384 HWC2::Error Display::addReleaseLayerLocked(hwc2_layer_t layerId) {
385   DEBUG_LOG("%s: display:%" PRIu64 " layer:%" PRIu64, __FUNCTION__, mId,
386             layerId);
387 
388   mReleaseLayerIds.push_back(layerId);
389   return HWC2::Error::None;
390 }
391 
getReleaseFences(uint32_t * outNumElements,hwc2_layer_t * outLayers,int32_t * outFences)392 HWC2::Error Display::getReleaseFences(uint32_t* outNumElements,
393                                       hwc2_layer_t* outLayers,
394                                       int32_t* outFences) {
395   DEBUG_LOG("%s: display:%" PRIu64, __FUNCTION__, mId);
396 
397   std::unique_lock<std::recursive_mutex> lock(mStateMutex);
398 
399   *outNumElements = mReleaseLayerIds.size();
400 
401   if (*outNumElements && outLayers) {
402     DEBUG_LOG("%s export release layers", __FUNCTION__);
403     memcpy(outLayers, mReleaseLayerIds.data(),
404            sizeof(hwc2_layer_t) * (*outNumElements));
405   }
406 
407   if (*outNumElements && outFences) {
408     DEBUG_LOG("%s export release fences", __FUNCTION__);
409     memcpy(outFences, mReleaseFences.data(),
410            sizeof(int32_t) * (*outNumElements));
411   }
412 
413   return HWC2::Error::None;
414 }
415 
clearReleaseFencesAndIdsLocked()416 HWC2::Error Display::clearReleaseFencesAndIdsLocked() {
417   DEBUG_LOG("%s: display:%" PRIu64, __FUNCTION__, mId);
418 
419   mReleaseLayerIds.clear();
420   mReleaseFences.clear();
421 
422   return HWC2::Error::None;
423 }
424 
getRequests(int32_t * outDisplayRequests,uint32_t * outNumElements,hwc2_layer_t * outLayers,int32_t * outLayerRequests)425 HWC2::Error Display::getRequests(int32_t* outDisplayRequests,
426                                  uint32_t* outNumElements,
427                                  hwc2_layer_t* outLayers,
428                                  int32_t* outLayerRequests) {
429   DEBUG_LOG("%s: display:%" PRIu64, __FUNCTION__, mId);
430 
431   std::unique_lock<std::recursive_mutex> lock(mStateMutex);
432 
433   if (!mChanges) {
434     return HWC2::Error::NotValidated;
435   }
436 
437   if (outLayers == nullptr || outLayerRequests == nullptr) {
438     *outNumElements = mChanges->getNumLayerRequests();
439     return HWC2::Error::None;
440   }
441 
442   // TODO
443   //  Display requests (HWC2::DisplayRequest) are not supported so far:
444   *outDisplayRequests = 0;
445 
446   uint32_t numWritten = 0;
447   for (const auto& request : mChanges->getLayerRequests()) {
448     if (numWritten == *outNumElements) {
449       break;
450     }
451     outLayers[numWritten] = request.first;
452     outLayerRequests[numWritten] = static_cast<int32_t>(request.second);
453     ++numWritten;
454   }
455 
456   return HWC2::Error::None;
457 }
458 
getType(int32_t * outType)459 HWC2::Error Display::getType(int32_t* outType) {
460   DEBUG_LOG("%s: display:%" PRIu64, __FUNCTION__, mId);
461 
462   std::unique_lock<std::recursive_mutex> lock(mStateMutex);
463 
464   *outType = (int32_t)mType;
465   return HWC2::Error::None;
466 }
467 
present(int32_t * outRetireFence)468 HWC2::Error Display::present(int32_t* outRetireFence) {
469   DEBUG_LOG("%s: display:%" PRIu64, __FUNCTION__, mId);
470 
471   *outRetireFence = -1;
472 
473   std::unique_lock<std::recursive_mutex> lock(mStateMutex);
474 
475   if (!mChanges || (mChanges->getNumTypes() > 0)) {
476     ALOGE("%s: display:%" PRIu64 " failed, not validated", __FUNCTION__, mId);
477     return HWC2::Error::NotValidated;
478   }
479   mChanges.reset();
480 
481   if (mComposer == nullptr) {
482     ALOGE("%s: display:%" PRIu64 " missing composer", __FUNCTION__, mId);
483     return HWC2::Error::NoResources;
484   }
485 
486   HWC2::Error error = mComposer->presentDisplay(this, outRetireFence);
487   if (error != HWC2::Error::None) {
488     ALOGE("%s: display:%" PRIu64 " failed to present", __FUNCTION__, mId);
489     return error;
490   }
491 
492   DEBUG_LOG("%s: display:%" PRIu64 " present done!", __FUNCTION__, mId);
493   return HWC2::Error::None;
494 }
495 
setActiveConfig(hwc2_config_t configId)496 HWC2::Error Display::setActiveConfig(hwc2_config_t configId) {
497   DEBUG_LOG("%s: display:%" PRIu64 " setting active config to %" PRIu32,
498             __FUNCTION__, mId, configId);
499 
500   std::unique_lock<std::recursive_mutex> lock(mStateMutex);
501 
502   if (mConfigs.find(configId) == mConfigs.end()) {
503     ALOGE("%s: display:%" PRIu64 " bad config:%" PRIu32, __FUNCTION__, mId,
504           configId);
505     return HWC2::Error::BadConfig;
506   }
507 
508   mActiveConfigId = configId;
509   return HWC2::Error::None;
510 }
511 
setClientTarget(buffer_handle_t target,int32_t acquireFence,int32_t,hwc_region_t)512 HWC2::Error Display::setClientTarget(buffer_handle_t target,
513                                      int32_t acquireFence,
514                                      int32_t /*dataspace*/,
515                                      hwc_region_t /*damage*/) {
516   DEBUG_LOG("%s: display:%" PRIu64, __FUNCTION__, mId);
517 
518   std::unique_lock<std::recursive_mutex> lock(mStateMutex);
519   mClientTarget.setBuffer(target);
520   mClientTarget.setFence(acquireFence);
521   mComposer->onDisplayClientTargetSet(this);
522   return HWC2::Error::None;
523 }
524 
setColorMode(int32_t intMode)525 HWC2::Error Display::setColorMode(int32_t intMode) {
526   DEBUG_LOG("%s: display:%" PRIu64 " setting color mode to %" PRId32,
527             __FUNCTION__, mId, intMode);
528 
529   auto mode = static_cast<android_color_mode_t>(intMode);
530   if (!IsValidColorMode(mode)) {
531     ALOGE("%s: display:%" PRIu64 " invalid color mode %" PRId32, __FUNCTION__,
532           mId, intMode);
533     return HWC2::Error::BadParameter;
534   }
535 
536   std::unique_lock<std::recursive_mutex> lock(mStateMutex);
537 
538   if (mColorModes.count(mode) == 0) {
539     ALOGE("%s: display %" PRIu64 " mode %d not found", __FUNCTION__, mId,
540           intMode);
541     return HWC2::Error::Unsupported;
542   }
543   mActiveColorMode = mode;
544   return HWC2::Error::None;
545 }
546 
setColorTransform(const float *,int32_t hint)547 HWC2::Error Display::setColorTransform(const float* /*matrix*/, int32_t hint) {
548   DEBUG_LOG("%s: display:%" PRIu64 " setting hint to %d", __FUNCTION__, mId,
549             hint);
550 
551   std::unique_lock<std::recursive_mutex> lock(mStateMutex);
552   // we force client composition if this is set
553   if (hint == 0) {
554     mSetColorTransform = false;
555   } else {
556     mSetColorTransform = true;
557   }
558   return HWC2::Error::None;
559 }
560 
setOutputBuffer(buffer_handle_t,int32_t)561 HWC2::Error Display::setOutputBuffer(buffer_handle_t /*buffer*/,
562                                      int32_t /*releaseFence*/) {
563   DEBUG_LOG("%s: display:%" PRIu64, __FUNCTION__, mId);
564   // TODO: for virtual display
565   return HWC2::Error::None;
566 }
567 
setPowerMode(int32_t intMode)568 HWC2::Error Display::setPowerMode(int32_t intMode) {
569   auto mode = static_cast<HWC2::PowerMode>(intMode);
570   auto modeString = to_string(mode);
571   DEBUG_LOG("%s: display:%" PRIu64 " setting power mode to %s", __FUNCTION__,
572             mId, modeString.c_str());
573 
574   if (!isValidPowerMode(mode)) {
575     return HWC2::Error::BadParameter;
576   }
577 
578   if (mode == HWC2::PowerMode::Doze || mode == HWC2::PowerMode::DozeSuspend) {
579     ALOGE("%s display %" PRIu64 " power mode %s not supported", __FUNCTION__,
580           mId, modeString.c_str());
581     return HWC2::Error::Unsupported;
582   }
583 
584   std::unique_lock<std::recursive_mutex> lock(mStateMutex);
585 
586   mPowerMode = mode;
587   return HWC2::Error::None;
588 }
589 
setVsyncEnabled(int32_t intEnable)590 HWC2::Error Display::setVsyncEnabled(int32_t intEnable) {
591   auto enable = static_cast<HWC2::Vsync>(intEnable);
592   auto enableString = to_string(enable);
593   DEBUG_LOG("%s: display:%" PRIu64 " setting vsync to %s", __FUNCTION__, mId,
594             enableString.c_str());
595 
596   if (enable == HWC2::Vsync::Invalid) {
597     return HWC2::Error::BadParameter;
598   }
599 
600   std::unique_lock<std::recursive_mutex> lock(mStateMutex);
601   DEBUG_LOG("%s: display:%" PRIu64 " setting vsync locked to %s", __FUNCTION__,
602             mId, enableString.c_str());
603 
604   mVsyncEnabled = enable;
605   return HWC2::Error::None;
606 }
607 
setVsyncPeriod(uint32_t period)608 HWC2::Error Display::setVsyncPeriod(uint32_t period) {
609   DEBUG_LOG("%s: display:%" PRIu64 " setting vsync period to %d", __FUNCTION__,
610             mId, period);
611 
612   mVsyncPeriod = period;
613   return HWC2::Error::None;
614 }
615 
validate(uint32_t * outNumTypes,uint32_t * outNumRequests)616 HWC2::Error Display::validate(uint32_t* outNumTypes, uint32_t* outNumRequests) {
617   DEBUG_LOG("%s: display:%" PRIu64, __FUNCTION__, mId);
618 
619   std::unique_lock<std::recursive_mutex> lock(mStateMutex);
620 
621   mOrderedLayers.clear();
622   mOrderedLayers.reserve(mLayers.size());
623   for (auto& [_, layerPtr] : mLayers) {
624     mOrderedLayers.push_back(layerPtr.get());
625   }
626 
627   std::sort(mOrderedLayers.begin(), mOrderedLayers.end(),
628             [](const Layer* layerA, const Layer* layerB) {
629               const auto zA = layerA->getZ();
630               const auto zB = layerB->getZ();
631               if (zA != zB) {
632                 return zA < zB;
633               }
634               return layerA->getId() < layerB->getId();
635             });
636 
637   if (!mChanges) {
638     mChanges.reset(new Changes);
639   } else {
640     ALOGE("Validate was called more than once!");
641   }
642 
643   if (mComposer == nullptr) {
644     ALOGE("%s: display:%" PRIu64 " missing composer", __FUNCTION__, mId);
645     return HWC2::Error::NoResources;
646   }
647 
648   std::unordered_map<hwc2_layer_t, HWC2::Composition> changes;
649 
650   HWC2::Error error = mComposer->validateDisplay(this, &changes);
651   if (error != HWC2::Error::None) {
652     ALOGE("%s: display:%" PRIu64 " failed to validate", __FUNCTION__, mId);
653     return error;
654   }
655 
656   for (const auto& [layerId, changedCompositionType] : changes) {
657     mChanges->addTypeChange(layerId, changedCompositionType);
658   }
659 
660   *outNumTypes = mChanges->getNumTypes();
661   *outNumRequests = mChanges->getNumLayerRequests();
662   return *outNumTypes > 0 ? HWC2::Error::HasChanges : HWC2::Error::None;
663 }
664 
updateLayerZ(hwc2_layer_t layerId,uint32_t z)665 HWC2::Error Display::updateLayerZ(hwc2_layer_t layerId, uint32_t z) {
666   DEBUG_LOG("%s: display:%" PRIu64 " update layer:%" PRIu64 " z:%d",
667             __FUNCTION__, mId, layerId, z);
668 
669   std::unique_lock<std::recursive_mutex> lock(mStateMutex);
670 
671   const auto layerIt = mLayers.find(layerId);
672   if (layerIt == mLayers.end()) {
673     ALOGE("%s failed to find layer %" PRIu64, __FUNCTION__, layerId);
674     return HWC2::Error::BadLayer;
675   }
676 
677   auto& layer = layerIt->second;
678   layer->setZ(z);
679   return HWC2::Error::None;
680 }
681 
getClientTargetSupport(uint32_t width,uint32_t height,int32_t format,int32_t dataspace)682 HWC2::Error Display::getClientTargetSupport(uint32_t width, uint32_t height,
683                                             int32_t format, int32_t dataspace) {
684   DEBUG_LOG("%s: display:%" PRIu64, __FUNCTION__, mId);
685   std::unique_lock<std::recursive_mutex> lock(mStateMutex);
686 
687   if (!mActiveConfigId) {
688     return HWC2::Error::Unsupported;
689   }
690 
691   const auto it = mConfigs.find(*mActiveConfigId);
692   if (it == mConfigs.end()) {
693     ALOGE("%s failed to find active config:%" PRIu32, __FUNCTION__,
694           *mActiveConfigId);
695     return HWC2::Error::Unsupported;
696   }
697 
698   const Config& activeConfig = it->second;
699   const uint32_t activeConfigWidth =
700       static_cast<uint32_t>(activeConfig.getAttribute(HWC2::Attribute::Width));
701   const uint32_t activeConfigHeight =
702       static_cast<uint32_t>(activeConfig.getAttribute(HWC2::Attribute::Height));
703   if (width == activeConfigWidth && height == activeConfigHeight &&
704       format == HAL_PIXEL_FORMAT_RGBA_8888 &&
705       dataspace == HAL_DATASPACE_UNKNOWN) {
706     return HWC2::Error::None;
707   }
708 
709   return HWC2::Error::None;
710 }
711 
712 // thess EDIDs are carefully generated according to the EDID spec version 1.3,
713 // more info can be found from the following file:
714 //   frameworks/native/services/surfaceflinger/DisplayHardware/DisplayIdentification.cpp
715 // approved pnp ids can be found here: https://uefi.org/pnp_id_list
716 // pnp id: GGL, name: EMU_display_0, last byte is checksum
717 // display id is local:8141603649153536
718 static const uint8_t sEDID0[] = {
719     0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1c, 0xec, 0x01, 0x00,
720     0x01, 0x00, 0x00, 0x00, 0x1b, 0x10, 0x01, 0x03, 0x80, 0x50, 0x2d, 0x78,
721     0x0a, 0x0d, 0xc9, 0xa0, 0x57, 0x47, 0x98, 0x27, 0x12, 0x48, 0x4c, 0x00,
722     0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
723     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38,
724     0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
725     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
726     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
727     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
728     0x00, 0x00, 0x00, 0xfc, 0x00, 0x45, 0x4d, 0x55, 0x5f, 0x64, 0x69, 0x73,
729     0x70, 0x6c, 0x61, 0x79, 0x5f, 0x30, 0x00, 0x4b};
730 
731 // pnp id: GGL, name: EMU_display_1
732 // display id is local:8140900251843329
733 static const uint8_t sEDID1[] = {
734     0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1c, 0xec, 0x01, 0x00,
735     0x01, 0x00, 0x00, 0x00, 0x1b, 0x10, 0x01, 0x03, 0x80, 0x50, 0x2d, 0x78,
736     0x0a, 0x0d, 0xc9, 0xa0, 0x57, 0x47, 0x98, 0x27, 0x12, 0x48, 0x4c, 0x00,
737     0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
738     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38,
739     0x2d, 0x40, 0x58, 0x2c, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
740     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
741     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
742     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
743     0x00, 0x00, 0x00, 0xfc, 0x00, 0x45, 0x4d, 0x55, 0x5f, 0x64, 0x69, 0x73,
744     0x70, 0x6c, 0x61, 0x79, 0x5f, 0x31, 0x00, 0x3b};
745 
746 // pnp id: GGL, name: EMU_display_2
747 // display id is local:8140940453066754
748 static const uint8_t sEDID2[] = {
749     0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1c, 0xec, 0x01, 0x00,
750     0x01, 0x00, 0x00, 0x00, 0x1b, 0x10, 0x01, 0x03, 0x80, 0x50, 0x2d, 0x78,
751     0x0a, 0x0d, 0xc9, 0xa0, 0x57, 0x47, 0x98, 0x27, 0x12, 0x48, 0x4c, 0x00,
752     0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
753     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38,
754     0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
755     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
756     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
757     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
758     0x00, 0x00, 0x00, 0xfc, 0x00, 0x45, 0x4d, 0x55, 0x5f, 0x64, 0x69, 0x73,
759     0x70, 0x6c, 0x61, 0x79, 0x5f, 0x32, 0x00, 0x49};
760 
761 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
762 
getDisplayIdentificationData(uint8_t * outPort,uint32_t * outDataSize,uint8_t * outData)763 HWC2::Error Display::getDisplayIdentificationData(uint8_t* outPort,
764                                                   uint32_t* outDataSize,
765                                                   uint8_t* outData) {
766   DEBUG_LOG("%s: display:%" PRIu64, __FUNCTION__, mId);
767 
768   if (outPort == nullptr || outDataSize == nullptr) {
769     return HWC2::Error::BadParameter;
770   }
771 
772   if (mEdid) {
773     if (outData) {
774       *outDataSize = std::min<uint32_t>(*outDataSize, (*mEdid).size());
775       memcpy(outData, (*mEdid).data(), *outDataSize);
776     } else {
777       *outDataSize = (*mEdid).size();
778     }
779     *outPort = mId;
780     return HWC2::Error::None;
781   }
782 
783   // fallback to legacy EDID implementation
784   uint32_t len = std::min(*outDataSize, (uint32_t)ARRAY_SIZE(sEDID0));
785   if (outData != nullptr && len < (uint32_t)ARRAY_SIZE(sEDID0)) {
786     ALOGW("%s: display:%" PRIu64 " small buffer size: %u is specified",
787           __FUNCTION__, mId, len);
788   }
789   *outDataSize = ARRAY_SIZE(sEDID0);
790   switch (mId) {
791     case 0:
792       *outPort = 0;
793       if (outData) memcpy(outData, sEDID0, len);
794       break;
795 
796     case 1:
797       *outPort = 1;
798       if (outData) memcpy(outData, sEDID1, len);
799       break;
800 
801     case 2:
802       *outPort = 2;
803       if (outData) memcpy(outData, sEDID2, len);
804       break;
805 
806     default:
807       *outPort = (uint8_t)mId;
808       if (outData) {
809         memcpy(outData, sEDID2, len);
810         uint32_t size = ARRAY_SIZE(sEDID0);
811         // change the name to EMU_display_<mID>
812         // note the 3rd char from back is the number, _0, _1, _2, etc.
813         if (len >= size - 2) outData[size - 3] = '0' + (uint8_t)mId;
814         if (len >= size) {
815           // update the last byte, which is checksum byte
816           uint8_t checksum = -(uint8_t)std::accumulate(
817               outData, outData + size - 1, static_cast<uint8_t>(0));
818           outData[size - 1] = checksum;
819         }
820       }
821       break;
822   }
823 
824   return HWC2::Error::None;
825 }
826 
getDisplayCapabilities(uint32_t * outNumCapabilities,uint32_t * outCapabilities)827 HWC2::Error Display::getDisplayCapabilities(uint32_t* outNumCapabilities,
828                                             uint32_t* outCapabilities) {
829   DEBUG_LOG("%s: display:%" PRIu64, __FUNCTION__, mId);
830   if (outNumCapabilities == nullptr) {
831     return HWC2::Error::None;
832   }
833 
834   bool brightness_support = false;
835   bool doze_support = false;
836 
837   uint32_t count = 1 + (doze_support ? 1 : 0) + (brightness_support ? 1 : 0);
838   int index = 0;
839   if (outCapabilities != nullptr && (*outNumCapabilities >= count)) {
840     outCapabilities[index++] =
841         HWC2_DISPLAY_CAPABILITY_SKIP_CLIENT_COLOR_TRANSFORM;
842     if (doze_support) {
843       outCapabilities[index++] = HWC2_DISPLAY_CAPABILITY_DOZE;
844     }
845     if (brightness_support) {
846       outCapabilities[index++] = HWC2_DISPLAY_CAPABILITY_BRIGHTNESS;
847     }
848   }
849 
850   *outNumCapabilities = count;
851   return HWC2::Error::None;
852 }
853 
getDisplayBrightnessSupport(bool * out_support)854 HWC2::Error Display::getDisplayBrightnessSupport(bool* out_support) {
855   DEBUG_LOG("%s: display:%" PRIu64, __FUNCTION__, mId);
856 
857   *out_support = false;
858   return HWC2::Error::None;
859 }
860 
setDisplayBrightness(float brightness)861 HWC2::Error Display::setDisplayBrightness(float brightness) {
862   DEBUG_LOG("%s: display:%" PRIu64 " brightness %f", __FUNCTION__, mId,
863             brightness);
864 
865   ALOGW("TODO: setDisplayBrightness() is not implemented yet: brightness=%f",
866         brightness);
867   return HWC2::Error::Unsupported;
868 }
869 
setAttribute(HWC2::Attribute attribute,int32_t value)870 void Display::Config::setAttribute(HWC2::Attribute attribute, int32_t value) {
871   mAttributes[attribute] = value;
872 }
873 
getAttribute(HWC2::Attribute attribute) const874 int32_t Display::Config::getAttribute(HWC2::Attribute attribute) const {
875   if (mAttributes.count(attribute) == 0) {
876     return -1;
877   }
878   return mAttributes.at(attribute);
879 }
880 
toString() const881 std::string Display::Config::toString() const {
882   std::string output;
883 
884   auto widthIt = mAttributes.find(HWC2::Attribute::Width);
885   if (widthIt != mAttributes.end()) {
886     output += " w:" + std::to_string(widthIt->second);
887   }
888 
889   auto heightIt = mAttributes.find(HWC2::Attribute::Height);
890   if (heightIt != mAttributes.end()) {
891     output += " h:" + std::to_string(heightIt->second);
892   }
893 
894   auto vsyncIt = mAttributes.find(HWC2::Attribute::VsyncPeriod);
895   if (vsyncIt != mAttributes.end()) {
896     output += " vsync:" + std::to_string(1e9 / vsyncIt->second);
897   }
898 
899   auto dpiXIt = mAttributes.find(HWC2::Attribute::DpiX);
900   if (dpiXIt != mAttributes.end()) {
901     output += " dpi-x:" + std::to_string(dpiXIt->second / 1000.0f);
902   }
903 
904   auto dpiYIt = mAttributes.find(HWC2::Attribute::DpiY);
905   if (dpiYIt != mAttributes.end()) {
906     output += " dpi-y:" + std::to_string(dpiYIt->second / 1000.0f);
907   }
908 
909   return output;
910 }
911 
912 // VsyncThread function
threadLoop()913 bool Display::VsyncThread::threadLoop() {
914   struct timespec rt;
915   if (clock_gettime(CLOCK_MONOTONIC, &rt) == -1) {
916     ALOGE("%s: error in vsync thread clock_gettime: %s", __FUNCTION__,
917           strerror(errno));
918     return true;
919   }
920   const int logInterval = 60;
921   int64_t lastLogged = rt.tv_sec;
922   int sent = 0;
923   int lastSent = 0;
924   bool vsyncEnabled = false;
925 
926   struct timespec wait_time;
927   wait_time.tv_sec = 0;
928   wait_time.tv_nsec = mDisplay.mVsyncPeriod;
929   const int64_t kOneRefreshNs = mDisplay.mVsyncPeriod;
930   const int64_t kOneSecondNs = 1000ULL * 1000ULL * 1000ULL;
931   int64_t lastTimeNs = -1;
932   int64_t phasedWaitNs = 0;
933   int64_t currentNs = 0;
934 
935   while (true) {
936     clock_gettime(CLOCK_MONOTONIC, &rt);
937     currentNs = rt.tv_nsec + rt.tv_sec * kOneSecondNs;
938 
939     if (lastTimeNs < 0) {
940       phasedWaitNs = currentNs + kOneRefreshNs;
941     } else {
942       phasedWaitNs =
943           kOneRefreshNs * ((currentNs - lastTimeNs) / kOneRefreshNs + 1) +
944           lastTimeNs;
945     }
946 
947     wait_time.tv_sec = phasedWaitNs / kOneSecondNs;
948     wait_time.tv_nsec = phasedWaitNs - wait_time.tv_sec * kOneSecondNs;
949 
950     int ret;
951     do {
952       ret = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &wait_time, NULL);
953     } while (ret == -1 && errno == EINTR);
954 
955     lastTimeNs = phasedWaitNs;
956 
957     std::unique_lock<std::recursive_mutex> lock(mDisplay.mStateMutex);
958     vsyncEnabled = (mDisplay.mVsyncEnabled == HWC2::Vsync::Enable);
959     lock.unlock();
960 
961     if (!vsyncEnabled) {
962       continue;
963     }
964 
965     lock.lock();
966     const auto& callbackInfo =
967         mDisplay.mDevice.mCallbacks[HWC2::Callback::Vsync];
968     auto vsync = reinterpret_cast<HWC2_PFN_VSYNC>(callbackInfo.pointer);
969     lock.unlock();
970 
971     if (vsync) {
972       DEBUG_LOG("%s: display:%" PRIu64 " calling vsync", __FUNCTION__,
973                 mDisplay.mId);
974       vsync(callbackInfo.data, mDisplay.mId, lastTimeNs);
975     }
976 
977     int64_t lastSentInterval = rt.tv_sec - lastLogged;
978     if (lastSentInterval >= logInterval) {
979       DEBUG_LOG("sent %d syncs in %" PRId64 "s", sent - lastSent,
980                 lastSentInterval);
981       lastLogged = rt.tv_sec;
982       lastSent = sent;
983     }
984     ++sent;
985   }
986   return false;
987 }
988 
989 }  // namespace android
990