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