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