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