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