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