diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2016-06-28 17:22:15 -0700 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2016-06-28 17:22:15 -0700 |
commit | 81abb87426aefd98594ae8d97357ee93d1f256f8 (patch) | |
tree | 57c3b3231fe5d5e4e469e43eda36d35862e313cd | |
parent | 52773656de7a11de050c2bf514b7b0811b384d5a (diff) | |
parent | 68b10a4b1956757b656b0786ec5b8f5392b4f38e (diff) | |
download | android_hardware_qcom_display-81abb87426aefd98594ae8d97357ee93d1f256f8.tar.gz android_hardware_qcom_display-81abb87426aefd98594ae8d97357ee93d1f256f8.tar.bz2 android_hardware_qcom_display-81abb87426aefd98594ae8d97357ee93d1f256f8.zip |
Merge "sdm: Add mode chose for dynamic framerate switch" into dev-2.0
-rw-r--r-- | sdm/libs/core/fb/hw_hdmi.cpp | 117 | ||||
-rw-r--r-- | sdm/libs/core/fb/hw_hdmi.h | 22 | ||||
-rw-r--r-- | sdm/libs/hwc/hwc_display_external.cpp | 21 |
3 files changed, 147 insertions, 13 deletions
diff --git a/sdm/libs/core/fb/hw_hdmi.cpp b/sdm/libs/core/fb/hw_hdmi.cpp index 5fe9bc1f1..ec76b4170 100644 --- a/sdm/libs/core/fb/hw_hdmi.cpp +++ b/sdm/libs/core/fb/hw_hdmi.cpp @@ -698,13 +698,103 @@ DisplayError HWHDMI::SetS3DMode(HWS3DMode s3d_mode) { return kErrorNone; } +DisplayError HWHDMI::GetDynamicFrameRateMode(uint32_t refresh_rate, uint32_t *mode, + DynamicFPSData *data, uint32_t *config_index) { + msm_hdmi_mode_timing_info *cur = NULL; + msm_hdmi_mode_timing_info *dst = NULL; + uint32_t i = 0; + int pre_refresh_rate_diff = 0; + bool pre_unstd_mode = false; + + for (i = 0; i < hdmi_mode_count_; i++) { + msm_hdmi_mode_timing_info *timing_mode = &supported_video_modes_[i]; + if (timing_mode->video_format == hdmi_modes_[active_config_index_]) { + cur = timing_mode; + break; + } + } + + if (cur == NULL) { + DLOGE("can't find timing info for active config index(%d)", active_config_index_); + return kErrorUndefined; + } + + if (cur->refresh_rate != frame_rate_) { + pre_unstd_mode = true; + } + + if (i >= hdmi_mode_count_) { + return kErrorNotSupported; + } + + dst = cur; + pre_refresh_rate_diff = static_cast<int>(dst->refresh_rate) - static_cast<int>(refresh_rate); + + for (i = 0; i < hdmi_mode_count_; i++) { + msm_hdmi_mode_timing_info *timing_mode = &supported_video_modes_[i]; + if (cur->active_h == timing_mode->active_h && + cur->active_v == timing_mode->active_v && + cur->pixel_formats == timing_mode->pixel_formats ) { + int cur_refresh_rate_diff = static_cast<int>(timing_mode->refresh_rate) - + static_cast<int>(refresh_rate); + if (abs(pre_refresh_rate_diff) > abs(cur_refresh_rate_diff)) { + pre_refresh_rate_diff = cur_refresh_rate_diff; + dst = timing_mode; + } + } + } + + if (dst == NULL) { + DLOGE("can't find timing mode switch to"); + return kErrorUndefined; + } + + GetConfigIndex(dst->video_format, config_index); + + data->hor_front_porch = dst->front_porch_h; + data->hor_back_porch = dst->back_porch_h; + data->hor_pulse_width = dst->pulse_width_h; + data->clk_rate_hz = dst->pixel_freq; + data->fps = refresh_rate; + + if (dst->front_porch_h != cur->front_porch_h) { + *mode = kModeHFP; + } + + if (dst->refresh_rate != refresh_rate || dst->pixel_freq != cur->pixel_freq) { + if (*mode == kModeHFP) { + if (dst->refresh_rate != refresh_rate) { + *mode = kModeHFPCalcClock; + } else { + *mode = kModeClockHFP; + } + } else { + *mode = kModeClock; + } + } + + if (pre_unstd_mode && (*mode == kModeHFP)) { + *mode = kModeClockHFP; + } + + return kErrorNone; +} + DisplayError HWHDMI::SetRefreshRate(uint32_t refresh_rate) { char mode_path[kMaxStringLength] = {0}; char node_path[kMaxStringLength] = {0}; - uint32_t mode = kModeHFP; + uint32_t mode = kModeClock; + uint32_t config_index = 0; + DynamicFPSData data; + DisplayError error = kErrorNone; if (refresh_rate == frame_rate_) { - return kErrorNone; + return error; + } + + error = GetDynamicFrameRateMode(refresh_rate, &mode, &data, &config_index); + if (error != kErrorNone) { + return error; } snprintf(mode_path, sizeof(mode_path), "%s%d/msm_fb_dfps_mode", fb_path_, fb_node_index_); @@ -712,7 +802,7 @@ DisplayError HWHDMI::SetRefreshRate(uint32_t refresh_rate) { int fd_mode = Sys::open_(mode_path, O_WRONLY); if (fd_mode < 0) { - DLOGE("Failed to open %s with error %s", node_path, strerror(errno)); + DLOGE("Failed to open %s with error %s", mode_path, strerror(errno)); return kErrorFileDescriptor; } @@ -734,8 +824,14 @@ DisplayError HWHDMI::SetRefreshRate(uint32_t refresh_rate) { } char refresh_rate_string[kMaxStringLength]; - snprintf(refresh_rate_string, sizeof(refresh_rate_string), "%d", refresh_rate); - DLOGI_IF(kTagDriverConfig, "Setting refresh rate = %d", refresh_rate); + if (mode == kModeHFP || mode == kModeClock) { + snprintf(refresh_rate_string, sizeof(refresh_rate_string), "%d", refresh_rate); + DLOGI_IF(kTagDriverConfig, "Setting refresh rate = %d", refresh_rate); + } else { + snprintf(refresh_rate_string, sizeof(refresh_rate_string), "%d %d %d %d %d", + data.hor_front_porch, data.hor_back_porch, data.hor_pulse_width, + data.clk_rate_hz, data.fps); + } len = Sys::pwrite_(fd_node, refresh_rate_string, strlen(refresh_rate_string), 0); if (len < 0) { DLOGE("Failed to write %d with error %s", refresh_rate, strerror(errno)); @@ -744,12 +840,21 @@ DisplayError HWHDMI::SetRefreshRate(uint32_t refresh_rate) { } Sys::close_(fd_node); - DisplayError error = ReadTimingInfo(); + error = ReadTimingInfo(); if (error != kErrorNone) { return error; } +// GetDisplayAttributes(config_index, &display_attributes_); +// UpdateMixerAttributes(); + frame_rate_ = refresh_rate; + active_config_index_ = config_index; + + DLOGI_IF(kTagDriverConfig, "config_index(%d) Mode(%d) frame_rate(%d)", + config_index, + mode, + frame_rate_); return kErrorNone; } diff --git a/sdm/libs/core/fb/hw_hdmi.h b/sdm/libs/core/fb/hw_hdmi.h index aa5e2a09e..28adc39e6 100644 --- a/sdm/libs/core/fb/hw_hdmi.h +++ b/sdm/libs/core/fb/hw_hdmi.h @@ -49,9 +49,29 @@ class HWHDMI : public HWDevice { kModeVFP, // Switch framerate by tuning horizontal front porch kModeHFP, + // Switch framerate by tuning horizontal front porch and clock + kModeClockHFP, + // Switch framerate by tuning horizontal front porch and re-caculate clock + kModeHFPCalcClock, kModeMAX }; + /** + * struct DynamicFPSData - defines dynamic fps related data + * @hor_front_porch: horizontal front porch + * @hor_back_porch: horizontal back porch + * @hor_pulse_width: horizontal pulse width + * @clk_rate_hz: panel clock rate in HZ + * @fps: frames per second + */ + struct DynamicFPSData { + uint32_t hor_front_porch; + uint32_t hor_back_porch; + uint32_t hor_pulse_width; + uint32_t clk_rate_hz; + uint32_t fps; + }; + HWHDMI(BufferSyncHandler *buffer_sync_handler, HWInfoInterface *hw_info_intf); virtual DisplayError Init(); virtual DisplayError Deinit(); @@ -84,6 +104,8 @@ class HWHDMI : public HWDevice { HWDisplayAttributes *attrib); bool IsSupportedS3DMode(HWS3DMode s3d_mode); + DisplayError GetDynamicFrameRateMode(uint32_t refresh_rate, uint32_t*mode, + DynamicFPSData *data, uint32_t *config_index); uint32_t hdmi_mode_count_; uint32_t hdmi_modes_[256]; // Holds the hdmi timing information. Ex: resolution, fps etc., diff --git a/sdm/libs/hwc/hwc_display_external.cpp b/sdm/libs/hwc/hwc_display_external.cpp index 43160c3a6..38be91be7 100644 --- a/sdm/libs/hwc/hwc_display_external.cpp +++ b/sdm/libs/hwc/hwc_display_external.cpp @@ -128,14 +128,12 @@ int HWCDisplayExternal::Prepare(hwc_display_contents_1_t *content_list) { if (current_refresh_rate_ != metadata_refresh_rate_ && one_video_updating_layer && drc_enabled_) { error = display_intf_->SetRefreshRate(metadata_refresh_rate_); + if (error == kErrorNone) { + // On success, set current refresh rate to new refresh rate + current_refresh_rate_ = metadata_refresh_rate_; + } } - if (error == kErrorNone) { - // On success, set current refresh rate to new refresh rate - current_refresh_rate_ = metadata_refresh_rate_; - } - - status = PrepareLayerStack(content_list); if (status) { return status; @@ -239,6 +237,11 @@ uint32_t HWCDisplayExternal::RoundToStandardFPS(float fps) { static const uint32_t mapping_fps[] = {59940, 60000, 60000, 59940, 60000, 50000, 59940, 60000}; uint32_t frame_rate = (uint32_t)(fps * 1000); + // process non valid + if (frame_rate == 0) { + return current_refresh_rate_; + } + int count = INT(sizeof(standard_fps) / sizeof(standard_fps[0])); for (int i = 0; i < count; i++) { // Most likely used for video, the fps for frames should be stable from video side. @@ -260,7 +263,11 @@ uint32_t HWCDisplayExternal::RoundToStandardFPS(float fps) { void HWCDisplayExternal::PrepareDynamicRefreshRate(Layer *layer) { if (layer->input_buffer->flags.video) { - metadata_refresh_rate_ = SanitizeRefreshRate(layer->frame_rate); + if (layer->frame_rate != 0) { + metadata_refresh_rate_ = SanitizeRefreshRate(layer->frame_rate); + } else { + metadata_refresh_rate_ = current_refresh_rate_; + } layer->frame_rate = current_refresh_rate_; } } |