1/*
2* Copyright (c) 2014 - 2017, 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
39namespace sdm {
40
41std::bitset<kDisplayMax> DisplayBase::needs_validate_ = 0;
42
43// TODO(user): Have a single structure handle carries all the interface pointers and variables.
44DisplayBase::DisplayBase(DisplayType display_type, DisplayEventHandler *event_handler,
45                         HWDeviceType hw_device_type, BufferSyncHandler *buffer_sync_handler,
46                         CompManager *comp_manager, HWInfoInterface *hw_info_intf)
47  : display_type_(display_type), event_handler_(event_handler), hw_device_type_(hw_device_type),
48    buffer_sync_handler_(buffer_sync_handler), comp_manager_(comp_manager),
49    hw_info_intf_(hw_info_intf) {
50}
51
52DisplayError DisplayBase::Init() {
53  lock_guard<recursive_mutex> obj(recursive_mutex_);
54  DisplayError error = kErrorNone;
55  hw_panel_info_ = HWPanelInfo();
56  hw_intf_->GetHWPanelInfo(&hw_panel_info_);
57
58  uint32_t active_index = 0;
59  hw_intf_->GetActiveConfig(&active_index);
60  hw_intf_->GetDisplayAttributes(active_index, &display_attributes_);
61  fb_config_ = display_attributes_;
62
63  error = Debug::GetMixerResolution(&mixer_attributes_.width, &mixer_attributes_.height);
64  if (error == kErrorNone) {
65    hw_intf_->SetMixerAttributes(mixer_attributes_);
66  }
67
68  error = hw_intf_->GetMixerAttributes(&mixer_attributes_);
69  if (error != kErrorNone) {
70    return error;
71  }
72
73  // Override x_pixels and y_pixels of frame buffer with mixer width and height
74  fb_config_.x_pixels = mixer_attributes_.width;
75  fb_config_.y_pixels = mixer_attributes_.height;
76
77  HWScaleLutInfo lut_info = {};
78  error = comp_manager_->GetScaleLutConfig(&lut_info);
79  if (error == kErrorNone) {
80    error = hw_intf_->SetScaleLutConfig(&lut_info);
81  }
82
83  if (error != kErrorNone) {
84    goto CleanupOnError;
85  }
86
87  error = comp_manager_->RegisterDisplay(display_type_, display_attributes_, hw_panel_info_,
88                                         mixer_attributes_, fb_config_, &display_comp_ctx_);
89  if (error != kErrorNone) {
90    goto CleanupOnError;
91  }
92
93  needs_validate_.set();
94
95  if (hw_info_intf_) {
96    HWResourceInfo hw_resource_info = HWResourceInfo();
97    hw_info_intf_->GetHWResourceInfo(&hw_resource_info);
98    auto max_mixer_stages = hw_resource_info.num_blending_stages;
99    int property_value = Debug::GetMaxPipesPerMixer(display_type_);
100    if (property_value >= 0) {
101      max_mixer_stages = std::min(UINT32(property_value), hw_resource_info.num_blending_stages);
102    }
103    DisplayBase::SetMaxMixerStages(max_mixer_stages);
104  }
105
106  color_mgr_ = ColorManagerProxy::CreateColorManagerProxy(display_type_, hw_intf_,
107                               display_attributes_, hw_panel_info_);
108  if (!color_mgr_) {
109    DLOGW("Unable to create ColorManagerProxy for display = %d", display_type_);
110  } else if (InitializeColorModes() != kErrorNone) {
111    DLOGW("InitColorModes failed for display = %d", display_type_);
112  }
113
114  Debug::Get()->GetProperty("sdm.disable_hdr_lut_gen", &disable_hdr_lut_gen_);
115
116  return kErrorNone;
117
118CleanupOnError:
119  if (display_comp_ctx_) {
120    comp_manager_->UnregisterDisplay(display_comp_ctx_);
121  }
122
123  return error;
124}
125
126DisplayError DisplayBase::Deinit() {
127  {  // Scope for lock
128    lock_guard<recursive_mutex> obj(recursive_mutex_);
129    color_modes_.clear();
130    color_mode_map_.clear();
131    color_mode_attr_map_.clear();
132
133    if (color_mgr_) {
134      delete color_mgr_;
135      color_mgr_ = NULL;
136    }
137
138    comp_manager_->UnregisterDisplay(display_comp_ctx_);
139  }
140  HWEventsInterface::Destroy(hw_events_intf_);
141  HWInterface::Destroy(hw_intf_);
142
143  return kErrorNone;
144}
145
146DisplayError DisplayBase::BuildLayerStackStats(LayerStack *layer_stack) {
147  std::vector<Layer *> &layers = layer_stack->layers;
148  HWLayersInfo &hw_layers_info = hw_layers_.info;
149
150  hw_layers_info.stack = layer_stack;
151
152  for (auto &layer : layers) {
153    if (layer->composition == kCompositionGPUTarget) {
154      hw_layers_info.gpu_target_index = hw_layers_info.app_layer_count;
155      break;
156    }
157    hw_layers_info.app_layer_count++;
158  }
159
160  DLOGV_IF(kTagNone, "LayerStack layer_count: %d, app_layer_count: %d, gpu_target_index: %d, "
161           "display type: %d", layers.size(), hw_layers_info.app_layer_count,
162           hw_layers_info.gpu_target_index, display_type_);
163
164  if (!hw_layers_info.app_layer_count) {
165    DLOGW("Layer count is zero");
166    return kErrorNoAppLayers;
167  }
168
169  if (hw_layers_info.gpu_target_index) {
170    return ValidateGPUTargetParams();
171  }
172
173  return kErrorNone;
174}
175
176DisplayError DisplayBase::ValidateGPUTargetParams() {
177  HWLayersInfo &hw_layers_info = hw_layers_.info;
178  Layer *gpu_target_layer = hw_layers_info.stack->layers.at(hw_layers_info.gpu_target_index);
179
180  if (!IsValid(gpu_target_layer->src_rect)) {
181    DLOGE("Invalid src rect for GPU target layer");
182    return kErrorParameters;
183  }
184
185  if (!IsValid(gpu_target_layer->dst_rect)) {
186    DLOGE("Invalid dst rect for GPU target layer");
187    return kErrorParameters;
188  }
189
190  float layer_mixer_width = FLOAT(mixer_attributes_.width);
191  float layer_mixer_height = FLOAT(mixer_attributes_.height);
192  float fb_width = FLOAT(fb_config_.x_pixels);
193  float fb_height = FLOAT(fb_config_.y_pixels);
194  LayerRect src_domain = (LayerRect){0.0f, 0.0f, fb_width, fb_height};
195  LayerRect dst_domain = (LayerRect){0.0f, 0.0f, layer_mixer_width, layer_mixer_height};
196  LayerRect out_rect = gpu_target_layer->dst_rect;
197
198  MapRect(src_domain, dst_domain, gpu_target_layer->dst_rect, &out_rect);
199  Normalize(1, 1, &out_rect);
200
201  auto gpu_target_layer_dst_xpixels = out_rect.right - out_rect.left;
202  auto gpu_target_layer_dst_ypixels = out_rect.bottom - out_rect.top;
203
204  if (gpu_target_layer_dst_xpixels > mixer_attributes_.width ||
205    gpu_target_layer_dst_ypixels > mixer_attributes_.height) {
206    DLOGE("GPU target layer dst rect is not with in limits gpu wxh %fx%f, mixer wxh %dx%d",
207                  gpu_target_layer_dst_xpixels, gpu_target_layer_dst_ypixels,
208                  mixer_attributes_.width, mixer_attributes_.height);
209    return kErrorParameters;
210  }
211
212  return kErrorNone;
213}
214
215DisplayError DisplayBase::Prepare(LayerStack *layer_stack) {
216  lock_guard<recursive_mutex> obj(recursive_mutex_);
217  DisplayError error = kErrorNone;
218  needs_validate_.set(display_type_);
219
220  if (!active_) {
221    return kErrorPermission;
222  }
223
224  if (!layer_stack) {
225    return kErrorParameters;
226  }
227
228  error = BuildLayerStackStats(layer_stack);
229  if (error != kErrorNone) {
230    return error;
231  }
232
233  error = HandleHDR(layer_stack);
234  if (error != kErrorNone) {
235    DLOGW("HandleHDR failed");
236    return error;
237  }
238
239  if (color_mgr_ && color_mgr_->NeedsPartialUpdateDisable()) {
240    DisablePartialUpdateOneFrame();
241  }
242
243  if (partial_update_control_ == false || disable_pu_one_frame_) {
244    comp_manager_->ControlPartialUpdate(display_comp_ctx_, false /* enable */);
245    disable_pu_one_frame_ = false;
246  }
247
248  comp_manager_->PrePrepare(display_comp_ctx_, &hw_layers_);
249  while (true) {
250    error = comp_manager_->Prepare(display_comp_ctx_, &hw_layers_);
251    if (error != kErrorNone) {
252      break;
253    }
254
255    error = hw_intf_->Validate(&hw_layers_);
256    if (error == kErrorNone) {
257      // Strategy is successful now, wait for Commit().
258      needs_validate_.reset(display_type_);
259      break;
260    }
261    if (error == kErrorShutDown) {
262      comp_manager_->PostPrepare(display_comp_ctx_, &hw_layers_);
263      return error;
264    }
265  }
266
267  comp_manager_->PostPrepare(display_comp_ctx_, &hw_layers_);
268
269  return error;
270}
271
272DisplayError DisplayBase::Commit(LayerStack *layer_stack) {
273  lock_guard<recursive_mutex> obj(recursive_mutex_);
274  DisplayError error = kErrorNone;
275
276  if (!active_) {
277    needs_validate_.set(display_type_);
278    return kErrorPermission;
279  }
280
281  if (!layer_stack) {
282    return kErrorParameters;
283  }
284
285  if (needs_validate_.test(display_type_)) {
286    DLOGV_IF(kTagNone, "Corresponding Prepare() is not called for display = %d", display_type_);
287    return kErrorNotValidated;
288  }
289
290  // Layer stack attributes has changed, need to Reconfigure, currently in use for Hybrid Comp
291  if (layer_stack->flags.attributes_changed) {
292    error = comp_manager_->ReConfigure(display_comp_ctx_, &hw_layers_);
293    if (error != kErrorNone) {
294      return error;
295    }
296
297    error = hw_intf_->Validate(&hw_layers_);
298    if (error != kErrorNone) {
299        return error;
300    }
301  }
302
303  CommitLayerParams(layer_stack);
304
305  if (comp_manager_->Commit(display_comp_ctx_, &hw_layers_)) {
306    if (error != kErrorNone) {
307      return error;
308    }
309  }
310
311  // check if feature list cache is dirty and pending.
312  // If dirty, need program to hardware blocks.
313  if (color_mgr_)
314    error = color_mgr_->Commit();
315  if (error != kErrorNone) {  // won't affect this execution path.
316    DLOGW("ColorManager::Commit(...) isn't working");
317  }
318
319  error = hw_intf_->Commit(&hw_layers_);
320  if (error != kErrorNone) {
321    return error;
322  }
323
324  PostCommitLayerParams(layer_stack);
325
326  if (partial_update_control_) {
327    comp_manager_->ControlPartialUpdate(display_comp_ctx_, true /* enable */);
328  }
329
330  error = comp_manager_->PostCommit(display_comp_ctx_, &hw_layers_);
331  if (error != kErrorNone) {
332    return error;
333  }
334
335  return kErrorNone;
336}
337
338DisplayError DisplayBase::Flush() {
339  lock_guard<recursive_mutex> obj(recursive_mutex_);
340  DisplayError error = kErrorNone;
341
342  if (!active_) {
343    return kErrorPermission;
344  }
345  hw_layers_.info.hw_layers.clear();
346  error = hw_intf_->Flush();
347  if (error == kErrorNone) {
348    comp_manager_->Purge(display_comp_ctx_);
349  } else {
350    DLOGW("Unable to flush display = %d", display_type_);
351  }
352
353  needs_validate_.set(display_type_);
354  return error;
355}
356
357DisplayError DisplayBase::GetDisplayState(DisplayState *state) {
358  lock_guard<recursive_mutex> obj(recursive_mutex_);
359  if (!state) {
360    return kErrorParameters;
361  }
362
363  *state = state_;
364  return kErrorNone;
365}
366
367DisplayError DisplayBase::GetNumVariableInfoConfigs(uint32_t *count) {
368  lock_guard<recursive_mutex> obj(recursive_mutex_);
369  return hw_intf_->GetNumDisplayAttributes(count);
370}
371
372DisplayError DisplayBase::GetConfig(uint32_t index, DisplayConfigVariableInfo *variable_info) {
373  lock_guard<recursive_mutex> obj(recursive_mutex_);
374  HWDisplayAttributes attrib;
375  if (hw_intf_->GetDisplayAttributes(index, &attrib) == kErrorNone) {
376    *variable_info = attrib;
377    return kErrorNone;
378  }
379
380  return kErrorNotSupported;
381}
382
383DisplayError DisplayBase::GetConfig(DisplayConfigFixedInfo *fixed_info) {
384  lock_guard<recursive_mutex> obj(recursive_mutex_);
385  fixed_info->is_cmdmode = (hw_panel_info_.mode == kModeCommand);
386
387  HWResourceInfo hw_resource_info = HWResourceInfo();
388  hw_info_intf_->GetHWResourceInfo(&hw_resource_info);
389  // hdr can be supported by display when target and panel supports HDR.
390  fixed_info->hdr_supported = (hw_resource_info.has_hdr && hw_panel_info_.hdr_enabled);
391  // Populate luminance values only if hdr will be supported on that display
392  fixed_info->max_luminance = fixed_info->hdr_supported ? hw_panel_info_.peak_luminance: 0;
393  fixed_info->average_luminance = fixed_info->hdr_supported ? hw_panel_info_.average_luminance : 0;
394  fixed_info->min_luminance = fixed_info->hdr_supported ?  hw_panel_info_.blackness_level: 0;
395
396  return kErrorNone;
397}
398
399DisplayError DisplayBase::GetActiveConfig(uint32_t *index) {
400  lock_guard<recursive_mutex> obj(recursive_mutex_);
401  return hw_intf_->GetActiveConfig(index);
402}
403
404DisplayError DisplayBase::GetVSyncState(bool *enabled) {
405  lock_guard<recursive_mutex> obj(recursive_mutex_);
406  if (!enabled) {
407    return kErrorParameters;
408  }
409
410  *enabled = vsync_enable_;
411
412  return kErrorNone;
413}
414
415DisplayError DisplayBase::SetDisplayState(DisplayState state) {
416  lock_guard<recursive_mutex> obj(recursive_mutex_);
417  DisplayError error = kErrorNone;
418  bool active = false;
419
420  DLOGI("Set state = %d, display %d", state, display_type_);
421
422  if (state == state_) {
423    DLOGI("Same state transition is requested.");
424    return kErrorNone;
425  }
426
427  needs_validate_.set(display_type_);
428
429  switch (state) {
430  case kStateOff:
431    hw_layers_.info.hw_layers.clear();
432    error = hw_intf_->Flush();
433    if (error == kErrorNone) {
434      error = hw_intf_->PowerOff();
435    }
436    break;
437
438  case kStateOn:
439    error = hw_intf_->PowerOn();
440    if (error != kErrorNone) {
441      return error;
442    }
443
444    error = comp_manager_->ReconfigureDisplay(display_comp_ctx_, display_attributes_,
445                                              hw_panel_info_, mixer_attributes_, fb_config_);
446    if (error != kErrorNone) {
447      return error;
448    }
449
450    active = true;
451    break;
452
453  case kStateDoze:
454    error = hw_intf_->Doze();
455    active = true;
456    break;
457
458  case kStateDozeSuspend:
459    error = hw_intf_->DozeSuspend();
460    if (display_type_ != kPrimary) {
461      active = true;
462    }
463
464    break;
465
466  case kStateStandby:
467    error = hw_intf_->Standby();
468    break;
469
470  default:
471    DLOGE("Spurious state = %d transition requested.", state);
472    break;
473  }
474
475  if (error == kErrorNone) {
476    active_ = active;
477    state_ = state;
478    comp_manager_->SetDisplayState(display_comp_ctx_, state, display_type_);
479  }
480
481  return error;
482}
483
484DisplayError DisplayBase::SetActiveConfig(uint32_t index) {
485  lock_guard<recursive_mutex> obj(recursive_mutex_);
486  DisplayError error = kErrorNone;
487  uint32_t active_index = 0;
488
489  hw_intf_->GetActiveConfig(&active_index);
490
491  if (active_index == index) {
492    return kErrorNone;
493  }
494
495  error = hw_intf_->SetDisplayAttributes(index);
496  if (error != kErrorNone) {
497    return error;
498  }
499
500  return ReconfigureDisplay();
501}
502
503DisplayError DisplayBase::SetMaxMixerStages(uint32_t max_mixer_stages) {
504  lock_guard<recursive_mutex> obj(recursive_mutex_);
505  DisplayError error = kErrorNone;
506
507  error = comp_manager_->SetMaxMixerStages(display_comp_ctx_, max_mixer_stages);
508
509  if (error == kErrorNone) {
510    max_mixer_stages_ = max_mixer_stages;
511  }
512
513  return error;
514}
515
516void DisplayBase::AppendDump(char *buffer, uint32_t length) {
517  lock_guard<recursive_mutex> obj(recursive_mutex_);
518  HWDisplayAttributes attrib;
519  uint32_t active_index = 0;
520  uint32_t num_modes = 0;
521  hw_intf_->GetNumDisplayAttributes(&num_modes);
522  hw_intf_->GetActiveConfig(&active_index);
523  hw_intf_->GetDisplayAttributes(active_index, &attrib);
524
525  DumpImpl::AppendString(buffer, length, "\n-----------------------");
526  DumpImpl::AppendString(buffer, length, "\ndevice type: %u", display_type_);
527  DumpImpl::AppendString(buffer, length, "\nstate: %u, vsync on: %u, max. mixer stages: %u",
528                         state_, INT(vsync_enable_), max_mixer_stages_);
529  DumpImpl::AppendString(buffer, length, "\nnum configs: %u, active config index: %u",
530                         num_modes, active_index);
531
532  DisplayConfigVariableInfo &info = attrib;
533
534  uint32_t num_hw_layers = 0;
535  if (hw_layers_.info.stack) {
536    num_hw_layers = UINT32(hw_layers_.info.hw_layers.size());
537  }
538
539  if (num_hw_layers == 0) {
540    DumpImpl::AppendString(buffer, length, "\nNo hardware layers programmed");
541    return;
542  }
543
544  LayerBuffer *out_buffer = hw_layers_.info.stack->output_buffer;
545  if (out_buffer) {
546    DumpImpl::AppendString(buffer, length, "\nres:%u x %u format: %s", out_buffer->width,
547                           out_buffer->height, GetFormatString(out_buffer->format));
548  } else {
549    DumpImpl::AppendString(buffer, length, "\nres:%u x %u, dpi:%.2f x %.2f, fps:%u,"
550                           "vsync period: %u", info.x_pixels, info.y_pixels, info.x_dpi,
551                           info.y_dpi, info.fps, info.vsync_period_ns);
552  }
553
554  DumpImpl::AppendString(buffer, length, "\n");
555
556  HWLayersInfo &layer_info = hw_layers_.info;
557
558  for (uint32_t i = 0; i < layer_info.left_frame_roi.size(); i++) {
559    LayerRect &l_roi = layer_info.left_frame_roi.at(i);
560
561    DumpImpl::AppendString(buffer, length, "\nROI%d(L T R B) : LEFT(%d %d %d %d)", i,
562                           INT(l_roi.left), INT(l_roi.top), INT(l_roi.right), INT(l_roi.bottom));
563    if (i < layer_info.right_frame_roi.size()) {
564      LayerRect &r_roi = layer_info.right_frame_roi.at(i);
565      if (IsValid(r_roi)) {
566        DumpImpl::AppendString(buffer, length, ", RIGHT(%d %d %d %d)", INT(r_roi.left),
567                               INT(r_roi.top), INT(r_roi.right), INT(r_roi.bottom));
568      }
569    }
570  }
571
572  LayerRect &fb_roi = layer_info.partial_fb_roi;
573  if (IsValid(fb_roi)) {
574    DumpImpl::AppendString(buffer, length, "\nPartial FB ROI(L T R B) : (%d %d %d %d)",
575                          INT(fb_roi.left), INT(fb_roi.top), INT(fb_roi.right), INT(fb_roi.bottom));
576  }
577
578  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 | Rng |";  //NOLINT
579  const char *newline = "\n|-----|-------------|--------|----|--------|-------------|--------------------------|---------------------|---------------------|----|------------|-----------|----|-----|";  //NOLINT
580  const char *format  = "\n| %3s | %11s "     "| %6s " "| %2s | 0x%04x | %4d x %4d | %24s "                  "| %4d %4d %4d %4d "  "| %4d %4d %4d %4d "  "| %2s | %10s "   "| %9s | %2s | %3s |";  //NOLINT
581
582  DumpImpl::AppendString(buffer, length, "\n");
583  DumpImpl::AppendString(buffer, length, newline);
584  DumpImpl::AppendString(buffer, length, header);
585  DumpImpl::AppendString(buffer, length, newline);
586
587  for (uint32_t i = 0; i < num_hw_layers; i++) {
588    uint32_t layer_index = hw_layers_.info.index[i];
589    // sdm-layer from client layer stack
590    Layer *sdm_layer = hw_layers_.info.stack->layers.at(layer_index);
591    // hw-layer from hw layers info
592    Layer &hw_layer = hw_layers_.info.hw_layers.at(i);
593    LayerBuffer *input_buffer = &hw_layer.input_buffer;
594    HWLayerConfig &layer_config = hw_layers_.config[i];
595    HWRotatorSession &hw_rotator_session = layer_config.hw_rotator_session;
596
597    char idx[8] = { 0 };
598    const char *comp_type = GetName(sdm_layer->composition);
599    const char *buffer_format = GetFormatString(input_buffer->format);
600    const char *rotate_split[2] = { "Rot-1", "Rot-2" };
601    const char *comp_split[2] = { "Comp-1", "Comp-2" };
602
603    snprintf(idx, sizeof(idx), "%d", layer_index);
604
605    for (uint32_t count = 0; count < hw_rotator_session.hw_block_count; count++) {
606      char writeback_id[8] = { 0 };
607      HWRotateInfo &rotate = hw_rotator_session.hw_rotate_info[count];
608      LayerRect &src_roi = rotate.src_roi;
609      LayerRect &dst_roi = rotate.dst_roi;
610
611      snprintf(writeback_id, sizeof(writeback_id), "%d", rotate.writeback_id);
612
613      DumpImpl::AppendString(buffer, length, format, idx, comp_type, rotate_split[count],
614                             writeback_id, rotate.pipe_id, input_buffer->width,
615                             input_buffer->height, buffer_format, INT(src_roi.left),
616                             INT(src_roi.top), INT(src_roi.right), INT(src_roi.bottom),
617                             INT(dst_roi.left), INT(dst_roi.top), INT(dst_roi.right),
618                             INT(dst_roi.bottom), "-", "-    ", "-    ", "-", "-");
619
620      // print the below only once per layer block, fill with spaces for rest.
621      idx[0] = 0;
622      comp_type = "";
623    }
624
625    if (hw_rotator_session.hw_block_count > 0) {
626      input_buffer = &hw_rotator_session.output_buffer;
627      buffer_format = GetFormatString(input_buffer->format);
628    }
629
630    for (uint32_t count = 0; count < 2; count++) {
631      char decimation[16] = { 0 };
632      char flags[16] = { 0 };
633      char z_order[8] = { 0 };
634      char color_primary[8] = { 0 };
635      char range[8] = { 0 };
636
637      HWPipeInfo &pipe = (count == 0) ? layer_config.left_pipe : layer_config.right_pipe;
638
639      if (!pipe.valid) {
640        continue;
641      }
642
643      LayerRect &src_roi = pipe.src_roi;
644      LayerRect &dst_roi = pipe.dst_roi;
645
646      snprintf(z_order, sizeof(z_order), "%d", pipe.z_order);
647      snprintf(flags, sizeof(flags), "0x%08x", hw_layer.flags.flags);
648      snprintf(decimation, sizeof(decimation), "%3d x %3d", pipe.horizontal_decimation,
649               pipe.vertical_decimation);
650      ColorMetaData &color_metadata = hw_layer.input_buffer.color_metadata;
651      snprintf(color_primary, sizeof(color_primary), "%d", color_metadata.colorPrimaries);
652      snprintf(range, sizeof(range), "%d", color_metadata.range);
653
654      DumpImpl::AppendString(buffer, length, format, idx, comp_type, comp_split[count],
655                             "-", pipe.pipe_id, input_buffer->width, input_buffer->height,
656                             buffer_format, INT(src_roi.left), INT(src_roi.top),
657                             INT(src_roi.right), INT(src_roi.bottom), INT(dst_roi.left),
658                             INT(dst_roi.top), INT(dst_roi.right), INT(dst_roi.bottom),
659                             z_order, flags, decimation, color_primary, range);
660
661      // print the below only once per layer block, fill with spaces for rest.
662      idx[0] = 0;
663      comp_type = "";
664    }
665
666    DumpImpl::AppendString(buffer, length, newline);
667  }
668}
669
670const char * DisplayBase::GetName(const LayerComposition &composition) {
671  switch (composition) {
672  case kCompositionGPU:         return "GPU";
673  case kCompositionSDE:         return "SDE";
674  case kCompositionHWCursor:    return "CURSOR";
675  case kCompositionHybrid:      return "HYBRID";
676  case kCompositionBlit:        return "BLIT";
677  case kCompositionGPUTarget:   return "GPU_TARGET";
678  case kCompositionBlitTarget:  return "BLIT_TARGET";
679  default:                      return "UNKNOWN";
680  }
681}
682
683DisplayError DisplayBase::ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload,
684                                               PPDisplayAPIPayload *out_payload,
685                                               PPPendingParams *pending_action) {
686  lock_guard<recursive_mutex> obj(recursive_mutex_);
687  if (color_mgr_)
688    return color_mgr_->ColorSVCRequestRoute(in_payload, out_payload, pending_action);
689  else
690    return kErrorParameters;
691}
692
693DisplayError DisplayBase::GetColorModeCount(uint32_t *mode_count) {
694  lock_guard<recursive_mutex> obj(recursive_mutex_);
695  if (!mode_count) {
696    return kErrorParameters;
697  }
698
699  if (!color_mgr_) {
700    return kErrorNotSupported;
701  }
702
703  DLOGV_IF(kTagQDCM, "Number of modes from color manager = %d", num_color_modes_);
704  *mode_count = num_color_modes_;
705
706  return kErrorNone;
707}
708
709DisplayError DisplayBase::GetColorModes(uint32_t *mode_count,
710                                        std::vector<std::string> *color_modes) {
711  lock_guard<recursive_mutex> obj(recursive_mutex_);
712  if (!mode_count || !color_modes) {
713    return kErrorParameters;
714  }
715
716  if (!color_mgr_) {
717    return kErrorNotSupported;
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    color_modes->at(i) = color_modes_[i].name;
724  }
725
726  return kErrorNone;
727}
728
729DisplayError DisplayBase::GetColorModeAttr(const std::string &color_mode, AttrVal *attr) {
730  lock_guard<recursive_mutex> obj(recursive_mutex_);
731  if (!attr) {
732    return kErrorParameters;
733  }
734
735  if (!color_mgr_) {
736    return kErrorNotSupported;
737  }
738
739  auto it = color_mode_attr_map_.find(color_mode);
740  if (it == color_mode_attr_map_.end()) {
741    DLOGI("Mode %s has no attribute", color_mode.c_str());
742    return kErrorNotSupported;
743  }
744  *attr = it->second;
745
746  return kErrorNone;
747}
748
749DisplayError DisplayBase::SetColorMode(const std::string &color_mode) {
750  lock_guard<recursive_mutex> obj(recursive_mutex_);
751  if (!color_mgr_) {
752    return kErrorNotSupported;
753  }
754
755  DynamicRangeType dynamic_range_type;
756  if (IsSupportColorModeAttribute(color_mode)) {
757    auto it_mode = color_mode_attr_map_.find(color_mode);
758    std::string dynamic_range;
759    GetValueOfModeAttribute(it_mode->second, kDynamicRangeAttribute, &dynamic_range);
760    if (dynamic_range == kHdr) {
761      dynamic_range_type = kHdrType;
762    } else {
763      dynamic_range_type = kSdrType;
764    }
765  } else {
766    if (color_mode.find("hal_hdr") != std::string::npos) {
767      dynamic_range_type = kHdrType;
768    } else {
769      dynamic_range_type = kSdrType;
770    }
771  }
772
773  DisplayError error = kErrorNone;
774  if (disable_hdr_lut_gen_) {
775    error = SetColorModeInternal(color_mode);
776    if (error != kErrorNone) {
777      return error;
778    }
779    // Store the new SDR color mode request by client
780    if (dynamic_range_type == kSdrType) {
781      current_color_mode_ = color_mode;
782    }
783    return error;
784  }
785
786  if (hdr_playback_mode_) {
787    // HDR playback on, If incoming mode is SDR mode,
788    // cache the mode and apply it after HDR playback stop.
789    if (dynamic_range_type == kHdrType) {
790      error = SetColorModeInternal(color_mode);
791      if (error != kErrorNone) {
792        return error;
793      }
794    } else if (dynamic_range_type == kSdrType) {
795      current_color_mode_ = color_mode;
796    }
797  } else {
798    // HDR playback off, do not apply HDR mode
799    if (dynamic_range_type == kHdrType) {
800      DLOGE("Failed: Forbid setting HDR Mode : %s when HDR playback off", color_mode.c_str());
801      return kErrorNotSupported;
802    }
803    error = SetColorModeInternal(color_mode);
804    if (error != kErrorNone) {
805      return error;
806    }
807    current_color_mode_ = color_mode;
808  }
809
810  return error;
811}
812
813DisplayError DisplayBase::SetColorModeById(int32_t color_mode_id) {
814  return color_mgr_->ColorMgrSetMode(color_mode_id);
815}
816
817DisplayError DisplayBase::SetColorModeInternal(const std::string &color_mode) {
818  DLOGV_IF(kTagQDCM, "Color Mode = %s", color_mode.c_str());
819
820  ColorModeMap::iterator it = color_mode_map_.find(color_mode);
821  if (it == color_mode_map_.end()) {
822    DLOGE("Failed: Unknown Mode : %s", color_mode.c_str());
823    return kErrorNotSupported;
824  }
825
826  SDEDisplayMode *sde_display_mode = it->second;
827
828  DLOGV_IF(kTagQDCM, "Color Mode Name = %s corresponding mode_id = %d", sde_display_mode->name,
829           sde_display_mode->id);
830  DisplayError error = kErrorNone;
831  error = color_mgr_->ColorMgrSetMode(sde_display_mode->id);
832  if (error != kErrorNone) {
833    DLOGE("Failed for mode id = %d", sde_display_mode->id);
834    return error;
835  }
836
837  return error;
838}
839
840DisplayError DisplayBase::GetValueOfModeAttribute(const AttrVal &attr, const std::string &type,
841                                                  std::string *value) {
842  if (!value) {
843    return kErrorParameters;
844  }
845  for (auto &it : attr) {
846    if (it.first.find(type) != std::string::npos) {
847      *value = it.second;
848    }
849  }
850
851  return kErrorNone;
852}
853
854bool DisplayBase::IsSupportColorModeAttribute(const std::string &color_mode) {
855  auto it = color_mode_attr_map_.find(color_mode);
856  if (it == color_mode_attr_map_.end()) {
857    return false;
858  }
859  return true;
860}
861
862DisplayError DisplayBase::GetHdrColorMode(std::string *color_mode, bool *found_hdr) {
863  if (!found_hdr || !color_mode) {
864    return kErrorParameters;
865  }
866  auto it_mode = color_mode_attr_map_.find(current_color_mode_);
867  if (it_mode == color_mode_attr_map_.end()) {
868    DLOGE("Failed: Unknown Mode : %s", current_color_mode_.c_str());
869    return kErrorNotSupported;
870  }
871
872  *found_hdr = false;
873  std::string cur_color_gamut, cur_pic_quality;
874  // get the attributes of current color mode
875  GetValueOfModeAttribute(it_mode->second, kColorGamutAttribute, &cur_color_gamut);
876  GetValueOfModeAttribute(it_mode->second, kPictureQualityAttribute, &cur_pic_quality);
877
878  // found the corresponding HDR mode id which
879  // has the same attributes with current SDR mode.
880  for (auto &it_hdr : color_mode_attr_map_) {
881    std::string dynamic_range, color_gamut, pic_quality;
882    GetValueOfModeAttribute(it_hdr.second, kDynamicRangeAttribute, &dynamic_range);
883    GetValueOfModeAttribute(it_hdr.second, kColorGamutAttribute, &color_gamut);
884    GetValueOfModeAttribute(it_hdr.second, kPictureQualityAttribute, &pic_quality);
885    if (dynamic_range == kHdr && cur_color_gamut == color_gamut &&
886        cur_pic_quality == pic_quality) {
887      *color_mode = it_hdr.first;
888      *found_hdr = true;
889      DLOGV_IF(kTagQDCM, "corresponding hdr mode  = %s", color_mode->c_str());
890      return kErrorNone;
891    }
892  }
893
894  // The corresponding HDR mode was not be found,
895  // apply the first HDR mode that we encouter.
896  for (auto &it_hdr : color_mode_attr_map_) {
897    std::string dynamic_range;
898    GetValueOfModeAttribute(it_hdr.second, kDynamicRangeAttribute, &dynamic_range);
899    if (dynamic_range == kHdr) {
900      *color_mode = it_hdr.first;
901      *found_hdr = true;
902      DLOGV_IF(kTagQDCM, "First hdr mode = %s", color_mode->c_str());
903      return kErrorNone;
904    }
905  }
906
907  return kErrorNone;
908}
909
910DisplayError DisplayBase::SetColorTransform(const uint32_t length, const double *color_transform) {
911  lock_guard<recursive_mutex> obj(recursive_mutex_);
912  if (!color_mgr_) {
913    return kErrorNotSupported;
914  }
915
916  if (!color_transform) {
917    return kErrorParameters;
918  }
919
920  return color_mgr_->ColorMgrSetColorTransform(length, color_transform);
921}
922
923DisplayError DisplayBase::GetDefaultColorMode(std::string *color_mode) {
924  lock_guard<recursive_mutex> obj(recursive_mutex_);
925  if (!color_mode) {
926    return kErrorParameters;
927  }
928
929  if (!color_mgr_) {
930    return kErrorNotSupported;
931  }
932
933  int32_t default_id = kInvalidModeId;
934  DisplayError error = color_mgr_->ColorMgrGetDefaultModeID(&default_id);
935  if (error != kErrorNone) {
936    DLOGE("Failed for get default color mode id");
937    return error;
938  }
939
940  for (uint32_t i = 0; i < num_color_modes_; i++) {
941    if (color_modes_[i].id == default_id) {
942      *color_mode = color_modes_[i].name;
943      return kErrorNone;
944    }
945  }
946
947  return kErrorNotSupported;
948}
949
950DisplayError DisplayBase::ApplyDefaultDisplayMode() {
951  lock_guard<recursive_mutex> obj(recursive_mutex_);
952  if (color_mgr_)
953    return color_mgr_->ApplyDefaultDisplayMode();
954  else
955    return kErrorParameters;
956}
957
958DisplayError DisplayBase::SetCursorPosition(int x, int y) {
959  lock_guard<recursive_mutex> obj(recursive_mutex_);
960  if (state_ != kStateOn) {
961    return kErrorNotSupported;
962  }
963
964  DisplayError error = comp_manager_->ValidateCursorPosition(display_comp_ctx_, &hw_layers_, x, y);
965  if (error == kErrorNone) {
966    return hw_intf_->SetCursorPosition(&hw_layers_, x, y);
967  }
968
969  return kErrorNone;
970}
971
972DisplayError DisplayBase::GetRefreshRateRange(uint32_t *min_refresh_rate,
973                                              uint32_t *max_refresh_rate) {
974  lock_guard<recursive_mutex> obj(recursive_mutex_);
975  // The min and max refresh rates will be same when the HWPanelInfo does not contain valid rates.
976  // Usually for secondary displays, command mode panels
977  HWDisplayAttributes display_attributes;
978  uint32_t active_index = 0;
979  hw_intf_->GetActiveConfig(&active_index);
980  DisplayError error = hw_intf_->GetDisplayAttributes(active_index, &display_attributes);
981  if (error) {
982    return error;
983  }
984
985  *min_refresh_rate = display_attributes.fps;
986  *max_refresh_rate = display_attributes.fps;
987
988  return error;
989}
990
991DisplayError DisplayBase::SetVSyncState(bool enable) {
992  lock_guard<recursive_mutex> obj(recursive_mutex_);
993  DisplayError error = kErrorNone;
994  if (vsync_enable_ != enable) {
995    error = hw_intf_->SetVSyncState(enable);
996    if (error == kErrorNone) {
997      vsync_enable_ = enable;
998    }
999  }
1000  return error;
1001}
1002
1003DisplayError DisplayBase::ReconfigureDisplay() {
1004  lock_guard<recursive_mutex> obj(recursive_mutex_);
1005  DisplayError error = kErrorNone;
1006  HWDisplayAttributes display_attributes;
1007  HWMixerAttributes mixer_attributes;
1008  HWPanelInfo hw_panel_info;
1009  uint32_t active_index = 0;
1010
1011  error = hw_intf_->GetActiveConfig(&active_index);
1012  if (error != kErrorNone) {
1013    return error;
1014  }
1015
1016  error = hw_intf_->GetDisplayAttributes(active_index, &display_attributes);
1017  if (error != kErrorNone) {
1018    return error;
1019  }
1020
1021  error = hw_intf_->GetMixerAttributes(&mixer_attributes);
1022  if (error != kErrorNone) {
1023    return error;
1024  }
1025
1026  error = hw_intf_->GetHWPanelInfo(&hw_panel_info);
1027  if (error != kErrorNone) {
1028    return error;
1029  }
1030
1031  if (display_attributes == display_attributes_ && mixer_attributes == mixer_attributes_ &&
1032      hw_panel_info == hw_panel_info_) {
1033    return kErrorNone;
1034  }
1035
1036  error = comp_manager_->ReconfigureDisplay(display_comp_ctx_, display_attributes, hw_panel_info,
1037                                            mixer_attributes, fb_config_);
1038  if (error != kErrorNone) {
1039    return error;
1040  }
1041
1042  if (mixer_attributes != mixer_attributes_) {
1043    DisablePartialUpdateOneFrame();
1044  }
1045
1046  display_attributes_ = display_attributes;
1047  mixer_attributes_ = mixer_attributes;
1048  hw_panel_info_ = hw_panel_info;
1049
1050  return kErrorNone;
1051}
1052
1053DisplayError DisplayBase::SetMixerResolution(uint32_t width, uint32_t height) {
1054  lock_guard<recursive_mutex> obj(recursive_mutex_);
1055
1056  DisplayError error = ReconfigureMixer(width, height);
1057  if (error != kErrorNone) {
1058    return error;
1059  }
1060
1061  req_mixer_width_ = width;
1062  req_mixer_height_ = height;
1063
1064  return kErrorNone;
1065}
1066
1067DisplayError DisplayBase::GetMixerResolution(uint32_t *width, uint32_t *height) {
1068  lock_guard<recursive_mutex> obj(recursive_mutex_);
1069  if (!width || !height) {
1070    return kErrorParameters;
1071  }
1072
1073  *width = mixer_attributes_.width;
1074  *height = mixer_attributes_.height;
1075
1076  return kErrorNone;
1077}
1078
1079DisplayError DisplayBase::ReconfigureMixer(uint32_t width, uint32_t height) {
1080  lock_guard<recursive_mutex> obj(recursive_mutex_);
1081  DisplayError error = kErrorNone;
1082
1083  if (!width || !height) {
1084    return kErrorParameters;
1085  }
1086
1087  HWMixerAttributes mixer_attributes;
1088  mixer_attributes.width = width;
1089  mixer_attributes.height = height;
1090
1091  error = hw_intf_->SetMixerAttributes(mixer_attributes);
1092  if (error != kErrorNone) {
1093    return error;
1094  }
1095
1096  return ReconfigureDisplay();
1097}
1098
1099bool DisplayBase::NeedsDownScale(const LayerRect &src_rect, const LayerRect &dst_rect,
1100                                 bool needs_rotation) {
1101  float src_width = FLOAT(src_rect.right - src_rect.left);
1102  float src_height = FLOAT(src_rect.bottom - src_rect.top);
1103  float dst_width = FLOAT(dst_rect.right - dst_rect.left);
1104  float dst_height = FLOAT(dst_rect.bottom - dst_rect.top);
1105
1106  if (needs_rotation) {
1107    std::swap(src_width, src_height);
1108  }
1109
1110  if ((src_width > dst_width) || (src_height > dst_height)) {
1111    return true;
1112  }
1113
1114  return false;
1115}
1116
1117bool DisplayBase::NeedsMixerReconfiguration(LayerStack *layer_stack, uint32_t *new_mixer_width,
1118                                            uint32_t *new_mixer_height) {
1119  lock_guard<recursive_mutex> obj(recursive_mutex_);
1120  uint32_t layer_count = UINT32(layer_stack->layers.size());
1121
1122  uint32_t fb_width  = fb_config_.x_pixels;
1123  uint32_t fb_height  = fb_config_.y_pixels;
1124  uint32_t fb_area = fb_width * fb_height;
1125  LayerRect fb_rect = (LayerRect) {0.0f, 0.0f, FLOAT(fb_width), FLOAT(fb_height)};
1126  uint32_t mixer_width = mixer_attributes_.width;
1127  uint32_t mixer_height = mixer_attributes_.height;
1128  uint32_t display_width = display_attributes_.x_pixels;
1129  uint32_t display_height = display_attributes_.y_pixels;
1130
1131  RectOrientation fb_orientation = GetOrientation(fb_rect);
1132  uint32_t max_layer_area = 0;
1133  uint32_t max_area_layer_index = 0;
1134  std::vector<Layer *> layers = layer_stack->layers;
1135  uint32_t align_x = display_attributes_.is_device_split ? 4 : 2;
1136  uint32_t align_y = 2;
1137
1138  if (req_mixer_width_ && req_mixer_height_) {
1139    *new_mixer_width = req_mixer_width_;
1140    *new_mixer_height = req_mixer_height_;
1141
1142    return (req_mixer_width_ != mixer_width || req_mixer_height_ != mixer_height);
1143  }
1144
1145  for (uint32_t i = 0; i < layer_count; i++) {
1146    Layer *layer = layers.at(i);
1147
1148    uint32_t layer_width = UINT32(layer->src_rect.right - layer->src_rect.left);
1149    uint32_t layer_height = UINT32(layer->src_rect.bottom - layer->src_rect.top);
1150    uint32_t layer_area = layer_width * layer_height;
1151
1152    if (layer_area > max_layer_area) {
1153      max_layer_area = layer_area;
1154      max_area_layer_index = i;
1155    }
1156  }
1157
1158  // TODO(user): Mark layer which needs downscaling on GPU fallback as priority layer and use MDP
1159  // for composition to avoid quality mismatch between GPU and MDP switch(idle timeout usecase).
1160  if (max_layer_area >= fb_area) {
1161    Layer *layer = layers.at(max_area_layer_index);
1162    bool needs_rotation = (layer->transform.rotation == 90.0f);
1163
1164    uint32_t layer_width = UINT32(layer->src_rect.right - layer->src_rect.left);
1165    uint32_t layer_height = UINT32(layer->src_rect.bottom - layer->src_rect.top);
1166    LayerRect layer_dst_rect = {};
1167
1168    RectOrientation layer_orientation = GetOrientation(layer->src_rect);
1169    if (layer_orientation != kOrientationUnknown &&
1170        fb_orientation != kOrientationUnknown) {
1171      if (layer_orientation != fb_orientation) {
1172        std::swap(layer_width, layer_height);
1173      }
1174    }
1175
1176    // Align the width and height according to fb's aspect ratio
1177    *new_mixer_width = FloorToMultipleOf(UINT32((FLOAT(fb_width) / FLOAT(fb_height)) *
1178                                         layer_height), align_x);
1179    *new_mixer_height = FloorToMultipleOf(layer_height, align_y);
1180
1181    LayerRect dst_domain = {0.0f, 0.0f, FLOAT(*new_mixer_width), FLOAT(*new_mixer_height)};
1182
1183    MapRect(fb_rect, dst_domain, layer->dst_rect, &layer_dst_rect);
1184    if (NeedsDownScale(layer->src_rect, layer_dst_rect, needs_rotation)) {
1185      *new_mixer_width = display_width;
1186      *new_mixer_height = display_height;
1187    }
1188
1189    return true;
1190  }
1191
1192  return false;
1193}
1194
1195DisplayError DisplayBase::SetFrameBufferConfig(const DisplayConfigVariableInfo &variable_info) {
1196  lock_guard<recursive_mutex> obj(recursive_mutex_);
1197  uint32_t width = variable_info.x_pixels;
1198  uint32_t height = variable_info.y_pixels;
1199
1200  if (width == 0 || height == 0) {
1201    DLOGE("Unsupported resolution: (%dx%d)", width, height);
1202    return kErrorParameters;
1203  }
1204
1205  // Create rects to represent the new source and destination crops
1206  LayerRect crop = LayerRect(0, 0, FLOAT(width), FLOAT(height));
1207  LayerRect dst = LayerRect(0, 0, FLOAT(mixer_attributes_.width), FLOAT(mixer_attributes_.height));
1208  // Set rotate90 to false since this is taken care of during regular composition.
1209  bool rotate90 = false;
1210
1211  DisplayError error = comp_manager_->ValidateScaling(crop, dst, rotate90);
1212  if (error != kErrorNone) {
1213    DLOGE("Unsupported resolution: (%dx%d)", width, height);
1214    return kErrorParameters;
1215  }
1216
1217  error =  comp_manager_->ReconfigureDisplay(display_comp_ctx_, display_attributes_, hw_panel_info_,
1218                                             mixer_attributes_, variable_info);
1219  if (error != kErrorNone) {
1220    return error;
1221  }
1222
1223  fb_config_.x_pixels = width;
1224  fb_config_.y_pixels = height;
1225
1226  DLOGI("New framebuffer resolution (%dx%d)", fb_config_.x_pixels, fb_config_.y_pixels);
1227
1228  return kErrorNone;
1229}
1230
1231DisplayError DisplayBase::GetFrameBufferConfig(DisplayConfigVariableInfo *variable_info) {
1232  lock_guard<recursive_mutex> obj(recursive_mutex_);
1233  if (!variable_info) {
1234    return kErrorParameters;
1235  }
1236
1237  *variable_info = fb_config_;
1238
1239  return kErrorNone;
1240}
1241
1242DisplayError DisplayBase::SetDetailEnhancerData(const DisplayDetailEnhancerData &de_data) {
1243  lock_guard<recursive_mutex> obj(recursive_mutex_);
1244  DisplayError error = comp_manager_->SetDetailEnhancerData(display_comp_ctx_, de_data);
1245  if (error != kErrorNone) {
1246    return error;
1247  }
1248
1249  DisablePartialUpdateOneFrame();
1250
1251  return kErrorNone;
1252}
1253
1254DisplayError DisplayBase::GetDisplayPort(DisplayPort *port) {
1255  lock_guard<recursive_mutex> obj(recursive_mutex_);
1256
1257  if (!port) {
1258    return kErrorParameters;
1259  }
1260
1261  *port = hw_panel_info_.port;
1262
1263  return kErrorNone;
1264}
1265
1266bool DisplayBase::IsPrimaryDisplay() {
1267  lock_guard<recursive_mutex> obj(recursive_mutex_);
1268
1269  return hw_panel_info_.is_primary_panel;
1270}
1271
1272DisplayError DisplayBase::SetCompositionState(LayerComposition composition_type, bool enable) {
1273  lock_guard<recursive_mutex> obj(recursive_mutex_);
1274
1275  return comp_manager_->SetCompositionState(display_comp_ctx_, composition_type, enable);
1276}
1277
1278void DisplayBase::CommitLayerParams(LayerStack *layer_stack) {
1279  // Copy the acquire fence from clients layers  to HWLayers
1280  uint32_t hw_layers_count = UINT32(hw_layers_.info.hw_layers.size());
1281
1282  for (uint32_t i = 0; i < hw_layers_count; i++) {
1283    Layer *sdm_layer = layer_stack->layers.at(hw_layers_.info.index[i]);
1284    Layer &hw_layer = hw_layers_.info.hw_layers.at(i);
1285
1286    hw_layer.input_buffer.planes[0].fd = sdm_layer->input_buffer.planes[0].fd;
1287    hw_layer.input_buffer.planes[0].offset = sdm_layer->input_buffer.planes[0].offset;
1288    hw_layer.input_buffer.planes[0].stride = sdm_layer->input_buffer.planes[0].stride;
1289    hw_layer.input_buffer.size = sdm_layer->input_buffer.size;
1290    hw_layer.input_buffer.acquire_fence_fd = sdm_layer->input_buffer.acquire_fence_fd;
1291    hw_layer.input_buffer.fb_id = sdm_layer->input_buffer.fb_id;
1292  }
1293
1294  return;
1295}
1296
1297void DisplayBase::PostCommitLayerParams(LayerStack *layer_stack) {
1298  // Copy the release fence from HWLayers to clients layers
1299    uint32_t hw_layers_count = UINT32(hw_layers_.info.hw_layers.size());
1300
1301  std::vector<uint32_t> fence_dup_flag = {};
1302
1303  for (uint32_t i = 0; i < hw_layers_count; i++) {
1304    uint32_t sdm_layer_index = hw_layers_.info.index[i];
1305    Layer *sdm_layer = layer_stack->layers.at(sdm_layer_index);
1306    Layer &hw_layer = hw_layers_.info.hw_layers.at(i);
1307
1308    // Copy the release fence only once for a SDM Layer.
1309    // In S3D use case, two hw layers can share the same input buffer, So make sure to merge the
1310    // output fence fd and assign it to layer's input buffer release fence fd.
1311    if (std::find(fence_dup_flag.begin(), fence_dup_flag.end(), sdm_layer_index) ==
1312        fence_dup_flag.end()) {
1313      sdm_layer->input_buffer.release_fence_fd = hw_layer.input_buffer.release_fence_fd;
1314      fence_dup_flag.push_back(sdm_layer_index);
1315    } else {
1316      int temp = -1;
1317      buffer_sync_handler_->SyncMerge(hw_layer.input_buffer.release_fence_fd,
1318                                      sdm_layer->input_buffer.release_fence_fd, &temp);
1319
1320      if (hw_layer.input_buffer.release_fence_fd >= 0) {
1321        Sys::close_(hw_layer.input_buffer.release_fence_fd);
1322        hw_layer.input_buffer.release_fence_fd = -1;
1323      }
1324
1325      if (sdm_layer->input_buffer.release_fence_fd >= 0) {
1326        Sys::close_(sdm_layer->input_buffer.release_fence_fd);
1327        sdm_layer->input_buffer.release_fence_fd = -1;
1328      }
1329
1330      sdm_layer->input_buffer.release_fence_fd = temp;
1331    }
1332
1333    // Reset the sync fence fds of HWLayer
1334    hw_layer.input_buffer.acquire_fence_fd = -1;
1335    hw_layer.input_buffer.release_fence_fd = -1;
1336  }
1337
1338  return;
1339}
1340
1341DisplayError DisplayBase::InitializeColorModes() {
1342  if (!color_mgr_) {
1343    return kErrorNotSupported;
1344  }
1345
1346  DisplayError error = color_mgr_->ColorMgrGetNumOfModes(&num_color_modes_);
1347  if (error != kErrorNone || !num_color_modes_) {
1348    DLOGV_IF(kTagQDCM, "GetNumModes failed = %d count = %d", error, num_color_modes_);
1349    return kErrorNotSupported;
1350  }
1351  DLOGI("Number of Color Modes = %d", num_color_modes_);
1352
1353  if (!color_modes_.size()) {
1354    color_modes_.resize(num_color_modes_);
1355
1356    DisplayError error = color_mgr_->ColorMgrGetModes(&num_color_modes_, color_modes_.data());
1357    if (error != kErrorNone) {
1358      color_modes_.clear();
1359      DLOGE("Failed");
1360      return error;
1361    }
1362    int32_t default_id = kInvalidModeId;
1363    error = color_mgr_->ColorMgrGetDefaultModeID(&default_id);
1364
1365    AttrVal var;
1366    for (uint32_t i = 0; i < num_color_modes_; i++) {
1367      DLOGV_IF(kTagQDCM, "Color Mode[%d]: Name = %s mode_id = %d", i, color_modes_[i].name,
1368               color_modes_[i].id);
1369      // get the name of default color mode
1370      if (color_modes_[i].id == default_id) {
1371        current_color_mode_ = color_modes_[i].name;
1372      }
1373      auto it = color_mode_map_.find(color_modes_[i].name);
1374      if (it != color_mode_map_.end()) {
1375        if (it->second->id < color_modes_[i].id) {
1376          color_mode_map_.erase(it);
1377          color_mode_map_.insert(std::make_pair(color_modes_[i].name, &color_modes_[i]));
1378        }
1379      } else {
1380        color_mode_map_.insert(std::make_pair(color_modes_[i].name, &color_modes_[i]));
1381      }
1382
1383      var.clear();
1384      error = color_mgr_->ColorMgrGetModeInfo(color_modes_[i].id, &var);
1385      if (error != kErrorNone) {
1386        DLOGE("Failed for get attributes of mode_id = %d", color_modes_[i].id);
1387        continue;
1388      }
1389      if (!var.empty()) {
1390        auto it = color_mode_attr_map_.find(color_modes_[i].name);
1391        if (it == color_mode_attr_map_.end()) {
1392          color_mode_attr_map_.insert(std::make_pair(color_modes_[i].name, var));
1393        }
1394      }
1395    }
1396  }
1397
1398  return kErrorNone;
1399}
1400
1401DisplayError DisplayBase::HandleHDR(LayerStack *layer_stack) {
1402  DisplayError error = kErrorNone;
1403
1404  if (display_type_ != kPrimary) {
1405    // Handling is needed for only primary displays
1406    return kErrorNone;
1407  }
1408
1409  if (!layer_stack->flags.hdr_present) {
1410    //  HDR playback off - set prev mode
1411    if (hdr_playback_mode_) {
1412      hdr_playback_mode_ = false;
1413      if (color_mgr_ && !disable_hdr_lut_gen_) {
1414        // Do not apply HDR Mode when hdr lut generation is disabled
1415        DLOGI("Setting color mode = %s", current_color_mode_.c_str());
1416        // HDR playback off - set prev mode
1417        error = SetColorModeInternal(current_color_mode_);
1418      }
1419      comp_manager_->ControlDpps(true);  // Enable Dpps
1420    }
1421  } else {
1422    // hdr is present
1423    if (!hdr_playback_mode_ && !layer_stack->flags.animating) {
1424      // hdr is starting
1425      hdr_playback_mode_ = true;
1426      if (color_mgr_ && !disable_hdr_lut_gen_) {
1427        std::string hdr_color_mode;
1428        if (IsSupportColorModeAttribute(current_color_mode_)) {
1429          bool found_hdr = false;
1430          error = GetHdrColorMode(&hdr_color_mode, &found_hdr);
1431          // try to set "hal-hdr" mode if did not found that
1432          // the dynamic range of mode is hdr
1433          if (!found_hdr) {
1434            hdr_color_mode = "hal_hdr";
1435          }
1436        } else {
1437          hdr_color_mode = "hal_hdr";
1438        }
1439        DLOGI("Setting color mode = %s", hdr_color_mode.c_str());
1440        error = SetColorModeInternal(hdr_color_mode);
1441      }
1442      comp_manager_->ControlDpps(false);  // Disable Dpps
1443    }
1444  }
1445
1446  return error;
1447}
1448
1449}  // namespace sdm
1450