hwc_display.cpp revision c25b1e71c5c04691c5fa3936b9a37c94e69a2e03
1/*
2 * Copyright (c) 2014-2016, 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 <gr.h>
23#include <gralloc_priv.h>
24#include <math.h>
25#include <sync/sync.h>
26#include <utils/constants.h>
27#include <utils/debug.h>
28#include <utils/formats.h>
29#include <utils/rect.h>
30
31#include <algorithm>
32#include <map>
33#include <sstream>
34#include <string>
35#include <utility>
36#include <vector>
37
38#include "hwc_display.h"
39#include "hwc_debugger.h"
40#include "blit_engine_c2d.h"
41
42#ifdef QTI_BSP
43#include <hardware/display_defs.h>
44#endif
45
46#define __CLASS__ "HWCDisplay"
47
48namespace sdm {
49
50static void ApplyDeInterlaceAdjustment(Layer *layer) {
51  // De-interlacing adjustment
52  if (layer->input_buffer->flags.interlace) {
53    float height = (layer->src_rect.bottom - layer->src_rect.top) / 2.0f;
54    layer->src_rect.top = ROUND_UP_ALIGN_DOWN(layer->src_rect.top / 2.0f, 2);
55    layer->src_rect.bottom = layer->src_rect.top + floorf(height);
56  }
57}
58
59HWCColorMode::HWCColorMode(DisplayInterface *display_intf) : display_intf_(display_intf) {}
60
61HWC2::Error HWCColorMode::Init() {
62  PopulateColorModes();
63  return HWC2::Error::None;
64}
65
66HWC2::Error HWCColorMode::DeInit() {
67  color_mode_transform_map_.clear();
68  return HWC2::Error::None;
69}
70
71uint32_t HWCColorMode::GetColorModeCount() {
72  uint32_t count = UINT32(color_mode_transform_map_.size());
73  DLOGI("Supported color mode count = %d", count);
74
75  return std::max(1U, count);
76}
77
78HWC2::Error HWCColorMode::GetColorModes(uint32_t *out_num_modes,
79                                        android_color_mode_t *out_modes) {
80  auto it = color_mode_transform_map_.begin();
81  for (auto i = 0; it != color_mode_transform_map_.end(); it++, i++) {
82    out_modes[i] = it->first;
83    DLOGI("Supports color mode[%d] = %d", i, it->first);
84  }
85  *out_num_modes = UINT32(color_mode_transform_map_.size());
86  return HWC2::Error::None;
87}
88
89HWC2::Error HWCColorMode::SetColorMode(android_color_mode_t mode) {
90  // first mode in 2D matrix is the mode (identity)
91  auto status = HandleColorModeTransform(mode, current_color_transform_, color_matrix_);
92  if (status != HWC2::Error::None) {
93    DLOGE("failed for mode = %d", mode);
94  }
95
96  return status;
97}
98
99HWC2::Error HWCColorMode::SetColorTransform(const float *matrix, android_color_transform_t hint) {
100  if (!matrix) {
101    return HWC2::Error::BadParameter;
102  }
103
104  double color_matrix[kColorTransformMatrixCount] = {0};
105  CopyColorTransformMatrix(matrix, color_matrix);
106
107  auto status = HandleColorModeTransform(current_color_mode_, hint, color_matrix);
108  if (status != HWC2::Error::None) {
109    DLOGE("failed for hint = %d", hint);
110  }
111
112  return status;
113}
114
115HWC2::Error HWCColorMode::HandleColorModeTransform(android_color_mode_t mode,
116                                                   android_color_transform_t hint,
117                                                   const double *matrix) {
118  android_color_transform_t transform_hint = hint;
119  std::string color_mode_transform;
120  bool use_matrix = false;
121  if (hint != HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX) {
122    // if the mode + transfrom request from HWC matches one mode in SDM, set that
123    color_mode_transform = color_mode_transform_map_[mode][hint];
124    if (color_mode_transform.empty()) {
125      transform_hint = HAL_COLOR_TRANSFORM_IDENTITY;
126      use_matrix = true;
127    }
128  } else {
129    use_matrix = true;
130    transform_hint = HAL_COLOR_TRANSFORM_IDENTITY;
131  }
132
133  // if the mode count is 1, then only native mode is supported, so just apply matrix w/o
134  // setting mode
135  if (color_mode_transform_map_.size() > 1U) {
136    color_mode_transform = color_mode_transform_map_[mode][transform_hint];
137    DisplayError error = display_intf_->SetColorMode(color_mode_transform);
138    if (error != kErrorNone) {
139      DLOGE("Failed to set color_mode  = %d transform_hint = %d", mode, hint);
140      // failure to force client composition
141      return HWC2::Error::Unsupported;
142    }
143  }
144
145  if (use_matrix) {
146    DisplayError error = display_intf_->SetColorTransform(kColorTransformMatrixCount, matrix);
147    if (error != kErrorNone) {
148      DLOGE("Failed to set Color Transform Matrix");
149      // failure to force client composition
150      return HWC2::Error::Unsupported;
151    }
152  }
153
154  current_color_mode_ = mode;
155  current_color_transform_ = hint;
156  CopyColorTransformMatrix(matrix, color_matrix_);
157  DLOGI("Setting Color Mode = %d Transform Hint = %d Success", mode, hint);
158
159  return HWC2::Error::None;
160}
161
162void HWCColorMode::PopulateColorModes() {
163  uint32_t color_mode_count = 0;
164  // SDM returns modes which is string combination of mode + transform.
165  DisplayError error = display_intf_->GetColorModeCount(&color_mode_count);
166  if (error != kErrorNone || (color_mode_count == 0)) {
167    DLOGW("GetColorModeCount failed, use native color mode");
168    PopulateTransform(HAL_COLOR_MODE_NATIVE, "native_identity");
169    return;
170  }
171
172  DLOGI("Color Modes supported count = %d", color_mode_count);
173
174  std::vector<std::string> color_modes(color_mode_count);
175  error = display_intf_->GetColorModes(&color_mode_count, &color_modes);
176
177  for (uint32_t i = 0; i < color_mode_count; i++) {
178    std::string &mode_string = color_modes.at(i);
179    DLOGI("Color Mode[%d] = %s", i, mode_string.c_str());
180    if (mode_string.find("hal_native") != std::string::npos) {
181      PopulateTransform(HAL_COLOR_MODE_NATIVE, mode_string);
182    } else if (mode_string.find("hal_srgb") != std::string::npos) {
183      PopulateTransform(HAL_COLOR_MODE_SRGB, mode_string);
184    } else if (mode_string.find("hal_adobe") != std::string::npos) {
185      PopulateTransform(HAL_COLOR_MODE_ADOBE_RGB, mode_string);
186    } else if (mode_string.find("hal_dci_p3") != std::string::npos) {
187      PopulateTransform(HAL_COLOR_MODE_DCI_P3, mode_string);
188    }
189  }
190}
191
192void HWCColorMode::PopulateTransform(const android_color_mode_t &mode,
193                                     const std::string &color_transform) {
194  // TODO(user): Check the substring from QDCM
195  if (color_transform.find("identity") != std::string::npos) {
196    color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_IDENTITY] = color_transform;
197  } else if (color_transform.find("arbitrary") != std::string::npos) {
198    // no color mode for arbitrary
199  } else if (color_transform.find("inverse") != std::string::npos) {
200    color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_VALUE_INVERSE] = color_transform;
201  } else if (color_transform.find("grayscale") != std::string::npos) {
202    color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_GRAYSCALE] = color_transform;
203  } else if (color_transform.find("correct_protonopia") != std::string::npos) {
204    color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_CORRECT_PROTANOPIA] = color_transform;
205  } else if (color_transform.find("correct_deuteranopia") != std::string::npos) {
206    color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_CORRECT_DEUTERANOPIA] = color_transform;
207  } else if (color_transform.find("correct_tritanopia") != std::string::npos) {
208    color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_CORRECT_TRITANOPIA] = color_transform;
209  }
210}
211
212HWCDisplay::HWCDisplay(CoreInterface *core_intf, HWCCallbacks *callbacks, DisplayType type,
213                       hwc2_display_t id, bool needs_blit, qService::QService *qservice,
214                       DisplayClass display_class)
215    : core_intf_(core_intf),
216      callbacks_(callbacks),
217      type_(type),
218      id_(id),
219      needs_blit_(needs_blit),
220      qservice_(qservice),
221      display_class_(display_class) {
222}
223
224int HWCDisplay::Init() {
225  DisplayError error = core_intf_->CreateDisplay(type_, this, &display_intf_);
226  if (error != kErrorNone) {
227    DLOGE("Display create failed. Error = %d display_type %d event_handler %p disp_intf %p", error,
228          type_, this, &display_intf_);
229    return -EINVAL;
230  }
231
232  int property_swap_interval = 1;
233  HWCDebugHandler::Get()->GetProperty("debug.egl.swapinterval", &property_swap_interval);
234  if (property_swap_interval == 0) {
235    swap_interval_zero_ = true;
236  }
237
238
239  client_target_ = new HWCLayer(id_);
240  int blit_enabled = 0;
241  HWCDebugHandler::Get()->GetProperty("persist.hwc.blit.comp", &blit_enabled);
242  if (needs_blit_ && blit_enabled) {
243    blit_engine_ = new BlitEngineC2d();
244    if (!blit_engine_) {
245      DLOGI("Create Blit Engine C2D failed");
246    } else {
247      if (blit_engine_->Init() < 0) {
248        DLOGI("Blit Engine Init failed, Blit Composition will not be used!!");
249        delete blit_engine_;
250        blit_engine_ = NULL;
251      }
252    }
253  }
254
255  display_intf_->GetRefreshRateRange(&min_refresh_rate_, &max_refresh_rate_);
256  current_refresh_rate_ = max_refresh_rate_;
257  DLOGI("Display created with id: %d", id_);
258  return 0;
259}
260
261int HWCDisplay::Deinit() {
262  DisplayError error = core_intf_->DestroyDisplay(display_intf_);
263  if (error != kErrorNone) {
264    DLOGE("Display destroy failed. Error = %d", error);
265    return -EINVAL;
266  }
267
268  delete client_target_;
269
270  if (blit_engine_) {
271    blit_engine_->DeInit();
272    delete blit_engine_;
273    blit_engine_ = NULL;
274  }
275
276  if (color_mode_) {
277    color_mode_->DeInit();
278    delete color_mode_;
279  }
280
281  return 0;
282}
283
284// LayerStack operations
285HWC2::Error HWCDisplay::CreateLayer(hwc2_layer_t *out_layer_id) {
286  HWCLayer *layer = *layer_set_.emplace(new HWCLayer(id_));
287  layer_map_.emplace(std::make_pair(layer->GetId(), layer));
288  *out_layer_id = layer->GetId();
289  geometry_changes_ |= GeometryChanges::kAdded;
290  return HWC2::Error::None;
291}
292
293HWCLayer *HWCDisplay::GetHWCLayer(hwc2_layer_t layer_id) {
294  const auto map_layer = layer_map_.find(layer_id);
295  if (map_layer == layer_map_.end()) {
296    DLOGE("[%" PRIu64 "] GetLayer(%" PRIu64 ") failed: no such layer", id_, layer_id);
297    return nullptr;
298  } else {
299    return map_layer->second;
300  }
301}
302
303HWC2::Error HWCDisplay::DestroyLayer(hwc2_layer_t layer_id) {
304  const auto map_layer = layer_map_.find(layer_id);
305  if (map_layer == layer_map_.end()) {
306    DLOGE("[%" PRIu64 "] destroyLayer(%" PRIu64 ") failed: no such layer", id_, layer_id);
307    return HWC2::Error::BadLayer;
308  }
309  const auto layer = map_layer->second;
310  layer_map_.erase(map_layer);
311  const auto z_range = layer_set_.equal_range(layer);
312  for (auto current = z_range.first; current != z_range.second; ++current) {
313    if (*current == layer) {
314      current = layer_set_.erase(current);
315      delete layer;
316      break;
317    }
318  }
319
320  geometry_changes_ |= GeometryChanges::kRemoved;
321  return HWC2::Error::None;
322}
323
324void HWCDisplay::BuildLayerStack() {
325  layer_stack_ = LayerStack();
326  display_rect_ = LayerRect();
327  metadata_refresh_rate_ = 0;
328
329  // Add one layer for fb target
330  // TODO(user): Add blit target layers
331  for (auto hwc_layer : layer_set_) {
332    Layer *layer = hwc_layer->GetSDMLayer();
333    // set default composition as GPU for SDM
334    layer->composition = kCompositionGPU;
335
336    if (swap_interval_zero_) {
337      if (layer->input_buffer->acquire_fence_fd >= 0) {
338        close(layer->input_buffer->acquire_fence_fd);
339        layer->input_buffer->acquire_fence_fd = -1;
340      }
341    }
342
343    const private_handle_t *handle =
344        reinterpret_cast<const private_handle_t *>(layer->input_buffer->buffer_id);
345    if (handle) {
346      if (handle->bufferType == BUFFER_TYPE_VIDEO) {
347        layer_stack_.flags.video_present = true;
348      }
349      // TZ Protected Buffer - L1
350      if (handle->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
351        layer_stack_.flags.secure_present = true;
352      }
353      // Gralloc Usage Protected Buffer - L3 - which needs to be treated as Secure & avoid fallback
354      if (handle->flags & private_handle_t::PRIV_FLAGS_PROTECTED_BUFFER) {
355        layer_stack_.flags.secure_present = true;
356      }
357    }
358
359    if (layer->flags.skip) {
360      layer_stack_.flags.skip_present = true;
361    }
362
363    if (layer->flags.cursor) {
364      layer_stack_.flags.cursor_present = true;
365    }
366    // TODO(user): Move to a getter if this is needed at other places
367    hwc_rect_t scaled_display_frame = {INT(layer->dst_rect.left), INT(layer->dst_rect.top),
368                                       INT(layer->dst_rect.right), INT(layer->dst_rect.bottom)};
369    ApplyScanAdjustment(&scaled_display_frame);
370    hwc_layer->SetLayerDisplayFrame(scaled_display_frame);
371    ApplyDeInterlaceAdjustment(layer);
372    // TODO(user): Verify if we still need to configure the solid fill layerbuffer,
373    // it should already have a valid dst_rect by this point
374
375    if (layer->frame_rate > metadata_refresh_rate_) {
376      metadata_refresh_rate_ = SanitizeRefreshRate(layer->frame_rate);
377    } else {
378      layer->frame_rate = current_refresh_rate_;
379    }
380    display_rect_ = Union(display_rect_, layer->dst_rect);
381    geometry_changes_ |= hwc_layer->GetGeometryChanges();
382    layer->flags.updating = IsLayerUpdating(layer);
383
384    layer_stack_.layers.push_back(layer);
385  }
386  // TODO(user): Set correctly when SDM supports geometry_changes as bitmask
387  layer_stack_.flags.geometry_changed = UINT32(geometry_changes_ > 0);
388  // Append client target to the layer stack
389  layer_stack_.layers.push_back(client_target_->GetSDMLayer());
390}
391
392void HWCDisplay::BuildSolidFillStack() {
393  layer_stack_ = LayerStack();
394  display_rect_ = LayerRect();
395
396  layer_stack_.layers.push_back(solid_fill_layer_);
397  layer_stack_.flags.geometry_changed = 1U;
398  // Append client target to the layer stack
399  layer_stack_.layers.push_back(client_target_->GetSDMLayer());
400}
401
402HWC2::Error HWCDisplay::SetLayerZOrder(hwc2_layer_t layer_id, uint32_t z) {
403  const auto map_layer = layer_map_.find(layer_id);
404  if (map_layer == layer_map_.end()) {
405    DLOGE("[%" PRIu64 "] updateLayerZ failed to find layer", id_);
406    return HWC2::Error::BadLayer;
407  }
408
409  const auto layer = map_layer->second;
410  const auto z_range = layer_set_.equal_range(layer);
411  bool layer_on_display = false;
412  for (auto current = z_range.first; current != z_range.second; ++current) {
413    if (*current == layer) {
414      if ((*current)->GetZ() == z) {
415        // Don't change anything if the Z hasn't changed
416        return HWC2::Error::None;
417      }
418      current = layer_set_.erase(current);
419      layer_on_display = true;
420      break;
421    }
422  }
423
424  if (!layer_on_display) {
425    DLOGE("[%" PRIu64 "] updateLayerZ failed to find layer on display", id_);
426    return HWC2::Error::BadLayer;
427  }
428
429  layer->SetLayerZOrder(z);
430  layer_set_.emplace(layer);
431  return HWC2::Error::None;
432}
433
434HWC2::Error HWCDisplay::SetVsyncEnabled(HWC2::Vsync enabled) {
435  DLOGV("Display ID: %d enabled: %s", id_, to_string(enabled).c_str());
436  DisplayError error = kErrorNone;
437
438  if (shutdown_pending_) {
439    return HWC2::Error::None;
440  }
441
442  bool state;
443  if (enabled == HWC2::Vsync::Enable)
444    state = true;
445  else if (enabled == HWC2::Vsync::Disable)
446    state = false;
447  else
448    return HWC2::Error::BadParameter;
449
450  error = display_intf_->SetVSyncState(state);
451
452  if (error != kErrorNone) {
453    if (error == kErrorShutDown) {
454      shutdown_pending_ = true;
455      return HWC2::Error::None;
456    }
457    DLOGE("Failed. enabled = %s, error = %d", to_string(enabled).c_str(), error);
458    return HWC2::Error::BadDisplay;
459  }
460
461  return HWC2::Error::None;
462}
463
464HWC2::Error HWCDisplay::SetPowerMode(HWC2::PowerMode mode) {
465  DLOGV("display = %d, mode = %s", id_, to_string(mode).c_str());
466  DisplayState state = kStateOff;
467  bool flush_on_error = flush_on_error_;
468
469  if (shutdown_pending_) {
470    return HWC2::Error::None;
471  }
472
473  switch (mode) {
474    case HWC2::PowerMode::Off:
475      // During power off, all of the buffers are released.
476      // Do not flush until a buffer is successfully submitted again.
477      flush_on_error = false;
478      state = kStateOff;
479      break;
480    case HWC2::PowerMode::On:
481      state = kStateOn;
482      last_power_mode_ = HWC2::PowerMode::On;
483      break;
484    case HWC2::PowerMode::Doze:
485      state = kStateDoze;
486      last_power_mode_ = HWC2::PowerMode::Doze;
487      break;
488    case HWC2::PowerMode::DozeSuspend:
489      state = kStateDozeSuspend;
490      last_power_mode_ = HWC2::PowerMode::DozeSuspend;
491      break;
492    default:
493      return HWC2::Error::BadParameter;
494  }
495
496  DisplayError error = display_intf_->SetDisplayState(state);
497  if (error == kErrorNone) {
498    flush_on_error_ = flush_on_error;
499  } else {
500    if (error == kErrorShutDown) {
501      shutdown_pending_ = true;
502      return HWC2::Error::None;
503    }
504    DLOGE("Set state failed. Error = %d", error);
505    return HWC2::Error::BadParameter;
506  }
507
508  return HWC2::Error::None;
509}
510
511HWC2::Error HWCDisplay::GetClientTargetSupport(uint32_t width, uint32_t height, int32_t format,
512                                               int32_t dataspace) {
513  DisplayConfigVariableInfo variable_config;
514  display_intf_->GetFrameBufferConfig(&variable_config);
515  // TODO(user): Support scaled configurations, other formats and other dataspaces
516  if (format != HAL_PIXEL_FORMAT_RGBA_8888 || dataspace != HAL_DATASPACE_UNKNOWN ||
517      width != variable_config.x_pixels || height != variable_config.y_pixels) {
518    return HWC2::Error::Unsupported;
519  } else {
520    return HWC2::Error::None;
521  }
522}
523
524HWC2::Error HWCDisplay::GetColorModes(uint32_t *out_num_modes, android_color_mode_t *out_modes) {
525  if (out_modes) {
526    out_modes[0] = HAL_COLOR_MODE_NATIVE;
527  }
528  *out_num_modes = 1;
529
530  return HWC2::Error::None;
531}
532
533HWC2::Error HWCDisplay::GetDisplayConfigs(uint32_t *out_num_configs, hwc2_config_t *out_configs) {
534  // TODO(user): Actually handle multiple configs
535  if (out_configs == nullptr) {
536    *out_num_configs = 1;
537  } else {
538    *out_num_configs = 1;
539    out_configs[0] = 0;
540  }
541
542  return HWC2::Error::None;
543}
544
545HWC2::Error HWCDisplay::GetDisplayAttribute(hwc2_config_t config, HWC2::Attribute attribute,
546                                            int32_t *out_value) {
547  DisplayConfigVariableInfo variable_config;
548  DisplayError error = display_intf_->GetFrameBufferConfig(&variable_config);
549  if (error != kErrorNone) {
550    DLOGV("Get variable config failed. Error = %d", error);
551    return HWC2::Error::BadDisplay;
552  }
553
554  switch (attribute) {
555    case HWC2::Attribute::VsyncPeriod:
556      *out_value = INT32(variable_config.vsync_period_ns);
557      break;
558    case HWC2::Attribute::Width:
559      *out_value = INT32(variable_config.x_pixels);
560      break;
561    case HWC2::Attribute::Height:
562      *out_value = INT32(variable_config.y_pixels);
563      break;
564    case HWC2::Attribute::DpiX:
565      *out_value = INT32(variable_config.x_dpi * 1000.0f);
566      break;
567    case HWC2::Attribute::DpiY:
568      *out_value = INT32(variable_config.y_dpi * 1000.0f);
569      break;
570    default:
571      DLOGW("Spurious attribute type = %s", to_string(attribute).c_str());
572      return HWC2::Error::BadConfig;
573  }
574
575  return HWC2::Error::None;
576}
577
578HWC2::Error HWCDisplay::GetDisplayName(uint32_t *out_size, char *out_name) {
579  // TODO(user): Get panel name and EDID name and populate it here
580  if (out_name == nullptr) {
581    *out_size = 32;
582  } else {
583    std::string name;
584    switch (id_) {
585      case HWC_DISPLAY_PRIMARY:
586        name = "Primary Display";
587        break;
588      case HWC_DISPLAY_EXTERNAL:
589        name = "External Display";
590        break;
591      case HWC_DISPLAY_VIRTUAL:
592        name = "Virtual Display";
593        break;
594      default:
595        name = "Unknown";
596        break;
597    }
598    std::strncpy(out_name, name.c_str(), name.size());
599    *out_size = UINT32(name.size());
600  }
601  return HWC2::Error::None;
602}
603
604HWC2::Error HWCDisplay::GetDisplayType(int32_t *out_type) {
605  if (out_type != nullptr) {
606    if (id_ == HWC_DISPLAY_VIRTUAL) {
607      *out_type = HWC2_DISPLAY_TYPE_VIRTUAL;
608    } else {
609      *out_type = HWC2_DISPLAY_TYPE_PHYSICAL;
610    }
611    return HWC2::Error::None;
612  } else {
613    return HWC2::Error::BadParameter;
614  }
615}
616
617// TODO(user): Store configurations and hook them up here
618HWC2::Error HWCDisplay::GetActiveConfig(hwc2_config_t *out_config) {
619  if (out_config != nullptr) {
620    *out_config = 0;
621    return HWC2::Error::None;
622  } else {
623    return HWC2::Error::BadParameter;
624  }
625}
626
627HWC2::Error HWCDisplay::SetClientTarget(buffer_handle_t target, int32_t acquire_fence,
628                                        int32_t dataspace, hwc_region_t damage) {
629  // TODO(user): SurfaceFlinger gives us a null pointer here when doing full SDE composition
630  // The error is problematic for layer caching as it would overwrite our cached client target.
631  // Reported bug 28569722 to resolve this.
632  // For now, continue to use the last valid buffer reported to us for layer caching.
633  if (target == nullptr) {
634    return HWC2::Error::None;
635  }
636
637  if (acquire_fence == 0) {
638    DLOGE("acquire_fence is zero");
639    return HWC2::Error::BadParameter;
640  }
641
642  client_target_->SetLayerBuffer(target, acquire_fence);
643  client_target_->SetLayerSurfaceDamage(damage);
644  // Ignoring dataspace for now
645  return HWC2::Error::None;
646}
647
648HWC2::Error HWCDisplay::SetActiveConfig(hwc2_config_t config) {
649  // We have only one config right now - do nothing
650  return HWC2::Error::None;
651}
652
653DisplayError HWCDisplay::SetMixerResolution(uint32_t width, uint32_t height) {
654  return kErrorNotSupported;
655}
656
657void HWCDisplay::SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type) {
658  dump_frame_count_ = count;
659  dump_frame_index_ = 0;
660  dump_input_layers_ = ((bit_mask_layer_type & (1 << INPUT_LAYER_DUMP)) != 0);
661
662  if (blit_engine_) {
663    blit_engine_->SetFrameDumpConfig(count);
664  }
665
666  DLOGI("num_frame_dump %d, input_layer_dump_enable %d", dump_frame_count_, dump_input_layers_);
667}
668
669HWC2::PowerMode HWCDisplay::GetLastPowerMode() {
670  return last_power_mode_;
671}
672
673DisplayError HWCDisplay::VSync(const DisplayEventVSync &vsync) {
674  callbacks_->Vsync(id_, vsync.timestamp);
675  return kErrorNone;
676}
677
678DisplayError HWCDisplay::Refresh() {
679  return kErrorNotSupported;
680}
681
682DisplayError HWCDisplay::CECMessage(char *message) {
683  if (qservice_) {
684    qservice_->onCECMessageReceived(message, 0);
685  } else {
686    DLOGW("Qservice instance not available.");
687  }
688
689  return kErrorNone;
690}
691
692HWC2::Error HWCDisplay::PrepareLayerStack(uint32_t *out_num_types, uint32_t *out_num_requests) {
693  layer_changes_.clear();
694  layer_requests_.clear();
695  if (shutdown_pending_) {
696    return HWC2::Error::BadDisplay;
697  }
698
699  if (!skip_prepare_) {
700    DisplayError error = display_intf_->Prepare(&layer_stack_);
701    if (error != kErrorNone) {
702      if (error == kErrorShutDown) {
703        shutdown_pending_ = true;
704      } else if (error != kErrorPermission) {
705        DLOGE("Prepare failed. Error = %d", error);
706        // To prevent surfaceflinger infinite wait, flush the previous frame during Commit()
707        // so that previous buffer and fences are released, and override the error.
708        flush_ = true;
709      }
710      return HWC2::Error::BadDisplay;
711    }
712  } else {
713    // Skip is not set
714    MarkLayersForGPUBypass();
715    skip_prepare_ = false;
716    DLOGI("SecureDisplay %s, Skip Prepare/Commit and Flush",
717          secure_display_active_ ? "Starting" : "Stopping");
718    flush_ = true;
719  }
720
721  for (auto hwc_layer : layer_set_) {
722    Layer *layer = hwc_layer->GetSDMLayer();
723    LayerComposition &composition = layer->composition;
724
725    if ((composition == kCompositionSDE) || (composition == kCompositionHybrid) ||
726        (composition == kCompositionBlit)) {
727      layer_requests_[hwc_layer->GetId()] = HWC2::LayerRequest::ClearClientTarget;
728    }
729
730    HWC2::Composition requested_composition = hwc_layer->GetClientRequestedCompositionType();
731    // Set SDM composition to HWC2 type in HWCLayer
732    hwc_layer->SetComposition(composition);
733    HWC2::Composition device_composition  = hwc_layer->GetDeviceSelectedCompositionType();
734    // Update the changes list only if the requested composition is different from SDM comp type
735    // TODO(user): Take Care of other comptypes(BLIT)
736    if (requested_composition != device_composition) {
737      layer_changes_[hwc_layer->GetId()] = device_composition;
738    }
739  }
740  *out_num_types = UINT32(layer_changes_.size());
741  *out_num_requests = UINT32(layer_requests_.size());
742  validated_ = true;
743  if (*out_num_types > 0) {
744    return HWC2::Error::HasChanges;
745  } else {
746    return HWC2::Error::None;
747  }
748}
749
750HWC2::Error HWCDisplay::AcceptDisplayChanges() {
751  if (!validated_ && !layer_set_.empty()) {
752    return HWC2::Error::NotValidated;
753  }
754  return HWC2::Error::None;
755}
756
757HWC2::Error HWCDisplay::GetChangedCompositionTypes(uint32_t *out_num_elements,
758                                                   hwc2_layer_t *out_layers, int32_t *out_types) {
759  if (layer_set_.empty()) {
760    return HWC2::Error::None;
761  }
762
763  if (!validated_) {
764    DLOGW("Display is not validated");
765    return HWC2::Error::NotValidated;
766  }
767  *out_num_elements = UINT32(layer_changes_.size());
768  if (out_layers != nullptr && out_types != nullptr) {
769    int i = 0;
770    for (auto change : layer_changes_) {
771      out_layers[i] = change.first;
772      out_types[i] = INT32(change.second);
773      i++;
774    }
775  }
776  return HWC2::Error::None;
777}
778
779HWC2::Error HWCDisplay::GetReleaseFences(uint32_t *out_num_elements, hwc2_layer_t *out_layers,
780                                         int32_t *out_fences) {
781  if (out_layers != nullptr && out_fences != nullptr) {
782    int i = 0;
783    for (auto hwc_layer : layer_set_) {
784      out_layers[i] = hwc_layer->GetId();
785      out_fences[i] = hwc_layer->PopReleaseFence();
786      i++;
787    }
788  }
789  *out_num_elements = UINT32(layer_set_.size());
790  return HWC2::Error::None;
791}
792
793HWC2::Error HWCDisplay::GetDisplayRequests(int32_t *out_display_requests,
794                                           uint32_t *out_num_elements, hwc2_layer_t *out_layers,
795                                           int32_t *out_layer_requests) {
796  // No display requests for now
797  // Use for sharing blit buffers and
798  // writing wfd buffer directly to output if there is full GPU composition
799  // and no color conversion needed
800  if (layer_set_.empty()) {
801    return HWC2::Error::None;
802  }
803
804  if (!validated_) {
805    DLOGW("Display is not validated");
806    return HWC2::Error::NotValidated;
807  }
808  *out_display_requests = 0;
809  *out_num_elements = UINT32(layer_requests_.size());
810  if (out_layers != nullptr && out_layer_requests != nullptr) {
811    int i = 0;
812    for (auto &request : layer_requests_) {
813      out_layers[i] = request.first;
814      out_layer_requests[i] = INT32(request.second);
815      i++;
816    }
817  }
818  return HWC2::Error::None;
819}
820
821HWC2::Error HWCDisplay::CommitLayerStack(void) {
822  if (shutdown_pending_ || layer_set_.empty()) {
823    return HWC2::Error::None;
824  }
825
826  if (!validated_) {
827    DLOGW("Display is not validated");
828    return HWC2::Error::NotValidated;
829  }
830
831  DumpInputBuffers();
832
833  if (!flush_) {
834    DisplayError error = kErrorUndefined;
835    error = display_intf_->Commit(&layer_stack_);
836    validated_ = false;
837
838    if (error == kErrorNone) {
839      // A commit is successfully submitted, start flushing on failure now onwards.
840      flush_on_error_ = true;
841    } else {
842      if (error == kErrorShutDown) {
843        shutdown_pending_ = true;
844        return HWC2::Error::Unsupported;
845      } else if (error != kErrorPermission) {
846        DLOGE("Commit failed. Error = %d", error);
847        // To prevent surfaceflinger infinite wait, flush the previous frame during Commit()
848        // so that previous buffer and fences are released, and override the error.
849        flush_ = true;
850      }
851    }
852  }
853
854  return HWC2::Error::None;
855}
856
857HWC2::Error HWCDisplay::PostCommitLayerStack(int32_t *out_retire_fence) {
858  auto status = HWC2::Error::None;
859
860  // Do no call flush on errors, if a successful buffer is never submitted.
861  if (flush_ && flush_on_error_) {
862    display_intf_->Flush();
863  }
864
865  // TODO(user): No way to set the client target release fence on SF
866  int32_t &client_target_release_fence =
867      client_target_->GetSDMLayer()->input_buffer->release_fence_fd;
868  if (client_target_release_fence >= 0) {
869    close(client_target_release_fence);
870    client_target_release_fence = -1;
871  }
872
873  for (auto hwc_layer : layer_set_) {
874    hwc_layer->ResetGeometryChanges();
875    Layer *layer = hwc_layer->GetSDMLayer();
876    LayerBuffer *layer_buffer = layer->input_buffer;
877
878    if (!flush_) {
879      // If swapinterval property is set to 0 or for single buffer layers, do not update f/w
880      // release fences and discard fences from driver
881      if (swap_interval_zero_ || layer->flags.single_buffer) {
882        close(layer_buffer->release_fence_fd);
883        layer_buffer->release_fence_fd = -1;
884      } else if (layer->composition != kCompositionGPU) {
885        hwc_layer->PushReleaseFence(layer_buffer->release_fence_fd);
886        layer_buffer->release_fence_fd = -1;
887      } else {
888        hwc_layer->PushReleaseFence(-1);
889      }
890    }
891
892    if (layer_buffer->acquire_fence_fd >= 0) {
893      close(layer_buffer->acquire_fence_fd);
894      layer_buffer->acquire_fence_fd = -1;
895    }
896  }
897
898  *out_retire_fence = -1;
899  if (!flush_) {
900    // if swapinterval property is set to 0 then close and reset the list retire fence
901    if (swap_interval_zero_) {
902      close(layer_stack_.retire_fence_fd);
903      layer_stack_.retire_fence_fd = -1;
904    }
905    *out_retire_fence = layer_stack_.retire_fence_fd;
906
907    if (dump_frame_count_) {
908      dump_frame_count_--;
909      dump_frame_index_++;
910    }
911  }
912
913  geometry_changes_ = GeometryChanges::kNone;
914  flush_ = false;
915
916  return status;
917}
918
919void HWCDisplay::SetIdleTimeoutMs(uint32_t timeout_ms) {
920  return;
921}
922
923DisplayError HWCDisplay::SetMaxMixerStages(uint32_t max_mixer_stages) {
924  DisplayError error = kErrorNone;
925
926  if (display_intf_) {
927    error = display_intf_->SetMaxMixerStages(max_mixer_stages);
928  }
929
930  return error;
931}
932
933LayerBufferFormat HWCDisplay::GetSDMFormat(const int32_t &source, const int flags) {
934  LayerBufferFormat format = kFormatInvalid;
935  if (flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
936    switch (source) {
937      case HAL_PIXEL_FORMAT_RGBA_8888:
938        format = kFormatRGBA8888Ubwc;
939        break;
940      case HAL_PIXEL_FORMAT_RGBX_8888:
941        format = kFormatRGBX8888Ubwc;
942        break;
943      case HAL_PIXEL_FORMAT_BGR_565:
944        format = kFormatBGR565Ubwc;
945        break;
946      case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
947      case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
948      case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
949        format = kFormatYCbCr420SPVenusUbwc;
950        break;
951      case HAL_PIXEL_FORMAT_RGBA_1010102:
952        format = kFormatRGBA1010102Ubwc;
953        break;
954      case HAL_PIXEL_FORMAT_RGBX_1010102:
955        format = kFormatRGBX1010102Ubwc;
956        break;
957      case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
958        format = kFormatYCbCr420TP10Ubwc;
959        break;
960      default:
961        DLOGE("Unsupported format type for UBWC %d", source);
962        return kFormatInvalid;
963    }
964    return format;
965  }
966
967  switch (source) {
968    case HAL_PIXEL_FORMAT_RGBA_8888:
969      format = kFormatRGBA8888;
970      break;
971    case HAL_PIXEL_FORMAT_RGBA_5551:
972      format = kFormatRGBA5551;
973      break;
974    case HAL_PIXEL_FORMAT_RGBA_4444:
975      format = kFormatRGBA4444;
976      break;
977    case HAL_PIXEL_FORMAT_BGRA_8888:
978      format = kFormatBGRA8888;
979      break;
980    case HAL_PIXEL_FORMAT_RGBX_8888:
981      format = kFormatRGBX8888;
982      break;
983    case HAL_PIXEL_FORMAT_BGRX_8888:
984      format = kFormatBGRX8888;
985      break;
986    case HAL_PIXEL_FORMAT_RGB_888:
987      format = kFormatRGB888;
988      break;
989    case HAL_PIXEL_FORMAT_RGB_565:
990      format = kFormatRGB565;
991      break;
992    case HAL_PIXEL_FORMAT_BGR_565:
993      format = kFormatBGR565;
994      break;
995    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
996    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
997      format = kFormatYCbCr420SemiPlanarVenus;
998      break;
999    case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
1000      format = kFormatYCrCb420SemiPlanarVenus;
1001      break;
1002    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
1003      format = kFormatYCbCr420SPVenusUbwc;
1004      break;
1005    case HAL_PIXEL_FORMAT_YV12:
1006      format = kFormatYCrCb420PlanarStride16;
1007      break;
1008    case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1009      format = kFormatYCrCb420SemiPlanar;
1010      break;
1011    case HAL_PIXEL_FORMAT_YCbCr_420_SP:
1012      format = kFormatYCbCr420SemiPlanar;
1013      break;
1014    case HAL_PIXEL_FORMAT_YCbCr_422_SP:
1015      format = kFormatYCbCr422H2V1SemiPlanar;
1016      break;
1017    case HAL_PIXEL_FORMAT_YCbCr_422_I:
1018      format = kFormatYCbCr422H2V1Packed;
1019      break;
1020    case HAL_PIXEL_FORMAT_RGBA_1010102:
1021      format = kFormatRGBA1010102;
1022      break;
1023    case HAL_PIXEL_FORMAT_ARGB_2101010:
1024      format = kFormatARGB2101010;
1025      break;
1026    case HAL_PIXEL_FORMAT_RGBX_1010102:
1027      format = kFormatRGBX1010102;
1028      break;
1029    case HAL_PIXEL_FORMAT_XRGB_2101010:
1030      format = kFormatXRGB2101010;
1031      break;
1032    case HAL_PIXEL_FORMAT_BGRA_1010102:
1033      format = kFormatBGRA1010102;
1034      break;
1035    case HAL_PIXEL_FORMAT_ABGR_2101010:
1036      format = kFormatABGR2101010;
1037      break;
1038    case HAL_PIXEL_FORMAT_BGRX_1010102:
1039      format = kFormatBGRX1010102;
1040      break;
1041    case HAL_PIXEL_FORMAT_XBGR_2101010:
1042      format = kFormatXBGR2101010;
1043      break;
1044    case HAL_PIXEL_FORMAT_YCbCr_420_P010:
1045      format = kFormatYCbCr420P010;
1046      break;
1047    case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
1048      format = kFormatYCbCr420TP10Ubwc;
1049      break;
1050    default:
1051      DLOGW("Unsupported format type = %d", source);
1052      return kFormatInvalid;
1053  }
1054
1055  return format;
1056}
1057
1058void HWCDisplay::DumpInputBuffers() {
1059  char dir_path[PATH_MAX];
1060
1061  if (!dump_frame_count_ || flush_ || !dump_input_layers_) {
1062    return;
1063  }
1064
1065  snprintf(dir_path, sizeof(dir_path), "/data/misc/display/frame_dump_%s", GetDisplayString());
1066
1067  if (mkdir(dir_path, 0777) != 0 && errno != EEXIST) {
1068    DLOGW("Failed to create %s directory errno = %d, desc = %s", dir_path, errno, strerror(errno));
1069    return;
1070  }
1071
1072  // if directory exists already, need to explicitly change the permission.
1073  if (errno == EEXIST && chmod(dir_path, 0777) != 0) {
1074    DLOGW("Failed to change permissions on %s directory", dir_path);
1075    return;
1076  }
1077
1078  for (uint32_t i = 0; i < layer_stack_.layers.size(); i++) {
1079    auto layer = layer_stack_.layers.at(i);
1080    const private_handle_t *pvt_handle =
1081        reinterpret_cast<const private_handle_t *>(layer->input_buffer->buffer_id);
1082    auto acquire_fence_fd = layer->input_buffer->acquire_fence_fd;
1083
1084    if (acquire_fence_fd >= 0) {
1085      int error = sync_wait(acquire_fence_fd, 1000);
1086      if (error < 0) {
1087        DLOGW("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
1088        return;
1089      }
1090    }
1091
1092    if (pvt_handle && pvt_handle->base) {
1093      char dump_file_name[PATH_MAX];
1094      size_t result = 0;
1095
1096      snprintf(dump_file_name, sizeof(dump_file_name), "%s/input_layer%d_%dx%d_%s_frame%d.raw",
1097               dir_path, i, pvt_handle->width, pvt_handle->height,
1098               GetHALPixelFormatString(pvt_handle->format), dump_frame_index_);
1099
1100      FILE *fp = fopen(dump_file_name, "w+");
1101      if (fp) {
1102        result = fwrite(reinterpret_cast<void *>(pvt_handle->base), pvt_handle->size, 1, fp);
1103        fclose(fp);
1104      }
1105
1106      DLOGI("Frame Dump %s: is %s", dump_file_name, result ? "Successful" : "Failed");
1107    }
1108  }
1109}
1110
1111void HWCDisplay::DumpOutputBuffer(const BufferInfo &buffer_info, void *base, int fence) {
1112  char dir_path[PATH_MAX];
1113
1114  snprintf(dir_path, sizeof(dir_path), "/data/misc/display/frame_dump_%s", GetDisplayString());
1115
1116  if (mkdir(dir_path, 777) != 0 && errno != EEXIST) {
1117    DLOGW("Failed to create %s directory errno = %d, desc = %s", dir_path, errno, strerror(errno));
1118    return;
1119  }
1120
1121  // if directory exists already, need to explicitly change the permission.
1122  if (errno == EEXIST && chmod(dir_path, 0777) != 0) {
1123    DLOGW("Failed to change permissions on %s directory", dir_path);
1124    return;
1125  }
1126
1127  if (base) {
1128    char dump_file_name[PATH_MAX];
1129    size_t result = 0;
1130
1131    if (fence >= 0) {
1132      int error = sync_wait(fence, 1000);
1133      if (error < 0) {
1134        DLOGW("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
1135        return;
1136      }
1137    }
1138
1139    snprintf(dump_file_name, sizeof(dump_file_name), "%s/output_layer_%dx%d_%s_frame%d.raw",
1140             dir_path, buffer_info.buffer_config.width, buffer_info.buffer_config.height,
1141             GetFormatString(buffer_info.buffer_config.format), dump_frame_index_);
1142
1143    FILE *fp = fopen(dump_file_name, "w+");
1144    if (fp) {
1145      result = fwrite(base, buffer_info.alloc_buffer_info.size, 1, fp);
1146      fclose(fp);
1147    }
1148
1149    DLOGI("Frame Dump of %s is %s", dump_file_name, result ? "Successful" : "Failed");
1150  }
1151}
1152
1153const char *HWCDisplay::GetHALPixelFormatString(int format) {
1154  switch (format) {
1155    case HAL_PIXEL_FORMAT_RGBA_8888:
1156      return "RGBA_8888";
1157    case HAL_PIXEL_FORMAT_RGBX_8888:
1158      return "RGBX_8888";
1159    case HAL_PIXEL_FORMAT_RGB_888:
1160      return "RGB_888";
1161    case HAL_PIXEL_FORMAT_RGB_565:
1162      return "RGB_565";
1163    case HAL_PIXEL_FORMAT_BGR_565:
1164      return "BGR_565";
1165    case HAL_PIXEL_FORMAT_BGRA_8888:
1166      return "BGRA_8888";
1167    case HAL_PIXEL_FORMAT_RGBA_5551:
1168      return "RGBA_5551";
1169    case HAL_PIXEL_FORMAT_RGBA_4444:
1170      return "RGBA_4444";
1171    case HAL_PIXEL_FORMAT_YV12:
1172      return "YV12";
1173    case HAL_PIXEL_FORMAT_YCbCr_422_SP:
1174      return "YCbCr_422_SP_NV16";
1175    case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1176      return "YCrCb_420_SP_NV21";
1177    case HAL_PIXEL_FORMAT_YCbCr_422_I:
1178      return "YCbCr_422_I_YUY2";
1179    case HAL_PIXEL_FORMAT_YCrCb_422_I:
1180      return "YCrCb_422_I_YVYU";
1181    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
1182      return "NV12_ENCODEABLE";
1183    case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
1184      return "YCbCr_420_SP_TILED_TILE_4x2";
1185    case HAL_PIXEL_FORMAT_YCbCr_420_SP:
1186      return "YCbCr_420_SP";
1187    case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
1188      return "YCrCb_420_SP_ADRENO";
1189    case HAL_PIXEL_FORMAT_YCrCb_422_SP:
1190      return "YCrCb_422_SP";
1191    case HAL_PIXEL_FORMAT_R_8:
1192      return "R_8";
1193    case HAL_PIXEL_FORMAT_RG_88:
1194      return "RG_88";
1195    case HAL_PIXEL_FORMAT_INTERLACE:
1196      return "INTERLACE";
1197    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
1198      return "YCbCr_420_SP_VENUS";
1199    case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
1200      return "YCrCb_420_SP_VENUS";
1201    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
1202      return "YCbCr_420_SP_VENUS_UBWC";
1203    case HAL_PIXEL_FORMAT_RGBA_1010102:
1204      return "RGBA_1010102";
1205    case HAL_PIXEL_FORMAT_ARGB_2101010:
1206      return "ARGB_2101010";
1207    case HAL_PIXEL_FORMAT_RGBX_1010102:
1208      return "RGBX_1010102";
1209    case HAL_PIXEL_FORMAT_XRGB_2101010:
1210      return "XRGB_2101010";
1211    case HAL_PIXEL_FORMAT_BGRA_1010102:
1212      return "BGRA_1010102";
1213    case HAL_PIXEL_FORMAT_ABGR_2101010:
1214      return "ABGR_2101010";
1215    case HAL_PIXEL_FORMAT_BGRX_1010102:
1216      return "BGRX_1010102";
1217    case HAL_PIXEL_FORMAT_XBGR_2101010:
1218      return "XBGR_2101010";
1219    case HAL_PIXEL_FORMAT_YCbCr_420_P010:
1220      return "YCbCr_420_P010";
1221    case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
1222      return "YCbCr_420_TP10_UBWC";
1223    default:
1224      return "Unknown_format";
1225  }
1226}
1227
1228const char *HWCDisplay::GetDisplayString() {
1229  switch (type_) {
1230    case kPrimary:
1231      return "primary";
1232    case kHDMI:
1233      return "hdmi";
1234    case kVirtual:
1235      return "virtual";
1236    default:
1237      return "invalid";
1238  }
1239}
1240
1241int HWCDisplay::SetFrameBufferResolution(uint32_t x_pixels, uint32_t y_pixels) {
1242  if (x_pixels <= 0 || y_pixels <= 0) {
1243    DLOGW("Unsupported config: x_pixels=%d, y_pixels=%d", x_pixels, y_pixels);
1244    return -EINVAL;
1245  }
1246
1247  DisplayConfigVariableInfo fb_config;
1248  DisplayError error = display_intf_->GetFrameBufferConfig(&fb_config);
1249  if (error != kErrorNone) {
1250    DLOGV("Get frame buffer config failed. Error = %d", error);
1251    return -EINVAL;
1252  }
1253
1254  fb_config.x_pixels = x_pixels;
1255  fb_config.y_pixels = y_pixels;
1256
1257  error = display_intf_->SetFrameBufferConfig(fb_config);
1258  if (error != kErrorNone) {
1259    DLOGV("Set frame buffer config failed. Error = %d", error);
1260    return -EINVAL;
1261  }
1262
1263  // Create rects to represent the new source and destination crops
1264  LayerRect crop = LayerRect(0, 0, FLOAT(x_pixels), FLOAT(y_pixels));
1265  LayerRect dst = LayerRect(0, 0, FLOAT(fb_config.x_pixels), FLOAT(fb_config.y_pixels));
1266  auto client_target_layer = client_target_->GetSDMLayer();
1267  client_target_layer->src_rect = crop;
1268  client_target_layer->dst_rect = dst;
1269
1270  int aligned_width;
1271  int aligned_height;
1272  int usage = GRALLOC_USAGE_HW_FB;
1273  int format = HAL_PIXEL_FORMAT_RGBA_8888;
1274  int ubwc_enabled = 0;
1275  int flags = 0;
1276  HWCDebugHandler::Get()->GetProperty("debug.gralloc.enable_fb_ubwc", &ubwc_enabled);
1277  if (ubwc_enabled == 1) {
1278    usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
1279    flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
1280  }
1281  AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(INT(x_pixels), INT(y_pixels), format, usage,
1282                                                        aligned_width, aligned_height);
1283
1284  // TODO(user): How does the dirty region get set on the client target? File bug on Google
1285  client_target_layer->composition = kCompositionGPUTarget;
1286  client_target_layer->input_buffer->format = GetSDMFormat(format, flags);
1287  client_target_layer->input_buffer->width = UINT32(aligned_width);
1288  client_target_layer->input_buffer->height = UINT32(aligned_height);
1289  client_target_layer->plane_alpha = 255;
1290
1291  DLOGI("New framebuffer resolution (%dx%d)", fb_config.x_pixels, fb_config.y_pixels);
1292
1293  return 0;
1294}
1295
1296void HWCDisplay::GetFrameBufferResolution(uint32_t *x_pixels, uint32_t *y_pixels) {
1297  DisplayConfigVariableInfo fb_config;
1298  display_intf_->GetFrameBufferConfig(&fb_config);
1299
1300  *x_pixels = fb_config.x_pixels;
1301  *y_pixels = fb_config.y_pixels;
1302}
1303
1304DisplayError HWCDisplay::GetMixerResolution(uint32_t *x_pixels, uint32_t *y_pixels) {
1305  return display_intf_->GetMixerResolution(x_pixels, y_pixels);
1306}
1307
1308void HWCDisplay::GetPanelResolution(uint32_t *x_pixels, uint32_t *y_pixels) {
1309  DisplayConfigVariableInfo display_config;
1310  uint32_t active_index = 0;
1311
1312  display_intf_->GetActiveConfig(&active_index);
1313  display_intf_->GetConfig(active_index, &display_config);
1314
1315  *x_pixels = display_config.x_pixels;
1316  *y_pixels = display_config.y_pixels;
1317}
1318
1319int HWCDisplay::SetDisplayStatus(uint32_t display_status) {
1320  int status = 0;
1321
1322  switch (display_status) {
1323    case kDisplayStatusResume:
1324      display_paused_ = false;
1325    case kDisplayStatusOnline:
1326      status = INT32(SetPowerMode(HWC2::PowerMode::On));
1327      break;
1328    case kDisplayStatusPause:
1329      display_paused_ = true;
1330    case kDisplayStatusOffline:
1331      status = INT32(SetPowerMode(HWC2::PowerMode::Off));
1332      break;
1333    default:
1334      DLOGW("Invalid display status %d", display_status);
1335      return -EINVAL;
1336  }
1337
1338  if (display_status == kDisplayStatusResume || display_status == kDisplayStatusPause) {
1339    callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
1340  }
1341
1342  return status;
1343}
1344
1345HWC2::Error HWCDisplay::SetCursorPosition(hwc2_layer_t layer, int x, int y) {
1346  if (shutdown_pending_) {
1347    return HWC2::Error::None;
1348  }
1349
1350  // TODO(user): Validate layer
1351  // TODO(user): Check if we're in a validate/present cycle
1352
1353  auto error = display_intf_->SetCursorPosition(x, y);
1354  if (error != kErrorNone) {
1355    if (error == kErrorShutDown) {
1356      shutdown_pending_ = true;
1357      return HWC2::Error::None;
1358    }
1359
1360    DLOGE("Failed for x = %d y = %d, Error = %d", x, y, error);
1361    return HWC2::Error::BadDisplay;
1362  }
1363
1364  return HWC2::Error::None;
1365}
1366
1367int HWCDisplay::OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level) {
1368  DisplayError error = display_intf_->OnMinHdcpEncryptionLevelChange(min_enc_level);
1369  if (error != kErrorNone) {
1370    DLOGE("Failed. Error = %d", error);
1371    return -1;
1372  }
1373
1374  return 0;
1375}
1376
1377void HWCDisplay::MarkLayersForGPUBypass() {
1378  for (auto hwc_layer : layer_set_) {
1379    auto layer = hwc_layer->GetSDMLayer();
1380    layer->composition = kCompositionSDE;
1381  }
1382}
1383
1384void HWCDisplay::MarkLayersForClientComposition() {
1385  // ClientComposition - GPU comp, to acheive this, set skip flag so that
1386  // SDM does not handle this layer and hwc_layer composition will be
1387  // set correctly at the end of Prepare.
1388  for (auto hwc_layer : layer_set_) {
1389    Layer *layer = hwc_layer->GetSDMLayer();
1390    layer->flags.skip = true;
1391  }
1392}
1393
1394void HWCDisplay::ApplyScanAdjustment(hwc_rect_t *display_frame) {
1395}
1396
1397int HWCDisplay::SetPanelBrightness(int level) {
1398  int ret = 0;
1399  if (display_intf_)
1400    ret = display_intf_->SetPanelBrightness(level);
1401  else
1402    ret = -EINVAL;
1403
1404  return ret;
1405}
1406
1407int HWCDisplay::GetPanelBrightness(int *level) {
1408  return display_intf_->GetPanelBrightness(level);
1409}
1410
1411int HWCDisplay::ToggleScreenUpdates(bool enable) {
1412  display_paused_ = enable ? false : true;
1413  callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
1414  return 0;
1415}
1416
1417int HWCDisplay::ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload,
1418                                     PPDisplayAPIPayload *out_payload,
1419                                     PPPendingParams *pending_action) {
1420  int ret = 0;
1421
1422  if (display_intf_)
1423    ret = display_intf_->ColorSVCRequestRoute(in_payload, out_payload, pending_action);
1424  else
1425    ret = -EINVAL;
1426
1427  return ret;
1428}
1429
1430void HWCDisplay::SolidFillPrepare() {
1431  if (solid_fill_enable_) {
1432    if (solid_fill_layer_ == NULL) {
1433      // Create a dummy layer here
1434      solid_fill_layer_ = new Layer();
1435      solid_fill_layer_->input_buffer = new LayerBuffer();
1436    }
1437    uint32_t primary_width = 0, primary_height = 0;
1438    GetMixerResolution(&primary_width, &primary_height);
1439
1440    LayerBuffer *layer_buffer = solid_fill_layer_->input_buffer;
1441    layer_buffer->width = primary_width;
1442    layer_buffer->height = primary_height;
1443    layer_buffer->acquire_fence_fd = -1;
1444    layer_buffer->release_fence_fd = -1;
1445
1446    LayerRect rect;
1447    rect.top = 0; rect.left = 0;
1448    rect.right = primary_width;
1449    rect.bottom = primary_height;
1450
1451    solid_fill_layer_->composition = kCompositionGPU;
1452    solid_fill_layer_->src_rect = rect;
1453    solid_fill_layer_->dst_rect = rect;
1454
1455    solid_fill_layer_->blending = kBlendingPremultiplied;
1456    solid_fill_layer_->solid_fill_color = solid_fill_color_;
1457    solid_fill_layer_->frame_rate = 60;
1458    solid_fill_layer_->visible_regions.push_back(solid_fill_layer_->dst_rect);
1459    solid_fill_layer_->flags.updating = 1;
1460    solid_fill_layer_->flags.solid_fill = true;
1461  } else {
1462    // delete the dummy layer
1463    if (solid_fill_layer_) {
1464      delete solid_fill_layer_->input_buffer;
1465    }
1466    delete solid_fill_layer_;
1467    solid_fill_layer_ = NULL;
1468  }
1469
1470  if (solid_fill_enable_ && solid_fill_layer_) {
1471    BuildSolidFillStack();
1472    MarkLayersForGPUBypass();
1473  }
1474
1475  return;
1476}
1477
1478void HWCDisplay::SolidFillCommit() {
1479  if (solid_fill_enable_ && solid_fill_layer_) {
1480    LayerBuffer *layer_buffer = solid_fill_layer_->input_buffer;
1481    if (layer_buffer->release_fence_fd > 0) {
1482      close(layer_buffer->release_fence_fd);
1483      layer_buffer->release_fence_fd = -1;
1484    }
1485    if (layer_stack_.retire_fence_fd > 0) {
1486      close(layer_stack_.retire_fence_fd);
1487      layer_stack_.retire_fence_fd = -1;
1488    }
1489  }
1490}
1491
1492int HWCDisplay::GetVisibleDisplayRect(hwc_rect_t *visible_rect) {
1493  if (!IsValid(display_rect_)) {
1494    return -EINVAL;
1495  }
1496
1497  visible_rect->left = INT(display_rect_.left);
1498  visible_rect->top = INT(display_rect_.top);
1499  visible_rect->right = INT(display_rect_.right);
1500  visible_rect->bottom = INT(display_rect_.bottom);
1501  DLOGI("Dpy = %d Visible Display Rect(%d %d %d %d)", visible_rect->left, visible_rect->top,
1502        visible_rect->right, visible_rect->bottom);
1503
1504  return 0;
1505}
1506
1507void HWCDisplay::SetSecureDisplay(bool secure_display_active) {
1508  secure_display_active_ = secure_display_active;
1509  return;
1510}
1511
1512int HWCDisplay::SetActiveDisplayConfig(int config) {
1513  return display_intf_->SetActiveConfig(UINT32(config)) == kErrorNone ? 0 : -1;
1514}
1515
1516int HWCDisplay::GetActiveDisplayConfig(uint32_t *config) {
1517  return display_intf_->GetActiveConfig(config) == kErrorNone ? 0 : -1;
1518}
1519
1520int HWCDisplay::GetDisplayConfigCount(uint32_t *count) {
1521  return display_intf_->GetNumVariableInfoConfigs(count) == kErrorNone ? 0 : -1;
1522}
1523
1524int HWCDisplay::GetDisplayAttributesForConfig(int config,
1525                                            DisplayConfigVariableInfo *display_attributes) {
1526  return display_intf_->GetConfig(UINT32(config), display_attributes) == kErrorNone ? 0 : -1;
1527}
1528
1529bool HWCDisplay::SingleLayerUpdating(void) {
1530  uint32_t updating_count = 0;
1531
1532  for (uint i = 0; i < layer_stack_.layers.size(); i++) {
1533    auto layer = layer_stack_.layers.at(i);
1534    if (layer->flags.updating) {
1535      updating_count++;
1536    }
1537  }
1538
1539  return (updating_count == 1);
1540}
1541
1542bool HWCDisplay::IsLayerUpdating(const Layer *layer) {
1543  // Layer should be considered updating if
1544  //   a) layer is in single buffer mode, or
1545  //   b) valid dirty_regions(android specific hint for updating status), or
1546  //   c) layer stack geometry has changed (TODO(user): Remove when SDM accepts
1547  //      geometry_changed as bit fields).
1548  return (layer->flags.single_buffer || IsSurfaceUpdated(layer->dirty_regions) ||
1549          geometry_changes_);
1550}
1551
1552bool HWCDisplay::IsSurfaceUpdated(const std::vector<LayerRect> &dirty_regions) {
1553  // based on dirty_regions determine if its updating
1554  // dirty_rect count = 0 - whole layer - updating.
1555  // dirty_rect count = 1 or more valid rects - updating.
1556  // dirty_rect count = 1 with (0,0,0,0) - not updating.
1557  return (dirty_regions.empty() || IsValid(dirty_regions.at(0)));
1558}
1559
1560uint32_t HWCDisplay::SanitizeRefreshRate(uint32_t req_refresh_rate) {
1561  uint32_t refresh_rate = req_refresh_rate;
1562
1563  if (refresh_rate < min_refresh_rate_) {
1564    // Pick the next multiple of request which is within the range
1565    refresh_rate =
1566        (((min_refresh_rate_ / refresh_rate) + ((min_refresh_rate_ % refresh_rate) ? 1 : 0)) *
1567         refresh_rate);
1568  }
1569
1570  if (refresh_rate > max_refresh_rate_) {
1571    refresh_rate = max_refresh_rate_;
1572  }
1573
1574  return refresh_rate;
1575}
1576
1577DisplayClass HWCDisplay::GetDisplayClass() {
1578  return display_class_;
1579}
1580
1581void HWCDisplay::CloseAcquireFds() {
1582  for (auto hwc_layer : layer_set_) {
1583    auto layer = hwc_layer->GetSDMLayer();
1584    if (layer->input_buffer->acquire_fence_fd >= 0) {
1585      close(layer->input_buffer->acquire_fence_fd);
1586      layer->input_buffer->acquire_fence_fd = -1;
1587    }
1588  }
1589  int32_t &client_target_acquire_fence =
1590      client_target_->GetSDMLayer()->input_buffer->acquire_fence_fd;
1591  if (client_target_acquire_fence >= 0) {
1592    close(client_target_acquire_fence);
1593    client_target_acquire_fence = -1;
1594  }
1595}
1596
1597std::string HWCDisplay::Dump() {
1598  std::ostringstream os;
1599  os << "-------------------------------" << std::endl;
1600  os << "HWC2 LayerDump display_id: " << id_ << std::endl;
1601  for (auto layer : layer_set_) {
1602    auto sdm_layer = layer->GetSDMLayer();
1603    auto transform = sdm_layer->transform;
1604    os << "-------------------------------" << std::endl;
1605    os << "layer_id: " << layer->GetId() << std::endl;
1606    os << "\tz: " << layer->GetZ() << std::endl;
1607    os << "\tclient(SF) composition: " <<
1608          to_string(layer->GetClientRequestedCompositionType()).c_str() << std::endl;
1609    os << "\tdevice(SDM) composition: " <<
1610          to_string(layer->GetDeviceSelectedCompositionType()).c_str() << std::endl;
1611    os << "\tplane_alpha: " << std::to_string(sdm_layer->plane_alpha).c_str() << std::endl;
1612    os << "\tformat: " << GetFormatString(sdm_layer->input_buffer->format) << std::endl;
1613    os << "\ttransform: rot: " << transform.rotation << " flip_h: " << transform.flip_horizontal <<
1614          " flip_v: "<< transform.flip_vertical << std::endl;
1615    os << "\tbuffer_id: " << std::hex << "0x" << sdm_layer->input_buffer->buffer_id << std::dec
1616       << std::endl;
1617  }
1618  return os.str();
1619}
1620}  // namespace sdm
1621