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