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