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