• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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