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