14a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh/* 24a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved. 34a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* 44a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* Redistribution and use in source and binary forms, with or without modification, are permitted 54a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* provided that the following conditions are met: 64a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* * Redistributions of source code must retain the above copyright notice, this list of 74a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* conditions and the following disclaimer. 84a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* * Redistributions in binary form must reproduce the above copyright notice, this list of 94a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* conditions and the following disclaimer in the documentation and/or other materials provided 104a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* with the distribution. 114a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* * Neither the name of The Linux Foundation nor the names of its contributors may be used to 124a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* endorse or promote products derived from this software without specific prior written 134a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* permission. 144a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* 154a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 164a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 174a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 184a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 194a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 204a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 214a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 224a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 234a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh*/ 244a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 254a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <utils/constants.h> 264a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <utils/debug.h> 274a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <map> 284a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <utility> 294a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <vector> 304a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 314a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include "display_hdmi.h" 324a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include "hw_interface.h" 334a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include "hw_info_interface.h" 344a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 354a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#define __CLASS__ "DisplayHDMI" 364a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 374a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhnamespace sdm { 384a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 394a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayHDMI::DisplayHDMI(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf, 404a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator, 414a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh CompManager *comp_manager) 424a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh : DisplayBase(kHDMI, event_handler, kDeviceHDMI, buffer_sync_handler, buffer_allocator, 434a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh comp_manager, hw_info_intf) { 444a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh} 454a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 464a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError DisplayHDMI::Init() { 474a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh lock_guard<recursive_mutex> obj(recursive_mutex_); 484a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 494a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh DisplayError error = HWInterface::Create(kHDMI, hw_info_intf_, buffer_sync_handler_, 504a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh buffer_allocator_, &hw_intf_); 514a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh if (error != kErrorNone) { 524a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh return error; 534a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } 544a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 554a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh uint32_t active_mode_index; 564a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh char value[64] = "0"; 574a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh Debug::GetProperty("sdm.hdmi.s3d_mode", value); 584a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh HWS3DMode mode = (HWS3DMode)atoi(value); 594a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh if (mode > kS3DModeNone && mode < kS3DModeMax) { 604a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh active_mode_index = GetBestConfig(mode); 614a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } else { 624a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh active_mode_index = GetBestConfig(kS3DModeNone); 634a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } 644a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 654a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh error = hw_intf_->SetDisplayAttributes(active_mode_index); 664a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh if (error != kErrorNone) { 674a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh HWInterface::Destroy(hw_intf_); 684a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } 694a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 704a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh error = DisplayBase::Init(); 714a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh if (error != kErrorNone) { 724a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh HWInterface::Destroy(hw_intf_); 734a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh return error; 744a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } 754a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 764a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh GetScanSupport(); 774a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh underscan_supported_ = (scan_support_ == kScanAlwaysUnderscanned) || (scan_support_ == kScanBoth); 784a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 794a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh s3d_format_to_mode_.insert(std::pair<LayerBufferS3DFormat, HWS3DMode> 804a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh (kS3dFormatNone, kS3DModeNone)); 814a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh s3d_format_to_mode_.insert(std::pair<LayerBufferS3DFormat, HWS3DMode> 824a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh (kS3dFormatLeftRight, kS3DModeLR)); 834a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh s3d_format_to_mode_.insert(std::pair<LayerBufferS3DFormat, HWS3DMode> 844a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh (kS3dFormatRightLeft, kS3DModeRL)); 854a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh s3d_format_to_mode_.insert(std::pair<LayerBufferS3DFormat, HWS3DMode> 864a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh (kS3dFormatTopBottom, kS3DModeTB)); 874a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh s3d_format_to_mode_.insert(std::pair<LayerBufferS3DFormat, HWS3DMode> 884a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh (kS3dFormatFramePacking, kS3DModeFP)); 894a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 904a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh error = HWEventsInterface::Create(INT(display_type_), this, event_list_, &hw_events_intf_); 914a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh if (error != kErrorNone) { 924a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh DisplayBase::Deinit(); 934a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh HWInterface::Destroy(hw_intf_); 944a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh DLOGE("Failed to create hardware events interface. Error = %d", error); 954a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } 964a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 974a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh return error; 984a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh} 994a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 1004a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError DisplayHDMI::Prepare(LayerStack *layer_stack) { 1014a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh lock_guard<recursive_mutex> obj(recursive_mutex_); 1024a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh DisplayError error = kErrorNone; 1034a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh uint32_t new_mixer_width = 0; 1044a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh uint32_t new_mixer_height = 0; 1054a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh uint32_t display_width = display_attributes_.x_pixels; 1064a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh uint32_t display_height = display_attributes_.y_pixels; 1074a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 1084a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh if (NeedsMixerReconfiguration(layer_stack, &new_mixer_width, &new_mixer_height)) { 1094a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh error = ReconfigureMixer(new_mixer_width, new_mixer_height); 1104a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh if (error != kErrorNone) { 1114a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh ReconfigureMixer(display_width, display_height); 1124a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } 1134a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } 1144a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 1154a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh SetS3DMode(layer_stack); 1164a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 1174a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh // Clean hw layers for reuse. 1184a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh hw_layers_ = HWLayers(); 1194a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 1204a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh return DisplayBase::Prepare(layer_stack); 1214a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh} 1224a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 1234a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError DisplayHDMI::GetRefreshRateRange(uint32_t *min_refresh_rate, 1244a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh uint32_t *max_refresh_rate) { 1254a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh lock_guard<recursive_mutex> obj(recursive_mutex_); 1264a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh DisplayError error = kErrorNone; 1274a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 1284a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh if (hw_panel_info_.min_fps && hw_panel_info_.max_fps) { 1294a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh *min_refresh_rate = hw_panel_info_.min_fps; 1304a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh *max_refresh_rate = hw_panel_info_.max_fps; 1314a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } else { 1324a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh error = DisplayBase::GetRefreshRateRange(min_refresh_rate, max_refresh_rate); 1334a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } 1344a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 1354a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh return error; 1364a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh} 1374a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 1384a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError DisplayHDMI::SetRefreshRate(uint32_t refresh_rate) { 1394a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh lock_guard<recursive_mutex> obj(recursive_mutex_); 1404a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 1414a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh if (!active_) { 1424a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh return kErrorPermission; 1434a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } 1444a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 1454a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh DisplayError error = hw_intf_->SetRefreshRate(refresh_rate); 1464a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh if (error != kErrorNone) { 1474a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh return error; 1484a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } 1494a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 1504a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh return DisplayBase::ReconfigureDisplay(); 1514a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh} 1524a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 1534a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhbool DisplayHDMI::IsUnderscanSupported() { 1544a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh lock_guard<recursive_mutex> obj(recursive_mutex_); 1554a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh return underscan_supported_; 1564a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh} 1574a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 1584a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError DisplayHDMI::OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level) { 1594a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh lock_guard<recursive_mutex> obj(recursive_mutex_); 1604a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh return hw_intf_->OnMinHdcpEncryptionLevelChange(min_enc_level); 1614a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh} 1624a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 1634a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhuint32_t DisplayHDMI::GetBestConfig(HWS3DMode s3d_mode) { 1644a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh uint32_t best_index = 0, index; 1654a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh uint32_t num_modes = 0; 1664a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 1674a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh hw_intf_->GetNumDisplayAttributes(&num_modes); 1684a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 1694a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh // Get display attribute for each mode 1704a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh std::vector<HWDisplayAttributes> attrib(num_modes); 1714a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh for (index = 0; index < num_modes; index++) { 1724a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh hw_intf_->GetDisplayAttributes(index, &attrib[index]); 1734a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } 1744a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 1754a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh // Select best config for s3d_mode. If s3d is not enabled, s3d_mode is kS3DModeNone 1764a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh for (index = 0; index < num_modes; index ++) { 1774a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh if (attrib[index].s3d_config[s3d_mode]) { 1784a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh break; 1794a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } 1804a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } 1814a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh if (index < num_modes) { 1824a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh best_index = UINT32(index); 1834a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh for (size_t index = best_index + 1; index < num_modes; index ++) { 1844a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh if (!attrib[index].s3d_config[s3d_mode]) 1854a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh continue; 1864a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 1874a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh // From the available configs, select the best 1884a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh // Ex: 1920x1080@60Hz is better than 1920x1080@30 and 1920x1080@30 is better than 1280x720@60 1894a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh if (attrib[index].y_pixels > attrib[best_index].y_pixels) { 1904a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh best_index = UINT32(index); 1914a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } else if (attrib[index].y_pixels == attrib[best_index].y_pixels) { 1924a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh if (attrib[index].x_pixels > attrib[best_index].x_pixels) { 1934a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh best_index = UINT32(index); 1944a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } else if (attrib[index].x_pixels == attrib[best_index].x_pixels) { 1954a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh if (attrib[index].vsync_period_ns < attrib[best_index].vsync_period_ns) { 1964a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh best_index = UINT32(index); 1974a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } 1984a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } 1994a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } 2004a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } 2014a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } else { 2024a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh DLOGW("%s, could not support S3D mode from EDID info. S3D mode is %d", 2034a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh __FUNCTION__, s3d_mode); 2044a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } 2054a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 2064a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh // Used for changing HDMI Resolution - override the best with user set config 2074a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh uint32_t user_config = UINT32(Debug::GetHDMIResolution()); 2084a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh if (user_config) { 2094a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh uint32_t config_index = 0; 2104a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh // For the config, get the corresponding index 2114a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh DisplayError error = hw_intf_->GetConfigIndex(user_config, &config_index); 2124a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh if (error == kErrorNone) 2134a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh return config_index; 2144a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } 2154a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 2164a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh return best_index; 2174a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh} 2184a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 2194a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhvoid DisplayHDMI::GetScanSupport() { 2204a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh DisplayError error = kErrorNone; 2214a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh uint32_t video_format = 0; 2224a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh uint32_t max_cea_format = 0; 2234a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh HWScanInfo scan_info = HWScanInfo(); 2244a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh hw_intf_->GetHWScanInfo(&scan_info); 2254a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 2264a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh uint32_t active_mode_index = 0; 2274a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh hw_intf_->GetActiveConfig(&active_mode_index); 2284a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 2294a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh error = hw_intf_->GetVideoFormat(active_mode_index, &video_format); 2304a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh if (error != kErrorNone) { 2314a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh return; 2324a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } 2334a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 2344a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh error = hw_intf_->GetMaxCEAFormat(&max_cea_format); 2354a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh if (error != kErrorNone) { 2364a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh return; 2374a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } 2384a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 2394a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh // The scan support for a given HDMI TV must be read from scan info corresponding to 2404a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh // Preferred Timing if the preferred timing of the display is currently active, and if it is 2414a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh // valid. In all other cases, we must read the scan support from CEA scan info if 2424a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh // the resolution is a CEA resolution, or from IT scan info for all other resolutions. 2434a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh if (active_mode_index == 0 && scan_info.pt_scan_support != kScanNotSupported) { 2444a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh scan_support_ = scan_info.pt_scan_support; 2454a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } else if (video_format < max_cea_format) { 2464a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh scan_support_ = scan_info.cea_scan_support; 2474a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } else { 2484a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh scan_support_ = scan_info.it_scan_support; 2494a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } 2504a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh} 2514a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 2524a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhvoid DisplayHDMI::SetS3DMode(LayerStack *layer_stack) { 2534a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh uint32_t s3d_layer_count = 0; 2544a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh HWS3DMode s3d_mode = kS3DModeNone; 2554a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh uint32_t layer_count = UINT32(layer_stack->layers.size()); 2564a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 2574a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh // S3D mode is supported for the following scenarios: 2584a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh // 1. Layer stack containing only one s3d layer which is not skip 2594a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh // 2. Layer stack containing only one secure layer along with one s3d layer 2604a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh for (uint32_t i = 0; i < layer_count; i++) { 2614a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh Layer *layer = layer_stack->layers.at(i); 2624a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh LayerBuffer &layer_buffer = layer->input_buffer; 2634a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 2644a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh if (layer_buffer.s3d_format != kS3dFormatNone) { 2654a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh s3d_layer_count++; 2664a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh if (s3d_layer_count > 1 || layer->flags.skip) { 2674a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh s3d_mode = kS3DModeNone; 2684a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh break; 2694a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } 2704a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 2714a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh std::map<LayerBufferS3DFormat, HWS3DMode>::iterator it = 2724a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh s3d_format_to_mode_.find(layer_buffer.s3d_format); 2734a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh if (it != s3d_format_to_mode_.end()) { 2744a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh s3d_mode = it->second; 2754a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } 2764a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } else if (layer_buffer.flags.secure && layer_count > 2) { 2774a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh s3d_mode = kS3DModeNone; 2784a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh break; 2794a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } 2804a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } 2814a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 2824a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh if (hw_intf_->SetS3DMode(s3d_mode) != kErrorNone) { 2834a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh hw_intf_->SetS3DMode(kS3DModeNone); 2844a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh layer_stack->flags.s3d_mode_present = false; 2854a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } else if (s3d_mode != kS3DModeNone) { 2864a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh layer_stack->flags.s3d_mode_present = true; 2874a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } 2884a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 2894a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh DisplayBase::ReconfigureDisplay(); 2904a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh} 2914a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 2924a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError DisplayHDMI::VSync(int64_t timestamp) { 2934a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh if (vsync_enable_) { 2944a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh DisplayEventVSync vsync; 2954a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh vsync.timestamp = timestamp; 2964a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh event_handler_->VSync(vsync); 2974a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } 2984a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 2994a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh return kErrorNone; 3004a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh} 3014a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 3024a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh} // namespace sdm 303