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