1 /*
2 * Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification, are permitted
5 * provided that the following conditions are met:
6 * * Redistributions of source code must retain the above copyright notice, this list of
7 * conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above copyright notice, this list of
9 * conditions and the following disclaimer in the documentation and/or other materials provided
10 * with the distribution.
11 * * Neither the name of The Linux Foundation nor the names of its contributors may be used to
12 * endorse or promote products derived from this software without specific prior written
13 * permission.
14 *
15 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
20 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
21 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */
24
25 #include <stdio.h>
26 #include <utils/constants.h>
27 #include <utils/debug.h>
28 #include <utils/formats.h>
29 #include <utils/rect.h>
30 #include <string>
31 #include <vector>
32 #include <algorithm>
33
34 #include "display_base.h"
35 #include "hw_info_interface.h"
36
37 #define __CLASS__ "DisplayBase"
38
39 namespace sdm {
40
41 // TODO(user): Have a single structure handle carries all the interface pointers and variables.
DisplayBase(DisplayType display_type,DisplayEventHandler * event_handler,HWDeviceType hw_device_type,BufferSyncHandler * buffer_sync_handler,CompManager * comp_manager,RotatorInterface * rotator_intf,HWInfoInterface * hw_info_intf)42 DisplayBase::DisplayBase(DisplayType display_type, DisplayEventHandler *event_handler,
43 HWDeviceType hw_device_type, BufferSyncHandler *buffer_sync_handler,
44 CompManager *comp_manager, RotatorInterface *rotator_intf,
45 HWInfoInterface *hw_info_intf)
46 : display_type_(display_type), event_handler_(event_handler), hw_device_type_(hw_device_type),
47 buffer_sync_handler_(buffer_sync_handler), comp_manager_(comp_manager),
48 rotator_intf_(rotator_intf), hw_info_intf_(hw_info_intf) {
49 }
50
Init()51 DisplayError DisplayBase::Init() {
52 lock_guard<recursive_mutex> obj(recursive_mutex_);
53 DisplayError error = kErrorNone;
54 hw_panel_info_ = HWPanelInfo();
55 hw_intf_->GetHWPanelInfo(&hw_panel_info_);
56
57 uint32_t active_index = 0;
58 hw_intf_->GetActiveConfig(&active_index);
59 hw_intf_->GetDisplayAttributes(active_index, &display_attributes_);
60 fb_config_ = display_attributes_;
61
62 error = hw_intf_->GetMixerAttributes(&mixer_attributes_);
63 if (error != kErrorNone) {
64 return error;
65 }
66
67 // Override x_pixels and y_pixels of frame buffer with mixer width and height
68 fb_config_.x_pixels = mixer_attributes_.width;
69 fb_config_.y_pixels = mixer_attributes_.height;
70
71 HWScaleLutInfo lut_info = {};
72 error = comp_manager_->GetScaleLutConfig(&lut_info);
73 if (error == kErrorNone) {
74 error = hw_intf_->SetScaleLutConfig(&lut_info);
75 }
76
77 if (error != kErrorNone) {
78 goto CleanupOnError;
79 }
80
81 error = comp_manager_->RegisterDisplay(display_type_, display_attributes_, hw_panel_info_,
82 mixer_attributes_, fb_config_, &display_comp_ctx_);
83 if (error != kErrorNone) {
84 goto CleanupOnError;
85 }
86
87 if (rotator_intf_) {
88 error = rotator_intf_->RegisterDisplay(display_type_, &display_rotator_ctx_);
89 if (error != kErrorNone) {
90 goto CleanupOnError;
91 }
92 }
93
94 if (hw_info_intf_) {
95 HWResourceInfo hw_resource_info = HWResourceInfo();
96 hw_info_intf_->GetHWResourceInfo(&hw_resource_info);
97 auto max_mixer_stages = hw_resource_info.num_blending_stages;
98 int property_value = Debug::GetMaxPipesPerMixer(display_type_);
99 if (property_value >= 0) {
100 max_mixer_stages = std::min(UINT32(property_value), hw_resource_info.num_blending_stages);
101 }
102 DisplayBase::SetMaxMixerStages(max_mixer_stages);
103 }
104
105 color_mgr_ = ColorManagerProxy::CreateColorManagerProxy(display_type_, hw_intf_,
106 display_attributes_, hw_panel_info_);
107 if (!color_mgr_) {
108 DLOGW("Unable to create ColorManagerProxy for display = %d", display_type_);
109 }
110
111 return kErrorNone;
112
113 CleanupOnError:
114 if (display_comp_ctx_) {
115 comp_manager_->UnregisterDisplay(display_comp_ctx_);
116 }
117
118 return error;
119 }
120
Deinit()121 DisplayError DisplayBase::Deinit() {
122 lock_guard<recursive_mutex> obj(recursive_mutex_);
123 if (rotator_intf_) {
124 rotator_intf_->UnregisterDisplay(display_rotator_ctx_);
125 }
126
127 if (color_mgr_) {
128 delete color_mgr_;
129 color_mgr_ = NULL;
130 }
131
132 comp_manager_->UnregisterDisplay(display_comp_ctx_);
133
134 HWEventsInterface::Destroy(hw_events_intf_);
135
136 return kErrorNone;
137 }
138
ValidateGPUTarget(LayerStack * layer_stack)139 DisplayError DisplayBase::ValidateGPUTarget(LayerStack *layer_stack) {
140 uint32_t i = 0;
141 std::vector<Layer *>layers = layer_stack->layers;
142
143 // TODO(user): Remove this check once we have query display attributes on virtual display
144 if (display_type_ == kVirtual) {
145 return kErrorNone;
146 }
147 uint32_t layer_count = UINT32(layers.size());
148 while ((i < layer_count) && (layers.at(i)->composition != kCompositionGPUTarget)) {
149 i++;
150 }
151
152 if (i >= layer_count) {
153 DLOGE("Either layer count is zero or GPU target layer is not present");
154 return kErrorParameters;
155 }
156
157 uint32_t gpu_target_index = i;
158
159 // Check GPU target layer
160 Layer *gpu_target_layer = layers.at(gpu_target_index);
161
162 if (!IsValid(gpu_target_layer->src_rect)) {
163 DLOGE("Invalid src rect for GPU target layer");
164 return kErrorParameters;
165 }
166
167 if (!IsValid(gpu_target_layer->dst_rect)) {
168 DLOGE("Invalid dst rect for GPU target layer");
169 return kErrorParameters;
170 }
171
172 float layer_mixer_width = FLOAT(mixer_attributes_.width);
173 float layer_mixer_height = FLOAT(mixer_attributes_.height);
174 float fb_width = FLOAT(fb_config_.x_pixels);
175 float fb_height = FLOAT(fb_config_.y_pixels);
176 LayerRect src_domain = (LayerRect){0.0f, 0.0f, fb_width, fb_height};
177 LayerRect dst_domain = (LayerRect){0.0f, 0.0f, layer_mixer_width, layer_mixer_height};
178 LayerRect out_rect = gpu_target_layer->dst_rect;
179
180 ScaleRect(src_domain, dst_domain, gpu_target_layer->dst_rect, &out_rect);
181
182 auto gpu_target_layer_dst_xpixels = out_rect.right - out_rect.left;
183 auto gpu_target_layer_dst_ypixels = out_rect.bottom - out_rect.top;
184
185 if (gpu_target_layer_dst_xpixels > mixer_attributes_.width ||
186 gpu_target_layer_dst_ypixels > mixer_attributes_.height) {
187 DLOGE("GPU target layer dst rect is not with in limits gpu wxh %fx%f mixer wxh %dx%d",
188 gpu_target_layer_dst_xpixels, gpu_target_layer_dst_ypixels, mixer_attributes_.width,
189 mixer_attributes_.height);
190 return kErrorParameters;
191 }
192
193 return kErrorNone;
194 }
195
Prepare(LayerStack * layer_stack)196 DisplayError DisplayBase::Prepare(LayerStack *layer_stack) {
197 lock_guard<recursive_mutex> obj(recursive_mutex_);
198 DisplayError error = kErrorNone;
199
200 if (!active_) {
201 return kErrorPermission;
202 }
203
204 if (!layer_stack) {
205 return kErrorParameters;
206 }
207
208 error = ValidateGPUTarget(layer_stack);
209 if (error != kErrorNone) {
210 return error;
211 }
212
213 if (color_mgr_ && color_mgr_->NeedsPartialUpdateDisable()) {
214 DisablePartialUpdateOneFrame();
215 }
216
217 if (partial_update_control_ == false || disable_pu_one_frame_) {
218 comp_manager_->ControlPartialUpdate(display_comp_ctx_, false /* enable */);
219 disable_pu_one_frame_ = false;
220 }
221
222 // Clean hw layers for reuse.
223 hw_layers_ = HWLayers();
224 hw_layers_.info.stack = layer_stack;
225 hw_layers_.output_compression = 1.0f;
226
227 comp_manager_->PrePrepare(display_comp_ctx_, &hw_layers_);
228 while (true) {
229 error = comp_manager_->Prepare(display_comp_ctx_, &hw_layers_);
230 if (error != kErrorNone) {
231 break;
232 }
233
234 if (IsRotationRequired(&hw_layers_)) {
235 if (!rotator_intf_) {
236 continue;
237 }
238 error = rotator_intf_->Prepare(display_rotator_ctx_, &hw_layers_);
239 } else {
240 // Release all the previous rotator sessions.
241 if (rotator_intf_) {
242 error = rotator_intf_->Purge(display_rotator_ctx_);
243 }
244 }
245
246 if (error == kErrorNone) {
247 error = hw_intf_->Validate(&hw_layers_);
248 if (error == kErrorNone) {
249 // Strategy is successful now, wait for Commit().
250 pending_commit_ = true;
251 break;
252 }
253 if (error == kErrorShutDown) {
254 comp_manager_->PostPrepare(display_comp_ctx_, &hw_layers_);
255 return error;
256 }
257 }
258 }
259
260 comp_manager_->PostPrepare(display_comp_ctx_, &hw_layers_);
261
262 return error;
263 }
264
Commit(LayerStack * layer_stack)265 DisplayError DisplayBase::Commit(LayerStack *layer_stack) {
266 lock_guard<recursive_mutex> obj(recursive_mutex_);
267 DisplayError error = kErrorNone;
268
269 if (!active_) {
270 pending_commit_ = false;
271 return kErrorPermission;
272 }
273
274 if (!layer_stack) {
275 return kErrorParameters;
276 }
277
278 if (!pending_commit_) {
279 DLOGE("Commit: Corresponding Prepare() is not called for display = %d", display_type_);
280 return kErrorUndefined;
281 }
282
283 pending_commit_ = false;
284
285 // Layer stack attributes has changed, need to Reconfigure, currently in use for Hybrid Comp
286 if (layer_stack->flags.attributes_changed) {
287 error = comp_manager_->ReConfigure(display_comp_ctx_, &hw_layers_);
288 if (error != kErrorNone) {
289 return error;
290 }
291
292 error = hw_intf_->Validate(&hw_layers_);
293 if (error != kErrorNone) {
294 return error;
295 }
296 }
297
298 if (rotator_intf_ && IsRotationRequired(&hw_layers_)) {
299 error = rotator_intf_->Commit(display_rotator_ctx_, &hw_layers_);
300 if (error != kErrorNone) {
301 return error;
302 }
303 }
304
305 // check if feature list cache is dirty and pending.
306 // If dirty, need program to hardware blocks.
307 if (color_mgr_)
308 error = color_mgr_->Commit();
309 if (error != kErrorNone) { // won't affect this execution path.
310 DLOGW("ColorManager::Commit(...) isn't working");
311 }
312
313 error = hw_intf_->Commit(&hw_layers_);
314 if (error != kErrorNone) {
315 return error;
316 }
317
318 if (rotator_intf_ && IsRotationRequired(&hw_layers_)) {
319 error = rotator_intf_->PostCommit(display_rotator_ctx_, &hw_layers_);
320 if (error != kErrorNone) {
321 return error;
322 }
323 }
324
325 if (partial_update_control_) {
326 comp_manager_->ControlPartialUpdate(display_comp_ctx_, true /* enable */);
327 }
328
329 error = comp_manager_->PostCommit(display_comp_ctx_, &hw_layers_);
330 if (error != kErrorNone) {
331 return error;
332 }
333
334 return kErrorNone;
335 }
336
Flush()337 DisplayError DisplayBase::Flush() {
338 lock_guard<recursive_mutex> obj(recursive_mutex_);
339 DisplayError error = kErrorNone;
340
341 if (!active_) {
342 return kErrorPermission;
343 }
344
345 hw_layers_.info.count = 0;
346 error = hw_intf_->Flush();
347 if (error == kErrorNone) {
348 // Release all the rotator sessions.
349 if (rotator_intf_) {
350 error = rotator_intf_->Purge(display_rotator_ctx_);
351 if (error != kErrorNone) {
352 DLOGE("Rotator purge failed for display %d", display_type_);
353 return error;
354 }
355 }
356
357 comp_manager_->Purge(display_comp_ctx_);
358
359 pending_commit_ = false;
360 } else {
361 DLOGW("Unable to flush display = %d", display_type_);
362 }
363
364 return error;
365 }
366
GetDisplayState(DisplayState * state)367 DisplayError DisplayBase::GetDisplayState(DisplayState *state) {
368 lock_guard<recursive_mutex> obj(recursive_mutex_);
369 if (!state) {
370 return kErrorParameters;
371 }
372
373 *state = state_;
374 return kErrorNone;
375 }
376
GetNumVariableInfoConfigs(uint32_t * count)377 DisplayError DisplayBase::GetNumVariableInfoConfigs(uint32_t *count) {
378 lock_guard<recursive_mutex> obj(recursive_mutex_);
379 return hw_intf_->GetNumDisplayAttributes(count);
380 }
381
GetConfig(uint32_t index,DisplayConfigVariableInfo * variable_info)382 DisplayError DisplayBase::GetConfig(uint32_t index, DisplayConfigVariableInfo *variable_info) {
383 lock_guard<recursive_mutex> obj(recursive_mutex_);
384 HWDisplayAttributes attrib;
385 if (hw_intf_->GetDisplayAttributes(index, &attrib) == kErrorNone) {
386 *variable_info = attrib;
387 return kErrorNone;
388 }
389
390 return kErrorNotSupported;
391 }
392
GetActiveConfig(uint32_t * index)393 DisplayError DisplayBase::GetActiveConfig(uint32_t *index) {
394 lock_guard<recursive_mutex> obj(recursive_mutex_);
395 return hw_intf_->GetActiveConfig(index);
396 }
397
GetVSyncState(bool * enabled)398 DisplayError DisplayBase::GetVSyncState(bool *enabled) {
399 lock_guard<recursive_mutex> obj(recursive_mutex_);
400 if (!enabled) {
401 return kErrorParameters;
402 }
403
404 *enabled = vsync_enable_;
405
406 return kErrorNone;
407 }
408
SetDisplayState(DisplayState state)409 DisplayError DisplayBase::SetDisplayState(DisplayState state) {
410 lock_guard<recursive_mutex> obj(recursive_mutex_);
411 DisplayError error = kErrorNone;
412 bool active = false;
413
414 DLOGI("Set state = %d, display %d", state, display_type_);
415
416 if (state == state_) {
417 DLOGI("Same state transition is requested.");
418 return kErrorNone;
419 }
420
421 switch (state) {
422 case kStateOff:
423 hw_layers_.info.count = 0;
424 error = hw_intf_->Flush();
425 if (error == kErrorNone) {
426 // Release all the rotator sessions.
427 if (rotator_intf_) {
428 error = rotator_intf_->Purge(display_rotator_ctx_);
429 if (error != kErrorNone) {
430 DLOGE("Rotator purge failed for display %d", display_type_);
431 return error;
432 }
433 }
434
435 comp_manager_->Purge(display_comp_ctx_);
436
437 error = hw_intf_->PowerOff();
438 }
439 break;
440
441 case kStateOn:
442 error = hw_intf_->PowerOn();
443 active = true;
444 break;
445
446 case kStateDoze:
447 error = hw_intf_->Doze();
448 active = true;
449 break;
450
451 case kStateDozeSuspend:
452 error = hw_intf_->DozeSuspend();
453 break;
454
455 case kStateStandby:
456 error = hw_intf_->Standby();
457 break;
458
459 default:
460 DLOGE("Spurious state = %d transition requested.", state);
461 break;
462 }
463
464 if (error == kErrorNone) {
465 active_ = active;
466 state_ = state;
467 }
468
469 return error;
470 }
471
SetActiveConfig(uint32_t index)472 DisplayError DisplayBase::SetActiveConfig(uint32_t index) {
473 lock_guard<recursive_mutex> obj(recursive_mutex_);
474 DisplayError error = kErrorNone;
475 uint32_t active_index = 0;
476
477 hw_intf_->GetActiveConfig(&active_index);
478
479 if (active_index == index) {
480 return kErrorNone;
481 }
482
483 error = hw_intf_->SetDisplayAttributes(index);
484 if (error != kErrorNone) {
485 return error;
486 }
487
488 return ReconfigureDisplay();
489 }
490
SetMaxMixerStages(uint32_t max_mixer_stages)491 DisplayError DisplayBase::SetMaxMixerStages(uint32_t max_mixer_stages) {
492 lock_guard<recursive_mutex> obj(recursive_mutex_);
493 DisplayError error = kErrorNone;
494
495 error = comp_manager_->SetMaxMixerStages(display_comp_ctx_, max_mixer_stages);
496
497 if (error == kErrorNone) {
498 max_mixer_stages_ = max_mixer_stages;
499 }
500
501 return error;
502 }
503
AppendDump(char * buffer,uint32_t length)504 void DisplayBase::AppendDump(char *buffer, uint32_t length) {
505 lock_guard<recursive_mutex> obj(recursive_mutex_);
506 HWDisplayAttributes attrib;
507 uint32_t active_index = 0;
508 uint32_t num_modes = 0;
509 hw_intf_->GetNumDisplayAttributes(&num_modes);
510 hw_intf_->GetActiveConfig(&active_index);
511 hw_intf_->GetDisplayAttributes(active_index, &attrib);
512
513 DumpImpl::AppendString(buffer, length, "\n-----------------------");
514 DumpImpl::AppendString(buffer, length, "\ndevice type: %u", display_type_);
515 DumpImpl::AppendString(buffer, length, "\nstate: %u, vsync on: %u, max. mixer stages: %u",
516 state_, INT(vsync_enable_), max_mixer_stages_);
517 DumpImpl::AppendString(buffer, length, "\nnum configs: %u, active config index: %u",
518 num_modes, active_index);
519
520 DisplayConfigVariableInfo &info = attrib;
521
522 uint32_t num_hw_layers = 0;
523 if (hw_layers_.info.stack) {
524 num_hw_layers = hw_layers_.info.count;
525 }
526
527 if (num_hw_layers == 0) {
528 DumpImpl::AppendString(buffer, length, "\nNo hardware layers programmed");
529 return;
530 }
531
532 LayerBuffer *out_buffer = hw_layers_.info.stack->output_buffer;
533 if (out_buffer) {
534 DumpImpl::AppendString(buffer, length, "\nres:%u x %u format: %s", out_buffer->width,
535 out_buffer->height, GetFormatString(out_buffer->format));
536 } else {
537 DumpImpl::AppendString(buffer, length, "\nres:%u x %u, dpi:%.2f x %.2f, fps:%u,"
538 "vsync period: %u", info.x_pixels, info.y_pixels, info.x_dpi,
539 info.y_dpi, info.fps, info.vsync_period_ns);
540 }
541
542 DumpImpl::AppendString(buffer, length, "\n");
543
544 HWLayersInfo &layer_info = hw_layers_.info;
545 LayerRect &l_roi = layer_info.left_partial_update;
546 LayerRect &r_roi = layer_info.right_partial_update;
547 DumpImpl::AppendString(buffer, length, "\nROI(L T R B) : LEFT(%d %d %d %d)", INT(l_roi.left),
548 INT(l_roi.top), INT(l_roi.right), INT(l_roi.bottom));
549
550 if (IsValid(r_roi)) {
551 DumpImpl::AppendString(buffer, length, ", RIGHT(%d %d %d %d)", INT(r_roi.left),
552 INT(r_roi.top), INT(r_roi.right), INT(r_roi.bottom));
553 }
554
555 const char *header = "\n| Idx | Comp Type | Split | WB | Pipe | W x H | Format | Src Rect (L T R B) | Dst Rect (L T R B) | Z | Flags | Deci(HxV) | CS |"; //NOLINT
556 const char *newline = "\n|-----|-------------|--------|----|-------|-------------|--------------------------|---------------------|---------------------|----|------------|-----------|----|"; //NOLINT
557 const char *format = "\n| %3s | %11s " "| %6s " "| %2s | 0x%03x | %4d x %4d | %24s " "| %4d %4d %4d %4d " "| %4d %4d %4d %4d " "| %2s | %10s " "| %9s | %2s |"; //NOLINT
558
559 DumpImpl::AppendString(buffer, length, "\n");
560 DumpImpl::AppendString(buffer, length, newline);
561 DumpImpl::AppendString(buffer, length, header);
562 DumpImpl::AppendString(buffer, length, newline);
563
564 for (uint32_t i = 0; i < num_hw_layers; i++) {
565 uint32_t layer_index = hw_layers_.info.index[i];
566 Layer *layer = hw_layers_.info.stack->layers.at(layer_index);
567 LayerBuffer *input_buffer = layer->input_buffer;
568 HWLayerConfig &layer_config = hw_layers_.config[i];
569 HWRotatorSession &hw_rotator_session = layer_config.hw_rotator_session;
570
571 char idx[8] = { 0 };
572 const char *comp_type = GetName(layer->composition);
573 const char *buffer_format = GetFormatString(input_buffer->format);
574 const char *rotate_split[2] = { "Rot-1", "Rot-2" };
575 const char *comp_split[2] = { "Comp-1", "Comp-2" };
576
577 snprintf(idx, sizeof(idx), "%d", layer_index);
578
579 for (uint32_t count = 0; count < hw_rotator_session.hw_block_count; count++) {
580 char writeback_id[8] = { 0 };
581 HWRotateInfo &rotate = hw_rotator_session.hw_rotate_info[count];
582 LayerRect &src_roi = rotate.src_roi;
583 LayerRect &dst_roi = rotate.dst_roi;
584
585 snprintf(writeback_id, sizeof(writeback_id), "%d", rotate.writeback_id);
586
587 DumpImpl::AppendString(buffer, length, format, idx, comp_type, rotate_split[count],
588 writeback_id, rotate.pipe_id, input_buffer->width,
589 input_buffer->height, buffer_format, INT(src_roi.left),
590 INT(src_roi.top), INT(src_roi.right), INT(src_roi.bottom),
591 INT(dst_roi.left), INT(dst_roi.top), INT(dst_roi.right),
592 INT(dst_roi.bottom), "-", "- ", "- ", "-");
593
594 // print the below only once per layer block, fill with spaces for rest.
595 idx[0] = 0;
596 comp_type = "";
597 }
598
599 if (hw_rotator_session.hw_block_count > 0) {
600 input_buffer = &hw_rotator_session.output_buffer;
601 buffer_format = GetFormatString(input_buffer->format);
602 }
603
604 for (uint32_t count = 0; count < 2; count++) {
605 char decimation[16] = { 0 };
606 char flags[16] = { 0 };
607 char z_order[8] = { 0 };
608 char csc[8] = { 0 };
609
610 HWPipeInfo &pipe = (count == 0) ? layer_config.left_pipe : layer_config.right_pipe;
611
612 if (!pipe.valid) {
613 continue;
614 }
615
616 LayerRect &src_roi = pipe.src_roi;
617 LayerRect &dst_roi = pipe.dst_roi;
618
619 snprintf(z_order, sizeof(z_order), "%d", pipe.z_order);
620 snprintf(flags, sizeof(flags), "0x%08x", layer->flags.flags);
621 snprintf(decimation, sizeof(decimation), "%3d x %3d", pipe.horizontal_decimation,
622 pipe.vertical_decimation);
623 snprintf(csc, sizeof(csc), "%d", layer->input_buffer->csc);
624
625 DumpImpl::AppendString(buffer, length, format, idx, comp_type, comp_split[count],
626 "-", pipe.pipe_id, input_buffer->width, input_buffer->height,
627 buffer_format, INT(src_roi.left), INT(src_roi.top),
628 INT(src_roi.right), INT(src_roi.bottom), INT(dst_roi.left),
629 INT(dst_roi.top), INT(dst_roi.right), INT(dst_roi.bottom),
630 z_order, flags, decimation, csc);
631
632 // print the below only once per layer block, fill with spaces for rest.
633 idx[0] = 0;
634 comp_type = "";
635 }
636
637 DumpImpl::AppendString(buffer, length, newline);
638 }
639 }
640
IsRotationRequired(HWLayers * hw_layers)641 bool DisplayBase::IsRotationRequired(HWLayers *hw_layers) {
642 lock_guard<recursive_mutex> obj(recursive_mutex_);
643 HWLayersInfo &layer_info = hw_layers->info;
644
645 for (uint32_t i = 0; i < layer_info.count; i++) {
646 HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
647
648 if (hw_rotator_session->hw_block_count) {
649 return true;
650 }
651 }
652
653 return false;
654 }
655
GetName(const LayerComposition & composition)656 const char * DisplayBase::GetName(const LayerComposition &composition) {
657 switch (composition) {
658 case kCompositionGPU: return "GPU";
659 case kCompositionSDE: return "SDE";
660 case kCompositionHWCursor: return "CURSOR";
661 case kCompositionHybrid: return "HYBRID";
662 case kCompositionBlit: return "BLIT";
663 case kCompositionGPUTarget: return "GPU_TARGET";
664 case kCompositionBlitTarget: return "BLIT_TARGET";
665 default: return "UNKNOWN";
666 }
667 }
668
ColorSVCRequestRoute(const PPDisplayAPIPayload & in_payload,PPDisplayAPIPayload * out_payload,PPPendingParams * pending_action)669 DisplayError DisplayBase::ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload,
670 PPDisplayAPIPayload *out_payload,
671 PPPendingParams *pending_action) {
672 lock_guard<recursive_mutex> obj(recursive_mutex_);
673 if (color_mgr_)
674 return color_mgr_->ColorSVCRequestRoute(in_payload, out_payload, pending_action);
675 else
676 return kErrorParameters;
677 }
678
GetColorModeCount(uint32_t * mode_count)679 DisplayError DisplayBase::GetColorModeCount(uint32_t *mode_count) {
680 lock_guard<recursive_mutex> obj(recursive_mutex_);
681 if (!mode_count) {
682 return kErrorParameters;
683 }
684
685 if (!color_mgr_) {
686 return kErrorNotSupported;
687 }
688
689 DisplayError error = color_mgr_->ColorMgrGetNumOfModes(&num_color_modes_);
690 if (error != kErrorNone || !num_color_modes_) {
691 return kErrorNotSupported;
692 }
693
694 DLOGV_IF(kTagQDCM, "Number of modes from color manager = %d", num_color_modes_);
695 *mode_count = num_color_modes_;
696
697 return kErrorNone;
698 }
699
GetColorModes(uint32_t * mode_count,std::vector<std::string> * color_modes)700 DisplayError DisplayBase::GetColorModes(uint32_t *mode_count,
701 std::vector<std::string> *color_modes) {
702 lock_guard<recursive_mutex> obj(recursive_mutex_);
703 if (!mode_count || !color_modes) {
704 return kErrorParameters;
705 }
706
707 if (!color_mgr_) {
708 return kErrorNotSupported;
709 }
710
711 if (!color_modes_.size()) {
712 color_modes_.resize(num_color_modes_);
713
714 DisplayError error = color_mgr_->ColorMgrGetModes(&num_color_modes_, color_modes_.data());
715 if (error != kErrorNone) {
716 DLOGE("Failed");
717 return error;
718 }
719
720 for (uint32_t i = 0; i < num_color_modes_; i++) {
721 DLOGV_IF(kTagQDCM, "Color Mode[%d]: Name = %s mode_id = %d", i, color_modes_[i].name,
722 color_modes_[i].id);
723 auto it = color_mode_map_.find(color_modes_[i].name);
724 if (it != color_mode_map_.end()) {
725 if (it->second->id < color_modes_[i].id) {
726 color_mode_map_.erase(it);
727 color_mode_map_.insert(std::make_pair(color_modes_[i].name, &color_modes_[i]));
728 }
729 } else {
730 color_mode_map_.insert(std::make_pair(color_modes_[i].name, &color_modes_[i]));
731 }
732 }
733 }
734
735 for (uint32_t i = 0; i < num_color_modes_; i++) {
736 DLOGV_IF(kTagQDCM, "Color Mode[%d]: Name = %s mode_id = %d", i, color_modes_[i].name,
737 color_modes_[i].id);
738 color_modes->at(i) = color_modes_[i].name;
739 }
740
741 return kErrorNone;
742 }
743
SetColorMode(const std::string & color_mode)744 DisplayError DisplayBase::SetColorMode(const std::string &color_mode) {
745 lock_guard<recursive_mutex> obj(recursive_mutex_);
746 if (!color_mgr_) {
747 return kErrorNotSupported;
748 }
749
750 DLOGV_IF(kTagQDCM, "Color Mode = %s", color_mode.c_str());
751
752 ColorModeMap::iterator it = color_mode_map_.find(color_mode);
753 if (it == color_mode_map_.end()) {
754 DLOGE("Failed: Unknown Mode : %s", color_mode.c_str());
755 return kErrorNotSupported;
756 }
757
758 SDEDisplayMode *sde_display_mode = it->second;
759
760 DLOGD("Color Mode Name = %s corresponding mode_id = %d", sde_display_mode->name,
761 sde_display_mode->id);
762 DisplayError error = kErrorNone;
763 error = color_mgr_->ColorMgrSetMode(sde_display_mode->id);
764 if (error != kErrorNone) {
765 DLOGE("Failed for mode id = %d", sde_display_mode->id);
766 return error;
767 }
768
769 return error;
770 }
771
SetColorTransform(const uint32_t length,const double * color_transform)772 DisplayError DisplayBase::SetColorTransform(const uint32_t length, const double *color_transform) {
773 lock_guard<recursive_mutex> obj(recursive_mutex_);
774 if (!color_mgr_) {
775 return kErrorNotSupported;
776 }
777
778 if (!color_transform) {
779 return kErrorParameters;
780 }
781
782 return color_mgr_->ColorMgrSetColorTransform(length, color_transform);
783 }
784
ApplyDefaultDisplayMode()785 DisplayError DisplayBase::ApplyDefaultDisplayMode() {
786 lock_guard<recursive_mutex> obj(recursive_mutex_);
787 if (color_mgr_)
788 return color_mgr_->ApplyDefaultDisplayMode();
789 else
790 return kErrorParameters;
791 }
792
SetCursorPosition(int x,int y)793 DisplayError DisplayBase::SetCursorPosition(int x, int y) {
794 lock_guard<recursive_mutex> obj(recursive_mutex_);
795 if (state_ != kStateOn) {
796 return kErrorNotSupported;
797 }
798
799 DisplayError error = comp_manager_->ValidateCursorPosition(display_comp_ctx_, &hw_layers_, x, y);
800 if (error == kErrorNone) {
801 return hw_intf_->SetCursorPosition(&hw_layers_, x, y);
802 }
803
804 return kErrorNone;
805 }
806
GetRefreshRateRange(uint32_t * min_refresh_rate,uint32_t * max_refresh_rate)807 DisplayError DisplayBase::GetRefreshRateRange(uint32_t *min_refresh_rate,
808 uint32_t *max_refresh_rate) {
809 lock_guard<recursive_mutex> obj(recursive_mutex_);
810 // The min and max refresh rates will be same when the HWPanelInfo does not contain valid rates.
811 // Usually for secondary displays, command mode panels
812 HWDisplayAttributes display_attributes;
813 uint32_t active_index = 0;
814 hw_intf_->GetActiveConfig(&active_index);
815 DisplayError error = hw_intf_->GetDisplayAttributes(active_index, &display_attributes);
816 if (error) {
817 return error;
818 }
819
820 *min_refresh_rate = display_attributes.fps;
821 *max_refresh_rate = display_attributes.fps;
822
823 return error;
824 }
825
SetVSyncState(bool enable)826 DisplayError DisplayBase::SetVSyncState(bool enable) {
827 lock_guard<recursive_mutex> obj(recursive_mutex_);
828 DisplayError error = kErrorNone;
829 if (vsync_enable_ != enable) {
830 error = hw_intf_->SetVSyncState(enable);
831 if (error == kErrorNone) {
832 vsync_enable_ = enable;
833 }
834 }
835 return error;
836 }
837
ReconfigureDisplay()838 DisplayError DisplayBase::ReconfigureDisplay() {
839 lock_guard<recursive_mutex> obj(recursive_mutex_);
840 DisplayError error = kErrorNone;
841 HWDisplayAttributes display_attributes;
842 HWMixerAttributes mixer_attributes;
843 HWPanelInfo hw_panel_info;
844 uint32_t active_index = 0;
845
846 error = hw_intf_->GetActiveConfig(&active_index);
847 if (error != kErrorNone) {
848 return error;
849 }
850
851 error = hw_intf_->GetDisplayAttributes(active_index, &display_attributes);
852 if (error != kErrorNone) {
853 return error;
854 }
855
856 error = hw_intf_->GetMixerAttributes(&mixer_attributes);
857 if (error != kErrorNone) {
858 return error;
859 }
860
861 error = hw_intf_->GetHWPanelInfo(&hw_panel_info);
862 if (error != kErrorNone) {
863 return error;
864 }
865
866 if (display_attributes == display_attributes_ && mixer_attributes == mixer_attributes_ &&
867 hw_panel_info == hw_panel_info_) {
868 return kErrorNone;
869 }
870
871 error = comp_manager_->ReconfigureDisplay(display_comp_ctx_, display_attributes, hw_panel_info,
872 mixer_attributes, fb_config_);
873 if (error != kErrorNone) {
874 return error;
875 }
876
877 if (mixer_attributes != mixer_attributes_) {
878 DisablePartialUpdateOneFrame();
879 }
880
881 display_attributes_ = display_attributes;
882 mixer_attributes_ = mixer_attributes;
883 hw_panel_info_ = hw_panel_info;
884
885 return kErrorNone;
886 }
887
SetMixerResolution(uint32_t width,uint32_t height)888 DisplayError DisplayBase::SetMixerResolution(uint32_t width, uint32_t height) {
889 lock_guard<recursive_mutex> obj(recursive_mutex_);
890 return ReconfigureMixer(width, height);
891 }
892
GetMixerResolution(uint32_t * width,uint32_t * height)893 DisplayError DisplayBase::GetMixerResolution(uint32_t *width, uint32_t *height) {
894 lock_guard<recursive_mutex> obj(recursive_mutex_);
895 if (!width || !height) {
896 return kErrorParameters;
897 }
898
899 *width = mixer_attributes_.width;
900 *height = mixer_attributes_.height;
901
902 return kErrorNone;
903 }
904
ReconfigureMixer(uint32_t width,uint32_t height)905 DisplayError DisplayBase::ReconfigureMixer(uint32_t width, uint32_t height) {
906 lock_guard<recursive_mutex> obj(recursive_mutex_);
907 DisplayError error = kErrorNone;
908
909 HWMixerAttributes mixer_attributes;
910 mixer_attributes.width = width;
911 mixer_attributes.height = height;
912
913 error = hw_intf_->SetMixerAttributes(mixer_attributes);
914 if (error != kErrorNone) {
915 return error;
916 }
917
918 return ReconfigureDisplay();
919 }
920
NeedsMixerReconfiguration(LayerStack * layer_stack,uint32_t * new_mixer_width,uint32_t * new_mixer_height)921 bool DisplayBase::NeedsMixerReconfiguration(LayerStack *layer_stack, uint32_t *new_mixer_width,
922 uint32_t *new_mixer_height) {
923 lock_guard<recursive_mutex> obj(recursive_mutex_);
924 uint32_t layer_count = UINT32(layer_stack->layers.size());
925
926 uint32_t fb_width = fb_config_.x_pixels;
927 uint32_t fb_height = fb_config_.y_pixels;
928 uint32_t fb_area = fb_width * fb_height;
929 LayerRect fb_rect = (LayerRect) {0.0f, 0.0f, FLOAT(fb_width), FLOAT(fb_height)};
930 uint32_t mixer_width = mixer_attributes_.width;
931 uint32_t mixer_height = mixer_attributes_.height;
932
933 RectOrientation fb_orientation = GetOrientation(fb_rect);
934 uint32_t max_layer_area = 0;
935 uint32_t max_area_layer_index = 0;
936 std::vector<Layer *> layers = layer_stack->layers;
937
938 for (uint32_t i = 0; i < layer_count; i++) {
939 Layer *layer = layers.at(i);
940 LayerBuffer *layer_buffer = layer->input_buffer;
941
942 if (!layer_buffer->flags.video) {
943 continue;
944 }
945
946 uint32_t layer_width = UINT32(layer->src_rect.right - layer->src_rect.left);
947 uint32_t layer_height = UINT32(layer->src_rect.bottom - layer->src_rect.top);
948 uint32_t layer_area = layer_width * layer_height;
949
950 if (layer_area > max_layer_area) {
951 max_layer_area = layer_area;
952 max_area_layer_index = i;
953 }
954 }
955
956 if (max_layer_area > fb_area) {
957 Layer *layer = layers.at(max_area_layer_index);
958
959 uint32_t layer_width = UINT32(layer->src_rect.right - layer->src_rect.left);
960 uint32_t layer_height = UINT32(layer->src_rect.bottom - layer->src_rect.top);
961 LayerRect layer_rect = (LayerRect){0.0f, 0.0f, FLOAT(layer_width), FLOAT(layer_height)};
962
963 RectOrientation layer_orientation = GetOrientation(layer_rect);
964 if (layer_orientation != kOrientationUnknown &&
965 fb_orientation != kOrientationUnknown) {
966 if (layer_orientation != fb_orientation) {
967 std::swap(layer_width, layer_height);
968 }
969 }
970
971 // Align the width and height according to fb's aspect ratio
972 layer_width = UINT32((FLOAT(fb_width) / FLOAT(fb_height)) * layer_height);
973
974 *new_mixer_width = layer_width;
975 *new_mixer_height = layer_height;
976
977 return true;
978 } else {
979 if (fb_width != mixer_width || fb_height != mixer_height) {
980 *new_mixer_width = fb_width;
981 *new_mixer_height = fb_height;
982
983 return true;
984 }
985 }
986
987 return false;
988 }
989
SetFrameBufferConfig(const DisplayConfigVariableInfo & variable_info)990 DisplayError DisplayBase::SetFrameBufferConfig(const DisplayConfigVariableInfo &variable_info) {
991 lock_guard<recursive_mutex> obj(recursive_mutex_);
992 uint32_t width = variable_info.x_pixels;
993 uint32_t height = variable_info.y_pixels;
994
995 if (width == 0 || height == 0) {
996 DLOGE("Unsupported resolution: (%dx%d)", width, height);
997 return kErrorParameters;
998 }
999
1000 // Create rects to represent the new source and destination crops
1001 LayerRect crop = LayerRect(0, 0, FLOAT(width), FLOAT(height));
1002 LayerRect dst = LayerRect(0, 0, FLOAT(mixer_attributes_.width), FLOAT(mixer_attributes_.height));
1003 // Set rotate90 to false since this is taken care of during regular composition.
1004 bool rotate90 = false;
1005
1006 DisplayError error = comp_manager_->ValidateScaling(crop, dst, rotate90);
1007 if (error != kErrorNone) {
1008 DLOGE("Unsupported resolution: (%dx%d)", width, height);
1009 return kErrorParameters;
1010 }
1011
1012 error = comp_manager_->ReconfigureDisplay(display_comp_ctx_, display_attributes_, hw_panel_info_,
1013 mixer_attributes_, variable_info);
1014 if (error != kErrorNone) {
1015 return error;
1016 }
1017
1018 fb_config_.x_pixels = width;
1019 fb_config_.y_pixels = height;
1020
1021 DLOGI("New framebuffer resolution (%dx%d)", fb_config_.x_pixels, fb_config_.y_pixels);
1022
1023 return kErrorNone;
1024 }
1025
GetFrameBufferConfig(DisplayConfigVariableInfo * variable_info)1026 DisplayError DisplayBase::GetFrameBufferConfig(DisplayConfigVariableInfo *variable_info) {
1027 lock_guard<recursive_mutex> obj(recursive_mutex_);
1028 if (!variable_info) {
1029 return kErrorParameters;
1030 }
1031
1032 *variable_info = fb_config_;
1033
1034 return kErrorNone;
1035 }
1036
SetDetailEnhancerData(const DisplayDetailEnhancerData & de_data)1037 DisplayError DisplayBase::SetDetailEnhancerData(const DisplayDetailEnhancerData &de_data) {
1038 lock_guard<recursive_mutex> obj(recursive_mutex_);
1039 DisplayError error = comp_manager_->SetDetailEnhancerData(display_comp_ctx_, de_data);
1040 if (error != kErrorNone) {
1041 return error;
1042 }
1043
1044 DisablePartialUpdateOneFrame();
1045
1046 return kErrorNone;
1047 }
1048
1049 } // namespace sdm
1050