1/*
2 * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
3 * Not a Contribution.
4 *
5 * Copyright 2015 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19
20#include <cutils/properties.h>
21#include <errno.h>
22#include <math.h>
23#include <sync/sync.h>
24#include <sys/types.h>
25#include <sys/stat.h>
26#include <utils/constants.h>
27#include <utils/debug.h>
28#include <utils/formats.h>
29#include <utils/rect.h>
30#include <qd_utils.h>
31
32#include <algorithm>
33#include <iomanip>
34#include <map>
35#include <sstream>
36#include <string>
37#include <utility>
38#include <vector>
39
40#include "hwc_display.h"
41#include "hwc_debugger.h"
42#include "blit_engine_c2d.h"
43#include "hwc_tonemapper.h"
44
45#ifndef USE_GRALLOC1
46#include <gr.h>
47#endif
48
49#ifdef QTI_BSP
50#include <hardware/display_defs.h>
51#endif
52
53#define __CLASS__ "HWCDisplay"
54
55namespace sdm {
56
57std::bitset<kDisplayMax> HWCDisplay::validated_ = 0;
58
59// This weight function is needed because the color primaries are not sorted by gamut size
60static ColorPrimaries WidestPrimaries(ColorPrimaries p1, ColorPrimaries p2) {
61  int weight = 10;
62  int lp1 = p1, lp2 = p2;
63  // TODO(user) add weight to other wide gamut primaries
64  if (lp1 == ColorPrimaries_BT2020) {
65    lp1 *= weight;
66  }
67  if (lp1 == ColorPrimaries_BT2020) {
68    lp2 *= weight;
69  }
70  if (lp1 >= lp2) {
71    return p1;
72  } else {
73    return p2;
74  }
75}
76
77HWCColorMode::HWCColorMode(DisplayInterface *display_intf) : display_intf_(display_intf) {}
78
79HWC2::Error HWCColorMode::Init() {
80  PopulateColorModes();
81  return ApplyDefaultColorMode();
82}
83
84HWC2::Error HWCColorMode::DeInit() {
85  color_mode_transform_map_.clear();
86  return HWC2::Error::None;
87}
88
89uint32_t HWCColorMode::GetColorModeCount() {
90  uint32_t count = UINT32(color_mode_transform_map_.size());
91  DLOGI("Supported color mode count = %d", count);
92#ifdef EXCLUDE_DISPLAY_PP
93  return count;
94#else
95  return std::max(1U, count);
96#endif
97}
98
99HWC2::Error HWCColorMode::GetColorModes(uint32_t *out_num_modes,
100                                        android_color_mode_t *out_modes) {
101  auto it = color_mode_transform_map_.begin();
102  for (auto i = 0; it != color_mode_transform_map_.end(); it++, i++) {
103    out_modes[i] = it->first;
104    DLOGI("Supports color mode[%d] = %d", i, it->first);
105  }
106  *out_num_modes = UINT32(color_mode_transform_map_.size());
107  return HWC2::Error::None;
108}
109
110HWC2::Error HWCColorMode::SetColorMode(android_color_mode_t mode) {
111  // first mode in 2D matrix is the mode (identity)
112  if (mode < HAL_COLOR_MODE_NATIVE || mode > HAL_COLOR_MODE_DISPLAY_P3) {
113    DLOGE("Could not find mode: %d", mode);
114    return HWC2::Error::BadParameter;
115  }
116  if (color_mode_transform_map_.find(mode) == color_mode_transform_map_.end()) {
117    return HWC2::Error::Unsupported;
118  }
119
120  auto status = HandleColorModeTransform(mode, current_color_transform_, color_matrix_);
121  if (status != HWC2::Error::None) {
122    DLOGE("failed for mode = %d", mode);
123  }
124
125  return status;
126}
127
128HWC2::Error HWCColorMode::SetColorTransform(const float *matrix, android_color_transform_t hint) {
129  if (!matrix || (hint < HAL_COLOR_TRANSFORM_IDENTITY ||
130      hint > HAL_COLOR_TRANSFORM_CORRECT_TRITANOPIA)) {
131    return HWC2::Error::BadParameter;
132  }
133
134  double color_matrix[kColorTransformMatrixCount] = {0};
135  CopyColorTransformMatrix(matrix, color_matrix);
136
137  auto status = HandleColorModeTransform(current_color_mode_, hint, color_matrix);
138  if (status != HWC2::Error::None) {
139    DLOGE("failed for hint = %d", hint);
140  }
141
142  return status;
143}
144
145HWC2::Error HWCColorMode::HandleColorModeTransform(android_color_mode_t mode,
146                                                   android_color_transform_t hint,
147                                                   const double *matrix) {
148  android_color_transform_t transform_hint = hint;
149  std::string color_mode_transform;
150  bool use_matrix = false;
151  if (hint != HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX) {
152    // if the mode + transfrom request from HWC matches one mode in SDM, set that
153    if (color_mode_transform.empty()) {
154      transform_hint = HAL_COLOR_TRANSFORM_IDENTITY;
155      use_matrix = true;
156    } else {
157      color_mode_transform = color_mode_transform_map_[mode][hint];
158    }
159  } else {
160    use_matrix = true;
161    transform_hint = HAL_COLOR_TRANSFORM_IDENTITY;
162  }
163
164  // if the mode count is 1, then only native mode is supported, so just apply matrix w/o
165  // setting mode
166  if (color_mode_transform_map_.size() > 1U && current_color_mode_ != mode) {
167    color_mode_transform = color_mode_transform_map_[mode][transform_hint];
168    DisplayError error = display_intf_->SetColorMode(color_mode_transform);
169    if (error != kErrorNone) {
170      DLOGE("Failed to set color_mode  = %d transform_hint = %d", mode, hint);
171      // failure to force client composition
172      return HWC2::Error::Unsupported;
173    }
174    DLOGI("Setting Color Mode = %d Transform Hint = %d Success", mode, hint);
175  }
176
177  if (use_matrix) {
178    DisplayError error = display_intf_->SetColorTransform(kColorTransformMatrixCount, matrix);
179    if (error != kErrorNone) {
180      DLOGE("Failed to set Color Transform Matrix");
181      // failure to force client composition
182      return HWC2::Error::Unsupported;
183    }
184  }
185
186  current_color_mode_ = mode;
187  current_color_transform_ = hint;
188  CopyColorTransformMatrix(matrix, color_matrix_);
189
190  return HWC2::Error::None;
191}
192
193void HWCColorMode::PopulateColorModes() {
194  uint32_t color_mode_count = 0;
195  // SDM returns modes which is string combination of mode + transform.
196  DisplayError error = display_intf_->GetColorModeCount(&color_mode_count);
197  if (error != kErrorNone || (color_mode_count == 0)) {
198#ifndef EXCLUDE_DISPLAY_PP
199    DLOGW("GetColorModeCount failed, use native color mode");
200    PopulateTransform(HAL_COLOR_MODE_NATIVE, "native", "identity");
201#endif
202    return;
203  }
204
205  DLOGV_IF(kTagQDCM, "Color Modes supported count = %d", color_mode_count);
206
207  const std::string color_transform = "identity";
208  std::vector<std::string> color_modes(color_mode_count);
209  error = display_intf_->GetColorModes(&color_mode_count, &color_modes);
210  for (uint32_t i = 0; i < color_mode_count; i++) {
211    std::string &mode_string = color_modes.at(i);
212    DLOGV_IF(kTagQDCM, "Color Mode[%d] = %s", i, mode_string.c_str());
213    AttrVal attr;
214    error = display_intf_->GetColorModeAttr(mode_string, &attr);
215    std::string color_gamut, dynamic_range, pic_quality;
216    if (!attr.empty()) {
217      for (auto &it : attr) {
218        if (it.first.find(kColorGamutAttribute) != std::string::npos) {
219          color_gamut = it.second;
220        } else if (it.first.find(kDynamicRangeAttribute) != std::string::npos) {
221          dynamic_range = it.second;
222        } else if (it.first.find(kPictureQualityAttribute) != std::string::npos) {
223          pic_quality = it.second;
224        }
225      }
226      if (dynamic_range == kHdr) {
227        continue;
228      }
229      if ((color_gamut == kNative) &&
230          (pic_quality.empty() || pic_quality == kStandard)) {
231        PopulateTransform(HAL_COLOR_MODE_NATIVE, mode_string, color_transform);
232      } else if ((color_gamut == kSrgb) &&
233                 (pic_quality.empty() || pic_quality == kStandard)) {
234        PopulateTransform(HAL_COLOR_MODE_SRGB, mode_string, color_transform);
235      } else if ((color_gamut == kDcip3) &&
236                 (pic_quality.empty() || pic_quality == kStandard)) {
237        PopulateTransform(HAL_COLOR_MODE_DISPLAY_P3, mode_string, color_transform);
238      } else if ((color_gamut == kDisplayP3) &&
239                 (pic_quality.empty() || pic_quality == kStandard)) {
240        PopulateTransform(HAL_COLOR_MODE_DISPLAY_P3, mode_string, color_transform);
241      }
242    }
243
244    // Look at the mode name, if no color gamut is found
245    if (color_gamut.empty()) {
246      if (mode_string.find("hal_native") != std::string::npos) {
247        PopulateTransform(HAL_COLOR_MODE_NATIVE, mode_string, mode_string);
248      } else if (mode_string.find("hal_srgb") != std::string::npos) {
249        PopulateTransform(HAL_COLOR_MODE_SRGB, mode_string, mode_string);
250      } else if (mode_string.find("hal_adobe") != std::string::npos) {
251        PopulateTransform(HAL_COLOR_MODE_ADOBE_RGB, mode_string, mode_string);
252      } else if (mode_string.find("hal_dci_p3") != std::string::npos) {
253        PopulateTransform(HAL_COLOR_MODE_DCI_P3, mode_string, mode_string);
254      } else if (mode_string.find("hal_display_p3") != std::string::npos) {
255        PopulateTransform(HAL_COLOR_MODE_DISPLAY_P3, mode_string, mode_string);
256      }
257    }
258  }
259}
260
261void HWCColorMode::PopulateTransform(const android_color_mode_t &mode,
262                                     const std::string &color_mode,
263                                     const std::string &color_transform) {
264  // TODO(user): Check the substring from QDCM
265  if (color_transform.find("identity") != std::string::npos) {
266    color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_IDENTITY] = color_mode;
267  } else if (color_transform.find("arbitrary") != std::string::npos) {
268    // no color mode for arbitrary
269  } else if (color_transform.find("inverse") != std::string::npos) {
270    color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_VALUE_INVERSE] = color_mode;
271  } else if (color_transform.find("grayscale") != std::string::npos) {
272    color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_GRAYSCALE] = color_mode;
273  } else if (color_transform.find("correct_protonopia") != std::string::npos) {
274    color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_CORRECT_PROTANOPIA] = color_mode;
275  } else if (color_transform.find("correct_deuteranopia") != std::string::npos) {
276    color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_CORRECT_DEUTERANOPIA] = color_mode;
277  } else if (color_transform.find("correct_tritanopia") != std::string::npos) {
278    color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_CORRECT_TRITANOPIA] = color_mode;
279  } else {
280    color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_IDENTITY] = color_mode;
281  }
282}
283
284HWC2::Error HWCColorMode::ApplyDefaultColorMode() {
285  android_color_mode_t color_mode = HAL_COLOR_MODE_NATIVE;
286  if (color_mode_transform_map_.size() == 1U) {
287    color_mode = color_mode_transform_map_.begin()->first;
288  } else if (color_mode_transform_map_.size() > 1U) {
289    std::string default_color_mode;
290    bool found = false;
291    DisplayError error = display_intf_->GetDefaultColorMode(&default_color_mode);
292    if (error == kErrorNone) {
293      // get the default mode corresponding android_color_mode_t
294      for (auto &it_mode : color_mode_transform_map_) {
295        for (auto &it : it_mode.second) {
296          if (it.second == default_color_mode) {
297            found = true;
298            break;
299          }
300        }
301        if (found) {
302          color_mode = it_mode.first;
303          break;
304        }
305      }
306    }
307
308    // return the first andrid_color_mode_t when we encouter if not found
309    if (!found) {
310      color_mode = color_mode_transform_map_.begin()->first;
311    }
312  }
313  return SetColorMode(color_mode);
314}
315
316void HWCColorMode::Dump(std::ostringstream* os) {
317  *os << "color modes supported: ";
318  for (auto it : color_mode_transform_map_) {
319    *os << it.first <<" ";
320  }
321  *os << "current mode: " << current_color_mode_ << std::endl;
322  *os << "current transform: ";
323  for (uint32_t i = 0; i < kColorTransformMatrixCount; i++) {
324    if (i % 4 == 0) {
325     *os << std::endl;
326    }
327    *os << std::fixed << std::setprecision(2) << std::setw(6) << std::setfill(' ')
328        << color_matrix_[i] << " ";
329  }
330  *os << std::endl;
331}
332
333HWCDisplay::HWCDisplay(CoreInterface *core_intf, HWCCallbacks *callbacks, DisplayType type,
334                       hwc2_display_t id, bool needs_blit, qService::QService *qservice,
335                       DisplayClass display_class, BufferAllocator *buffer_allocator)
336    : core_intf_(core_intf),
337      callbacks_(callbacks),
338      type_(type),
339      id_(id),
340      needs_blit_(needs_blit),
341      qservice_(qservice),
342      display_class_(display_class) {
343  buffer_allocator_ = static_cast<HWCBufferAllocator *>(buffer_allocator);
344}
345
346int HWCDisplay::Init() {
347  DisplayError error = core_intf_->CreateDisplay(type_, this, &display_intf_);
348  if (error != kErrorNone) {
349    DLOGE("Display create failed. Error = %d display_type %d event_handler %p disp_intf %p", error,
350          type_, this, &display_intf_);
351    return -EINVAL;
352  }
353
354  validated_.reset();
355  HWCDebugHandler::Get()->GetProperty("sys.hwc_disable_hdr", &disable_hdr_handling_);
356  if (disable_hdr_handling_) {
357    DLOGI("HDR Handling disabled");
358  }
359
360  int property_swap_interval = 1;
361  HWCDebugHandler::Get()->GetProperty("debug.egl.swapinterval", &property_swap_interval);
362  if (property_swap_interval == 0) {
363    swap_interval_zero_ = true;
364  }
365
366  client_target_ = new HWCLayer(id_, buffer_allocator_);
367
368  int blit_enabled = 0;
369  HWCDebugHandler::Get()->GetProperty("persist.hwc.blit.comp", &blit_enabled);
370  if (needs_blit_ && blit_enabled) {
371    // TODO(user): Add blit engine when needed
372  }
373
374  error = display_intf_->GetNumVariableInfoConfigs(&num_configs_);
375  if (error != kErrorNone) {
376    DLOGE("Getting config count failed. Error = %d", error);
377    return -EINVAL;
378  }
379
380  tone_mapper_ = new HWCToneMapper(buffer_allocator_);
381
382  display_intf_->GetRefreshRateRange(&min_refresh_rate_, &max_refresh_rate_);
383  current_refresh_rate_ = max_refresh_rate_;
384
385  GetUnderScanConfig();
386  DLOGI("Display created with id: %d", id_);
387
388  return 0;
389}
390
391int HWCDisplay::Deinit() {
392  DisplayError error = core_intf_->DestroyDisplay(display_intf_);
393  if (error != kErrorNone) {
394    DLOGE("Display destroy failed. Error = %d", error);
395    return -EINVAL;
396  }
397
398  delete client_target_;
399
400  if (color_mode_) {
401    color_mode_->DeInit();
402    delete color_mode_;
403  }
404
405  delete tone_mapper_;
406  tone_mapper_ = nullptr;
407
408  return 0;
409}
410
411// LayerStack operations
412HWC2::Error HWCDisplay::CreateLayer(hwc2_layer_t *out_layer_id) {
413  HWCLayer *layer = *layer_set_.emplace(new HWCLayer(id_, buffer_allocator_));
414  layer_map_.emplace(std::make_pair(layer->GetId(), layer));
415  *out_layer_id = layer->GetId();
416  geometry_changes_ |= GeometryChanges::kAdded;
417  validated_.reset();
418  return HWC2::Error::None;
419}
420
421HWCLayer *HWCDisplay::GetHWCLayer(hwc2_layer_t layer_id) {
422  const auto map_layer = layer_map_.find(layer_id);
423  if (map_layer == layer_map_.end()) {
424    DLOGE("[%" PRIu64 "] GetLayer(%" PRIu64 ") failed: no such layer", id_, layer_id);
425    return nullptr;
426  } else {
427    return map_layer->second;
428  }
429}
430
431HWC2::Error HWCDisplay::DestroyLayer(hwc2_layer_t layer_id) {
432  const auto map_layer = layer_map_.find(layer_id);
433  if (map_layer == layer_map_.end()) {
434    DLOGE("[%" PRIu64 "] destroyLayer(%" PRIu64 ") failed: no such layer", id_, layer_id);
435    return HWC2::Error::BadLayer;
436  }
437  const auto layer = map_layer->second;
438  layer_map_.erase(map_layer);
439  const auto z_range = layer_set_.equal_range(layer);
440  for (auto current = z_range.first; current != z_range.second; ++current) {
441    if (*current == layer) {
442      current = layer_set_.erase(current);
443      delete layer;
444      break;
445    }
446  }
447
448  geometry_changes_ |= GeometryChanges::kRemoved;
449  validated_.reset();
450  return HWC2::Error::None;
451}
452
453
454void HWCDisplay::BuildLayerStack() {
455  layer_stack_ = LayerStack();
456  display_rect_ = LayerRect();
457  metadata_refresh_rate_ = 0;
458  auto working_primaries = ColorPrimaries_BT709_5;
459
460  uint32_t color_mode_count = 0;
461  display_intf_->GetColorModeCount(&color_mode_count);
462
463  // Add one layer for fb target
464  // TODO(user): Add blit target layers
465  for (auto hwc_layer : layer_set_) {
466    Layer *layer = hwc_layer->GetSDMLayer();
467    layer->flags = {};   // Reset earlier flags
468    if (hwc_layer->GetClientRequestedCompositionType() == HWC2::Composition::Client) {
469      layer->flags.skip = true;
470    } else if (hwc_layer->GetClientRequestedCompositionType() == HWC2::Composition::SolidColor) {
471      layer->flags.solid_fill = true;
472    }
473
474#ifdef FEATURE_WIDE_COLOR
475    if (!hwc_layer->SupportedDataspace()) {
476        layer->flags.skip = true;
477        DLOGW_IF(kTagStrategy, "Unsupported dataspace: 0x%x", hwc_layer->GetLayerDataspace());
478    }
479#endif
480
481    working_primaries = WidestPrimaries(working_primaries,
482                                        layer->input_buffer.color_metadata.colorPrimaries);
483
484    // set default composition as GPU for SDM
485    layer->composition = kCompositionGPU;
486
487    if (swap_interval_zero_) {
488      if (layer->input_buffer.acquire_fence_fd >= 0) {
489        close(layer->input_buffer.acquire_fence_fd);
490        layer->input_buffer.acquire_fence_fd = -1;
491      }
492    }
493
494    const private_handle_t *handle =
495        reinterpret_cast<const private_handle_t *>(layer->input_buffer.buffer_id);
496    if (handle) {
497#ifdef USE_GRALLOC1
498      if (handle->buffer_type == BUFFER_TYPE_VIDEO) {
499#else
500      if (handle->bufferType == BUFFER_TYPE_VIDEO) {
501#endif
502        layer_stack_.flags.video_present = true;
503      }
504      // TZ Protected Buffer - L1
505      if (handle->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
506        layer_stack_.flags.secure_present = true;
507      }
508      // Gralloc Usage Protected Buffer - L3 - which needs to be treated as Secure & avoid fallback
509      if (handle->flags & private_handle_t::PRIV_FLAGS_PROTECTED_BUFFER) {
510        layer_stack_.flags.secure_present = true;
511      }
512    }
513
514    if (layer->flags.skip) {
515      layer_stack_.flags.skip_present = true;
516    }
517
518    if (hwc_layer->GetClientRequestedCompositionType() == HWC2::Composition::Cursor) {
519      // Currently we support only one HWCursor & only at top most z-order
520      if ((*layer_set_.rbegin())->GetId() == hwc_layer->GetId()) {
521        layer->flags.cursor = true;
522        layer_stack_.flags.cursor_present = true;
523      }
524    }
525
526    bool hdr_layer = layer->input_buffer.color_metadata.colorPrimaries == ColorPrimaries_BT2020 &&
527                     (layer->input_buffer.color_metadata.transfer == Transfer_SMPTE_ST2084 ||
528                     layer->input_buffer.color_metadata.transfer == Transfer_HLG);
529    if (hdr_layer && !disable_hdr_handling_ && color_mode_count) {
530      // dont honor HDR when its handling is disabled
531      layer->input_buffer.flags.hdr = true;
532      layer_stack_.flags.hdr_present = true;
533    }
534
535    // TODO(user): Move to a getter if this is needed at other places
536    hwc_rect_t scaled_display_frame = {INT(layer->dst_rect.left), INT(layer->dst_rect.top),
537                                       INT(layer->dst_rect.right), INT(layer->dst_rect.bottom)};
538    ApplyScanAdjustment(&scaled_display_frame);
539    hwc_layer->SetLayerDisplayFrame(scaled_display_frame);
540    // SDM requires these details even for solid fill
541    if (layer->flags.solid_fill) {
542      LayerBuffer *layer_buffer = &layer->input_buffer;
543      layer_buffer->width = UINT32(layer->dst_rect.right - layer->dst_rect.left);
544      layer_buffer->height = UINT32(layer->dst_rect.bottom - layer->dst_rect.top);
545      layer_buffer->unaligned_width = layer_buffer->width;
546      layer_buffer->unaligned_height = layer_buffer->height;
547      layer_buffer->acquire_fence_fd = -1;
548      layer_buffer->release_fence_fd = -1;
549      layer->src_rect.left = 0;
550      layer->src_rect.top = 0;
551      layer->src_rect.right = layer_buffer->width;
552      layer->src_rect.bottom = layer_buffer->height;
553    }
554
555    if (layer->frame_rate > metadata_refresh_rate_) {
556      metadata_refresh_rate_ = SanitizeRefreshRate(layer->frame_rate);
557    } else {
558      layer->frame_rate = current_refresh_rate_;
559    }
560    display_rect_ = Union(display_rect_, layer->dst_rect);
561    geometry_changes_ |= hwc_layer->GetGeometryChanges();
562
563    layer->flags.updating = true;
564    if (layer_set_.size() <= kMaxLayerCount) {
565      layer->flags.updating = IsLayerUpdating(layer);
566    }
567
568    layer_stack_.layers.push_back(layer);
569  }
570
571
572#ifdef FEATURE_WIDE_COLOR
573  for (auto hwc_layer : layer_set_) {
574    auto layer = hwc_layer->GetSDMLayer();
575    if (layer->input_buffer.color_metadata.colorPrimaries != working_primaries &&
576        !hwc_layer->SupportLocalConversion(working_primaries)) {
577      layer->flags.skip = true;
578    }
579    if (layer->flags.skip) {
580      layer_stack_.flags.skip_present = true;
581    }
582  }
583#endif
584
585  // TODO(user): Set correctly when SDM supports geometry_changes as bitmask
586  layer_stack_.flags.geometry_changed = UINT32(geometry_changes_ > 0);
587  // Append client target to the layer stack
588  layer_stack_.layers.push_back(client_target_->GetSDMLayer());
589}
590
591void HWCDisplay::BuildSolidFillStack() {
592  layer_stack_ = LayerStack();
593  display_rect_ = LayerRect();
594
595  layer_stack_.layers.push_back(solid_fill_layer_);
596  layer_stack_.flags.geometry_changed = 1U;
597  // Append client target to the layer stack
598  layer_stack_.layers.push_back(client_target_->GetSDMLayer());
599}
600
601HWC2::Error HWCDisplay::SetLayerZOrder(hwc2_layer_t layer_id, uint32_t z) {
602  const auto map_layer = layer_map_.find(layer_id);
603  if (map_layer == layer_map_.end()) {
604    DLOGE("[%" PRIu64 "] updateLayerZ failed to find layer", id_);
605    return HWC2::Error::BadLayer;
606  }
607
608  const auto layer = map_layer->second;
609  const auto z_range = layer_set_.equal_range(layer);
610  bool layer_on_display = false;
611  for (auto current = z_range.first; current != z_range.second; ++current) {
612    if (*current == layer) {
613      if ((*current)->GetZ() == z) {
614        // Don't change anything if the Z hasn't changed
615        return HWC2::Error::None;
616      }
617      current = layer_set_.erase(current);
618      layer_on_display = true;
619      break;
620    }
621  }
622
623  if (!layer_on_display) {
624    DLOGE("[%" PRIu64 "] updateLayerZ failed to find layer on display", id_);
625    return HWC2::Error::BadLayer;
626  }
627
628  layer->SetLayerZOrder(z);
629  layer_set_.emplace(layer);
630  return HWC2::Error::None;
631}
632
633HWC2::Error HWCDisplay::SetVsyncEnabled(HWC2::Vsync enabled) {
634  DLOGV("Display ID: %d enabled: %s", id_, to_string(enabled).c_str());
635  DisplayError error = kErrorNone;
636
637  if (shutdown_pending_ || !callbacks_->VsyncCallbackRegistered()) {
638    return HWC2::Error::None;
639  }
640
641  bool state;
642  if (enabled == HWC2::Vsync::Enable)
643    state = true;
644  else if (enabled == HWC2::Vsync::Disable)
645    state = false;
646  else
647    return HWC2::Error::BadParameter;
648
649  error = display_intf_->SetVSyncState(state);
650
651  if (error != kErrorNone) {
652    if (error == kErrorShutDown) {
653      shutdown_pending_ = true;
654      return HWC2::Error::None;
655    }
656    DLOGE("Failed. enabled = %s, error = %d", to_string(enabled).c_str(), error);
657    return HWC2::Error::BadDisplay;
658  }
659
660  return HWC2::Error::None;
661}
662
663HWC2::Error HWCDisplay::SetPowerMode(HWC2::PowerMode mode) {
664  DLOGV("display = %d, mode = %s", id_, to_string(mode).c_str());
665  DisplayState state = kStateOff;
666  bool flush_on_error = flush_on_error_;
667
668  if (shutdown_pending_) {
669    return HWC2::Error::None;
670  }
671
672  switch (mode) {
673    case HWC2::PowerMode::Off:
674      // During power off, all of the buffers are released.
675      // Do not flush until a buffer is successfully submitted again.
676      flush_on_error = false;
677      state = kStateOff;
678      if (tone_mapper_) {
679        tone_mapper_->Terminate();
680      }
681      break;
682    case HWC2::PowerMode::On:
683      state = kStateOn;
684      last_power_mode_ = HWC2::PowerMode::On;
685      break;
686    case HWC2::PowerMode::Doze:
687      state = kStateDoze;
688      last_power_mode_ = HWC2::PowerMode::Doze;
689      break;
690    case HWC2::PowerMode::DozeSuspend:
691      state = kStateDozeSuspend;
692      last_power_mode_ = HWC2::PowerMode::DozeSuspend;
693      break;
694    default:
695      return HWC2::Error::BadParameter;
696  }
697
698  DisplayError error = display_intf_->SetDisplayState(state);
699  validated_.reset();
700
701  if (error == kErrorNone) {
702    flush_on_error_ = flush_on_error;
703  } else {
704    if (error == kErrorShutDown) {
705      shutdown_pending_ = true;
706      return HWC2::Error::None;
707    }
708    DLOGE("Set state failed. Error = %d", error);
709    return HWC2::Error::BadParameter;
710  }
711
712  return HWC2::Error::None;
713}
714
715HWC2::Error HWCDisplay::GetClientTargetSupport(uint32_t width, uint32_t height, int32_t format,
716                                               int32_t dataspace) {
717  DisplayConfigVariableInfo variable_config;
718  display_intf_->GetFrameBufferConfig(&variable_config);
719  // TODO(user): Support scaled configurations, other formats and other dataspaces
720  if (format != HAL_PIXEL_FORMAT_RGBA_8888 || dataspace != HAL_DATASPACE_UNKNOWN ||
721      width != variable_config.x_pixels || height != variable_config.y_pixels) {
722    return HWC2::Error::Unsupported;
723  } else {
724    return HWC2::Error::None;
725  }
726}
727
728HWC2::Error HWCDisplay::GetColorModes(uint32_t *out_num_modes, android_color_mode_t *out_modes) {
729  if (out_modes) {
730    out_modes[0] = HAL_COLOR_MODE_NATIVE;
731  }
732  *out_num_modes = 1;
733
734  return HWC2::Error::None;
735}
736
737HWC2::Error HWCDisplay::GetDisplayConfigs(uint32_t *out_num_configs, hwc2_config_t *out_configs) {
738  if (out_configs == nullptr) {
739    *out_num_configs = num_configs_;
740    return HWC2::Error::None;
741  }
742
743  *out_num_configs = num_configs_;
744
745  for (uint32_t i = 0; i < num_configs_; i++) {
746    out_configs[i] = i;
747  }
748
749  return HWC2::Error::None;
750}
751
752HWC2::Error HWCDisplay::GetDisplayAttribute(hwc2_config_t config, HWC2::Attribute attribute,
753                                            int32_t *out_value) {
754  DisplayConfigVariableInfo variable_config;
755  if (GetDisplayAttributesForConfig(INT(config), &variable_config) != kErrorNone) {
756    DLOGE("Get variable config failed");
757    return HWC2::Error::BadDisplay;
758  }
759
760  switch (attribute) {
761    case HWC2::Attribute::VsyncPeriod:
762      *out_value = INT32(variable_config.vsync_period_ns);
763      break;
764    case HWC2::Attribute::Width:
765      *out_value = INT32(variable_config.x_pixels);
766      break;
767    case HWC2::Attribute::Height:
768      *out_value = INT32(variable_config.y_pixels);
769      break;
770    case HWC2::Attribute::DpiX:
771      *out_value = INT32(variable_config.x_dpi * 1000.0f);
772      break;
773    case HWC2::Attribute::DpiY:
774      *out_value = INT32(variable_config.y_dpi * 1000.0f);
775      break;
776    default:
777      DLOGW("Spurious attribute type = %s", to_string(attribute).c_str());
778      *out_value = -1;
779      return HWC2::Error::BadConfig;
780  }
781
782  return HWC2::Error::None;
783}
784
785HWC2::Error HWCDisplay::GetDisplayName(uint32_t *out_size, char *out_name) {
786  // TODO(user): Get panel name and EDID name and populate it here
787  if (out_name == nullptr) {
788    *out_size = 32;
789  } else {
790    std::string name;
791    switch (id_) {
792      case HWC_DISPLAY_PRIMARY:
793        name = "Primary Display";
794        break;
795      case HWC_DISPLAY_EXTERNAL:
796        name = "External Display";
797        break;
798      case HWC_DISPLAY_VIRTUAL:
799        name = "Virtual Display";
800        break;
801      default:
802        name = "Unknown";
803        break;
804    }
805    std::strncpy(out_name, name.c_str(), name.size());
806    *out_size = UINT32(name.size());
807  }
808  return HWC2::Error::None;
809}
810
811HWC2::Error HWCDisplay::GetDisplayType(int32_t *out_type) {
812  if (out_type != nullptr) {
813    if (id_ == HWC_DISPLAY_VIRTUAL) {
814      *out_type = HWC2_DISPLAY_TYPE_VIRTUAL;
815    } else {
816      *out_type = HWC2_DISPLAY_TYPE_PHYSICAL;
817    }
818    return HWC2::Error::None;
819  } else {
820    return HWC2::Error::BadParameter;
821  }
822}
823
824HWC2::Error HWCDisplay::GetActiveConfig(hwc2_config_t *out_config) {
825  if (out_config == nullptr) {
826    return HWC2::Error::BadDisplay;
827  }
828
829  uint32_t active_index = 0;
830  if (GetActiveDisplayConfig(&active_index) != kErrorNone) {
831    return HWC2::Error::BadConfig;
832  }
833
834  *out_config = active_index;
835
836  return HWC2::Error::None;
837}
838
839HWC2::Error HWCDisplay::SetClientTarget(buffer_handle_t target, int32_t acquire_fence,
840                                        int32_t dataspace, hwc_region_t damage) {
841  // TODO(user): SurfaceFlinger gives us a null pointer here when doing full SDE composition
842  // The error is problematic for layer caching as it would overwrite our cached client target.
843  // Reported bug 28569722 to resolve this.
844  // For now, continue to use the last valid buffer reported to us for layer caching.
845  if (target == nullptr) {
846    return HWC2::Error::None;
847  }
848
849  if (acquire_fence == 0) {
850    DLOGE("acquire_fence is zero");
851    return HWC2::Error::BadParameter;
852  }
853
854  client_target_->SetLayerBuffer(target, acquire_fence);
855  client_target_->SetLayerSurfaceDamage(damage);
856  // Ignoring dataspace for now
857  return HWC2::Error::None;
858}
859
860HWC2::Error HWCDisplay::SetActiveConfig(hwc2_config_t config) {
861  if (SetActiveDisplayConfig(config) != kErrorNone) {
862    return HWC2::Error::BadConfig;
863  }
864
865  validated_.reset();
866  return HWC2::Error::None;
867}
868
869DisplayError HWCDisplay::SetMixerResolution(uint32_t width, uint32_t height) {
870  return kErrorNotSupported;
871}
872
873void HWCDisplay::SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type) {
874  dump_frame_count_ = count;
875  dump_frame_index_ = 0;
876  dump_input_layers_ = ((bit_mask_layer_type & (1 << INPUT_LAYER_DUMP)) != 0);
877
878  if (tone_mapper_) {
879    tone_mapper_->SetFrameDumpConfig(count);
880  }
881
882  DLOGI("num_frame_dump %d, input_layer_dump_enable %d", dump_frame_count_, dump_input_layers_);
883  validated_.reset();
884}
885
886HWC2::PowerMode HWCDisplay::GetLastPowerMode() {
887  return last_power_mode_;
888}
889
890DisplayError HWCDisplay::VSync(const DisplayEventVSync &vsync) {
891  callbacks_->Vsync(id_, vsync.timestamp);
892  return kErrorNone;
893}
894
895DisplayError HWCDisplay::Refresh() {
896  return kErrorNotSupported;
897}
898
899DisplayError HWCDisplay::CECMessage(char *message) {
900  if (qservice_) {
901    qservice_->onCECMessageReceived(message, 0);
902  } else {
903    DLOGW("Qservice instance not available.");
904  }
905
906  return kErrorNone;
907}
908
909DisplayError HWCDisplay::HandleEvent(DisplayEvent event) {
910  switch (event) {
911    case kIdleTimeout:
912    case kThermalEvent:
913      validated_.reset();
914      break;
915    default:
916      DLOGW("Unknown event: %d", event);
917      break;
918  }
919
920  return kErrorNone;
921}
922
923HWC2::Error HWCDisplay::PrepareLayerStack(uint32_t *out_num_types, uint32_t *out_num_requests) {
924  layer_changes_.clear();
925  layer_requests_.clear();
926  if (shutdown_pending_) {
927    return HWC2::Error::BadDisplay;
928  }
929
930  if (!skip_prepare_) {
931    DisplayError error = display_intf_->Prepare(&layer_stack_);
932    if (error != kErrorNone) {
933      if (error == kErrorShutDown) {
934        shutdown_pending_ = true;
935      } else if (error != kErrorPermission) {
936        DLOGE("Prepare failed. Error = %d", error);
937        // To prevent surfaceflinger infinite wait, flush the previous frame during Commit()
938        // so that previous buffer and fences are released, and override the error.
939        flush_ = true;
940      }
941      return HWC2::Error::BadDisplay;
942    } else {
943      validated_.set(type_);
944    }
945  } else {
946    // Skip is not set
947    MarkLayersForGPUBypass();
948    skip_prepare_ = false;
949    DLOGI("SecureDisplay %s, Skip Prepare/Commit and Flush",
950          secure_display_active_ ? "Starting" : "Stopping");
951    flush_ = true;
952  }
953
954  for (auto hwc_layer : layer_set_) {
955    Layer *layer = hwc_layer->GetSDMLayer();
956    LayerComposition &composition = layer->composition;
957
958    if ((composition == kCompositionSDE) || (composition == kCompositionHybrid) ||
959        (composition == kCompositionBlit)) {
960      layer_requests_[hwc_layer->GetId()] = HWC2::LayerRequest::ClearClientTarget;
961    }
962
963    HWC2::Composition requested_composition = hwc_layer->GetClientRequestedCompositionType();
964    // Set SDM composition to HWC2 type in HWCLayer
965    hwc_layer->SetComposition(composition);
966    HWC2::Composition device_composition  = hwc_layer->GetDeviceSelectedCompositionType();
967    // Update the changes list only if the requested composition is different from SDM comp type
968    // TODO(user): Take Care of other comptypes(BLIT)
969    if (requested_composition != device_composition) {
970      layer_changes_[hwc_layer->GetId()] = device_composition;
971    }
972    hwc_layer->ResetValidation();
973  }
974  *out_num_types = UINT32(layer_changes_.size());
975  *out_num_requests = UINT32(layer_requests_.size());
976  skip_validate_ = false;
977  if (*out_num_types > 0) {
978    return HWC2::Error::HasChanges;
979  } else {
980    return HWC2::Error::None;
981  }
982}
983
984HWC2::Error HWCDisplay::AcceptDisplayChanges() {
985  if (layer_set_.empty()) {
986    return HWC2::Error::None;
987  }
988
989  if (!validated_.test(type_)) {
990    return HWC2::Error::NotValidated;
991  }
992
993  for (const auto& change : layer_changes_) {
994    auto hwc_layer = layer_map_[change.first];
995    auto composition = change.second;
996    if (hwc_layer != nullptr) {
997      hwc_layer->UpdateClientCompositionType(composition);
998    } else {
999      DLOGW("Invalid layer: %" PRIu64, change.first);
1000    }
1001  }
1002  return HWC2::Error::None;
1003}
1004
1005HWC2::Error HWCDisplay::GetChangedCompositionTypes(uint32_t *out_num_elements,
1006                                                   hwc2_layer_t *out_layers, int32_t *out_types) {
1007  if (layer_set_.empty()) {
1008    return HWC2::Error::None;
1009  }
1010
1011  if (!validated_.test(type_)) {
1012    DLOGW("Display is not validated");
1013    return HWC2::Error::NotValidated;
1014  }
1015
1016  *out_num_elements = UINT32(layer_changes_.size());
1017  if (out_layers != nullptr && out_types != nullptr) {
1018    int i = 0;
1019    for (auto change : layer_changes_) {
1020      out_layers[i] = change.first;
1021      out_types[i] = INT32(change.second);
1022      i++;
1023    }
1024  }
1025  return HWC2::Error::None;
1026}
1027
1028HWC2::Error HWCDisplay::GetReleaseFences(uint32_t *out_num_elements, hwc2_layer_t *out_layers,
1029                                         int32_t *out_fences) {
1030  if (out_layers != nullptr && out_fences != nullptr) {
1031    int i = 0;
1032    for (auto hwc_layer : layer_set_) {
1033      out_layers[i] = hwc_layer->GetId();
1034      out_fences[i] = hwc_layer->PopReleaseFence();
1035      i++;
1036    }
1037  }
1038  *out_num_elements = UINT32(layer_set_.size());
1039  return HWC2::Error::None;
1040}
1041
1042HWC2::Error HWCDisplay::GetDisplayRequests(int32_t *out_display_requests,
1043                                           uint32_t *out_num_elements, hwc2_layer_t *out_layers,
1044                                           int32_t *out_layer_requests) {
1045  if (layer_set_.empty()) {
1046    return HWC2::Error::None;
1047  }
1048
1049  // No display requests for now
1050  // Use for sharing blit buffers and
1051  // writing wfd buffer directly to output if there is full GPU composition
1052  // and no color conversion needed
1053  if (!validated_.test(type_)) {
1054    DLOGW("Display is not validated");
1055    return HWC2::Error::NotValidated;
1056  }
1057
1058  *out_display_requests = 0;
1059  *out_num_elements = UINT32(layer_requests_.size());
1060  if (out_layers != nullptr && out_layer_requests != nullptr) {
1061    int i = 0;
1062    for (auto &request : layer_requests_) {
1063      out_layers[i] = request.first;
1064      out_layer_requests[i] = INT32(request.second);
1065      i++;
1066    }
1067  }
1068
1069  auto client_target_layer = client_target_->GetSDMLayer();
1070  if (client_target_layer->request.flags.flip_buffer) {
1071    *out_display_requests = INT32(HWC2::DisplayRequest::FlipClientTarget);
1072  }
1073
1074  return HWC2::Error::None;
1075}
1076
1077HWC2::Error HWCDisplay::GetHdrCapabilities(uint32_t *out_num_types, int32_t *out_types,
1078                                           float *out_max_luminance,
1079                                           float *out_max_average_luminance,
1080                                           float *out_min_luminance) {
1081  DisplayConfigFixedInfo fixed_info = {};
1082  display_intf_->GetConfig(&fixed_info);
1083
1084  if (!fixed_info.hdr_supported) {
1085    *out_num_types = 0;
1086    DLOGI("HDR is not supported");
1087    return HWC2::Error::None;
1088  }
1089
1090  if (out_types == nullptr) {
1091    // 1(now) - because we support only HDR10, change when HLG & DOLBY vision are supported
1092    *out_num_types  = 1;
1093  } else {
1094    // Only HDR10 supported
1095    *out_types = HAL_HDR_HDR10;
1096    static const float kLuminanceFactor = 10000.0;
1097    // luminance is expressed in the unit of 0.0001 cd/m2, convert it to 1cd/m2.
1098    *out_max_luminance = FLOAT(fixed_info.max_luminance)/kLuminanceFactor;
1099    *out_max_average_luminance = FLOAT(fixed_info.average_luminance)/kLuminanceFactor;
1100    *out_min_luminance = FLOAT(fixed_info.min_luminance)/kLuminanceFactor;
1101  }
1102
1103  return HWC2::Error::None;
1104}
1105
1106
1107HWC2::Error HWCDisplay::CommitLayerStack(void) {
1108  if (skip_validate_ && !CanSkipValidate()) {
1109    validated_.reset(type_);
1110  }
1111
1112  if (!validated_.test(type_)) {
1113    DLOGV_IF(kTagCompManager, "Display %d is not validated", id_);
1114    return HWC2::Error::NotValidated;
1115  }
1116
1117  if (shutdown_pending_ || layer_set_.empty()) {
1118    return HWC2::Error::None;
1119  }
1120
1121  DumpInputBuffers();
1122
1123  if (!flush_) {
1124    DisplayError error = kErrorUndefined;
1125    int status = 0;
1126    if (tone_mapper_) {
1127      if (layer_stack_.flags.hdr_present) {
1128        status = tone_mapper_->HandleToneMap(&layer_stack_);
1129        if (status != 0) {
1130          DLOGE("Error handling HDR in ToneMapper");
1131        }
1132      } else {
1133        tone_mapper_->Terminate();
1134      }
1135    }
1136    error = display_intf_->Commit(&layer_stack_);
1137
1138    if (error == kErrorNone) {
1139      // A commit is successfully submitted, start flushing on failure now onwards.
1140      flush_on_error_ = true;
1141    } else {
1142      if (error == kErrorShutDown) {
1143        shutdown_pending_ = true;
1144        return HWC2::Error::Unsupported;
1145      } else if (error == kErrorNotValidated) {
1146        validated_.reset(type_);
1147        return HWC2::Error::NotValidated;
1148      } else if (error != kErrorPermission) {
1149        DLOGE("Commit failed. Error = %d", error);
1150        // To prevent surfaceflinger infinite wait, flush the previous frame during Commit()
1151        // so that previous buffer and fences are released, and override the error.
1152        flush_ = true;
1153      }
1154    }
1155  }
1156
1157  skip_validate_ = true;
1158  return HWC2::Error::None;
1159}
1160
1161HWC2::Error HWCDisplay::PostCommitLayerStack(int32_t *out_retire_fence) {
1162  auto status = HWC2::Error::None;
1163
1164  // Do no call flush on errors, if a successful buffer is never submitted.
1165  if (flush_ && flush_on_error_) {
1166    display_intf_->Flush();
1167    validated_.reset();
1168  }
1169
1170  if (tone_mapper_ && tone_mapper_->IsActive()) {
1171     tone_mapper_->PostCommit(&layer_stack_);
1172  }
1173
1174  // TODO(user): No way to set the client target release fence on SF
1175  int32_t &client_target_release_fence =
1176      client_target_->GetSDMLayer()->input_buffer.release_fence_fd;
1177  if (client_target_release_fence >= 0) {
1178    close(client_target_release_fence);
1179    client_target_release_fence = -1;
1180  }
1181
1182  for (auto hwc_layer : layer_set_) {
1183    hwc_layer->ResetGeometryChanges();
1184    Layer *layer = hwc_layer->GetSDMLayer();
1185    LayerBuffer *layer_buffer = &layer->input_buffer;
1186
1187    if (!flush_) {
1188      // If swapinterval property is set to 0 or for single buffer layers, do not update f/w
1189      // release fences and discard fences from driver
1190      if (swap_interval_zero_ || layer->flags.single_buffer) {
1191        close(layer_buffer->release_fence_fd);
1192        layer_buffer->release_fence_fd = -1;
1193      } else if (layer->composition != kCompositionGPU) {
1194        hwc_layer->PushReleaseFence(layer_buffer->release_fence_fd);
1195        layer_buffer->release_fence_fd = -1;
1196      } else {
1197        hwc_layer->PushReleaseFence(-1);
1198      }
1199    }
1200
1201    if (layer_buffer->acquire_fence_fd >= 0) {
1202      close(layer_buffer->acquire_fence_fd);
1203      layer_buffer->acquire_fence_fd = -1;
1204    }
1205    layer->request.flags = {};
1206  }
1207
1208  client_target_->GetSDMLayer()->request.flags = {};
1209  *out_retire_fence = -1;
1210  if (!flush_) {
1211    // if swapinterval property is set to 0 then close and reset the list retire fence
1212    if (swap_interval_zero_) {
1213      close(layer_stack_.retire_fence_fd);
1214      layer_stack_.retire_fence_fd = -1;
1215    }
1216    *out_retire_fence = layer_stack_.retire_fence_fd;
1217    layer_stack_.retire_fence_fd = -1;
1218
1219    if (dump_frame_count_) {
1220      dump_frame_count_--;
1221      dump_frame_index_++;
1222    }
1223  }
1224
1225  geometry_changes_ = GeometryChanges::kNone;
1226  flush_ = false;
1227
1228  return status;
1229}
1230
1231void HWCDisplay::SetIdleTimeoutMs(uint32_t timeout_ms) {
1232  return;
1233}
1234
1235DisplayError HWCDisplay::SetMaxMixerStages(uint32_t max_mixer_stages) {
1236  DisplayError error = kErrorNone;
1237
1238  if (display_intf_) {
1239    error = display_intf_->SetMaxMixerStages(max_mixer_stages);
1240    validated_.reset();
1241  }
1242
1243  return error;
1244}
1245
1246LayerBufferFormat HWCDisplay::GetSDMFormat(const int32_t &source, const int flags) {
1247  LayerBufferFormat format = kFormatInvalid;
1248  if (flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
1249    switch (source) {
1250      case HAL_PIXEL_FORMAT_RGBA_8888:
1251        format = kFormatRGBA8888Ubwc;
1252        break;
1253      case HAL_PIXEL_FORMAT_RGBX_8888:
1254        format = kFormatRGBX8888Ubwc;
1255        break;
1256      case HAL_PIXEL_FORMAT_BGR_565:
1257        format = kFormatBGR565Ubwc;
1258        break;
1259      case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
1260      case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
1261      case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
1262        format = kFormatYCbCr420SPVenusUbwc;
1263        break;
1264      case HAL_PIXEL_FORMAT_RGBA_1010102:
1265        format = kFormatRGBA1010102Ubwc;
1266        break;
1267      case HAL_PIXEL_FORMAT_RGBX_1010102:
1268        format = kFormatRGBX1010102Ubwc;
1269        break;
1270      case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
1271        format = kFormatYCbCr420TP10Ubwc;
1272        break;
1273      case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
1274        format = kFormatYCbCr420P010Ubwc;
1275        break;
1276      default:
1277        DLOGE("Unsupported format type for UBWC %d", source);
1278        return kFormatInvalid;
1279    }
1280    return format;
1281  }
1282
1283  switch (source) {
1284    case HAL_PIXEL_FORMAT_RGBA_8888:
1285      format = kFormatRGBA8888;
1286      break;
1287    case HAL_PIXEL_FORMAT_RGBA_5551:
1288      format = kFormatRGBA5551;
1289      break;
1290    case HAL_PIXEL_FORMAT_RGBA_4444:
1291      format = kFormatRGBA4444;
1292      break;
1293    case HAL_PIXEL_FORMAT_BGRA_8888:
1294      format = kFormatBGRA8888;
1295      break;
1296    case HAL_PIXEL_FORMAT_RGBX_8888:
1297      format = kFormatRGBX8888;
1298      break;
1299    case HAL_PIXEL_FORMAT_BGRX_8888:
1300      format = kFormatBGRX8888;
1301      break;
1302    case HAL_PIXEL_FORMAT_RGB_888:
1303      format = kFormatRGB888;
1304      break;
1305    case HAL_PIXEL_FORMAT_RGB_565:
1306      format = kFormatRGB565;
1307      break;
1308    case HAL_PIXEL_FORMAT_BGR_565:
1309      format = kFormatBGR565;
1310      break;
1311    case HAL_PIXEL_FORMAT_BGR_888:
1312      format = kFormatBGR888;
1313      break;
1314    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
1315    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
1316      format = kFormatYCbCr420SemiPlanarVenus;
1317      break;
1318    case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
1319      format = kFormatYCrCb420SemiPlanarVenus;
1320      break;
1321    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
1322      format = kFormatYCbCr420SPVenusUbwc;
1323      break;
1324    case HAL_PIXEL_FORMAT_YV12:
1325      format = kFormatYCrCb420PlanarStride16;
1326      break;
1327    case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1328      format = kFormatYCrCb420SemiPlanar;
1329      break;
1330    case HAL_PIXEL_FORMAT_YCbCr_420_SP:
1331      format = kFormatYCbCr420SemiPlanar;
1332      break;
1333    case HAL_PIXEL_FORMAT_YCbCr_422_SP:
1334      format = kFormatYCbCr422H2V1SemiPlanar;
1335      break;
1336    case HAL_PIXEL_FORMAT_YCbCr_422_I:
1337      format = kFormatYCbCr422H2V1Packed;
1338      break;
1339    case HAL_PIXEL_FORMAT_CbYCrY_422_I:
1340      format = kFormatCbYCrY422H2V1Packed;
1341      break;
1342    case HAL_PIXEL_FORMAT_RGBA_1010102:
1343      format = kFormatRGBA1010102;
1344      break;
1345    case HAL_PIXEL_FORMAT_ARGB_2101010:
1346      format = kFormatARGB2101010;
1347      break;
1348    case HAL_PIXEL_FORMAT_RGBX_1010102:
1349      format = kFormatRGBX1010102;
1350      break;
1351    case HAL_PIXEL_FORMAT_XRGB_2101010:
1352      format = kFormatXRGB2101010;
1353      break;
1354    case HAL_PIXEL_FORMAT_BGRA_1010102:
1355      format = kFormatBGRA1010102;
1356      break;
1357    case HAL_PIXEL_FORMAT_ABGR_2101010:
1358      format = kFormatABGR2101010;
1359      break;
1360    case HAL_PIXEL_FORMAT_BGRX_1010102:
1361      format = kFormatBGRX1010102;
1362      break;
1363    case HAL_PIXEL_FORMAT_XBGR_2101010:
1364      format = kFormatXBGR2101010;
1365      break;
1366    case HAL_PIXEL_FORMAT_YCbCr_420_P010:
1367      format = kFormatYCbCr420P010;
1368      break;
1369    case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
1370      format = kFormatYCbCr420TP10Ubwc;
1371      break;
1372    case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
1373      format = kFormatYCbCr420P010Ubwc;
1374      break;
1375    default:
1376      DLOGW("Unsupported format type = %d", source);
1377      return kFormatInvalid;
1378  }
1379
1380  return format;
1381}
1382
1383void HWCDisplay::DumpInputBuffers() {
1384  char dir_path[PATH_MAX];
1385
1386  if (!dump_frame_count_ || flush_ || !dump_input_layers_) {
1387    return;
1388  }
1389
1390  snprintf(dir_path, sizeof(dir_path), "%s/frame_dump_%s", HWCDebugHandler::DumpDir(),
1391           GetDisplayString());
1392
1393  if (mkdir(dir_path, 0777) != 0 && errno != EEXIST) {
1394    DLOGW("Failed to create %s directory errno = %d, desc = %s", dir_path, errno, strerror(errno));
1395    return;
1396  }
1397
1398  // if directory exists already, need to explicitly change the permission.
1399  if (errno == EEXIST && chmod(dir_path, 0777) != 0) {
1400    DLOGW("Failed to change permissions on %s directory", dir_path);
1401    return;
1402  }
1403
1404  for (uint32_t i = 0; i < layer_stack_.layers.size(); i++) {
1405    auto layer = layer_stack_.layers.at(i);
1406    const private_handle_t *pvt_handle =
1407        reinterpret_cast<const private_handle_t *>(layer->input_buffer.buffer_id);
1408    auto acquire_fence_fd = layer->input_buffer.acquire_fence_fd;
1409
1410    if (acquire_fence_fd >= 0) {
1411      int error = sync_wait(acquire_fence_fd, 1000);
1412      if (error < 0) {
1413        DLOGW("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
1414        return;
1415      }
1416    }
1417
1418    if (pvt_handle && pvt_handle->base) {
1419      char dump_file_name[PATH_MAX];
1420      size_t result = 0;
1421
1422      snprintf(dump_file_name, sizeof(dump_file_name), "%s/input_layer%d_%dx%d_%s_frame%d.raw",
1423               dir_path, i, pvt_handle->width, pvt_handle->height,
1424               qdutils::GetHALPixelFormatString(pvt_handle->format), dump_frame_index_);
1425
1426      FILE *fp = fopen(dump_file_name, "w+");
1427      if (fp) {
1428        result = fwrite(reinterpret_cast<void *>(pvt_handle->base), pvt_handle->size, 1, fp);
1429        fclose(fp);
1430      }
1431
1432      DLOGI("Frame Dump %s: is %s", dump_file_name, result ? "Successful" : "Failed");
1433    }
1434  }
1435}
1436
1437void HWCDisplay::DumpOutputBuffer(const BufferInfo &buffer_info, void *base, int fence) {
1438  char dir_path[PATH_MAX];
1439
1440  snprintf(dir_path, sizeof(dir_path), "%s/frame_dump_%s", HWCDebugHandler::DumpDir(),
1441           GetDisplayString());
1442
1443  if (mkdir(dir_path, 777) != 0 && errno != EEXIST) {
1444    DLOGW("Failed to create %s directory errno = %d, desc = %s", dir_path, errno, strerror(errno));
1445    return;
1446  }
1447
1448  // if directory exists already, need to explicitly change the permission.
1449  if (errno == EEXIST && chmod(dir_path, 0777) != 0) {
1450    DLOGW("Failed to change permissions on %s directory", dir_path);
1451    return;
1452  }
1453
1454  if (base) {
1455    char dump_file_name[PATH_MAX];
1456    size_t result = 0;
1457
1458    if (fence >= 0) {
1459      int error = sync_wait(fence, 1000);
1460      if (error < 0) {
1461        DLOGW("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
1462        return;
1463      }
1464    }
1465
1466    snprintf(dump_file_name, sizeof(dump_file_name), "%s/output_layer_%dx%d_%s_frame%d.raw",
1467             dir_path, buffer_info.buffer_config.width, buffer_info.buffer_config.height,
1468             GetFormatString(buffer_info.buffer_config.format), dump_frame_index_);
1469
1470    FILE *fp = fopen(dump_file_name, "w+");
1471    if (fp) {
1472      result = fwrite(base, buffer_info.alloc_buffer_info.size, 1, fp);
1473      fclose(fp);
1474    }
1475
1476    DLOGI("Frame Dump of %s is %s", dump_file_name, result ? "Successful" : "Failed");
1477  }
1478}
1479
1480const char *HWCDisplay::GetDisplayString() {
1481  switch (type_) {
1482    case kPrimary:
1483      return "primary";
1484    case kHDMI:
1485      return "hdmi";
1486    case kVirtual:
1487      return "virtual";
1488    default:
1489      return "invalid";
1490  }
1491}
1492
1493int HWCDisplay::SetFrameBufferResolution(uint32_t x_pixels, uint32_t y_pixels) {
1494  if (x_pixels <= 0 || y_pixels <= 0) {
1495    DLOGW("Unsupported config: x_pixels=%d, y_pixels=%d", x_pixels, y_pixels);
1496    return -EINVAL;
1497  }
1498
1499  DisplayConfigVariableInfo fb_config;
1500  DisplayError error = display_intf_->GetFrameBufferConfig(&fb_config);
1501  if (error != kErrorNone) {
1502    DLOGV("Get frame buffer config failed. Error = %d", error);
1503    return -EINVAL;
1504  }
1505
1506  fb_config.x_pixels = x_pixels;
1507  fb_config.y_pixels = y_pixels;
1508
1509  error = display_intf_->SetFrameBufferConfig(fb_config);
1510  if (error != kErrorNone) {
1511    DLOGV("Set frame buffer config failed. Error = %d", error);
1512    return -EINVAL;
1513  }
1514
1515  // Create rects to represent the new source and destination crops
1516  LayerRect crop = LayerRect(0, 0, FLOAT(x_pixels), FLOAT(y_pixels));
1517  LayerRect dst = LayerRect(0, 0, FLOAT(fb_config.x_pixels), FLOAT(fb_config.y_pixels));
1518  auto client_target_layer = client_target_->GetSDMLayer();
1519  client_target_layer->src_rect = crop;
1520  client_target_layer->dst_rect = dst;
1521
1522  int aligned_width;
1523  int aligned_height;
1524  uint32_t usage = GRALLOC_USAGE_HW_FB;
1525  int format = HAL_PIXEL_FORMAT_RGBA_8888;
1526  int ubwc_disabled = 0;
1527  int flags = 0;
1528
1529  // By default UBWC is enabled and below property is global enable/disable for all
1530  // buffers allocated through gralloc , including framebuffer targets.
1531  HWCDebugHandler::Get()->GetProperty("debug.gralloc.gfx_ubwc_disable", &ubwc_disabled);
1532  if (!ubwc_disabled) {
1533    usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
1534    flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
1535  }
1536
1537#ifdef USE_GRALLOC1
1538  buffer_allocator_->GetAlignedWidthAndHeight(INT(x_pixels), INT(y_pixels), format, usage,
1539                                              &aligned_width, &aligned_height);
1540#else
1541  AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(INT(x_pixels), INT(y_pixels), format,
1542                                                        INT(usage), aligned_width, aligned_height);
1543#endif
1544
1545  // TODO(user): How does the dirty region get set on the client target? File bug on Google
1546  client_target_layer->composition = kCompositionGPUTarget;
1547  client_target_layer->input_buffer.format = GetSDMFormat(format, flags);
1548  client_target_layer->input_buffer.width = UINT32(aligned_width);
1549  client_target_layer->input_buffer.height = UINT32(aligned_height);
1550  client_target_layer->input_buffer.unaligned_width = x_pixels;
1551  client_target_layer->input_buffer.unaligned_height = y_pixels;
1552  client_target_layer->plane_alpha = 255;
1553
1554  DLOGI("New framebuffer resolution (%dx%d)", fb_config.x_pixels, fb_config.y_pixels);
1555
1556  return 0;
1557}
1558
1559void HWCDisplay::GetFrameBufferResolution(uint32_t *x_pixels, uint32_t *y_pixels) {
1560  DisplayConfigVariableInfo fb_config;
1561  display_intf_->GetFrameBufferConfig(&fb_config);
1562
1563  *x_pixels = fb_config.x_pixels;
1564  *y_pixels = fb_config.y_pixels;
1565}
1566
1567DisplayError HWCDisplay::GetMixerResolution(uint32_t *x_pixels, uint32_t *y_pixels) {
1568  return display_intf_->GetMixerResolution(x_pixels, y_pixels);
1569}
1570
1571void HWCDisplay::GetPanelResolution(uint32_t *x_pixels, uint32_t *y_pixels) {
1572  DisplayConfigVariableInfo display_config;
1573  uint32_t active_index = 0;
1574
1575  display_intf_->GetActiveConfig(&active_index);
1576  display_intf_->GetConfig(active_index, &display_config);
1577
1578  *x_pixels = display_config.x_pixels;
1579  *y_pixels = display_config.y_pixels;
1580}
1581
1582int HWCDisplay::SetDisplayStatus(DisplayStatus display_status) {
1583  int status = 0;
1584
1585  switch (display_status) {
1586    case kDisplayStatusResume:
1587      display_paused_ = false;
1588    case kDisplayStatusOnline:
1589      status = INT32(SetPowerMode(HWC2::PowerMode::On));
1590      break;
1591    case kDisplayStatusPause:
1592      display_paused_ = true;
1593    case kDisplayStatusOffline:
1594      status = INT32(SetPowerMode(HWC2::PowerMode::Off));
1595      break;
1596    default:
1597      DLOGW("Invalid display status %d", display_status);
1598      return -EINVAL;
1599  }
1600
1601  if (display_status == kDisplayStatusResume || display_status == kDisplayStatusPause) {
1602    callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
1603    validated_.reset();
1604  }
1605
1606  return status;
1607}
1608
1609HWC2::Error HWCDisplay::SetCursorPosition(hwc2_layer_t layer, int x, int y) {
1610  if (shutdown_pending_) {
1611    return HWC2::Error::None;
1612  }
1613
1614  HWCLayer *hwc_layer = GetHWCLayer(layer);
1615  if (hwc_layer == nullptr) {
1616    return HWC2::Error::BadLayer;
1617  }
1618  if (hwc_layer->GetDeviceSelectedCompositionType() != HWC2::Composition::Cursor) {
1619    return HWC2::Error::None;
1620  }
1621  if (!skip_validate_ && validated_.test(type_)) {
1622    // the device is currently in the middle of the validate/present sequence,
1623    // cannot set the Position(as per HWC2 spec)
1624    return HWC2::Error::NotValidated;
1625  }
1626
1627  DisplayState state;
1628  if (display_intf_->GetDisplayState(&state) == kErrorNone) {
1629    if (state != kStateOn) {
1630      return HWC2::Error::None;
1631    }
1632  }
1633
1634  // TODO(user): HWC1.5 was not letting SetCursorPosition before validateDisplay,
1635  // but HWC2.0 doesn't let setting cursor position after validate before present.
1636  // Need to revisit.
1637
1638  auto error = display_intf_->SetCursorPosition(x, y);
1639  if (error != kErrorNone) {
1640    if (error == kErrorShutDown) {
1641      shutdown_pending_ = true;
1642      return HWC2::Error::None;
1643    }
1644
1645    DLOGE("Failed for x = %d y = %d, Error = %d", x, y, error);
1646    return HWC2::Error::BadDisplay;
1647  }
1648
1649  return HWC2::Error::None;
1650}
1651
1652int HWCDisplay::OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level) {
1653  DisplayError error = display_intf_->OnMinHdcpEncryptionLevelChange(min_enc_level);
1654  if (error != kErrorNone) {
1655    DLOGE("Failed. Error = %d", error);
1656    return -1;
1657  }
1658
1659  validated_.reset();
1660  return 0;
1661}
1662
1663void HWCDisplay::MarkLayersForGPUBypass() {
1664  for (auto hwc_layer : layer_set_) {
1665    auto layer = hwc_layer->GetSDMLayer();
1666    layer->composition = kCompositionSDE;
1667  }
1668  validated_.set(type_);
1669}
1670
1671void HWCDisplay::MarkLayersForClientComposition() {
1672  // ClientComposition - GPU comp, to acheive this, set skip flag so that
1673  // SDM does not handle this layer and hwc_layer composition will be
1674  // set correctly at the end of Prepare.
1675  for (auto hwc_layer : layer_set_) {
1676    Layer *layer = hwc_layer->GetSDMLayer();
1677    layer->flags.skip = true;
1678  }
1679}
1680
1681void HWCDisplay::ApplyScanAdjustment(hwc_rect_t *display_frame) {
1682}
1683
1684int HWCDisplay::SetPanelBrightness(int level) {
1685  int ret = 0;
1686  if (display_intf_) {
1687    ret = display_intf_->SetPanelBrightness(level);
1688    validated_.reset();
1689  } else {
1690    ret = -EINVAL;
1691  }
1692
1693  return ret;
1694}
1695
1696int HWCDisplay::GetPanelBrightness(int *level) {
1697  return display_intf_->GetPanelBrightness(level);
1698}
1699
1700int HWCDisplay::ToggleScreenUpdates(bool enable) {
1701  display_paused_ = enable ? false : true;
1702  callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
1703  validated_.reset();
1704  return 0;
1705}
1706
1707int HWCDisplay::ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload,
1708                                     PPDisplayAPIPayload *out_payload,
1709                                     PPPendingParams *pending_action) {
1710  int ret = 0;
1711
1712  if (display_intf_)
1713    ret = display_intf_->ColorSVCRequestRoute(in_payload, out_payload, pending_action);
1714  else
1715    ret = -EINVAL;
1716
1717  return ret;
1718}
1719
1720void HWCDisplay::SolidFillPrepare() {
1721  if (solid_fill_enable_) {
1722    if (solid_fill_layer_ == NULL) {
1723      // Create a dummy layer here
1724      solid_fill_layer_ = new Layer();
1725    }
1726    uint32_t primary_width = 0, primary_height = 0;
1727    GetMixerResolution(&primary_width, &primary_height);
1728
1729    LayerBuffer *layer_buffer = &solid_fill_layer_->input_buffer;
1730    layer_buffer->width = primary_width;
1731    layer_buffer->height = primary_height;
1732    layer_buffer->unaligned_width = primary_width;
1733    layer_buffer->unaligned_height = primary_height;
1734    layer_buffer->acquire_fence_fd = -1;
1735    layer_buffer->release_fence_fd = -1;
1736
1737    LayerRect rect;
1738    rect.top = 0; rect.left = 0;
1739    rect.right = primary_width;
1740    rect.bottom = primary_height;
1741
1742    solid_fill_layer_->composition = kCompositionGPU;
1743    solid_fill_layer_->src_rect = rect;
1744    solid_fill_layer_->dst_rect = rect;
1745
1746    solid_fill_layer_->blending = kBlendingPremultiplied;
1747    solid_fill_layer_->solid_fill_color = solid_fill_color_;
1748    solid_fill_layer_->frame_rate = 60;
1749    solid_fill_layer_->visible_regions.push_back(solid_fill_layer_->dst_rect);
1750    solid_fill_layer_->flags.updating = 1;
1751    solid_fill_layer_->flags.solid_fill = true;
1752  } else {
1753    // delete the dummy layer
1754    delete solid_fill_layer_;
1755    solid_fill_layer_ = NULL;
1756  }
1757
1758  if (solid_fill_enable_ && solid_fill_layer_) {
1759    BuildSolidFillStack();
1760    MarkLayersForGPUBypass();
1761  }
1762
1763  return;
1764}
1765
1766void HWCDisplay::SolidFillCommit() {
1767  if (solid_fill_enable_ && solid_fill_layer_) {
1768    LayerBuffer *layer_buffer = &solid_fill_layer_->input_buffer;
1769    if (layer_buffer->release_fence_fd > 0) {
1770      close(layer_buffer->release_fence_fd);
1771      layer_buffer->release_fence_fd = -1;
1772    }
1773    if (layer_stack_.retire_fence_fd > 0) {
1774      close(layer_stack_.retire_fence_fd);
1775      layer_stack_.retire_fence_fd = -1;
1776    }
1777  }
1778}
1779
1780int HWCDisplay::GetVisibleDisplayRect(hwc_rect_t *visible_rect) {
1781  if (!IsValid(display_rect_)) {
1782    return -EINVAL;
1783  }
1784
1785  visible_rect->left = INT(display_rect_.left);
1786  visible_rect->top = INT(display_rect_.top);
1787  visible_rect->right = INT(display_rect_.right);
1788  visible_rect->bottom = INT(display_rect_.bottom);
1789  DLOGI("Dpy = %d Visible Display Rect(%d %d %d %d)", visible_rect->left, visible_rect->top,
1790        visible_rect->right, visible_rect->bottom);
1791
1792  return 0;
1793}
1794
1795void HWCDisplay::SetSecureDisplay(bool secure_display_active) {
1796  secure_display_active_ = secure_display_active;
1797  return;
1798}
1799
1800int HWCDisplay::SetActiveDisplayConfig(uint32_t config) {
1801  int status = (display_intf_->SetActiveConfig(config) == kErrorNone) ? 0 : -1;
1802  validated_.reset();
1803  return status;
1804}
1805
1806int HWCDisplay::GetActiveDisplayConfig(uint32_t *config) {
1807  return display_intf_->GetActiveConfig(config) == kErrorNone ? 0 : -1;
1808}
1809
1810int HWCDisplay::GetDisplayConfigCount(uint32_t *count) {
1811  return display_intf_->GetNumVariableInfoConfigs(count) == kErrorNone ? 0 : -1;
1812}
1813
1814int HWCDisplay::GetDisplayAttributesForConfig(int config,
1815                                            DisplayConfigVariableInfo *display_attributes) {
1816  return display_intf_->GetConfig(UINT32(config), display_attributes) == kErrorNone ? 0 : -1;
1817}
1818
1819bool HWCDisplay::SingleLayerUpdating(void) {
1820  uint32_t updating_count = 0;
1821
1822  for (uint i = 0; i < layer_stack_.layers.size(); i++) {
1823    auto layer = layer_stack_.layers.at(i);
1824    if (layer->flags.updating) {
1825      updating_count++;
1826    }
1827  }
1828
1829  return (updating_count == 1);
1830}
1831
1832bool HWCDisplay::IsLayerUpdating(const Layer *layer) {
1833  // Layer should be considered updating if
1834  //   a) layer is in single buffer mode, or
1835  //   b) valid dirty_regions(android specific hint for updating status), or
1836  //   c) layer stack geometry has changed (TODO(user): Remove when SDM accepts
1837  //      geometry_changed as bit fields).
1838  return (layer->flags.single_buffer || IsSurfaceUpdated(layer->dirty_regions) ||
1839          geometry_changes_);
1840}
1841
1842bool HWCDisplay::IsSurfaceUpdated(const std::vector<LayerRect> &dirty_regions) {
1843  // based on dirty_regions determine if its updating
1844  // dirty_rect count = 0 - whole layer - updating.
1845  // dirty_rect count = 1 or more valid rects - updating.
1846  // dirty_rect count = 1 with (0,0,0,0) - not updating.
1847  return (dirty_regions.empty() || IsValid(dirty_regions.at(0)));
1848}
1849
1850uint32_t HWCDisplay::SanitizeRefreshRate(uint32_t req_refresh_rate) {
1851  uint32_t refresh_rate = req_refresh_rate;
1852
1853  if (refresh_rate < min_refresh_rate_) {
1854    // Pick the next multiple of request which is within the range
1855    refresh_rate =
1856        (((min_refresh_rate_ / refresh_rate) + ((min_refresh_rate_ % refresh_rate) ? 1 : 0)) *
1857         refresh_rate);
1858  }
1859
1860  if (refresh_rate > max_refresh_rate_) {
1861    refresh_rate = max_refresh_rate_;
1862  }
1863
1864  return refresh_rate;
1865}
1866
1867DisplayClass HWCDisplay::GetDisplayClass() {
1868  return display_class_;
1869}
1870
1871void HWCDisplay::CloseAcquireFds() {
1872  for (auto hwc_layer : layer_set_) {
1873    auto layer = hwc_layer->GetSDMLayer();
1874    if (layer->input_buffer.acquire_fence_fd >= 0) {
1875      close(layer->input_buffer.acquire_fence_fd);
1876      layer->input_buffer.acquire_fence_fd = -1;
1877    }
1878  }
1879  int32_t &client_target_acquire_fence =
1880      client_target_->GetSDMLayer()->input_buffer.acquire_fence_fd;
1881  if (client_target_acquire_fence >= 0) {
1882    close(client_target_acquire_fence);
1883    client_target_acquire_fence = -1;
1884  }
1885}
1886
1887std::string HWCDisplay::Dump() {
1888  std::ostringstream os;
1889  os << "-------------------------------" << std::endl;
1890  os << "HWC2 display_id: " << id_ << std::endl;
1891  for (auto layer : layer_set_) {
1892    auto sdm_layer = layer->GetSDMLayer();
1893    auto transform = sdm_layer->transform;
1894    os << "layer: " << std::setw(4) << layer->GetId();
1895    os << " z: " << layer->GetZ();
1896    os << " compositon: " <<
1897          to_string(layer->GetClientRequestedCompositionType()).c_str();
1898    os << "/" <<
1899          to_string(layer->GetDeviceSelectedCompositionType()).c_str();
1900    os << " alpha: " << std::to_string(sdm_layer->plane_alpha).c_str();
1901    os << " format: " << std::setw(22) << GetFormatString(sdm_layer->input_buffer.format);
1902    os << " dataspace:" << std::hex << "0x" << std::setw(8) << std::setfill('0')
1903       << layer->GetLayerDataspace() << std::dec << std::setfill(' ');
1904    os << " transform: " << transform.rotation << "/" << transform.flip_horizontal <<
1905          "/"<< transform.flip_vertical;
1906    os << " buffer_id: " << std::hex << "0x" << sdm_layer->input_buffer.buffer_id << std::dec
1907       << std::endl;
1908  }
1909  if (color_mode_) {
1910    color_mode_->Dump(&os);
1911  }
1912  os << "-------------------------------" << std::endl;
1913  return os.str();
1914}
1915
1916bool HWCDisplay::CanSkipValidate() {
1917  // Layer Stack checks
1918  if (layer_stack_.flags.hdr_present && (tone_mapper_ && tone_mapper_->IsActive())) {
1919    return false;
1920  }
1921
1922  for (auto hwc_layer : layer_set_) {
1923    if (hwc_layer->NeedsValidation()) {
1924      return false;
1925    }
1926
1927    // Do not allow Skip Validate, if any layer needs GPU Composition.
1928    if (hwc_layer->GetDeviceSelectedCompositionType() == HWC2::Composition::Client) {
1929      return false;
1930    }
1931  }
1932
1933  return true;
1934}
1935
1936}  // namespace sdm
1937