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