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