1 /*
2  * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
3  * Not a Contribution.
4  *
5  * Copyright 2015 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 #include <cutils/properties.h>
21 #include <errno.h>
22 #include <math.h>
23 #include <sync/sync.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <utils/constants.h>
27 #include <utils/debug.h>
28 #include <utils/formats.h>
29 #include <utils/rect.h>
30 #include <qd_utils.h>
31 
32 #include <algorithm>
33 #include <iomanip>
34 #include <map>
35 #include <sstream>
36 #include <string>
37 #include <utility>
38 #include <vector>
39 
40 #include "hwc_display.h"
41 #include "hwc_debugger.h"
42 #include "hwc_tonemapper.h"
43 #include "hwc_session.h"
44 
45 #ifdef QTI_BSP
46 #include <hardware/display_defs.h>
47 #endif
48 
49 #define __CLASS__ "HWCDisplay"
50 
51 namespace sdm {
52 
HWCColorMode(DisplayInterface * display_intf)53 HWCColorMode::HWCColorMode(DisplayInterface *display_intf) : display_intf_(display_intf) {}
54 
Init()55 HWC2::Error HWCColorMode::Init() {
56   PopulateColorModes();
57   InitColorCompensation();
58   return ApplyDefaultColorMode();
59 }
60 
DeInit()61 HWC2::Error HWCColorMode::DeInit() {
62   color_mode_map_.clear();
63   return HWC2::Error::None;
64 }
65 
GetColorModeCount()66 uint32_t HWCColorMode::GetColorModeCount() {
67   uint32_t count = UINT32(color_mode_map_.size());
68   DLOGI("Supported color mode count = %d", count);
69   return std::max(1U, count);
70 }
71 
GetRenderIntentCount(ColorMode mode)72 uint32_t HWCColorMode::GetRenderIntentCount(ColorMode mode) {
73   uint32_t count = UINT32(color_mode_map_[mode].size());
74   DLOGI("mode: %d supported rendering intent count = %d", mode, count);
75   return std::max(1U, count);
76 }
77 
GetColorModes(uint32_t * out_num_modes,ColorMode * out_modes)78 HWC2::Error HWCColorMode::GetColorModes(uint32_t *out_num_modes, ColorMode *out_modes) {
79   auto it = color_mode_map_.begin();
80   *out_num_modes = std::min(*out_num_modes, UINT32(color_mode_map_.size()));
81   for (uint32_t i = 0; i < *out_num_modes; it++, i++) {
82     out_modes[i] = it->first;
83   }
84   return HWC2::Error::None;
85 }
86 
GetRenderIntents(ColorMode mode,uint32_t * out_num_intents,RenderIntent * out_intents)87 HWC2::Error HWCColorMode::GetRenderIntents(ColorMode mode, uint32_t *out_num_intents,
88                                            RenderIntent *out_intents) {
89   if (color_mode_map_.find(mode) == color_mode_map_.end()) {
90     return HWC2::Error::BadParameter;
91   }
92   auto it = color_mode_map_[mode].begin();
93   *out_num_intents = std::min(*out_num_intents, UINT32(color_mode_map_[mode].size()));
94   for (uint32_t i = 0; i < *out_num_intents; it++, i++) {
95     out_intents[i] = it->first;
96   }
97   return HWC2::Error::None;
98 }
99 
SetColorModeWithRenderIntent(ColorMode mode,RenderIntent intent)100 HWC2::Error HWCColorMode::SetColorModeWithRenderIntent(ColorMode mode, RenderIntent intent) {
101   DTRACE_SCOPED();
102   if (mode < ColorMode::NATIVE || mode > ColorMode::BT2100_HLG) {
103     DLOGE("Could not find mode: %d", mode);
104     return HWC2::Error::BadParameter;
105   }
106   if (color_mode_map_.find(mode) == color_mode_map_.end()) {
107     return HWC2::Error::Unsupported;
108   }
109   if (color_mode_map_[mode].find(intent) == color_mode_map_[mode].end()) {
110     return HWC2::Error::Unsupported;
111   }
112 
113   if (current_color_mode_ == mode && current_render_intent_ == intent) {
114     return HWC2::Error::None;
115   }
116 
117   auto mode_string = color_mode_map_[mode][intent];
118   DisplayError error = display_intf_->SetColorMode(mode_string);
119   if (error != kErrorNone) {
120     DLOGE("failed for mode = %d intent = %d name = %s", mode, intent, mode_string.c_str());
121     return HWC2::Error::Unsupported;
122   }
123 
124   current_color_mode_ = mode;
125   current_render_intent_ = intent;
126 
127   // The mode does not have the PCC configured, restore the transform
128   RestoreColorTransform();
129 
130   DLOGV_IF(kTagClient, "Successfully applied mode = %d intent = %d name = %s", mode, intent,
131            mode_string.c_str());
132   return HWC2::Error::None;
133 }
134 
SetColorModeById(int32_t color_mode_id)135 HWC2::Error HWCColorMode::SetColorModeById(int32_t color_mode_id) {
136   DLOGI("Applying mode: %d", color_mode_id);
137   DisplayError error = display_intf_->SetColorModeById(color_mode_id);
138   if (error != kErrorNone) {
139     DLOGI_IF(kTagClient, "Failed to apply mode: %d", color_mode_id);
140     return HWC2::Error::BadParameter;
141   }
142   return HWC2::Error::None;
143 }
144 
RestoreColorTransform()145 HWC2::Error HWCColorMode::RestoreColorTransform() {
146   DisplayError error =
147       display_intf_->SetColorTransform(kColorTransformMatrixCount, PickTransferMatrix());
148   if (error != kErrorNone) {
149     DLOGE("Failed to set Color Transform");
150     return HWC2::Error::BadParameter;
151   }
152 
153   return HWC2::Error::None;
154 }
155 
InitColorCompensation()156 void HWCColorMode::InitColorCompensation() {
157   char value[kPropertyMax] = {0};
158   if (Debug::Get()->GetProperty(ADAPTIVE_WHITE_COEFFICIENT_PROP, value) == kErrorNone) {
159     adaptive_white_ = std::make_unique<WhiteCompensation>(string(value));
160     adaptive_white_->SetEnabled(true);
161   }
162   std::memset(value, 0, sizeof(value));
163   if (Debug::Get()->GetProperty(ADAPTIVE_SATURATION_PARAMETER_PROP, value) == kErrorNone) {
164     adaptive_saturation_ = std::make_unique<SaturationCompensation>(string(value));
165     adaptive_saturation_->SetEnabled(true);
166   }
167 }
168 
PickTransferMatrix()169 const double *HWCColorMode::PickTransferMatrix() {
170   double matrix[kColorTransformMatrixCount] = {0};
171   if (current_render_intent_ == RenderIntent::ENHANCE) {
172     CopyColorTransformMatrix(color_matrix_, matrix);
173     if (HasSaturationCompensation())
174       adaptive_saturation_->ApplyToMatrix(matrix);
175 
176     if (HasWhiteCompensation())
177       adaptive_white_->ApplyToMatrix(matrix);
178 
179     CopyColorTransformMatrix(matrix, compensated_color_matrix_);
180     return compensated_color_matrix_;
181   } else {
182     return color_matrix_;
183   }
184 }
185 
SetWhiteCompensation(bool enabled)186 HWC2::Error HWCColorMode::SetWhiteCompensation(bool enabled) {
187   if (adaptive_white_ == NULL)
188     return HWC2::Error::Unsupported;
189 
190   if (adaptive_white_->SetEnabled(enabled) != HWC2::Error::None) {
191     return HWC2::Error::NotValidated;
192   }
193 
194   RestoreColorTransform();
195 
196   DLOGI("Set White Compensation: %d", enabled);
197   return HWC2::Error::None;
198 }
199 
SetEnabled(bool enabled)200 HWC2::Error HWCColorMatrix::SetEnabled(bool enabled) {
201   enabled_ = enabled;
202   return HWC2::Error::None;
203 }
204 
ParseFloatValueByCommas(const string & values,uint32_t length,std::vector<float> & elements) const205 bool HWCColorMatrix::ParseFloatValueByCommas(const string &values, uint32_t length,
206                                              std::vector<float> &elements) const {
207   std::istringstream data_stream(values);
208   string data;
209   uint32_t index = 0;
210   std::vector<float> temp_elements;
211   while (std::getline(data_stream, data, ',')) {
212     temp_elements.push_back(std::move(std::stof(data.c_str())));
213     index++;
214   }
215 
216   if (index != length) {
217     DLOGW("Insufficient elements defined");
218     return false;
219   }
220   std::move(temp_elements.begin(), temp_elements.end(), elements.begin());
221   return true;
222 }
223 
SetEnabled(bool enabled)224 HWC2::Error WhiteCompensation::SetEnabled(bool enabled) {
225   // re-parse data when set enabled for retry calibration
226   if (enabled) {
227     if (!ConfigCoefficients() || !ParseWhitePointCalibrationData()) {
228       enabled_ = false;
229       DLOGE("Failed to WhiteCompensation Set");
230       return HWC2::Error::NotValidated;
231     }
232     CalculateRGBRatio();
233   }
234   enabled_ = enabled;
235   return HWC2::Error::None;
236 }
237 
ParseWhitePointCalibrationData()238 bool WhiteCompensation::ParseWhitePointCalibrationData() {
239   static constexpr char kWhitePointCalibrationDataPath[] = "/persist/display/calibrated_rgb";
240   FILE *fp = fopen(kWhitePointCalibrationDataPath, "r");
241   int ret;
242 
243   if (!fp) {
244     DLOGW("Failed to open white point calibration data file");
245     return false;
246   }
247 
248   ret = fscanf(fp, "%d %d %d", &compensated_red_, &compensated_green_, &compensated_blue_);
249   fclose(fp);
250 
251   if ((ret == kNumOfCompensationData) && CheckCompensatedRGB(compensated_red_) &&
252       CheckCompensatedRGB(compensated_green_) && CheckCompensatedRGB(compensated_blue_)) {
253     DLOGD("Compensated RGB: %d %d %d", compensated_red_, compensated_green_, compensated_blue_);
254     return true;
255   } else {
256     compensated_red_ = kCompensatedMaxRGB;
257     compensated_green_ = kCompensatedMaxRGB;
258     compensated_blue_ = kCompensatedMaxRGB;
259     DLOGE("Wrong white compensated value");
260     return false;
261   }
262 }
263 
ConfigCoefficients()264 bool WhiteCompensation::ConfigCoefficients() {
265   std::vector<float> CompensatedCoefficients(kCoefficientElements);
266   if (!ParseFloatValueByCommas(key_values_, kCoefficientElements, CompensatedCoefficients))
267     return false;
268   std::move(CompensatedCoefficients.begin(), CompensatedCoefficients.end(),
269             white_compensated_Coefficients_);
270   for (const auto &c : white_compensated_Coefficients_) {
271     DLOGD("white_compensated_Coefficients_=%f", c);
272   }
273   return true;
274 }
275 
CalculateRGBRatio()276 void WhiteCompensation::CalculateRGBRatio() {
277   // r = r_coeffient2 * R^2 + r_coeffient1 * R + r_coeffient0
278   // g = g_coeffient2 * G^2 + g_coeffient1 * G + g_coeffient0
279   // b = b_coeffient2 * B^2 + b_coeffient1 * B + b_coeffient0
280   // r_ratio = r/kCompensatedMaxRGB
281   // g_ratio = g/kCompensatedMaxRGB
282   // b_ratio = b/kCompensatedMaxRGB
283   auto rgb_ratio = [=](int rgb, float c2, float c1, float c0) {
284     float frgb = FLOAT(rgb);
285     return ((c2 * frgb * frgb + c1 * frgb + c0) / kCompensatedMaxRGB);
286   };
287 
288   compensated_red_ratio_ =
289       rgb_ratio(compensated_red_, white_compensated_Coefficients_[0],
290                 white_compensated_Coefficients_[1], white_compensated_Coefficients_[2]);
291   compensated_green_ratio_ =
292       rgb_ratio(compensated_green_, white_compensated_Coefficients_[3],
293                 white_compensated_Coefficients_[4], white_compensated_Coefficients_[5]);
294   compensated_blue_ratio_ =
295       rgb_ratio(compensated_blue_, white_compensated_Coefficients_[6],
296                 white_compensated_Coefficients_[7], white_compensated_Coefficients_[8]);
297   DLOGI("Compensated ratio %f %f %f", compensated_red_ratio_, compensated_green_ratio_,
298         compensated_blue_ratio_);
299 }
300 
ApplyToMatrix(double * in)301 void WhiteCompensation::ApplyToMatrix(double *in) {
302   double matrix[kColorTransformMatrixCount] = {0};
303   for (uint32_t i = 0; i < kColorTransformMatrixCount; i++) {
304     if ((i % 4) == 0)
305       matrix[i] = compensated_red_ratio_ * in[i];
306     else if ((i % 4) == 1)
307       matrix[i] = compensated_green_ratio_ * in[i];
308     else if ((i % 4) == 2)
309       matrix[i] = compensated_blue_ratio_ * in[i];
310     else if ((i % 4) == 3)
311       matrix[i] = in[i];
312   }
313   std::move(&matrix[0], &matrix[kColorTransformMatrixCount - 1], in);
314 }
315 
SetEnabled(bool enabled)316 HWC2::Error SaturationCompensation::SetEnabled(bool enabled) {
317   if (enabled == enabled_)
318     return HWC2::Error::None;
319 
320   if (enabled) {
321     if (!ConfigSaturationParameter()) {
322       enabled_ = false;
323       return HWC2::Error::NotValidated;
324     }
325   }
326   enabled_ = enabled;
327   return HWC2::Error::None;
328 }
329 
ConfigSaturationParameter()330 bool SaturationCompensation::ConfigSaturationParameter() {
331   std::vector<float> SaturationParameter(kSaturationParameters);
332   if (!ParseFloatValueByCommas(key_values_, kSaturationParameters, SaturationParameter))
333     return false;
334 
335   int32_t matrix_index = 0;
336   for (uint32_t i = 0; i < SaturationParameter.size(); i++) {
337     saturated_matrix_[matrix_index] = SaturationParameter.at(i);
338     // Put parameters to matrix and keep the last row/column identity
339     if ((i + 1) % 3 == 0) {
340       matrix_index += 2;
341     } else {
342       matrix_index++;
343     }
344     DLOGD("SaturationParameter[%d]=%f", i, SaturationParameter.at(i));
345   }
346   return true;
347 }
348 
ApplyToMatrix(double * in)349 void SaturationCompensation::ApplyToMatrix(double *in) {
350   double matrix[kColorTransformMatrixCount] = {0};
351   // 4 x 4 matrix multiplication
352   for (uint32_t i = 0; i < kNumOfRows; i++) {
353     for (uint32_t j = 0; j < kColumnsPerRow; j++) {
354       for (uint32_t k = 0; k < kColumnsPerRow; k++) {
355         matrix[j + (i * kColumnsPerRow)] +=
356             saturated_matrix_[k + (i * kColumnsPerRow)] * in[j + (k * kColumnsPerRow)];
357       }
358     }
359   }
360   std::move(&matrix[0], &matrix[kColorTransformMatrixCount - 1], in);
361 }
362 
SetColorTransform(const float * matrix,android_color_transform_t)363 HWC2::Error HWCColorMode::SetColorTransform(const float *matrix,
364                                             android_color_transform_t /*hint*/) {
365   DTRACE_SCOPED();
366   auto status = HWC2::Error::None;
367   double color_matrix_restore[kColorTransformMatrixCount] = {0};
368   CopyColorTransformMatrix(color_matrix_, color_matrix_restore);
369   CopyColorTransformMatrix(matrix, color_matrix_);
370   DisplayError error =
371       display_intf_->SetColorTransform(kColorTransformMatrixCount, PickTransferMatrix());
372   if (error != kErrorNone) {
373     CopyColorTransformMatrix(color_matrix_restore, color_matrix_);
374     DLOGE("Failed to set Color Transform Matrix");
375     status = HWC2::Error::Unsupported;
376   }
377 
378   return status;
379 }
380 
FindRenderIntent(const ColorMode & mode,const std::string & mode_string)381 void HWCColorMode::FindRenderIntent(const ColorMode &mode, const std::string &mode_string) {
382   auto intent = RenderIntent::COLORIMETRIC;
383   if (mode_string.find("enhanced") != std::string::npos) {
384     intent = RenderIntent::ENHANCE;
385   }
386   color_mode_map_[mode][intent] = mode_string;
387 }
388 
PopulateColorModes()389 void HWCColorMode::PopulateColorModes() {
390   uint32_t color_mode_count = 0;
391   // SDM returns modes which have attributes defining mode and rendering intent
392   DisplayError error = display_intf_->GetColorModeCount(&color_mode_count);
393   if (error != kErrorNone || (color_mode_count == 0)) {
394     DLOGW("GetColorModeCount failed, use native color mode");
395     color_mode_map_[ColorMode::NATIVE][RenderIntent::COLORIMETRIC] = "hal_native_identity";
396     return;
397   }
398 
399   DLOGV_IF(kTagClient, "Color Modes supported count = %d", color_mode_count);
400 
401   std::vector<std::string> color_modes(color_mode_count);
402   error = display_intf_->GetColorModes(&color_mode_count, &color_modes);
403   for (uint32_t i = 0; i < color_mode_count; i++) {
404     std::string &mode_string = color_modes.at(i);
405     DLOGV_IF(kTagClient, "Color Mode[%d] = %s", i, mode_string.c_str());
406     AttrVal attr;
407     error = display_intf_->GetColorModeAttr(mode_string, &attr);
408     std::string color_gamut = kNative, dynamic_range = kSdr, pic_quality = kStandard;
409     if (!attr.empty()) {
410       for (auto &it : attr) {
411         if (it.first.find(kColorGamutAttribute) != std::string::npos) {
412           color_gamut = it.second;
413         } else if (it.first.find(kDynamicRangeAttribute) != std::string::npos) {
414           dynamic_range = it.second;
415         } else if (it.first.find(kPictureQualityAttribute) != std::string::npos) {
416           pic_quality = it.second;
417         }
418       }
419 
420       DLOGV_IF(kTagClient, "color_gamut : %s, dynamic_range : %s, pic_quality : %s",
421                color_gamut.c_str(), dynamic_range.c_str(), pic_quality.c_str());
422       if (color_gamut == kNative) {
423         color_mode_map_[ColorMode::NATIVE][RenderIntent::COLORIMETRIC] = mode_string;
424       }
425 
426       if (color_gamut == kSrgb && dynamic_range == kSdr) {
427         if (pic_quality == kStandard) {
428           color_mode_map_[ColorMode::SRGB][RenderIntent::COLORIMETRIC] = mode_string;
429         }
430         if (pic_quality == kEnhanced) {
431           color_mode_map_[ColorMode::SRGB][RenderIntent::ENHANCE] = mode_string;
432         }
433       }
434 
435       if (color_gamut == kDcip3 && dynamic_range == kSdr) {
436         if (pic_quality == kStandard) {
437           color_mode_map_[ColorMode::DISPLAY_P3][RenderIntent::COLORIMETRIC] = mode_string;
438         }
439         if (pic_quality == kEnhanced) {
440           color_mode_map_[ColorMode::DISPLAY_P3][RenderIntent::ENHANCE] = mode_string;
441         }
442       }
443 
444       if (pic_quality == kStandard && dynamic_range == kHdr) {
445         color_mode_map_[ColorMode::BT2100_PQ][RenderIntent::TONE_MAP_COLORIMETRIC] = mode_string;
446         color_mode_map_[ColorMode::BT2100_HLG][RenderIntent::TONE_MAP_COLORIMETRIC] = mode_string;
447       }
448     } else {
449       // Look at the mode names, if no attributes are found
450       if (mode_string.find("hal_native") != std::string::npos) {
451         color_mode_map_[ColorMode::NATIVE][RenderIntent::COLORIMETRIC] = mode_string;
452       }
453     }
454   }
455 }
456 
ApplyDefaultColorMode()457 HWC2::Error HWCColorMode::ApplyDefaultColorMode() {
458   auto color_mode = ColorMode::NATIVE;
459   if (color_mode_map_.size() == 1U) {
460     color_mode = color_mode_map_.begin()->first;
461   } else if (color_mode_map_.size() > 1U) {
462     std::string default_color_mode;
463     bool found = false;
464     DisplayError error = display_intf_->GetDefaultColorMode(&default_color_mode);
465     if (error == kErrorNone) {
466       // get the default mode corresponding android_color_mode_t
467       for (auto &it_mode : color_mode_map_) {
468         for (auto &it : it_mode.second) {
469           if (it.second == default_color_mode) {
470             found = true;
471             break;
472           }
473         }
474         if (found) {
475           color_mode = it_mode.first;
476           break;
477         }
478       }
479     }
480 
481     // return the first color mode we encounter if not found
482     if (!found) {
483       color_mode = color_mode_map_.begin()->first;
484     }
485   }
486   return SetColorModeWithRenderIntent(color_mode, RenderIntent::COLORIMETRIC);
487 }
488 
GetWorkingColorSpace()489 PrimariesTransfer HWCColorMode::GetWorkingColorSpace() {
490   ColorPrimaries primaries = ColorPrimaries_BT709_5;
491   GammaTransfer transfer = Transfer_sRGB;
492   switch (current_color_mode_) {
493     case ColorMode::BT2100_PQ:
494       primaries = ColorPrimaries_BT2020;
495       transfer = Transfer_SMPTE_ST2084;
496       break;
497     case ColorMode::BT2100_HLG:
498       primaries = ColorPrimaries_BT2020;
499       transfer = Transfer_HLG;
500       break;
501     case ColorMode::DISPLAY_P3:
502       primaries = ColorPrimaries_DCIP3;
503       transfer = Transfer_sRGB;
504       break;
505     case ColorMode::NATIVE:
506     case ColorMode::SRGB:
507       break;
508     default:
509       DLOGW("Invalid color mode: %d", current_color_mode_);
510       break;
511   }
512   return std::make_pair(primaries, transfer);
513 }
514 
Dump(std::ostringstream * os)515 void HWCColorMode::Dump(std::ostringstream* os) {
516   *os << "color modes supported: \n";
517   for (auto it : color_mode_map_) {
518     *os << "mode: " << static_cast<int32_t>(it.first) << " RIs { ";
519     for (auto rit : color_mode_map_[it.first]) {
520       *os << static_cast<int32_t>(rit.first) << " ";
521     }
522     *os << "} \n";
523   }
524   *os << "current mode: " << static_cast<uint32_t>(current_color_mode_) << std::endl;
525   *os << "current render_intent: " << static_cast<uint32_t>(current_render_intent_) << std::endl;
526   *os << "Need WhiteCompensation: "
527       << (current_render_intent_ == RenderIntent::ENHANCE && HasWhiteCompensation()) << std::endl;
528   *os << "Need SaturationCompensation: "
529       << (current_render_intent_ == RenderIntent::ENHANCE && HasSaturationCompensation())
530       << std::endl;
531 
532   *os << "current transform: ";
533   double color_matrix[kColorTransformMatrixCount] = {0};
534 
535   CopyColorTransformMatrix(PickTransferMatrix(), color_matrix);
536 
537   for (uint32_t i = 0; i < kColorTransformMatrixCount; i++) {
538     if (i % 4 == 0) {
539      *os << std::endl;
540     }
541     *os << std::fixed << std::setprecision(4) << std::setw(8) << std::setfill(' ')
542         << color_matrix[i] << " ";
543   }
544   *os << std::endl;
545 }
546 
HWCDisplay(CoreInterface * core_intf,HWCCallbacks * callbacks,DisplayType type,hwc2_display_t id,bool needs_blit,qService::QService * qservice,DisplayClass display_class,BufferAllocator * buffer_allocator)547 HWCDisplay::HWCDisplay(CoreInterface *core_intf, HWCCallbacks *callbacks, DisplayType type,
548                        hwc2_display_t id, bool needs_blit, qService::QService *qservice,
549                        DisplayClass display_class, BufferAllocator *buffer_allocator)
550     : core_intf_(core_intf),
551       callbacks_(callbacks),
552       type_(type),
553       id_(id),
554       needs_blit_(needs_blit),
555       qservice_(qservice),
556       display_class_(display_class) {
557   buffer_allocator_ = static_cast<HWCBufferAllocator *>(buffer_allocator);
558 }
559 
Init()560 int HWCDisplay::Init() {
561   DisplayError error = core_intf_->CreateDisplay(type_, this, &display_intf_);
562   if (error != kErrorNone) {
563     DLOGE("Display create failed. Error = %d display_type %d event_handler %p disp_intf %p", error,
564           type_, this, &display_intf_);
565     return -EINVAL;
566   }
567 
568   validated_ = false;
569   HWCDebugHandler::Get()->GetProperty(DISABLE_HDR, &disable_hdr_handling_);
570   if (disable_hdr_handling_) {
571     DLOGI("HDR Handling disabled");
572   }
573 
574   int property_swap_interval = 1;
575   HWCDebugHandler::Get()->GetProperty("debug.egl.swapinterval", &property_swap_interval);
576   if (property_swap_interval == 0) {
577     swap_interval_zero_ = true;
578   }
579 
580   client_target_ = new HWCLayer(id_, buffer_allocator_);
581 
582   int blit_enabled = 0;
583   HWCDebugHandler::Get()->GetProperty(DISABLE_BLIT_COMPOSITION_PROP, &blit_enabled);
584   if (needs_blit_ && blit_enabled) {
585     // TODO(user): Add blit engine when needed
586   }
587 
588   error = display_intf_->GetNumVariableInfoConfigs(&num_configs_);
589   if (error != kErrorNone) {
590     DLOGE("Getting config count failed. Error = %d", error);
591     return -EINVAL;
592   }
593 
594   display_intf_->GetRefreshRateRange(&min_refresh_rate_, &max_refresh_rate_);
595   current_refresh_rate_ = max_refresh_rate_;
596 
597   GetUnderScanConfig();
598 
599   DisplayConfigFixedInfo fixed_info = {};
600   display_intf_->GetConfig(&fixed_info);
601   partial_update_enabled_ = fixed_info.partial_update || (!fixed_info.is_cmdmode);
602   client_target_->SetPartialUpdate(partial_update_enabled_);
603 
604   DLOGI("Display created with id: %d", id_);
605 
606   return 0;
607 }
608 
Deinit()609 int HWCDisplay::Deinit() {
610   DisplayError error = core_intf_->DestroyDisplay(display_intf_);
611   if (error != kErrorNone) {
612     DLOGE("Display destroy failed. Error = %d", error);
613     return -EINVAL;
614   }
615 
616   delete client_target_;
617   for (auto hwc_layer : layer_set_) {
618     delete hwc_layer;
619   }
620 
621   if (color_mode_) {
622     color_mode_->DeInit();
623     delete color_mode_;
624   }
625 
626   return 0;
627 }
628 
629 // LayerStack operations
CreateLayer(hwc2_layer_t * out_layer_id)630 HWC2::Error HWCDisplay::CreateLayer(hwc2_layer_t *out_layer_id) {
631   HWCLayer *layer = *layer_set_.emplace(new HWCLayer(id_, buffer_allocator_));
632   layer_map_.emplace(std::make_pair(layer->GetId(), layer));
633   *out_layer_id = layer->GetId();
634   geometry_changes_ |= GeometryChanges::kAdded;
635   validated_ = false;
636   layer_stack_invalid_ = true;
637   layer->SetPartialUpdate(partial_update_enabled_);
638 
639   return HWC2::Error::None;
640 }
641 
GetHWCLayer(hwc2_layer_t layer_id)642 HWCLayer *HWCDisplay::GetHWCLayer(hwc2_layer_t layer_id) {
643   const auto map_layer = layer_map_.find(layer_id);
644   if (map_layer == layer_map_.end()) {
645     DLOGE("[%" PRIu64 "] GetLayer(%" PRIu64 ") failed: no such layer", id_, layer_id);
646     return nullptr;
647   } else {
648     return map_layer->second;
649   }
650 }
651 
DestroyLayer(hwc2_layer_t layer_id)652 HWC2::Error HWCDisplay::DestroyLayer(hwc2_layer_t layer_id) {
653   const auto map_layer = layer_map_.find(layer_id);
654   if (map_layer == layer_map_.end()) {
655     DLOGE("[%" PRIu64 "] destroyLayer(%" PRIu64 ") failed: no such layer", id_, layer_id);
656     return HWC2::Error::BadLayer;
657   }
658   const auto layer = map_layer->second;
659   layer_map_.erase(map_layer);
660   const auto z_range = layer_set_.equal_range(layer);
661   for (auto current = z_range.first; current != z_range.second; ++current) {
662     if (*current == layer) {
663       current = layer_set_.erase(current);
664       delete layer;
665       break;
666     }
667   }
668 
669   geometry_changes_ |= GeometryChanges::kRemoved;
670   validated_ = false;
671   layer_stack_invalid_ = true;
672 
673   return HWC2::Error::None;
674 }
675 
676 
BuildLayerStack()677 void HWCDisplay::BuildLayerStack() {
678   layer_stack_ = LayerStack();
679   display_rect_ = LayerRect();
680   metadata_refresh_rate_ = 0;
681   bool secure_display_active = false;
682   layer_stack_.flags.animating = animating_;
683 
684   uint32_t color_mode_count = 0;
685   display_intf_->GetColorModeCount(&color_mode_count);
686   hdr_largest_layer_px_ = 0.0f;
687 
688   // Add one layer for fb target
689   // TODO(user): Add blit target layers
690   for (auto hwc_layer : layer_set_) {
691     // Reset layer data which SDM may change
692     hwc_layer->ResetPerFrameData();
693 
694     Layer *layer = hwc_layer->GetSDMLayer();
695     layer->flags = {};   // Reset earlier flags
696     if (hwc_layer->GetClientRequestedCompositionType() == HWC2::Composition::Client) {
697       layer->flags.skip = true;
698     } else if (hwc_layer->GetClientRequestedCompositionType() == HWC2::Composition::SolidColor) {
699       layer->flags.solid_fill = true;
700     }
701 
702     if (!hwc_layer->ValidateAndSetCSC()) {
703       layer->flags.skip = true;
704     }
705 
706     auto range = hwc_layer->GetLayerDataspace() & HAL_DATASPACE_RANGE_MASK;
707     if (range == HAL_DATASPACE_RANGE_EXTENDED) {
708       layer->flags.skip = true;
709     }
710 
711     if (hwc_layer->IsColorTransformSet()) {
712       layer->flags.skip = true;
713     }
714 
715     // set default composition as GPU for SDM
716     layer->composition = kCompositionGPU;
717 
718     if (swap_interval_zero_) {
719       if (layer->input_buffer.acquire_fence_fd >= 0) {
720         close(layer->input_buffer.acquire_fence_fd);
721         layer->input_buffer.acquire_fence_fd = -1;
722       }
723     }
724 
725     bool is_secure = false;
726     bool is_video = false;
727     const private_handle_t *handle =
728         reinterpret_cast<const private_handle_t *>(layer->input_buffer.buffer_id);
729     if (handle) {
730       if (handle->buffer_type == BUFFER_TYPE_VIDEO) {
731         layer_stack_.flags.video_present = true;
732         is_video = true;
733       } else if (layer->transform.rotation != 0.0f) {
734         layer->flags.skip = true;
735       }
736       // TZ Protected Buffer - L1
737       // Gralloc Usage Protected Buffer - L3 - which needs to be treated as Secure & avoid fallback
738       if (handle->flags & private_handle_t::PRIV_FLAGS_PROTECTED_BUFFER ||
739           handle->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
740         layer_stack_.flags.secure_present = true;
741         is_secure = true;
742       }
743     }
744 
745     if (layer->input_buffer.flags.secure_display) {
746       secure_display_active = true;
747       is_secure = true;
748     }
749 
750     if (hwc_layer->IsSingleBuffered() &&
751        !(hwc_layer->IsRotationPresent() || hwc_layer->IsScalingPresent())) {
752       layer->flags.single_buffer = true;
753       layer_stack_.flags.single_buffered_layer_present = true;
754     }
755 
756     if (hwc_layer->GetClientRequestedCompositionType() == HWC2::Composition::Cursor) {
757       // Currently we support only one HWCursor & only at top most z-order
758       if ((*layer_set_.rbegin())->GetId() == hwc_layer->GetId()) {
759         layer->flags.cursor = true;
760         layer_stack_.flags.cursor_present = true;
761       }
762     }
763 
764     bool hdr_layer = layer->input_buffer.color_metadata.colorPrimaries == ColorPrimaries_BT2020 &&
765                      (layer->input_buffer.color_metadata.transfer == Transfer_SMPTE_ST2084 ||
766                      layer->input_buffer.color_metadata.transfer == Transfer_HLG);
767     if (hdr_layer && !disable_hdr_handling_  &&
768         current_color_mode_ != ColorMode::NATIVE) {
769       // Dont honor HDR when its handling is disabled
770       // Also, when the color mode is native, it implies that
771       // SF has not correctly set the mode to BT2100_PQ in the presence of an HDR layer
772       // In such cases, we should not handle HDR as the HDR mode isn't applied
773       layer->input_buffer.flags.hdr = true;
774       layer_stack_.flags.hdr_present = true;
775 
776       // HDR area
777       auto hdr_layer_area = (layer->dst_rect.right - layer->dst_rect.left) *
778                             (layer->dst_rect.bottom - layer->dst_rect.top);
779       hdr_largest_layer_px_ = std::max(hdr_largest_layer_px_, hdr_layer_area);
780     }
781 
782     if (hwc_layer->IsNonIntegralSourceCrop() && !is_secure && !layer->flags.solid_fill &&
783         !is_video) {
784       layer->flags.skip = true;
785     }
786 
787     if (layer->flags.skip) {
788       layer_stack_.flags.skip_present = true;
789     }
790 
791     // TODO(user): Move to a getter if this is needed at other places
792     hwc_rect_t scaled_display_frame = {INT(layer->dst_rect.left), INT(layer->dst_rect.top),
793                                        INT(layer->dst_rect.right), INT(layer->dst_rect.bottom)};
794     if (hwc_layer->GetGeometryChanges() & kDisplayFrame) {
795       ApplyScanAdjustment(&scaled_display_frame);
796     }
797     hwc_layer->SetLayerDisplayFrame(scaled_display_frame);
798     hwc_layer->ResetPerFrameData();
799     // SDM requires these details even for solid fill
800     if (layer->flags.solid_fill) {
801       LayerBuffer *layer_buffer = &layer->input_buffer;
802       layer_buffer->width = UINT32(layer->dst_rect.right - layer->dst_rect.left);
803       layer_buffer->height = UINT32(layer->dst_rect.bottom - layer->dst_rect.top);
804       layer_buffer->unaligned_width = layer_buffer->width;
805       layer_buffer->unaligned_height = layer_buffer->height;
806       layer_buffer->acquire_fence_fd = -1;
807       layer_buffer->release_fence_fd = -1;
808       layer->src_rect.left = 0;
809       layer->src_rect.top = 0;
810       layer->src_rect.right = FLOAT(layer_buffer->width);
811       layer->src_rect.bottom = FLOAT(layer_buffer->height);
812     }
813 
814     if (hwc_layer->HasMetaDataRefreshRate() && layer->frame_rate > metadata_refresh_rate_) {
815       metadata_refresh_rate_ = SanitizeRefreshRate(layer->frame_rate);
816     }
817 
818     display_rect_ = Union(display_rect_, layer->dst_rect);
819     geometry_changes_ |= hwc_layer->GetGeometryChanges();
820 
821     layer->flags.updating = true;
822     if (layer_set_.size() <= kMaxLayerCount) {
823       layer->flags.updating = IsLayerUpdating(hwc_layer);
824     }
825 
826     layer_stack_.layers.push_back(layer);
827   }
828 
829   for (auto hwc_layer : layer_set_) {
830     auto layer = hwc_layer->GetSDMLayer();
831     if (layer->input_buffer.color_metadata.colorPrimaries != working_primaries_ &&
832         !hwc_layer->SupportLocalConversion(working_primaries_)) {
833       layer->flags.skip = true;
834     }
835     if (layer->flags.skip) {
836       layer_stack_.flags.skip_present = true;
837     }
838   }
839 
840   // TODO(user): Set correctly when SDM supports geometry_changes as bitmask
841   layer_stack_.flags.geometry_changed = UINT32(geometry_changes_ > 0);
842   // Append client target to the layer stack
843   Layer *sdm_client_target = client_target_->GetSDMLayer();
844   sdm_client_target->flags.updating = IsLayerUpdating(client_target_);
845   layer_stack_.layers.push_back(sdm_client_target);
846   // fall back frame composition to GPU when client target is 10bit
847   // TODO(user): clarify the behaviour from Client(SF) and SDM Extn -
848   // when handling 10bit FBT, as it would affect blending
849   if (Is10BitFormat(sdm_client_target->input_buffer.format)) {
850     // Must fall back to client composition
851     MarkLayersForClientComposition();
852   }
853   // set secure display
854   SetSecureDisplay(secure_display_active);
855 }
856 
BuildSolidFillStack()857 void HWCDisplay::BuildSolidFillStack() {
858   layer_stack_ = LayerStack();
859   display_rect_ = LayerRect();
860 
861   layer_stack_.layers.push_back(solid_fill_layer_);
862   layer_stack_.flags.geometry_changed = 1U;
863   // Append client target to the layer stack
864   layer_stack_.layers.push_back(client_target_->GetSDMLayer());
865 }
866 
SetLayerZOrder(hwc2_layer_t layer_id,uint32_t z)867 HWC2::Error HWCDisplay::SetLayerZOrder(hwc2_layer_t layer_id, uint32_t z) {
868   const auto map_layer = layer_map_.find(layer_id);
869   if (map_layer == layer_map_.end()) {
870     DLOGE("[%" PRIu64 "] updateLayerZ failed to find layer", id_);
871     return HWC2::Error::BadLayer;
872   }
873 
874   const auto layer = map_layer->second;
875   const auto z_range = layer_set_.equal_range(layer);
876   bool layer_on_display = false;
877   for (auto current = z_range.first; current != z_range.second; ++current) {
878     if (*current == layer) {
879       if ((*current)->GetZ() == z) {
880         // Don't change anything if the Z hasn't changed
881         return HWC2::Error::None;
882       }
883       current = layer_set_.erase(current);
884       layer_on_display = true;
885       break;
886     }
887   }
888 
889   if (!layer_on_display) {
890     DLOGE("[%" PRIu64 "] updateLayerZ failed to find layer on display", id_);
891     return HWC2::Error::BadLayer;
892   }
893 
894   layer->SetLayerZOrder(z);
895   layer_set_.emplace(layer);
896   return HWC2::Error::None;
897 }
898 
SetVsyncEnabled(HWC2::Vsync enabled)899 HWC2::Error HWCDisplay::SetVsyncEnabled(HWC2::Vsync enabled) {
900   DLOGV("Display ID: %d enabled: %s", id_, to_string(enabled).c_str());
901   ATRACE_INT("SetVsyncState ", enabled == HWC2::Vsync::Enable ? 1 : 0);
902   DisplayError error = kErrorNone;
903 
904   if (shutdown_pending_ || !callbacks_->VsyncCallbackRegistered()) {
905     return HWC2::Error::None;
906   }
907 
908   bool state;
909   if (enabled == HWC2::Vsync::Enable)
910     state = true;
911   else if (enabled == HWC2::Vsync::Disable)
912     state = false;
913   else
914     return HWC2::Error::BadParameter;
915 
916   error = display_intf_->SetVSyncState(state);
917 
918   if (error != kErrorNone) {
919     if (error == kErrorShutDown) {
920       shutdown_pending_ = true;
921       return HWC2::Error::None;
922     }
923     DLOGE("Failed. enabled = %s, error = %d", to_string(enabled).c_str(), error);
924     return HWC2::Error::BadDisplay;
925   }
926 
927   return HWC2::Error::None;
928 }
929 
SetPowerMode(HWC2::PowerMode mode)930 HWC2::Error HWCDisplay::SetPowerMode(HWC2::PowerMode mode) {
931   DLOGV("display = %d, mode = %s", id_, to_string(mode).c_str());
932   DisplayState state = kStateOff;
933   bool flush_on_error = flush_on_error_;
934 
935   if (shutdown_pending_) {
936     return HWC2::Error::None;
937   }
938 
939   switch (mode) {
940     case HWC2::PowerMode::Off:
941       // During power off, all of the buffers are released.
942       // Do not flush until a buffer is successfully submitted again.
943       flush_on_error = false;
944       state = kStateOff;
945       if (tone_mapper_) {
946         tone_mapper_->Terminate();
947       }
948       break;
949     case HWC2::PowerMode::On:
950       state = kStateOn;
951       last_power_mode_ = HWC2::PowerMode::On;
952       break;
953     case HWC2::PowerMode::Doze:
954       state = kStateDoze;
955       last_power_mode_ = HWC2::PowerMode::Doze;
956       break;
957     case HWC2::PowerMode::DozeSuspend:
958       state = kStateDozeSuspend;
959       last_power_mode_ = HWC2::PowerMode::DozeSuspend;
960       break;
961     default:
962       return HWC2::Error::BadParameter;
963   }
964   int release_fence = -1;
965 
966   ATRACE_INT("SetPowerMode ", state);
967   DisplayError error = display_intf_->SetDisplayState(state, &release_fence);
968   validated_ = false;
969 
970   if (error == kErrorNone) {
971     flush_on_error_ = flush_on_error;
972   } else {
973     if (error == kErrorShutDown) {
974       shutdown_pending_ = true;
975       return HWC2::Error::None;
976     }
977     DLOGE("Set state failed. Error = %d", error);
978     return HWC2::Error::BadParameter;
979   }
980 
981   if (release_fence >= 0) {
982     for (auto hwc_layer : layer_set_) {
983       auto fence = hwc_layer->PopBackReleaseFence();
984       auto merged_fence = -1;
985       if (fence >= 0) {
986         merged_fence = sync_merge("sync_merge", release_fence, fence);
987         ::close(fence);
988       } else {
989         merged_fence = ::dup(release_fence);
990       }
991       hwc_layer->PushBackReleaseFence(merged_fence);
992     }
993     ::close(release_fence);
994   }
995   return HWC2::Error::None;
996 }
997 
GetClientTargetSupport(uint32_t width,uint32_t height,int32_t format,int32_t dataspace)998 HWC2::Error HWCDisplay::GetClientTargetSupport(uint32_t width, uint32_t height, int32_t format,
999                                                int32_t dataspace) {
1000   ColorMetaData color_metadata = {};
1001   if (dataspace != HAL_DATASPACE_UNKNOWN) {
1002     GetColorPrimary(dataspace, &(color_metadata.colorPrimaries));
1003     GetTransfer(dataspace, &(color_metadata.transfer));
1004     GetRange(dataspace, &(color_metadata.range));
1005   }
1006 
1007   LayerBufferFormat sdm_format = GetSDMFormat(format, 0);
1008   if (display_intf_->GetClientTargetSupport(width, height, sdm_format,
1009                                             color_metadata) != kErrorNone) {
1010     return HWC2::Error::Unsupported;
1011   }
1012 
1013   return HWC2::Error::None;
1014 }
1015 
GetColorModes(uint32_t * out_num_modes,ColorMode * out_modes)1016 HWC2::Error HWCDisplay::GetColorModes(uint32_t *out_num_modes, ColorMode *out_modes) {
1017   if (out_modes == nullptr) {
1018     *out_num_modes = 1;
1019   } else if (out_modes && *out_num_modes > 0) {
1020     *out_num_modes = 1;
1021     out_modes[0] = ColorMode::NATIVE;
1022   }
1023   return HWC2::Error::None;
1024 }
1025 
GetRenderIntents(ColorMode mode,uint32_t * out_num_intents,RenderIntent * out_intents)1026 HWC2::Error HWCDisplay::GetRenderIntents(ColorMode mode, uint32_t *out_num_intents,
1027                                          RenderIntent *out_intents) {
1028   if (mode != ColorMode::NATIVE) {
1029     return HWC2::Error::Unsupported;
1030   }
1031   if (out_intents == nullptr) {
1032     *out_num_intents = 1;
1033   } else if (out_intents && *out_num_intents > 0) {
1034     *out_num_intents = 1;
1035     out_intents[0] = RenderIntent::COLORIMETRIC;
1036   }
1037   return HWC2::Error::None;
1038 }
1039 
GetDisplayConfigs(uint32_t * out_num_configs,hwc2_config_t * out_configs)1040 HWC2::Error HWCDisplay::GetDisplayConfigs(uint32_t *out_num_configs, hwc2_config_t *out_configs) {
1041   if (out_num_configs == nullptr) {
1042     return HWC2::Error::BadParameter;
1043   }
1044 
1045   if (out_configs == nullptr) {
1046     *out_num_configs = num_configs_;
1047     return HWC2::Error::None;
1048   }
1049 
1050   *out_num_configs = std::min(*out_num_configs, num_configs_);
1051   for (uint32_t i = 0; i < *out_num_configs; i++) {
1052     out_configs[i] = i;
1053   }
1054 
1055   return HWC2::Error::None;
1056 }
1057 
GetDisplayAttribute(hwc2_config_t config,HWC2::Attribute attribute,int32_t * out_value)1058 HWC2::Error HWCDisplay::GetDisplayAttribute(hwc2_config_t config, HWC2::Attribute attribute,
1059                                             int32_t *out_value) {
1060   DisplayConfigVariableInfo variable_config;
1061   // Get display attributes from config index only if resolution switch is supported.
1062   // Otherwise always send mixer attributes. This is to support destination scaler.
1063   if (num_configs_ > 1) {
1064     if (GetDisplayAttributesForConfig(INT(config), &variable_config) != kErrorNone) {
1065       DLOGE("Get variable config failed");
1066       return HWC2::Error::BadDisplay;
1067     }
1068   } else {
1069     if (display_intf_->GetFrameBufferConfig(&variable_config) != kErrorNone) {
1070       DLOGV("Get variable config failed");
1071       return HWC2::Error::BadDisplay;
1072     }
1073   }
1074 
1075   switch (attribute) {
1076     case HWC2::Attribute::VsyncPeriod:
1077       *out_value = INT32(variable_config.vsync_period_ns);
1078       break;
1079     case HWC2::Attribute::Width:
1080       *out_value = INT32(variable_config.x_pixels);
1081       break;
1082     case HWC2::Attribute::Height:
1083       *out_value = INT32(variable_config.y_pixels);
1084       break;
1085     case HWC2::Attribute::DpiX:
1086       *out_value = INT32(variable_config.x_dpi * 1000.0f);
1087       break;
1088     case HWC2::Attribute::DpiY:
1089       *out_value = INT32(variable_config.y_dpi * 1000.0f);
1090       break;
1091     default:
1092       DLOGW("Spurious attribute type = %s", to_string(attribute).c_str());
1093       *out_value = -1;
1094       return HWC2::Error::BadConfig;
1095   }
1096 
1097   return HWC2::Error::None;
1098 }
1099 
GetDisplayName(uint32_t * out_size,char * out_name)1100 HWC2::Error HWCDisplay::GetDisplayName(uint32_t *out_size, char *out_name) {
1101   // TODO(user): Get panel name and EDID name and populate it here
1102   if (out_size == nullptr) {
1103     return HWC2::Error::BadParameter;
1104   }
1105 
1106   std::string name;
1107   switch (id_) {
1108     case HWC_DISPLAY_PRIMARY:
1109       name = "Primary Display";
1110       break;
1111     case HWC_DISPLAY_EXTERNAL:
1112       name = "External Display";
1113       break;
1114     case HWC_DISPLAY_VIRTUAL:
1115       name = "Virtual Display";
1116       break;
1117     default:
1118       name = "Unknown";
1119       break;
1120   }
1121 
1122   if (out_name == nullptr) {
1123     *out_size = UINT32(name.size()) + 1;
1124   } else {
1125     *out_size = std::min((UINT32(name.size()) + 1), *out_size);
1126     if (*out_size > 0) {
1127       std::strncpy(out_name, name.c_str(), *out_size);
1128       out_name[*out_size - 1] = '\0';
1129     } else {
1130       DLOGW("Invalid size requested");
1131     }
1132   }
1133 
1134   return HWC2::Error::None;
1135 }
1136 
GetDisplayType(int32_t * out_type)1137 HWC2::Error HWCDisplay::GetDisplayType(int32_t *out_type) {
1138   if (out_type != nullptr) {
1139     if (id_ == HWC_DISPLAY_VIRTUAL) {
1140       *out_type = HWC2_DISPLAY_TYPE_VIRTUAL;
1141     } else {
1142       *out_type = HWC2_DISPLAY_TYPE_PHYSICAL;
1143     }
1144     return HWC2::Error::None;
1145   } else {
1146     return HWC2::Error::BadParameter;
1147   }
1148 }
1149 
GetPerFrameMetadataKeys(uint32_t * out_num_keys,PerFrameMetadataKey * out_keys)1150 HWC2::Error HWCDisplay::GetPerFrameMetadataKeys(uint32_t *out_num_keys,
1151                                                 PerFrameMetadataKey *out_keys) {
1152   if (out_num_keys == nullptr) {
1153     return HWC2::Error::BadParameter;
1154   }
1155   *out_num_keys = UINT32(PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL) + 1;
1156   if (out_keys != nullptr) {
1157     out_keys[0] = PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X;
1158     out_keys[1] = PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y;
1159     out_keys[2] = PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X;
1160     out_keys[3] = PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y;
1161     out_keys[4] = PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X;
1162     out_keys[5] = PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y;
1163     out_keys[6] = PerFrameMetadataKey::WHITE_POINT_X;
1164     out_keys[7] = PerFrameMetadataKey::WHITE_POINT_Y;
1165     out_keys[8] = PerFrameMetadataKey::MAX_LUMINANCE;
1166     out_keys[9] = PerFrameMetadataKey::MIN_LUMINANCE;
1167     out_keys[10] = PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL;
1168     out_keys[11] = PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL;
1169   }
1170   return HWC2::Error::None;
1171 }
1172 
GetActiveConfig(hwc2_config_t * out_config)1173 HWC2::Error HWCDisplay::GetActiveConfig(hwc2_config_t *out_config) {
1174   if (out_config == nullptr) {
1175     return HWC2::Error::BadDisplay;
1176   }
1177 
1178   uint32_t active_index = 0;
1179   if (GetActiveDisplayConfig(&active_index) != kErrorNone) {
1180     return HWC2::Error::BadConfig;
1181   }
1182 
1183   *out_config = active_index;
1184 
1185   return HWC2::Error::None;
1186 }
1187 
SetClientTarget(buffer_handle_t target,int32_t acquire_fence,int32_t dataspace,hwc_region_t damage)1188 HWC2::Error HWCDisplay::SetClientTarget(buffer_handle_t target, int32_t acquire_fence,
1189                                         int32_t dataspace, hwc_region_t damage) {
1190   // TODO(user): SurfaceFlinger gives us a null pointer here when doing full SDE composition
1191   // The error is problematic for layer caching as it would overwrite our cached client target.
1192   // Reported bug 28569722 to resolve this.
1193   // For now, continue to use the last valid buffer reported to us for layer caching.
1194   if (target == nullptr) {
1195     return HWC2::Error::None;
1196   }
1197 
1198   if (acquire_fence == 0) {
1199     DLOGE("acquire_fence is zero");
1200     return HWC2::Error::BadParameter;
1201   }
1202 
1203   Layer *sdm_layer = client_target_->GetSDMLayer();
1204   sdm_layer->frame_rate = current_refresh_rate_;
1205   client_target_->SetLayerBuffer(target, acquire_fence);
1206   client_target_->SetLayerSurfaceDamage(damage);
1207   if (client_target_->GetLayerDataspace() != dataspace) {
1208     client_target_->SetLayerDataspace(dataspace);
1209     Layer *sdm_layer = client_target_->GetSDMLayer();
1210     // Data space would be validated at GetClientTargetSupport, so just use here.
1211     sdm::GetSDMColorSpace(dataspace, &sdm_layer->input_buffer.color_metadata);
1212   }
1213 
1214   return HWC2::Error::None;
1215 }
1216 
SetActiveConfig(hwc2_config_t config)1217 HWC2::Error HWCDisplay::SetActiveConfig(hwc2_config_t config) {
1218   if (SetActiveDisplayConfig(config) != kErrorNone) {
1219     return HWC2::Error::BadConfig;
1220   }
1221 
1222   validated_ = false;
1223   return HWC2::Error::None;
1224 }
1225 
SetMixerResolution(uint32_t width,uint32_t height)1226 DisplayError HWCDisplay::SetMixerResolution(uint32_t width, uint32_t height) {
1227   return kErrorNotSupported;
1228 }
1229 
SetFrameDumpConfig(uint32_t count,uint32_t bit_mask_layer_type,int32_t format,bool post_processed)1230 HWC2::Error HWCDisplay::SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type,
1231                                            int32_t format, bool post_processed) {
1232   dump_frame_count_ = count;
1233   dump_frame_index_ = 0;
1234   dump_input_layers_ = ((bit_mask_layer_type & (1 << INPUT_LAYER_DUMP)) != 0);
1235 
1236   if (tone_mapper_) {
1237     tone_mapper_->SetFrameDumpConfig(count);
1238   }
1239 
1240   DLOGI("num_frame_dump %d, input_layer_dump_enable %d", dump_frame_count_, dump_input_layers_);
1241   validated_ = false;
1242   return HWC2::Error::None;
1243 }
1244 
GetLastPowerMode()1245 HWC2::PowerMode HWCDisplay::GetLastPowerMode() {
1246   return last_power_mode_;
1247 }
1248 
VSync(const DisplayEventVSync & vsync)1249 DisplayError HWCDisplay::VSync(const DisplayEventVSync &vsync) {
1250   callbacks_->Vsync(id_, vsync.timestamp);
1251   return kErrorNone;
1252 }
1253 
Refresh()1254 DisplayError HWCDisplay::Refresh() {
1255   return kErrorNotSupported;
1256 }
1257 
CECMessage(char * message)1258 DisplayError HWCDisplay::CECMessage(char *message) {
1259   if (qservice_) {
1260     qservice_->onCECMessageReceived(message, 0);
1261   } else {
1262     DLOGW("Qservice instance not available.");
1263   }
1264 
1265   return kErrorNone;
1266 }
1267 
HandleEvent(DisplayEvent event)1268 DisplayError HWCDisplay::HandleEvent(DisplayEvent event) {
1269   switch (event) {
1270     case kIdleTimeout: {
1271       SCOPE_LOCK(HWCSession::locker_[type_]);
1272       if (pending_commit_) {
1273         // If idle timeout event comes in between prepare
1274         // and commit, drop it since device is not really
1275         // idle.
1276         return kErrorNotSupported;
1277       }
1278       validated_ = false;
1279       break;
1280     }
1281     case kThermalEvent:
1282     case kPanelDeadEvent: {
1283       SEQUENCE_WAIT_SCOPE_LOCK(HWCSession::locker_[type_]);
1284       validated_ = false;
1285     } break;
1286     case kIdlePowerCollapse:
1287       break;
1288     default:
1289       DLOGW("Unknown event: %d", event);
1290       break;
1291   }
1292 
1293   return kErrorNone;
1294 }
1295 
PrepareLayerStack(uint32_t * out_num_types,uint32_t * out_num_requests)1296 HWC2::Error HWCDisplay::PrepareLayerStack(uint32_t *out_num_types, uint32_t *out_num_requests) {
1297   layer_changes_.clear();
1298   layer_requests_.clear();
1299   has_client_composition_ = false;
1300 
1301   if (shutdown_pending_) {
1302     validated_ = false;
1303     return HWC2::Error::BadDisplay;
1304   }
1305 
1306   UpdateRefreshRate();
1307 
1308   if (CanSkipSdmPrepare(out_num_types, out_num_requests)) {
1309     return ((*out_num_types > 0) ? HWC2::Error::HasChanges : HWC2::Error::None);
1310   }
1311 
1312   if (!skip_prepare_) {
1313     DisplayError error = display_intf_->Prepare(&layer_stack_);
1314     if (error != kErrorNone) {
1315       if (error == kErrorShutDown) {
1316         shutdown_pending_ = true;
1317       } else if (error != kErrorPermission) {
1318         DLOGE("Prepare failed. Error = %d", error);
1319         // To prevent surfaceflinger infinite wait, flush the previous frame during Commit()
1320         // so that previous buffer and fences are released, and override the error.
1321         flush_ = true;
1322       }
1323       validated_ = false;
1324       return HWC2::Error::BadDisplay;
1325     }
1326   } else {
1327     // Skip is not set
1328     MarkLayersForGPUBypass();
1329     skip_prepare_ = false;
1330     DLOGI("SecureDisplay %s, Skip Prepare/Commit and Flush",
1331           secure_display_active_ ? "Starting" : "Stopping");
1332     flush_ = true;
1333   }
1334 
1335   for (auto hwc_layer : layer_set_) {
1336     Layer *layer = hwc_layer->GetSDMLayer();
1337     LayerComposition &composition = layer->composition;
1338 
1339     if ((composition == kCompositionSDE) || (composition == kCompositionHybrid) ||
1340         (composition == kCompositionBlit)) {
1341       layer_requests_[hwc_layer->GetId()] = HWC2::LayerRequest::ClearClientTarget;
1342     }
1343 
1344     HWC2::Composition requested_composition = hwc_layer->GetClientRequestedCompositionType();
1345     // Set SDM composition to HWC2 type in HWCLayer
1346     hwc_layer->SetComposition(composition);
1347     HWC2::Composition device_composition  = hwc_layer->GetDeviceSelectedCompositionType();
1348     if (device_composition == HWC2::Composition::Client) {
1349       has_client_composition_ = true;
1350     }
1351     // Update the changes list only if the requested composition is different from SDM comp type
1352     // TODO(user): Take Care of other comptypes(BLIT)
1353     if (requested_composition != device_composition) {
1354       layer_changes_[hwc_layer->GetId()] = device_composition;
1355     }
1356     hwc_layer->ResetValidation();
1357   }
1358 
1359   client_target_->ResetValidation();
1360   *out_num_types = UINT32(layer_changes_.size());
1361   *out_num_requests = UINT32(layer_requests_.size());
1362   validate_state_ = kNormalValidate;
1363   validated_ = true;
1364   layer_stack_invalid_ = false;
1365   return ((*out_num_types > 0) ? HWC2::Error::HasChanges : HWC2::Error::None);
1366 }
1367 
AcceptDisplayChanges()1368 HWC2::Error HWCDisplay::AcceptDisplayChanges() {
1369   if (layer_set_.empty()) {
1370     return HWC2::Error::None;
1371   }
1372 
1373   if (!validated_) {
1374     return HWC2::Error::NotValidated;
1375   }
1376 
1377   for (const auto& change : layer_changes_) {
1378     auto hwc_layer = layer_map_[change.first];
1379     auto composition = change.second;
1380     if (hwc_layer != nullptr) {
1381       hwc_layer->UpdateClientCompositionType(composition);
1382     } else {
1383       DLOGW("Invalid layer: %" PRIu64, change.first);
1384     }
1385   }
1386   return HWC2::Error::None;
1387 }
1388 
GetChangedCompositionTypes(uint32_t * out_num_elements,hwc2_layer_t * out_layers,int32_t * out_types)1389 HWC2::Error HWCDisplay::GetChangedCompositionTypes(uint32_t *out_num_elements,
1390                                                    hwc2_layer_t *out_layers, int32_t *out_types) {
1391   if (layer_set_.empty()) {
1392     return HWC2::Error::None;
1393   }
1394 
1395   if (!validated_) {
1396     DLOGW("Display is not validated");
1397     return HWC2::Error::NotValidated;
1398   }
1399 
1400   *out_num_elements = UINT32(layer_changes_.size());
1401   if (out_layers != nullptr && out_types != nullptr) {
1402     int i = 0;
1403     for (auto change : layer_changes_) {
1404       out_layers[i] = change.first;
1405       out_types[i] = INT32(change.second);
1406       i++;
1407     }
1408   }
1409   return HWC2::Error::None;
1410 }
1411 
GetReleaseFences(uint32_t * out_num_elements,hwc2_layer_t * out_layers,int32_t * out_fences)1412 HWC2::Error HWCDisplay::GetReleaseFences(uint32_t *out_num_elements, hwc2_layer_t *out_layers,
1413                                          int32_t *out_fences) {
1414   if (out_num_elements == nullptr) {
1415     return HWC2::Error::BadParameter;
1416   }
1417 
1418   if (out_layers != nullptr && out_fences != nullptr) {
1419     *out_num_elements = std::min(*out_num_elements, UINT32(layer_set_.size()));
1420     auto it = layer_set_.begin();
1421     for (uint32_t i = 0; i < *out_num_elements; i++, it++) {
1422       auto hwc_layer = *it;
1423       out_layers[i] = hwc_layer->GetId();
1424       out_fences[i] = hwc_layer->PopFrontReleaseFence();
1425     }
1426   } else {
1427     *out_num_elements = UINT32(layer_set_.size());
1428   }
1429 
1430   return HWC2::Error::None;
1431 }
1432 
GetDisplayRequests(int32_t * out_display_requests,uint32_t * out_num_elements,hwc2_layer_t * out_layers,int32_t * out_layer_requests)1433 HWC2::Error HWCDisplay::GetDisplayRequests(int32_t *out_display_requests,
1434                                            uint32_t *out_num_elements, hwc2_layer_t *out_layers,
1435                                            int32_t *out_layer_requests) {
1436   if (layer_set_.empty()) {
1437     return HWC2::Error::None;
1438   }
1439 
1440   if (out_display_requests == nullptr || out_num_elements == nullptr) {
1441     return HWC2::Error::BadParameter;
1442   }
1443 
1444   // No display requests for now
1445   // Use for sharing blit buffers and
1446   // writing wfd buffer directly to output if there is full GPU composition
1447   // and no color conversion needed
1448   if (!validated_) {
1449     DLOGW("Display is not validated");
1450     return HWC2::Error::NotValidated;
1451   }
1452 
1453   *out_display_requests = 0;
1454   if (out_layers != nullptr && out_layer_requests != nullptr) {
1455     *out_num_elements = std::min(*out_num_elements, UINT32(layer_requests_.size()));
1456     auto it = layer_requests_.begin();
1457     for (uint32_t i = 0; i < *out_num_elements; i++, it++) {
1458       out_layers[i] = it->first;
1459       out_layer_requests[i] = INT32(it->second);
1460     }
1461   } else {
1462     *out_num_elements = UINT32(layer_requests_.size());
1463   }
1464 
1465   auto client_target_layer = client_target_->GetSDMLayer();
1466   if (client_target_layer->request.flags.flip_buffer) {
1467     *out_display_requests = INT32(HWC2::DisplayRequest::FlipClientTarget);
1468   }
1469 
1470   return HWC2::Error::None;
1471 }
1472 
GetHdrCapabilities(uint32_t * out_num_types,int32_t * out_types,float * out_max_luminance,float * out_max_average_luminance,float * out_min_luminance)1473 HWC2::Error HWCDisplay::GetHdrCapabilities(uint32_t *out_num_types, int32_t *out_types,
1474                                            float *out_max_luminance,
1475                                            float *out_max_average_luminance,
1476                                            float *out_min_luminance) {
1477   if (out_num_types == nullptr || out_max_luminance == nullptr ||
1478       out_max_average_luminance == nullptr || out_min_luminance == nullptr) {
1479     return HWC2::Error::BadParameter;
1480   }
1481 
1482   DisplayConfigFixedInfo fixed_info = {};
1483   display_intf_->GetConfig(&fixed_info);
1484 
1485   if (!fixed_info.hdr_supported) {
1486     *out_num_types = 0;
1487     DLOGI("HDR is not supported");
1488     return HWC2::Error::None;
1489   }
1490 
1491   if (out_types == nullptr) {
1492     // We support HDR10 and HLG
1493     *out_num_types = 2;
1494   } else {
1495     // HDR10 and HLG are supported
1496     out_types[0] = HAL_HDR_HDR10;
1497     out_types[1] = HAL_HDR_HLG;
1498     static const float kLuminanceFactor = 10000.0;
1499     // luminance is expressed in the unit of 0.0001 cd/m2, convert it to 1cd/m2.
1500     *out_max_luminance = FLOAT(fixed_info.max_luminance)/kLuminanceFactor;
1501     *out_max_average_luminance = FLOAT(fixed_info.average_luminance)/kLuminanceFactor;
1502     *out_min_luminance = FLOAT(fixed_info.min_luminance)/kLuminanceFactor;
1503   }
1504 
1505   return HWC2::Error::None;
1506 }
1507 
1508 
CommitLayerStack(void)1509 HWC2::Error HWCDisplay::CommitLayerStack(void) {
1510   if (!validated_) {
1511     DLOGV_IF(kTagClient, "Display %d is not validated", id_);
1512     return HWC2::Error::NotValidated;
1513   }
1514 
1515   if (shutdown_pending_ || layer_set_.empty()) {
1516     return HWC2::Error::None;
1517   }
1518 
1519   DumpInputBuffers();
1520 
1521   if (!flush_) {
1522     DisplayError error = kErrorUndefined;
1523     int status = 0;
1524     if (tone_mapper_) {
1525       if (layer_stack_.flags.hdr_present) {
1526         status = tone_mapper_->HandleToneMap(&layer_stack_);
1527         if (status != 0) {
1528           DLOGE("Error handling HDR in ToneMapper");
1529         }
1530       } else {
1531         tone_mapper_->Terminate();
1532       }
1533     }
1534     error = display_intf_->Commit(&layer_stack_);
1535 
1536     if (error == kErrorNone) {
1537       // A commit is successfully submitted, start flushing on failure now onwards.
1538       flush_on_error_ = true;
1539     } else {
1540       if (error == kErrorShutDown) {
1541         shutdown_pending_ = true;
1542         return HWC2::Error::Unsupported;
1543       } else if (error == kErrorNotValidated) {
1544         validated_ = false;
1545         return HWC2::Error::NotValidated;
1546       } else if (error != kErrorPermission) {
1547         DLOGE("Commit failed. Error = %d", error);
1548         // To prevent surfaceflinger infinite wait, flush the previous frame during Commit()
1549         // so that previous buffer and fences are released, and override the error.
1550         flush_ = true;
1551       }
1552     }
1553   }
1554 
1555   validate_state_ = kSkipValidate;
1556   return HWC2::Error::None;
1557 }
1558 
PostCommitLayerStack(int32_t * out_retire_fence)1559 HWC2::Error HWCDisplay::PostCommitLayerStack(int32_t *out_retire_fence) {
1560   auto status = HWC2::Error::None;
1561 
1562   // Do no call flush on errors, if a successful buffer is never submitted.
1563   if (flush_ && flush_on_error_) {
1564     display_intf_->Flush();
1565     validated_ = false;
1566   }
1567 
1568   if (tone_mapper_ && tone_mapper_->IsActive()) {
1569      tone_mapper_->PostCommit(&layer_stack_);
1570   }
1571 
1572   // TODO(user): No way to set the client target release fence on SF
1573   int32_t &client_target_release_fence =
1574       client_target_->GetSDMLayer()->input_buffer.release_fence_fd;
1575   if (client_target_release_fence >= 0) {
1576     close(client_target_release_fence);
1577     client_target_release_fence = -1;
1578   }
1579   client_target_->ResetGeometryChanges();
1580 
1581   for (auto hwc_layer : layer_set_) {
1582     hwc_layer->ResetGeometryChanges();
1583     Layer *layer = hwc_layer->GetSDMLayer();
1584     LayerBuffer *layer_buffer = &layer->input_buffer;
1585 
1586     if (!flush_) {
1587       // If swapinterval property is set to 0 or for single buffer layers, do not update f/w
1588       // release fences and discard fences from driver
1589       if (swap_interval_zero_ || layer->flags.single_buffer) {
1590         close(layer_buffer->release_fence_fd);
1591       } else if (layer->composition != kCompositionGPU) {
1592         hwc_layer->PushBackReleaseFence(layer_buffer->release_fence_fd);
1593       } else {
1594         hwc_layer->PushBackReleaseFence(-1);
1595       }
1596     } else {
1597       // In case of flush, we don't return an error to f/w, so it will get a release fence out of
1598       // the hwc_layer's release fence queue. We should push a -1 to preserve release fence
1599       // circulation semantics.
1600       hwc_layer->PushBackReleaseFence(-1);
1601     }
1602 
1603     layer_buffer->release_fence_fd = -1;
1604     if (layer_buffer->acquire_fence_fd >= 0) {
1605       close(layer_buffer->acquire_fence_fd);
1606       layer_buffer->acquire_fence_fd = -1;
1607     }
1608 
1609     layer->request.flags = {};
1610   }
1611 
1612   client_target_->GetSDMLayer()->request.flags = {};
1613   *out_retire_fence = -1;
1614   if (!flush_) {
1615     // if swapinterval property is set to 0 then close and reset the list retire fence
1616     if (swap_interval_zero_) {
1617       close(layer_stack_.retire_fence_fd);
1618       layer_stack_.retire_fence_fd = -1;
1619     }
1620     *out_retire_fence = layer_stack_.retire_fence_fd;
1621     layer_stack_.retire_fence_fd = -1;
1622 
1623     if (dump_frame_count_) {
1624       dump_frame_count_--;
1625       dump_frame_index_++;
1626     }
1627   }
1628   config_pending_ = false;
1629 
1630   geometry_changes_ = GeometryChanges::kNone;
1631   flush_ = false;
1632 
1633   return status;
1634 }
1635 
SetIdleTimeoutMs(uint32_t timeout_ms)1636 void HWCDisplay::SetIdleTimeoutMs(uint32_t timeout_ms) {
1637   return;
1638 }
1639 
SetMaxMixerStages(uint32_t max_mixer_stages)1640 DisplayError HWCDisplay::SetMaxMixerStages(uint32_t max_mixer_stages) {
1641   DisplayError error = kErrorNone;
1642 
1643   if (display_intf_) {
1644     error = display_intf_->SetMaxMixerStages(max_mixer_stages);
1645     validated_ = false;
1646   }
1647 
1648   return error;
1649 }
1650 
GetSDMFormat(const int32_t & source,const int flags)1651 LayerBufferFormat HWCDisplay::GetSDMFormat(const int32_t &source, const int flags) {
1652   LayerBufferFormat format = kFormatInvalid;
1653   if (flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
1654     switch (source) {
1655       case HAL_PIXEL_FORMAT_RGBA_8888:
1656         format = kFormatRGBA8888Ubwc;
1657         break;
1658       case HAL_PIXEL_FORMAT_RGBX_8888:
1659         format = kFormatRGBX8888Ubwc;
1660         break;
1661       case HAL_PIXEL_FORMAT_BGR_565:
1662         format = kFormatBGR565Ubwc;
1663         break;
1664       case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
1665       case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
1666       case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
1667         format = kFormatYCbCr420SPVenusUbwc;
1668         break;
1669       case HAL_PIXEL_FORMAT_RGBA_1010102:
1670         format = kFormatRGBA1010102Ubwc;
1671         break;
1672       case HAL_PIXEL_FORMAT_RGBX_1010102:
1673         format = kFormatRGBX1010102Ubwc;
1674         break;
1675       case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
1676         format = kFormatYCbCr420TP10Ubwc;
1677         break;
1678       case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
1679         format = kFormatYCbCr420P010Ubwc;
1680         break;
1681       default:
1682         DLOGE("Unsupported format type for UBWC %d", source);
1683         return kFormatInvalid;
1684     }
1685     return format;
1686   }
1687 
1688   switch (source) {
1689     case HAL_PIXEL_FORMAT_RGBA_8888:
1690       format = kFormatRGBA8888;
1691       break;
1692     case HAL_PIXEL_FORMAT_RGBA_5551:
1693       format = kFormatRGBA5551;
1694       break;
1695     case HAL_PIXEL_FORMAT_RGBA_4444:
1696       format = kFormatRGBA4444;
1697       break;
1698     case HAL_PIXEL_FORMAT_BGRA_8888:
1699       format = kFormatBGRA8888;
1700       break;
1701     case HAL_PIXEL_FORMAT_RGBX_8888:
1702       format = kFormatRGBX8888;
1703       break;
1704     case HAL_PIXEL_FORMAT_BGRX_8888:
1705       format = kFormatBGRX8888;
1706       break;
1707     case HAL_PIXEL_FORMAT_RGB_888:
1708       format = kFormatRGB888;
1709       break;
1710     case HAL_PIXEL_FORMAT_RGB_565:
1711       format = kFormatRGB565;
1712       break;
1713     case HAL_PIXEL_FORMAT_BGR_565:
1714       format = kFormatBGR565;
1715       break;
1716     case HAL_PIXEL_FORMAT_BGR_888:
1717       format = kFormatBGR888;
1718       break;
1719     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
1720     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
1721       format = kFormatYCbCr420SemiPlanarVenus;
1722       break;
1723     case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
1724       format = kFormatYCrCb420SemiPlanarVenus;
1725       break;
1726     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
1727       format = kFormatYCbCr420SPVenusUbwc;
1728       break;
1729     case HAL_PIXEL_FORMAT_YV12:
1730       format = kFormatYCrCb420PlanarStride16;
1731       break;
1732     case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1733       format = kFormatYCrCb420SemiPlanar;
1734       break;
1735     case HAL_PIXEL_FORMAT_YCbCr_420_SP:
1736       format = kFormatYCbCr420SemiPlanar;
1737       break;
1738     case HAL_PIXEL_FORMAT_YCbCr_422_SP:
1739       format = kFormatYCbCr422H2V1SemiPlanar;
1740       break;
1741     case HAL_PIXEL_FORMAT_YCbCr_422_I:
1742       format = kFormatYCbCr422H2V1Packed;
1743       break;
1744     case HAL_PIXEL_FORMAT_CbYCrY_422_I:
1745       format = kFormatCbYCrY422H2V1Packed;
1746       break;
1747     case HAL_PIXEL_FORMAT_RGBA_1010102:
1748       format = kFormatRGBA1010102;
1749       break;
1750     case HAL_PIXEL_FORMAT_ARGB_2101010:
1751       format = kFormatARGB2101010;
1752       break;
1753     case HAL_PIXEL_FORMAT_RGBX_1010102:
1754       format = kFormatRGBX1010102;
1755       break;
1756     case HAL_PIXEL_FORMAT_XRGB_2101010:
1757       format = kFormatXRGB2101010;
1758       break;
1759     case HAL_PIXEL_FORMAT_BGRA_1010102:
1760       format = kFormatBGRA1010102;
1761       break;
1762     case HAL_PIXEL_FORMAT_ABGR_2101010:
1763       format = kFormatABGR2101010;
1764       break;
1765     case HAL_PIXEL_FORMAT_BGRX_1010102:
1766       format = kFormatBGRX1010102;
1767       break;
1768     case HAL_PIXEL_FORMAT_XBGR_2101010:
1769       format = kFormatXBGR2101010;
1770       break;
1771     case HAL_PIXEL_FORMAT_YCbCr_420_P010:
1772       format = kFormatYCbCr420P010;
1773       break;
1774     case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
1775       format = kFormatYCbCr420TP10Ubwc;
1776       break;
1777     case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
1778       format = kFormatYCbCr420P010Ubwc;
1779       break;
1780     case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
1781       format = kFormatYCbCr420P010Venus;
1782       break;
1783     default:
1784       DLOGW("Unsupported format type = %d", source);
1785       return kFormatInvalid;
1786   }
1787 
1788   return format;
1789 }
1790 
DumpInputBuffers()1791 void HWCDisplay::DumpInputBuffers() {
1792   char dir_path[PATH_MAX];
1793   int  status;
1794 
1795   if (!dump_frame_count_ || flush_ || !dump_input_layers_) {
1796     return;
1797   }
1798 
1799   DLOGI("dump_frame_count %d dump_input_layers %d", dump_frame_count_, dump_input_layers_);
1800   snprintf(dir_path, sizeof(dir_path), "%s/frame_dump_%s", HWCDebugHandler::DumpDir(),
1801            GetDisplayString());
1802 
1803   status = mkdir(dir_path, 777);
1804   if ((status != 0) && errno != EEXIST) {
1805     DLOGW("Failed to create %s directory errno = %d, desc = %s", dir_path, errno, strerror(errno));
1806     return;
1807   }
1808 
1809   // Even if directory exists already, need to explicitly change the permission.
1810   if (chmod(dir_path, 0777) != 0) {
1811     DLOGW("Failed to change permissions on %s directory", dir_path);
1812     return;
1813   }
1814 
1815   for (uint32_t i = 0; i < layer_stack_.layers.size(); i++) {
1816     auto layer = layer_stack_.layers.at(i);
1817     const private_handle_t *pvt_handle =
1818         reinterpret_cast<const private_handle_t *>(layer->input_buffer.buffer_id);
1819     auto acquire_fence_fd = layer->input_buffer.acquire_fence_fd;
1820 
1821     if (acquire_fence_fd >= 0) {
1822       int error = sync_wait(acquire_fence_fd, 1000);
1823       if (error < 0) {
1824         DLOGW("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
1825         return;
1826       }
1827     }
1828 
1829     DLOGI("Dump layer[%d] of %d pvt_handle %x pvt_handle->base %x", i, layer_stack_.layers.size(),
1830           pvt_handle, pvt_handle? pvt_handle->base : 0);
1831 
1832     if (!pvt_handle) {
1833       DLOGE("Buffer handle is null");
1834       return;
1835     }
1836 
1837     if (!pvt_handle->base) {
1838       DisplayError error = buffer_allocator_->MapBuffer(pvt_handle, -1);
1839       if (error != kErrorNone) {
1840         DLOGE("Failed to map buffer, error = %d", error);
1841         return;
1842       }
1843     }
1844 
1845     char dump_file_name[PATH_MAX];
1846     size_t result = 0;
1847 
1848     snprintf(dump_file_name, sizeof(dump_file_name), "%s/input_layer%d_%dx%d_%s_frame%d.raw",
1849              dir_path, i, pvt_handle->width, pvt_handle->height,
1850              qdutils::GetHALPixelFormatString(pvt_handle->format), dump_frame_index_);
1851 
1852     FILE *fp = fopen(dump_file_name, "w+");
1853     if (fp) {
1854       result = fwrite(reinterpret_cast<void *>(pvt_handle->base), pvt_handle->size, 1, fp);
1855       fclose(fp);
1856     }
1857 
1858     int release_fence = -1;
1859     DisplayError error = buffer_allocator_->UnmapBuffer(pvt_handle, &release_fence);
1860     if (error != kErrorNone) {
1861       DLOGE("Failed to unmap buffer, error = %d", error);
1862       return;
1863     }
1864 
1865     DLOGI("Frame Dump %s: is %s", dump_file_name, result ? "Successful" : "Failed");
1866   }
1867 }
1868 
DumpOutputBuffer(const BufferInfo & buffer_info,void * base,int fence)1869 void HWCDisplay::DumpOutputBuffer(const BufferInfo &buffer_info, void *base, int fence) {
1870   char dir_path[PATH_MAX];
1871   int  status;
1872 
1873   snprintf(dir_path, sizeof(dir_path), "%s/frame_dump_%s", HWCDebugHandler::DumpDir(),
1874            GetDisplayString());
1875 
1876   status = mkdir(dir_path, 777);
1877   if ((status != 0) && errno != EEXIST) {
1878     DLOGW("Failed to create %s directory errno = %d, desc = %s", dir_path, errno, strerror(errno));
1879     return;
1880   }
1881 
1882   // Even if directory exists already, need to explicitly change the permission.
1883   if (chmod(dir_path, 0777) != 0) {
1884     DLOGW("Failed to change permissions on %s directory", dir_path);
1885     return;
1886   }
1887 
1888   if (base) {
1889     char dump_file_name[PATH_MAX];
1890     size_t result = 0;
1891 
1892     if (fence >= 0) {
1893       int error = sync_wait(fence, 1000);
1894       if (error < 0) {
1895         DLOGW("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
1896         return;
1897       }
1898     }
1899 
1900     snprintf(dump_file_name, sizeof(dump_file_name), "%s/output_layer_%dx%d_%s_frame%d.raw",
1901              dir_path, buffer_info.alloc_buffer_info.aligned_width,
1902              buffer_info.alloc_buffer_info.aligned_height,
1903              GetFormatString(buffer_info.buffer_config.format), dump_frame_index_);
1904 
1905     FILE *fp = fopen(dump_file_name, "w+");
1906     if (fp) {
1907       result = fwrite(base, buffer_info.alloc_buffer_info.size, 1, fp);
1908       fclose(fp);
1909     }
1910 
1911     DLOGI("Frame Dump of %s is %s", dump_file_name, result ? "Successful" : "Failed");
1912   }
1913 }
1914 
GetDisplayString()1915 const char *HWCDisplay::GetDisplayString() {
1916   switch (type_) {
1917     case kPrimary:
1918       return "primary";
1919     case kHDMI:
1920       return "hdmi";
1921     case kVirtual:
1922       return "virtual";
1923     default:
1924       return "invalid";
1925   }
1926 }
1927 
SetFrameBufferResolution(uint32_t x_pixels,uint32_t y_pixels)1928 int HWCDisplay::SetFrameBufferResolution(uint32_t x_pixels, uint32_t y_pixels) {
1929   if (x_pixels <= 0 || y_pixels <= 0) {
1930     DLOGW("Unsupported config: x_pixels=%d, y_pixels=%d", x_pixels, y_pixels);
1931     return -EINVAL;
1932   }
1933 
1934   DisplayConfigVariableInfo fb_config;
1935   DisplayError error = display_intf_->GetFrameBufferConfig(&fb_config);
1936   if (error != kErrorNone) {
1937     DLOGV("Get frame buffer config failed. Error = %d", error);
1938     return -EINVAL;
1939   }
1940 
1941   fb_config.x_pixels = x_pixels;
1942   fb_config.y_pixels = y_pixels;
1943 
1944   error = display_intf_->SetFrameBufferConfig(fb_config);
1945   if (error != kErrorNone) {
1946     DLOGV("Set frame buffer config failed. Error = %d", error);
1947     return -EINVAL;
1948   }
1949 
1950   // Create rects to represent the new source and destination crops
1951   LayerRect crop = LayerRect(0, 0, FLOAT(x_pixels), FLOAT(y_pixels));
1952   hwc_rect_t scaled_display_frame = {0, 0, INT(x_pixels), INT(y_pixels)};
1953   ApplyScanAdjustment(&scaled_display_frame);
1954   client_target_->SetLayerDisplayFrame(scaled_display_frame);
1955   client_target_->ResetPerFrameData();
1956 
1957   auto client_target_layer = client_target_->GetSDMLayer();
1958   client_target_layer->src_rect = crop;
1959 
1960   int aligned_width;
1961   int aligned_height;
1962   uint32_t usage = GRALLOC_USAGE_HW_FB;
1963   int format = HAL_PIXEL_FORMAT_RGBA_8888;
1964   int ubwc_disabled = 0;
1965   int flags = 0;
1966 
1967   // By default UBWC is enabled and below property is global enable/disable for all
1968   // buffers allocated through gralloc , including framebuffer targets.
1969   HWCDebugHandler::Get()->GetProperty(DISABLE_UBWC_PROP, &ubwc_disabled);
1970   if (!ubwc_disabled) {
1971     usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
1972     flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
1973   }
1974 
1975   buffer_allocator_->GetAlignedWidthAndHeight(INT(x_pixels), INT(y_pixels), format, usage,
1976                                               &aligned_width, &aligned_height);
1977 
1978   // TODO(user): How does the dirty region get set on the client target? File bug on Google
1979   client_target_layer->composition = kCompositionGPUTarget;
1980   client_target_layer->input_buffer.format = GetSDMFormat(format, flags);
1981   client_target_layer->input_buffer.width = UINT32(aligned_width);
1982   client_target_layer->input_buffer.height = UINT32(aligned_height);
1983   client_target_layer->input_buffer.unaligned_width = x_pixels;
1984   client_target_layer->input_buffer.unaligned_height = y_pixels;
1985   client_target_layer->plane_alpha = 255;
1986 
1987   DLOGI("New framebuffer resolution (%dx%d)", fb_config.x_pixels, fb_config.y_pixels);
1988 
1989   return 0;
1990 }
1991 
GetFrameBufferResolution(uint32_t * x_pixels,uint32_t * y_pixels)1992 void HWCDisplay::GetFrameBufferResolution(uint32_t *x_pixels, uint32_t *y_pixels) {
1993   DisplayConfigVariableInfo fb_config;
1994   display_intf_->GetFrameBufferConfig(&fb_config);
1995 
1996   *x_pixels = fb_config.x_pixels;
1997   *y_pixels = fb_config.y_pixels;
1998 }
1999 
GetMixerResolution(uint32_t * x_pixels,uint32_t * y_pixels)2000 DisplayError HWCDisplay::GetMixerResolution(uint32_t *x_pixels, uint32_t *y_pixels) {
2001   return display_intf_->GetMixerResolution(x_pixels, y_pixels);
2002 }
2003 
GetPanelResolution(uint32_t * x_pixels,uint32_t * y_pixels)2004 void HWCDisplay::GetPanelResolution(uint32_t *x_pixels, uint32_t *y_pixels) {
2005   DisplayConfigVariableInfo display_config;
2006   uint32_t active_index = 0;
2007 
2008   display_intf_->GetActiveConfig(&active_index);
2009   display_intf_->GetConfig(active_index, &display_config);
2010 
2011   *x_pixels = display_config.x_pixels;
2012   *y_pixels = display_config.y_pixels;
2013 }
2014 
SetDisplayStatus(DisplayStatus display_status)2015 int HWCDisplay::SetDisplayStatus(DisplayStatus display_status) {
2016   int status = 0;
2017 
2018   switch (display_status) {
2019     case kDisplayStatusResume:
2020       display_paused_ = false;
2021       status = INT32(SetPowerMode(HWC2::PowerMode::On));
2022       break;
2023     case kDisplayStatusOnline:
2024       status = INT32(SetPowerMode(HWC2::PowerMode::On));
2025       break;
2026     case kDisplayStatusPause:
2027       display_paused_ = true;
2028       status = INT32(SetPowerMode(HWC2::PowerMode::Off));
2029       break;
2030     case kDisplayStatusOffline:
2031       status = INT32(SetPowerMode(HWC2::PowerMode::Off));
2032       break;
2033     default:
2034       DLOGW("Invalid display status %d", display_status);
2035       return -EINVAL;
2036   }
2037 
2038   if (display_status == kDisplayStatusResume || display_status == kDisplayStatusPause) {
2039     callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
2040     validated_ = false;
2041   }
2042 
2043   return status;
2044 }
2045 
SetCursorPosition(hwc2_layer_t layer,int x,int y)2046 HWC2::Error HWCDisplay::SetCursorPosition(hwc2_layer_t layer, int x, int y) {
2047   if (shutdown_pending_) {
2048     return HWC2::Error::None;
2049   }
2050 
2051   HWCLayer *hwc_layer = GetHWCLayer(layer);
2052   if (hwc_layer == nullptr) {
2053     return HWC2::Error::BadLayer;
2054   }
2055   if (hwc_layer->GetDeviceSelectedCompositionType() != HWC2::Composition::Cursor) {
2056     return HWC2::Error::None;
2057   }
2058   if ((validate_state_ != kSkipValidate) && validated_) {
2059     // the device is currently in the middle of the validate/present sequence,
2060     // cannot set the Position(as per HWC2 spec)
2061     return HWC2::Error::NotValidated;
2062   }
2063 
2064   DisplayState state;
2065   if (display_intf_->GetDisplayState(&state) == kErrorNone) {
2066     if (state != kStateOn) {
2067       return HWC2::Error::None;
2068     }
2069   }
2070 
2071   // TODO(user): HWC1.5 was not letting SetCursorPosition before validateDisplay,
2072   // but HWC2.0 doesn't let setting cursor position after validate before present.
2073   // Need to revisit.
2074 
2075   auto error = display_intf_->SetCursorPosition(x, y);
2076   if (error != kErrorNone) {
2077     if (error == kErrorShutDown) {
2078       shutdown_pending_ = true;
2079       return HWC2::Error::None;
2080     }
2081 
2082     DLOGE("Failed for x = %d y = %d, Error = %d", x, y, error);
2083     return HWC2::Error::BadDisplay;
2084   }
2085 
2086   return HWC2::Error::None;
2087 }
2088 
OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level)2089 int HWCDisplay::OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level) {
2090   DisplayError error = display_intf_->OnMinHdcpEncryptionLevelChange(min_enc_level);
2091   if (error != kErrorNone) {
2092     DLOGE("Failed. Error = %d", error);
2093     return -1;
2094   }
2095 
2096   validated_ = false;
2097   return 0;
2098 }
2099 
MarkLayersForGPUBypass()2100 void HWCDisplay::MarkLayersForGPUBypass() {
2101   for (auto hwc_layer : layer_set_) {
2102     auto layer = hwc_layer->GetSDMLayer();
2103     layer->composition = kCompositionSDE;
2104   }
2105   validated_ = true;
2106 }
2107 
MarkLayersForClientComposition()2108 void HWCDisplay::MarkLayersForClientComposition() {
2109   // ClientComposition - GPU comp, to acheive this, set skip flag so that
2110   // SDM does not handle this layer and hwc_layer composition will be
2111   // set correctly at the end of Prepare.
2112   DLOGV_IF(kTagClient, "HWC Layers marked for GPU comp");
2113   for (auto hwc_layer : layer_set_) {
2114     Layer *layer = hwc_layer->GetSDMLayer();
2115     layer->flags.skip = true;
2116   }
2117   layer_stack_.flags.skip_present = true;
2118 }
2119 
ApplyScanAdjustment(hwc_rect_t * display_frame)2120 void HWCDisplay::ApplyScanAdjustment(hwc_rect_t *display_frame) {
2121 }
2122 
SetPanelBrightness(int level)2123 int HWCDisplay::SetPanelBrightness(int level) {
2124   int ret = 0;
2125   if (display_intf_) {
2126     ret = display_intf_->SetPanelBrightness(level);
2127     validated_ = false;
2128   } else {
2129     ret = -EINVAL;
2130   }
2131 
2132   return ret;
2133 }
2134 
GetPanelBrightness(int * level)2135 int HWCDisplay::GetPanelBrightness(int *level) {
2136   return display_intf_->GetPanelBrightness(level);
2137 }
2138 
ToggleScreenUpdates(bool enable)2139 int HWCDisplay::ToggleScreenUpdates(bool enable) {
2140   display_paused_ = enable ? false : true;
2141   callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
2142   validated_ = false;
2143   return 0;
2144 }
2145 
ColorSVCRequestRoute(const PPDisplayAPIPayload & in_payload,PPDisplayAPIPayload * out_payload,PPPendingParams * pending_action)2146 int HWCDisplay::ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload,
2147                                      PPDisplayAPIPayload *out_payload,
2148                                      PPPendingParams *pending_action) {
2149   int ret = 0;
2150 
2151   if (display_intf_)
2152     ret = display_intf_->ColorSVCRequestRoute(in_payload, out_payload, pending_action);
2153   else
2154     ret = -EINVAL;
2155 
2156   return ret;
2157 }
2158 
SolidFillPrepare()2159 void HWCDisplay::SolidFillPrepare() {
2160   if (solid_fill_enable_) {
2161     if (solid_fill_layer_ == NULL) {
2162       // Create a dummy layer here
2163       solid_fill_layer_ = new Layer();
2164     }
2165     uint32_t primary_width = 0, primary_height = 0;
2166     GetMixerResolution(&primary_width, &primary_height);
2167 
2168     LayerBuffer *layer_buffer = &solid_fill_layer_->input_buffer;
2169     layer_buffer->width = primary_width;
2170     layer_buffer->height = primary_height;
2171     layer_buffer->unaligned_width = primary_width;
2172     layer_buffer->unaligned_height = primary_height;
2173     layer_buffer->acquire_fence_fd = -1;
2174     layer_buffer->release_fence_fd = -1;
2175 
2176     solid_fill_layer_->composition = kCompositionGPU;
2177     solid_fill_layer_->src_rect = solid_fill_rect_;
2178     solid_fill_layer_->dst_rect = solid_fill_rect_;
2179 
2180     solid_fill_layer_->blending = kBlendingPremultiplied;
2181     solid_fill_layer_->solid_fill_color = 0;
2182     solid_fill_layer_->solid_fill_info.bit_depth = solid_fill_color_.bit_depth;
2183     solid_fill_layer_->solid_fill_info.red = solid_fill_color_.red;
2184     solid_fill_layer_->solid_fill_info.blue = solid_fill_color_.blue;
2185     solid_fill_layer_->solid_fill_info.green = solid_fill_color_.green;
2186     solid_fill_layer_->solid_fill_info.alpha = solid_fill_color_.alpha;
2187     solid_fill_layer_->frame_rate = 60;
2188     solid_fill_layer_->visible_regions.push_back(solid_fill_layer_->dst_rect);
2189     solid_fill_layer_->flags.updating = 1;
2190     solid_fill_layer_->flags.solid_fill = true;
2191   } else {
2192     // delete the dummy layer
2193     delete solid_fill_layer_;
2194     solid_fill_layer_ = NULL;
2195   }
2196 
2197   if (solid_fill_enable_ && solid_fill_layer_) {
2198     BuildSolidFillStack();
2199     MarkLayersForGPUBypass();
2200   }
2201 
2202   return;
2203 }
2204 
SolidFillCommit()2205 void HWCDisplay::SolidFillCommit() {
2206   if (solid_fill_enable_ && solid_fill_layer_) {
2207     LayerBuffer *layer_buffer = &solid_fill_layer_->input_buffer;
2208     if (layer_buffer->release_fence_fd > 0) {
2209       close(layer_buffer->release_fence_fd);
2210       layer_buffer->release_fence_fd = -1;
2211     }
2212     if (layer_stack_.retire_fence_fd > 0) {
2213       close(layer_stack_.retire_fence_fd);
2214       layer_stack_.retire_fence_fd = -1;
2215     }
2216   }
2217 }
2218 
GetVisibleDisplayRect(hwc_rect_t * visible_rect)2219 int HWCDisplay::GetVisibleDisplayRect(hwc_rect_t *visible_rect) {
2220   if (!IsValid(display_rect_)) {
2221     return -EINVAL;
2222   }
2223 
2224   visible_rect->left = INT(display_rect_.left);
2225   visible_rect->top = INT(display_rect_.top);
2226   visible_rect->right = INT(display_rect_.right);
2227   visible_rect->bottom = INT(display_rect_.bottom);
2228   DLOGI("Dpy = %d Visible Display Rect(%d %d %d %d)", visible_rect->left, visible_rect->top,
2229         visible_rect->right, visible_rect->bottom);
2230 
2231   return 0;
2232 }
2233 
SetSecureDisplay(bool secure_display_active)2234 void HWCDisplay::SetSecureDisplay(bool secure_display_active) {
2235   if (secure_display_active_ != secure_display_active) {
2236     DLOGI("SecureDisplay state changed from %d to %d Needs Flush!!", secure_display_active_,
2237           secure_display_active);
2238     secure_display_active_ = secure_display_active;
2239     skip_prepare_ = true;
2240   }
2241   return;
2242 }
2243 
SetActiveDisplayConfig(uint32_t config)2244 int HWCDisplay::SetActiveDisplayConfig(uint32_t config) {
2245   if (display_config_ == config) {
2246     return 0;
2247   }
2248   display_config_ = config;
2249   config_pending_ = true;
2250   validated_ = false;
2251 
2252   callbacks_->Refresh(id_);
2253 
2254   return 0;
2255 }
2256 
GetActiveDisplayConfig(uint32_t * config)2257 int HWCDisplay::GetActiveDisplayConfig(uint32_t *config) {
2258   if (config_pending_) {
2259     *config = display_config_;
2260     return 0;
2261   }
2262   return display_intf_->GetActiveConfig(config) == kErrorNone ? 0 : -1;
2263 }
2264 
GetDisplayConfigCount(uint32_t * count)2265 int HWCDisplay::GetDisplayConfigCount(uint32_t *count) {
2266   return display_intf_->GetNumVariableInfoConfigs(count) == kErrorNone ? 0 : -1;
2267 }
2268 
GetDisplayAttributesForConfig(int config,DisplayConfigVariableInfo * display_attributes)2269 int HWCDisplay::GetDisplayAttributesForConfig(int config,
2270                                             DisplayConfigVariableInfo *display_attributes) {
2271   return display_intf_->GetConfig(UINT32(config), display_attributes) == kErrorNone ? 0 : -1;
2272 }
2273 
GetUpdatingLayersCount(void)2274 uint32_t HWCDisplay::GetUpdatingLayersCount(void) {
2275   uint32_t updating_count = 0;
2276 
2277   for (uint i = 0; i < layer_stack_.layers.size(); i++) {
2278     auto layer = layer_stack_.layers.at(i);
2279     if (layer->flags.updating) {
2280       updating_count++;
2281     }
2282   }
2283 
2284   return updating_count;
2285 }
2286 
IsLayerUpdating(HWCLayer * hwc_layer)2287 bool HWCDisplay::IsLayerUpdating(HWCLayer *hwc_layer) {
2288   auto layer = hwc_layer->GetSDMLayer();
2289   // Layer should be considered updating if
2290   //   a) layer is in single buffer mode, or
2291   //   b) valid dirty_regions(android specific hint for updating status), or
2292   //   c) layer stack geometry has changed (TODO(user): Remove when SDM accepts
2293   //      geometry_changed as bit fields).
2294   return (layer->flags.single_buffer || hwc_layer->IsSurfaceUpdated() ||
2295           geometry_changes_);
2296 }
2297 
SanitizeRefreshRate(uint32_t req_refresh_rate)2298 uint32_t HWCDisplay::SanitizeRefreshRate(uint32_t req_refresh_rate) {
2299   uint32_t refresh_rate = req_refresh_rate;
2300 
2301   if (refresh_rate < min_refresh_rate_) {
2302     // Pick the next multiple of request which is within the range
2303     refresh_rate =
2304         (((min_refresh_rate_ / refresh_rate) + ((min_refresh_rate_ % refresh_rate) ? 1 : 0)) *
2305          refresh_rate);
2306   }
2307 
2308   if (refresh_rate > max_refresh_rate_) {
2309     refresh_rate = max_refresh_rate_;
2310   }
2311 
2312   return refresh_rate;
2313 }
2314 
GetDisplayClass()2315 DisplayClass HWCDisplay::GetDisplayClass() {
2316   return display_class_;
2317 }
2318 
Dump()2319 std::string HWCDisplay::Dump() {
2320   std::ostringstream os;
2321   os << "\n------------HWC----------------\n";
2322   os << "HWC2 display_id: " << id_ << std::endl;
2323   for (auto layer : layer_set_) {
2324     auto sdm_layer = layer->GetSDMLayer();
2325     auto transform = sdm_layer->transform;
2326     os << "layer: " << std::setw(4) << layer->GetId();
2327     os << " z: " << layer->GetZ();
2328     os << " composition: " <<
2329           to_string(layer->GetClientRequestedCompositionType()).c_str();
2330     os << "/" <<
2331           to_string(layer->GetDeviceSelectedCompositionType()).c_str();
2332     os << " alpha: " << std::to_string(sdm_layer->plane_alpha).c_str();
2333     os << " format: " << std::setw(22) << GetFormatString(sdm_layer->input_buffer.format);
2334     os << " dataspace:" << std::hex << "0x" << std::setw(8) << std::setfill('0')
2335        << layer->GetLayerDataspace() << std::dec << std::setfill(' ');
2336     os << " transform: " << transform.rotation << "/" << transform.flip_horizontal <<
2337           "/"<< transform.flip_vertical;
2338     os << " buffer_id: " << std::hex << "0x" << sdm_layer->input_buffer.buffer_id << std::dec
2339        << std::endl;
2340   }
2341 
2342   if (layer_stack_invalid_) {
2343     os << "\n Layers added or removed but not reflected to SDM's layer stack yet\n";
2344     return os.str();
2345   }
2346 
2347   if (color_mode_) {
2348     os << "\n----------Color Modes---------\n";
2349     color_mode_->Dump(&os);
2350   }
2351 
2352   if (display_intf_) {
2353     os << "\n------------SDM----------------\n";
2354     os << display_intf_->Dump();
2355   }
2356 
2357   os << "\n";
2358 
2359   return os.str();
2360 }
2361 
CanSkipValidate()2362 bool HWCDisplay::CanSkipValidate() {
2363   if (!validated_ || solid_fill_enable_) {
2364     return false;
2365   }
2366 
2367   // Layer Stack checks
2368   if ((layer_stack_.flags.hdr_present && (tone_mapper_ && tone_mapper_->IsActive())) ||
2369      layer_stack_.flags.single_buffered_layer_present) {
2370     DLOGV_IF(kTagClient, "HDR content present with tone mapping enabled. Returning false.");
2371     return false;
2372   }
2373 
2374   if (client_target_->NeedsValidation()) {
2375     DLOGV_IF(kTagClient, "Framebuffer target needs validation. Returning false.");
2376     return false;
2377   }
2378 
2379   for (auto hwc_layer : layer_set_) {
2380     if (hwc_layer->NeedsValidation()) {
2381       DLOGV_IF(kTagClient, "hwc_layer[%d] needs validation. Returning false.",
2382                hwc_layer->GetId());
2383       return false;
2384     }
2385 
2386     // Do not allow Skip Validate, if any layer needs GPU Composition.
2387     if (hwc_layer->GetDeviceSelectedCompositionType() == HWC2::Composition::Client) {
2388       DLOGV_IF(kTagClient, "hwc_layer[%d] is GPU composed. Returning false.",
2389                hwc_layer->GetId());
2390       return false;
2391     }
2392   }
2393 
2394   return true;
2395 }
2396 
GetValidateDisplayOutput(uint32_t * out_num_types,uint32_t * out_num_requests)2397 HWC2::Error HWCDisplay::GetValidateDisplayOutput(uint32_t *out_num_types,
2398                                                  uint32_t *out_num_requests) {
2399   *out_num_types = UINT32(layer_changes_.size());
2400   *out_num_requests = UINT32(layer_requests_.size());
2401 
2402   return ((*out_num_types > 0) ? HWC2::Error::HasChanges : HWC2::Error::None);
2403 }
2404 
SetDisplayedContentSamplingEnabledVndService(bool enabled)2405 HWC2::Error HWCDisplay::SetDisplayedContentSamplingEnabledVndService(bool enabled) {
2406   return HWC2::Error::Unsupported;
2407 }
2408 
SetDisplayedContentSamplingEnabled(int32_t enabled,uint8_t component_mask,uint64_t max_frames)2409 HWC2::Error HWCDisplay::SetDisplayedContentSamplingEnabled(int32_t enabled,
2410     uint8_t component_mask, uint64_t max_frames) {
2411 
2412   DLOGV("Request to start/stop histogram thread not supported on this display");
2413   return HWC2::Error::Unsupported;
2414 }
2415 
GetDisplayedContentSamplingAttributes(int32_t * format,int32_t * dataspace,uint8_t * supported_components)2416 HWC2::Error HWCDisplay::GetDisplayedContentSamplingAttributes(int32_t* format,
2417                                                               int32_t* dataspace,
2418                                                               uint8_t* supported_components) {
2419   return HWC2::Error::Unsupported;
2420 }
2421 
GetDisplayedContentSample(uint64_t max_frames,uint64_t timestamp,uint64_t * numFrames,int32_t samples_size[NUM_HISTOGRAM_COLOR_COMPONENTS],uint64_t * samples[NUM_HISTOGRAM_COLOR_COMPONENTS])2422 HWC2::Error HWCDisplay::GetDisplayedContentSample(uint64_t max_frames,
2423                                                   uint64_t timestamp,
2424                                                   uint64_t* numFrames,
2425                                                   int32_t samples_size[NUM_HISTOGRAM_COLOR_COMPONENTS],
2426                                                   uint64_t* samples[NUM_HISTOGRAM_COLOR_COMPONENTS]) {
2427   return HWC2::Error::Unsupported;
2428 }
2429 
UpdateRefreshRate()2430 void HWCDisplay::UpdateRefreshRate() {
2431   for (auto hwc_layer : layer_set_) {
2432     if (hwc_layer->HasMetaDataRefreshRate()) {
2433       continue;
2434     }
2435     auto layer = hwc_layer->GetSDMLayer();
2436     layer->frame_rate = current_refresh_rate_;
2437   }
2438 
2439   Layer *sdm_client_target = client_target_->GetSDMLayer();
2440   sdm_client_target->frame_rate = current_refresh_rate_;
2441 }
2442 
2443 // Skip SDM prepare if all the layers in the current draw cycle are marked as Skip and
2444 // previous draw cycle had GPU Composition, as the resources for GPU Target layer have
2445 // already been validated and configured to the driver.
CanSkipSdmPrepare(uint32_t * num_types,uint32_t * num_requests)2446 bool HWCDisplay::CanSkipSdmPrepare(uint32_t *num_types, uint32_t *num_requests) {
2447   if (!validated_ || layer_set_.empty()) {
2448     return false;
2449   }
2450 
2451   bool skip_prepare = true;
2452   for (auto hwc_layer : layer_set_) {
2453     if (!hwc_layer->GetSDMLayer()->flags.skip ||
2454         (hwc_layer->GetDeviceSelectedCompositionType() != HWC2::Composition::Client)) {
2455       skip_prepare = false;
2456       layer_changes_.clear();
2457       break;
2458     }
2459     if (hwc_layer->GetClientRequestedCompositionType() != HWC2::Composition::Client) {
2460       layer_changes_[hwc_layer->GetId()] = HWC2::Composition::Client;
2461     }
2462   }
2463 
2464   if (skip_prepare) {
2465     *num_types = UINT32(layer_changes_.size());
2466     *num_requests = 0;
2467     layer_stack_invalid_ = false;
2468     has_client_composition_ = true;
2469     client_target_->ResetValidation();
2470     validate_state_ = kNormalValidate;
2471   }
2472 
2473   return skip_prepare;
2474 }
2475 
2476 }  // namespace sdm
2477