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