display: Update to AU199 proprietary drop
Update to AU_LINUX_ANDROID_LA.HB.1.3.9.06.00.01.213.199
These display HAL changes are necessary for getting HWC2 fixed.
display_hal:
a46b76b Promotion of display.lnx.3.0-00025.
353beaa Promotion of display.lnx.3.0-00024.
5f57d11 sdm: Add support to override detail enhancer settings
fc09cc2 sdm: Modify partial update interface for destination scalar.
6884047 sdm: Add support for dynamic layer mixer resolution change.
2e9ea8d sdm: Move display state and input validation in appropriate place
b29788d Merge "hwc2: Use floating value refresh rate"
89ff452 hwc2: Use floating value refresh rate
29cd658 sdm: Add support for color mode & color transform
1626488 sdm: color-manager: New color management feature.
a216262 Merge "sdm: Add interface to disable PU for one frame"
8ce93e9 Promotion of display.lnx.3.0-00022.
3abfa78 Merge "qdutils: Query MDP caps for UBWC feature"
149b8bc libmemtrack: Update parsing of kgsl mem file
8011276 sdm: Add interface to disable PU for one frame
e7e9d0f Promotion of display.lnx.3.0-00021.
0136141 qdutils: Query MDP caps for UBWC feature
cad386a Promotion of display.lnx.3.0-00019.
4625171 Promotion of display.lnx.3.0-00018.
0a006ac Promotion of display.lnx.3.0-00017.
1204328 Promotion of display.lnx.3.0-00016.
Bug: 29463310
Change-Id: Ifc0d2a81503a7d8b91f08b7fcd2c5346f79e8c8b
diff --git a/msm8996/libgralloc/alloc_controller.cpp b/msm8996/libgralloc/alloc_controller.cpp
index 2a5d099..e9cdc73 100644
--- a/msm8996/libgralloc/alloc_controller.cpp
+++ b/msm8996/libgralloc/alloc_controller.cpp
@@ -99,14 +99,10 @@
//------------- MDPCapabilityInfo-----------------------//
MDPCapabilityInfo :: MDPCapabilityInfo() {
- isMacroTileSupported = false;
qdutils::querySDEInfo(HAS_MACRO_TILE, &isMacroTileSupported);
+ qdutils::querySDEInfo(HAS_UBWC, &isUBwcSupported);
}
-int MDPCapabilityInfo :: isMacroTilingSupportedByMDP(){
- return isMacroTileSupported;
- }
-
//------------- AdrenoMemInfo-----------------------//
AdrenoMemInfo::AdrenoMemInfo()
{
@@ -932,20 +928,23 @@
static bool isUBwcSupported(int format)
{
- // Existing HAL formats with UBWC support
- switch(format)
- {
- case HAL_PIXEL_FORMAT_BGR_565:
- case HAL_PIXEL_FORMAT_RGBA_8888:
- case HAL_PIXEL_FORMAT_RGBX_8888:
- case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
- case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
- case HAL_PIXEL_FORMAT_RGBA_1010102:
- case HAL_PIXEL_FORMAT_RGBX_1010102:
- return true;
- default:
- return false;
+ if (MDPCapabilityInfo::getInstance().isUBwcSupportedByMDP()) {
+ // Existing HAL formats with UBWC support
+ switch(format)
+ {
+ case HAL_PIXEL_FORMAT_BGR_565:
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ case HAL_PIXEL_FORMAT_RGBX_8888:
+ case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+ case HAL_PIXEL_FORMAT_RGBA_1010102:
+ case HAL_PIXEL_FORMAT_RGBX_1010102:
+ return true;
+ default:
+ break;
+ }
}
+ return false;
}
bool isUBwcEnabled(int format, int usage)
diff --git a/msm8996/libgralloc/gr.h b/msm8996/libgralloc/gr.h
index e7d449e..5fe1bdb 100644
--- a/msm8996/libgralloc/gr.h
+++ b/msm8996/libgralloc/gr.h
@@ -201,7 +201,9 @@
class MDPCapabilityInfo : public android::Singleton <MDPCapabilityInfo>
{
- int isMacroTileSupported;
+ int isMacroTileSupported = 0;
+ int isUBwcSupported = 0;
+
public:
MDPCapabilityInfo();
/*
@@ -210,8 +212,14 @@
* @return 1 : supported
* 0 : not supported
*/
- int isMacroTilingSupportedByMDP();
-
+ int isMacroTilingSupportedByMDP() { return isMacroTileSupported; }
+ /*
+ * Function to return whether MDP supports UBWC feature
+ *
+ * @return 1 : supported
+ * 0 : not supported
+ */
+ int isUBwcSupportedByMDP() { return isUBwcSupported; }
};
#endif /* GR_H_ */
diff --git a/msm8996/libmemtrack/kgsl.c b/msm8996/libmemtrack/kgsl.c
index 4ad94ce..5a6b075 100644
--- a/msm8996/libmemtrack/kgsl.c
+++ b/msm8996/libmemtrack/kgsl.c
@@ -83,7 +83,7 @@
* count the entry as accounted else count the entry as unaccounted.
*/
while (1) {
- unsigned long size;
+ unsigned long size, mapsize;
char line_type[7];
char flags[8];
char line_usage[19];
@@ -94,20 +94,21 @@
}
/* Format:
- * gpuaddr useraddr size id flags type usage sglen
- * 545ba000 545ba000 4096 1 -----pY gpumem arraybuffer 1
+ * gpuaddr useraddr size id flags type usage sglen mapsize
+ * 545ba000 545ba000 4096 1 -----pY gpumem arraybuffer 1 4096
*/
- ret = sscanf(line, "%*x %*x %lu %*d %7s %6s %18s %*d\n",
- &size, flags, line_type, line_usage);
- if (ret != 4) {
+ ret = sscanf(line, "%*x %*x %lu %*d %7s %6s %18s %*d %lu\n",
+ &size, flags, line_type, line_usage, &mapsize);
+ if (ret != 5) {
continue;
}
if (type == MEMTRACK_TYPE_GL && strcmp(line_type, "gpumem") == 0) {
- if (flags[6] == 'Y')
- accounted_size += size;
- else
+ if (flags[6] == 'Y') {
+ accounted_size += mapsize;
+ unaccounted_size += size - mapsize;
+ } else
unaccounted_size += size;
} else if (type == MEMTRACK_TYPE_GRAPHICS && strcmp(line_type, "ion") == 0) {
diff --git a/msm8996/libqdutils/qd_utils.cpp b/msm8996/libqdutils/qd_utils.cpp
index 254df30..6453b58 100644
--- a/msm8996/libqdutils/qd_utils.cpp
+++ b/msm8996/libqdutils/qd_utils.cpp
@@ -62,6 +62,10 @@
featureName = "tile_format";
break;
+ case HAS_UBWC:
+ featureName = "ubwc";
+ break;
+
default:
ALOGE("Invalid query type %d", type);
return -EINVAL;
diff --git a/msm8996/libqdutils/qd_utils.h b/msm8996/libqdutils/qd_utils.h
index 2b9ca74..0392e05 100644
--- a/msm8996/libqdutils/qd_utils.h
+++ b/msm8996/libqdutils/qd_utils.h
@@ -48,6 +48,7 @@
enum HWQueryType {
HAS_MACRO_TILE = 0,
+ HAS_UBWC = 1,
};
enum {
diff --git a/msm8996/libqservice/IQService.h b/msm8996/libqservice/IQService.h
index 2d7dddc..49467db 100644
--- a/msm8996/libqservice/IQService.h
+++ b/msm8996/libqservice/IQService.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2012-2014, 2016 The Linux Foundation. All rights reserved.
*
* Not a Contribution, Apache license notifications and license are
* retained for attribution purposes only.
@@ -72,6 +72,7 @@
SET_CAMERA_STATUS = 30, // To notify display when camera is on and off
MIN_HDCP_ENCRYPTION_LEVEL_CHANGED = 31,
GET_BW_TRANSACTION_STATUS = 32, //Client can query BW transaction status.
+ SET_LAYER_MIXER_RESOLUTION = 33, // Enables client to set layer mixer resolution.
COMMAND_LIST_END = 400,
};
diff --git a/msm8996/sdm/include/core/display_interface.h b/msm8996/sdm/include/core/display_interface.h
index 951cd54..bb89d1d 100644
--- a/msm8996/sdm/include/core/display_interface.h
+++ b/msm8996/sdm/include/core/display_interface.h
@@ -76,6 +76,48 @@
//!< if VSync is enabled. Contents are not rendered in this state.
};
+/*! @brief This enum represents flags to override detail enhancer parameters.
+
+ @sa DisplayInterface::SetDetailEnhancerData
+*/
+enum DetailEnhancerOverrideFlags {
+ kOverrideDEEnable = 0x1, // Specifies to enable detail enhancer
+ kOverrideDESharpen1 = 0x2, // Specifies user defined Sharpening/smooth for noise
+ kOverrideDESharpen2 = 0x4, // Specifies user defined Sharpening/smooth for signal
+ kOverrideDEClip = 0x8, // Specifies user defined DE clip shift
+ kOverrideDELimit = 0x10, // Specifies user defined DE limit value
+ kOverrideDEThrQuiet = 0x20, // Specifies user defined DE quiet threshold
+ kOverrideDEThrDieout = 0x40, // Specifies user defined DE dieout threshold
+ kOverrideDEThrLow = 0x80, // Specifies user defined DE low threshold
+ kOverrideDEThrHigh = 0x100, // Specifies user defined DE high threshold
+ kOverrideDEFilterConfig = 0x200, // Specifies user defined scaling filter config
+ kOverrideDEMax = 0xFFFFFFFF,
+};
+
+/*! @brief This enum represents Y/RGB scaling filter configuration.
+
+ @sa DisplayInterface::SetDetailEnhancerData
+*/
+enum ScalingFilterConfig {
+ kFilterEdgeDirected,
+ kFilterCircular,
+ kFilterSeparable,
+ kFilterBilinear,
+ kFilterMax,
+};
+
+/*! @brief This enum represents the quality level of the content.
+
+ @sa DisplayInterface::SetDetailEnhancerData
+*/
+enum ContentQuality {
+ kContentQualityUnknown, // Default: high artifact and noise
+ kContentQualityLow, // Low quality content, high artifact and noise,
+ kContentQualityMedium, // Medium quality, medium artifact and noise,
+ kContentQualityHigh, // High quality content, low artifact and noise
+ kContentQualityMax,
+};
+
/*! @brief This structure defines configuration for fixed properties of a display device.
@sa DisplayInterface::GetConfig
@@ -109,6 +151,30 @@
int64_t timestamp = 0; //!< System monotonic clock timestamp in nanoseconds.
};
+/*! @brief The structure defines the user input for detail enhancer module.
+
+ @sa DisplayInterface::SetDetailEnhancerData
+*/
+struct DisplayDetailEnhancerData {
+ uint32_t override_flags = 0; // flags to specify which data to be set.
+ uint16_t enable = 0; // Detail enchancer enable
+ int16_t sharpen_level1 = 0; // Sharpening/smooth strenght for noise
+ int16_t sharpen_level2 = 0; // Sharpening/smooth strenght for signal
+ uint16_t clip = 0; // DE clip shift
+ uint16_t limit = 0; // DE limit value
+ uint16_t thr_quiet = 0; // DE quiet threshold
+ uint16_t thr_dieout = 0; // DE dieout threshold
+ uint16_t thr_low = 0; // DE low threshold
+ uint16_t thr_high = 0; // DE high threshold
+ int32_t sharp_factor = 50; // sharp_factor specifies sharpness/smoothness level,
+ // range -100..100 positive for sharpness and negative for
+ // smoothness
+ ContentQuality quality_level = kContentQualityUnknown;
+ // Specifies context quality level
+ ScalingFilterConfig filter_config = kFilterEdgeDirected;
+ // Y/RGB filter configuration
+};
+
/*! @brief Display device event handler implemented by the client.
@details This class declares prototype for display device event handler methods which must be
@@ -343,6 +409,11 @@
*/
virtual DisplayError ControlPartialUpdate(bool enable, uint32_t *pending) = 0;
+ /*! @brief Method to disable partial update for at least 1 frame.
+ @return \link DisplayError \endlink
+ */
+ virtual DisplayError DisablePartialUpdateOneFrame() = 0;
+
/*! @brief Method to set the mode of the primary display.
@param[in] mode the new display mode.
@@ -351,13 +422,6 @@
*/
virtual DisplayError SetDisplayMode(uint32_t mode) = 0;
- /*! @brief Method to determine whether scaling for a custom resolution is valid.
-
- @return \link DisplayError \endlink
- */
- virtual DisplayError IsScalingValid(const LayerRect &crop, const LayerRect &dst,
- bool rotate90) = 0;
-
/*! @brief Method to get the min and max refresh rate of a display.
@param[out] min and max refresh rate.
@@ -467,6 +531,48 @@
*/
virtual DisplayError GetPanelBrightness(int *level) = 0;
+ /*! @brief Method to set layer mixer resolution.
+
+ @param[in] width layer mixer width
+ @param[in] height layer mixer height
+
+ @return \link DisplayError \endlink
+ */
+ virtual DisplayError SetMixerResolution(uint32_t width, uint32_t height) = 0;
+
+ /*! @brief Method to get layer mixer resolution.
+
+ @param[out] width layer mixer width
+ @param[out] height layer mixer height
+
+ @return \link DisplayError \endlink
+ */
+ virtual DisplayError GetMixerResolution(uint32_t *width, uint32_t *height) = 0;
+
+ /*! @brief Method to set frame buffer configuration.
+
+ @param[in] variable_info \link DisplayConfigVariableInfo \endlink
+
+ @return \link DisplayError \endlink
+ */
+ virtual DisplayError SetFrameBufferConfig(const DisplayConfigVariableInfo &variable_info) = 0;
+
+ /*! @brief Method to get frame buffer configuration.
+
+ @param[out] variable_info \link DisplayConfigVariableInfo \endlink
+
+ @return \link DisplayError \endlink
+ */
+ virtual DisplayError GetFrameBufferConfig(DisplayConfigVariableInfo *variable_info) = 0;
+
+ /*! @brief Method to set detail enhancement data.
+
+ @param[in] de_data \link DisplayDetailEnhancerData \endlink
+
+ @return \link DisplayError \endlink
+ */
+ virtual DisplayError SetDetailEnhancerData(const DisplayDetailEnhancerData &de_data) = 0;
+
protected:
virtual ~DisplayInterface() { }
};
diff --git a/msm8996/sdm/include/core/layer_buffer.h b/msm8996/sdm/include/core/layer_buffer.h
index 7eba4e3..7713394 100644
--- a/msm8996/sdm/include/core/layer_buffer.h
+++ b/msm8996/sdm/include/core/layer_buffer.h
@@ -68,6 +68,7 @@
kFormatXBGR2101010, //!< 10-bits Padding, Blue, Green, Red interleaved in XBGR order. No Alpha.
kFormatRGBA1010102Ubwc, //!< UBWC aligned RGBA1010102 format
kFormatRGBX1010102Ubwc, //!< UBWC aligned RGBX1010102 format
+ kFormatRGB101010, // 10-bits Red, Green, Blue, interleaved in RGB order. No Alpha.
/* All YUV-Planar formats, Any new format will be added towards end of this group to maintain
backward compatibility.
diff --git a/msm8996/sdm/include/private/extension_interface.h b/msm8996/sdm/include/private/extension_interface.h
index 4283b53..dea127e 100644
--- a/msm8996/sdm/include/private/extension_interface.h
+++ b/msm8996/sdm/include/private/extension_interface.h
@@ -54,11 +54,16 @@
public:
virtual DisplayError CreatePartialUpdate(DisplayType type, const HWResourceInfo &hw_resource_info,
const HWPanelInfo &hw_panel_info,
+ const HWMixerAttributes &mixer_attributes,
+ const HWDisplayAttributes &display_attributes,
PartialUpdateInterface **interface) = 0;
virtual DisplayError DestroyPartialUpdate(PartialUpdateInterface *interface) = 0;
virtual DisplayError CreateStrategyExtn(DisplayType type, HWDisplayMode mode,
- HWS3DMode s3d_mode, StrategyInterface **interface) = 0;
+ HWS3DMode s3d_mode,
+ const HWMixerAttributes &mixer_attributes,
+ const DisplayConfigVariableInfo &fb_config,
+ StrategyInterface **interface) = 0;
virtual DisplayError DestroyStrategyExtn(StrategyInterface *interface) = 0;
virtual DisplayError CreateResourceExtn(const HWResourceInfo &hw_resource_info,
diff --git a/msm8996/sdm/include/private/hw_info_types.h b/msm8996/sdm/include/private/hw_info_types.h
index 70d5b96..0f40e17 100644
--- a/msm8996/sdm/include/private/hw_info_types.h
+++ b/msm8996/sdm/include/private/hw_info_types.h
@@ -91,15 +91,6 @@
kHWSubBlockMax,
};
-// y/RGB & UV Scaling Filters
-enum HWScalingFilter {
- kScalingFilterEdgeDirected,
- kScalingFilterCircular,
- kScalingFilterSeparable,
- kScalingFilterBilinear,
- kScalingFilterMax,
-};
-
enum HWAlphaInterpolation {
kInterpolationPixelRepeat,
kInterpolationBilinear,
@@ -142,6 +133,13 @@
void Reset() { *this = HWRotatorInfo(); }
};
+struct HWDestScalarInfo {
+ uint32_t count = 0;
+ uint32_t max_input_width = 0;
+ uint32_t max_output_width = 0;
+ uint32_t max_scale_up = 1;
+};
+
struct HWResourceInfo {
uint32_t hw_version = 0;
uint32_t hw_revision = 0;
@@ -188,6 +186,7 @@
std::vector<HWPipeCaps> hw_pipes;
FormatsMap supported_formats_map;
HWRotatorInfo hw_rot_info;
+ HWDestScalarInfo hw_dest_scalar_info;
void Reset() { *this = HWResourceInfo(); }
};
@@ -308,16 +307,7 @@
uint64_t sep_lut = 0;
};
-struct HWDetailEnhanceData {
- uint32_t enable = 0;
- int16_t sharpen_level1 = 0;
- int16_t sharpen_level2 = 0;
- uint16_t clip = 0;
- uint16_t limit = 0;
- uint16_t thr_quiet = 0;
- uint16_t thr_dieout = 0;
- uint16_t thr_low = 0;
- uint16_t thr_high = 0;
+struct HWDetailEnhanceData : DisplayDetailEnhancerData {
uint16_t prec_shift = 0;
int16_t adjust_a[MAX_DETAIL_ENHANCE_CURVE] = {0};
int16_t adjust_b[MAX_DETAIL_ENHANCE_CURVE] = {0};
@@ -362,8 +352,8 @@
uint32_t dst_height = 0;
HWPlane plane[MAX_PLANES];
// scale_v2_data fields
- HWScalingFilter y_rgb_filter_cfg = kScalingFilterEdgeDirected;
- HWScalingFilter uv_filter_cfg = kScalingFilterEdgeDirected;
+ ScalingFilterConfig y_rgb_filter_cfg = kFilterEdgeDirected;
+ ScalingFilterConfig uv_filter_cfg = kFilterEdgeDirected;
HWAlphaInterpolation alpha_filter_cfg = kInterpolationPixelRepeat;
HWBlendingFilter blend_cfg = kBlendFilterCircular;
@@ -386,6 +376,15 @@
HWDetailEnhanceData detail_enhance;
};
+struct HWDestScaleInfo {
+ uint32_t mixer_width = 0;
+ uint32_t mixer_height = 0;
+ bool scale_update = false;
+ HWScaleData scale_data = {};
+};
+
+typedef std::map<uint32_t, HWDestScaleInfo *> DestScaleInfoMap;
+
struct HWPipeInfo {
uint32_t pipe_id = 0;
HWSubBlockType sub_block_type = kHWSubBlockMax;
@@ -427,6 +426,7 @@
LayerRect right_partial_update; // Right ROI.
bool use_hw_cursor = false; // Indicates that HWCursor pipe needs to be used for cursor layer
+ DestScaleInfoMap dest_scale_info_map = {};
};
struct HWLayers {
@@ -439,7 +439,6 @@
struct HWDisplayAttributes : DisplayConfigVariableInfo {
bool is_device_split = false;
- uint32_t split_left = 0;
uint32_t v_front_porch = 0; //!< Vertical front porch of panel
uint32_t v_back_porch = 0; //!< Vertical back porch of panel
uint32_t v_pulse_width = 0; //!< Vertical pulse width of panel
@@ -448,20 +447,44 @@
void Reset() { *this = HWDisplayAttributes(); }
- bool operator !=(const HWDisplayAttributes &attributes) {
- return ((is_device_split != attributes.is_device_split) ||
- (split_left != attributes.split_left) ||
- (x_pixels != attributes.x_pixels) || (y_pixels != attributes.y_pixels) ||
- (x_dpi != attributes.x_dpi) || (y_dpi != attributes.y_dpi) || (fps != attributes.fps) ||
- (vsync_period_ns != attributes.vsync_period_ns) ||
- (v_front_porch != attributes.v_front_porch) ||
- (v_back_porch != attributes.v_back_porch) ||
- (v_pulse_width != attributes.v_pulse_width) ||
- (is_yuv != attributes.is_yuv));
+ bool operator !=(const HWDisplayAttributes &display_attributes) {
+ return ((is_device_split != display_attributes.is_device_split) ||
+ (x_pixels != display_attributes.x_pixels) ||
+ (y_pixels != display_attributes.y_pixels) ||
+ (x_dpi != display_attributes.x_dpi) ||
+ (y_dpi != display_attributes.y_dpi) ||
+ (fps != display_attributes.fps) ||
+ (vsync_period_ns != display_attributes.vsync_period_ns) ||
+ (v_front_porch != display_attributes.v_front_porch) ||
+ (v_back_porch != display_attributes.v_back_porch) ||
+ (v_pulse_width != display_attributes.v_pulse_width) ||
+ (is_yuv != display_attributes.is_yuv));
}
- bool operator ==(const HWDisplayAttributes &attributes) {
- return !(operator !=(attributes));
+ bool operator ==(const HWDisplayAttributes &display_attributes) {
+ return !(operator !=(display_attributes));
+ }
+};
+
+struct HWMixerAttributes {
+ uint32_t width = 0; // Layer mixer width
+ uint32_t height = 0; // Layer mixer height
+ uint32_t split_left = 0;
+ LayerBufferFormat output_format = kFormatRGB101010; // Layer mixer output format
+
+ bool operator !=(const HWMixerAttributes &mixer_attributes) {
+ return ((width != mixer_attributes.width) ||
+ (height != mixer_attributes.height) ||
+ (output_format != mixer_attributes.output_format) ||
+ (split_left != mixer_attributes.split_left));
+ }
+
+ bool operator ==(const HWMixerAttributes &mixer_attributes) {
+ return !(operator !=(mixer_attributes));
+ }
+
+ bool IsValid() {
+ return (width > 0 && height > 0);
}
};
diff --git a/msm8996/sdm/include/private/resource_interface.h b/msm8996/sdm/include/private/resource_interface.h
index 21652f5..6115112 100644
--- a/msm8996/sdm/include/private/resource_interface.h
+++ b/msm8996/sdm/include/private/resource_interface.h
@@ -32,11 +32,16 @@
class ResourceInterface {
public:
- virtual DisplayError RegisterDisplay(DisplayType type, const HWDisplayAttributes &attributes,
- const HWPanelInfo &hw_panel_info, Handle *display_ctx) = 0;
+ virtual DisplayError RegisterDisplay(DisplayType type,
+ const HWDisplayAttributes &display_attributes,
+ const HWPanelInfo &hw_panel_info,
+ const HWMixerAttributes &mixer_attributes,
+ Handle *display_ctx) = 0;
virtual DisplayError UnregisterDisplay(Handle display_ctx) = 0;
- virtual void ReconfigureDisplay(Handle display_ctx, const HWDisplayAttributes &attributes,
- const HWPanelInfo &hw_panel_info) = 0;
+ virtual DisplayError ReconfigureDisplay(Handle display_ctx,
+ const HWDisplayAttributes &display_attributes,
+ const HWPanelInfo &hw_panel_info,
+ const HWMixerAttributes &mixer_attributes) = 0;
virtual DisplayError Start(Handle display_ctx) = 0;
virtual DisplayError Stop(Handle display_ctx) = 0;
virtual DisplayError Acquire(Handle display_ctx, HWLayers *hw_layers) = 0;
@@ -53,6 +58,8 @@
int x, int y) = 0;
virtual DisplayError SetMaxBandwidthMode(HWBwModes mode) = 0;
virtual DisplayError GetScaleLutConfig(HWScaleLutInfo *lut_info) = 0;
+ virtual DisplayError SetDetailEnhancerData(Handle display_ctx,
+ const DisplayDetailEnhancerData &de_data) = 0;
protected:
virtual ~ResourceInterface() { }
diff --git a/msm8996/sdm/include/private/strategy_interface.h b/msm8996/sdm/include/private/strategy_interface.h
index 17acfed..f2bfe23 100644
--- a/msm8996/sdm/include/private/strategy_interface.h
+++ b/msm8996/sdm/include/private/strategy_interface.h
@@ -48,7 +48,9 @@
virtual DisplayError Start(HWLayersInfo *hw_layers_info, uint32_t *max_attempts) = 0;
virtual DisplayError GetNextStrategy(StrategyConstraints *constraints) = 0;
virtual DisplayError Stop() = 0;
- virtual DisplayError Reconfigure(HWDisplayMode mode, HWS3DMode s3d_mode) = 0;
+ virtual DisplayError Reconfigure(HWDisplayMode mode, HWS3DMode s3d_mode,
+ const HWMixerAttributes &mixer_attributes,
+ const DisplayConfigVariableInfo &fb_config) = 0;
protected:
virtual ~StrategyInterface() { }
diff --git a/msm8996/sdm/include/utils/rect.h b/msm8996/sdm/include/utils/rect.h
index c198645..d084556 100644
--- a/msm8996/sdm/include/utils/rect.h
+++ b/msm8996/sdm/include/utils/rect.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -37,6 +37,12 @@
namespace sdm {
+ enum RectOrientation {
+ kOrientationPortrait,
+ kOrientationLandscape,
+ kOrientationUnknown,
+ };
+
bool IsValid(const LayerRect &rect);
bool IsCongruent(const LayerRect &rect1, const LayerRect &rect2);
void Log(DebugTag debug_tag, const char *prefix, const LayerRect &roi);
@@ -49,6 +55,9 @@
bool flip_horizontal, LayerRect *out_rects);
void SplitTopBottom(const LayerRect &in_rect, uint32_t split_count, uint32_t align_y,
bool flip_horizontal, LayerRect *out_rects);
+ void ScaleRect(const LayerRect &src_domain, const LayerRect &dst_domain, const LayerRect &in_rect,
+ LayerRect *out_rect);
+ RectOrientation GetOrientation(const LayerRect &in_rect);
} // namespace sdm
#endif // __RECT_H__
diff --git a/msm8996/sdm/libs/core/comp_manager.cpp b/msm8996/sdm/libs/core/comp_manager.cpp
index 562186c..6fa7e5f 100644
--- a/msm8996/sdm/libs/core/comp_manager.cpp
+++ b/msm8996/sdm/libs/core/comp_manager.cpp
@@ -69,8 +69,12 @@
return kErrorNone;
}
-DisplayError CompManager::RegisterDisplay(DisplayType type, const HWDisplayAttributes &attributes,
- const HWPanelInfo &hw_panel_info, Handle *display_ctx) {
+DisplayError CompManager::RegisterDisplay(DisplayType type,
+ const HWDisplayAttributes &display_attributes,
+ const HWPanelInfo &hw_panel_info,
+ const HWMixerAttributes &mixer_attributes,
+ const DisplayConfigVariableInfo &fb_config,
+ Handle *display_ctx) {
SCOPE_LOCK(locker_);
DisplayError error = kErrorNone;
@@ -81,7 +85,8 @@
}
Strategy *&strategy = display_comp_ctx->strategy;
- strategy = new Strategy(extension_intf_, type, hw_res_info_, hw_panel_info, attributes);
+ strategy = new Strategy(extension_intf_, type, hw_res_info_, hw_panel_info, mixer_attributes,
+ display_attributes, fb_config);
if (!strategy) {
DLOGE("Unable to create strategy");
delete display_comp_ctx;
@@ -95,7 +100,7 @@
return error;
}
- error = resource_intf_->RegisterDisplay(type, attributes, hw_panel_info,
+ error = resource_intf_->RegisterDisplay(type, display_attributes, hw_panel_info, mixer_attributes,
&display_comp_ctx->display_resource_ctx);
if (error != kErrorNone) {
strategy->Deinit();
@@ -154,17 +159,25 @@
}
DisplayError CompManager::ReconfigureDisplay(Handle comp_handle,
- const HWDisplayAttributes &attributes,
- const HWPanelInfo &hw_panel_info) {
+ const HWDisplayAttributes &display_attributes,
+ const HWPanelInfo &hw_panel_info,
+ const HWMixerAttributes &mixer_attributes,
+ const DisplayConfigVariableInfo &fb_config) {
+ SCOPE_LOCK(locker_);
+
+ DisplayError error = kErrorNone;
DisplayCompositionContext *display_comp_ctx =
reinterpret_cast<DisplayCompositionContext *>(comp_handle);
- resource_intf_->ReconfigureDisplay(display_comp_ctx->display_resource_ctx, attributes,
- hw_panel_info);
+ error = resource_intf_->ReconfigureDisplay(display_comp_ctx->display_resource_ctx,
+ display_attributes, hw_panel_info, mixer_attributes);
+ if (error != kErrorNone) {
+ return error;
+ }
- DisplayError error = kErrorNone;
if (display_comp_ctx->strategy) {
- error = display_comp_ctx->strategy->Reconfigure(hw_panel_info, attributes);
+ error = display_comp_ctx->strategy->Reconfigure(hw_panel_info, display_attributes,
+ mixer_attributes, fb_config);
if (error != kErrorNone) {
DLOGE("Unable to Reconfigure strategy.");
display_comp_ctx->strategy->Deinit();
@@ -468,5 +481,15 @@
return resource_intf_->GetScaleLutConfig(lut_info);
}
+DisplayError CompManager::SetDetailEnhancerData(Handle display_ctx,
+ const DisplayDetailEnhancerData &de_data) {
+ SCOPE_LOCK(locker_);
+
+ DisplayCompositionContext *display_comp_ctx =
+ reinterpret_cast<DisplayCompositionContext *>(display_ctx);
+
+ return resource_intf_->SetDetailEnhancerData(display_comp_ctx->display_resource_ctx, de_data);
+}
+
} // namespace sdm
diff --git a/msm8996/sdm/libs/core/comp_manager.h b/msm8996/sdm/libs/core/comp_manager.h
index d6d45c1..a77eed0 100644
--- a/msm8996/sdm/libs/core/comp_manager.h
+++ b/msm8996/sdm/libs/core/comp_manager.h
@@ -41,11 +41,15 @@
DisplayError Init(const HWResourceInfo &hw_res_info_, ExtensionInterface *extension_intf,
BufferSyncHandler *buffer_sync_handler);
DisplayError Deinit();
- DisplayError RegisterDisplay(DisplayType type, const HWDisplayAttributes &attributes,
- const HWPanelInfo &hw_panel_info, Handle *res_mgr_hnd);
+ DisplayError RegisterDisplay(DisplayType type, const HWDisplayAttributes &display_attributes,
+ const HWPanelInfo &hw_panel_info,
+ const HWMixerAttributes &mixer_attributes,
+ const DisplayConfigVariableInfo &fb_config, Handle *res_mgr_hnd);
DisplayError UnregisterDisplay(Handle res_mgr_hnd);
- DisplayError ReconfigureDisplay(Handle display_ctx, const HWDisplayAttributes &attributes,
- const HWPanelInfo &hw_panel_info);
+ DisplayError ReconfigureDisplay(Handle display_ctx, const HWDisplayAttributes &display_attributes,
+ const HWPanelInfo &hw_panel_info,
+ const HWMixerAttributes &mixer_attributes,
+ const DisplayConfigVariableInfo &fb_config);
void PrePrepare(Handle display_ctx, HWLayers *hw_layers);
DisplayError Prepare(Handle display_ctx, HWLayers *hw_layers);
DisplayError PostPrepare(Handle display_ctx, HWLayers *hw_layers);
@@ -62,6 +66,7 @@
bool CanSetIdleTimeout(Handle display_ctx);
DisplayError SetMaxBandwidthMode(HWBwModes mode);
DisplayError GetScaleLutConfig(HWScaleLutInfo *lut_info);
+ DisplayError SetDetailEnhancerData(Handle display_ctx, const DisplayDetailEnhancerData &de_data);
// DumpImpl method
virtual void AppendDump(char *buffer, uint32_t length);
diff --git a/msm8996/sdm/libs/core/display_base.cpp b/msm8996/sdm/libs/core/display_base.cpp
index 8cbdeb2..d9583b7 100644
--- a/msm8996/sdm/libs/core/display_base.cpp
+++ b/msm8996/sdm/libs/core/display_base.cpp
@@ -56,6 +56,18 @@
uint32_t active_index = 0;
hw_intf_->GetActiveConfig(&active_index);
hw_intf_->GetDisplayAttributes(active_index, &display_attributes_);
+ fb_config_ = display_attributes_;
+
+ HWMixerAttributes mixer_attributes;
+ error = hw_intf_->GetMixerAttributes(&mixer_attributes);
+ if (error != kErrorNone) {
+ return error;
+ }
+ mixer_attributes_ = mixer_attributes;
+
+ // Override x_pixels and y_pixels of frame buffer with mixer width and height
+ fb_config_.x_pixels = mixer_attributes.width;
+ fb_config_.y_pixels = mixer_attributes.height;
HWScaleLutInfo lut_info = {};
error = comp_manager_->GetScaleLutConfig(&lut_info);
@@ -67,8 +79,8 @@
goto CleanupOnError;
}
- error = comp_manager_->RegisterDisplay(display_type_, display_attributes_,
- hw_panel_info_, &display_comp_ctx_);
+ error = comp_manager_->RegisterDisplay(display_type_, display_attributes_, hw_panel_info_,
+ mixer_attributes, fb_config_, &display_comp_ctx_);
if (error != kErrorNone) {
goto CleanupOnError;
}
@@ -161,17 +173,24 @@
return kErrorParameters;
}
- auto gpu_target_layer_dst_xpixels = gpu_target_layer->dst_rect.right;
- auto gpu_target_layer_dst_ypixels = gpu_target_layer->dst_rect.bottom;
+ float layer_mixer_width = FLOAT(mixer_attributes_.width);
+ float layer_mixer_height = FLOAT(mixer_attributes_.height);
+ float fb_width = FLOAT(fb_config_.x_pixels);
+ float fb_height = FLOAT(fb_config_.y_pixels);
+ LayerRect src_domain = (LayerRect){0.0f, 0.0f, fb_width, fb_height};
+ LayerRect dst_domain = (LayerRect){0.0f, 0.0f, layer_mixer_width, layer_mixer_height};
+ LayerRect out_rect = gpu_target_layer->dst_rect;
- HWDisplayAttributes display_attrib;
- uint32_t active_index = 0;
- hw_intf_->GetActiveConfig(&active_index);
- hw_intf_->GetDisplayAttributes(active_index, &display_attrib);
+ ScaleRect(src_domain, dst_domain, gpu_target_layer->dst_rect, &out_rect);
- if (gpu_target_layer_dst_xpixels > display_attrib.x_pixels ||
- gpu_target_layer_dst_ypixels > display_attrib.y_pixels) {
- DLOGE("GPU target layer dst rect is not with in limits");
+ auto gpu_target_layer_dst_xpixels = out_rect.right - out_rect.left;
+ auto gpu_target_layer_dst_ypixels = out_rect.bottom - out_rect.top;
+
+ if (gpu_target_layer_dst_xpixels > mixer_attributes_.width ||
+ gpu_target_layer_dst_ypixels > mixer_attributes_.height) {
+ DLOGE("GPU target layer dst rect is not with in limits gpu wxh %fx%f mixer wxh %dx%d",
+ gpu_target_layer_dst_xpixels, gpu_target_layer_dst_ypixels, mixer_attributes_.width,
+ mixer_attributes_.height);
return kErrorParameters;
}
@@ -179,35 +198,34 @@
}
DisplayError DisplayBase::Prepare(LayerStack *layer_stack) {
- DisplayError error = kErrorNone;
- bool disable_partial_update = false;
- uint32_t pending = 0;
+ SCOPE_LOCK(locker_);
+
+ if (!active_) {
+ return kErrorPermission;
+ }
if (!layer_stack) {
return kErrorParameters;
}
- pending_commit_ = false;
+ return PrepareLocked(layer_stack);
+}
+
+DisplayError DisplayBase::PrepareLocked(LayerStack *layer_stack) {
+ DisplayError error = kErrorNone;
error = ValidateGPUTarget(layer_stack);
if (error != kErrorNone) {
return error;
}
- if (!active_) {
- return kErrorPermission;
+ if (color_mgr_ && color_mgr_->NeedsPartialUpdateDisable()) {
+ DisablePartialUpdateOneFrameLocked();
}
- // Request to disable partial update only if it is currently enabled.
- if (color_mgr_ && partial_update_control_) {
- disable_partial_update = color_mgr_->NeedsPartialUpdateDisable();
- if (disable_partial_update) {
- ControlPartialUpdate(false, &pending);
- }
- }
-
- if (one_frame_full_roi_) {
- ControlPartialUpdate(false, &pending);
+ if (partial_update_control_ == false || disable_pu_one_frame_) {
+ comp_manager_->ControlPartialUpdate(display_comp_ctx_, false /* enable */);
+ disable_pu_one_frame_ = false;
}
// Clean hw layers for reuse.
@@ -249,29 +267,22 @@
}
comp_manager_->PostPrepare(display_comp_ctx_, &hw_layers_);
- if (disable_partial_update) {
- ControlPartialUpdate(true, &pending);
- }
-
- if (one_frame_full_roi_) {
- ControlPartialUpdate(true, &pending);
- one_frame_full_roi_ = false;
- }
return error;
}
DisplayError DisplayBase::Commit(LayerStack *layer_stack) {
- DisplayError error = kErrorNone;
+ SCOPE_LOCK(locker_);
+
+ if (!active_) {
+ pending_commit_ = false;
+ return kErrorPermission;
+ }
if (!layer_stack) {
return kErrorParameters;
}
- if (!active_) {
- return kErrorPermission;
- }
-
if (!pending_commit_) {
DLOGE("Commit: Corresponding Prepare() is not called for display = %d", display_type_);
return kErrorUndefined;
@@ -279,6 +290,12 @@
pending_commit_ = false;
+ return CommitLocked(layer_stack);
+}
+
+DisplayError DisplayBase::CommitLocked(LayerStack *layer_stack) {
+ DisplayError error = kErrorNone;
+
// Layer stack attributes has changed, need to Reconfigure, currently in use for Hybrid Comp
if (layer_stack->flags.attributes_changed) {
error = comp_manager_->ReConfigure(display_comp_ctx_, &hw_layers_);
@@ -319,6 +336,10 @@
}
}
+ if (partial_update_control_) {
+ comp_manager_->ControlPartialUpdate(display_comp_ctx_, true /* enable */);
+ }
+
error = comp_manager_->PostCommit(display_comp_ctx_, &hw_layers_);
if (error != kErrorNone) {
return error;
@@ -460,6 +481,11 @@
}
DisplayError DisplayBase::SetActiveConfig(uint32_t index) {
+ SCOPE_LOCK(locker_);
+ return SetActiveConfigLocked(index);
+}
+
+DisplayError DisplayBase::SetActiveConfigLocked(uint32_t index) {
DisplayError error = kErrorNone;
uint32_t active_index = 0;
@@ -474,26 +500,12 @@
return error;
}
- HWDisplayAttributes attrib;
- error = hw_intf_->GetDisplayAttributes(index, &attrib);
- if (error != kErrorNone) {
- return error;
- }
+ return ReconfigureDisplay();
+}
- hw_intf_->GetHWPanelInfo(&hw_panel_info_);
-
- if (display_comp_ctx_) {
- comp_manager_->UnregisterDisplay(display_comp_ctx_);
- }
-
- error = comp_manager_->RegisterDisplay(display_type_, attrib, hw_panel_info_,
- &display_comp_ctx_);
-
- if (error == kErrorNone && partial_update_control_) {
- one_frame_full_roi_ = true;
- }
-
- return error;
+DisplayError DisplayBase::SetActiveConfig(DisplayConfigVariableInfo *variable_info) {
+ SCOPE_LOCK(locker_);
+ return SetActiveConfigLocked(variable_info);
}
DisplayError DisplayBase::SetMaxMixerStages(uint32_t max_mixer_stages) {
@@ -509,43 +521,19 @@
}
DisplayError DisplayBase::ControlPartialUpdate(bool enable, uint32_t *pending) {
- if (!pending) {
- return kErrorParameters;
- }
+ SCOPE_LOCK(locker_);
+ return ControlPartialUpdateLocked(enable, pending);
+}
- if (!hw_panel_info_.partial_update) {
- // Nothing to be done.
- DLOGI("partial update is not applicable for display=%d", display_type_);
- return kErrorNotSupported;
- }
-
- *pending = 0;
- if (enable == partial_update_control_) {
- DLOGI("Same state transition is requested.");
- return kErrorNone;
- }
-
- partial_update_control_ = enable;
- comp_manager_->ControlPartialUpdate(display_comp_ctx_, enable);
-
- if (!enable) {
- // If the request is to turn off feature, new draw call is required to have
- // the new setting into effect.
- *pending = 1;
- }
-
- return kErrorNone;
+DisplayError DisplayBase::DisablePartialUpdateOneFrame() {
+ SCOPE_LOCK(locker_);
+ return DisablePartialUpdateOneFrameLocked();
}
DisplayError DisplayBase::SetDisplayMode(uint32_t mode) {
return kErrorNotSupported;
}
-DisplayError DisplayBase::IsScalingValid(const LayerRect &crop, const LayerRect &dst,
- bool rotate90) {
- return comp_manager_->ValidateScaling(crop, dst, rotate90);
-}
-
DisplayError DisplayBase::SetPanelBrightness(int level) {
return kErrorNotSupported;
}
@@ -878,4 +866,135 @@
return error;
}
+DisplayError DisplayBase::ReconfigureDisplay() {
+ DisplayError error = kErrorNone;
+ HWDisplayAttributes display_attributes;
+ HWMixerAttributes mixer_attributes;
+ HWPanelInfo hw_panel_info;
+ uint32_t active_index = 0;
+
+ error = hw_intf_->GetActiveConfig(&active_index);
+ if (error != kErrorNone) {
+ return error;
+ }
+
+ error = hw_intf_->GetDisplayAttributes(active_index, &display_attributes);
+ if (error != kErrorNone) {
+ return error;
+ }
+
+ error = hw_intf_->GetMixerAttributes(&mixer_attributes);
+ if (error != kErrorNone) {
+ return error;
+ }
+
+ error = hw_intf_->GetHWPanelInfo(&hw_panel_info);
+ if (error != kErrorNone) {
+ return error;
+ }
+
+ if (display_attributes == display_attributes_ && mixer_attributes == mixer_attributes_ &&
+ hw_panel_info == hw_panel_info_) {
+ return kErrorNone;
+ }
+
+ error = comp_manager_->ReconfigureDisplay(display_comp_ctx_, display_attributes, hw_panel_info,
+ mixer_attributes, fb_config_);
+ if (error != kErrorNone) {
+ return error;
+ }
+
+ if (mixer_attributes != mixer_attributes_) {
+ DisablePartialUpdateOneFrameLocked();
+ }
+
+ display_attributes_ = display_attributes;
+ mixer_attributes_ = mixer_attributes;
+ hw_panel_info_ = hw_panel_info;
+
+ return kErrorNone;
+}
+
+DisplayError DisplayBase::SetMixerResolution(uint32_t width, uint32_t height) {
+ SCOPE_LOCK(locker_);
+ return SetMixerResolutionLocked(width, height);
+}
+
+DisplayError DisplayBase::GetMixerResolution(uint32_t *width, uint32_t *height) {
+ SCOPE_LOCK(locker_);
+ return GetMixerResolutionLocked(width, height);
+}
+
+DisplayError DisplayBase::GetMixerResolutionLocked(uint32_t *width, uint32_t *height) {
+ if (!width || !height) {
+ return kErrorParameters;
+ }
+
+ *width = mixer_attributes_.width;
+ *height = mixer_attributes_.height;
+
+ return kErrorNone;
+}
+
+DisplayError DisplayBase::SetFrameBufferConfig(const DisplayConfigVariableInfo &variable_info) {
+ SCOPE_LOCK(locker_);
+ return SetFrameBufferConfigLocked(variable_info);
+}
+
+DisplayError DisplayBase::SetFrameBufferConfigLocked(
+ const DisplayConfigVariableInfo &variable_info) {
+ uint32_t width = variable_info.x_pixels;
+ uint32_t height = variable_info.y_pixels;
+
+ if (width == 0 || height == 0) {
+ DLOGE("Unsupported resolution: (%dx%d)", width, height);
+ return kErrorParameters;
+ }
+
+ // Create rects to represent the new source and destination crops
+ LayerRect crop = LayerRect(0, 0, FLOAT(width), FLOAT(height));
+ LayerRect dst = LayerRect(0, 0, FLOAT(mixer_attributes_.width), FLOAT(mixer_attributes_.height));
+ // Set rotate90 to false since this is taken care of during regular composition.
+ bool rotate90 = false;
+
+ DisplayError error = comp_manager_->ValidateScaling(crop, dst, rotate90);
+ if (error != kErrorNone) {
+ DLOGE("Unsupported resolution: (%dx%d)", width, height);
+ return kErrorParameters;
+ }
+
+ error = comp_manager_->ReconfigureDisplay(display_comp_ctx_, display_attributes_, hw_panel_info_,
+ mixer_attributes_, variable_info);
+ if (error != kErrorNone) {
+ return error;
+ }
+
+ fb_config_.x_pixels = width;
+ fb_config_.y_pixels = height;
+
+ DLOGI("New framebuffer resolution (%dx%d)", fb_config_.x_pixels, fb_config_.y_pixels);
+
+ return kErrorNone;
+}
+
+DisplayError DisplayBase::GetFrameBufferConfig(DisplayConfigVariableInfo *variable_info) {
+ SCOPE_LOCK(locker_);
+ return GetFrameBufferConfigLocked(variable_info);
+}
+
+DisplayError DisplayBase::GetFrameBufferConfigLocked(DisplayConfigVariableInfo *variable_info) {
+ if (!variable_info) {
+ return kErrorParameters;
+ }
+
+ *variable_info = fb_config_;
+
+ return kErrorNone;
+}
+
+DisplayError DisplayBase::SetDetailEnhancerData(const DisplayDetailEnhancerData &de_data) {
+ SCOPE_LOCK(locker_);
+ return SetDetailEnhancerDataLocked(de_data);
+}
+
} // namespace sdm
diff --git a/msm8996/sdm/libs/core/display_base.h b/msm8996/sdm/libs/core/display_base.h
index 3d58ed6..1672351 100644
--- a/msm8996/sdm/libs/core/display_base.h
+++ b/msm8996/sdm/libs/core/display_base.h
@@ -54,8 +54,8 @@
virtual ~DisplayBase() { }
virtual DisplayError Init();
virtual DisplayError Deinit();
- virtual DisplayError Prepare(LayerStack *layer_stack);
- virtual DisplayError Commit(LayerStack *layer_stack);
+ DisplayError Prepare(LayerStack *layer_stack) final;
+ DisplayError Commit(LayerStack *layer_stack) final;
virtual DisplayError Flush();
virtual DisplayError GetDisplayState(DisplayState *state);
virtual DisplayError GetNumVariableInfoConfigs(uint32_t *count);
@@ -63,11 +63,12 @@
virtual DisplayError GetActiveConfig(uint32_t *index);
virtual DisplayError GetVSyncState(bool *enabled);
virtual DisplayError SetDisplayState(DisplayState state);
- virtual DisplayError SetActiveConfig(uint32_t index);
+ DisplayError SetActiveConfig(uint32_t index) final;
+ DisplayError SetActiveConfig(DisplayConfigVariableInfo *variable_info) final;
virtual DisplayError SetMaxMixerStages(uint32_t max_mixer_stages);
- virtual DisplayError ControlPartialUpdate(bool enable, uint32_t *pending);
+ DisplayError ControlPartialUpdate(bool enable, uint32_t *pending) final;
+ DisplayError DisablePartialUpdateOneFrame() final;
virtual DisplayError SetDisplayMode(uint32_t mode);
- virtual DisplayError IsScalingValid(const LayerRect &crop, const LayerRect &dst, bool rotate90);
virtual bool IsUnderscanSupported();
virtual DisplayError SetPanelBrightness(int level);
virtual DisplayError OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level);
@@ -83,21 +84,49 @@
virtual DisplayError GetRefreshRateRange(uint32_t *min_refresh_rate, uint32_t *max_refresh_rate);
virtual DisplayError GetPanelBrightness(int *level);
virtual DisplayError SetVSyncState(bool enable);
+ DisplayError SetMixerResolution(uint32_t width, uint32_t height) final;
+ DisplayError GetMixerResolution(uint32_t *width, uint32_t *height) final;
+ DisplayError SetFrameBufferConfig(const DisplayConfigVariableInfo &variable_info) final;
+ DisplayError GetFrameBufferConfig(DisplayConfigVariableInfo *variable_info) final;
+ DisplayError SetDetailEnhancerData(const DisplayDetailEnhancerData &de_data) final;
protected:
+ virtual DisplayError PrepareLocked(LayerStack *layer_stack);
+ virtual DisplayError CommitLocked(LayerStack *layer_stack);
+ virtual DisplayError SetActiveConfigLocked(uint32_t index);
+ virtual DisplayError SetActiveConfigLocked(DisplayConfigVariableInfo *variable_info) {
+ return kErrorNotSupported;
+ }
+ virtual DisplayError ControlPartialUpdateLocked(bool enable, uint32_t *pending) {
+ return kErrorNotSupported;
+ }
+ virtual DisplayError DisablePartialUpdateOneFrameLocked() {
+ return kErrorNotSupported;
+ }
+ virtual DisplayError SetMixerResolutionLocked(uint32_t width, uint32_t height) {
+ return kErrorNotSupported;
+ }
+ virtual DisplayError GetMixerResolutionLocked(uint32_t *width, uint32_t *height);
+ virtual DisplayError SetFrameBufferConfigLocked(const DisplayConfigVariableInfo &variable_info);
+ virtual DisplayError GetFrameBufferConfigLocked(DisplayConfigVariableInfo *variable_info);
+ virtual DisplayError SetDetailEnhancerDataLocked(const DisplayDetailEnhancerData &de_data) {
+ return kErrorNotSupported;
+ }
+
// DumpImpl method
void AppendDump(char *buffer, uint32_t length);
bool IsRotationRequired(HWLayers *hw_layers);
const char *GetName(const LayerComposition &composition);
DisplayError ValidateGPUTarget(LayerStack *layer_stack);
+ DisplayError ReconfigureDisplay();
+ Locker locker_;
DisplayType display_type_;
DisplayEventHandler *event_handler_ = NULL;
HWDeviceType hw_device_type_;
HWInterface *hw_intf_ = NULL;
HWPanelInfo hw_panel_info_;
- HWDisplayAttributes display_attributes_;
BufferSyncHandler *buffer_sync_handler_ = NULL;
CompManager *comp_manager_ = NULL;
RotatorInterface *rotator_intf_ = NULL;
@@ -115,14 +144,17 @@
ColorManagerProxy *color_mgr_ = NULL; // each display object owns its ColorManagerProxy
bool partial_update_control_ = true;
HWEventsInterface *hw_events_intf_ = NULL;
+ bool disable_pu_one_frame_ = false;
uint32_t num_color_modes_ = 0;
SDEDisplayMode *color_modes_ = NULL;
int32_t color_mode_ = 0;
typedef std::map<std::string, SDEDisplayMode *> ColorModeMap;
ColorModeMap color_mode_map_ = {};
+ HWDisplayAttributes display_attributes_ = {};
+ HWMixerAttributes mixer_attributes_ = {};
+ DisplayConfigVariableInfo fb_config_ = {};
private:
- bool one_frame_full_roi_ = false;
// Unused
virtual DisplayError GetConfig(DisplayConfigFixedInfo *variable_info) {
return kErrorNone;
diff --git a/msm8996/sdm/libs/core/display_hdmi.cpp b/msm8996/sdm/libs/core/display_hdmi.cpp
index 9a9628a..11c268a 100644
--- a/msm8996/sdm/libs/core/display_hdmi.cpp
+++ b/msm8996/sdm/libs/core/display_hdmi.cpp
@@ -106,17 +106,10 @@
return error;
}
-DisplayError DisplayHDMI::Prepare(LayerStack *layer_stack) {
- SCOPE_LOCK(locker_);
-
+DisplayError DisplayHDMI::PrepareLocked(LayerStack *layer_stack) {
SetS3DMode(layer_stack);
- return DisplayBase::Prepare(layer_stack);
-}
-
-DisplayError DisplayHDMI::Commit(LayerStack *layer_stack) {
- SCOPE_LOCK(locker_);
- return DisplayBase::Commit(layer_stack);
+ return DisplayBase::PrepareLocked(layer_stack);
}
DisplayError DisplayHDMI::Flush() {
@@ -154,16 +147,6 @@
return DisplayBase::SetDisplayState(state);
}
-DisplayError DisplayHDMI::SetActiveConfig(DisplayConfigVariableInfo *variable_info) {
- SCOPE_LOCK(locker_);
- return kErrorNotSupported;
-}
-
-DisplayError DisplayHDMI::SetActiveConfig(uint32_t index) {
- SCOPE_LOCK(locker_);
- return DisplayBase::SetActiveConfig(index);
-}
-
DisplayError DisplayHDMI::SetVSyncState(bool enable) {
SCOPE_LOCK(locker_);
return DisplayBase::SetVSyncState(enable);
@@ -181,12 +164,6 @@
return DisplayBase::SetDisplayMode(mode);
}
-DisplayError DisplayHDMI::IsScalingValid(const LayerRect &crop, const LayerRect &dst,
- bool rotate90) {
- SCOPE_LOCK(locker_);
- return DisplayBase::IsScalingValid(crop, dst, rotate90);
-}
-
DisplayError DisplayHDMI::GetRefreshRateRange(uint32_t *min_refresh_rate,
uint32_t *max_refresh_rate) {
SCOPE_LOCK(locker_);
@@ -336,9 +313,6 @@
void DisplayHDMI::SetS3DMode(LayerStack *layer_stack) {
uint32_t s3d_layer_count = 0;
HWS3DMode s3d_mode = kS3DModeNone;
- HWPanelInfo panel_info;
- HWDisplayAttributes display_attributes;
- uint32_t active_index = 0;
uint32_t layer_count = UINT32(layer_stack->layers.size());
// S3D mode is supported for the following scenarios:
@@ -373,15 +347,7 @@
layer_stack->flags.s3d_mode_present = true;
}
- hw_intf_->GetHWPanelInfo(&panel_info);
- hw_intf_->GetActiveConfig(&active_index);
- hw_intf_->GetDisplayAttributes(active_index, &display_attributes);
-
- if (panel_info != hw_panel_info_ || display_attributes != display_attributes_) {
- comp_manager_->ReconfigureDisplay(display_comp_ctx_, display_attributes, panel_info);
- hw_panel_info_ = panel_info;
- display_attributes_ = display_attributes;
- }
+ DisplayBase::ReconfigureDisplay();
}
void DisplayHDMI::CECMessage(char *message) {
diff --git a/msm8996/sdm/libs/core/display_hdmi.h b/msm8996/sdm/libs/core/display_hdmi.h
index 88e553d..b3ec9af 100644
--- a/msm8996/sdm/libs/core/display_hdmi.h
+++ b/msm8996/sdm/libs/core/display_hdmi.h
@@ -42,8 +42,6 @@
RotatorInterface *rotator_intf);
virtual DisplayError Init();
virtual DisplayError Deinit();
- virtual DisplayError Prepare(LayerStack *layer_stack);
- virtual DisplayError Commit(LayerStack *layer_stack);
virtual DisplayError Flush();
virtual DisplayError GetDisplayState(DisplayState *state);
virtual DisplayError GetNumVariableInfoConfigs(uint32_t *count);
@@ -51,13 +49,10 @@
virtual DisplayError GetActiveConfig(uint32_t *index);
virtual DisplayError GetVSyncState(bool *enabled);
virtual DisplayError SetDisplayState(DisplayState state);
- virtual DisplayError SetActiveConfig(DisplayConfigVariableInfo *variable_info);
- virtual DisplayError SetActiveConfig(uint32_t index);
virtual DisplayError SetVSyncState(bool enable);
virtual void SetIdleTimeoutMs(uint32_t timeout_ms);
virtual DisplayError SetMaxMixerStages(uint32_t max_mixer_stages);
virtual DisplayError SetDisplayMode(uint32_t mode);
- virtual DisplayError IsScalingValid(const LayerRect &crop, const LayerRect &dst, bool rotate90);
virtual DisplayError GetRefreshRateRange(uint32_t *min_refresh_rate, uint32_t *max_refresh_rate);
virtual DisplayError SetRefreshRate(uint32_t refresh_rate);
virtual bool IsUnderscanSupported();
@@ -74,11 +69,11 @@
virtual void CECMessage(char *message);
private:
+ virtual DisplayError PrepareLocked(LayerStack *layer_stack);
virtual uint32_t GetBestConfig(HWS3DMode s3d_mode);
virtual void GetScanSupport();
virtual void SetS3DMode(LayerStack *layer_stack);
- Locker locker_;
HWScanSupport scan_support_;
std::map<LayerBufferS3DFormat, HWS3DMode> s3d_format_to_mode_;
std::vector<const char *> event_list_ = {"vsync_event", "idle_notify", "cec/rd_msg",
diff --git a/msm8996/sdm/libs/core/display_primary.cpp b/msm8996/sdm/libs/core/display_primary.cpp
index e5751df..70b96fe 100644
--- a/msm8996/sdm/libs/core/display_primary.cpp
+++ b/msm8996/sdm/libs/core/display_primary.cpp
@@ -24,6 +24,11 @@
#include <utils/constants.h>
#include <utils/debug.h>
+#include <utils/rect.h>
+#include <map>
+#include <algorithm>
+#include <functional>
+#include <vector>
#include "display_primary.h"
#include "hw_interface.h"
@@ -86,17 +91,25 @@
return error;
}
-DisplayError DisplayPrimary::Prepare(LayerStack *layer_stack) {
- SCOPE_LOCK(locker_);
- return DisplayBase::Prepare(layer_stack);
+DisplayError DisplayPrimary::PrepareLocked(LayerStack *layer_stack) {
+ DisplayError error = kErrorNone;
+ uint32_t new_mixer_width = 0;
+ uint32_t new_mixer_height = 0;
+ uint32_t display_width = display_attributes_.x_pixels;
+ uint32_t display_height = display_attributes_.y_pixels;
+
+ if (NeedsMixerReconfiguration(layer_stack, &new_mixer_width, &new_mixer_height)) {
+ error = ReconfigureMixer(new_mixer_width, new_mixer_height);
+ if (error != kErrorNone) {
+ ReconfigureMixer(display_width, display_height);
+ }
+ }
+
+ return DisplayBase::PrepareLocked(layer_stack);
}
-DisplayError DisplayPrimary::Commit(LayerStack *layer_stack) {
- SCOPE_LOCK(locker_);
+DisplayError DisplayPrimary::CommitLocked(LayerStack *layer_stack) {
DisplayError error = kErrorNone;
- HWPanelInfo panel_info;
- HWDisplayAttributes display_attributes;
- uint32_t active_index = 0;
// Enabling auto refresh is async and needs to happen before commit ioctl
if (hw_panel_info_.mode == kModeCommand) {
@@ -105,19 +118,12 @@
bool set_idle_timeout = comp_manager_->CanSetIdleTimeout(display_comp_ctx_);
- error = DisplayBase::Commit(layer_stack);
+ error = DisplayBase::CommitLocked(layer_stack);
if (error != kErrorNone) {
return error;
}
- hw_intf_->GetHWPanelInfo(&panel_info);
- hw_intf_->GetActiveConfig(&active_index);
- hw_intf_->GetDisplayAttributes(active_index, &display_attributes);
-
- if (panel_info != hw_panel_info_) {
- error = comp_manager_->ReconfigureDisplay(display_comp_ctx_, display_attributes, panel_info);
- hw_panel_info_ = panel_info;
- }
+ DisplayBase::ReconfigureDisplay();
if (hw_panel_info_.mode == kModeVideo) {
if (set_idle_timeout && !layer_stack->flags.single_buffered_layer_present) {
@@ -181,16 +187,6 @@
return kErrorNone;
}
-DisplayError DisplayPrimary::SetActiveConfig(DisplayConfigVariableInfo *variable_info) {
- SCOPE_LOCK(locker_);
- return kErrorNotSupported;
-}
-
-DisplayError DisplayPrimary::SetActiveConfig(uint32_t index) {
- SCOPE_LOCK(locker_);
- return DisplayBase::SetActiveConfig(index);
-}
-
DisplayError DisplayPrimary::SetVSyncState(bool enable) {
SCOPE_LOCK(locker_);
return DisplayBase::SetVSyncState(enable);
@@ -214,22 +210,16 @@
DisplayError DisplayPrimary::SetDisplayMode(uint32_t mode) {
SCOPE_LOCK(locker_);
DisplayError error = kErrorNone;
- HWDisplayMode hw_display_mode = kModeDefault;
+ HWDisplayMode hw_display_mode = static_cast<HWDisplayMode>(mode);
+ uint32_t pending = 0;
if (!active_) {
DLOGW("Invalid display state = %d. Panel must be on.", state_);
return kErrorNotSupported;
}
- switch (mode) {
- case kModeVideo:
- hw_display_mode = kModeVideo;
- break;
- case kModeCommand:
- hw_display_mode = kModeCommand;
- break;
- default:
- DLOGW("Invalid panel mode parameters. Requested = %d", mode);
+ if (hw_display_mode != kModeCommand && hw_display_mode != kModeVideo) {
+ DLOGW("Invalid panel mode parameters. Requested = %d", hw_display_mode);
return kErrorParameters;
}
@@ -246,16 +236,11 @@
return error;
}
- // Disable PU if the previous PU state is on when switching to video mode, and re-enable PU when
- // switching back to command mode.
- bool toggle_partial_update = !(hw_display_mode == kModeVideo);
- if (partial_update_control_) {
- comp_manager_->ControlPartialUpdate(display_comp_ctx_, toggle_partial_update);
- }
-
- if (hw_display_mode == kModeVideo) {
+ if (mode == kModeVideo) {
+ ControlPartialUpdateLocked(false /* enable */, &pending);
hw_intf_->SetIdleTimeoutMs(idle_timeout_ms_);
- } else if (hw_display_mode == kModeCommand) {
+ } else if (mode == kModeCommand) {
+ ControlPartialUpdateLocked(true /* enable */, &pending);
hw_intf_->SetIdleTimeoutMs(0);
}
@@ -267,12 +252,6 @@
return hw_intf_->SetPanelBrightness(level);
}
-DisplayError DisplayPrimary::IsScalingValid(const LayerRect &crop, const LayerRect &dst,
- bool rotate90) {
- SCOPE_LOCK(locker_);
- return DisplayBase::IsScalingValid(crop, dst, rotate90);
-}
-
DisplayError DisplayPrimary::GetRefreshRateRange(uint32_t *min_refresh_rate,
uint32_t *max_refresh_rate) {
SCOPE_LOCK(locker_);
@@ -305,21 +284,7 @@
return error;
}
- HWDisplayAttributes display_attributes;
- uint32_t active_index = 0;
- error = hw_intf_->GetActiveConfig(&active_index);
- if (error != kErrorNone) {
- return error;
- }
-
- error = hw_intf_->GetDisplayAttributes(active_index, &display_attributes);
- if (error != kErrorNone) {
- return error;
- }
-
- comp_manager_->ReconfigureDisplay(display_comp_ctx_, display_attributes, hw_panel_info_);
-
- return kErrorNone;
+ return DisplayBase::ReconfigureDisplay();
}
void DisplayPrimary::AppendDump(char *buffer, uint32_t length) {
@@ -362,5 +327,137 @@
return hw_intf_->GetPanelBrightness(level);
}
+DisplayError DisplayPrimary::ControlPartialUpdateLocked(bool enable, uint32_t *pending) {
+ if (!pending) {
+ return kErrorParameters;
+ }
+
+ if (!hw_panel_info_.partial_update) {
+ // Nothing to be done.
+ DLOGI("partial update is not applicable for display=%d", display_type_);
+ return kErrorNotSupported;
+ }
+
+ *pending = 0;
+ if (enable == partial_update_control_) {
+ DLOGI("Same state transition is requested.");
+ return kErrorNone;
+ }
+
+ partial_update_control_ = enable;
+
+ if (!enable) {
+ // If the request is to turn off feature, new draw call is required to have
+ // the new setting into effect.
+ *pending = 1;
+ }
+
+ return kErrorNone;
+}
+
+DisplayError DisplayPrimary::DisablePartialUpdateOneFrameLocked() {
+ disable_pu_one_frame_ = true;
+
+ return kErrorNone;
+}
+
+DisplayError DisplayPrimary::SetMixerResolutionLocked(uint32_t width, uint32_t height) {
+ return ReconfigureMixer(width, height);
+}
+
+DisplayError DisplayPrimary::ReconfigureMixer(uint32_t width, uint32_t height) {
+ DisplayError error = kErrorNone;
+
+ HWMixerAttributes mixer_attributes;
+ mixer_attributes.width = width;
+ mixer_attributes.height = height;
+
+ error = hw_intf_->SetMixerAttributes(mixer_attributes);
+ if (error != kErrorNone) {
+ return error;
+ }
+
+ return DisplayBase::ReconfigureDisplay();
+}
+
+bool DisplayPrimary::NeedsMixerReconfiguration(LayerStack *layer_stack, uint32_t *new_mixer_width,
+ uint32_t *new_mixer_height) {
+ uint32_t layer_count = UINT32(layer_stack->layers.size());
+
+ uint32_t fb_width = fb_config_.x_pixels;
+ uint32_t fb_height = fb_config_.y_pixels;
+ uint32_t fb_area = fb_width * fb_height;
+ LayerRect fb_rect = (LayerRect) {0.0f, 0.0f, FLOAT(fb_width), FLOAT(fb_height)};
+ uint32_t mixer_width = mixer_attributes_.width;
+ uint32_t mixer_height = mixer_attributes_.height;
+
+ RectOrientation fb_orientation = GetOrientation(fb_rect);
+ uint32_t max_layer_area = 0;
+ uint32_t max_area_layer_index = 0;
+ std::vector<Layer *> layers = layer_stack->layers;
+
+ for (uint32_t i = 0; i < layer_count; i++) {
+ Layer *layer = layers.at(i);
+ LayerBuffer *layer_buffer = layer->input_buffer;
+
+ if (!layer_buffer->flags.video) {
+ continue;
+ }
+
+ uint32_t layer_width = UINT32(layer->src_rect.right - layer->src_rect.left);
+ uint32_t layer_height = UINT32(layer->src_rect.bottom - layer->src_rect.top);
+ uint32_t layer_area = layer_width * layer_height;
+
+ if (layer_area > max_layer_area) {
+ max_layer_area = layer_area;
+ max_area_layer_index = i;
+ }
+ }
+
+ if (max_layer_area > fb_area) {
+ Layer *layer = layers.at(max_area_layer_index);
+
+ uint32_t layer_width = UINT32(layer->src_rect.right - layer->src_rect.left);
+ uint32_t layer_height = UINT32(layer->src_rect.bottom - layer->src_rect.top);
+ LayerRect layer_rect = (LayerRect){0.0f, 0.0f, FLOAT(layer_width), FLOAT(layer_height)};
+
+ RectOrientation layer_orientation = GetOrientation(layer_rect);
+ if (layer_orientation != kOrientationUnknown &&
+ fb_orientation != kOrientationUnknown) {
+ if (layer_orientation != fb_orientation) {
+ Swap(layer_width, layer_height);
+ }
+ }
+
+ // Align the width and height according to fb's aspect ratio
+ layer_width = UINT32((FLOAT(fb_width) / FLOAT(fb_height)) * layer_height);
+
+ *new_mixer_width = layer_width;
+ *new_mixer_height = layer_height;
+
+ return true;
+ } else {
+ if (fb_width != mixer_width || fb_height != mixer_height) {
+ *new_mixer_width = fb_width;
+ *new_mixer_height = fb_height;
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+DisplayError DisplayPrimary::SetDetailEnhancerDataLocked(const DisplayDetailEnhancerData &de_data) {
+ DisplayError error = comp_manager_->SetDetailEnhancerData(display_comp_ctx_, de_data);
+ if (error != kErrorNone) {
+ return error;
+ }
+
+ DisablePartialUpdateOneFrameLocked();
+
+ return kErrorNone;
+}
+
} // namespace sdm
diff --git a/msm8996/sdm/libs/core/display_primary.h b/msm8996/sdm/libs/core/display_primary.h
index d3a37cd..f029961 100644
--- a/msm8996/sdm/libs/core/display_primary.h
+++ b/msm8996/sdm/libs/core/display_primary.h
@@ -41,8 +41,6 @@
RotatorInterface *rotator_intf);
virtual DisplayError Init();
virtual DisplayError Deinit();
- virtual DisplayError Prepare(LayerStack *layer_stack);
- virtual DisplayError Commit(LayerStack *layer_stack);
virtual DisplayError Flush();
virtual DisplayError GetDisplayState(DisplayState *state);
virtual DisplayError GetNumVariableInfoConfigs(uint32_t *count);
@@ -50,13 +48,10 @@
virtual DisplayError GetActiveConfig(uint32_t *index);
virtual DisplayError GetVSyncState(bool *enabled);
virtual DisplayError SetDisplayState(DisplayState state);
- virtual DisplayError SetActiveConfig(DisplayConfigVariableInfo *variable_info);
- virtual DisplayError SetActiveConfig(uint32_t index);
virtual DisplayError SetVSyncState(bool enable);
virtual void SetIdleTimeoutMs(uint32_t timeout_ms);
virtual DisplayError SetMaxMixerStages(uint32_t max_mixer_stages);
virtual DisplayError SetDisplayMode(uint32_t mode);
- virtual DisplayError IsScalingValid(const LayerRect &crop, const LayerRect &dst, bool rotate90);
virtual DisplayError GetRefreshRateRange(uint32_t *min_refresh_rate, uint32_t *max_refresh_rate);
virtual DisplayError SetRefreshRate(uint32_t refresh_rate);
virtual bool IsUnderscanSupported();
@@ -73,7 +68,17 @@
virtual void CECMessage(char *message) { }
private:
- Locker locker_;
+ virtual DisplayError PrepareLocked(LayerStack *layer_stack);
+ virtual DisplayError CommitLocked(LayerStack *layer_stack);
+ virtual DisplayError ControlPartialUpdateLocked(bool enable, uint32_t *pending);
+ virtual DisplayError DisablePartialUpdateOneFrameLocked();
+ virtual DisplayError SetMixerResolutionLocked(uint32_t width, uint32_t height);
+ virtual DisplayError SetDetailEnhancerDataLocked(const DisplayDetailEnhancerData &de_data);
+
+ bool NeedsMixerReconfiguration(LayerStack *layer_stack, uint32_t *new_mixer_width,
+ uint32_t *new_mixer_height);
+ DisplayError ReconfigureMixer(uint32_t width, uint32_t height);
+
uint32_t idle_timeout_ms_ = 0;
std::vector<const char *> event_list_ = {"vsync_event", "show_blank_event", "idle_notify",
"msm_fb_thermal_level", "thread_exit"};
diff --git a/msm8996/sdm/libs/core/display_virtual.cpp b/msm8996/sdm/libs/core/display_virtual.cpp
index ff8da68..cafb986 100644
--- a/msm8996/sdm/libs/core/display_virtual.cpp
+++ b/msm8996/sdm/libs/core/display_virtual.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014 - 2015, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
@@ -69,16 +69,6 @@
return error;
}
-DisplayError DisplayVirtual::Prepare(LayerStack *layer_stack) {
- SCOPE_LOCK(locker_);
- return DisplayBase::Prepare(layer_stack);
-}
-
-DisplayError DisplayVirtual::Commit(LayerStack *layer_stack) {
- SCOPE_LOCK(locker_);
- return DisplayBase::Commit(layer_stack);
-}
-
DisplayError DisplayVirtual::Flush() {
SCOPE_LOCK(locker_);
return DisplayBase::Flush();
@@ -122,10 +112,7 @@
return DisplayBase::SetDisplayState(state);
}
-DisplayError DisplayVirtual::SetActiveConfig(DisplayConfigVariableInfo *variable_info) {
- SCOPE_LOCK(locker_);
- DisplayError error = kErrorNone;
-
+DisplayError DisplayVirtual::SetActiveConfigLocked(DisplayConfigVariableInfo *variable_info) {
if (!variable_info) {
return kErrorParameters;
}
@@ -134,24 +121,17 @@
display_attributes_.y_pixels = variable_info->y_pixels;
display_attributes_.fps = variable_info->fps;
+ HWMixerAttributes mixer_attributes;
+ mixer_attributes.width = variable_info->x_pixels;;
+ mixer_attributes.height = variable_info->y_pixels;
// if display is already connected, unregister display from composition manager and register
// the display with new configuration.
if (display_comp_ctx_) {
comp_manager_->UnregisterDisplay(display_comp_ctx_);
}
- error = comp_manager_->RegisterDisplay(display_type_, display_attributes_, hw_panel_info_,
- &display_comp_ctx_);
- if (error != kErrorNone) {
- return error;
- }
-
- return error;
-}
-
-DisplayError DisplayVirtual::SetActiveConfig(uint32_t index) {
- SCOPE_LOCK(locker_);
- return kErrorNotSupported;
+ return comp_manager_->RegisterDisplay(display_type_, display_attributes_, hw_panel_info_,
+ mixer_attributes, fb_config_, &display_comp_ctx_);
}
DisplayError DisplayVirtual::SetVSyncState(bool enable) {
@@ -171,12 +151,6 @@
return DisplayBase::SetDisplayMode(mode);
}
-DisplayError DisplayVirtual::IsScalingValid(const LayerRect &crop, const LayerRect &dst,
- bool rotate90) {
- SCOPE_LOCK(locker_);
- return DisplayBase::IsScalingValid(crop, dst, rotate90);
-}
-
DisplayError DisplayVirtual::GetRefreshRateRange(uint32_t *min_refresh_rate,
uint32_t *max_refresh_rate) {
SCOPE_LOCK(locker_);
diff --git a/msm8996/sdm/libs/core/display_virtual.h b/msm8996/sdm/libs/core/display_virtual.h
index b26be12..ba164ae 100644
--- a/msm8996/sdm/libs/core/display_virtual.h
+++ b/msm8996/sdm/libs/core/display_virtual.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014 - 2015, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
@@ -40,8 +40,6 @@
RotatorInterface *rotator_intf);
virtual DisplayError Init();
virtual DisplayError Deinit();
- virtual DisplayError Prepare(LayerStack *layer_stack);
- virtual DisplayError Commit(LayerStack *layer_stack);
virtual DisplayError Flush();
virtual DisplayError GetDisplayState(DisplayState *state);
virtual DisplayError GetNumVariableInfoConfigs(uint32_t *count);
@@ -49,13 +47,10 @@
virtual DisplayError GetActiveConfig(uint32_t *index);
virtual DisplayError GetVSyncState(bool *enabled);
virtual DisplayError SetDisplayState(DisplayState state);
- virtual DisplayError SetActiveConfig(DisplayConfigVariableInfo *variable_info);
- virtual DisplayError SetActiveConfig(uint32_t index);
virtual DisplayError SetVSyncState(bool enable);
virtual void SetIdleTimeoutMs(uint32_t timeout_ms);
virtual DisplayError SetMaxMixerStages(uint32_t max_mixer_stages);
virtual DisplayError SetDisplayMode(uint32_t mode);
- virtual DisplayError IsScalingValid(const LayerRect &crop, const LayerRect &dst, bool rotate90);
virtual DisplayError GetRefreshRateRange(uint32_t *min_refresh_rate, uint32_t *max_refresh_rate);
virtual DisplayError SetRefreshRate(uint32_t refresh_rate);
virtual bool IsUnderscanSupported();
@@ -64,8 +59,10 @@
virtual DisplayError SetCursorPosition(int x, int y);
private:
- Locker locker_;
- HWDisplayAttributes display_attributes_;
+ virtual DisplayError SetActiveConfigLocked(uint32_t index) {
+ return kErrorNotSupported;
+ }
+ virtual DisplayError SetActiveConfigLocked(DisplayConfigVariableInfo *variable_info);
};
} // namespace sdm
diff --git a/msm8996/sdm/libs/core/fb/hw_device.cpp b/msm8996/sdm/libs/core/fb/hw_device.cpp
index 546490a..6b7dd2e 100644
--- a/msm8996/sdm/libs/core/fb/hw_device.cpp
+++ b/msm8996/sdm/libs/core/fb/hw_device.cpp
@@ -238,8 +238,10 @@
mdp_layer.bg_color = layer->solid_fill_color;
// HWScaleData to MDP driver
- hw_scale_->SetHWScaleData(pipe_info->scale_data, mdp_layer_count, &mdp_layer);
- mdp_layer.scale = hw_scale_->GetScaleDataRef(mdp_layer_count);
+ hw_scale_->SetHWScaleData(pipe_info->scale_data, mdp_layer_count, &mdp_commit,
+ pipe_info->sub_block_type);
+ mdp_layer.scale = hw_scale_->GetScaleDataRef(mdp_layer_count, pipe_info->sub_block_type);
+
mdp_layer_count++;
DLOGV_IF(kTagDriverConfig, "******************* Layer[%d] %s pipe Input ******************",
diff --git a/msm8996/sdm/libs/core/fb/hw_device.h b/msm8996/sdm/libs/core/fb/hw_device.h
index 7311271..d5b18de 100644
--- a/msm8996/sdm/libs/core/fb/hw_device.h
+++ b/msm8996/sdm/libs/core/fb/hw_device.h
@@ -84,6 +84,12 @@
virtual DisplayError SetAutoRefresh(bool enable) { return kErrorNone; }
virtual DisplayError SetS3DMode(HWS3DMode s3d_mode);
virtual DisplayError SetScaleLutConfig(HWScaleLutInfo *lut_info);
+ virtual DisplayError SetMixerAttributes(const HWMixerAttributes &mixer_attributes) {
+ return kErrorNotSupported;
+ }
+ virtual DisplayError GetMixerAttributes(HWMixerAttributes *mixer_attributes) {
+ return kErrorNotSupported;
+ }
// For HWDevice derivatives
virtual DisplayError Init();
diff --git a/msm8996/sdm/libs/core/fb/hw_hdmi.cpp b/msm8996/sdm/libs/core/fb/hw_hdmi.cpp
index db7a2d9..3dfac8a 100644
--- a/msm8996/sdm/libs/core/fb/hw_hdmi.cpp
+++ b/msm8996/sdm/libs/core/fb/hw_hdmi.cpp
@@ -252,10 +252,8 @@
display_attributes->y_dpi = 0;
display_attributes->fps = timing_mode->refresh_rate / 1000;
display_attributes->vsync_period_ns = UINT32(1000000000L / display_attributes->fps);
- display_attributes->split_left = display_attributes->x_pixels;
if (display_attributes->x_pixels > hw_resource_.max_mixer_width) {
display_attributes->is_device_split = true;
- display_attributes->split_left = display_attributes->x_pixels / 2;
display_attributes->h_total += h_blanking;
}
@@ -755,5 +753,21 @@
return kErrorNone;
}
+DisplayError HWHDMI::GetMixerAttributes(HWMixerAttributes *mixer_attributes) {
+ if (!mixer_attributes) {
+ return kErrorParameters;
+ }
+
+ HWDisplayAttributes display_attributes;
+ GetDisplayAttributes(active_config_index_, &display_attributes);
+
+ mixer_attributes->width = display_attributes.x_pixels;
+ mixer_attributes->height = display_attributes.y_pixels;
+ mixer_attributes->split_left = display_attributes.is_device_split ?
+ (display_attributes.x_pixels / 2) : mixer_attributes->width;
+
+ return kErrorNone;
+}
+
} // namespace sdm
diff --git a/msm8996/sdm/libs/core/fb/hw_hdmi.h b/msm8996/sdm/libs/core/fb/hw_hdmi.h
index aa5e2a0..833b3d3 100644
--- a/msm8996/sdm/libs/core/fb/hw_hdmi.h
+++ b/msm8996/sdm/libs/core/fb/hw_hdmi.h
@@ -69,6 +69,7 @@
virtual DisplayError Validate(HWLayers *hw_layers);
virtual DisplayError SetS3DMode(HWS3DMode s3d_mode);
virtual DisplayError SetRefreshRate(uint32_t refresh_rate);
+ virtual DisplayError GetMixerAttributes(HWMixerAttributes *mixer_attributes);
private:
DisplayError ReadEDIDInfo();
diff --git a/msm8996/sdm/libs/core/fb/hw_info.cpp b/msm8996/sdm/libs/core/fb/hw_info.cpp
index f6f664a..25bb01c 100644
--- a/msm8996/sdm/libs/core/fb/hw_info.cpp
+++ b/msm8996/sdm/libs/core/fb/hw_info.cpp
@@ -31,6 +31,7 @@
#include <utils/constants.h>
#include <utils/debug.h>
#include <utils/sys.h>
+#include <dlfcn.h>
#include <algorithm>
#include <iostream>
@@ -241,6 +242,16 @@
hw_resource->system_overhead_lines = UINT32(atoi(tokens[1]));
} else if (!strncmp(tokens[0], "wb_intf_index", strlen("wb_intf_index"))) {
hw_resource->writeback_index = UINT32(atoi(tokens[1]));
+ } else if (!strncmp(tokens[0], "dest_scaler_count", strlen("dest_scaler_count"))) {
+ hw_resource->hw_dest_scalar_info.count = UINT32(atoi(tokens[1]));
+ } else if (!strncmp(tokens[0], "max_dest_scale_up", strlen("max_dest_scale_up"))) {
+ hw_resource->hw_dest_scalar_info.max_scale_up = UINT32(atoi(tokens[1]));
+ } else if (!strncmp(tokens[0], "max_dest_scaler_input_width",
+ strlen("max_dest_scaler_input_width"))) {
+ hw_resource->hw_dest_scalar_info.max_input_width = UINT32(atoi(tokens[1]));
+ } else if (!strncmp(tokens[0], "max_dest_scaler_output_width",
+ strlen("max_dest_scaler_output_width"))) {
+ hw_resource->hw_dest_scalar_info.max_output_width = UINT32(atoi(tokens[1]));
} else if (!strncmp(tokens[0], "features", strlen("features"))) {
for (uint32_t i = 0; i < token_count; i++) {
if (!strncmp(tokens[i], "bwc", strlen("bwc"))) {
@@ -316,6 +327,14 @@
}
}
+ // Disable destination scalar count to 0 if extension library is not present
+ void *extension_lib = ::dlopen("libsdmextension.so", RTLD_NOW);
+ if (!extension_lib) {
+ hw_resource->hw_dest_scalar_info.count = 0;
+ } else {
+ ::dlclose(extension_lib);
+ }
+
Sys::fclose_(fileptr);
DLOGI("SDE Version = %d, SDE Revision = %x, RGB = %d, VIG = %d, DMA = %d, Cursor = %d",
diff --git a/msm8996/sdm/libs/core/fb/hw_primary.cpp b/msm8996/sdm/libs/core/fb/hw_primary.cpp
index 84eea2a..3d0c776 100644
--- a/msm8996/sdm/libs/core/fb/hw_primary.cpp
+++ b/msm8996/sdm/libs/core/fb/hw_primary.cpp
@@ -40,6 +40,7 @@
#include <utils/sys.h>
#include <core/display_interface.h>
#include <linux/msm_mdp_ext.h>
+#include <utils/rect.h>
#include <string>
@@ -99,11 +100,18 @@
return error;
}
+ uint32_t dest_scalar_count = hw_resource_.hw_dest_scalar_info.count;
+ if (dest_scalar_count) {
+ mdp_dest_scalar_data_ = new mdp_destination_scaler_data[dest_scalar_count];
+ }
+
error = PopulateDisplayAttributes();
if (error != kErrorNone) {
return error;
}
+ UpdateMixerAttributes();
+
// Disable HPD at start if HDMI is external, it will be enabled later when the display powers on
// This helps for framework reboot or adb shell stop/start
EnableHotPlugDetection(0);
@@ -199,6 +207,8 @@
}
DisplayError HWPrimary::Deinit() {
+ delete [] mdp_dest_scalar_data_;
+
return HWDevice::Deinit();
}
@@ -273,8 +283,6 @@
display_attributes_.vsync_period_ns = UINT32(1000000000L / display_attributes_.fps);
display_attributes_.is_device_split = (hw_panel_info_.split_info.left_split ||
(var_screeninfo.xres > hw_resource_.max_mixer_width)) ? true : false;
- display_attributes_.split_left = hw_panel_info_.split_info.left_split ?
- hw_panel_info_.split_info.left_split : display_attributes_.x_pixels / 2;
display_attributes_.h_total += display_attributes_.is_device_split ? h_blanking : 0;
return kErrorNone;
@@ -305,6 +313,7 @@
DLOGI("Successfully set config %u", index);
PopulateHWPanelInfo();
PopulateDisplayAttributes();
+ UpdateMixerAttributes();
active_config_index_ = index;
} else {
DLOGE("Writing config index %u failed with error: %s", index, strerror(errno));
@@ -381,15 +390,27 @@
return kErrorNone;
}
-DisplayError HWPrimary::Validate(HWLayers *hw_layers) {
- LayerStack *stack = hw_layers->info.stack;
+void HWPrimary::ResetDisplayParams() {
+ uint32_t dst_scalar_cnt = hw_resource_.hw_dest_scalar_info.count;
HWDevice::ResetDisplayParams();
+ if (mdp_dest_scalar_data_) {
+ memset(mdp_dest_scalar_data_, 0, sizeof(mdp_dest_scalar_data_) * dst_scalar_cnt);
+ mdp_disp_commit_.commit_v1.dest_scaler = mdp_dest_scalar_data_;
+ }
+}
+
+DisplayError HWPrimary::Validate(HWLayers *hw_layers) {
+ HWLayersInfo &hw_layer_info = hw_layers->info;
+ LayerStack *stack = hw_layer_info.stack;
+
+ ResetDisplayParams();
+
mdp_layer_commit_v1 &mdp_commit = mdp_disp_commit_.commit_v1;
- LayerRect left_roi = hw_layers->info.left_partial_update;
- LayerRect right_roi = hw_layers->info.right_partial_update;
+ LayerRect left_roi = hw_layer_info.left_partial_update;
+ LayerRect right_roi = hw_layer_info.right_partial_update;
mdp_commit.left_roi.x = UINT32(left_roi.left);
mdp_commit.left_roi.y = UINT32(left_roi.top);
mdp_commit.left_roi.w = UINT32(left_roi.right - left_roi.left);
@@ -398,8 +419,8 @@
// SDM treats ROI as one full coordinate system.
// In case source split is disabled, However, Driver assumes Mixer to operate in
// different co-ordinate system.
- if (!hw_resource_.is_src_split) {
- mdp_commit.right_roi.x = UINT32(right_roi.left) - hw_panel_info_.split_info.left_split;
+ if (!hw_resource_.is_src_split && IsValid(right_roi)) {
+ mdp_commit.right_roi.x = UINT32(right_roi.left) - mixer_attributes_.split_left;
mdp_commit.right_roi.y = UINT32(right_roi.top);
mdp_commit.right_roi.w = UINT32(right_roi.right - right_roi.left);
mdp_commit.right_roi.h = UINT32(right_roi.bottom - right_roi.top);
@@ -424,6 +445,40 @@
DLOGI_IF(kTagDriverConfig, "****************************************************************");
}
+ uint32_t index = 0;
+ for (uint32_t i = 0; i < hw_resource_.hw_dest_scalar_info.count; i++) {
+ DestScaleInfoMap::iterator it = hw_layer_info.dest_scale_info_map.find(i);
+
+ if (it == hw_layer_info.dest_scale_info_map.end()) {
+ continue;
+ }
+
+ HWDestScaleInfo *dest_scale_info = it->second;
+
+ mdp_destination_scaler_data *dest_scalar_data = &mdp_dest_scalar_data_[index];
+ hw_scale_->SetHWScaleData(dest_scale_info->scale_data, index, &mdp_commit,
+ kHWDestinationScalar);
+
+ if (dest_scale_info->scale_update) {
+ dest_scalar_data->flags |= MDP_DESTSCALER_SCALE_UPDATE;
+ }
+
+ dest_scalar_data->dest_scaler_ndx = i;
+ dest_scalar_data->lm_width = dest_scale_info->mixer_width;
+ dest_scalar_data->lm_height = dest_scale_info->mixer_height;
+ dest_scalar_data->scale = reinterpret_cast <uint64_t>
+ (hw_scale_->GetScaleDataRef(index, kHWDestinationScalar));
+
+ index++;
+
+ DLOGV_IF(kTagDriverConfig, "************************ DestScalar[%d] **************************",
+ dest_scalar_data->dest_scaler_ndx);
+ DLOGV_IF(kTagDriverConfig, "Mixer WxH %dx%d", dest_scalar_data->lm_width,
+ dest_scalar_data->lm_height);
+ DLOGI_IF(kTagDriverConfig, "*****************************************************************");
+ }
+ mdp_commit.dest_scaler_cnt = UINT32(hw_layer_info.dest_scale_info_map.size());
+
return HWDevice::Validate(hw_layers);
}
@@ -640,5 +695,76 @@
return kErrorNone;
}
+DisplayError HWPrimary::SetMixerAttributes(const HWMixerAttributes &mixer_attributes) {
+ if (IsResolutionSwitchEnabled() || !hw_resource_.hw_dest_scalar_info.count) {
+ return kErrorNotSupported;
+ }
+
+ if (mixer_attributes.width > display_attributes_.x_pixels ||
+ mixer_attributes.height > display_attributes_.y_pixels) {
+ DLOGW("Input resolution exceeds display resolution! input: res %dx%d display: res %dx%d",
+ mixer_attributes.width, mixer_attributes.height, display_attributes_.x_pixels,
+ display_attributes_.y_pixels);
+ return kErrorNotSupported;
+ }
+
+ uint32_t max_input_width = hw_resource_.hw_dest_scalar_info.max_input_width;
+ if (display_attributes_.is_device_split) {
+ max_input_width *= 2;
+ }
+
+ if (mixer_attributes.width > max_input_width) {
+ DLOGW("Input width exceeds width limit! input_width %d width_limit %d", mixer_attributes.width,
+ max_input_width);
+ return kErrorNotSupported;
+ }
+
+ float mixer_aspect_ratio = FLOAT(mixer_attributes.width) / FLOAT(mixer_attributes.height);
+ float display_aspect_ratio =
+ FLOAT(display_attributes_.x_pixels) / FLOAT(display_attributes_.y_pixels);
+
+ if (display_aspect_ratio != mixer_aspect_ratio) {
+ DLOGW("Aspect ratio mismatch! input: res %dx%d display: res %dx%d", mixer_attributes.width,
+ mixer_attributes.height, display_attributes_.x_pixels, display_attributes_.y_pixels);
+ return kErrorNotSupported;
+ }
+
+ float scale_x = FLOAT(display_attributes_.x_pixels) / FLOAT(mixer_attributes.width);
+ float scale_y = FLOAT(display_attributes_.y_pixels) / FLOAT(mixer_attributes.height);
+ float max_scale_up = hw_resource_.hw_dest_scalar_info.max_scale_up;
+ if (scale_x > max_scale_up || scale_y > max_scale_up) {
+ DLOGW("Up scaling ratio exceeds for destination scalar upscale limit scale_x %f scale_y %f " \
+ "max_scale_up %f", scale_x, scale_y, max_scale_up);
+ return kErrorNotSupported;
+ }
+
+ float mixer_split_ratio = FLOAT(mixer_attributes_.split_left) / FLOAT(mixer_attributes_.width);
+
+ mixer_attributes_ = mixer_attributes;
+ mixer_attributes_.split_left = mixer_attributes_.width;
+ if (display_attributes_.is_device_split) {
+ mixer_attributes_.split_left = UINT32(FLOAT(mixer_attributes.width) * mixer_split_ratio);
+ }
+
+ return kErrorNone;
+}
+
+DisplayError HWPrimary::GetMixerAttributes(HWMixerAttributes *mixer_attributes) {
+ if (!mixer_attributes) {
+ return kErrorParameters;
+ }
+
+ *mixer_attributes = mixer_attributes_;
+
+ return kErrorNone;
+}
+
+void HWPrimary::UpdateMixerAttributes() {
+ mixer_attributes_.width = display_attributes_.x_pixels;
+ mixer_attributes_.height = display_attributes_.y_pixels;
+ mixer_attributes_.split_left = display_attributes_.is_device_split ?
+ hw_panel_info_.split_info.left_split : mixer_attributes_.width;
+}
+
} // namespace sdm
diff --git a/msm8996/sdm/libs/core/fb/hw_primary.h b/msm8996/sdm/libs/core/fb/hw_primary.h
index 999c41a..36b3f63 100644
--- a/msm8996/sdm/libs/core/fb/hw_primary.h
+++ b/msm8996/sdm/libs/core/fb/hw_primary.h
@@ -65,6 +65,8 @@
virtual DisplayError SetPPFeatures(PPFeaturesConfig *feature_list);
virtual DisplayError GetPanelBrightness(int *level);
virtual DisplayError SetAutoRefresh(bool enable);
+ virtual DisplayError SetMixerAttributes(const HWMixerAttributes &mixer_attributes);
+ virtual DisplayError GetMixerAttributes(HWMixerAttributes *mixer_attributes);
private:
// Panel modes for the MSMFB_LPM_ENABLE ioctl
@@ -77,6 +79,8 @@
void InitializeConfigs();
bool IsResolutionSwitchEnabled() { return !display_configs_.empty(); }
bool GetCurrentModeFromSysfs(size_t *curr_x_pixels, size_t *curr_y_pixels);
+ void UpdateMixerAttributes();
+ void ResetDisplayParams();
HWDisplayAttributes display_attributes_;
std::vector<DisplayConfigVariableInfo> display_configs_;
@@ -85,6 +89,8 @@
const char *kBrightnessNode = "/sys/class/leds/lcd-backlight/brightness";
const char *kAutoRefreshNode = "/sys/devices/virtual/graphics/fb0/msm_cmd_autorefresh_en";
bool auto_refresh_ = false;
+ HWMixerAttributes mixer_attributes_ = {};
+ mdp_destination_scaler_data *mdp_dest_scalar_data_ = NULL;
};
} // namespace sdm
diff --git a/msm8996/sdm/libs/core/fb/hw_scale.cpp b/msm8996/sdm/libs/core/fb/hw_scale.cpp
index f18727f..3d175e5 100644
--- a/msm8996/sdm/libs/core/fb/hw_scale.cpp
+++ b/msm8996/sdm/libs/core/fb/hw_scale.cpp
@@ -47,11 +47,16 @@
}
void HWScaleV1::SetHWScaleData(const HWScaleData &scale_data, uint32_t index,
- mdp_input_layer *mdp_layer) {
+ mdp_layer_commit_v1 *mdp_commit, HWSubBlockType sub_block_type) {
if (!scale_data.enable.scale) {
return;
}
+ if (sub_block_type == kHWDestinationScalar) {
+ return;
+ }
+
+ mdp_input_layer *mdp_layer = &mdp_commit->input_layers[index];
mdp_layer->flags |= MDP_LAYER_ENABLE_PIXEL_EXT;
mdp_scale_data *mdp_scale = &scale_data_v1_.at(index);
mdp_scale->enable_pxl_ext = scale_data.enable.scale;
@@ -84,8 +89,12 @@
return;
}
-void* HWScaleV1::GetScaleDataRef(uint32_t index) {
- return &scale_data_v1_.at(index);
+void* HWScaleV1::GetScaleDataRef(uint32_t index, HWSubBlockType sub_block_type) {
+ if (sub_block_type != kHWDestinationScalar) {
+ return &scale_data_v1_.at(index);
+ }
+
+ return NULL;
}
void HWScaleV1::DumpScaleData(void *mdp_scale) {
@@ -112,14 +121,32 @@
}
void HWScaleV2::SetHWScaleData(const HWScaleData &scale_data, uint32_t index,
- mdp_input_layer *mdp_layer) {
+ mdp_layer_commit_v1 *mdp_commit, HWSubBlockType sub_block_type) {
if (!scale_data.enable.scale && !scale_data.enable.direction_detection &&
!scale_data.enable.detail_enhance ) {
return;
}
- mdp_scale_data_v2 *mdp_scale = &scale_data_v2_.at(index);
- mdp_layer->flags |= MDP_LAYER_ENABLE_QSEED3_SCALE;
+ mdp_scale_data_v2 *mdp_scale;
+ if (sub_block_type != kHWDestinationScalar) {
+ mdp_input_layer *mdp_layer = &mdp_commit->input_layers[index];
+ mdp_layer->flags |= MDP_LAYER_ENABLE_QSEED3_SCALE;
+ mdp_scale = &scale_data_v2_.at(index);
+ } else {
+ mdp_scale_data_v2 mdp_dest_scale;
+ mdp_destination_scaler_data *dest_scalar =
+ reinterpret_cast<mdp_destination_scaler_data *>(mdp_commit->dest_scaler);
+
+ dest_scalar[index].flags = MDP_DESTSCALER_ENABLE;
+
+ if (scale_data.enable.detail_enhance) {
+ dest_scalar[index].flags |= MDP_DESTSCALER_ENHANCER_UPDATE;
+ }
+
+ dest_scale_data_v2_.insert(std::make_pair(index, mdp_dest_scale));
+ mdp_scale = &dest_scale_data_v2_[index];
+ }
+
mdp_scale->enable = (scale_data.enable.scale ? ENABLE_SCALE : 0) |
(scale_data.enable.direction_detection ? ENABLE_DIRECTION_DETECTION : 0) |
(scale_data.enable.detail_enhance ? ENABLE_DETAIL_ENHANCE : 0);
@@ -206,23 +233,27 @@
return;
}
-void* HWScaleV2::GetScaleDataRef(uint32_t index) {
- return &scale_data_v2_.at(index);
+void* HWScaleV2::GetScaleDataRef(uint32_t index, HWSubBlockType sub_block_type) {
+ if (sub_block_type != kHWDestinationScalar) {
+ return &scale_data_v2_.at(index);
+ } else {
+ return &dest_scale_data_v2_[index];
+ }
}
-uint32_t HWScaleV2::GetMDPScalingFilter(HWScalingFilter filter_cfg) {
+uint32_t HWScaleV2::GetMDPScalingFilter(ScalingFilterConfig filter_cfg) {
switch (filter_cfg) {
- case kScalingFilterEdgeDirected:
+ case kFilterEdgeDirected:
return FILTER_EDGE_DIRECTED_2D;
- case kScalingFilterCircular:
+ case kFilterCircular:
return FILTER_CIRCULAR_2D;
- case kScalingFilterSeparable:
+ case kFilterSeparable:
return FILTER_SEPARABLE_1D;
- case kScalingFilterBilinear:
+ case kFilterBilinear:
return FILTER_BILINEAR;
default:
DLOGE("Invalid Scaling Filter");
- return kScalingFilterMax;
+ return kFilterMax;
}
}
diff --git a/msm8996/sdm/libs/core/fb/hw_scale.h b/msm8996/sdm/libs/core/fb/hw_scale.h
index 0891d42..7590833 100644
--- a/msm8996/sdm/libs/core/fb/hw_scale.h
+++ b/msm8996/sdm/libs/core/fb/hw_scale.h
@@ -30,6 +30,7 @@
#include <cstring>
#include <array>
+#include <map>
namespace sdm {
@@ -39,8 +40,8 @@
static DisplayError Destroy(HWScale *intf);
virtual void SetHWScaleData(const HWScaleData &scale, uint32_t index,
- mdp_input_layer *mdp_layer) = 0;
- virtual void* GetScaleDataRef(uint32_t index) = 0;
+ mdp_layer_commit_v1 *mdp_commit, HWSubBlockType sub_block_type) = 0;
+ virtual void* GetScaleDataRef(uint32_t index, HWSubBlockType sub_block_type) = 0;
virtual void DumpScaleData(void *mdp_scale) = 0;
virtual void ResetScaleParams() = 0;
protected:
@@ -50,8 +51,8 @@
class HWScaleV1 : public HWScale {
public:
virtual void SetHWScaleData(const HWScaleData &scale, uint32_t index,
- mdp_input_layer *mdp_layer);
- virtual void* GetScaleDataRef(uint32_t index);
+ mdp_layer_commit_v1 *mdp_commit, HWSubBlockType sub_block_type);
+ virtual void* GetScaleDataRef(uint32_t index, HWSubBlockType sub_block_type);
virtual void DumpScaleData(void *mdp_scale);
virtual void ResetScaleParams() { scale_data_v1_ = {}; }
@@ -63,18 +64,19 @@
class HWScaleV2 : public HWScale {
public:
virtual void SetHWScaleData(const HWScaleData &scale, uint32_t index,
- mdp_input_layer *mdp_layer);
- virtual void* GetScaleDataRef(uint32_t index);
+ mdp_layer_commit_v1 *mdp_commit, HWSubBlockType sub_block_type);
+ virtual void* GetScaleDataRef(uint32_t index, HWSubBlockType sub_block_type);
virtual void DumpScaleData(void *mdp_scale);
- virtual void ResetScaleParams() { scale_data_v2_ = {}; }
+ virtual void ResetScaleParams() { scale_data_v2_ = {}; dest_scale_data_v2_ = {}; }
protected:
~HWScaleV2() {}
std::array<mdp_scale_data_v2, (kMaxSDELayers * 2)> scale_data_v2_ = {};
+ std::map<uint32_t, mdp_scale_data_v2> dest_scale_data_v2_ = {};
private:
uint32_t GetMDPAlphaInterpolation(HWAlphaInterpolation alpha_filter_cfg);
- uint32_t GetMDPScalingFilter(HWScalingFilter filter_cfg);
+ uint32_t GetMDPScalingFilter(ScalingFilterConfig filter_cfg);
};
} // namespace sdm
diff --git a/msm8996/sdm/libs/core/hw_interface.h b/msm8996/sdm/libs/core/hw_interface.h
index 75d92b9..0ff5126 100644
--- a/msm8996/sdm/libs/core/hw_interface.h
+++ b/msm8996/sdm/libs/core/hw_interface.h
@@ -95,6 +95,8 @@
virtual DisplayError SetAutoRefresh(bool enable) = 0;
virtual DisplayError SetS3DMode(HWS3DMode s3d_mode) = 0;
virtual DisplayError SetScaleLutConfig(HWScaleLutInfo *lut_info) = 0;
+ virtual DisplayError SetMixerAttributes(const HWMixerAttributes &mixer_attributes) = 0;
+ virtual DisplayError GetMixerAttributes(HWMixerAttributes *mixer_attributes) = 0;
protected:
virtual ~HWInterface() { }
diff --git a/msm8996/sdm/libs/core/resource_default.cpp b/msm8996/sdm/libs/core/resource_default.cpp
index e13150b..bdbd8b7 100644
--- a/msm8996/sdm/libs/core/resource_default.cpp
+++ b/msm8996/sdm/libs/core/resource_default.cpp
@@ -104,8 +104,9 @@
}
DisplayError ResourceDefault::RegisterDisplay(DisplayType type,
- const HWDisplayAttributes &attributes,
+ const HWDisplayAttributes &display_attributes,
const HWPanelInfo &hw_panel_info,
+ const HWMixerAttributes &mixer_attributes,
Handle *display_ctx) {
DisplayError error = kErrorNone;
@@ -139,12 +140,9 @@
hw_block_ctx_[hw_block_id].is_in_use = true;
- display_resource_ctx->display_attributes = attributes;
+ display_resource_ctx->display_attributes = display_attributes;
display_resource_ctx->hw_block_id = hw_block_id;
-
- if (!display_resource_ctx->display_attributes.is_device_split) {
- display_resource_ctx->display_attributes.split_left = attributes.x_pixels;
- }
+ display_resource_ctx->mixer_attributes = mixer_attributes;
*display_ctx = display_resource_ctx;
return error;
@@ -162,14 +160,19 @@
return kErrorNone;
}
-void ResourceDefault::ReconfigureDisplay(Handle display_ctx, const HWDisplayAttributes &attributes,
- const HWPanelInfo &hw_panel_info) {
+DisplayError ResourceDefault::ReconfigureDisplay(Handle display_ctx,
+ const HWDisplayAttributes &display_attributes,
+ const HWPanelInfo &hw_panel_info,
+ const HWMixerAttributes &mixer_attributes) {
SCOPE_LOCK(locker_);
DisplayResourceContext *display_resource_ctx =
reinterpret_cast<DisplayResourceContext *>(display_ctx);
- display_resource_ctx->display_attributes = attributes;
+ display_resource_ctx->display_attributes = display_attributes;
+ display_resource_ctx->mixer_attributes = mixer_attributes;
+
+ return kErrorNone;
}
DisplayError ResourceDefault::Start(Handle display_ctx) {
@@ -447,20 +450,20 @@
DisplayError ResourceDefault::DisplaySplitConfig(DisplayResourceContext *display_resource_ctx,
const LayerRect &src_rect, const LayerRect &dst_rect,
HWLayerConfig *layer_config) {
- HWDisplayAttributes &display_attributes = display_resource_ctx->display_attributes;
+ HWMixerAttributes &mixer_attributes = display_resource_ctx->mixer_attributes;
// for display split case
HWPipeInfo *left_pipe = &layer_config->left_pipe;
HWPipeInfo *right_pipe = &layer_config->right_pipe;
LayerRect scissor_left, scissor_right, dst_left, crop_left, crop_right, dst_right;
- scissor_left.right = FLOAT(display_attributes.split_left);
- scissor_left.bottom = FLOAT(display_attributes.y_pixels);
+ scissor_left.right = FLOAT(mixer_attributes.split_left);
+ scissor_left.bottom = FLOAT(mixer_attributes.height);
- scissor_right.left = FLOAT(display_attributes.split_left);
+ scissor_right.left = FLOAT(mixer_attributes.split_left);
scissor_right.top = 0.0f;
- scissor_right.right = FLOAT(display_attributes.x_pixels);
- scissor_right.bottom = FLOAT(display_attributes.y_pixels);
+ scissor_right.right = FLOAT(mixer_attributes.width);
+ scissor_right.bottom = FLOAT(mixer_attributes.height);
crop_left = src_rect;
dst_left = dst_rect;
@@ -901,4 +904,9 @@
return kErrorNone;
}
+DisplayError ResourceDefault::SetDetailEnhancerData(Handle display_ctx,
+ const DisplayDetailEnhancerData &de_data) {
+ return kErrorNotSupported;
+}
+
} // namespace sdm
diff --git a/msm8996/sdm/libs/core/resource_default.h b/msm8996/sdm/libs/core/resource_default.h
index ce6dd5f..b57ce94 100644
--- a/msm8996/sdm/libs/core/resource_default.h
+++ b/msm8996/sdm/libs/core/resource_default.h
@@ -37,11 +37,16 @@
public:
DisplayError Init(const HWResourceInfo &hw_resource_info);
DisplayError Deinit();
- virtual DisplayError RegisterDisplay(DisplayType type, const HWDisplayAttributes &attributes,
- const HWPanelInfo &hw_panel_info, Handle *display_ctx);
+ virtual DisplayError RegisterDisplay(DisplayType type,
+ const HWDisplayAttributes &display_attributes,
+ const HWPanelInfo &hw_panel_info,
+ const HWMixerAttributes &mixer_attributes,
+ Handle *display_ctx);
virtual DisplayError UnregisterDisplay(Handle display_ctx);
- virtual void ReconfigureDisplay(Handle display_ctx, const HWDisplayAttributes &attributes,
- const HWPanelInfo &hw_panel_info);
+ virtual DisplayError ReconfigureDisplay(Handle display_ctx,
+ const HWDisplayAttributes &display_attributes,
+ const HWPanelInfo &hw_panel_info,
+ const HWMixerAttributes &mixer_attributes);
virtual DisplayError Start(Handle display_ctx);
virtual DisplayError Stop(Handle display_ctx);
virtual DisplayError Acquire(Handle display_ctx, HWLayers *hw_layers);
@@ -54,6 +59,8 @@
DisplayError ValidateCursorConfig(Handle display_ctx, const Layer *layer, bool is_top);
DisplayError ValidateCursorPosition(Handle display_ctx, HWLayers *hw_layers, int x, int y);
DisplayError SetMaxBandwidthMode(HWBwModes mode);
+ virtual DisplayError SetDetailEnhancerData(Handle display_ctx,
+ const DisplayDetailEnhancerData &de_data);
private:
enum PipeOwner {
@@ -84,6 +91,7 @@
HWDisplayAttributes display_attributes;
HWBlockType hw_block_id;
uint64_t frame_count;
+ HWMixerAttributes mixer_attributes;
DisplayResourceContext() : hw_block_id(kHWBlockMax), frame_count(0) { }
};
diff --git a/msm8996/sdm/libs/core/strategy.cpp b/msm8996/sdm/libs/core/strategy.cpp
index b8a499e..a70ac36 100644
--- a/msm8996/sdm/libs/core/strategy.cpp
+++ b/msm8996/sdm/libs/core/strategy.cpp
@@ -33,9 +33,12 @@
Strategy::Strategy(ExtensionInterface *extension_intf, DisplayType type,
const HWResourceInfo &hw_resource_info, const HWPanelInfo &hw_panel_info,
- const HWDisplayAttributes &hw_display_attributes)
+ const HWMixerAttributes &mixer_attributes,
+ const HWDisplayAttributes &display_attributes,
+ const DisplayConfigVariableInfo &fb_config)
: extension_intf_(extension_intf), display_type_(type), hw_resource_info_(hw_resource_info),
- hw_panel_info_(hw_panel_info), hw_display_attributes_(hw_display_attributes) {
+ hw_panel_info_(hw_panel_info), mixer_attributes_(mixer_attributes),
+ display_attributes_(display_attributes), fb_config_(fb_config) {
}
DisplayError Strategy::Init() {
@@ -43,14 +46,16 @@
if (extension_intf_) {
error = extension_intf_->CreateStrategyExtn(display_type_, hw_panel_info_.mode,
- hw_panel_info_.s3d_mode, &strategy_intf_);
+ hw_panel_info_.s3d_mode, mixer_attributes_,
+ fb_config_, &strategy_intf_);
if (error != kErrorNone) {
DLOGE("Failed to create strategy");
return error;
}
- error = extension_intf_->CreatePartialUpdate(display_type_, hw_resource_info_,
- hw_panel_info_, &partial_update_intf_);
+ error = extension_intf_->CreatePartialUpdate(display_type_, hw_resource_info_, hw_panel_info_,
+ mixer_attributes_, display_attributes_,
+ &partial_update_intf_);
}
return kErrorNone;
@@ -75,11 +80,9 @@
hw_layers_info_ = hw_layers_info;
extn_start_success_ = false;
tried_default_ = false;
-
uint32_t i = 0;
LayerStack *layer_stack = hw_layers_info_->stack;
uint32_t layer_count = UINT32(layer_stack->layers.size());
-
for (; i < layer_count; i++) {
if (layer_stack->layers.at(i)->composition == kCompositionGPUTarget) {
fb_layer_index_ = i;
@@ -167,29 +170,34 @@
return;
}
- float disp_x_res = hw_display_attributes_.x_pixels;
- float disp_y_res = hw_display_attributes_.y_pixels;
+ float layer_mixer_width = mixer_attributes_.width;
+ float layer_mixer_height = mixer_attributes_.height;
if (!hw_resource_info_.is_src_split &&
- ((disp_x_res > hw_resource_info_.max_mixer_width) ||
+ ((layer_mixer_width > hw_resource_info_.max_mixer_width) ||
((display_type_ == kPrimary) && hw_panel_info_.split_info.right_split))) {
split_display = true;
}
if (split_display) {
- float left_split = FLOAT(hw_panel_info_.split_info.left_split);
- hw_layers_info_->left_partial_update = (LayerRect) {0.0f, 0.0f, left_split, disp_y_res};
- hw_layers_info_->right_partial_update = (LayerRect) {left_split, 0.0f, disp_x_res, disp_y_res};
+ float left_split = FLOAT(mixer_attributes_.split_left);
+ hw_layers_info_->left_partial_update = (LayerRect) {0.0f, 0.0f, left_split, layer_mixer_height};
+ hw_layers_info_->right_partial_update = (LayerRect) {left_split, 0.0f, layer_mixer_width,
+ layer_mixer_height};
} else {
- hw_layers_info_->left_partial_update = (LayerRect) {0.0f, 0.0f, disp_x_res, disp_y_res};
+ hw_layers_info_->left_partial_update = (LayerRect) {0.0f, 0.0f, layer_mixer_width,
+ layer_mixer_height};
hw_layers_info_->right_partial_update = (LayerRect) {0.0f, 0.0f, 0.0f, 0.0f};
}
}
DisplayError Strategy::Reconfigure(const HWPanelInfo &hw_panel_info,
- const HWDisplayAttributes &hw_display_attributes) {
+ const HWDisplayAttributes &display_attributes,
+ const HWMixerAttributes &mixer_attributes,
+ const DisplayConfigVariableInfo &fb_config) {
hw_panel_info_ = hw_panel_info;
- hw_display_attributes_ = hw_display_attributes;
+ display_attributes_ = display_attributes;
+ mixer_attributes_ = mixer_attributes;
if (!extension_intf_) {
return kErrorNone;
@@ -202,10 +210,12 @@
partial_update_intf_ = NULL;
}
- extension_intf_->CreatePartialUpdate(display_type_, hw_resource_info_,
- hw_panel_info_, &partial_update_intf_);
+ extension_intf_->CreatePartialUpdate(display_type_, hw_resource_info_, hw_panel_info_,
+ mixer_attributes_, display_attributes_,
+ &partial_update_intf_);
- return strategy_intf_->Reconfigure(hw_panel_info_.mode, hw_panel_info_.s3d_mode);
+ return strategy_intf_->Reconfigure(hw_panel_info_.mode, hw_panel_info_.s3d_mode, mixer_attributes,
+ fb_config);
}
} // namespace sdm
diff --git a/msm8996/sdm/libs/core/strategy.h b/msm8996/sdm/libs/core/strategy.h
index 5f14d28..b284d61 100644
--- a/msm8996/sdm/libs/core/strategy.h
+++ b/msm8996/sdm/libs/core/strategy.h
@@ -34,7 +34,8 @@
public:
Strategy(ExtensionInterface *extension_intf, DisplayType type,
const HWResourceInfo &hw_resource_info, const HWPanelInfo &hw_panel_info,
- const HWDisplayAttributes &hw_display_attributes);
+ const HWMixerAttributes &mixer_attributes, const HWDisplayAttributes &display_attributes,
+ const DisplayConfigVariableInfo &fb_config);
DisplayError Init();
DisplayError Deinit();
@@ -44,7 +45,9 @@
DisplayError GetNextStrategy(StrategyConstraints *constraints);
DisplayError Stop();
DisplayError Reconfigure(const HWPanelInfo &hw_panel_info,
- const HWDisplayAttributes &hw_display_attributes);
+ const HWDisplayAttributes &hw_display_attributes,
+ const HWMixerAttributes &mixer_attributes,
+ const DisplayConfigVariableInfo &fb_config);
private:
void GenerateROI();
@@ -56,7 +59,9 @@
HWResourceInfo hw_resource_info_;
HWPanelInfo hw_panel_info_;
HWLayersInfo *hw_layers_info_ = NULL;
- HWDisplayAttributes hw_display_attributes_;
+ HWMixerAttributes mixer_attributes_ = {};
+ HWDisplayAttributes display_attributes_ = {};
+ DisplayConfigVariableInfo fb_config_ = {};
uint32_t fb_layer_index_ = 0;
bool extn_start_success_ = false;
bool tried_default_ = false;
diff --git a/msm8996/sdm/libs/hwc/hwc_color_manager.cpp b/msm8996/sdm/libs/hwc/hwc_color_manager.cpp
index 27115b5..7c12ec0 100644
--- a/msm8996/sdm/libs/hwc/hwc_color_manager.cpp
+++ b/msm8996/sdm/libs/hwc/hwc_color_manager.cpp
@@ -254,7 +254,7 @@
uint32_t primary_width = 0;
uint32_t primary_height = 0;
- hwc_display->GetPanelResolution(&primary_width, &primary_height);
+ hwc_display->GetMixerResolution(&primary_width, &primary_height);
uint8_t *buf = new uint8_t[size]();
// handle for solid fill layer with fd = -1.
private_handle_t *handle =
diff --git a/msm8996/sdm/libs/hwc/hwc_display.cpp b/msm8996/sdm/libs/hwc/hwc_display.cpp
index f829f68..97e6c02 100644
--- a/msm8996/sdm/libs/hwc/hwc_display.cpp
+++ b/msm8996/sdm/libs/hwc/hwc_display.cpp
@@ -83,13 +83,6 @@
swap_interval_zero_ = true;
}
- framebuffer_config_ = new DisplayConfigVariableInfo();
- if (!framebuffer_config_) {
- DLOGV("Failed to allocate memory for custom framebuffer config.");
- core_intf_->DestroyDisplay(display_intf_);
- return -EINVAL;
- }
-
int blit_enabled = 0;
HWCDebugHandler::Get()->GetProperty("persist.hwc.blit.comp", &blit_enabled);
if (needs_blit_ && blit_enabled) {
@@ -126,8 +119,6 @@
return -EINVAL;
}
- delete framebuffer_config_;
-
if (blit_engine_) {
blit_engine_->DeInit();
delete blit_engine_;
@@ -224,11 +215,17 @@
return 0;
}
-int HWCDisplay::GetDisplayAttributes(uint32_t config, const uint32_t *attributes, int32_t *values) {
- DisplayConfigVariableInfo variable_config = *framebuffer_config_;
+int HWCDisplay::GetDisplayAttributes(uint32_t config, const uint32_t *display_attributes,
+ int32_t *values) {
+ DisplayConfigVariableInfo variable_config;
+ DisplayError error = display_intf_->GetFrameBufferConfig(&variable_config);
+ if (error != kErrorNone) {
+ DLOGV("Get variable config failed. Error = %d", error);
+ return -EINVAL;
+ }
- for (int i = 0; attributes[i] != HWC_DISPLAY_NO_ATTRIBUTE; i++) {
- switch (attributes[i]) {
+ for (int i = 0; display_attributes[i] != HWC_DISPLAY_NO_ATTRIBUTE; i++) {
+ switch (display_attributes[i]) {
case HWC_DISPLAY_VSYNC_PERIOD:
values[i] = INT32(variable_config.vsync_period_ns);
break;
@@ -245,7 +242,7 @@
values[i] = INT32(variable_config.y_dpi * 1000.0f);
break;
default:
- DLOGW("Spurious attribute type = %d", attributes[i]);
+ DLOGW("Spurious attribute type = %d", display_attributes[i]);
return -EINVAL;
}
}
@@ -261,6 +258,10 @@
return -1;
}
+DisplayError HWCDisplay::SetMixerResolution(uint32_t width, uint32_t height) {
+ return kErrorNotSupported;
+}
+
void HWCDisplay::SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type) {
dump_frame_count_ = count;
dump_frame_index_ = 0;
@@ -450,7 +451,6 @@
}
hwc_rect_t scaled_display_frame = hwc_layer.displayFrame;
- ScaleDisplayFrame(&scaled_display_frame);
ApplyScanAdjustment(&scaled_display_frame);
SetRect(scaled_display_frame, &layer->dst_rect);
@@ -792,16 +792,6 @@
return error;
}
-DisplayError HWCDisplay::ControlPartialUpdate(bool enable, uint32_t *pending) {
- DisplayError error = kErrorNone;
-
- if (display_intf_) {
- error = display_intf_->ControlPartialUpdate(enable, pending);
- }
-
- return error;
-}
-
LayerBufferFormat HWCDisplay::GetSDMFormat(const int32_t &source, const int flags) {
LayerBufferFormat format = kFormatInvalid;
if (flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
@@ -1042,108 +1032,49 @@
}
int HWCDisplay::SetFrameBufferResolution(uint32_t x_pixels, uint32_t y_pixels) {
- if (x_pixels <= 0 || y_pixels <= 0) {
- DLOGV("Unsupported config: x_pixels=%d, y_pixels=%d", x_pixels, y_pixels);
- return -EINVAL;
- }
-
- if (framebuffer_config_->x_pixels == x_pixels && framebuffer_config_->y_pixels == y_pixels) {
- return 0;
- }
-
- DisplayConfigVariableInfo active_config;
- uint32_t active_config_index = 0;
- display_intf_->GetActiveConfig(&active_config_index);
- DisplayError error = display_intf_->GetConfig(active_config_index, &active_config);
+ DisplayConfigVariableInfo fb_config;
+ DisplayError error = display_intf_->GetFrameBufferConfig(&fb_config);
if (error != kErrorNone) {
- DLOGV("GetConfig variable info failed. Error = %d", error);
+ DLOGV("Get frame buffer config failed. Error = %d", error);
return -EINVAL;
}
- if (active_config.x_pixels <= 0 || active_config.y_pixels <= 0) {
- DLOGV("Invalid panel resolution (%dx%d)", active_config.x_pixels, active_config.y_pixels);
- return -EINVAL;
- }
+ fb_config.x_pixels = x_pixels;
+ fb_config.y_pixels = y_pixels;
- // Create rects to represent the new source and destination crops
- LayerRect crop = LayerRect(0, 0, FLOAT(x_pixels), FLOAT(y_pixels));
- LayerRect dst = LayerRect(0, 0, FLOAT(active_config.x_pixels), FLOAT(active_config.y_pixels));
- // Set rotate90 to false since this is taken care of during regular composition.
- bool rotate90 = false;
- error = display_intf_->IsScalingValid(crop, dst, rotate90);
+ error = display_intf_->SetFrameBufferConfig(fb_config);
if (error != kErrorNone) {
- DLOGV("Unsupported resolution: (%dx%d)", x_pixels, y_pixels);
+ DLOGV("Set frame buffer config failed. Error = %d", error);
return -EINVAL;
}
- framebuffer_config_->x_pixels = x_pixels;
- framebuffer_config_->y_pixels = y_pixels;
- framebuffer_config_->vsync_period_ns = active_config.vsync_period_ns;
- framebuffer_config_->x_dpi = active_config.x_dpi;
- framebuffer_config_->y_dpi = active_config.y_dpi;
-
- DLOGI("New framebuffer resolution (%dx%d)", framebuffer_config_->x_pixels,
- framebuffer_config_->y_pixels);
+ DLOGI("New framebuffer resolution (%dx%d)", x_pixels, y_pixels);
return 0;
}
void HWCDisplay::GetFrameBufferResolution(uint32_t *x_pixels, uint32_t *y_pixels) {
- *x_pixels = framebuffer_config_->x_pixels;
- *y_pixels = framebuffer_config_->y_pixels;
+ DisplayConfigVariableInfo fb_config;
+ display_intf_->GetFrameBufferConfig(&fb_config);
+
+ *x_pixels = fb_config.x_pixels;
+ *y_pixels = fb_config.y_pixels;
}
-void HWCDisplay::ScaleDisplayFrame(hwc_rect_t *display_frame) {
- if (!IsFrameBufferScaled()) {
- return;
- }
-
- uint32_t active_config_index = 0;
- display_intf_->GetActiveConfig(&active_config_index);
- DisplayConfigVariableInfo active_config;
- DisplayError error = display_intf_->GetConfig(active_config_index, &active_config);
- if (error != kErrorNone) {
- DLOGE("GetConfig variable info failed. Error = %d", error);
- return;
- }
-
- float custom_x_pixels = FLOAT(framebuffer_config_->x_pixels);
- float custom_y_pixels = FLOAT(framebuffer_config_->y_pixels);
- float active_x_pixels = FLOAT(active_config.x_pixels);
- float active_y_pixels = FLOAT(active_config.y_pixels);
- float x_pixels_ratio = active_x_pixels / custom_x_pixels;
- float y_pixels_ratio = active_y_pixels / custom_y_pixels;
- float layer_width = FLOAT(display_frame->right - display_frame->left);
- float layer_height = FLOAT(display_frame->bottom - display_frame->top);
-
- display_frame->left = INT(x_pixels_ratio * FLOAT(display_frame->left));
- display_frame->top = INT(y_pixels_ratio * FLOAT(display_frame->top));
- display_frame->right = INT(FLOAT(display_frame->left) + layer_width * x_pixels_ratio);
- display_frame->bottom = INT(FLOAT(display_frame->top) + layer_height * y_pixels_ratio);
+DisplayError HWCDisplay::GetMixerResolution(uint32_t *x_pixels, uint32_t *y_pixels) {
+ return display_intf_->GetMixerResolution(x_pixels, y_pixels);
}
-bool HWCDisplay::IsFrameBufferScaled() {
- if (framebuffer_config_->x_pixels == 0 || framebuffer_config_->y_pixels == 0) {
- return false;
- }
- uint32_t panel_x_pixels = 0;
- uint32_t panel_y_pixels = 0;
- GetPanelResolution(&panel_x_pixels, &panel_y_pixels);
- return (framebuffer_config_->x_pixels != panel_x_pixels) ||
- (framebuffer_config_->y_pixels != panel_y_pixels);
-}
void HWCDisplay::GetPanelResolution(uint32_t *x_pixels, uint32_t *y_pixels) {
- DisplayConfigVariableInfo active_config;
- uint32_t active_config_index = 0;
- display_intf_->GetActiveConfig(&active_config_index);
- DisplayError error = display_intf_->GetConfig(active_config_index, &active_config);
- if (error != kErrorNone) {
- DLOGE("GetConfig variable info failed. Error = %d", error);
- return;
- }
- *x_pixels = active_config.x_pixels;
- *y_pixels = active_config.y_pixels;
+ DisplayConfigVariableInfo display_config;
+ uint32_t active_index = 0;
+
+ display_intf_->GetActiveConfig(&active_index);
+ display_intf_->GetConfig(active_index, &display_config);
+
+ *x_pixels = display_config.x_pixels;
+ *y_pixels = display_config.y_pixels;
}
int HWCDisplay::SetDisplayStatus(uint32_t display_status) {
@@ -1365,8 +1296,9 @@
return display_intf_->GetNumVariableInfoConfigs(count) == kErrorNone ? 0 : -1;
}
-int HWCDisplay::GetDisplayAttributesForConfig(int config, DisplayConfigVariableInfo *attributes) {
- return display_intf_->GetConfig(UINT32(config), attributes) == kErrorNone ? 0 : -1;
+int HWCDisplay::GetDisplayAttributesForConfig(int config,
+ DisplayConfigVariableInfo *display_attributes) {
+ return display_intf_->GetConfig(UINT32(config), display_attributes) == kErrorNone ? 0 : -1;
}
// TODO(user): HWC needs to know updating for dyn_fps, cpu hint features,
diff --git a/msm8996/sdm/libs/hwc/hwc_display.h b/msm8996/sdm/libs/hwc/hwc_display.h
index 8bc7a91..1dfface 100644
--- a/msm8996/sdm/libs/hwc/hwc_display.h
+++ b/msm8996/sdm/libs/hwc/hwc_display.h
@@ -59,23 +59,28 @@
// Framebuffer configurations
virtual int GetDisplayConfigs(uint32_t *configs, size_t *num_configs);
- virtual int GetDisplayAttributes(uint32_t config, const uint32_t *attributes, int32_t *values);
+ virtual int GetDisplayAttributes(uint32_t config, const uint32_t *display_attributes,
+ int32_t *values);
virtual int GetActiveConfig();
virtual int SetActiveConfig(int index);
virtual void SetIdleTimeoutMs(uint32_t timeout_ms);
virtual void SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type);
virtual DisplayError SetMaxMixerStages(uint32_t max_mixer_stages);
- virtual DisplayError ControlPartialUpdate(bool enable, uint32_t *pending);
+ virtual DisplayError ControlPartialUpdate(bool enable, uint32_t *pending) {
+ return kErrorNotSupported;
+ }
virtual uint32_t GetLastPowerMode();
virtual int SetFrameBufferResolution(uint32_t x_pixels, uint32_t y_pixels);
virtual void GetFrameBufferResolution(uint32_t *x_pixels, uint32_t *y_pixels);
- virtual void GetPanelResolution(uint32_t *x_pixels, uint32_t *y_pixels);
virtual int SetDisplayStatus(uint32_t display_status);
virtual int OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level);
virtual int Perform(uint32_t operation, ...);
virtual int SetCursorPosition(int x, int y);
virtual void SetSecureDisplay(bool secure_display_active);
+ virtual DisplayError SetMixerResolution(uint32_t width, uint32_t height);
+ virtual DisplayError GetMixerResolution(uint32_t *width, uint32_t *height);
+ virtual void GetPanelResolution(uint32_t *width, uint32_t *height);
// Captures frame output in the buffer specified by output_buffer_info. The API is
// non-blocking and the client is expected to check operation status later on.
@@ -93,7 +98,8 @@
virtual int SetActiveDisplayConfig(int config);
virtual int GetActiveDisplayConfig(uint32_t *config);
virtual int GetDisplayConfigCount(uint32_t *count);
- virtual int GetDisplayAttributesForConfig(int config, DisplayConfigVariableInfo *attributes);
+ virtual int GetDisplayAttributesForConfig(int config,
+ DisplayConfigVariableInfo *display_attributes);
int SetPanelBrightness(int level);
int GetPanelBrightness(int *level);
@@ -136,6 +142,9 @@
virtual uint32_t RoundToStandardFPS(float fps);
virtual uint32_t SanitizeRefreshRate(uint32_t req_refresh_rate);
virtual void PrepareDynamicRefreshRate(Layer *layer);
+ virtual DisplayError DisablePartialUpdateOneFrame() {
+ return kErrorNotSupported;
+ }
inline void SetRect(const hwc_rect_t &source, LayerRect *target);
inline void SetRect(const hwc_frect_t &source, LayerRect *target);
inline void SetComposition(const int32_t &source, LayerComposition *target);
@@ -145,7 +154,6 @@
LayerBufferFormat GetSDMFormat(const int32_t &source, const int flags);
const char *GetHALPixelFormatString(int format);
const char *GetDisplayString();
- void ScaleDisplayFrame(hwc_rect_t *display_frame);
void MarkLayersForGPUBypass(hwc_display_contents_1_t *content_list);
virtual void ApplyScanAdjustment(hwc_rect_t *display_frame);
DisplayError SetCSC(ColorSpace_t source, LayerCSC *target);
@@ -176,7 +184,6 @@
bool dump_input_layers_ = false;
uint32_t last_power_mode_;
bool swap_interval_zero_ = false;
- DisplayConfigVariableInfo *framebuffer_config_ = NULL;
bool display_paused_ = false;
uint32_t min_refresh_rate_ = 0;
uint32_t max_refresh_rate_ = 0;
@@ -196,7 +203,6 @@
bool animating_ = false;
private:
- bool IsFrameBufferScaled();
void DumpInputBuffers(hwc_display_contents_1_t *content_list);
int PrepareLayerParams(hwc_layer_1_t *hwc_layer, Layer *layer);
void CommitLayerParams(hwc_layer_1_t *hwc_layer, Layer *layer);
diff --git a/msm8996/sdm/libs/hwc/hwc_display_external.cpp b/msm8996/sdm/libs/hwc/hwc_display_external.cpp
index a647517..ad8690c 100644
--- a/msm8996/sdm/libs/hwc/hwc_display_external.cpp
+++ b/msm8996/sdm/libs/hwc/hwc_display_external.cpp
@@ -50,6 +50,7 @@
uint32_t external_width = 0;
uint32_t external_height = 0;
int drc_enabled = 0;
+ DisplayError error = kErrorNone;
HWCDisplay *hwc_display_external = new HWCDisplayExternal(core_intf, hwc_procs, qservice);
int status = hwc_display_external->Init();
@@ -58,7 +59,10 @@
return status;
}
- hwc_display_external->GetPanelResolution(&external_width, &external_height);
+ error = hwc_display_external->GetMixerResolution(&external_width, &external_height);
+ if (error != kErrorNone) {
+ return -EINVAL;
+ }
if (primary_width && primary_height) {
// use_primary_res means HWCDisplayExternal should directly set framebuffer resolution to the
@@ -180,28 +184,28 @@
return;
}
- uint32_t panel_width = 0;
- uint32_t panel_height = 0;
- GetPanelResolution(&panel_width, &panel_height);
+ uint32_t mixer_width = 0;
+ uint32_t mixer_height = 0;
+ GetMixerResolution(&mixer_width, &mixer_height);
- if (panel_width == 0 || panel_height == 0) {
- DLOGV("Invalid panel dimensions (%d, %d)", panel_width, panel_height);
+ if (mixer_width == 0 || mixer_height == 0) {
+ DLOGV("Invalid mixer dimensions (%d, %d)", mixer_width, mixer_height);
return;
}
- uint32_t new_panel_width = UINT32(panel_width * FLOAT(1.0f - width_ratio));
- uint32_t new_panel_height = UINT32(panel_height * FLOAT(1.0f - height_ratio));
+ uint32_t new_mixer_width = UINT32(mixer_width * FLOAT(1.0f - width_ratio));
+ uint32_t new_mixer_height = UINT32(mixer_height * FLOAT(1.0f - height_ratio));
- int x_offset = INT((FLOAT(panel_width) * width_ratio) / 2.0f);
- int y_offset = INT((FLOAT(panel_height) * height_ratio) / 2.0f);
+ int x_offset = INT((FLOAT(mixer_width) * width_ratio) / 2.0f);
+ int y_offset = INT((FLOAT(mixer_height) * height_ratio) / 2.0f);
- display_frame->left = (display_frame->left * INT32(new_panel_width) / INT32(panel_width))
+ display_frame->left = (display_frame->left * INT32(new_mixer_width) / INT32(mixer_width))
+ x_offset;
- display_frame->top = (display_frame->top * INT32(new_panel_height) / INT32(panel_height)) +
+ display_frame->top = (display_frame->top * INT32(new_mixer_height) / INT32(mixer_height)) +
y_offset;
- display_frame->right = ((display_frame->right * INT32(new_panel_width)) / INT32(panel_width)) +
+ display_frame->right = ((display_frame->right * INT32(new_mixer_width)) / INT32(mixer_width)) +
x_offset;
- display_frame->bottom = ((display_frame->bottom * INT32(new_panel_height)) / INT32(panel_height))
+ display_frame->bottom = ((display_frame->bottom * INT32(new_mixer_height)) / INT32(mixer_height))
+ y_offset;
}
diff --git a/msm8996/sdm/libs/hwc/hwc_display_null.cpp b/msm8996/sdm/libs/hwc/hwc_display_null.cpp
index 11cf47a..649f40c 100644
--- a/msm8996/sdm/libs/hwc/hwc_display_null.cpp
+++ b/msm8996/sdm/libs/hwc/hwc_display_null.cpp
@@ -97,12 +97,12 @@
#define NULL_DISPLAY_FPS 60
-int HWCDisplayNull::GetDisplayAttributes(uint32_t config, const uint32_t *attributes,
+int HWCDisplayNull::GetDisplayAttributes(uint32_t config, const uint32_t *display_attributes,
int32_t *values) {
- for (int i = 0; attributes[i] != HWC_DISPLAY_NO_ATTRIBUTE; i++) {
+ for (int i = 0; display_attributes[i] != HWC_DISPLAY_NO_ATTRIBUTE; i++) {
// We fake display resolution as 1080P by default, though it can be overriden through a call to
// SetResolution(), and DPI as 160, though what the DPI value does is not clear
- switch (attributes[i]) {
+ switch (display_attributes[i]) {
case HWC_DISPLAY_VSYNC_PERIOD:
values[i] = INT32(1000000000L / NULL_DISPLAY_FPS);
break;
diff --git a/msm8996/sdm/libs/hwc/hwc_display_null.h b/msm8996/sdm/libs/hwc/hwc_display_null.h
index 2f6438a..297e870 100644
--- a/msm8996/sdm/libs/hwc/hwc_display_null.h
+++ b/msm8996/sdm/libs/hwc/hwc_display_null.h
@@ -48,7 +48,8 @@
return HWCDisplay::GetDisplayConfigs(configs, num_configs);
}
- virtual int GetDisplayAttributes(uint32_t config, const uint32_t *attributes, int32_t *values);
+ virtual int GetDisplayAttributes(uint32_t config, const uint32_t *display_attributes,
+ int32_t *values);
virtual int GetActiveConfig() { return 0; }
virtual int SetActiveConfig(int index) { return -1; }
@@ -79,7 +80,8 @@
virtual int SetActiveDisplayConfig(int config) { return 0; }
virtual int GetActiveDisplayConfig(uint32_t *config) { return -1; }
virtual int GetDisplayConfigCount(uint32_t *count) { return -1; }
- virtual int GetDisplayAttributesForConfig(int config, DisplayConfigVariableInfo *attributes) {
+ virtual int GetDisplayAttributesForConfig(int config,
+ DisplayConfigVariableInfo *display_attributes) {
return -1;
}
virtual bool IsValidContentList(hwc_display_contents_1_t *content_list) {
diff --git a/msm8996/sdm/libs/hwc/hwc_display_primary.cpp b/msm8996/sdm/libs/hwc/hwc_display_primary.cpp
index 32ff73b..f92ab43 100644
--- a/msm8996/sdm/libs/hwc/hwc_display_primary.cpp
+++ b/msm8996/sdm/libs/hwc/hwc_display_primary.cpp
@@ -56,7 +56,7 @@
return status;
}
- hwc_display_primary->GetPanelResolution(&primary_width, &primary_height);
+ hwc_display_primary->GetMixerResolution(&primary_width, &primary_height);
int width = 0, height = 0;
HWCDebugHandler::Get()->GetProperty("sdm.fb_size_width", &width);
HWCDebugHandler::Get()->GetProperty("sdm.fb_size_height", &height);
@@ -382,9 +382,6 @@
frame_capture_buffer_queued_ = false;
post_processed_output_ = false;
output_buffer_ = {};
-
- uint32_t pending = 0; // Just a temporary to satisfy the API
- ControlPartialUpdate(true /* enable */, &pending);
}
void HWCDisplayPrimary::HandleFrameDump() {
@@ -413,9 +410,6 @@
output_buffer_ = {};
output_buffer_info_ = {};
output_buffer_base_ = nullptr;
-
- uint32_t pending = 0; // Just a temporary to satisfy the API
- ControlPartialUpdate(true /* enable */, &pending);
}
}
@@ -454,8 +448,7 @@
output_buffer_base_ = buffer;
post_processed_output_ = true;
- uint32_t pending = 0; // Just a temporary to satisfy the API
- ControlPartialUpdate(false /* enable */, &pending);
+ DisablePartialUpdateOneFrame();
}
int HWCDisplayPrimary::FrameCaptureAsync(const BufferInfo& output_buffer_info,
@@ -489,12 +482,38 @@
frame_capture_buffer_queued_ = true;
// Status is only cleared on a new call to dump and remains valid otherwise
frame_capture_status_ = -EAGAIN;
-
- uint32_t pending = 0; // Just a temporary to satisfy the API
- ControlPartialUpdate(false /* enable */, &pending);
+ DisablePartialUpdateOneFrame();
return 0;
}
+DisplayError HWCDisplayPrimary::ControlPartialUpdate(bool enable, uint32_t *pending) {
+ DisplayError error = kErrorNone;
+
+ if (display_intf_) {
+ error = display_intf_->ControlPartialUpdate(enable, pending);
+ }
+
+ return error;
+}
+
+DisplayError HWCDisplayPrimary::DisablePartialUpdateOneFrame() {
+ DisplayError error = kErrorNone;
+
+ if (display_intf_) {
+ error = display_intf_->DisablePartialUpdateOneFrame();
+ }
+
+ return error;
+}
+
+DisplayError HWCDisplayPrimary::SetMixerResolution(uint32_t width, uint32_t height) {
+ return display_intf_->SetMixerResolution(width, height);
+}
+
+DisplayError HWCDisplayPrimary::GetMixerResolution(uint32_t *width, uint32_t *height) {
+ return display_intf_->GetMixerResolution(width, height);
+}
+
} // namespace sdm
diff --git a/msm8996/sdm/libs/hwc/hwc_display_primary.h b/msm8996/sdm/libs/hwc/hwc_display_primary.h
index 8c02731..81e510f 100644
--- a/msm8996/sdm/libs/hwc/hwc_display_primary.h
+++ b/msm8996/sdm/libs/hwc/hwc_display_primary.h
@@ -54,12 +54,14 @@
virtual void SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type);
virtual int FrameCaptureAsync(const BufferInfo& output_buffer_info, bool post_processed);
virtual int GetFrameCaptureStatus() { return frame_capture_status_; }
+ virtual DisplayError ControlPartialUpdate(bool enable, uint32_t *pending);
private:
HWCDisplayPrimary(CoreInterface *core_intf, BufferAllocator *buffer_allocator,
hwc_procs_t const **hwc_procs, qService::QService *qservice);
void SetMetaDataRefreshRateFlag(bool enable);
virtual DisplayError SetDisplayMode(uint32_t mode);
+ virtual DisplayError DisablePartialUpdateOneFrame();
void ProcessBootAnimCompleted(hwc_display_contents_1_t *content_list);
void SetQDCMSolidFillInfo(bool enable, uint32_t color);
void ToggleCPUHint(bool set);
@@ -68,6 +70,8 @@
void HandleFrameOutput();
void HandleFrameCapture();
void HandleFrameDump();
+ DisplayError SetMixerResolution(uint32_t width, uint32_t height);
+ DisplayError GetMixerResolution(uint32_t *width, uint32_t *height);
BufferAllocator *buffer_allocator_ = nullptr;
CPUHint *cpu_hint_ = nullptr;
diff --git a/msm8996/sdm/libs/hwc/hwc_display_virtual.cpp b/msm8996/sdm/libs/hwc/hwc_display_virtual.cpp
index ef7198c..1363839 100644
--- a/msm8996/sdm/libs/hwc/hwc_display_virtual.cpp
+++ b/msm8996/sdm/libs/hwc/hwc_display_virtual.cpp
@@ -67,7 +67,7 @@
return status;
}
- hwc_display_virtual->GetPanelResolution(&virtual_width, &virtual_height);
+ hwc_display_virtual->GetMixerResolution(&virtual_width, &virtual_height);
if (content_list->numHwLayers < 1) {
Destroy(hwc_display_virtual);
diff --git a/msm8996/sdm/libs/hwc/hwc_session.cpp b/msm8996/sdm/libs/hwc/hwc_session.cpp
index 63bde5c..8d12aee 100644
--- a/msm8996/sdm/libs/hwc/hwc_session.cpp
+++ b/msm8996/sdm/libs/hwc/hwc_session.cpp
@@ -555,10 +555,10 @@
}
int HWCSession::GetDisplayAttributes(hwc_composer_device_1 *device, int disp, uint32_t config,
- const uint32_t *attributes, int32_t *values) {
+ const uint32_t *display_attributes, int32_t *values) {
SCOPE_LOCK(locker_);
- if (!device || !attributes || !values) {
+ if (!device || !display_attributes || !values) {
return -EINVAL;
}
@@ -569,7 +569,8 @@
HWCSession *hwc_session = static_cast<HWCSession *>(device);
int status = -EINVAL;
if (hwc_session->hwc_display_[disp]) {
- status = hwc_session->hwc_display_[disp]->GetDisplayAttributes(config, attributes, values);
+ status = hwc_session->hwc_display_[disp]->GetDisplayAttributes(config, display_attributes,
+ values);
}
return status;
@@ -775,6 +776,10 @@
status = GetBWTransactionStatus(input_parcel, output_parcel);
break;
+ case qService::IQService::SET_LAYER_MIXER_RESOLUTION:
+ status = SetMixerResolution(input_parcel);
+ break;
+
default:
DLOGW("QService command = %d is not supported", command);
return -EINVAL;
@@ -947,22 +952,22 @@
int config = input_parcel->readInt32();
int dpy = input_parcel->readInt32();
int error = android::BAD_VALUE;
- DisplayConfigVariableInfo attributes;
+ DisplayConfigVariableInfo display_attributes;
if (dpy > HWC_DISPLAY_VIRTUAL) {
return android::BAD_VALUE;
}
if (hwc_display_[dpy]) {
- error = hwc_display_[dpy]->GetDisplayAttributesForConfig(config, &attributes);
+ error = hwc_display_[dpy]->GetDisplayAttributesForConfig(config, &display_attributes);
if (error == 0) {
- output_parcel->writeInt32(INT(attributes.vsync_period_ns));
- output_parcel->writeInt32(INT(attributes.x_pixels));
- output_parcel->writeInt32(INT(attributes.y_pixels));
- output_parcel->writeFloat(attributes.x_dpi);
- output_parcel->writeFloat(attributes.y_dpi);
+ output_parcel->writeInt32(INT(display_attributes.vsync_period_ns));
+ output_parcel->writeInt32(INT(display_attributes.x_pixels));
+ output_parcel->writeInt32(INT(display_attributes.y_pixels));
+ output_parcel->writeFloat(display_attributes.x_dpi);
+ output_parcel->writeFloat(display_attributes.y_dpi);
output_parcel->writeInt32(0); // Panel type, unsupported.
- output_parcel->writeInt32(attributes.is_yuv);
+ output_parcel->writeInt32(display_attributes.is_yuv);
}
}
@@ -1116,6 +1121,31 @@
}
}
+android::status_t HWCSession::SetMixerResolution(const android::Parcel *input_parcel) {
+ DisplayError error = kErrorNone;
+ uint32_t dpy = UINT32(input_parcel->readInt32());
+
+ if (dpy != HWC_DISPLAY_PRIMARY) {
+ DLOGI("Resoulution change not supported for this display %d", dpy);
+ return -EINVAL;
+ }
+
+ if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
+ DLOGI("Primary display is not initialized");
+ return -EINVAL;
+ }
+
+ uint32_t width = UINT32(input_parcel->readInt32());
+ uint32_t height = UINT32(input_parcel->readInt32());
+
+ error = hwc_display_[HWC_DISPLAY_PRIMARY]->SetMixerResolution(width, height);
+ if (error != kErrorNone) {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
void HWCSession::DynamicDebug(const android::Parcel *input_parcel) {
int type = input_parcel->readInt32();
bool enable = (input_parcel->readInt32() > 0);
diff --git a/msm8996/sdm/libs/hwc/hwc_session.h b/msm8996/sdm/libs/hwc/hwc_session.h
index efcafcf..2bdae2b 100644
--- a/msm8996/sdm/libs/hwc/hwc_session.h
+++ b/msm8996/sdm/libs/hwc/hwc_session.h
@@ -68,7 +68,7 @@
static int GetDisplayConfigs(hwc_composer_device_1 *device, int disp, uint32_t *configs,
size_t *numConfigs);
static int GetDisplayAttributes(hwc_composer_device_1 *device, int disp, uint32_t config,
- const uint32_t *attributes, int32_t *values);
+ const uint32_t *display_attributes, int32_t *values);
static int GetActiveConfig(hwc_composer_device_1 *device, int disp);
static int SetActiveConfig(hwc_composer_device_1 *device, int disp, int index);
static int SetCursorPositionAsync(hwc_composer_device_1 *device, int disp, int x, int y);
@@ -123,6 +123,8 @@
android::Parcel *output_parcel);
android::status_t GetBWTransactionStatus(const android::Parcel *input_parcel,
android::Parcel *output_parcel);
+ android::status_t SetMixerResolution(const android::Parcel *input_parcel);
+
static Locker locker_;
CoreInterface *core_intf_ = NULL;
hwc_procs_t hwc_procs_default_;
diff --git a/msm8996/sdm/libs/utils/rect.cpp b/msm8996/sdm/libs/utils/rect.cpp
index e756464..1872df2 100644
--- a/msm8996/sdm/libs/utils/rect.cpp
+++ b/msm8996/sdm/libs/utils/rect.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -198,5 +198,40 @@
}
}
+void ScaleRect(const LayerRect &src_domain, const LayerRect &dst_domain, const LayerRect &in_rect,
+ LayerRect *out_rect) {
+ if (!IsValid(src_domain) || !IsValid(dst_domain) || !IsValid(in_rect)) {
+ return;
+ }
+
+ float src_domain_width = src_domain.right - src_domain.left;
+ float src_domain_height = src_domain.bottom - src_domain.top;
+ float dst_domain_width = dst_domain.right - dst_domain.left;
+ float dst_domain_height = dst_domain.bottom - dst_domain.top;
+
+ float width_ratio = dst_domain_width / src_domain_width;
+ float height_ratio = dst_domain_height / src_domain_height;
+
+ out_rect->left = width_ratio * in_rect.left;
+ out_rect->top = height_ratio * in_rect.top;
+ out_rect->right = width_ratio * in_rect.right;
+ out_rect->bottom = height_ratio * in_rect.bottom;
+}
+
+RectOrientation GetOrientation(const LayerRect &in_rect) {
+ if (!IsValid(in_rect)) {
+ return kOrientationUnknown;
+ }
+
+ float input_width = in_rect.right - in_rect.left;
+ float input_height = in_rect.bottom - in_rect.top;
+
+ if (input_width < input_height) {
+ return kOrientationPortrait;
+ }
+
+ return kOrientationLandscape;
+}
+
} // namespace sdm