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