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 "blit_engine_c2d.h"
43 #include "hwc_tonemapper.h"
44
45 #ifndef USE_GRALLOC1
46 #include <gr.h>
47 #endif
48
49 #ifdef QTI_BSP
50 #include <hardware/display_defs.h>
51 #endif
52
53 #define __CLASS__ "HWCDisplay"
54
55 namespace sdm {
56
57 std::bitset<kDisplayMax> HWCDisplay::validated_ = 0;
58
59 // This weight function is needed because the color primaries are not sorted by gamut size
WidestPrimaries(ColorPrimaries p1,ColorPrimaries p2)60 static ColorPrimaries WidestPrimaries(ColorPrimaries p1, ColorPrimaries p2) {
61 int weight = 10;
62 int lp1 = p1, lp2 = p2;
63 // TODO(user) add weight to other wide gamut primaries
64 if (lp1 == ColorPrimaries_BT2020) {
65 lp1 *= weight;
66 }
67 if (lp1 == ColorPrimaries_BT2020) {
68 lp2 *= weight;
69 }
70 if (lp1 >= lp2) {
71 return p1;
72 } else {
73 return p2;
74 }
75 }
76
HWCColorMode(DisplayInterface * display_intf)77 HWCColorMode::HWCColorMode(DisplayInterface *display_intf) : display_intf_(display_intf) {}
78
Init()79 HWC2::Error HWCColorMode::Init() {
80 PopulateColorModes();
81 return ApplyDefaultColorMode();
82 }
83
DeInit()84 HWC2::Error HWCColorMode::DeInit() {
85 color_mode_transform_map_.clear();
86 return HWC2::Error::None;
87 }
88
GetColorModeCount()89 uint32_t HWCColorMode::GetColorModeCount() {
90 uint32_t count = UINT32(color_mode_transform_map_.size());
91 DLOGI("Supported color mode count = %d", count);
92 #ifdef EXCLUDE_DISPLAY_PP
93 return count;
94 #else
95 return std::max(1U, count);
96 #endif
97 }
98
GetColorModes(uint32_t * out_num_modes,android_color_mode_t * out_modes)99 HWC2::Error HWCColorMode::GetColorModes(uint32_t *out_num_modes,
100 android_color_mode_t *out_modes) {
101 auto it = color_mode_transform_map_.begin();
102 for (auto i = 0; it != color_mode_transform_map_.end(); it++, i++) {
103 out_modes[i] = it->first;
104 DLOGI("Supports color mode[%d] = %d", i, it->first);
105 }
106 *out_num_modes = UINT32(color_mode_transform_map_.size());
107 return HWC2::Error::None;
108 }
109
SetColorMode(android_color_mode_t mode)110 HWC2::Error HWCColorMode::SetColorMode(android_color_mode_t mode) {
111 // first mode in 2D matrix is the mode (identity)
112 if (mode < HAL_COLOR_MODE_NATIVE || mode > HAL_COLOR_MODE_DISPLAY_P3) {
113 DLOGE("Could not find mode: %d", mode);
114 return HWC2::Error::BadParameter;
115 }
116 if (color_mode_transform_map_.find(mode) == color_mode_transform_map_.end()) {
117 return HWC2::Error::Unsupported;
118 }
119
120 auto status = HandleColorModeTransform(mode, current_color_transform_, color_matrix_);
121 if (status != HWC2::Error::None) {
122 DLOGE("failed for mode = %d", mode);
123 }
124
125 return status;
126 }
127
SetColorTransform(const float * matrix,android_color_transform_t hint)128 HWC2::Error HWCColorMode::SetColorTransform(const float *matrix, android_color_transform_t hint) {
129 if (!matrix || (hint < HAL_COLOR_TRANSFORM_IDENTITY ||
130 hint > HAL_COLOR_TRANSFORM_CORRECT_TRITANOPIA)) {
131 return HWC2::Error::BadParameter;
132 }
133
134 double color_matrix[kColorTransformMatrixCount] = {0};
135 CopyColorTransformMatrix(matrix, color_matrix);
136
137 auto status = HandleColorModeTransform(current_color_mode_, hint, color_matrix);
138 if (status != HWC2::Error::None) {
139 DLOGE("failed for hint = %d", hint);
140 }
141
142 return status;
143 }
144
HandleColorModeTransform(android_color_mode_t mode,android_color_transform_t hint,const double * matrix)145 HWC2::Error HWCColorMode::HandleColorModeTransform(android_color_mode_t mode,
146 android_color_transform_t hint,
147 const double *matrix) {
148 android_color_transform_t transform_hint = hint;
149 std::string color_mode_transform;
150 bool use_matrix = false;
151 if (hint != HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX) {
152 // if the mode + transfrom request from HWC matches one mode in SDM, set that
153 if (color_mode_transform.empty()) {
154 transform_hint = HAL_COLOR_TRANSFORM_IDENTITY;
155 use_matrix = true;
156 } else {
157 color_mode_transform = color_mode_transform_map_[mode][hint];
158 }
159 } else {
160 use_matrix = true;
161 transform_hint = HAL_COLOR_TRANSFORM_IDENTITY;
162 }
163
164 // if the mode count is 1, then only native mode is supported, so just apply matrix w/o
165 // setting mode
166 if (color_mode_transform_map_.size() > 1U && current_color_mode_ != mode) {
167 color_mode_transform = color_mode_transform_map_[mode][transform_hint];
168 DisplayError error = display_intf_->SetColorMode(color_mode_transform);
169 if (error != kErrorNone) {
170 DLOGE("Failed to set color_mode = %d transform_hint = %d", mode, hint);
171 // failure to force client composition
172 return HWC2::Error::Unsupported;
173 }
174 DLOGI("Setting Color Mode = %d Transform Hint = %d Success", mode, hint);
175 }
176
177 if (use_matrix) {
178 DisplayError error = display_intf_->SetColorTransform(kColorTransformMatrixCount, matrix);
179 if (error != kErrorNone) {
180 DLOGE("Failed to set Color Transform Matrix");
181 // failure to force client composition
182 return HWC2::Error::Unsupported;
183 }
184 }
185
186 current_color_mode_ = mode;
187 current_color_transform_ = hint;
188 CopyColorTransformMatrix(matrix, color_matrix_);
189
190 return HWC2::Error::None;
191 }
192
PopulateColorModes()193 void HWCColorMode::PopulateColorModes() {
194 uint32_t color_mode_count = 0;
195 // SDM returns modes which is string combination of mode + transform.
196 DisplayError error = display_intf_->GetColorModeCount(&color_mode_count);
197 if (error != kErrorNone || (color_mode_count == 0)) {
198 #ifndef EXCLUDE_DISPLAY_PP
199 DLOGW("GetColorModeCount failed, use native color mode");
200 PopulateTransform(HAL_COLOR_MODE_NATIVE, "native", "identity");
201 #endif
202 return;
203 }
204
205 DLOGV_IF(kTagQDCM, "Color Modes supported count = %d", color_mode_count);
206
207 const std::string color_transform = "identity";
208 std::vector<std::string> color_modes(color_mode_count);
209 error = display_intf_->GetColorModes(&color_mode_count, &color_modes);
210 for (uint32_t i = 0; i < color_mode_count; i++) {
211 std::string &mode_string = color_modes.at(i);
212 DLOGV_IF(kTagQDCM, "Color Mode[%d] = %s", i, mode_string.c_str());
213 AttrVal attr;
214 error = display_intf_->GetColorModeAttr(mode_string, &attr);
215 std::string color_gamut, dynamic_range, pic_quality;
216 if (!attr.empty()) {
217 for (auto &it : attr) {
218 if (it.first.find(kColorGamutAttribute) != std::string::npos) {
219 color_gamut = it.second;
220 } else if (it.first.find(kDynamicRangeAttribute) != std::string::npos) {
221 dynamic_range = it.second;
222 } else if (it.first.find(kPictureQualityAttribute) != std::string::npos) {
223 pic_quality = it.second;
224 }
225 }
226 if (dynamic_range == kHdr) {
227 continue;
228 }
229 if ((color_gamut == kNative) &&
230 (pic_quality.empty() || pic_quality == kStandard)) {
231 PopulateTransform(HAL_COLOR_MODE_NATIVE, mode_string, color_transform);
232 } else if ((color_gamut == kSrgb) &&
233 (pic_quality.empty() || pic_quality == kStandard)) {
234 PopulateTransform(HAL_COLOR_MODE_SRGB, mode_string, color_transform);
235 } else if ((color_gamut == kDcip3) &&
236 (pic_quality.empty() || pic_quality == kStandard)) {
237 PopulateTransform(HAL_COLOR_MODE_DISPLAY_P3, mode_string, color_transform);
238 } else if ((color_gamut == kDisplayP3) &&
239 (pic_quality.empty() || pic_quality == kStandard)) {
240 PopulateTransform(HAL_COLOR_MODE_DISPLAY_P3, mode_string, color_transform);
241 }
242 }
243
244 // Look at the mode name, if no color gamut is found
245 if (color_gamut.empty()) {
246 if (mode_string.find("hal_native") != std::string::npos) {
247 PopulateTransform(HAL_COLOR_MODE_NATIVE, mode_string, mode_string);
248 } else if (mode_string.find("hal_srgb") != std::string::npos) {
249 PopulateTransform(HAL_COLOR_MODE_SRGB, mode_string, mode_string);
250 } else if (mode_string.find("hal_adobe") != std::string::npos) {
251 PopulateTransform(HAL_COLOR_MODE_ADOBE_RGB, mode_string, mode_string);
252 } else if (mode_string.find("hal_dci_p3") != std::string::npos) {
253 PopulateTransform(HAL_COLOR_MODE_DCI_P3, mode_string, mode_string);
254 } else if (mode_string.find("hal_display_p3") != std::string::npos) {
255 PopulateTransform(HAL_COLOR_MODE_DISPLAY_P3, mode_string, mode_string);
256 }
257 }
258 }
259 }
260
PopulateTransform(const android_color_mode_t & mode,const std::string & color_mode,const std::string & color_transform)261 void HWCColorMode::PopulateTransform(const android_color_mode_t &mode,
262 const std::string &color_mode,
263 const std::string &color_transform) {
264 // TODO(user): Check the substring from QDCM
265 if (color_transform.find("identity") != std::string::npos) {
266 color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_IDENTITY] = color_mode;
267 } else if (color_transform.find("arbitrary") != std::string::npos) {
268 // no color mode for arbitrary
269 } else if (color_transform.find("inverse") != std::string::npos) {
270 color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_VALUE_INVERSE] = color_mode;
271 } else if (color_transform.find("grayscale") != std::string::npos) {
272 color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_GRAYSCALE] = color_mode;
273 } else if (color_transform.find("correct_protonopia") != std::string::npos) {
274 color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_CORRECT_PROTANOPIA] = color_mode;
275 } else if (color_transform.find("correct_deuteranopia") != std::string::npos) {
276 color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_CORRECT_DEUTERANOPIA] = color_mode;
277 } else if (color_transform.find("correct_tritanopia") != std::string::npos) {
278 color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_CORRECT_TRITANOPIA] = color_mode;
279 } else {
280 color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_IDENTITY] = color_mode;
281 }
282 }
283
ApplyDefaultColorMode()284 HWC2::Error HWCColorMode::ApplyDefaultColorMode() {
285 android_color_mode_t color_mode = HAL_COLOR_MODE_NATIVE;
286 if (color_mode_transform_map_.size() == 1U) {
287 color_mode = color_mode_transform_map_.begin()->first;
288 } else if (color_mode_transform_map_.size() > 1U) {
289 std::string default_color_mode;
290 bool found = false;
291 DisplayError error = display_intf_->GetDefaultColorMode(&default_color_mode);
292 if (error == kErrorNone) {
293 // get the default mode corresponding android_color_mode_t
294 for (auto &it_mode : color_mode_transform_map_) {
295 for (auto &it : it_mode.second) {
296 if (it.second == default_color_mode) {
297 found = true;
298 break;
299 }
300 }
301 if (found) {
302 color_mode = it_mode.first;
303 break;
304 }
305 }
306 }
307
308 // return the first andrid_color_mode_t when we encouter if not found
309 if (!found) {
310 color_mode = color_mode_transform_map_.begin()->first;
311 }
312 }
313 return SetColorMode(color_mode);
314 }
315
Dump(std::ostringstream * os)316 void HWCColorMode::Dump(std::ostringstream* os) {
317 *os << "color modes supported: ";
318 for (auto it : color_mode_transform_map_) {
319 *os << it.first <<" ";
320 }
321 *os << "current mode: " << current_color_mode_ << std::endl;
322 *os << "current transform: ";
323 for (uint32_t i = 0; i < kColorTransformMatrixCount; i++) {
324 if (i % 4 == 0) {
325 *os << std::endl;
326 }
327 *os << std::fixed << std::setprecision(2) << std::setw(6) << std::setfill(' ')
328 << color_matrix_[i] << " ";
329 }
330 *os << std::endl;
331 }
332
HWCDisplay(CoreInterface * core_intf,HWCCallbacks * callbacks,DisplayType type,hwc2_display_t id,bool needs_blit,qService::QService * qservice,DisplayClass display_class,BufferAllocator * buffer_allocator)333 HWCDisplay::HWCDisplay(CoreInterface *core_intf, HWCCallbacks *callbacks, DisplayType type,
334 hwc2_display_t id, bool needs_blit, qService::QService *qservice,
335 DisplayClass display_class, BufferAllocator *buffer_allocator)
336 : core_intf_(core_intf),
337 callbacks_(callbacks),
338 type_(type),
339 id_(id),
340 needs_blit_(needs_blit),
341 qservice_(qservice),
342 display_class_(display_class) {
343 buffer_allocator_ = static_cast<HWCBufferAllocator *>(buffer_allocator);
344 }
345
Init()346 int HWCDisplay::Init() {
347 DisplayError error = core_intf_->CreateDisplay(type_, this, &display_intf_);
348 if (error != kErrorNone) {
349 DLOGE("Display create failed. Error = %d display_type %d event_handler %p disp_intf %p", error,
350 type_, this, &display_intf_);
351 return -EINVAL;
352 }
353
354 validated_.reset();
355 HWCDebugHandler::Get()->GetProperty("sys.hwc_disable_hdr", &disable_hdr_handling_);
356 if (disable_hdr_handling_) {
357 DLOGI("HDR Handling disabled");
358 }
359
360 int property_swap_interval = 1;
361 HWCDebugHandler::Get()->GetProperty("debug.egl.swapinterval", &property_swap_interval);
362 if (property_swap_interval == 0) {
363 swap_interval_zero_ = true;
364 }
365
366 client_target_ = new HWCLayer(id_, buffer_allocator_);
367
368 int blit_enabled = 0;
369 HWCDebugHandler::Get()->GetProperty("persist.hwc.blit.comp", &blit_enabled);
370 if (needs_blit_ && blit_enabled) {
371 // TODO(user): Add blit engine when needed
372 }
373
374 error = display_intf_->GetNumVariableInfoConfigs(&num_configs_);
375 if (error != kErrorNone) {
376 DLOGE("Getting config count failed. Error = %d", error);
377 return -EINVAL;
378 }
379
380 tone_mapper_ = new HWCToneMapper(buffer_allocator_);
381
382 display_intf_->GetRefreshRateRange(&min_refresh_rate_, &max_refresh_rate_);
383 current_refresh_rate_ = max_refresh_rate_;
384
385 GetUnderScanConfig();
386 DLOGI("Display created with id: %d", id_);
387
388 return 0;
389 }
390
Deinit()391 int HWCDisplay::Deinit() {
392 DisplayError error = core_intf_->DestroyDisplay(display_intf_);
393 if (error != kErrorNone) {
394 DLOGE("Display destroy failed. Error = %d", error);
395 return -EINVAL;
396 }
397
398 delete client_target_;
399
400 if (color_mode_) {
401 color_mode_->DeInit();
402 delete color_mode_;
403 }
404
405 delete tone_mapper_;
406 tone_mapper_ = nullptr;
407
408 return 0;
409 }
410
411 // LayerStack operations
CreateLayer(hwc2_layer_t * out_layer_id)412 HWC2::Error HWCDisplay::CreateLayer(hwc2_layer_t *out_layer_id) {
413 HWCLayer *layer = *layer_set_.emplace(new HWCLayer(id_, buffer_allocator_));
414 layer_map_.emplace(std::make_pair(layer->GetId(), layer));
415 *out_layer_id = layer->GetId();
416 geometry_changes_ |= GeometryChanges::kAdded;
417 validated_.reset();
418 return HWC2::Error::None;
419 }
420
GetHWCLayer(hwc2_layer_t layer_id)421 HWCLayer *HWCDisplay::GetHWCLayer(hwc2_layer_t layer_id) {
422 const auto map_layer = layer_map_.find(layer_id);
423 if (map_layer == layer_map_.end()) {
424 DLOGE("[%" PRIu64 "] GetLayer(%" PRIu64 ") failed: no such layer", id_, layer_id);
425 return nullptr;
426 } else {
427 return map_layer->second;
428 }
429 }
430
DestroyLayer(hwc2_layer_t layer_id)431 HWC2::Error HWCDisplay::DestroyLayer(hwc2_layer_t layer_id) {
432 const auto map_layer = layer_map_.find(layer_id);
433 if (map_layer == layer_map_.end()) {
434 DLOGE("[%" PRIu64 "] destroyLayer(%" PRIu64 ") failed: no such layer", id_, layer_id);
435 return HWC2::Error::BadLayer;
436 }
437 const auto layer = map_layer->second;
438 layer_map_.erase(map_layer);
439 const auto z_range = layer_set_.equal_range(layer);
440 for (auto current = z_range.first; current != z_range.second; ++current) {
441 if (*current == layer) {
442 current = layer_set_.erase(current);
443 delete layer;
444 break;
445 }
446 }
447
448 geometry_changes_ |= GeometryChanges::kRemoved;
449 validated_.reset();
450 return HWC2::Error::None;
451 }
452
453
BuildLayerStack()454 void HWCDisplay::BuildLayerStack() {
455 layer_stack_ = LayerStack();
456 display_rect_ = LayerRect();
457 metadata_refresh_rate_ = 0;
458 auto working_primaries = ColorPrimaries_BT709_5;
459
460 uint32_t color_mode_count = 0;
461 display_intf_->GetColorModeCount(&color_mode_count);
462
463 // Add one layer for fb target
464 // TODO(user): Add blit target layers
465 for (auto hwc_layer : layer_set_) {
466 Layer *layer = hwc_layer->GetSDMLayer();
467 layer->flags = {}; // Reset earlier flags
468 if (hwc_layer->GetClientRequestedCompositionType() == HWC2::Composition::Client) {
469 layer->flags.skip = true;
470 } else if (hwc_layer->GetClientRequestedCompositionType() == HWC2::Composition::SolidColor) {
471 layer->flags.solid_fill = true;
472 }
473
474 #ifdef FEATURE_WIDE_COLOR
475 if (!hwc_layer->SupportedDataspace()) {
476 layer->flags.skip = true;
477 DLOGW_IF(kTagStrategy, "Unsupported dataspace: 0x%x", hwc_layer->GetLayerDataspace());
478 }
479 #endif
480
481 working_primaries = WidestPrimaries(working_primaries,
482 layer->input_buffer.color_metadata.colorPrimaries);
483
484 // set default composition as GPU for SDM
485 layer->composition = kCompositionGPU;
486
487 if (swap_interval_zero_) {
488 if (layer->input_buffer.acquire_fence_fd >= 0) {
489 close(layer->input_buffer.acquire_fence_fd);
490 layer->input_buffer.acquire_fence_fd = -1;
491 }
492 }
493
494 const private_handle_t *handle =
495 reinterpret_cast<const private_handle_t *>(layer->input_buffer.buffer_id);
496 if (handle) {
497 #ifdef USE_GRALLOC1
498 if (handle->buffer_type == BUFFER_TYPE_VIDEO) {
499 #else
500 if (handle->bufferType == BUFFER_TYPE_VIDEO) {
501 #endif
502 layer_stack_.flags.video_present = true;
503 }
504 // TZ Protected Buffer - L1
505 if (handle->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
506 layer_stack_.flags.secure_present = true;
507 }
508 // Gralloc Usage Protected Buffer - L3 - which needs to be treated as Secure & avoid fallback
509 if (handle->flags & private_handle_t::PRIV_FLAGS_PROTECTED_BUFFER) {
510 layer_stack_.flags.secure_present = true;
511 }
512 }
513
514 if (layer->flags.skip) {
515 layer_stack_.flags.skip_present = true;
516 }
517
518 if (hwc_layer->GetClientRequestedCompositionType() == HWC2::Composition::Cursor) {
519 // Currently we support only one HWCursor & only at top most z-order
520 if ((*layer_set_.rbegin())->GetId() == hwc_layer->GetId()) {
521 layer->flags.cursor = true;
522 layer_stack_.flags.cursor_present = true;
523 }
524 }
525
526 bool hdr_layer = layer->input_buffer.color_metadata.colorPrimaries == ColorPrimaries_BT2020 &&
527 (layer->input_buffer.color_metadata.transfer == Transfer_SMPTE_ST2084 ||
528 layer->input_buffer.color_metadata.transfer == Transfer_HLG);
529 if (hdr_layer && !disable_hdr_handling_ && color_mode_count) {
530 // dont honor HDR when its handling is disabled
531 layer->input_buffer.flags.hdr = true;
532 layer_stack_.flags.hdr_present = true;
533 }
534
535 // TODO(user): Move to a getter if this is needed at other places
536 hwc_rect_t scaled_display_frame = {INT(layer->dst_rect.left), INT(layer->dst_rect.top),
537 INT(layer->dst_rect.right), INT(layer->dst_rect.bottom)};
538 ApplyScanAdjustment(&scaled_display_frame);
539 hwc_layer->SetLayerDisplayFrame(scaled_display_frame);
540 // SDM requires these details even for solid fill
541 if (layer->flags.solid_fill) {
542 LayerBuffer *layer_buffer = &layer->input_buffer;
543 layer_buffer->width = UINT32(layer->dst_rect.right - layer->dst_rect.left);
544 layer_buffer->height = UINT32(layer->dst_rect.bottom - layer->dst_rect.top);
545 layer_buffer->unaligned_width = layer_buffer->width;
546 layer_buffer->unaligned_height = layer_buffer->height;
547 layer_buffer->acquire_fence_fd = -1;
548 layer_buffer->release_fence_fd = -1;
549 layer->src_rect.left = 0;
550 layer->src_rect.top = 0;
551 layer->src_rect.right = layer_buffer->width;
552 layer->src_rect.bottom = layer_buffer->height;
553 }
554
555 if (layer->frame_rate > metadata_refresh_rate_) {
556 metadata_refresh_rate_ = SanitizeRefreshRate(layer->frame_rate);
557 } else {
558 layer->frame_rate = current_refresh_rate_;
559 }
560 display_rect_ = Union(display_rect_, layer->dst_rect);
561 geometry_changes_ |= hwc_layer->GetGeometryChanges();
562
563 layer->flags.updating = true;
564 if (layer_set_.size() <= kMaxLayerCount) {
565 layer->flags.updating = IsLayerUpdating(layer);
566 }
567
568 layer_stack_.layers.push_back(layer);
569 }
570
571
572 #ifdef FEATURE_WIDE_COLOR
573 for (auto hwc_layer : layer_set_) {
574 auto layer = hwc_layer->GetSDMLayer();
575 if (layer->input_buffer.color_metadata.colorPrimaries != working_primaries &&
576 !hwc_layer->SupportLocalConversion(working_primaries)) {
577 layer->flags.skip = true;
578 }
579 if (layer->flags.skip) {
580 layer_stack_.flags.skip_present = true;
581 }
582 }
583 #endif
584
585 // TODO(user): Set correctly when SDM supports geometry_changes as bitmask
586 layer_stack_.flags.geometry_changed = UINT32(geometry_changes_ > 0);
587 // Append client target to the layer stack
588 layer_stack_.layers.push_back(client_target_->GetSDMLayer());
589 }
590
591 void HWCDisplay::BuildSolidFillStack() {
592 layer_stack_ = LayerStack();
593 display_rect_ = LayerRect();
594
595 layer_stack_.layers.push_back(solid_fill_layer_);
596 layer_stack_.flags.geometry_changed = 1U;
597 // Append client target to the layer stack
598 layer_stack_.layers.push_back(client_target_->GetSDMLayer());
599 }
600
601 HWC2::Error HWCDisplay::SetLayerZOrder(hwc2_layer_t layer_id, uint32_t z) {
602 const auto map_layer = layer_map_.find(layer_id);
603 if (map_layer == layer_map_.end()) {
604 DLOGE("[%" PRIu64 "] updateLayerZ failed to find layer", id_);
605 return HWC2::Error::BadLayer;
606 }
607
608 const auto layer = map_layer->second;
609 const auto z_range = layer_set_.equal_range(layer);
610 bool layer_on_display = false;
611 for (auto current = z_range.first; current != z_range.second; ++current) {
612 if (*current == layer) {
613 if ((*current)->GetZ() == z) {
614 // Don't change anything if the Z hasn't changed
615 return HWC2::Error::None;
616 }
617 current = layer_set_.erase(current);
618 layer_on_display = true;
619 break;
620 }
621 }
622
623 if (!layer_on_display) {
624 DLOGE("[%" PRIu64 "] updateLayerZ failed to find layer on display", id_);
625 return HWC2::Error::BadLayer;
626 }
627
628 layer->SetLayerZOrder(z);
629 layer_set_.emplace(layer);
630 return HWC2::Error::None;
631 }
632
633 HWC2::Error HWCDisplay::SetVsyncEnabled(HWC2::Vsync enabled) {
634 DLOGV("Display ID: %d enabled: %s", id_, to_string(enabled).c_str());
635 DisplayError error = kErrorNone;
636
637 if (shutdown_pending_ || !callbacks_->VsyncCallbackRegistered()) {
638 return HWC2::Error::None;
639 }
640
641 bool state;
642 if (enabled == HWC2::Vsync::Enable)
643 state = true;
644 else if (enabled == HWC2::Vsync::Disable)
645 state = false;
646 else
647 return HWC2::Error::BadParameter;
648
649 error = display_intf_->SetVSyncState(state);
650
651 if (error != kErrorNone) {
652 if (error == kErrorShutDown) {
653 shutdown_pending_ = true;
654 return HWC2::Error::None;
655 }
656 DLOGE("Failed. enabled = %s, error = %d", to_string(enabled).c_str(), error);
657 return HWC2::Error::BadDisplay;
658 }
659
660 return HWC2::Error::None;
661 }
662
663 HWC2::Error HWCDisplay::SetPowerMode(HWC2::PowerMode mode) {
664 DLOGV("display = %d, mode = %s", id_, to_string(mode).c_str());
665 DisplayState state = kStateOff;
666 bool flush_on_error = flush_on_error_;
667
668 if (shutdown_pending_) {
669 return HWC2::Error::None;
670 }
671
672 switch (mode) {
673 case HWC2::PowerMode::Off:
674 // During power off, all of the buffers are released.
675 // Do not flush until a buffer is successfully submitted again.
676 flush_on_error = false;
677 state = kStateOff;
678 if (tone_mapper_) {
679 tone_mapper_->Terminate();
680 }
681 break;
682 case HWC2::PowerMode::On:
683 state = kStateOn;
684 last_power_mode_ = HWC2::PowerMode::On;
685 break;
686 case HWC2::PowerMode::Doze:
687 state = kStateDoze;
688 last_power_mode_ = HWC2::PowerMode::Doze;
689 break;
690 case HWC2::PowerMode::DozeSuspend:
691 state = kStateDozeSuspend;
692 last_power_mode_ = HWC2::PowerMode::DozeSuspend;
693 break;
694 default:
695 return HWC2::Error::BadParameter;
696 }
697
698 DisplayError error = display_intf_->SetDisplayState(state);
699 validated_.reset();
700
701 if (error == kErrorNone) {
702 flush_on_error_ = flush_on_error;
703 } else {
704 if (error == kErrorShutDown) {
705 shutdown_pending_ = true;
706 return HWC2::Error::None;
707 }
708 DLOGE("Set state failed. Error = %d", error);
709 return HWC2::Error::BadParameter;
710 }
711
712 return HWC2::Error::None;
713 }
714
715 HWC2::Error HWCDisplay::GetClientTargetSupport(uint32_t width, uint32_t height, int32_t format,
716 int32_t dataspace) {
717 DisplayConfigVariableInfo variable_config;
718 display_intf_->GetFrameBufferConfig(&variable_config);
719 // TODO(user): Support scaled configurations, other formats and other dataspaces
720 if (format != HAL_PIXEL_FORMAT_RGBA_8888 || dataspace != HAL_DATASPACE_UNKNOWN ||
721 width != variable_config.x_pixels || height != variable_config.y_pixels) {
722 return HWC2::Error::Unsupported;
723 } else {
724 return HWC2::Error::None;
725 }
726 }
727
728 HWC2::Error HWCDisplay::GetColorModes(uint32_t *out_num_modes, android_color_mode_t *out_modes) {
729 if (out_modes) {
730 out_modes[0] = HAL_COLOR_MODE_NATIVE;
731 }
732 *out_num_modes = 1;
733
734 return HWC2::Error::None;
735 }
736
737 HWC2::Error HWCDisplay::GetDisplayConfigs(uint32_t *out_num_configs, hwc2_config_t *out_configs) {
738 if (out_configs == nullptr) {
739 *out_num_configs = num_configs_;
740 return HWC2::Error::None;
741 }
742
743 *out_num_configs = num_configs_;
744
745 for (uint32_t i = 0; i < num_configs_; i++) {
746 out_configs[i] = i;
747 }
748
749 return HWC2::Error::None;
750 }
751
752 HWC2::Error HWCDisplay::GetDisplayAttribute(hwc2_config_t config, HWC2::Attribute attribute,
753 int32_t *out_value) {
754 DisplayConfigVariableInfo variable_config;
755 if (GetDisplayAttributesForConfig(INT(config), &variable_config) != kErrorNone) {
756 DLOGE("Get variable config failed");
757 return HWC2::Error::BadDisplay;
758 }
759
760 switch (attribute) {
761 case HWC2::Attribute::VsyncPeriod:
762 *out_value = INT32(variable_config.vsync_period_ns);
763 break;
764 case HWC2::Attribute::Width:
765 *out_value = INT32(variable_config.x_pixels);
766 break;
767 case HWC2::Attribute::Height:
768 *out_value = INT32(variable_config.y_pixels);
769 break;
770 case HWC2::Attribute::DpiX:
771 *out_value = INT32(variable_config.x_dpi * 1000.0f);
772 break;
773 case HWC2::Attribute::DpiY:
774 *out_value = INT32(variable_config.y_dpi * 1000.0f);
775 break;
776 default:
777 DLOGW("Spurious attribute type = %s", to_string(attribute).c_str());
778 *out_value = -1;
779 return HWC2::Error::BadConfig;
780 }
781
782 return HWC2::Error::None;
783 }
784
785 HWC2::Error HWCDisplay::GetDisplayName(uint32_t *out_size, char *out_name) {
786 // TODO(user): Get panel name and EDID name and populate it here
787 if (out_name == nullptr) {
788 *out_size = 32;
789 } else {
790 std::string name;
791 switch (id_) {
792 case HWC_DISPLAY_PRIMARY:
793 name = "Primary Display";
794 break;
795 case HWC_DISPLAY_EXTERNAL:
796 name = "External Display";
797 break;
798 case HWC_DISPLAY_VIRTUAL:
799 name = "Virtual Display";
800 break;
801 default:
802 name = "Unknown";
803 break;
804 }
805 std::strncpy(out_name, name.c_str(), name.size());
806 *out_size = UINT32(name.size());
807 }
808 return HWC2::Error::None;
809 }
810
811 HWC2::Error HWCDisplay::GetDisplayType(int32_t *out_type) {
812 if (out_type != nullptr) {
813 if (id_ == HWC_DISPLAY_VIRTUAL) {
814 *out_type = HWC2_DISPLAY_TYPE_VIRTUAL;
815 } else {
816 *out_type = HWC2_DISPLAY_TYPE_PHYSICAL;
817 }
818 return HWC2::Error::None;
819 } else {
820 return HWC2::Error::BadParameter;
821 }
822 }
823
824 HWC2::Error HWCDisplay::GetActiveConfig(hwc2_config_t *out_config) {
825 if (out_config == nullptr) {
826 return HWC2::Error::BadDisplay;
827 }
828
829 uint32_t active_index = 0;
830 if (GetActiveDisplayConfig(&active_index) != kErrorNone) {
831 return HWC2::Error::BadConfig;
832 }
833
834 *out_config = active_index;
835
836 return HWC2::Error::None;
837 }
838
839 HWC2::Error HWCDisplay::SetClientTarget(buffer_handle_t target, int32_t acquire_fence,
840 int32_t dataspace, hwc_region_t damage) {
841 // TODO(user): SurfaceFlinger gives us a null pointer here when doing full SDE composition
842 // The error is problematic for layer caching as it would overwrite our cached client target.
843 // Reported bug 28569722 to resolve this.
844 // For now, continue to use the last valid buffer reported to us for layer caching.
845 if (target == nullptr) {
846 return HWC2::Error::None;
847 }
848
849 if (acquire_fence == 0) {
850 DLOGE("acquire_fence is zero");
851 return HWC2::Error::BadParameter;
852 }
853
854 client_target_->SetLayerBuffer(target, acquire_fence);
855 client_target_->SetLayerSurfaceDamage(damage);
856 // Ignoring dataspace for now
857 return HWC2::Error::None;
858 }
859
860 HWC2::Error HWCDisplay::SetActiveConfig(hwc2_config_t config) {
861 if (SetActiveDisplayConfig(config) != kErrorNone) {
862 return HWC2::Error::BadConfig;
863 }
864
865 validated_.reset();
866 return HWC2::Error::None;
867 }
868
869 DisplayError HWCDisplay::SetMixerResolution(uint32_t width, uint32_t height) {
870 return kErrorNotSupported;
871 }
872
873 void HWCDisplay::SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type) {
874 dump_frame_count_ = count;
875 dump_frame_index_ = 0;
876 dump_input_layers_ = ((bit_mask_layer_type & (1 << INPUT_LAYER_DUMP)) != 0);
877
878 if (tone_mapper_) {
879 tone_mapper_->SetFrameDumpConfig(count);
880 }
881
882 DLOGI("num_frame_dump %d, input_layer_dump_enable %d", dump_frame_count_, dump_input_layers_);
883 validated_.reset();
884 }
885
886 HWC2::PowerMode HWCDisplay::GetLastPowerMode() {
887 return last_power_mode_;
888 }
889
890 DisplayError HWCDisplay::VSync(const DisplayEventVSync &vsync) {
891 callbacks_->Vsync(id_, vsync.timestamp);
892 return kErrorNone;
893 }
894
895 DisplayError HWCDisplay::Refresh() {
896 return kErrorNotSupported;
897 }
898
899 DisplayError HWCDisplay::CECMessage(char *message) {
900 if (qservice_) {
901 qservice_->onCECMessageReceived(message, 0);
902 } else {
903 DLOGW("Qservice instance not available.");
904 }
905
906 return kErrorNone;
907 }
908
909 DisplayError HWCDisplay::HandleEvent(DisplayEvent event) {
910 switch (event) {
911 case kIdleTimeout:
912 case kThermalEvent:
913 validated_.reset();
914 break;
915 default:
916 DLOGW("Unknown event: %d", event);
917 break;
918 }
919
920 return kErrorNone;
921 }
922
923 HWC2::Error HWCDisplay::PrepareLayerStack(uint32_t *out_num_types, uint32_t *out_num_requests) {
924 layer_changes_.clear();
925 layer_requests_.clear();
926 if (shutdown_pending_) {
927 return HWC2::Error::BadDisplay;
928 }
929
930 if (!skip_prepare_) {
931 DisplayError error = display_intf_->Prepare(&layer_stack_);
932 if (error != kErrorNone) {
933 if (error == kErrorShutDown) {
934 shutdown_pending_ = true;
935 } else if (error != kErrorPermission) {
936 DLOGE("Prepare failed. Error = %d", error);
937 // To prevent surfaceflinger infinite wait, flush the previous frame during Commit()
938 // so that previous buffer and fences are released, and override the error.
939 flush_ = true;
940 }
941 return HWC2::Error::BadDisplay;
942 } else {
943 validated_.set(type_);
944 }
945 } else {
946 // Skip is not set
947 MarkLayersForGPUBypass();
948 skip_prepare_ = false;
949 DLOGI("SecureDisplay %s, Skip Prepare/Commit and Flush",
950 secure_display_active_ ? "Starting" : "Stopping");
951 flush_ = true;
952 }
953
954 for (auto hwc_layer : layer_set_) {
955 Layer *layer = hwc_layer->GetSDMLayer();
956 LayerComposition &composition = layer->composition;
957
958 if ((composition == kCompositionSDE) || (composition == kCompositionHybrid) ||
959 (composition == kCompositionBlit)) {
960 layer_requests_[hwc_layer->GetId()] = HWC2::LayerRequest::ClearClientTarget;
961 }
962
963 HWC2::Composition requested_composition = hwc_layer->GetClientRequestedCompositionType();
964 // Set SDM composition to HWC2 type in HWCLayer
965 hwc_layer->SetComposition(composition);
966 HWC2::Composition device_composition = hwc_layer->GetDeviceSelectedCompositionType();
967 // Update the changes list only if the requested composition is different from SDM comp type
968 // TODO(user): Take Care of other comptypes(BLIT)
969 if (requested_composition != device_composition) {
970 layer_changes_[hwc_layer->GetId()] = device_composition;
971 }
972 hwc_layer->ResetValidation();
973 }
974 *out_num_types = UINT32(layer_changes_.size());
975 *out_num_requests = UINT32(layer_requests_.size());
976 skip_validate_ = false;
977 if (*out_num_types > 0) {
978 return HWC2::Error::HasChanges;
979 } else {
980 return HWC2::Error::None;
981 }
982 }
983
984 HWC2::Error HWCDisplay::AcceptDisplayChanges() {
985 if (layer_set_.empty()) {
986 return HWC2::Error::None;
987 }
988
989 if (!validated_.test(type_)) {
990 return HWC2::Error::NotValidated;
991 }
992
993 for (const auto& change : layer_changes_) {
994 auto hwc_layer = layer_map_[change.first];
995 auto composition = change.second;
996 if (hwc_layer != nullptr) {
997 hwc_layer->UpdateClientCompositionType(composition);
998 } else {
999 DLOGW("Invalid layer: %" PRIu64, change.first);
1000 }
1001 }
1002 return HWC2::Error::None;
1003 }
1004
1005 HWC2::Error HWCDisplay::GetChangedCompositionTypes(uint32_t *out_num_elements,
1006 hwc2_layer_t *out_layers, int32_t *out_types) {
1007 if (layer_set_.empty()) {
1008 return HWC2::Error::None;
1009 }
1010
1011 if (!validated_.test(type_)) {
1012 DLOGW("Display is not validated");
1013 return HWC2::Error::NotValidated;
1014 }
1015
1016 *out_num_elements = UINT32(layer_changes_.size());
1017 if (out_layers != nullptr && out_types != nullptr) {
1018 int i = 0;
1019 for (auto change : layer_changes_) {
1020 out_layers[i] = change.first;
1021 out_types[i] = INT32(change.second);
1022 i++;
1023 }
1024 }
1025 return HWC2::Error::None;
1026 }
1027
1028 HWC2::Error HWCDisplay::GetReleaseFences(uint32_t *out_num_elements, hwc2_layer_t *out_layers,
1029 int32_t *out_fences) {
1030 if (out_layers != nullptr && out_fences != nullptr) {
1031 int i = 0;
1032 for (auto hwc_layer : layer_set_) {
1033 out_layers[i] = hwc_layer->GetId();
1034 out_fences[i] = hwc_layer->PopReleaseFence();
1035 i++;
1036 }
1037 }
1038 *out_num_elements = UINT32(layer_set_.size());
1039 return HWC2::Error::None;
1040 }
1041
1042 HWC2::Error HWCDisplay::GetDisplayRequests(int32_t *out_display_requests,
1043 uint32_t *out_num_elements, hwc2_layer_t *out_layers,
1044 int32_t *out_layer_requests) {
1045 if (layer_set_.empty()) {
1046 return HWC2::Error::None;
1047 }
1048
1049 // No display requests for now
1050 // Use for sharing blit buffers and
1051 // writing wfd buffer directly to output if there is full GPU composition
1052 // and no color conversion needed
1053 if (!validated_.test(type_)) {
1054 DLOGW("Display is not validated");
1055 return HWC2::Error::NotValidated;
1056 }
1057
1058 *out_display_requests = 0;
1059 *out_num_elements = UINT32(layer_requests_.size());
1060 if (out_layers != nullptr && out_layer_requests != nullptr) {
1061 int i = 0;
1062 for (auto &request : layer_requests_) {
1063 out_layers[i] = request.first;
1064 out_layer_requests[i] = INT32(request.second);
1065 i++;
1066 }
1067 }
1068
1069 auto client_target_layer = client_target_->GetSDMLayer();
1070 if (client_target_layer->request.flags.flip_buffer) {
1071 *out_display_requests = INT32(HWC2::DisplayRequest::FlipClientTarget);
1072 }
1073
1074 return HWC2::Error::None;
1075 }
1076
1077 HWC2::Error HWCDisplay::GetHdrCapabilities(uint32_t *out_num_types, int32_t *out_types,
1078 float *out_max_luminance,
1079 float *out_max_average_luminance,
1080 float *out_min_luminance) {
1081 DisplayConfigFixedInfo fixed_info = {};
1082 display_intf_->GetConfig(&fixed_info);
1083
1084 if (!fixed_info.hdr_supported) {
1085 *out_num_types = 0;
1086 DLOGI("HDR is not supported");
1087 return HWC2::Error::None;
1088 }
1089
1090 if (out_types == nullptr) {
1091 // 1(now) - because we support only HDR10, change when HLG & DOLBY vision are supported
1092 *out_num_types = 1;
1093 } else {
1094 // Only HDR10 supported
1095 *out_types = HAL_HDR_HDR10;
1096 static const float kLuminanceFactor = 10000.0;
1097 // luminance is expressed in the unit of 0.0001 cd/m2, convert it to 1cd/m2.
1098 *out_max_luminance = FLOAT(fixed_info.max_luminance)/kLuminanceFactor;
1099 *out_max_average_luminance = FLOAT(fixed_info.average_luminance)/kLuminanceFactor;
1100 *out_min_luminance = FLOAT(fixed_info.min_luminance)/kLuminanceFactor;
1101 }
1102
1103 return HWC2::Error::None;
1104 }
1105
1106
1107 HWC2::Error HWCDisplay::CommitLayerStack(void) {
1108 if (skip_validate_ && !CanSkipValidate()) {
1109 validated_.reset(type_);
1110 }
1111
1112 if (!validated_.test(type_)) {
1113 DLOGV_IF(kTagCompManager, "Display %d is not validated", id_);
1114 return HWC2::Error::NotValidated;
1115 }
1116
1117 if (shutdown_pending_ || layer_set_.empty()) {
1118 return HWC2::Error::None;
1119 }
1120
1121 DumpInputBuffers();
1122
1123 if (!flush_) {
1124 DisplayError error = kErrorUndefined;
1125 int status = 0;
1126 if (tone_mapper_) {
1127 if (layer_stack_.flags.hdr_present) {
1128 status = tone_mapper_->HandleToneMap(&layer_stack_);
1129 if (status != 0) {
1130 DLOGE("Error handling HDR in ToneMapper");
1131 }
1132 } else {
1133 tone_mapper_->Terminate();
1134 }
1135 }
1136 error = display_intf_->Commit(&layer_stack_);
1137
1138 if (error == kErrorNone) {
1139 // A commit is successfully submitted, start flushing on failure now onwards.
1140 flush_on_error_ = true;
1141 } else {
1142 if (error == kErrorShutDown) {
1143 shutdown_pending_ = true;
1144 return HWC2::Error::Unsupported;
1145 } else if (error == kErrorNotValidated) {
1146 validated_.reset(type_);
1147 return HWC2::Error::NotValidated;
1148 } else if (error != kErrorPermission) {
1149 DLOGE("Commit failed. Error = %d", error);
1150 // To prevent surfaceflinger infinite wait, flush the previous frame during Commit()
1151 // so that previous buffer and fences are released, and override the error.
1152 flush_ = true;
1153 }
1154 }
1155 }
1156
1157 skip_validate_ = true;
1158 return HWC2::Error::None;
1159 }
1160
1161 HWC2::Error HWCDisplay::PostCommitLayerStack(int32_t *out_retire_fence) {
1162 auto status = HWC2::Error::None;
1163
1164 // Do no call flush on errors, if a successful buffer is never submitted.
1165 if (flush_ && flush_on_error_) {
1166 display_intf_->Flush();
1167 validated_.reset();
1168 }
1169
1170 if (tone_mapper_ && tone_mapper_->IsActive()) {
1171 tone_mapper_->PostCommit(&layer_stack_);
1172 }
1173
1174 // TODO(user): No way to set the client target release fence on SF
1175 int32_t &client_target_release_fence =
1176 client_target_->GetSDMLayer()->input_buffer.release_fence_fd;
1177 if (client_target_release_fence >= 0) {
1178 close(client_target_release_fence);
1179 client_target_release_fence = -1;
1180 }
1181
1182 for (auto hwc_layer : layer_set_) {
1183 hwc_layer->ResetGeometryChanges();
1184 Layer *layer = hwc_layer->GetSDMLayer();
1185 LayerBuffer *layer_buffer = &layer->input_buffer;
1186
1187 if (!flush_) {
1188 // If swapinterval property is set to 0 or for single buffer layers, do not update f/w
1189 // release fences and discard fences from driver
1190 if (swap_interval_zero_ || layer->flags.single_buffer) {
1191 close(layer_buffer->release_fence_fd);
1192 layer_buffer->release_fence_fd = -1;
1193 } else if (layer->composition != kCompositionGPU) {
1194 hwc_layer->PushReleaseFence(layer_buffer->release_fence_fd);
1195 layer_buffer->release_fence_fd = -1;
1196 } else {
1197 hwc_layer->PushReleaseFence(-1);
1198 }
1199 }
1200
1201 if (layer_buffer->acquire_fence_fd >= 0) {
1202 close(layer_buffer->acquire_fence_fd);
1203 layer_buffer->acquire_fence_fd = -1;
1204 }
1205 layer->request.flags = {};
1206 }
1207
1208 client_target_->GetSDMLayer()->request.flags = {};
1209 *out_retire_fence = -1;
1210 if (!flush_) {
1211 // if swapinterval property is set to 0 then close and reset the list retire fence
1212 if (swap_interval_zero_) {
1213 close(layer_stack_.retire_fence_fd);
1214 layer_stack_.retire_fence_fd = -1;
1215 }
1216 *out_retire_fence = layer_stack_.retire_fence_fd;
1217 layer_stack_.retire_fence_fd = -1;
1218
1219 if (dump_frame_count_) {
1220 dump_frame_count_--;
1221 dump_frame_index_++;
1222 }
1223 }
1224
1225 geometry_changes_ = GeometryChanges::kNone;
1226 flush_ = false;
1227
1228 return status;
1229 }
1230
1231 void HWCDisplay::SetIdleTimeoutMs(uint32_t timeout_ms) {
1232 return;
1233 }
1234
1235 DisplayError HWCDisplay::SetMaxMixerStages(uint32_t max_mixer_stages) {
1236 DisplayError error = kErrorNone;
1237
1238 if (display_intf_) {
1239 error = display_intf_->SetMaxMixerStages(max_mixer_stages);
1240 validated_.reset();
1241 }
1242
1243 return error;
1244 }
1245
1246 LayerBufferFormat HWCDisplay::GetSDMFormat(const int32_t &source, const int flags) {
1247 LayerBufferFormat format = kFormatInvalid;
1248 if (flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
1249 switch (source) {
1250 case HAL_PIXEL_FORMAT_RGBA_8888:
1251 format = kFormatRGBA8888Ubwc;
1252 break;
1253 case HAL_PIXEL_FORMAT_RGBX_8888:
1254 format = kFormatRGBX8888Ubwc;
1255 break;
1256 case HAL_PIXEL_FORMAT_BGR_565:
1257 format = kFormatBGR565Ubwc;
1258 break;
1259 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
1260 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
1261 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
1262 format = kFormatYCbCr420SPVenusUbwc;
1263 break;
1264 case HAL_PIXEL_FORMAT_RGBA_1010102:
1265 format = kFormatRGBA1010102Ubwc;
1266 break;
1267 case HAL_PIXEL_FORMAT_RGBX_1010102:
1268 format = kFormatRGBX1010102Ubwc;
1269 break;
1270 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
1271 format = kFormatYCbCr420TP10Ubwc;
1272 break;
1273 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
1274 format = kFormatYCbCr420P010Ubwc;
1275 break;
1276 default:
1277 DLOGE("Unsupported format type for UBWC %d", source);
1278 return kFormatInvalid;
1279 }
1280 return format;
1281 }
1282
1283 switch (source) {
1284 case HAL_PIXEL_FORMAT_RGBA_8888:
1285 format = kFormatRGBA8888;
1286 break;
1287 case HAL_PIXEL_FORMAT_RGBA_5551:
1288 format = kFormatRGBA5551;
1289 break;
1290 case HAL_PIXEL_FORMAT_RGBA_4444:
1291 format = kFormatRGBA4444;
1292 break;
1293 case HAL_PIXEL_FORMAT_BGRA_8888:
1294 format = kFormatBGRA8888;
1295 break;
1296 case HAL_PIXEL_FORMAT_RGBX_8888:
1297 format = kFormatRGBX8888;
1298 break;
1299 case HAL_PIXEL_FORMAT_BGRX_8888:
1300 format = kFormatBGRX8888;
1301 break;
1302 case HAL_PIXEL_FORMAT_RGB_888:
1303 format = kFormatRGB888;
1304 break;
1305 case HAL_PIXEL_FORMAT_RGB_565:
1306 format = kFormatRGB565;
1307 break;
1308 case HAL_PIXEL_FORMAT_BGR_565:
1309 format = kFormatBGR565;
1310 break;
1311 case HAL_PIXEL_FORMAT_BGR_888:
1312 format = kFormatBGR888;
1313 break;
1314 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
1315 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
1316 format = kFormatYCbCr420SemiPlanarVenus;
1317 break;
1318 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
1319 format = kFormatYCrCb420SemiPlanarVenus;
1320 break;
1321 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
1322 format = kFormatYCbCr420SPVenusUbwc;
1323 break;
1324 case HAL_PIXEL_FORMAT_YV12:
1325 format = kFormatYCrCb420PlanarStride16;
1326 break;
1327 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1328 format = kFormatYCrCb420SemiPlanar;
1329 break;
1330 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
1331 format = kFormatYCbCr420SemiPlanar;
1332 break;
1333 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
1334 format = kFormatYCbCr422H2V1SemiPlanar;
1335 break;
1336 case HAL_PIXEL_FORMAT_YCbCr_422_I:
1337 format = kFormatYCbCr422H2V1Packed;
1338 break;
1339 case HAL_PIXEL_FORMAT_CbYCrY_422_I:
1340 format = kFormatCbYCrY422H2V1Packed;
1341 break;
1342 case HAL_PIXEL_FORMAT_RGBA_1010102:
1343 format = kFormatRGBA1010102;
1344 break;
1345 case HAL_PIXEL_FORMAT_ARGB_2101010:
1346 format = kFormatARGB2101010;
1347 break;
1348 case HAL_PIXEL_FORMAT_RGBX_1010102:
1349 format = kFormatRGBX1010102;
1350 break;
1351 case HAL_PIXEL_FORMAT_XRGB_2101010:
1352 format = kFormatXRGB2101010;
1353 break;
1354 case HAL_PIXEL_FORMAT_BGRA_1010102:
1355 format = kFormatBGRA1010102;
1356 break;
1357 case HAL_PIXEL_FORMAT_ABGR_2101010:
1358 format = kFormatABGR2101010;
1359 break;
1360 case HAL_PIXEL_FORMAT_BGRX_1010102:
1361 format = kFormatBGRX1010102;
1362 break;
1363 case HAL_PIXEL_FORMAT_XBGR_2101010:
1364 format = kFormatXBGR2101010;
1365 break;
1366 case HAL_PIXEL_FORMAT_YCbCr_420_P010:
1367 format = kFormatYCbCr420P010;
1368 break;
1369 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
1370 format = kFormatYCbCr420TP10Ubwc;
1371 break;
1372 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
1373 format = kFormatYCbCr420P010Ubwc;
1374 break;
1375 default:
1376 DLOGW("Unsupported format type = %d", source);
1377 return kFormatInvalid;
1378 }
1379
1380 return format;
1381 }
1382
1383 void HWCDisplay::DumpInputBuffers() {
1384 char dir_path[PATH_MAX];
1385
1386 if (!dump_frame_count_ || flush_ || !dump_input_layers_) {
1387 return;
1388 }
1389
1390 snprintf(dir_path, sizeof(dir_path), "%s/frame_dump_%s", HWCDebugHandler::DumpDir(),
1391 GetDisplayString());
1392
1393 if (mkdir(dir_path, 0777) != 0 && errno != EEXIST) {
1394 DLOGW("Failed to create %s directory errno = %d, desc = %s", dir_path, errno, strerror(errno));
1395 return;
1396 }
1397
1398 // if directory exists already, need to explicitly change the permission.
1399 if (errno == EEXIST && chmod(dir_path, 0777) != 0) {
1400 DLOGW("Failed to change permissions on %s directory", dir_path);
1401 return;
1402 }
1403
1404 for (uint32_t i = 0; i < layer_stack_.layers.size(); i++) {
1405 auto layer = layer_stack_.layers.at(i);
1406 const private_handle_t *pvt_handle =
1407 reinterpret_cast<const private_handle_t *>(layer->input_buffer.buffer_id);
1408 auto acquire_fence_fd = layer->input_buffer.acquire_fence_fd;
1409
1410 if (acquire_fence_fd >= 0) {
1411 int error = sync_wait(acquire_fence_fd, 1000);
1412 if (error < 0) {
1413 DLOGW("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
1414 return;
1415 }
1416 }
1417
1418 if (pvt_handle && pvt_handle->base) {
1419 char dump_file_name[PATH_MAX];
1420 size_t result = 0;
1421
1422 snprintf(dump_file_name, sizeof(dump_file_name), "%s/input_layer%d_%dx%d_%s_frame%d.raw",
1423 dir_path, i, pvt_handle->width, pvt_handle->height,
1424 qdutils::GetHALPixelFormatString(pvt_handle->format), dump_frame_index_);
1425
1426 FILE *fp = fopen(dump_file_name, "w+");
1427 if (fp) {
1428 result = fwrite(reinterpret_cast<void *>(pvt_handle->base), pvt_handle->size, 1, fp);
1429 fclose(fp);
1430 }
1431
1432 DLOGI("Frame Dump %s: is %s", dump_file_name, result ? "Successful" : "Failed");
1433 }
1434 }
1435 }
1436
1437 void HWCDisplay::DumpOutputBuffer(const BufferInfo &buffer_info, void *base, int fence) {
1438 char dir_path[PATH_MAX];
1439
1440 snprintf(dir_path, sizeof(dir_path), "%s/frame_dump_%s", HWCDebugHandler::DumpDir(),
1441 GetDisplayString());
1442
1443 if (mkdir(dir_path, 777) != 0 && errno != EEXIST) {
1444 DLOGW("Failed to create %s directory errno = %d, desc = %s", dir_path, errno, strerror(errno));
1445 return;
1446 }
1447
1448 // if directory exists already, need to explicitly change the permission.
1449 if (errno == EEXIST && chmod(dir_path, 0777) != 0) {
1450 DLOGW("Failed to change permissions on %s directory", dir_path);
1451 return;
1452 }
1453
1454 if (base) {
1455 char dump_file_name[PATH_MAX];
1456 size_t result = 0;
1457
1458 if (fence >= 0) {
1459 int error = sync_wait(fence, 1000);
1460 if (error < 0) {
1461 DLOGW("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
1462 return;
1463 }
1464 }
1465
1466 snprintf(dump_file_name, sizeof(dump_file_name), "%s/output_layer_%dx%d_%s_frame%d.raw",
1467 dir_path, buffer_info.buffer_config.width, buffer_info.buffer_config.height,
1468 GetFormatString(buffer_info.buffer_config.format), dump_frame_index_);
1469
1470 FILE *fp = fopen(dump_file_name, "w+");
1471 if (fp) {
1472 result = fwrite(base, buffer_info.alloc_buffer_info.size, 1, fp);
1473 fclose(fp);
1474 }
1475
1476 DLOGI("Frame Dump of %s is %s", dump_file_name, result ? "Successful" : "Failed");
1477 }
1478 }
1479
1480 const char *HWCDisplay::GetDisplayString() {
1481 switch (type_) {
1482 case kPrimary:
1483 return "primary";
1484 case kHDMI:
1485 return "hdmi";
1486 case kVirtual:
1487 return "virtual";
1488 default:
1489 return "invalid";
1490 }
1491 }
1492
1493 int HWCDisplay::SetFrameBufferResolution(uint32_t x_pixels, uint32_t y_pixels) {
1494 if (x_pixels <= 0 || y_pixels <= 0) {
1495 DLOGW("Unsupported config: x_pixels=%d, y_pixels=%d", x_pixels, y_pixels);
1496 return -EINVAL;
1497 }
1498
1499 DisplayConfigVariableInfo fb_config;
1500 DisplayError error = display_intf_->GetFrameBufferConfig(&fb_config);
1501 if (error != kErrorNone) {
1502 DLOGV("Get frame buffer config failed. Error = %d", error);
1503 return -EINVAL;
1504 }
1505
1506 fb_config.x_pixels = x_pixels;
1507 fb_config.y_pixels = y_pixels;
1508
1509 error = display_intf_->SetFrameBufferConfig(fb_config);
1510 if (error != kErrorNone) {
1511 DLOGV("Set frame buffer config failed. Error = %d", error);
1512 return -EINVAL;
1513 }
1514
1515 // Create rects to represent the new source and destination crops
1516 LayerRect crop = LayerRect(0, 0, FLOAT(x_pixels), FLOAT(y_pixels));
1517 LayerRect dst = LayerRect(0, 0, FLOAT(fb_config.x_pixels), FLOAT(fb_config.y_pixels));
1518 auto client_target_layer = client_target_->GetSDMLayer();
1519 client_target_layer->src_rect = crop;
1520 client_target_layer->dst_rect = dst;
1521
1522 int aligned_width;
1523 int aligned_height;
1524 uint32_t usage = GRALLOC_USAGE_HW_FB;
1525 int format = HAL_PIXEL_FORMAT_RGBA_8888;
1526 int ubwc_disabled = 0;
1527 int flags = 0;
1528
1529 // By default UBWC is enabled and below property is global enable/disable for all
1530 // buffers allocated through gralloc , including framebuffer targets.
1531 HWCDebugHandler::Get()->GetProperty("debug.gralloc.gfx_ubwc_disable", &ubwc_disabled);
1532 if (!ubwc_disabled) {
1533 usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
1534 flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
1535 }
1536
1537 #ifdef USE_GRALLOC1
1538 buffer_allocator_->GetAlignedWidthAndHeight(INT(x_pixels), INT(y_pixels), format, usage,
1539 &aligned_width, &aligned_height);
1540 #else
1541 AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(INT(x_pixels), INT(y_pixels), format,
1542 INT(usage), aligned_width, aligned_height);
1543 #endif
1544
1545 // TODO(user): How does the dirty region get set on the client target? File bug on Google
1546 client_target_layer->composition = kCompositionGPUTarget;
1547 client_target_layer->input_buffer.format = GetSDMFormat(format, flags);
1548 client_target_layer->input_buffer.width = UINT32(aligned_width);
1549 client_target_layer->input_buffer.height = UINT32(aligned_height);
1550 client_target_layer->input_buffer.unaligned_width = x_pixels;
1551 client_target_layer->input_buffer.unaligned_height = y_pixels;
1552 client_target_layer->plane_alpha = 255;
1553
1554 DLOGI("New framebuffer resolution (%dx%d)", fb_config.x_pixels, fb_config.y_pixels);
1555
1556 return 0;
1557 }
1558
1559 void HWCDisplay::GetFrameBufferResolution(uint32_t *x_pixels, uint32_t *y_pixels) {
1560 DisplayConfigVariableInfo fb_config;
1561 display_intf_->GetFrameBufferConfig(&fb_config);
1562
1563 *x_pixels = fb_config.x_pixels;
1564 *y_pixels = fb_config.y_pixels;
1565 }
1566
1567 DisplayError HWCDisplay::GetMixerResolution(uint32_t *x_pixels, uint32_t *y_pixels) {
1568 return display_intf_->GetMixerResolution(x_pixels, y_pixels);
1569 }
1570
1571 void HWCDisplay::GetPanelResolution(uint32_t *x_pixels, uint32_t *y_pixels) {
1572 DisplayConfigVariableInfo display_config;
1573 uint32_t active_index = 0;
1574
1575 display_intf_->GetActiveConfig(&active_index);
1576 display_intf_->GetConfig(active_index, &display_config);
1577
1578 *x_pixels = display_config.x_pixels;
1579 *y_pixels = display_config.y_pixels;
1580 }
1581
1582 int HWCDisplay::SetDisplayStatus(DisplayStatus display_status) {
1583 int status = 0;
1584
1585 switch (display_status) {
1586 case kDisplayStatusResume:
1587 display_paused_ = false;
1588 case kDisplayStatusOnline:
1589 status = INT32(SetPowerMode(HWC2::PowerMode::On));
1590 break;
1591 case kDisplayStatusPause:
1592 display_paused_ = true;
1593 case kDisplayStatusOffline:
1594 status = INT32(SetPowerMode(HWC2::PowerMode::Off));
1595 break;
1596 default:
1597 DLOGW("Invalid display status %d", display_status);
1598 return -EINVAL;
1599 }
1600
1601 if (display_status == kDisplayStatusResume || display_status == kDisplayStatusPause) {
1602 callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
1603 validated_.reset();
1604 }
1605
1606 return status;
1607 }
1608
1609 HWC2::Error HWCDisplay::SetCursorPosition(hwc2_layer_t layer, int x, int y) {
1610 if (shutdown_pending_) {
1611 return HWC2::Error::None;
1612 }
1613
1614 HWCLayer *hwc_layer = GetHWCLayer(layer);
1615 if (hwc_layer == nullptr) {
1616 return HWC2::Error::BadLayer;
1617 }
1618 if (hwc_layer->GetDeviceSelectedCompositionType() != HWC2::Composition::Cursor) {
1619 return HWC2::Error::None;
1620 }
1621 if (!skip_validate_ && validated_.test(type_)) {
1622 // the device is currently in the middle of the validate/present sequence,
1623 // cannot set the Position(as per HWC2 spec)
1624 return HWC2::Error::NotValidated;
1625 }
1626
1627 DisplayState state;
1628 if (display_intf_->GetDisplayState(&state) == kErrorNone) {
1629 if (state != kStateOn) {
1630 return HWC2::Error::None;
1631 }
1632 }
1633
1634 // TODO(user): HWC1.5 was not letting SetCursorPosition before validateDisplay,
1635 // but HWC2.0 doesn't let setting cursor position after validate before present.
1636 // Need to revisit.
1637
1638 auto error = display_intf_->SetCursorPosition(x, y);
1639 if (error != kErrorNone) {
1640 if (error == kErrorShutDown) {
1641 shutdown_pending_ = true;
1642 return HWC2::Error::None;
1643 }
1644
1645 DLOGE("Failed for x = %d y = %d, Error = %d", x, y, error);
1646 return HWC2::Error::BadDisplay;
1647 }
1648
1649 return HWC2::Error::None;
1650 }
1651
1652 int HWCDisplay::OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level) {
1653 DisplayError error = display_intf_->OnMinHdcpEncryptionLevelChange(min_enc_level);
1654 if (error != kErrorNone) {
1655 DLOGE("Failed. Error = %d", error);
1656 return -1;
1657 }
1658
1659 validated_.reset();
1660 return 0;
1661 }
1662
1663 void HWCDisplay::MarkLayersForGPUBypass() {
1664 for (auto hwc_layer : layer_set_) {
1665 auto layer = hwc_layer->GetSDMLayer();
1666 layer->composition = kCompositionSDE;
1667 }
1668 validated_.set(type_);
1669 }
1670
1671 void HWCDisplay::MarkLayersForClientComposition() {
1672 // ClientComposition - GPU comp, to acheive this, set skip flag so that
1673 // SDM does not handle this layer and hwc_layer composition will be
1674 // set correctly at the end of Prepare.
1675 for (auto hwc_layer : layer_set_) {
1676 Layer *layer = hwc_layer->GetSDMLayer();
1677 layer->flags.skip = true;
1678 }
1679 }
1680
1681 void HWCDisplay::ApplyScanAdjustment(hwc_rect_t *display_frame) {
1682 }
1683
1684 int HWCDisplay::SetPanelBrightness(int level) {
1685 int ret = 0;
1686 if (display_intf_) {
1687 ret = display_intf_->SetPanelBrightness(level);
1688 validated_.reset();
1689 } else {
1690 ret = -EINVAL;
1691 }
1692
1693 return ret;
1694 }
1695
1696 int HWCDisplay::GetPanelBrightness(int *level) {
1697 return display_intf_->GetPanelBrightness(level);
1698 }
1699
1700 int HWCDisplay::ToggleScreenUpdates(bool enable) {
1701 display_paused_ = enable ? false : true;
1702 callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
1703 validated_.reset();
1704 return 0;
1705 }
1706
1707 int HWCDisplay::ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload,
1708 PPDisplayAPIPayload *out_payload,
1709 PPPendingParams *pending_action) {
1710 int ret = 0;
1711
1712 if (display_intf_)
1713 ret = display_intf_->ColorSVCRequestRoute(in_payload, out_payload, pending_action);
1714 else
1715 ret = -EINVAL;
1716
1717 return ret;
1718 }
1719
1720 void HWCDisplay::SolidFillPrepare() {
1721 if (solid_fill_enable_) {
1722 if (solid_fill_layer_ == NULL) {
1723 // Create a dummy layer here
1724 solid_fill_layer_ = new Layer();
1725 }
1726 uint32_t primary_width = 0, primary_height = 0;
1727 GetMixerResolution(&primary_width, &primary_height);
1728
1729 LayerBuffer *layer_buffer = &solid_fill_layer_->input_buffer;
1730 layer_buffer->width = primary_width;
1731 layer_buffer->height = primary_height;
1732 layer_buffer->unaligned_width = primary_width;
1733 layer_buffer->unaligned_height = primary_height;
1734 layer_buffer->acquire_fence_fd = -1;
1735 layer_buffer->release_fence_fd = -1;
1736
1737 LayerRect rect;
1738 rect.top = 0; rect.left = 0;
1739 rect.right = primary_width;
1740 rect.bottom = primary_height;
1741
1742 solid_fill_layer_->composition = kCompositionGPU;
1743 solid_fill_layer_->src_rect = rect;
1744 solid_fill_layer_->dst_rect = rect;
1745
1746 solid_fill_layer_->blending = kBlendingPremultiplied;
1747 solid_fill_layer_->solid_fill_color = solid_fill_color_;
1748 solid_fill_layer_->frame_rate = 60;
1749 solid_fill_layer_->visible_regions.push_back(solid_fill_layer_->dst_rect);
1750 solid_fill_layer_->flags.updating = 1;
1751 solid_fill_layer_->flags.solid_fill = true;
1752 } else {
1753 // delete the dummy layer
1754 delete solid_fill_layer_;
1755 solid_fill_layer_ = NULL;
1756 }
1757
1758 if (solid_fill_enable_ && solid_fill_layer_) {
1759 BuildSolidFillStack();
1760 MarkLayersForGPUBypass();
1761 }
1762
1763 return;
1764 }
1765
1766 void HWCDisplay::SolidFillCommit() {
1767 if (solid_fill_enable_ && solid_fill_layer_) {
1768 LayerBuffer *layer_buffer = &solid_fill_layer_->input_buffer;
1769 if (layer_buffer->release_fence_fd > 0) {
1770 close(layer_buffer->release_fence_fd);
1771 layer_buffer->release_fence_fd = -1;
1772 }
1773 if (layer_stack_.retire_fence_fd > 0) {
1774 close(layer_stack_.retire_fence_fd);
1775 layer_stack_.retire_fence_fd = -1;
1776 }
1777 }
1778 }
1779
1780 int HWCDisplay::GetVisibleDisplayRect(hwc_rect_t *visible_rect) {
1781 if (!IsValid(display_rect_)) {
1782 return -EINVAL;
1783 }
1784
1785 visible_rect->left = INT(display_rect_.left);
1786 visible_rect->top = INT(display_rect_.top);
1787 visible_rect->right = INT(display_rect_.right);
1788 visible_rect->bottom = INT(display_rect_.bottom);
1789 DLOGI("Dpy = %d Visible Display Rect(%d %d %d %d)", visible_rect->left, visible_rect->top,
1790 visible_rect->right, visible_rect->bottom);
1791
1792 return 0;
1793 }
1794
1795 void HWCDisplay::SetSecureDisplay(bool secure_display_active) {
1796 secure_display_active_ = secure_display_active;
1797 return;
1798 }
1799
1800 int HWCDisplay::SetActiveDisplayConfig(uint32_t config) {
1801 int status = (display_intf_->SetActiveConfig(config) == kErrorNone) ? 0 : -1;
1802 validated_.reset();
1803 return status;
1804 }
1805
1806 int HWCDisplay::GetActiveDisplayConfig(uint32_t *config) {
1807 return display_intf_->GetActiveConfig(config) == kErrorNone ? 0 : -1;
1808 }
1809
1810 int HWCDisplay::GetDisplayConfigCount(uint32_t *count) {
1811 return display_intf_->GetNumVariableInfoConfigs(count) == kErrorNone ? 0 : -1;
1812 }
1813
1814 int HWCDisplay::GetDisplayAttributesForConfig(int config,
1815 DisplayConfigVariableInfo *display_attributes) {
1816 return display_intf_->GetConfig(UINT32(config), display_attributes) == kErrorNone ? 0 : -1;
1817 }
1818
1819 bool HWCDisplay::SingleLayerUpdating(void) {
1820 uint32_t updating_count = 0;
1821
1822 for (uint i = 0; i < layer_stack_.layers.size(); i++) {
1823 auto layer = layer_stack_.layers.at(i);
1824 if (layer->flags.updating) {
1825 updating_count++;
1826 }
1827 }
1828
1829 return (updating_count == 1);
1830 }
1831
1832 bool HWCDisplay::IsLayerUpdating(const Layer *layer) {
1833 // Layer should be considered updating if
1834 // a) layer is in single buffer mode, or
1835 // b) valid dirty_regions(android specific hint for updating status), or
1836 // c) layer stack geometry has changed (TODO(user): Remove when SDM accepts
1837 // geometry_changed as bit fields).
1838 return (layer->flags.single_buffer || IsSurfaceUpdated(layer->dirty_regions) ||
1839 geometry_changes_);
1840 }
1841
1842 bool HWCDisplay::IsSurfaceUpdated(const std::vector<LayerRect> &dirty_regions) {
1843 // based on dirty_regions determine if its updating
1844 // dirty_rect count = 0 - whole layer - updating.
1845 // dirty_rect count = 1 or more valid rects - updating.
1846 // dirty_rect count = 1 with (0,0,0,0) - not updating.
1847 return (dirty_regions.empty() || IsValid(dirty_regions.at(0)));
1848 }
1849
1850 uint32_t HWCDisplay::SanitizeRefreshRate(uint32_t req_refresh_rate) {
1851 uint32_t refresh_rate = req_refresh_rate;
1852
1853 if (refresh_rate < min_refresh_rate_) {
1854 // Pick the next multiple of request which is within the range
1855 refresh_rate =
1856 (((min_refresh_rate_ / refresh_rate) + ((min_refresh_rate_ % refresh_rate) ? 1 : 0)) *
1857 refresh_rate);
1858 }
1859
1860 if (refresh_rate > max_refresh_rate_) {
1861 refresh_rate = max_refresh_rate_;
1862 }
1863
1864 return refresh_rate;
1865 }
1866
1867 DisplayClass HWCDisplay::GetDisplayClass() {
1868 return display_class_;
1869 }
1870
1871 void HWCDisplay::CloseAcquireFds() {
1872 for (auto hwc_layer : layer_set_) {
1873 auto layer = hwc_layer->GetSDMLayer();
1874 if (layer->input_buffer.acquire_fence_fd >= 0) {
1875 close(layer->input_buffer.acquire_fence_fd);
1876 layer->input_buffer.acquire_fence_fd = -1;
1877 }
1878 }
1879 int32_t &client_target_acquire_fence =
1880 client_target_->GetSDMLayer()->input_buffer.acquire_fence_fd;
1881 if (client_target_acquire_fence >= 0) {
1882 close(client_target_acquire_fence);
1883 client_target_acquire_fence = -1;
1884 }
1885 }
1886
1887 std::string HWCDisplay::Dump() {
1888 std::ostringstream os;
1889 os << "-------------------------------" << std::endl;
1890 os << "HWC2 display_id: " << id_ << std::endl;
1891 for (auto layer : layer_set_) {
1892 auto sdm_layer = layer->GetSDMLayer();
1893 auto transform = sdm_layer->transform;
1894 os << "layer: " << std::setw(4) << layer->GetId();
1895 os << " z: " << layer->GetZ();
1896 os << " compositon: " <<
1897 to_string(layer->GetClientRequestedCompositionType()).c_str();
1898 os << "/" <<
1899 to_string(layer->GetDeviceSelectedCompositionType()).c_str();
1900 os << " alpha: " << std::to_string(sdm_layer->plane_alpha).c_str();
1901 os << " format: " << std::setw(22) << GetFormatString(sdm_layer->input_buffer.format);
1902 os << " dataspace:" << std::hex << "0x" << std::setw(8) << std::setfill('0')
1903 << layer->GetLayerDataspace() << std::dec << std::setfill(' ');
1904 os << " transform: " << transform.rotation << "/" << transform.flip_horizontal <<
1905 "/"<< transform.flip_vertical;
1906 os << " buffer_id: " << std::hex << "0x" << sdm_layer->input_buffer.buffer_id << std::dec
1907 << std::endl;
1908 }
1909 if (color_mode_) {
1910 color_mode_->Dump(&os);
1911 }
1912 os << "-------------------------------" << std::endl;
1913 return os.str();
1914 }
1915
1916 bool HWCDisplay::CanSkipValidate() {
1917 // Layer Stack checks
1918 if (layer_stack_.flags.hdr_present && (tone_mapper_ && tone_mapper_->IsActive())) {
1919 return false;
1920 }
1921
1922 for (auto hwc_layer : layer_set_) {
1923 if (hwc_layer->NeedsValidation()) {
1924 return false;
1925 }
1926
1927 // Do not allow Skip Validate, if any layer needs GPU Composition.
1928 if (hwc_layer->GetDeviceSelectedCompositionType() == HWC2::Composition::Client) {
1929 return false;
1930 }
1931 }
1932
1933 return true;
1934 }
1935
1936 } // namespace sdm
1937