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