sdm: Align to new SDM design.
- Align code base to new SDM design. Change-Id: I38d7d138ae704cf036e2b96c16453aea63bc333f
This commit is contained in:
10
Android.mk
10
Android.mk
@@ -1,15 +1,15 @@
|
||||
ifeq ($(call is-board-platform-in-list, msm8996),true)
|
||||
TARGET_USES_SDE = true
|
||||
TARGET_USES_SDM = true
|
||||
else
|
||||
TARGET_USES_SDE = false
|
||||
TARGET_USES_SDM = false
|
||||
endif
|
||||
|
||||
display-hals := libgralloc libcopybit liblight libmemtrack libqservice libqdutils
|
||||
display-hals += hdmi_cec
|
||||
|
||||
ifeq ($(TARGET_USES_SDE), true)
|
||||
sde-libs := displayengine/libs
|
||||
display-hals += $(sde-libs)/utils $(sde-libs)/core $(sde-libs)/hwc
|
||||
ifeq ($(TARGET_USES_SDM), true)
|
||||
sdm-libs := sdm/libs
|
||||
display-hals += $(sdm-libs)/utils $(sdm-libs)/core $(sdm-libs)/hwc
|
||||
else
|
||||
display-hals += libgenlock libhwcomposer liboverlay libhdmi
|
||||
endif
|
||||
|
||||
@@ -1,188 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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:
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
|
||||
* endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*! @file hw_info_types.h
|
||||
@brief Definitions for types that contain information pertaining to hardware devices.
|
||||
*/
|
||||
|
||||
#ifndef __HW_INFO_TYPES_H__
|
||||
#define __HW_INFO_TYPES_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <core/sde_types.h>
|
||||
|
||||
namespace sde {
|
||||
|
||||
/*! @brief This enumeration holds the possible hardware device types. */
|
||||
enum HWDeviceType {
|
||||
kDevicePrimary,
|
||||
kDeviceHDMI,
|
||||
kDeviceVirtual,
|
||||
kDeviceRotator,
|
||||
kDeviceMax,
|
||||
};
|
||||
|
||||
/*! @brief This structure is a representation of hardware capabilities of the target device display
|
||||
driver.
|
||||
*/
|
||||
struct HWResourceInfo {
|
||||
uint32_t hw_version;
|
||||
uint32_t hw_revision;
|
||||
uint32_t num_dma_pipe;
|
||||
uint32_t num_vig_pipe;
|
||||
uint32_t num_rgb_pipe;
|
||||
uint32_t num_cursor_pipe;
|
||||
uint32_t num_blending_stages;
|
||||
uint32_t num_rotator;
|
||||
uint32_t num_control;
|
||||
uint32_t num_mixer_to_disp;
|
||||
uint32_t smp_total;
|
||||
uint32_t smp_size;
|
||||
uint32_t num_smp_per_pipe;
|
||||
uint32_t max_scale_up;
|
||||
uint32_t max_scale_down;
|
||||
uint64_t max_bandwidth_low;
|
||||
uint64_t max_bandwidth_high;
|
||||
uint32_t max_mixer_width;
|
||||
uint32_t max_pipe_width;
|
||||
uint32_t max_pipe_bw;
|
||||
uint32_t max_sde_clk;
|
||||
float clk_fudge_factor;
|
||||
bool has_bwc;
|
||||
bool has_ubwc;
|
||||
bool has_decimation;
|
||||
bool has_macrotile;
|
||||
bool has_rotator_downscale;
|
||||
bool has_non_scalar_rgb;
|
||||
bool is_src_split;
|
||||
|
||||
HWResourceInfo()
|
||||
: hw_version(0), hw_revision(0), num_dma_pipe(0), num_vig_pipe(0), num_rgb_pipe(0),
|
||||
num_cursor_pipe(0), num_blending_stages(0), num_rotator(0), num_control(0),
|
||||
num_mixer_to_disp(0), smp_total(0), smp_size(0), num_smp_per_pipe(0), max_scale_up(1),
|
||||
max_scale_down(1), max_bandwidth_low(0), max_bandwidth_high(0), max_mixer_width(2048),
|
||||
max_pipe_width(2048), max_pipe_bw(0), max_sde_clk(0), clk_fudge_factor(1.0f), has_bwc(false),
|
||||
has_ubwc(false), has_decimation(false), has_macrotile(false), has_rotator_downscale(false),
|
||||
has_non_scalar_rgb(false), is_src_split(false) { }
|
||||
|
||||
void Reset() { *this = HWResourceInfo(); }
|
||||
};
|
||||
|
||||
/*! @brief This enumeration holds the possible display modes. */
|
||||
enum HWDisplayMode {
|
||||
kModeDefault,
|
||||
kModeVideo,
|
||||
kModeCommand,
|
||||
};
|
||||
|
||||
/*! @brief This enumeration holds the all possible display port types. */
|
||||
enum HWDisplayPort {
|
||||
kPortDefault,
|
||||
kPortDSI,
|
||||
kPortDTv,
|
||||
kPortWriteBack,
|
||||
kPortLVDS,
|
||||
kPortEDP,
|
||||
};
|
||||
|
||||
/*! @brief This enumeration holds the all possible scan types. */
|
||||
enum HWScanSupport {
|
||||
kScanNotSupported,
|
||||
kScanAlwaysOverscanned,
|
||||
kScanAlwaysUnderscanned,
|
||||
kScanBoth,
|
||||
};
|
||||
|
||||
/*! @brief This structure holds the scan support for different timing modes. */
|
||||
struct HWScanInfo {
|
||||
HWScanSupport pt_scan_support; //!< Scan support for preferred timing
|
||||
HWScanSupport it_scan_support; //!< Scan support for digital monitor or industry timings
|
||||
HWScanSupport cea_scan_support; //!< Scan support for CEA resolution timings
|
||||
|
||||
HWScanInfo() : pt_scan_support(kScanNotSupported), it_scan_support(kScanNotSupported),
|
||||
cea_scan_support(kScanNotSupported) { }
|
||||
};
|
||||
|
||||
/*! @brief This structure describes the split configuration of a display panel. */
|
||||
struct HWSplitInfo {
|
||||
uint32_t left_split;
|
||||
uint32_t right_split;
|
||||
bool always_src_split;
|
||||
|
||||
HWSplitInfo() : left_split(0), right_split(0), always_src_split(false) { }
|
||||
|
||||
bool operator !=(const HWSplitInfo &split_info) {
|
||||
return ((left_split != split_info.left_split) || (right_split != split_info.right_split) ||
|
||||
(always_src_split != split_info.always_src_split));
|
||||
}
|
||||
|
||||
bool operator ==(const HWSplitInfo &split_info) {
|
||||
return !(operator !=(split_info));
|
||||
}
|
||||
};
|
||||
|
||||
/*! @brief This structure describes properties of a display panel. */
|
||||
struct HWPanelInfo {
|
||||
HWDisplayPort port; //!< Display port
|
||||
HWDisplayMode mode; //!< Display mode
|
||||
bool partial_update; //!< Partial update feature
|
||||
int left_align; //!< ROI left alignment restriction
|
||||
int width_align; //!< ROI width alignment restriction
|
||||
int top_align;; //!< ROI top alignment restriction
|
||||
int height_align; //!< ROI height alignment restriction
|
||||
int min_roi_width; //!< Min width needed for ROI
|
||||
int min_roi_height; //!< Min height needed for ROI
|
||||
bool needs_roi_merge; //!< Merge ROI's of both the DSI's
|
||||
bool dynamic_fps; //!< Panel Supports dynamic fps
|
||||
uint32_t min_fps; //!< Min fps supported by panel
|
||||
uint32_t max_fps; //!< Max fps supported by panel
|
||||
bool is_primary_panel; //!< Panel is primary display
|
||||
HWSplitInfo split_info; //!< Panel split configuration
|
||||
|
||||
HWPanelInfo() : port(kPortDefault), mode(kModeDefault), partial_update(false), left_align(false),
|
||||
width_align(false), top_align(false), height_align(false), min_roi_width(0), min_roi_height(0),
|
||||
needs_roi_merge(false), dynamic_fps(false), min_fps(0), max_fps(0) { }
|
||||
|
||||
bool operator !=(const HWPanelInfo &panel_info) {
|
||||
return ((port != panel_info.port) || (mode != panel_info.mode) ||
|
||||
(partial_update != panel_info.partial_update) ||
|
||||
(left_align != panel_info.left_align) || (width_align != panel_info.width_align) ||
|
||||
(top_align != panel_info.top_align) || (height_align != panel_info.height_align) ||
|
||||
(min_roi_width != panel_info.min_roi_width) ||
|
||||
(min_roi_height != panel_info.min_roi_height) ||
|
||||
(needs_roi_merge != panel_info.needs_roi_merge) ||
|
||||
(dynamic_fps != panel_info.dynamic_fps) || (min_fps != panel_info.min_fps) ||
|
||||
(max_fps != panel_info.max_fps) || (is_primary_panel != panel_info.is_primary_panel) ||
|
||||
(split_info != panel_info.split_info));
|
||||
}
|
||||
|
||||
bool operator ==(const HWPanelInfo &panel_info) {
|
||||
return !(operator !=(panel_info));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
|
||||
#endif // __HW_INFO_TYPES_H__
|
||||
|
||||
@@ -1,201 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 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:
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
|
||||
* endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*! @file strategy_interface.h
|
||||
@brief Interface file for strategy manager which will be used by display core to select a
|
||||
composition strategy for a frame to be displayed on target.
|
||||
*/
|
||||
#ifndef __STRATEGY_INTERFACE_H__
|
||||
#define __STRATEGY_INTERFACE_H__
|
||||
|
||||
#include <core/sde_types.h>
|
||||
#include <core/display_interface.h>
|
||||
#include "hw_info_types.h"
|
||||
|
||||
namespace sde {
|
||||
|
||||
/*! @brief Strategy library name
|
||||
|
||||
@details This macro defines name for the composition strategy library. This macro shall be used
|
||||
to load library using dlopen().
|
||||
|
||||
@sa CreateStrategyInterface
|
||||
@sa DestoryStrategyInterface
|
||||
*/
|
||||
#define STRATEGY_LIBRARY_NAME "libsdestrategy.so"
|
||||
|
||||
/*! @brief Function name to create composer strategy interface
|
||||
|
||||
@details This macro defines function name for CreateStrategyInterface() which is implemented in
|
||||
the composition strategy library. This macro shall be used to specify name of the function in
|
||||
dlsym().
|
||||
|
||||
@sa CreateStrategyInterface
|
||||
*/
|
||||
#define CREATE_STRATEGY_INTERFACE_NAME "CreateStrategyInterface"
|
||||
|
||||
/*! @brief Function name to destroy composer strategy interface
|
||||
|
||||
@details This macro defines function name for DestroyStrategyInterface() which is implemented in
|
||||
the composition strategy library. This macro shall be used to specify name of the function in
|
||||
dlsym().
|
||||
|
||||
@sa DestroyStrategyInterface
|
||||
*/
|
||||
#define DESTROY_STRATEGY_INTERFACE_NAME "DestroyStrategyInterface"
|
||||
|
||||
/*! @brief Strategy interface version.
|
||||
|
||||
@details Strategy interface is version tagged to maintain backward compatibility. This version is
|
||||
supplied as a default argument during strategy library initialization.
|
||||
|
||||
Client may use an older version of interfaces and link to a higher version of strategy library,
|
||||
but vice versa is not allowed.
|
||||
|
||||
@sa CreateStrategyInterface
|
||||
*/
|
||||
#define STRATEGY_REVISION_MAJOR (1)
|
||||
#define STRATEGY_REVISION_MINOR (0)
|
||||
|
||||
#define STRATEGY_VERSION_TAG ((uint16_t) ((STRATEGY_REVISION_MAJOR << 8) | STRATEGY_REVISION_MINOR))
|
||||
|
||||
class StrategyInterface;
|
||||
|
||||
/*! @brief Function to create composer strategy interface.
|
||||
|
||||
@details This function is used to create StrategyInterface object which resides in the composer
|
||||
strategy library loaded at runtime.
|
||||
|
||||
@param[in] version \link STRATEGY_VERSION_TAG \endlink
|
||||
@param[in] type \link DisplayType \endlink
|
||||
@param[in] hw_resource_info \link HWResourceInfo \endlink
|
||||
@param[in] hw_panel_info \link HWPanelInfo \endlink
|
||||
@param[out] interface \link StrategyInterface \endlink
|
||||
|
||||
@return \link DisplayError \endlink
|
||||
*/
|
||||
typedef DisplayError (*CreateStrategyInterface)(uint16_t version, DisplayType type,
|
||||
const HWResourceInfo &hw_resource_info, const HWPanelInfo &hw_panel_info,
|
||||
StrategyInterface **interface);
|
||||
|
||||
/*! @brief Function to destroy composer strategy interface.
|
||||
|
||||
@details This function is used to destroy StrategyInterface object.
|
||||
|
||||
@param[in] interface \link StrategyInterface \endlink
|
||||
|
||||
@return \link DisplayError \endlink
|
||||
*/
|
||||
typedef DisplayError (*DestroyStrategyInterface)(StrategyInterface *interface);
|
||||
|
||||
/*! @brief Maximum number of layers that can be handled by hardware in a given layer stack.
|
||||
*/
|
||||
const int kMaxSDELayers = 16;
|
||||
|
||||
/*! @brief This structure defines constraints and display properties that shall be considered for
|
||||
deciding a composition strategy.
|
||||
|
||||
@sa GetNextStrategy
|
||||
*/
|
||||
struct StrategyConstraints {
|
||||
bool safe_mode; //!< In this mode, strategy manager chooses the composition strategy
|
||||
//!< that requires minimum number of pipe for the current frame. i.e.,
|
||||
//!< video only composition, secure only composition or GPU composition
|
||||
|
||||
uint32_t max_layers; //!< Maximum number of layers that shall be programmed on hardware for the
|
||||
//!< given layer stack.
|
||||
|
||||
StrategyConstraints() : safe_mode(false), max_layers(kMaxSDELayers) { }
|
||||
};
|
||||
|
||||
/*! @brief This structure encapsulates information about the input layer stack and the layers which
|
||||
shall be programmed on hardware.
|
||||
|
||||
@sa Start
|
||||
*/
|
||||
struct HWLayersInfo {
|
||||
LayerStack *stack; //!< Input layer stack. Set by the caller.
|
||||
|
||||
uint32_t index[kMaxSDELayers];
|
||||
//!< Indexes of the layers from the layer stack which need to be
|
||||
//!< programmed on hardware.
|
||||
|
||||
uint32_t count; //!< Total number of layers which need to be set on hardware.
|
||||
|
||||
LayerRect left_partial_update;
|
||||
//!< Left ROI.
|
||||
|
||||
LayerRect right_partial_update;
|
||||
//!< Right ROI.
|
||||
|
||||
|
||||
HWLayersInfo() : stack(NULL), count(0) { }
|
||||
};
|
||||
|
||||
/*! @brief Strategy interface.
|
||||
|
||||
@details This class defines Strategy interface. It contains methods which client shall use to
|
||||
determine which strategy to be used for layer composition. This interface is created during
|
||||
display device creation and remains valid until destroyed.
|
||||
*/
|
||||
|
||||
class StrategyInterface {
|
||||
public:
|
||||
/*! @brief Method to indicate start of a new strategy selection iteration for a layer stack.
|
||||
|
||||
@details Client shall call this method at beginning of each draw cycle before iterating
|
||||
through strategy selection. Strategy interface implementation uses this method to do
|
||||
preprocessing for a given layer stack.
|
||||
|
||||
@param[in] layers_info \link HWLayersInfo \endlink
|
||||
@param[out] max_attempts Maximum calls to \link GetNextStrategy \endlink
|
||||
|
||||
@return \link DisplayError \endlink
|
||||
*/
|
||||
virtual DisplayError Start(HWLayersInfo *hw_layers_info, uint32_t *max_attempts) = 0;
|
||||
|
||||
|
||||
/*! @brief Method to get strategy for a layer stack. Caller can loop through this method to try
|
||||
get all applicable strategies.
|
||||
|
||||
@param[in] constraints \link StrategyConstraints \endlink
|
||||
|
||||
@return \link DisplayError \endlink
|
||||
*/
|
||||
virtual DisplayError GetNextStrategy(StrategyConstraints *constraints) = 0;
|
||||
|
||||
/*! @brief Method to indicate end of a strategy selection cycle.
|
||||
|
||||
@return \link DisplayError \endlink
|
||||
*/
|
||||
virtual DisplayError Stop() = 0;
|
||||
|
||||
protected:
|
||||
virtual ~StrategyInterface() { }
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
|
||||
#endif // __STRATEGY_INTERFACE_H__
|
||||
|
||||
@@ -1,354 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <utils/debug.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
#include "hw_rotator.h"
|
||||
|
||||
#define __CLASS__ "HWRotator"
|
||||
|
||||
namespace sde {
|
||||
|
||||
DisplayError HWRotatorInterface::Create(BufferSyncHandler *buffer_sync_handler,
|
||||
HWRotatorInterface **intf) {
|
||||
DisplayError error = kErrorNone;
|
||||
HWRotator *hw_rotator = NULL;
|
||||
|
||||
hw_rotator = new HWRotator(buffer_sync_handler);
|
||||
if (!hw_rotator) {
|
||||
error = kErrorMemory;
|
||||
} else {
|
||||
*intf = hw_rotator;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
DisplayError HWRotatorInterface::Destroy(HWRotatorInterface *intf) {
|
||||
delete intf;
|
||||
intf = NULL;
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
HWRotator::HWRotator(BufferSyncHandler *buffer_sync_handler) : HWDevice(buffer_sync_handler) {
|
||||
HWDevice::device_type_ = kDeviceRotator;
|
||||
HWDevice::device_name_ = "Rotator Device";
|
||||
}
|
||||
|
||||
DisplayError HWRotator::Open() {
|
||||
DisplayError error = kErrorNone;
|
||||
|
||||
char device_name[64] = {0};
|
||||
snprintf(device_name, sizeof(device_name), "%s", "/dev/mdss_rotator");
|
||||
|
||||
HWDevice::device_fd_ = open_(device_name, O_RDWR);
|
||||
if (HWDevice::device_fd_ < 0) {
|
||||
DLOGE("open %s failed err = %d errstr = %s", device_name, errno, strerror(errno));
|
||||
return kErrorResources;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
DisplayError HWRotator::Close() {
|
||||
if (HWDevice::device_fd_ > 0) {
|
||||
close_(HWDevice::device_fd_);
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError HWRotator::OpenSession(HWRotatorSession *hw_rotator_session) {
|
||||
uint32_t frame_rate = hw_rotator_session->hw_session_config.frame_rate;
|
||||
LayerBufferFormat src_format = hw_rotator_session->hw_session_config.src_format;
|
||||
LayerBufferFormat dst_format = hw_rotator_session->hw_session_config.dst_format;
|
||||
bool rot90 = (hw_rotator_session->transform.rotation == 90.0f);
|
||||
|
||||
for (uint32_t i = 0; i < hw_rotator_session->hw_block_count; i++) {
|
||||
HWRotateInfo *hw_rotate_info = &hw_rotator_session->hw_rotate_info[i];
|
||||
|
||||
if (!hw_rotate_info->valid) {
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32_t src_width = UINT32(hw_rotate_info->src_roi.right - hw_rotate_info->src_roi.left);
|
||||
uint32_t src_height =
|
||||
UINT32(hw_rotate_info->src_roi.bottom - hw_rotate_info->src_roi.top);
|
||||
|
||||
uint32_t dst_width = UINT32(hw_rotate_info->dst_roi.right - hw_rotate_info->dst_roi.left);
|
||||
uint32_t dst_height =
|
||||
UINT32(hw_rotate_info->dst_roi.bottom - hw_rotate_info->dst_roi.top);
|
||||
|
||||
STRUCT_VAR(mdp_rotation_config, mdp_rot_config);
|
||||
|
||||
mdp_rot_config.version = MDP_ROTATION_REQUEST_VERSION_1_0;
|
||||
mdp_rot_config.input.width = src_width;
|
||||
mdp_rot_config.input.height = src_height;
|
||||
SetFormat(src_format, &mdp_rot_config.input.format);
|
||||
mdp_rot_config.output.width = dst_width;
|
||||
mdp_rot_config.output.height = dst_height;
|
||||
SetFormat(dst_format, &mdp_rot_config.output.format);
|
||||
mdp_rot_config.frame_rate = frame_rate;
|
||||
|
||||
if (rot90) {
|
||||
mdp_rot_config.flags |= MDP_ROTATION_90;
|
||||
}
|
||||
|
||||
if (ioctl_(device_fd_, MDSS_ROTATION_OPEN, &mdp_rot_config) < 0) {
|
||||
IOCTL_LOGE(MDSS_ROTATION_OPEN, device_type_);
|
||||
return kErrorHardware;
|
||||
}
|
||||
|
||||
hw_rotate_info->rotate_id = mdp_rot_config.session_id;
|
||||
|
||||
DLOGV_IF(kTagDriverConfig, "session_id %d", hw_rotate_info->rotate_id);
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError HWRotator::CloseSession(HWRotatorSession *hw_rotator_session) {
|
||||
for (uint32_t i = 0; i < hw_rotator_session->hw_block_count; i++) {
|
||||
HWRotateInfo *hw_rotate_info = &hw_rotator_session->hw_rotate_info[i];
|
||||
|
||||
if (!hw_rotate_info->valid) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ioctl_(device_fd_, MDSS_ROTATION_CLOSE, UINT32(hw_rotate_info->rotate_id)) < 0) {
|
||||
IOCTL_LOGE(MDSS_ROTATION_CLOSE, device_type_);
|
||||
return kErrorHardware;
|
||||
}
|
||||
|
||||
DLOGV_IF(kTagDriverConfig, "session_id %d", hw_rotate_info->rotate_id);
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
void HWRotator::SetCtrlParams(HWLayers *hw_layers) {
|
||||
DLOGV_IF(kTagDriverConfig, "************************* %s Validate Input ************************",
|
||||
HWDevice::device_name_);
|
||||
|
||||
ResetParams();
|
||||
|
||||
HWLayersInfo &hw_layer_info = hw_layers->info;
|
||||
|
||||
uint32_t &rot_count = mdp_rot_request_.count;
|
||||
for (uint32_t i = 0; i < hw_layer_info.count; i++) {
|
||||
Layer& layer = hw_layer_info.stack->layers[hw_layer_info.index[i]];
|
||||
HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
|
||||
bool rot90 = (layer.transform.rotation == 90.0f);
|
||||
|
||||
for (uint32_t count = 0; count < hw_rotator_session->hw_block_count; count++) {
|
||||
HWRotateInfo *hw_rotate_info = &hw_rotator_session->hw_rotate_info[count];
|
||||
|
||||
if (hw_rotate_info->valid) {
|
||||
mdp_rotation_item *mdp_rot_item = &mdp_rot_request_.list[rot_count];
|
||||
|
||||
SetMDPFlags(layer, &mdp_rot_item->flags);
|
||||
|
||||
SetRect(hw_rotate_info->src_roi, &mdp_rot_item->src_rect);
|
||||
SetRect(hw_rotate_info->dst_roi, &mdp_rot_item->dst_rect);
|
||||
|
||||
// TODO(user): Need to assign the writeback id and pipe id returned from resource manager.
|
||||
mdp_rot_item->pipe_idx = 0;
|
||||
mdp_rot_item->wb_idx = 0;
|
||||
|
||||
mdp_rot_item->input.width = layer.input_buffer->width;
|
||||
mdp_rot_item->input.height = layer.input_buffer->height;
|
||||
SetFormat(layer.input_buffer->format, &mdp_rot_item->input.format);
|
||||
|
||||
mdp_rot_item->output.width = hw_rotator_session->output_buffer.width;
|
||||
mdp_rot_item->output.height = hw_rotator_session->output_buffer.height;
|
||||
SetFormat(hw_rotator_session->output_buffer.format, &mdp_rot_item->output.format);
|
||||
|
||||
mdp_rot_item->session_id = hw_rotate_info->rotate_id;
|
||||
|
||||
rot_count++;
|
||||
|
||||
DLOGV_IF(kTagDriverConfig, "******************** Layer[%d] %s rotate ********************",
|
||||
i, count ? "Right" : "Left");
|
||||
DLOGV_IF(kTagDriverConfig, "in_w %d, in_h %d, in_f %d,\t out_w %d, out_h %d, out_f %d",
|
||||
mdp_rot_item->input.width, mdp_rot_item->input.height, mdp_rot_item->input.format,
|
||||
mdp_rot_item->output.width, mdp_rot_item->output.height,
|
||||
mdp_rot_item->output.format);
|
||||
DLOGV_IF(kTagDriverConfig, "pipe_id 0x%x, wb_id %d, rot_flag 0x%x, session_id %d",
|
||||
mdp_rot_item->pipe_idx, mdp_rot_item->wb_idx, mdp_rot_item->flags,
|
||||
mdp_rot_item->session_id);
|
||||
DLOGV_IF(kTagDriverConfig, "src_rect [%d, %d, %d, %d]", mdp_rot_item->src_rect.x,
|
||||
mdp_rot_item->src_rect.y, mdp_rot_item->src_rect.w, mdp_rot_item->src_rect.h);
|
||||
DLOGV_IF(kTagDriverConfig, "dst_rect [%d, %d, %d, %d]", mdp_rot_item->dst_rect.x,
|
||||
mdp_rot_item->dst_rect.y, mdp_rot_item->dst_rect.w, mdp_rot_item->dst_rect.h);
|
||||
DLOGV_IF(kTagDriverConfig, "*************************************************************");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HWRotator::SetBufferParams(HWLayers *hw_layers) {
|
||||
HWLayersInfo &hw_layer_info = hw_layers->info;
|
||||
uint32_t rot_count = 0;
|
||||
|
||||
DLOGV_IF(kTagDriverConfig, "************************* %s Commit Input **************************",
|
||||
HWDevice::device_name_);
|
||||
DLOGV_IF(kTagDriverConfig, "Rotate layer count is %d", mdp_rot_request_.count);
|
||||
|
||||
for (uint32_t i = 0; i < hw_layer_info.count; i++) {
|
||||
Layer& layer = hw_layer_info.stack->layers[hw_layer_info.index[i]];
|
||||
HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
|
||||
|
||||
for (uint32_t count = 0; count < hw_rotator_session->hw_block_count; count++) {
|
||||
HWRotateInfo *hw_rotate_info = &hw_rotator_session->hw_rotate_info[count];
|
||||
|
||||
if (hw_rotate_info->valid) {
|
||||
mdp_rotation_item *mdp_rot_item = &mdp_rot_request_.list[rot_count];
|
||||
|
||||
mdp_rot_item->input.planes[0].fd = layer.input_buffer->planes[0].fd;
|
||||
mdp_rot_item->input.planes[0].offset = layer.input_buffer->planes[0].offset;
|
||||
SetStride(device_type_, layer.input_buffer->format, layer.input_buffer->width,
|
||||
&mdp_rot_item->input.planes[0].stride);
|
||||
mdp_rot_item->input.plane_count = 1;
|
||||
mdp_rot_item->input.fence = layer.input_buffer->acquire_fence_fd;
|
||||
|
||||
mdp_rot_item->output.planes[0].fd = hw_rotator_session->output_buffer.planes[0].fd;
|
||||
mdp_rot_item->output.planes[0].offset = hw_rotator_session->output_buffer.planes[0].offset;
|
||||
SetStride(device_type_, hw_rotator_session->output_buffer.format,
|
||||
hw_rotator_session->output_buffer.planes[0].stride,
|
||||
&mdp_rot_item->output.planes[0].stride);
|
||||
mdp_rot_item->output.plane_count = 1;
|
||||
mdp_rot_item->output.fence = -1;
|
||||
|
||||
rot_count++;
|
||||
|
||||
DLOGV_IF(kTagDriverConfig, "******************** Layer[%d] %s rotate ********************",
|
||||
i, count ? "Right" : "Left");
|
||||
DLOGV_IF(kTagDriverConfig, "in_buf_fd %d, in_buf_offset %d, in_stride %d, " \
|
||||
"in_plane_count %d, in_fence %d", mdp_rot_item->input.planes[0].fd,
|
||||
mdp_rot_item->input.planes[0].offset, mdp_rot_item->input.planes[0].stride,
|
||||
mdp_rot_item->input.plane_count, mdp_rot_item->input.fence);
|
||||
DLOGV_IF(kTagDriverConfig, "out_fd %d, out_offset %d, out_stride %d, out_plane_count %d, " \
|
||||
"out_fence %d", mdp_rot_item->output.planes[0].fd,
|
||||
mdp_rot_item->output.planes[0].offset, mdp_rot_item->output.planes[0].stride,
|
||||
mdp_rot_item->output.plane_count, mdp_rot_item->output.fence);
|
||||
DLOGV_IF(kTagDriverConfig, "*************************************************************");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HWRotator::SetMDPFlags(const Layer &layer, uint32_t *mdp_flags) {
|
||||
LayerTransform transform = layer.transform;
|
||||
bool rot90 = (transform.rotation == 90.0f);
|
||||
|
||||
if (rot90) {
|
||||
*mdp_flags |= MDP_ROTATION_90;
|
||||
}
|
||||
|
||||
if (transform.flip_horizontal) {
|
||||
*mdp_flags |= MDP_ROTATION_FLIP_LR;
|
||||
}
|
||||
|
||||
if (transform.flip_vertical) {
|
||||
*mdp_flags |= MDP_ROTATION_FLIP_UD;
|
||||
}
|
||||
|
||||
if (layer.input_buffer->flags.secure) {
|
||||
*mdp_flags |= MDP_ROTATION_SECURE;
|
||||
}
|
||||
}
|
||||
|
||||
DisplayError HWRotator::Validate(HWLayers *hw_layers) {
|
||||
SetCtrlParams(hw_layers);
|
||||
|
||||
mdp_rot_request_.flags = MDSS_ROTATION_REQUEST_VALIDATE;
|
||||
if (ioctl_(HWDevice::device_fd_, MDSS_ROTATION_REQUEST, &mdp_rot_request_) < 0) {
|
||||
IOCTL_LOGE(MDSS_ROTATION_REQUEST, HWDevice::device_type_);
|
||||
return kErrorHardware;
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError HWRotator::Commit(HWLayers *hw_layers) {
|
||||
HWLayersInfo &hw_layer_info = hw_layers->info;
|
||||
uint32_t rot_count = 0;
|
||||
|
||||
SetCtrlParams(hw_layers);
|
||||
|
||||
SetBufferParams(hw_layers);
|
||||
|
||||
mdp_rot_request_.flags &= ~MDSS_ROTATION_REQUEST_VALIDATE;
|
||||
if (ioctl_(HWDevice::device_fd_, MDSS_ROTATION_REQUEST, &mdp_rot_request_) < 0) {
|
||||
IOCTL_LOGE(MDSS_ROTATION_REQUEST, HWDevice::device_type_);
|
||||
return kErrorHardware;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < hw_layer_info.count; i++) {
|
||||
Layer& layer = hw_layer_info.stack->layers[hw_layer_info.index[i]];
|
||||
HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
|
||||
|
||||
layer.input_buffer->release_fence_fd = -1;
|
||||
|
||||
for (uint32_t count = 0; count < hw_rotator_session->hw_block_count; count++) {
|
||||
HWRotateInfo *hw_rotate_info = &hw_rotator_session->hw_rotate_info[count];
|
||||
|
||||
if (hw_rotate_info->valid) {
|
||||
mdp_rotation_item *mdp_rot_item = &mdp_rot_request_.list[rot_count];
|
||||
|
||||
HWDevice::SyncMerge(layer.input_buffer->release_fence_fd, dup(mdp_rot_item->output.fence),
|
||||
&layer.input_buffer->release_fence_fd);
|
||||
|
||||
hw_rotator_session->output_buffer.acquire_fence_fd = dup(mdp_rot_item->output.fence);
|
||||
|
||||
close_(mdp_rot_item->output.fence);
|
||||
rot_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
void HWRotator::ResetParams() {
|
||||
memset(&mdp_rot_request_, 0, sizeof(mdp_rot_request_));
|
||||
memset(&mdp_rot_layers_, 0, sizeof(mdp_rot_layers_));
|
||||
|
||||
for (uint32_t i = 0; i < kMaxSDELayers * 2; i++) {
|
||||
mdp_rot_layers_[i].input.fence = -1;
|
||||
mdp_rot_layers_[i].output.fence = -1;
|
||||
}
|
||||
|
||||
mdp_rot_request_.version = MDP_ROTATION_REQUEST_VERSION_1_0;
|
||||
mdp_rot_request_.list = mdp_rot_layers_;
|
||||
}
|
||||
|
||||
} // namespace sde
|
||||
|
||||
@@ -1,229 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 - 2015, 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:
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
|
||||
* endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __HW_INTERFACE_H__
|
||||
#define __HW_INTERFACE_H__
|
||||
|
||||
#include <core/display_interface.h>
|
||||
#include <private/strategy_interface.h>
|
||||
#include <private/hw_info_types.h>
|
||||
#include <utils/constants.h>
|
||||
#include <core/buffer_allocator.h>
|
||||
#include <core/buffer_sync_handler.h>
|
||||
|
||||
namespace sde {
|
||||
|
||||
enum HWBlockType {
|
||||
kHWPrimary,
|
||||
kHWHDMI,
|
||||
kHWWriteback0,
|
||||
kHWWriteback1,
|
||||
kHWWriteback2,
|
||||
kHWBlockMax
|
||||
};
|
||||
|
||||
struct HWSessionConfig {
|
||||
uint32_t src_width;
|
||||
uint32_t src_height;
|
||||
LayerBufferFormat src_format;
|
||||
uint32_t dst_width;
|
||||
uint32_t dst_height;
|
||||
LayerBufferFormat dst_format;
|
||||
uint32_t buffer_count;
|
||||
bool secure;
|
||||
bool cache;
|
||||
uint32_t frame_rate;
|
||||
|
||||
HWSessionConfig()
|
||||
: src_width(0), src_height(0), src_format(kFormatInvalid), dst_width(0), dst_height(0),
|
||||
dst_format(kFormatInvalid), buffer_count(0), secure(false), cache(false), frame_rate(0) { }
|
||||
|
||||
bool operator != (const HWSessionConfig &input_config) const {
|
||||
if ((src_width != input_config.src_width) || (src_height != input_config.src_height) ||
|
||||
(src_format != input_config.src_format) || (dst_width != input_config.dst_width) ||
|
||||
(dst_height != input_config.dst_height) || (dst_format != input_config.dst_format) ||
|
||||
(buffer_count != input_config.buffer_count) || (secure != input_config.secure) ||
|
||||
(cache != input_config.cache) || (frame_rate != input_config.frame_rate)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator == (const HWSessionConfig &input_config) const {
|
||||
return !(operator != (input_config));
|
||||
}
|
||||
};
|
||||
|
||||
struct HWRotateInfo {
|
||||
uint32_t pipe_id;
|
||||
LayerRect src_roi;
|
||||
LayerRect dst_roi;
|
||||
HWBlockType writeback_id;
|
||||
bool valid;
|
||||
int rotate_id;
|
||||
|
||||
HWRotateInfo()
|
||||
: pipe_id(0), writeback_id(kHWWriteback0), valid(false), rotate_id(-1) { }
|
||||
|
||||
void Reset() { *this = HWRotateInfo(); }
|
||||
};
|
||||
|
||||
struct HWRotatorSession {
|
||||
HWRotateInfo hw_rotate_info[kMaxRotatePerLayer];
|
||||
uint32_t hw_block_count; // number of rotator hw blocks used by rotator session
|
||||
float downscale_ratio;
|
||||
LayerTransform transform;
|
||||
HWSessionConfig hw_session_config;
|
||||
LayerBuffer output_buffer;
|
||||
int session_id;
|
||||
|
||||
HWRotatorSession() : hw_block_count(0), downscale_ratio(1.0f), session_id(-1) { }
|
||||
};
|
||||
|
||||
struct HWPixelExtension {
|
||||
// Number of pixels extension in left, right, top and bottom directions for all color components.
|
||||
// This pixel value for each color component should be sum of fetch and repeat pixels.
|
||||
int extension;
|
||||
|
||||
// Number of pixels need to be overfetched in left, right, top and bottom directions from source
|
||||
// image for scaling.
|
||||
int overfetch;
|
||||
|
||||
// Number of pixels need to be repeated in left, right, top and bottom directions for scaling.
|
||||
int repeat;
|
||||
};
|
||||
|
||||
struct HWPlane {
|
||||
int init_phase_x;
|
||||
int phase_step_x;
|
||||
int init_phase_y;
|
||||
int phase_step_y;
|
||||
HWPixelExtension left;
|
||||
HWPixelExtension top;
|
||||
HWPixelExtension right;
|
||||
HWPixelExtension bottom;
|
||||
uint32_t roi_width;
|
||||
};
|
||||
|
||||
struct ScaleData {
|
||||
uint8_t enable_pixel_ext;
|
||||
uint32_t src_width;
|
||||
uint32_t src_height;
|
||||
HWPlane plane[4];
|
||||
};
|
||||
|
||||
struct HWPipeInfo {
|
||||
uint32_t pipe_id;
|
||||
LayerRect src_roi;
|
||||
LayerRect dst_roi;
|
||||
uint8_t horizontal_decimation;
|
||||
uint8_t vertical_decimation;
|
||||
ScaleData scale_data;
|
||||
bool valid;
|
||||
uint32_t z_order;
|
||||
|
||||
HWPipeInfo()
|
||||
: pipe_id(0), horizontal_decimation(0), vertical_decimation(0), valid(false), z_order(0) { }
|
||||
|
||||
void Reset() { *this = HWPipeInfo(); }
|
||||
};
|
||||
|
||||
struct HWLayerConfig {
|
||||
bool use_non_dma_pipe; // set by client
|
||||
HWPipeInfo left_pipe; // pipe for left side of output
|
||||
HWPipeInfo right_pipe; // pipe for right side of output
|
||||
HWRotatorSession hw_rotator_session;
|
||||
|
||||
HWLayerConfig() : use_non_dma_pipe(false) { }
|
||||
|
||||
void Reset() { *this = HWLayerConfig(); }
|
||||
};
|
||||
|
||||
struct HWLayers {
|
||||
HWLayersInfo info;
|
||||
HWLayerConfig config[kMaxSDELayers];
|
||||
};
|
||||
|
||||
struct HWDisplayAttributes : DisplayConfigVariableInfo {
|
||||
bool is_device_split;
|
||||
uint32_t split_left;
|
||||
bool always_src_split;
|
||||
|
||||
HWDisplayAttributes() : is_device_split(false), split_left(0), always_src_split(false) { }
|
||||
|
||||
void Reset() { *this = HWDisplayAttributes(); }
|
||||
|
||||
bool operator !=(const HWDisplayAttributes &attributes) {
|
||||
return ((is_device_split != attributes.is_device_split) ||
|
||||
(split_left != attributes.split_left) ||
|
||||
(always_src_split != attributes.always_src_split) ||
|
||||
(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_total != attributes.v_total));
|
||||
}
|
||||
|
||||
bool operator ==(const HWDisplayAttributes &attributes) {
|
||||
return !(operator !=(attributes));
|
||||
}
|
||||
};
|
||||
|
||||
// HWEventHandler - Implemented in DisplayBase and HWInterface implementation
|
||||
class HWEventHandler {
|
||||
public:
|
||||
virtual DisplayError VSync(int64_t timestamp) = 0;
|
||||
virtual DisplayError Blank(bool blank) = 0;
|
||||
virtual void IdleTimeout() = 0;
|
||||
virtual void ThermalEvent(int64_t thermal_level) = 0;
|
||||
protected:
|
||||
virtual ~HWEventHandler() { }
|
||||
};
|
||||
|
||||
class HWInterface {
|
||||
public:
|
||||
virtual DisplayError Open(HWEventHandler *eventhandler) = 0;
|
||||
virtual DisplayError Close() = 0;
|
||||
virtual DisplayError GetNumDisplayAttributes(uint32_t *count) = 0;
|
||||
virtual DisplayError GetDisplayAttributes(HWDisplayAttributes *display_attributes,
|
||||
uint32_t index) = 0;
|
||||
virtual DisplayError GetHWPanelInfo(HWPanelInfo *panel_info) = 0;
|
||||
virtual DisplayError SetDisplayAttributes(uint32_t index) = 0;
|
||||
virtual DisplayError GetConfigIndex(uint32_t mode, uint32_t *index) = 0;
|
||||
virtual DisplayError PowerOn() = 0;
|
||||
virtual DisplayError PowerOff() = 0;
|
||||
virtual DisplayError Doze() = 0;
|
||||
virtual DisplayError DozeSuspend() = 0;
|
||||
virtual DisplayError Standby() = 0;
|
||||
virtual DisplayError Validate(HWLayers *hw_layers) = 0;
|
||||
virtual DisplayError Commit(HWLayers *hw_layers) = 0;
|
||||
virtual DisplayError Flush() = 0;
|
||||
|
||||
protected:
|
||||
virtual ~HWInterface() { }
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
|
||||
#endif // __HW_INTERFACE_H__
|
||||
|
||||
@@ -1,825 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 - 2015, 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:
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
|
||||
* endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <utils/constants.h>
|
||||
#include <utils/debug.h>
|
||||
#include <utils/rect.h>
|
||||
|
||||
#include "res_manager.h"
|
||||
|
||||
#define __CLASS__ "ResManager"
|
||||
|
||||
namespace sde {
|
||||
|
||||
static void GetAlignFactor(const LayerBufferFormat &format, uint32_t *align_x, uint32_t *align_y) {
|
||||
*align_x = 1;
|
||||
*align_y = 1;
|
||||
if (!IS_RGB_FORMAT(format)) {
|
||||
*align_x = 2;
|
||||
*align_y = 2;
|
||||
}
|
||||
}
|
||||
|
||||
void ResManager::RotationConfig(const Layer &layer, const float &downscale, LayerRect *src_rect,
|
||||
struct HWLayerConfig *layer_config, uint32_t *rotate_count) {
|
||||
HWRotatorSession *hw_rotator_session = &layer_config->hw_rotator_session;
|
||||
HWRotateInfo *hw_rotate_info = &hw_rotator_session->hw_rotate_info[0];
|
||||
float src_width = src_rect->right - src_rect->left;
|
||||
float src_height = src_rect->bottom - src_rect->top;
|
||||
bool rot90 = IsRotationNeeded(layer.transform.rotation);
|
||||
bool is_opaque = (layer.blending == kBlendingOpaque);
|
||||
LayerRect dst_rect;
|
||||
// Rotate output is a temp buffer, always output to the top left corner for saving memory
|
||||
dst_rect.top = 0.0f;
|
||||
dst_rect.left = 0.0f;
|
||||
|
||||
hw_rotator_session->downscale_ratio = downscale;
|
||||
uint32_t align_x, align_y;
|
||||
GetAlignFactor(layer.input_buffer->format, &align_x, &align_y);
|
||||
|
||||
// downscale when doing rotation
|
||||
if (rot90) {
|
||||
if (downscale > 1.0f) {
|
||||
src_height = ROUND_UP_ALIGN_DOWN(src_height, downscale * FLOAT(align_x));
|
||||
src_rect->bottom = src_rect->top + src_height;
|
||||
src_width = ROUND_UP_ALIGN_DOWN(src_width, downscale * FLOAT(align_y));
|
||||
src_rect->right = src_rect->left + src_width;
|
||||
}
|
||||
dst_rect.right = src_height / downscale;
|
||||
dst_rect.bottom = src_width / downscale;
|
||||
} else {
|
||||
if (downscale > 1.0f) {
|
||||
src_width = ROUND_UP_ALIGN_DOWN(src_width, downscale * FLOAT(align_x));
|
||||
src_rect->right = src_rect->left + src_width;
|
||||
src_height = ROUND_UP_ALIGN_DOWN(src_height, downscale * FLOAT(align_y));
|
||||
src_rect->bottom = src_rect->top + src_height;
|
||||
}
|
||||
dst_rect.right = src_width / downscale;
|
||||
dst_rect.bottom = src_height / downscale;
|
||||
}
|
||||
|
||||
hw_rotate_info->src_roi = *src_rect;
|
||||
hw_rotate_info->valid = true;
|
||||
hw_rotate_info->dst_roi = dst_rect;
|
||||
|
||||
LayerBufferFormat *output_format = &hw_rotator_session->output_buffer.format;
|
||||
SetRotatorOutputFormat(layer.input_buffer->format, is_opaque, rot90, (downscale > 1.0f),
|
||||
output_format);
|
||||
|
||||
*src_rect = dst_rect;
|
||||
hw_rotator_session->hw_block_count = 1;
|
||||
hw_rotator_session->transform = layer.transform;
|
||||
(*rotate_count)++;
|
||||
}
|
||||
|
||||
DisplayError ResManager::SrcSplitConfig(DisplayResourceContext *display_resource_ctx,
|
||||
const LayerTransform &transform, const LayerRect &src_rect,
|
||||
const LayerRect &dst_rect, HWLayerConfig *layer_config,
|
||||
uint32_t align_x) {
|
||||
HWDisplayAttributes &display_attributes = display_resource_ctx->display_attributes;
|
||||
HWPipeInfo *left_pipe = &layer_config->left_pipe;
|
||||
HWPipeInfo *right_pipe = &layer_config->right_pipe;
|
||||
float src_width = src_rect.right - src_rect.left;
|
||||
float dst_width = dst_rect.right - dst_rect.left;
|
||||
float src_height = src_rect.bottom - src_rect.top;
|
||||
float dst_height = dst_rect.bottom - dst_rect.top;
|
||||
float left_mixer_width = FLOAT(display_attributes.split_left);
|
||||
|
||||
uint8_t decimation = 0;
|
||||
if (CalculateDecimation((src_height / dst_height), &decimation) != kErrorNone) {
|
||||
return kErrorNotSupported;
|
||||
}
|
||||
// Adjust source height to consider decimation
|
||||
src_height /= powf(2.0f, decimation);
|
||||
|
||||
// No need to include common factors in clock calculation of pipe & mixer
|
||||
float pipe_clock = MAX(dst_width, (dst_width * src_height / dst_height));
|
||||
float mixer_clock = left_mixer_width;
|
||||
|
||||
// Layer cannot qualify for SrcSplit if source or destination width exceeds max pipe width.
|
||||
// For perf/power optimization, even if "always_src_split" is enabled, use 2 pipes only if:
|
||||
// 1. Source width is greater than split_left (left_mixer_width)
|
||||
// 2. Pipe clock exceeds the mixer clock
|
||||
if ((src_width > hw_res_info_.max_pipe_width) || (dst_width > hw_res_info_.max_pipe_width) ||
|
||||
(display_resource_ctx->display_attributes.always_src_split &&
|
||||
((src_width > left_mixer_width) || (pipe_clock > mixer_clock)))) {
|
||||
SplitRect(transform.flip_horizontal, src_rect, dst_rect, &left_pipe->src_roi,
|
||||
&left_pipe->dst_roi, &right_pipe->src_roi, &right_pipe->dst_roi, align_x);
|
||||
left_pipe->valid = true;
|
||||
right_pipe->valid = true;
|
||||
} else {
|
||||
left_pipe->src_roi = src_rect;
|
||||
left_pipe->dst_roi = dst_rect;
|
||||
left_pipe->valid = true;
|
||||
right_pipe->Reset();
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError ResManager::DisplaySplitConfig(DisplayResourceContext *display_resource_ctx,
|
||||
const LayerTransform &transform,
|
||||
const LayerRect &src_rect, const LayerRect &dst_rect,
|
||||
const HWLayers &hw_layers, HWLayerConfig *layer_config,
|
||||
uint32_t align_x) {
|
||||
LayerRect scissor_dst_left, scissor_dst_right;
|
||||
HWDisplayAttributes &display_attributes = display_resource_ctx->display_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_right.left = FLOAT(display_attributes.split_left);
|
||||
scissor_right.top = 0.0f;
|
||||
scissor_right.right = FLOAT(display_attributes.x_pixels);
|
||||
scissor_right.bottom = FLOAT(display_attributes.y_pixels);
|
||||
|
||||
if (IsValid(hw_layers.info.left_partial_update) ||
|
||||
IsValid(hw_layers.info.right_partial_update)) {
|
||||
scissor_left = hw_layers.info.left_partial_update;
|
||||
scissor_right = hw_layers.info.right_partial_update;
|
||||
}
|
||||
|
||||
crop_left = src_rect;
|
||||
dst_left = dst_rect;
|
||||
crop_right = crop_left;
|
||||
dst_right = dst_left;
|
||||
bool crop_left_valid = CalculateCropRects(scissor_left, transform, &crop_left, &dst_left);
|
||||
bool crop_right_valid = false;
|
||||
|
||||
if (IsValid(scissor_right)) {
|
||||
crop_right_valid = CalculateCropRects(scissor_right, transform, &crop_right, &dst_right);
|
||||
}
|
||||
|
||||
if (crop_left_valid && (crop_left.right - crop_left.left) > hw_res_info_.max_pipe_width) {
|
||||
if (crop_right_valid) {
|
||||
DLOGV_IF(kTagResources, "Need more than 2 pipes: left width = %.0f, right width = %.0f",
|
||||
crop_left.right - crop_left.left, crop_right.right - crop_right.left);
|
||||
return kErrorNotSupported;
|
||||
}
|
||||
// 2 pipes both are on the left
|
||||
SplitRect(transform.flip_horizontal, crop_left, dst_left, &left_pipe->src_roi,
|
||||
&left_pipe->dst_roi, &right_pipe->src_roi, &right_pipe->dst_roi, align_x);
|
||||
left_pipe->valid = true;
|
||||
right_pipe->valid = true;
|
||||
crop_right_valid = true;
|
||||
} else if (crop_right_valid &&
|
||||
(crop_right.right - crop_right.left) > hw_res_info_.max_pipe_width) {
|
||||
if (crop_left_valid) {
|
||||
DLOGV_IF(kTagResources, "Need more than 2 pipes: left width = %.0f, right width = %.0f",
|
||||
crop_left.right - crop_left.left, crop_right.right - crop_right.left);
|
||||
return kErrorNotSupported;
|
||||
}
|
||||
// 2 pipes both are on the right
|
||||
SplitRect(transform.flip_horizontal, crop_right, dst_right, &left_pipe->src_roi,
|
||||
&left_pipe->dst_roi, &right_pipe->src_roi, &right_pipe->dst_roi, align_x);
|
||||
left_pipe->valid = true;
|
||||
right_pipe->valid = true;
|
||||
crop_left_valid = true;
|
||||
} else if (crop_left_valid) {
|
||||
// assign left pipe
|
||||
left_pipe->src_roi = crop_left;
|
||||
left_pipe->dst_roi = dst_left;
|
||||
left_pipe->valid = true;
|
||||
} else {
|
||||
// Set default value, left_pipe is not needed.
|
||||
left_pipe->Reset();
|
||||
}
|
||||
|
||||
// assign right pipe if needed
|
||||
if (crop_right_valid) {
|
||||
if (left_pipe->valid) {
|
||||
right_pipe->src_roi = crop_right;
|
||||
right_pipe->dst_roi = dst_right;
|
||||
right_pipe->valid = true;
|
||||
} else {
|
||||
// If left pipe is not used, use left pipe first.
|
||||
left_pipe->src_roi = crop_right;
|
||||
left_pipe->dst_roi = dst_right;
|
||||
left_pipe->valid = true;
|
||||
right_pipe->Reset();
|
||||
}
|
||||
} else {
|
||||
// need not right pipe
|
||||
right_pipe->Reset();
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError ResManager::Config(DisplayResourceContext *display_resource_ctx, HWLayers *hw_layers,
|
||||
uint32_t *rotate_count) {
|
||||
HWBlockType hw_block_id = display_resource_ctx->hw_block_id;
|
||||
HWDisplayAttributes &display_attributes = display_resource_ctx->display_attributes;
|
||||
HWLayersInfo &layer_info = hw_layers->info;
|
||||
DisplayError error = kErrorNone;
|
||||
uint32_t z_order = 0;
|
||||
|
||||
for (uint32_t i = 0; i < layer_info.count; i++) {
|
||||
Layer& layer = layer_info.stack->layers[layer_info.index[i]];
|
||||
float rotator_scale_factor = 1.0f;
|
||||
|
||||
error = ValidateLayerDimensions(layer);
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
|
||||
LayerRect scissor, src_rect, dst_rect;
|
||||
src_rect = layer.src_rect;
|
||||
dst_rect = layer.dst_rect;
|
||||
scissor.right = FLOAT(display_attributes.x_pixels);
|
||||
scissor.bottom = FLOAT(display_attributes.y_pixels);
|
||||
|
||||
if (IsValid(hw_layers->info.left_partial_update)) {
|
||||
scissor = hw_layers->info.left_partial_update;
|
||||
}
|
||||
|
||||
struct HWLayerConfig *layer_config = &hw_layers->config[i];
|
||||
HWPipeInfo &left_pipe = layer_config->left_pipe;
|
||||
HWPipeInfo &right_pipe = layer_config->right_pipe;
|
||||
HWRotatorSession *hw_rotator_session = &layer_config->hw_rotator_session;
|
||||
LayerTransform transform = layer.transform;
|
||||
bool rotated90 = IsRotationNeeded(transform.rotation);
|
||||
|
||||
if (!CalculateCropRects(scissor, layer.transform, &src_rect, &dst_rect)) {
|
||||
layer_config->Reset();
|
||||
left_pipe.Reset();
|
||||
right_pipe.Reset();
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32_t align_x, align_y;
|
||||
GetAlignFactor(layer.input_buffer->format, &align_x, &align_y);
|
||||
if (align_x > 1 || align_y > 1) {
|
||||
Normalize(align_x, align_y, &src_rect);
|
||||
}
|
||||
|
||||
error = ValidateDimensions(src_rect, dst_rect, rotated90);
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
|
||||
error = ValidateScaling(src_rect, dst_rect, rotated90);
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
|
||||
error = GetRotatorScaleFactor(src_rect, dst_rect, rotated90, &rotator_scale_factor);
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
|
||||
// config rotator first
|
||||
for (uint32_t j = 0; j < kMaxRotatePerLayer; j++) {
|
||||
hw_rotator_session->hw_rotate_info[j].Reset();
|
||||
}
|
||||
hw_rotator_session->hw_block_count = 0;
|
||||
|
||||
if (rotated90 || UINT32(rotator_scale_factor) != 1) {
|
||||
RotationConfig(layer, rotator_scale_factor, &src_rect, layer_config, rotate_count);
|
||||
// rotator will take care of flipping, reset tranform
|
||||
transform = LayerTransform();
|
||||
}
|
||||
|
||||
// TODO(user): need to revisit this logic
|
||||
if (hw_res_info_.is_src_split) {
|
||||
error = SrcSplitConfig(display_resource_ctx, transform, src_rect, dst_rect, layer_config,
|
||||
align_x);
|
||||
} else {
|
||||
error = DisplaySplitConfig(display_resource_ctx, transform, src_rect, dst_rect, *hw_layers,
|
||||
layer_config, align_x);
|
||||
}
|
||||
|
||||
if (error != kErrorNone) {
|
||||
break;
|
||||
}
|
||||
|
||||
error = AlignPipeConfig(layer, transform, *hw_layers, &left_pipe, &right_pipe, align_x,
|
||||
align_y);
|
||||
if (error != kErrorNone) {
|
||||
break;
|
||||
}
|
||||
|
||||
DLOGV_IF(kTagResources, "==== layer = %d, left pipe valid = %d ====",
|
||||
i, layer_config->left_pipe.valid);
|
||||
Log(kTagResources, "input layer src_rect", layer.src_rect);
|
||||
Log(kTagResources, "input layer dst_rect", layer.dst_rect);
|
||||
for (uint32_t k = 0; k < hw_rotator_session->hw_block_count; k++) {
|
||||
DLOGV_IF(kTagResources, "rotate num = %d, scale_x = %.2f", k, rotator_scale_factor);
|
||||
Log(kTagResources, "rotate src", hw_rotator_session->hw_rotate_info[k].src_roi);
|
||||
Log(kTagResources, "rotate dst", hw_rotator_session->hw_rotate_info[k].dst_roi);
|
||||
}
|
||||
|
||||
Log(kTagResources, "cropped src_rect", src_rect);
|
||||
Log(kTagResources, "cropped dst_rect", dst_rect);
|
||||
Log(kTagResources, "left pipe src", layer_config->left_pipe.src_roi);
|
||||
Log(kTagResources, "left pipe dst", layer_config->left_pipe.dst_roi);
|
||||
if (hw_layers->config[i].right_pipe.valid) {
|
||||
Log(kTagResources, "right pipe src", layer_config->right_pipe.src_roi);
|
||||
Log(kTagResources, "right pipe dst", layer_config->right_pipe.dst_roi);
|
||||
}
|
||||
// set z_order, left_pipe should always be valid
|
||||
left_pipe.z_order = z_order;
|
||||
if (layer_config->right_pipe.valid) {
|
||||
// use different z_order if 2 pipes are on one mixer and without src split support
|
||||
if (!hw_res_info_.is_src_split &&
|
||||
((left_pipe.dst_roi.right <= display_attributes.split_left &&
|
||||
right_pipe.dst_roi.right <= display_attributes.split_left) ||
|
||||
(left_pipe.dst_roi.left >= display_attributes.split_left &&
|
||||
right_pipe.dst_roi.left >= display_attributes.split_left))) {
|
||||
z_order++;
|
||||
}
|
||||
layer_config->right_pipe.z_order = z_order;
|
||||
}
|
||||
z_order++;
|
||||
if (z_order > display_resource_ctx->max_mixer_stages) {
|
||||
DLOGV_IF(kTagResources, "z_order is over the limit of max_mixer_stages = %d",
|
||||
display_resource_ctx->max_mixer_stages);
|
||||
return kErrorResources;
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void ResManager::CalculateCut(const LayerTransform &transform, float *left_cut_ratio,
|
||||
float *top_cut_ratio, float *right_cut_ratio,
|
||||
float *bottom_cut_ratio) {
|
||||
if (transform.flip_horizontal) {
|
||||
Swap(*left_cut_ratio, *right_cut_ratio);
|
||||
}
|
||||
|
||||
if (transform.flip_vertical) {
|
||||
Swap(*top_cut_ratio, *bottom_cut_ratio);
|
||||
}
|
||||
|
||||
if (IsRotationNeeded(transform.rotation)) {
|
||||
// Anti clock swapping
|
||||
float tmp_cut_ratio = *left_cut_ratio;
|
||||
*left_cut_ratio = *top_cut_ratio;
|
||||
*top_cut_ratio = *right_cut_ratio;
|
||||
*right_cut_ratio = *bottom_cut_ratio;
|
||||
*bottom_cut_ratio = tmp_cut_ratio;
|
||||
}
|
||||
}
|
||||
|
||||
bool ResManager::CalculateCropRects(const LayerRect &scissor, const LayerTransform &transform,
|
||||
LayerRect *crop, LayerRect *dst) {
|
||||
float &crop_left = crop->left;
|
||||
float &crop_top = crop->top;
|
||||
float &crop_right = crop->right;
|
||||
float &crop_bottom = crop->bottom;
|
||||
float crop_width = crop->right - crop->left;
|
||||
float crop_height = crop->bottom - crop->top;
|
||||
|
||||
float &dst_left = dst->left;
|
||||
float &dst_top = dst->top;
|
||||
float &dst_right = dst->right;
|
||||
float &dst_bottom = dst->bottom;
|
||||
float dst_width = dst->right - dst->left;
|
||||
float dst_height = dst->bottom - dst->top;
|
||||
|
||||
const float &sci_left = scissor.left;
|
||||
const float &sci_top = scissor.top;
|
||||
const float &sci_right = scissor.right;
|
||||
const float &sci_bottom = scissor.bottom;
|
||||
|
||||
float left_cut_ratio = 0.0, right_cut_ratio = 0.0, top_cut_ratio = 0.0, bottom_cut_ratio = 0.0;
|
||||
bool need_cut = false;
|
||||
|
||||
if (dst_left < sci_left) {
|
||||
left_cut_ratio = (sci_left - dst_left) / dst_width;
|
||||
dst_left = sci_left;
|
||||
need_cut = true;
|
||||
}
|
||||
|
||||
if (dst_right > sci_right) {
|
||||
right_cut_ratio = (dst_right - sci_right) / dst_width;
|
||||
dst_right = sci_right;
|
||||
need_cut = true;
|
||||
}
|
||||
|
||||
if (dst_top < sci_top) {
|
||||
top_cut_ratio = (sci_top - dst_top) / (dst_height);
|
||||
dst_top = sci_top;
|
||||
need_cut = true;
|
||||
}
|
||||
|
||||
if (dst_bottom > sci_bottom) {
|
||||
bottom_cut_ratio = (dst_bottom - sci_bottom) / (dst_height);
|
||||
dst_bottom = sci_bottom;
|
||||
need_cut = true;
|
||||
}
|
||||
|
||||
if (!need_cut)
|
||||
return true;
|
||||
|
||||
CalculateCut(transform, &left_cut_ratio, &top_cut_ratio, &right_cut_ratio, &bottom_cut_ratio);
|
||||
|
||||
crop_left += crop_width * left_cut_ratio;
|
||||
crop_top += crop_height * top_cut_ratio;
|
||||
crop_right -= crop_width * right_cut_ratio;
|
||||
crop_bottom -= crop_height * bottom_cut_ratio;
|
||||
Normalize(1, 1, crop);
|
||||
Normalize(1, 1, dst);
|
||||
if (IsValid(*crop) && IsValid(*dst))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
DisplayError ResManager::ValidateLayerDimensions(const Layer &layer) {
|
||||
const LayerRect &src = layer.src_rect;
|
||||
const LayerRect &dst = layer.dst_rect;
|
||||
LayerBuffer *input_buffer = layer.input_buffer;
|
||||
|
||||
if (!IsValid(src) || !IsValid(dst)) {
|
||||
Log(kTagResources, "input layer src_rect", src);
|
||||
Log(kTagResources, "input layer dst_rect", dst);
|
||||
return kErrorNotSupported;
|
||||
}
|
||||
|
||||
// Make sure source in integral only if it is a non secure layer.
|
||||
if (!input_buffer->flags.secure && (src.left - roundf(src.left) || src.top - roundf(src.top) ||
|
||||
src.right - roundf(src.right) || src.bottom - roundf(src.bottom))) {
|
||||
DLOGV_IF(kTagResources, "Input ROI is not integral");
|
||||
return kErrorNotSupported;
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError ResManager::ValidateDimensions(const LayerRect &crop, const LayerRect &dst,
|
||||
bool rotated90) {
|
||||
float crop_width = 0.0f, crop_height = 0.0f, dst_width = 0.0f, dst_height = 0.0f;
|
||||
|
||||
DisplayError error = GetCropAndDestination(crop, dst, rotated90, &crop_width, &crop_height,
|
||||
&dst_width, &dst_height);
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
|
||||
if ((dst_width < 1.0f) || (dst_height < 1.0f)) {
|
||||
DLOGV_IF(kTagResources, "dst ROI is too small w = %.0f, h = %.0f, right = %.0f, bottom = %.0f",
|
||||
dst_width, dst_height, dst.right, dst.bottom);
|
||||
return kErrorNotSupported;
|
||||
}
|
||||
|
||||
if ((crop_width < 1.0f) || (crop_height < 1.0f)) {
|
||||
DLOGV_IF(kTagResources, "src ROI is too small w = %.0f, h = %.0f, right = %.0f, bottom = %.0f",
|
||||
crop_width, crop_height, crop.right, crop.bottom);
|
||||
return kErrorNotSupported;
|
||||
}
|
||||
|
||||
if ((UINT32(crop_width - dst_width) == 1) || (UINT32(crop_height - dst_height) == 1)) {
|
||||
DLOGV_IF(kTagResources, "One pixel downscaling detected crop_w = %.0f, dst_w = %.0f, " \
|
||||
"crop_h = %.0f, dst_h = %.0f", crop_width, dst_width, crop_height, dst_height);
|
||||
return kErrorNotSupported;
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError ResManager::ValidatePipeParams(HWPipeInfo *pipe_info) {
|
||||
DisplayError error = kErrorNone;
|
||||
|
||||
const LayerRect &src_rect = pipe_info->src_roi;
|
||||
const LayerRect &dst_rect = pipe_info->dst_roi;
|
||||
|
||||
error = ValidateDimensions(src_rect, dst_rect, false /* rotated90 */);
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
|
||||
error = ValidateScaling(src_rect, dst_rect, false /* rotated90 */);
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError ResManager::ValidateScaling(const LayerRect &crop, const LayerRect &dst,
|
||||
bool rotated90) {
|
||||
DisplayError error = kErrorNone;
|
||||
|
||||
float scale_x = 1.0f;
|
||||
float scale_y = 1.0f;
|
||||
|
||||
error = GetScaleFactor(crop, dst, rotated90, &scale_x, &scale_y);
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
|
||||
error = ValidateDownScaling(scale_x, scale_y);
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
|
||||
error = ValidateUpScaling(scale_x, scale_y);
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError ResManager::ValidateDownScaling(float scale_x, float scale_y) {
|
||||
if ((UINT32(scale_x) > 1) || (UINT32(scale_y) > 1)) {
|
||||
float max_scale_down = FLOAT(hw_res_info_.max_scale_down);
|
||||
float rotator_scale_factor = 1.0f;
|
||||
|
||||
if (hw_res_info_.has_rotator_downscale && !property_setting_.disable_rotator_downscaling) {
|
||||
rotator_scale_factor = GetRotatorScaleFactor(scale_x, scale_y);
|
||||
scale_x /= rotator_scale_factor;
|
||||
scale_y /= rotator_scale_factor;
|
||||
|
||||
DLOGV_IF(kTagResources, "scale_x = %.4f, scale_y = %.4f, rotator_scale_factor = %d",
|
||||
scale_x, scale_y, rotator_scale_factor);
|
||||
}
|
||||
|
||||
if (hw_res_info_.has_decimation && !property_setting_.disable_decimation) {
|
||||
max_scale_down *= FLOAT(kMaxDecimationDownScaleRatio);
|
||||
}
|
||||
|
||||
if (scale_x > max_scale_down || scale_y > max_scale_down) {
|
||||
DLOGV_IF(kTagResources,
|
||||
"Scaling down is over the limit: scale_x = %.0f, scale_y = %.0f, " \
|
||||
"has_deci = %d, disable_deci = %d, rotator_scale_factor= %.0f",
|
||||
scale_x, scale_y, hw_res_info_.has_decimation, property_setting_.disable_decimation,
|
||||
rotator_scale_factor);
|
||||
return kErrorNotSupported;
|
||||
}
|
||||
}
|
||||
|
||||
DLOGV_IF(kTagResources, "scale_x = %.4f, scale_y = %.4f", scale_x, scale_y);
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError ResManager::ValidateUpScaling(float scale_x, float scale_y) {
|
||||
float max_scale_up = FLOAT(hw_res_info_.max_scale_up);
|
||||
|
||||
if (UINT32(scale_x) < 1 && scale_x > 0.0f) {
|
||||
if ((1.0f / scale_x) > max_scale_up) {
|
||||
DLOGV_IF(kTagResources, "Scaling up is over limit scale_x = %f", 1.0f / scale_x);
|
||||
return kErrorNotSupported;
|
||||
}
|
||||
}
|
||||
|
||||
if (UINT32(scale_y) < 1 && scale_y > 0.0f) {
|
||||
if ((1.0f / scale_y) > max_scale_up) {
|
||||
DLOGV_IF(kTagResources, "Scaling up is over limit scale_y = %f", 1.0f / scale_y);
|
||||
return kErrorNotSupported;
|
||||
}
|
||||
}
|
||||
|
||||
DLOGV_IF(kTagResources, "scale_x = %.4f, scale_y = %.4f", scale_x, scale_y);
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError ResManager::GetCropAndDestination(const LayerRect &crop, const LayerRect &dst,
|
||||
const bool rotated90, float *crop_width,
|
||||
float *crop_height, float *dst_width,
|
||||
float *dst_height) {
|
||||
if (!IsValid(crop)) {
|
||||
Log(kTagResources, "Invalid crop rect", crop);
|
||||
return kErrorNotSupported;
|
||||
}
|
||||
|
||||
if (!IsValid(dst)) {
|
||||
Log(kTagResources, "Invalid dst rect", dst);
|
||||
return kErrorNotSupported;
|
||||
}
|
||||
|
||||
*crop_width = crop.right - crop.left;
|
||||
*crop_height = crop.bottom - crop.top;
|
||||
if (rotated90) {
|
||||
Swap(*crop_width, *crop_height);
|
||||
}
|
||||
|
||||
*dst_width = dst.right - dst.left;
|
||||
*dst_height = dst.bottom - dst.top;
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError ResManager::GetRotatorScaleFactor(const LayerRect &crop, const LayerRect &dst,
|
||||
bool rotated90, float *rotator_scale_factor) {
|
||||
DisplayError error = kErrorNone;
|
||||
|
||||
float scale_x = 1.0f;
|
||||
float scale_y = 1.0f;
|
||||
|
||||
if (hw_res_info_.has_rotator_downscale && !property_setting_.disable_rotator_downscaling) {
|
||||
error = GetScaleFactor(crop, dst, rotated90, &scale_x, &scale_y);
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
|
||||
*rotator_scale_factor = GetRotatorScaleFactor(scale_x, scale_y);
|
||||
} else {
|
||||
*rotator_scale_factor = 1.0f;
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
float ResManager::GetRotatorScaleFactor(float scale_x, float scale_y) {
|
||||
float max_scale_down = FLOAT(hw_res_info_.max_scale_down);
|
||||
float scale_min = MIN(scale_x, scale_y);
|
||||
float scale_max = MAX(scale_x, scale_y);
|
||||
uint32_t rotator_scale_factor = 1;
|
||||
|
||||
// use rotator to downscale when over the pipe scaling ability
|
||||
if (UINT32(scale_min) >= 2 && scale_max > max_scale_down) {
|
||||
// downscaling ratio needs be the same for both direction, use the smaller one.
|
||||
rotator_scale_factor = 1 << UINT32(ceilf(log2f(scale_min / max_scale_down)));
|
||||
if (rotator_scale_factor > kMaxRotateDownScaleRatio) {
|
||||
rotator_scale_factor = kMaxRotateDownScaleRatio;
|
||||
}
|
||||
}
|
||||
|
||||
DLOGV_IF(kTagResources, "scale_x = %.4f, scale_y = %.4f, rotator_scale_factor = %d",
|
||||
scale_x, scale_y, rotator_scale_factor);
|
||||
|
||||
return FLOAT(rotator_scale_factor);
|
||||
}
|
||||
|
||||
DisplayError ResManager::GetScaleFactor(const LayerRect &crop, const LayerRect &dst,
|
||||
bool rotated90, float *scale_x, float *scale_y) {
|
||||
float crop_width = 1.0f, crop_height = 1.0f, dst_width = 1.0f, dst_height = 1.0f;
|
||||
|
||||
DisplayError error = GetCropAndDestination(crop, dst, rotated90, &crop_width, &crop_height,
|
||||
&dst_width, &dst_height);
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
|
||||
*scale_x = crop_width / dst_width;
|
||||
*scale_y = crop_height / dst_height;
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError ResManager::SetDecimationFactor(HWPipeInfo *pipe) {
|
||||
float src_h = pipe->src_roi.bottom - pipe->src_roi.top;
|
||||
float dst_h = pipe->dst_roi.bottom - pipe->dst_roi.top;
|
||||
float down_scale_h = src_h / dst_h;
|
||||
|
||||
float src_w = pipe->src_roi.right - pipe->src_roi.left;
|
||||
float dst_w = pipe->dst_roi.right - pipe->dst_roi.left;
|
||||
float down_scale_w = src_w / dst_w;
|
||||
|
||||
pipe->horizontal_decimation = 0;
|
||||
pipe->vertical_decimation = 0;
|
||||
|
||||
if (CalculateDecimation(down_scale_w, &pipe->horizontal_decimation) != kErrorNone) {
|
||||
return kErrorNotSupported;
|
||||
}
|
||||
|
||||
if (CalculateDecimation(down_scale_h, &pipe->vertical_decimation) != kErrorNone) {
|
||||
return kErrorNotSupported;
|
||||
}
|
||||
|
||||
DLOGI_IF(kTagResources, "horizontal_decimation %d, vertical_decimation %d",
|
||||
pipe->horizontal_decimation, pipe->vertical_decimation);
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
void ResManager::SplitRect(bool flip_horizontal, const LayerRect &src_rect,
|
||||
const LayerRect &dst_rect, LayerRect *src_left, LayerRect *dst_left,
|
||||
LayerRect *src_right, LayerRect *dst_right, uint32_t align_x) {
|
||||
// Split rectangle horizontally and evenly into two.
|
||||
float src_width = src_rect.right - src_rect.left;
|
||||
float dst_width = dst_rect.right - dst_rect.left;
|
||||
float src_width_ori = src_width;
|
||||
src_width = ROUND_UP_ALIGN_DOWN(src_width / 2, align_x);
|
||||
dst_width = ROUND_UP_ALIGN_DOWN(dst_width * src_width / src_width_ori, 1);
|
||||
|
||||
if (flip_horizontal) {
|
||||
src_left->left = src_rect.right - src_width;
|
||||
src_left->right = src_rect.right;
|
||||
|
||||
src_right->left = src_rect.left;
|
||||
src_right->right = src_left->left;
|
||||
} else {
|
||||
src_left->left = src_rect.left;
|
||||
src_left->right = src_rect.left + src_width;
|
||||
|
||||
src_right->left = src_left->right;
|
||||
src_right->right = src_rect.right;
|
||||
}
|
||||
|
||||
src_left->top = src_rect.top;
|
||||
src_left->bottom = src_rect.bottom;
|
||||
dst_left->top = dst_rect.top;
|
||||
dst_left->bottom = dst_rect.bottom;
|
||||
|
||||
src_right->top = src_rect.top;
|
||||
src_right->bottom = src_rect.bottom;
|
||||
dst_right->top = dst_rect.top;
|
||||
dst_right->bottom = dst_rect.bottom;
|
||||
|
||||
dst_left->left = dst_rect.left;
|
||||
dst_left->right = dst_rect.left + dst_width;
|
||||
dst_right->left = dst_left->right;
|
||||
dst_right->right = dst_rect.right;
|
||||
}
|
||||
|
||||
DisplayError ResManager::AlignPipeConfig(const Layer &layer, const LayerTransform &transform,
|
||||
const HWLayers &hw_layers, HWPipeInfo *left_pipe,
|
||||
HWPipeInfo *right_pipe, uint32_t align_x,
|
||||
uint32_t align_y) {
|
||||
DisplayError error = kErrorNone;
|
||||
if (!left_pipe->valid) {
|
||||
DLOGE_IF(kTagResources, "left_pipe should not be invalid");
|
||||
return kErrorNotSupported;
|
||||
}
|
||||
// 1. Normalize video layer source rectangle to multiple of 2, as MDP hardware require source
|
||||
// rectangle of video layer to be even.
|
||||
// 2. Normalize source and destination rect of a layer to multiple of 1.
|
||||
// TODO(user) Check buffer format and check if rotate is involved.
|
||||
Normalize(align_x, align_y, &left_pipe->src_roi);
|
||||
Normalize(1, 1, &left_pipe->dst_roi);
|
||||
|
||||
if (right_pipe->valid) {
|
||||
Normalize(align_x, align_y, &right_pipe->src_roi);
|
||||
Normalize(1, 1, &right_pipe->dst_roi);
|
||||
}
|
||||
|
||||
// Make sure the left and right ROI are conjunct, then make pipes ROI conjunct.
|
||||
if (right_pipe->valid &&
|
||||
(!IsValid(hw_layers.info.right_partial_update) ||
|
||||
(hw_layers.info.left_partial_update.right == hw_layers.info.right_partial_update.left))) {
|
||||
if (transform.flip_horizontal) {
|
||||
left_pipe->src_roi.left = right_pipe->src_roi.right;
|
||||
} else {
|
||||
right_pipe->src_roi.left = left_pipe->src_roi.right;
|
||||
}
|
||||
right_pipe->dst_roi.left = left_pipe->dst_roi.right;
|
||||
}
|
||||
|
||||
error = ValidatePipeParams(left_pipe);
|
||||
if (error != kErrorNone) {
|
||||
goto PipeConfigExit;
|
||||
}
|
||||
|
||||
if (right_pipe->valid) {
|
||||
error = ValidatePipeParams(right_pipe);
|
||||
}
|
||||
PipeConfigExit:
|
||||
if (error != kErrorNone) {
|
||||
DLOGV_IF(kTagResources, "AlignPipeConfig failed");
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
DisplayError ResManager::CalculateDecimation(float downscale, uint8_t *decimation) {
|
||||
float max_down_scale = FLOAT(hw_res_info_.max_scale_down);
|
||||
|
||||
if (downscale <= max_down_scale) {
|
||||
*decimation = 0;
|
||||
return kErrorNone;
|
||||
} else if (!hw_res_info_.has_decimation) {
|
||||
DLOGE("Downscaling exceeds the maximum MDP downscale limit but decimation not enabled");
|
||||
return kErrorNotSupported;
|
||||
}
|
||||
|
||||
// Decimation is the remaining downscale factor after doing max SDE downscale.
|
||||
// In SDE, decimation is supported in powers of 2.
|
||||
// For ex: If a pipe needs downscale of 8 but max_down_scale is 4
|
||||
// So decimation = powf(2.0, ceilf(log2f(8 / 4))) = powf(2.0, 1.0) = 2
|
||||
*decimation = UINT8(ceilf(log2f(downscale / max_down_scale)));
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
} // namespace sde
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,246 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 - 2015, 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:
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
|
||||
* endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __RES_MANAGER_H__
|
||||
#define __RES_MANAGER_H__
|
||||
|
||||
#include <core/display_interface.h>
|
||||
#include <private/hw_info_types.h>
|
||||
#include <utils/locker.h>
|
||||
|
||||
#include "hw_interface.h"
|
||||
#include "dump_impl.h"
|
||||
#include "scalar_helper.h"
|
||||
|
||||
namespace sde {
|
||||
|
||||
class ResManager : public DumpImpl {
|
||||
public:
|
||||
ResManager();
|
||||
DisplayError Init(const HWResourceInfo &hw_res_info);
|
||||
DisplayError Deinit();
|
||||
DisplayError RegisterDisplay(DisplayType type, const HWDisplayAttributes &attributes,
|
||||
const HWPanelInfo &hw_panel_info, Handle *display_ctx);
|
||||
DisplayError UnregisterDisplay(Handle display_ctx);
|
||||
void ReconfigureDisplay(Handle display_ctx, const HWDisplayAttributes &attributes,
|
||||
const HWPanelInfo &hw_panel_info);
|
||||
DisplayError Start(Handle display_ctx);
|
||||
DisplayError Stop(Handle display_ctx);
|
||||
DisplayError Acquire(Handle display_ctx, HWLayers *hw_layers);
|
||||
DisplayError PostPrepare(Handle display_ctx, HWLayers *hw_layers);
|
||||
DisplayError PostCommit(Handle display_ctx, HWLayers *hw_layers);
|
||||
void Purge(Handle display_ctx);
|
||||
DisplayError SetMaxMixerStages(Handle display_ctx, uint32_t max_mixer_stages);
|
||||
DisplayError ValidateScaling(const LayerRect &crop, const LayerRect &dst, bool rotate90);
|
||||
|
||||
// DumpImpl method
|
||||
virtual void AppendDump(char *buffer, uint32_t length);
|
||||
|
||||
private:
|
||||
enum PipeId {
|
||||
kPipeIdVIG0,
|
||||
kPipeIdVIG1,
|
||||
kPipeIdVIG2,
|
||||
kPipeIdRGB0,
|
||||
kPipeIdRGB1,
|
||||
kPipeIdRGB2,
|
||||
kPipeIdDMA0,
|
||||
kPipeIdDMA1,
|
||||
kPipeIdVIG3,
|
||||
kPipeIdRGB3,
|
||||
kPipeIdMax,
|
||||
};
|
||||
|
||||
enum PipeType {
|
||||
kPipeTypeUnused,
|
||||
kPipeTypeVIG,
|
||||
kPipeTypeRGB,
|
||||
kPipeTypeDMA,
|
||||
kPipeTypeMax,
|
||||
};
|
||||
|
||||
enum PipeState {
|
||||
kPipeStateIdle, // Pipe state when it is available for reservation
|
||||
kPipeStateAcquired, // Pipe state after successful commit
|
||||
kPipeStateToRelease, // Pipe state that can be moved to Idle when releasefence is signaled
|
||||
kPipeStateOwnedByKernel, // Pipe state when pipe is owned by kernel
|
||||
};
|
||||
|
||||
// todo: retrieve all these from kernel
|
||||
enum {
|
||||
kMaxInterfaceWidth = 2048,
|
||||
kMaxRotateDownScaleRatio = 8,
|
||||
kMaxDecimationDownScaleRatio = 8,
|
||||
kMaxNumRotator = 2,
|
||||
};
|
||||
|
||||
struct SourcePipe {
|
||||
PipeType type;
|
||||
uint32_t mdss_pipe_id;
|
||||
uint32_t index;
|
||||
PipeState state;
|
||||
HWBlockType hw_block_id;
|
||||
bool at_right;
|
||||
uint64_t state_frame_count;
|
||||
int priority;
|
||||
HWBlockType reserved_hw_block;
|
||||
HWBlockType dedicated_hw_block;
|
||||
|
||||
SourcePipe() : type(kPipeTypeUnused), mdss_pipe_id(kPipeIdMax), index(0),
|
||||
state(kPipeStateIdle), hw_block_id(kHWBlockMax), at_right(false),
|
||||
state_frame_count(0), priority(0), reserved_hw_block(kHWBlockMax),
|
||||
dedicated_hw_block(kHWBlockMax) { }
|
||||
|
||||
inline void ResetState() { state = kPipeStateIdle; hw_block_id = kHWBlockMax;
|
||||
at_right = false; reserved_hw_block = kHWBlockMax; dedicated_hw_block = kHWBlockMax; }
|
||||
};
|
||||
|
||||
struct DisplayResourceContext {
|
||||
HWDisplayAttributes display_attributes;
|
||||
DisplayType display_type;
|
||||
HWBlockType hw_block_id;
|
||||
HWPanelInfo hw_panel_info_;
|
||||
uint64_t frame_count;
|
||||
int32_t session_id; // applicable for virtual display sessions only
|
||||
uint32_t rotate_count;
|
||||
bool frame_start;
|
||||
uint32_t max_mixer_stages;
|
||||
|
||||
DisplayResourceContext() : hw_block_id(kHWBlockMax), frame_count(0), session_id(-1),
|
||||
rotate_count(0), frame_start(false), max_mixer_stages(0) { }
|
||||
};
|
||||
|
||||
struct HWBlockContext {
|
||||
bool is_in_use;
|
||||
HWBlockContext() : is_in_use(false) { }
|
||||
};
|
||||
|
||||
struct HWRotator {
|
||||
uint32_t pipe_index;
|
||||
HWBlockType writeback_id;
|
||||
uint32_t client_bit_mask;
|
||||
uint32_t request_bit_mask;
|
||||
HWRotator() : pipe_index(0), writeback_id(kHWBlockMax), client_bit_mask(0),
|
||||
request_bit_mask(0) { }
|
||||
|
||||
inline void ClearState(HWBlockType block) { CLEAR_BIT(client_bit_mask, block);
|
||||
CLEAR_BIT(request_bit_mask, block); }
|
||||
};
|
||||
|
||||
struct PropertySetting {
|
||||
bool disable_rotator_downscaling;
|
||||
bool disable_decimation;
|
||||
PropertySetting() : disable_rotator_downscaling(false), disable_decimation(false) { }
|
||||
};
|
||||
|
||||
uint32_t GetMdssPipeId(PipeType pipe_type, uint32_t index);
|
||||
uint32_t NextPipe(PipeType pipe_type, HWBlockType hw_block_id, bool at_right);
|
||||
uint32_t SearchPipe(HWBlockType hw_block_id, SourcePipe *src_pipes, uint32_t num_pipe,
|
||||
bool at_right);
|
||||
uint32_t GetPipe(HWBlockType hw_block_id, bool is_yuv, bool need_scale, bool at_right,
|
||||
bool use_non_dma_pipe);
|
||||
bool IsScalingNeeded(const HWPipeInfo *pipe_info);
|
||||
DisplayError Config(DisplayResourceContext *display_resource_ctx, HWLayers *hw_layers,
|
||||
uint32_t *rotate_count);
|
||||
DisplayError DisplaySplitConfig(DisplayResourceContext *display_resource_ctx,
|
||||
const LayerTransform &transform,
|
||||
const LayerRect &src_rect, const LayerRect &dst_rect,
|
||||
const HWLayers &hw_layers, HWLayerConfig *layer_config,
|
||||
uint32_t align_x);
|
||||
DisplayError ValidateScaling(const Layer &layer, const LayerRect &crop,
|
||||
const LayerRect &dst, float *rot_scale);
|
||||
DisplayError SrcSplitConfig(DisplayResourceContext *display_resource_ctx,
|
||||
const LayerTransform &transform, const LayerRect &src_rect,
|
||||
const LayerRect &dst_rect, HWLayerConfig *layer_config,
|
||||
uint32_t align_x);
|
||||
void CalculateCut(const LayerTransform &transform, float *left_cut_ratio, float *top_cut_ratio,
|
||||
float *right_cut_ratio, float *bottom_cut_ratio);
|
||||
bool CalculateCropRects(const LayerRect &scissor, const LayerTransform &transform,
|
||||
LayerRect *crop, LayerRect *dst);
|
||||
DisplayError ValidateLayerDimensions(const Layer &layer);
|
||||
DisplayError ValidateDimensions(const LayerRect &crop, const LayerRect &dst, bool rotate90);
|
||||
DisplayError ValidatePipeParams(HWPipeInfo *pipe_info);
|
||||
DisplayError ValidateDownScaling(float scale_x, float scale_y);
|
||||
DisplayError ValidateUpScaling(float scale_x, float scale_y);
|
||||
DisplayError GetCropAndDestination(const LayerRect &crop, const LayerRect &dst,
|
||||
bool rotate90, float *crop_width, float *crop_height,
|
||||
float *dst_width, float *dst_height);
|
||||
DisplayError GetRotatorScaleFactor(const LayerRect &crop, const LayerRect &dst,
|
||||
bool rotate90, float *rotator_scale_factor);
|
||||
float GetRotatorScaleFactor(float scale_x, float scale_y);
|
||||
DisplayError GetScaleFactor(const LayerRect &crop, const LayerRect &dst, bool rotate90,
|
||||
float *scale_x, float *scale_y);
|
||||
bool CheckBandwidth(DisplayResourceContext *display_ctx, HWLayers *hw_layers);
|
||||
float GetPipeBw(DisplayResourceContext *display_ctx, HWPipeInfo *pipe, float bpp);
|
||||
float GetClockForPipe(DisplayResourceContext *display_ctx, HWPipeInfo *pipe);
|
||||
float GetOverlapBw(HWLayers *hw_layers, float *pipe_bw, bool left_mixer);
|
||||
DisplayError SetDecimationFactor(HWPipeInfo *pipe);
|
||||
float GetBpp(LayerBufferFormat format);
|
||||
void SplitRect(bool flip_horizontal, const LayerRect &src_rect, const LayerRect &dst_rect,
|
||||
LayerRect *src_left, LayerRect *dst_left, LayerRect *src_right,
|
||||
LayerRect *dst_right, uint32_t align_x);
|
||||
bool IsMacroTileFormat(const LayerBuffer *buffer) { return buffer->flags.macro_tile; }
|
||||
bool IsRotationNeeded(float rotation)
|
||||
{ return (UINT32(rotation) == 90 || UINT32(rotation) == 270); }
|
||||
void RotationConfig(const Layer &layer, const float &downscale, LayerRect *src_rect,
|
||||
HWLayerConfig *layer_config, uint32_t *rotate_count);
|
||||
DisplayError AcquireRotator(DisplayResourceContext *display_resource_ctx,
|
||||
const uint32_t roate_cnt);
|
||||
void AssignRotator(HWRotateInfo *rotate, uint32_t *rotate_cnt);
|
||||
void ClearRotator(DisplayResourceContext *display_resource_ctx);
|
||||
void SetRotatorOutputFormat(const LayerBufferFormat &input_format, const bool &is_opaque,
|
||||
const bool &rot90, const bool &downscale,
|
||||
LayerBufferFormat *output_format);
|
||||
DisplayError AlignPipeConfig(const Layer &layer, const LayerTransform &transform,
|
||||
const HWLayers &hw_layers, HWPipeInfo *left_pipe,
|
||||
HWPipeInfo *right_pipe, uint32_t align_x, uint32_t align_y);
|
||||
void ResourceStateLog(void);
|
||||
DisplayError CalculateDecimation(float downscale, uint8_t *decimation);
|
||||
|
||||
Locker locker_;
|
||||
HWResourceInfo hw_res_info_;
|
||||
HWBlockContext hw_block_ctx_[kHWBlockMax];
|
||||
SourcePipe src_pipes_[kPipeIdMax];
|
||||
uint32_t num_pipe_;
|
||||
SourcePipe *vig_pipes_;
|
||||
SourcePipe *rgb_pipes_;
|
||||
SourcePipe *dma_pipes_;
|
||||
bool frame_start_;
|
||||
float bw_claimed_; // Bandwidth claimed by other display
|
||||
float clk_claimed_; // Clock claimed by other display
|
||||
float last_primary_bw_;
|
||||
float max_system_bw_;
|
||||
uint32_t virtual_count_;
|
||||
struct HWRotator rotators_[kMaxNumRotator];
|
||||
BufferAllocator *buffer_allocator_;
|
||||
BufferSyncHandler *buffer_sync_handler_; // Pointer to buffer sync handler that was defined by
|
||||
// the display engine's client
|
||||
PropertySetting property_setting_;
|
||||
Scalar *scalar_;
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
|
||||
#endif // __RES_MANAGER_H__
|
||||
|
||||
@@ -1,250 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 - 2015, 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:
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
|
||||
* endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <utils/constants.h>
|
||||
#include <utils/debug.h>
|
||||
#include <utils/rect.h>
|
||||
#include <core/buffer_allocator.h>
|
||||
#include <core/buffer_sync_handler.h>
|
||||
|
||||
#include "rotator_ctrl.h"
|
||||
#include "hw_rotator_interface.h"
|
||||
#include "hw_interface.h"
|
||||
#include "session_manager.h"
|
||||
|
||||
#define __CLASS__ "RotatorCtrl"
|
||||
|
||||
namespace sde {
|
||||
|
||||
RotatorCtrl::RotatorCtrl() : hw_rotator_intf_(NULL) {
|
||||
}
|
||||
|
||||
DisplayError RotatorCtrl::Init(BufferAllocator *buffer_allocator,
|
||||
BufferSyncHandler *buffer_sync_handler) {
|
||||
DisplayError error = kErrorNone;
|
||||
|
||||
error = HWRotatorInterface::Create(buffer_sync_handler, &hw_rotator_intf_);
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
|
||||
error = hw_rotator_intf_->Open();
|
||||
if (error != kErrorNone) {
|
||||
DLOGE("Failed to open rotator device");
|
||||
return error;
|
||||
}
|
||||
|
||||
session_manager_ = new SessionManager(hw_rotator_intf_, buffer_allocator, buffer_sync_handler);
|
||||
if (session_manager_ == NULL) {
|
||||
HWRotatorInterface::Destroy(hw_rotator_intf_);
|
||||
return kErrorMemory;
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError RotatorCtrl::Deinit() {
|
||||
DisplayError error = kErrorNone;
|
||||
|
||||
error = hw_rotator_intf_->Close();
|
||||
if (error != kErrorNone) {
|
||||
DLOGW("Failed to close rotator device");
|
||||
return error;
|
||||
}
|
||||
|
||||
if (session_manager_) {
|
||||
delete session_manager_;
|
||||
session_manager_ = NULL;
|
||||
}
|
||||
|
||||
HWRotatorInterface::Destroy(hw_rotator_intf_);
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError RotatorCtrl::RegisterDisplay(DisplayType type, Handle *display_ctx) {
|
||||
DisplayRotatorContext *disp_rotator_ctx = new DisplayRotatorContext();
|
||||
if (disp_rotator_ctx == NULL) {
|
||||
return kErrorMemory;
|
||||
}
|
||||
|
||||
disp_rotator_ctx->display_type = type;
|
||||
*display_ctx = disp_rotator_ctx;
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
void RotatorCtrl::UnregisterDisplay(Handle display_ctx) {
|
||||
DisplayRotatorContext *disp_rotator_ctx = reinterpret_cast<DisplayRotatorContext *>(display_ctx);
|
||||
|
||||
delete disp_rotator_ctx;
|
||||
disp_rotator_ctx = NULL;
|
||||
}
|
||||
|
||||
|
||||
DisplayError RotatorCtrl::Prepare(Handle display_ctx, HWLayers *hw_layers) {
|
||||
DisplayError error = kErrorNone;
|
||||
|
||||
DisplayRotatorContext *disp_rotator_ctx = reinterpret_cast<DisplayRotatorContext *>(display_ctx);
|
||||
|
||||
error = PrepareSessions(disp_rotator_ctx, hw_layers);
|
||||
if (error != kErrorNone) {
|
||||
DLOGE("Prepare rotator session failed for display %d", disp_rotator_ctx->display_type);
|
||||
return error;
|
||||
}
|
||||
|
||||
error = hw_rotator_intf_->Validate(hw_layers);
|
||||
if (error != kErrorNone) {
|
||||
DLOGE("Rotator validation failed for display %d", disp_rotator_ctx->display_type);
|
||||
return error;
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError RotatorCtrl::Commit(Handle display_ctx, HWLayers *hw_layers) {
|
||||
DisplayError error = kErrorNone;
|
||||
|
||||
DisplayRotatorContext *disp_rotator_ctx = reinterpret_cast<DisplayRotatorContext *>(display_ctx);
|
||||
|
||||
error = GetOutputBuffers(disp_rotator_ctx, hw_layers);
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
|
||||
error = hw_rotator_intf_->Commit(hw_layers);
|
||||
if (error != kErrorNone) {
|
||||
DLOGE("Rotator commit failed for display %d", disp_rotator_ctx->display_type);
|
||||
return error;
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError RotatorCtrl::PostCommit(Handle display_ctx, HWLayers *hw_layers) {
|
||||
HWLayersInfo &hw_layer_info = hw_layers->info;
|
||||
DisplayError error = kErrorNone;
|
||||
DisplayRotatorContext *disp_rotator_ctx = reinterpret_cast<DisplayRotatorContext *>(display_ctx);
|
||||
int client_id = INT(disp_rotator_ctx->display_type);
|
||||
|
||||
for (uint32_t i = 0; i < hw_layer_info.count; i++) {
|
||||
Layer& layer = hw_layer_info.stack->layers[hw_layer_info.index[i]];
|
||||
HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
|
||||
|
||||
if (!hw_rotator_session->hw_block_count) {
|
||||
continue;
|
||||
}
|
||||
|
||||
error = session_manager_->SetReleaseFd(client_id, hw_rotator_session);
|
||||
if (error != kErrorNone) {
|
||||
DLOGE("Rotator Post commit failed for display %d", disp_rotator_ctx->display_type);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError RotatorCtrl::Purge(Handle display_ctx, HWLayers *hw_layers) {
|
||||
DisplayRotatorContext *disp_rotator_ctx = reinterpret_cast<DisplayRotatorContext *>(display_ctx);
|
||||
int client_id = INT(disp_rotator_ctx->display_type);
|
||||
|
||||
session_manager_->Start(client_id);
|
||||
|
||||
return session_manager_->Stop(client_id);
|
||||
}
|
||||
|
||||
DisplayError RotatorCtrl::PrepareSessions(DisplayRotatorContext *disp_rotator_ctx,
|
||||
HWLayers *hw_layers) {
|
||||
HWLayersInfo &hw_layer_info = hw_layers->info;
|
||||
DisplayError error = kErrorNone;
|
||||
int client_id = INT(disp_rotator_ctx->display_type);
|
||||
|
||||
session_manager_->Start(client_id);
|
||||
|
||||
for (uint32_t i = 0; i < hw_layer_info.count; i++) {
|
||||
Layer& layer = hw_layer_info.stack->layers[hw_layer_info.index[i]];
|
||||
HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
|
||||
HWSessionConfig &hw_session_config = hw_rotator_session->hw_session_config;
|
||||
HWRotateInfo *left_rotate = &hw_rotator_session->hw_rotate_info[0];
|
||||
HWRotateInfo *right_rotate = &hw_rotator_session->hw_rotate_info[1];
|
||||
|
||||
if (!hw_rotator_session->hw_block_count) {
|
||||
continue;
|
||||
}
|
||||
|
||||
hw_session_config.src_width = UINT32(layer.src_rect.right - layer.src_rect.left);
|
||||
hw_session_config.src_height = UINT32(layer.src_rect.bottom - layer.src_rect.top);
|
||||
hw_session_config.src_format = layer.input_buffer->format;
|
||||
|
||||
LayerRect dst_rect = Union(left_rotate->dst_roi, right_rotate->dst_roi);
|
||||
|
||||
hw_session_config.dst_width = UINT32(dst_rect.right - dst_rect.left);
|
||||
hw_session_config.dst_height = UINT32(dst_rect.bottom - dst_rect.top);
|
||||
hw_session_config.dst_format = hw_rotator_session->output_buffer.format;
|
||||
|
||||
// Allocate two rotator output buffers by default for double buffering.
|
||||
hw_session_config.buffer_count = kDoubleBuffering;
|
||||
hw_session_config.secure = layer.input_buffer->flags.secure;
|
||||
hw_session_config.frame_rate = layer.frame_rate;
|
||||
|
||||
error = session_manager_->OpenSession(client_id, hw_rotator_session);
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
error = session_manager_->Stop(client_id);
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError RotatorCtrl::GetOutputBuffers(DisplayRotatorContext *disp_rotator_ctx,
|
||||
HWLayers *hw_layers) {
|
||||
HWLayersInfo &hw_layer_info = hw_layers->info;
|
||||
DisplayError error = kErrorNone;
|
||||
int client_id = INT(disp_rotator_ctx->display_type);
|
||||
|
||||
for (uint32_t i = 0; i < hw_layer_info.count; i++) {
|
||||
Layer& layer = hw_layer_info.stack->layers[hw_layer_info.index[i]];
|
||||
HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
|
||||
|
||||
if (!hw_rotator_session->hw_block_count) {
|
||||
continue;
|
||||
}
|
||||
|
||||
error = session_manager_->GetNextBuffer(client_id, hw_rotator_session);
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
} // namespace sde
|
||||
|
||||
@@ -1,267 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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:
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
|
||||
* endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <utils/debug.h>
|
||||
#include "scalar_helper.h"
|
||||
|
||||
#define __CLASS__ "ScalarHelper"
|
||||
|
||||
namespace sde {
|
||||
|
||||
#ifdef USES_SCALAR
|
||||
ScalarHelper::ScalarHelper()
|
||||
: scalar_library_name_("libscalar.so"), configure_scale_api_("configureScale"),
|
||||
lib_scalar_(NULL), configure_scale_(NULL) {
|
||||
}
|
||||
|
||||
DisplayError ScalarHelper::Init() {
|
||||
lib_scalar_ = dlopen(scalar_library_name_, RTLD_NOW);
|
||||
if (lib_scalar_) {
|
||||
void **scalar_func = reinterpret_cast<void **>(&configure_scale_);
|
||||
*scalar_func = ::dlsym(lib_scalar_, configure_scale_api_);
|
||||
if (!configure_scale_) {
|
||||
DLOGE("Unable to find symbol for %s API!", configure_scale_api_);
|
||||
dlclose(lib_scalar_);
|
||||
return kErrorUndefined;
|
||||
}
|
||||
} else {
|
||||
DLOGW("Unable to load %s !", scalar_library_name_);
|
||||
return kErrorNotSupported;
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
void ScalarHelper::Deinit() {
|
||||
if (lib_scalar_) {
|
||||
dlclose(lib_scalar_);
|
||||
}
|
||||
}
|
||||
|
||||
// Helper functions
|
||||
void ScalarHelper::SetPipeInfo(const HWPipeInfo &hw_pipe, scalar::PipeInfo *pipe) {
|
||||
pipe->id = hw_pipe.pipe_id;
|
||||
pipe->horz_deci = hw_pipe.horizontal_decimation;
|
||||
pipe->vert_deci = hw_pipe.vertical_decimation;
|
||||
|
||||
pipe->src_rect.x = UINT32(hw_pipe.src_roi.left);
|
||||
pipe->src_rect.y = UINT32(hw_pipe.src_roi.top);
|
||||
pipe->src_rect.w = UINT32(hw_pipe.src_roi.right) - pipe->src_rect.x;
|
||||
pipe->src_rect.h = UINT32(hw_pipe.src_roi.bottom) - pipe->src_rect.y;
|
||||
|
||||
pipe->dst_rect.x = UINT32(hw_pipe.dst_roi.left);
|
||||
pipe->dst_rect.y = UINT32(hw_pipe.dst_roi.top);
|
||||
pipe->dst_rect.w = UINT32(hw_pipe.dst_roi.right) - pipe->dst_rect.x;
|
||||
pipe->dst_rect.h = UINT32(hw_pipe.dst_roi.bottom) - pipe->dst_rect.y;
|
||||
}
|
||||
|
||||
void ScalarHelper::UpdateSrcRoi(const scalar::PipeInfo &pipe, HWPipeInfo *hw_pipe) {
|
||||
hw_pipe->src_roi.left = FLOAT(pipe.src_rect.x);
|
||||
hw_pipe->src_roi.top = FLOAT(pipe.src_rect.y);
|
||||
hw_pipe->src_roi.right = FLOAT(pipe.src_rect.x + pipe.src_rect.w);
|
||||
hw_pipe->src_roi.bottom = FLOAT(pipe.src_rect.y + pipe.src_rect.h);
|
||||
}
|
||||
|
||||
void ScalarHelper::SetScaleData(const scalar::PipeInfo &pipe, ScaleData *scale_data) {
|
||||
scalar::Scale *scale = pipe.scale_data;
|
||||
scale_data->src_width = pipe.src_width;
|
||||
scale_data->src_height = pipe.src_height;
|
||||
scale_data->enable_pixel_ext = scale->enable_pxl_ext;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
HWPlane &plane = scale_data->plane[i];
|
||||
plane.init_phase_x = scale->init_phase_x[i];
|
||||
plane.phase_step_x = scale->phase_step_x[i];
|
||||
plane.init_phase_y = scale->init_phase_y[i];
|
||||
plane.phase_step_y = scale->phase_step_y[i];
|
||||
|
||||
plane.left.extension = scale->left.extension[i];
|
||||
plane.left.overfetch = scale->left.overfetch[i];
|
||||
plane.left.repeat = scale->left.repeat[i];
|
||||
|
||||
plane.top.extension = scale->top.extension[i];
|
||||
plane.top.overfetch = scale->top.overfetch[i];
|
||||
plane.top.repeat = scale->top.repeat[i];
|
||||
|
||||
plane.right.extension = scale->right.extension[i];
|
||||
plane.right.overfetch = scale->right.overfetch[i];
|
||||
plane.right.repeat = scale->right.repeat[i];
|
||||
|
||||
plane.bottom.extension = scale->bottom.extension[i];
|
||||
plane.bottom.overfetch = scale->bottom.overfetch[i];
|
||||
plane.bottom.repeat = scale->bottom.repeat[i];
|
||||
|
||||
plane.roi_width = scale->roi_width[i];
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t ScalarHelper::GetScalarFormat(LayerBufferFormat source) {
|
||||
uint32_t format = scalar::UNKNOWN_FORMAT;
|
||||
|
||||
switch (source) {
|
||||
case kFormatARGB8888: format = scalar::ARGB_8888; break;
|
||||
case kFormatRGBA8888: format = scalar::RGBA_8888; break;
|
||||
case kFormatBGRA8888: format = scalar::BGRA_8888; break;
|
||||
case kFormatXRGB8888: format = scalar::XRGB_8888; break;
|
||||
case kFormatRGBX8888: format = scalar::RGBX_8888; break;
|
||||
case kFormatBGRX8888: format = scalar::BGRX_8888; break;
|
||||
case kFormatRGBA5551: format = scalar::RGBA_5551; break;
|
||||
case kFormatRGBA4444: format = scalar::RGBA_4444; break;
|
||||
case kFormatRGB888: format = scalar::RGB_888; break;
|
||||
case kFormatBGR888: format = scalar::BGR_888; break;
|
||||
case kFormatRGB565: format = scalar::RGB_565; break;
|
||||
case kFormatYCbCr420Planar: format = scalar::Y_CB_CR_H2V2; break;
|
||||
case kFormatYCrCb420Planar: format = scalar::Y_CR_CB_H2V2; break;
|
||||
case kFormatYCbCr420SemiPlanar: format = scalar::Y_CBCR_H2V2; break;
|
||||
case kFormatYCrCb420SemiPlanar: format = scalar::Y_CRCB_H2V2; break;
|
||||
case kFormatYCbCr422H1V2SemiPlanar: format = scalar::Y_CBCR_H1V2; break;
|
||||
case kFormatYCrCb422H1V2SemiPlanar: format = scalar::Y_CRCB_H1V2; break;
|
||||
case kFormatYCbCr422H2V1SemiPlanar: format = scalar::Y_CBCR_H2V1; break;
|
||||
case kFormatYCrCb422H2V1SemiPlanar: format = scalar::Y_CRCB_H2V1; break;
|
||||
case kFormatYCbCr422H2V1Packed: format = scalar::YCBYCR_H2V1; break;
|
||||
case kFormatYCbCr420SemiPlanarVenus: format = scalar::Y_CBCR_H2V2_VENUS; break;
|
||||
case kFormatRGBA8888Ubwc: format = scalar::RGBA_8888_UBWC; break;
|
||||
case kFormatRGBX8888Ubwc: format = scalar::RGBX_8888_UBWC; break;
|
||||
case kFormatRGB565Ubwc: format = scalar::RGB_565_UBWC; break;
|
||||
case kFormatYCbCr420SPVenusUbwc: format = scalar::Y_CBCR_H2V2_UBWC; break;
|
||||
default:
|
||||
DLOGE("Unsupported source format: %x", source);
|
||||
break;
|
||||
}
|
||||
return format;
|
||||
}
|
||||
|
||||
DisplayError ScalarHelper::ConfigureScale(HWLayers *hw_layers) {
|
||||
HWLayersInfo &hw_layer_info = hw_layers->info;
|
||||
|
||||
for (uint32_t i = 0; i < hw_layer_info.count; i++) {
|
||||
Layer &layer = hw_layer_info.stack->layers[hw_layer_info.index[i]];
|
||||
uint32_t width = layer.input_buffer->width;
|
||||
uint32_t height = layer.input_buffer->height;
|
||||
LayerBufferFormat format = layer.input_buffer->format;
|
||||
HWPipeInfo &left_pipe = hw_layers->config[i].left_pipe;
|
||||
HWPipeInfo &right_pipe = hw_layers->config[i].right_pipe;
|
||||
HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
|
||||
|
||||
// Reset scale data
|
||||
memset(&left_pipe.scale_data, 0, sizeof(ScaleData));
|
||||
memset(&right_pipe.scale_data, 0, sizeof(ScaleData));
|
||||
|
||||
// Prepare data structure for lib scalar
|
||||
uint32_t flags = 0;
|
||||
struct scalar::LayerInfo layer_info;
|
||||
struct scalar::Scale left_scale, right_scale;
|
||||
|
||||
if (layer.transform.rotation == 90.0f) {
|
||||
// Flips will be taken care by rotator, if layer requires 90 rotation
|
||||
flags |= scalar::SCALAR_SOURCE_ROTATED_90;
|
||||
} else {
|
||||
flags |= layer.transform.flip_vertical ? scalar::SCALAR_FLIP_UD : 0;
|
||||
flags |= layer.transform.flip_horizontal ? scalar::SCALAR_FLIP_LR : 0;
|
||||
}
|
||||
|
||||
for (uint32_t count = 0; count < 2; count++) {
|
||||
const HWPipeInfo &hw_pipe = (count == 0) ? left_pipe : right_pipe;
|
||||
HWRotateInfo* hw_rotate_info = &hw_rotator_session->hw_rotate_info[count];
|
||||
scalar::PipeInfo* pipe = (count == 0) ? &layer_info.left_pipe : &layer_info.right_pipe;
|
||||
|
||||
if (hw_rotate_info->valid) {
|
||||
width = UINT32(hw_rotate_info->dst_roi.right - hw_rotate_info->dst_roi.left);
|
||||
height = UINT32(hw_rotate_info->dst_roi.bottom - hw_rotate_info->dst_roi.top);
|
||||
format = hw_rotator_session->output_buffer.format;
|
||||
}
|
||||
|
||||
pipe->flags = flags;
|
||||
pipe->scale_data = (count == 0) ? &left_scale : &right_scale;
|
||||
pipe->src_width = width;
|
||||
pipe->src_height = height;
|
||||
SetPipeInfo(hw_pipe, pipe);
|
||||
}
|
||||
layer_info.src_format = GetScalarFormat(format);
|
||||
|
||||
DLOGV_IF(kTagScalar, "Scalar Input[%d] flags=%x format=%x", i, flags, layer_info.src_format);
|
||||
DLOGV_IF(kTagScalar, "Left: id=%d hD=%d vD=%d srcRect=[%d %d %d %d] dstRect=[%d %d %d %d]",
|
||||
layer_info.left_pipe.id, layer_info.left_pipe.horz_deci, layer_info.left_pipe.vert_deci,
|
||||
layer_info.left_pipe.src_rect.x, layer_info.left_pipe.src_rect.y,
|
||||
layer_info.left_pipe.src_rect.w, layer_info.left_pipe.src_rect.h,
|
||||
layer_info.left_pipe.dst_rect.x, layer_info.left_pipe.dst_rect.y,
|
||||
layer_info.left_pipe.dst_rect.w, layer_info.left_pipe.dst_rect.h);
|
||||
DLOGV_IF(kTagScalar, "Right: id=%d hD=%d vD=%d srcRect=[%d %d %d %d] dstRect=[%d %d %d %d]",
|
||||
layer_info.right_pipe.id, layer_info.right_pipe.horz_deci, layer_info.right_pipe.vert_deci,
|
||||
layer_info.right_pipe.src_rect.x, layer_info.right_pipe.src_rect.y,
|
||||
layer_info.right_pipe.src_rect.w, layer_info.right_pipe.src_rect.h,
|
||||
layer_info.right_pipe.dst_rect.x, layer_info.right_pipe.dst_rect.y,
|
||||
layer_info.right_pipe.dst_rect.w, layer_info.right_pipe.dst_rect.h);
|
||||
|
||||
// Configure scale data structure
|
||||
if (configure_scale_(&layer_info) < 0) {
|
||||
DLOGE("Scalar library failed to configure scale data!");
|
||||
return kErrorParameters;
|
||||
}
|
||||
|
||||
// Set ScaleData and update SrcRoi in HWPipeInfo
|
||||
if (left_scale.enable_pxl_ext) {
|
||||
SetScaleData(layer_info.left_pipe, &left_pipe.scale_data);
|
||||
UpdateSrcRoi(layer_info.left_pipe, &left_pipe);
|
||||
}
|
||||
if (right_scale.enable_pxl_ext) {
|
||||
SetScaleData(layer_info.right_pipe, &right_pipe.scale_data);
|
||||
UpdateSrcRoi(layer_info.right_pipe, &right_pipe);
|
||||
}
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
#endif
|
||||
|
||||
DisplayError Scalar::CreateScalar(Scalar **scalar) {
|
||||
Scalar *scalar_obj = NULL;
|
||||
|
||||
#ifdef USES_SCALAR
|
||||
scalar_obj = new ScalarHelper();
|
||||
if (scalar_obj) {
|
||||
if (scalar_obj->Init() == kErrorNone) {
|
||||
goto OnSuccess;
|
||||
} else {
|
||||
delete scalar_obj;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
scalar_obj = new Scalar();
|
||||
if (!scalar_obj) {
|
||||
return kErrorMemory;
|
||||
}
|
||||
|
||||
OnSuccess:
|
||||
*scalar = scalar_obj;
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
void Scalar::Destroy(Scalar *scalar) {
|
||||
scalar->Deinit();
|
||||
}
|
||||
|
||||
} // namespace sde
|
||||
@@ -1,364 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <utils/debug.h>
|
||||
#include <utils/constants.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "session_manager.h"
|
||||
#include "hw_rotator_interface.h"
|
||||
|
||||
#define __CLASS__ "SessionManager"
|
||||
|
||||
namespace sde {
|
||||
|
||||
// SessionManager State Transition
|
||||
// *******************************************************
|
||||
// Current State * Next State
|
||||
// *****************************************
|
||||
// * RELEASED READY ACQUIRED
|
||||
// *******************************************************
|
||||
// RELEASED * NA NA OpenSession()
|
||||
// READY * Stop() NA OpenSession()
|
||||
// ACQUIRED * NA Start() NA
|
||||
//********************************************************
|
||||
|
||||
// ------------------------------- SessionManager Implementation -----------------------------------
|
||||
|
||||
SessionManager::SessionManager(HWRotatorInterface *hw_rotator_intf,
|
||||
BufferAllocator *buffer_allocator,
|
||||
BufferSyncHandler *buffer_sync_handler)
|
||||
: hw_rotator_intf_(hw_rotator_intf), buffer_allocator_(buffer_allocator),
|
||||
buffer_sync_handler_(buffer_sync_handler), active_session_count_(0) {
|
||||
}
|
||||
|
||||
void SessionManager::Start(const int &client_id) {
|
||||
SCOPE_LOCK(locker_);
|
||||
|
||||
uint32_t session_count = 0;
|
||||
uint32_t acquired_session_count = 0;
|
||||
|
||||
// Change the state of acquired session to kSessionReady
|
||||
while ((acquired_session_count < active_session_count_) && (session_count < kMaxSessionCount)) {
|
||||
if (session_list_[session_count].state == kSessionAcquired) {
|
||||
if (session_list_[session_count].client_id == client_id) {
|
||||
session_list_[session_count].state = kSessionReady;
|
||||
}
|
||||
acquired_session_count++;
|
||||
}
|
||||
session_count++;
|
||||
}
|
||||
}
|
||||
|
||||
DisplayError SessionManager::OpenSession(const int &client_id,
|
||||
HWRotatorSession *hw_rotator_session) {
|
||||
SCOPE_LOCK(locker_);
|
||||
|
||||
DisplayError error = kErrorNone;
|
||||
|
||||
const HWSessionConfig &input_config = hw_rotator_session->hw_session_config;
|
||||
|
||||
DLOGI_IF(kTagRotator, "Src buffer: width = %d, height = %d, format = %d",
|
||||
input_config.src_width, input_config.src_height, input_config.src_format);
|
||||
DLOGI_IF(kTagRotator, "Dst buffer: width = %d, height = %d, format = %d",
|
||||
input_config.dst_width, input_config.dst_height, input_config.dst_format);
|
||||
DLOGI_IF(kTagRotator, "buffer_count = %d, secure = %d, cache = %d, frame_rate = %d",
|
||||
input_config.buffer_count, input_config.secure, input_config.cache,
|
||||
input_config.frame_rate);
|
||||
|
||||
uint32_t free_session = active_session_count_;
|
||||
uint32_t acquired_session = kMaxSessionCount;
|
||||
uint32_t active_session_count = 0;
|
||||
|
||||
// First look for a session in ready state, if no session found in ready state matching
|
||||
// with current input session config, assign a session in released state.
|
||||
for (uint32_t session_count = 0; session_count < kMaxSessionCount &&
|
||||
active_session_count < active_session_count_; session_count++) {
|
||||
HWSessionConfig &hw_session_config =
|
||||
session_list_[session_count].hw_rotator_session.hw_session_config;
|
||||
|
||||
if (session_list_[session_count].state == kSessionReleased) {
|
||||
free_session = session_count;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (session_list_[session_count].state == kSessionReady) {
|
||||
if (session_list_[session_count].client_id == client_id &&
|
||||
input_config == hw_session_config) {
|
||||
session_list_[session_count].state = kSessionAcquired;
|
||||
acquired_session = session_count;
|
||||
break;
|
||||
}
|
||||
}
|
||||
active_session_count++;
|
||||
}
|
||||
|
||||
// If the input config does not match with existing config, then add new session and change the
|
||||
// state to kSessionAcquired
|
||||
if (acquired_session == kMaxSessionCount) {
|
||||
if (free_session >= kMaxSessionCount) {
|
||||
return kErrorMemory;
|
||||
}
|
||||
|
||||
error = AcquireSession(hw_rotator_session, &session_list_[free_session]);
|
||||
if (error !=kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
|
||||
acquired_session = free_session;
|
||||
hw_rotator_session->session_id = acquired_session;
|
||||
session_list_[acquired_session].client_id = client_id;
|
||||
active_session_count_++;
|
||||
|
||||
DLOGV_IF(kTagRotator, "Acquire new session Output: width = %d, height = %d, format = %d, " \
|
||||
"session_id %d, client_id %d", hw_rotator_session->output_buffer.width,
|
||||
hw_rotator_session->output_buffer.height, hw_rotator_session->output_buffer.format,
|
||||
hw_rotator_session->session_id, client_id);
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
*hw_rotator_session = session_list_[acquired_session].hw_rotator_session;
|
||||
|
||||
DLOGV_IF(kTagRotator, "Acquire existing session Output: width = %d, height = %d, format = %d, " \
|
||||
"session_id %d, client_id %d", hw_rotator_session->output_buffer.width,
|
||||
hw_rotator_session->output_buffer.height, hw_rotator_session->output_buffer.format,
|
||||
hw_rotator_session->session_id, client_id);
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError SessionManager::GetNextBuffer(const int &client_id,
|
||||
HWRotatorSession *hw_rotator_session) {
|
||||
SCOPE_LOCK(locker_);
|
||||
|
||||
DisplayError error = kErrorNone;
|
||||
|
||||
int session_id = hw_rotator_session->session_id;
|
||||
if (session_id > kMaxSessionCount) {
|
||||
return kErrorParameters;
|
||||
}
|
||||
|
||||
Session *session = &session_list_[session_id];
|
||||
if (session->state != kSessionAcquired) {
|
||||
DLOGE("Invalid session state %d", session->state);
|
||||
return kErrorParameters;
|
||||
}
|
||||
|
||||
uint32_t curr_index = session->curr_index;
|
||||
|
||||
BufferInfo *buffer_info = &session->buffer_info;
|
||||
if (buffer_info->alloc_buffer_info.fd < 0) {
|
||||
const uint32_t &buffer_count = buffer_info->buffer_config.buffer_count;
|
||||
const size_t &buffer_size = buffer_info->alloc_buffer_info.size;
|
||||
|
||||
error = buffer_allocator_->AllocateBuffer(buffer_info);
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
|
||||
for (uint32_t idx = 0; idx < buffer_count; idx++) {
|
||||
session->offset[idx] = UINT32((buffer_size / buffer_count) * idx);
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for the release fence fd before the session being given to the client.
|
||||
buffer_sync_handler_->SyncWait(session->release_fd[curr_index]);
|
||||
close(session->release_fd[curr_index]);
|
||||
session->release_fd[curr_index] = -1;
|
||||
|
||||
hw_rotator_session->output_buffer.planes[0].stride = buffer_info->alloc_buffer_info.stride;
|
||||
hw_rotator_session->output_buffer.planes[0].fd = buffer_info->alloc_buffer_info.fd;
|
||||
hw_rotator_session->output_buffer.planes[0].offset = session->offset[curr_index];
|
||||
|
||||
session->hw_rotator_session = *hw_rotator_session;
|
||||
|
||||
DLOGI_IF(kTagRotator, "Output: width = %d, height = %d, format = %d, stride %d, " \
|
||||
"curr_index = %d, offset %d, fd %d, session_id %d, client_id %d",
|
||||
hw_rotator_session->output_buffer.width, hw_rotator_session->output_buffer.height,
|
||||
hw_rotator_session->output_buffer.format,
|
||||
hw_rotator_session->output_buffer.planes[0].stride, curr_index,
|
||||
hw_rotator_session->output_buffer.planes[0].offset,
|
||||
hw_rotator_session->output_buffer.planes[0].fd, session_id, client_id);
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError SessionManager::Stop(const int &client_id) {
|
||||
SCOPE_LOCK(locker_);
|
||||
|
||||
DisplayError error = kErrorNone;
|
||||
uint32_t session_id = 0;
|
||||
|
||||
// Release all the sessions which were not acquired in the current cycle and deallocate the
|
||||
// buffers associated with it.
|
||||
while ((active_session_count_ > 0) && (session_id < kMaxSessionCount)) {
|
||||
if (session_list_[session_id].state == kSessionReady &&
|
||||
session_list_[session_id].client_id == client_id) {
|
||||
error = ReleaseSession(&session_list_[session_id]);
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
active_session_count_--;
|
||||
|
||||
DLOGI_IF(kTagRotator, "session_id = %d, active_session_count = %d, client_id %d", session_id,
|
||||
active_session_count_, client_id);
|
||||
}
|
||||
session_id++;
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError SessionManager::SetReleaseFd(const int &client_id,
|
||||
HWRotatorSession *hw_rotator_session) {
|
||||
SCOPE_LOCK(locker_);
|
||||
|
||||
int session_id = hw_rotator_session->session_id;
|
||||
if (session_id > kMaxSessionCount) {
|
||||
return kErrorParameters;
|
||||
}
|
||||
|
||||
Session *session = &session_list_[session_id];
|
||||
if (session->state != kSessionAcquired) {
|
||||
DLOGE("Invalid session state %d", session->state);
|
||||
return kErrorParameters;
|
||||
}
|
||||
|
||||
uint32_t &curr_index = session->curr_index;
|
||||
uint32_t buffer_count = hw_rotator_session->hw_session_config.buffer_count;
|
||||
|
||||
// 1. Store the release fence fd, so that session manager waits for the release fence fd
|
||||
// to be signaled and populates the session info to the client.
|
||||
// 2. Modify the curr_index to point to next buffer.
|
||||
session->release_fd[curr_index] = hw_rotator_session->output_buffer.release_fence_fd;
|
||||
|
||||
curr_index = (curr_index + 1) % buffer_count;
|
||||
|
||||
DLOGI_IF(kTagRotator, "session_id %d, curr_index = %d, release fd %d, client_id %d", session_id,
|
||||
curr_index, hw_rotator_session->output_buffer.release_fence_fd, client_id);
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError SessionManager::AcquireSession(HWRotatorSession *hw_rotator_session,
|
||||
Session *session) {
|
||||
DisplayError error = kErrorNone;
|
||||
const HWSessionConfig &input_config = hw_rotator_session->hw_session_config;
|
||||
|
||||
error = hw_rotator_intf_->OpenSession(hw_rotator_session);
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
|
||||
hw_rotator_session->output_buffer = LayerBuffer();
|
||||
hw_rotator_session->output_buffer.width = input_config.dst_width;
|
||||
hw_rotator_session->output_buffer.height = input_config.dst_height;
|
||||
hw_rotator_session->output_buffer.format = input_config.dst_format;
|
||||
hw_rotator_session->output_buffer.flags.secure = input_config.secure;
|
||||
|
||||
uint32_t buffer_count = hw_rotator_session->hw_session_config.buffer_count;
|
||||
|
||||
session->release_fd = new int[buffer_count];
|
||||
if (session->release_fd == NULL) {
|
||||
return kErrorMemory;
|
||||
}
|
||||
|
||||
session->offset = new uint32_t[buffer_count];
|
||||
if (session->offset == NULL) {
|
||||
delete[] session->release_fd;
|
||||
session->release_fd = NULL;
|
||||
return kErrorMemory;
|
||||
}
|
||||
|
||||
for (uint32_t idx = 0; idx < buffer_count; idx++) {
|
||||
session->release_fd[idx] = -1;
|
||||
session->offset[idx] = 0;
|
||||
}
|
||||
session->curr_index = 0;
|
||||
|
||||
session->hw_rotator_session = HWRotatorSession();
|
||||
session->buffer_info = BufferInfo();
|
||||
|
||||
BufferInfo *buffer_info = &session->buffer_info;
|
||||
buffer_info->buffer_config.buffer_count = hw_rotator_session->hw_session_config.buffer_count;
|
||||
buffer_info->buffer_config.secure = hw_rotator_session->hw_session_config.secure;
|
||||
buffer_info->buffer_config.cache = hw_rotator_session->hw_session_config.cache;
|
||||
buffer_info->buffer_config.width = hw_rotator_session->hw_session_config.dst_width;
|
||||
buffer_info->buffer_config.height = hw_rotator_session->hw_session_config.dst_height;
|
||||
buffer_info->buffer_config.format = hw_rotator_session->hw_session_config.dst_format;
|
||||
|
||||
session->state = kSessionAcquired;
|
||||
session->hw_rotator_session = *hw_rotator_session;
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError SessionManager::ReleaseSession(Session *session) {
|
||||
DisplayError error = kErrorNone;
|
||||
|
||||
BufferInfo *buffer_info = &session->buffer_info;
|
||||
|
||||
error = buffer_allocator_->FreeBuffer(buffer_info);
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
|
||||
error = hw_rotator_intf_->CloseSession(&session->hw_rotator_session);
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
|
||||
uint32_t buffer_count = buffer_info->buffer_config.buffer_count;
|
||||
|
||||
for (uint32_t idx = 0; idx < buffer_count; idx++) {
|
||||
if (session->release_fd[idx] >= 0) {
|
||||
close(session->release_fd[idx]);
|
||||
session->release_fd[idx] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
session->state = kSessionReleased;
|
||||
session->client_id == -1;
|
||||
|
||||
if (session->offset) {
|
||||
delete[] session->offset;
|
||||
session->offset = NULL;
|
||||
}
|
||||
|
||||
if (session->release_fd) {
|
||||
delete[] session->release_fd;
|
||||
session->release_fd = NULL;
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
} // namespace sde
|
||||
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __SESSION_MANAGER_H__
|
||||
#define __SESSION_MANAGER_H__
|
||||
|
||||
#include <utils/locker.h>
|
||||
#include <core/buffer_allocator.h>
|
||||
#include "hw_interface.h"
|
||||
|
||||
namespace sde {
|
||||
|
||||
class HWRotatorInterface;
|
||||
|
||||
class SessionManager {
|
||||
public:
|
||||
SessionManager(HWRotatorInterface *hw_intf, BufferAllocator *buffer_allocator,
|
||||
BufferSyncHandler *buffer_sync_handler);
|
||||
|
||||
void Start(const int &client_id);
|
||||
DisplayError Stop(const int &client_id);
|
||||
DisplayError OpenSession(const int &client_id, HWRotatorSession *hw_rotator_session);
|
||||
DisplayError GetNextBuffer(const int &client_id, HWRotatorSession *hw_rotator_session);
|
||||
DisplayError SetReleaseFd(const int &client_id, HWRotatorSession *hw_rotator_session);
|
||||
|
||||
private:
|
||||
// TODO(user): Read from hw capability instead of hardcoding
|
||||
static const int kMaxSessionCount = 32;
|
||||
|
||||
enum SessionState {
|
||||
kSessionReleased = 0,
|
||||
kSessionReady = 1,
|
||||
kSessionAcquired = 2,
|
||||
};
|
||||
|
||||
struct Session {
|
||||
HWRotatorSession hw_rotator_session;
|
||||
BufferInfo buffer_info;
|
||||
SessionState state;
|
||||
int *release_fd;
|
||||
uint32_t *offset;
|
||||
uint32_t curr_index;
|
||||
int client_id;
|
||||
|
||||
Session() : state(kSessionReleased), release_fd(NULL), offset(NULL), curr_index(0),
|
||||
client_id(-1) { }
|
||||
};
|
||||
|
||||
DisplayError AcquireSession(HWRotatorSession *hw_rotator_session, Session *session);
|
||||
DisplayError ReleaseSession(Session *session);
|
||||
|
||||
Locker locker_;
|
||||
Session session_list_[kMaxSessionCount];
|
||||
HWRotatorInterface *hw_rotator_intf_;
|
||||
BufferAllocator *buffer_allocator_;
|
||||
BufferSyncHandler *buffer_sync_handler_;
|
||||
uint32_t active_session_count_; // number of sessions in ready/acquired state.
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
|
||||
#endif // __SESSION_MANAGER_H__
|
||||
|
||||
|
||||
@@ -1,142 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 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:
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
|
||||
* endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <utils/constants.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
#include "strategy_default.h"
|
||||
|
||||
#define __CLASS__ "StrategyDefault"
|
||||
|
||||
namespace sde {
|
||||
|
||||
StrategyDefault::StrategyDefault(DisplayType type, const HWResourceInfo &hw_resource_info,
|
||||
const HWPanelInfo &hw_panel_info) : type_(type),
|
||||
hw_resource_info_(hw_resource_info),
|
||||
hw_panel_info_(hw_panel_info), hw_layers_info_(NULL) {
|
||||
}
|
||||
|
||||
DisplayError StrategyDefault::CreateStrategyInterface(uint16_t version, DisplayType type,
|
||||
const HWResourceInfo &hw_resource_info,
|
||||
const HWPanelInfo &hw_panel_info,
|
||||
StrategyInterface **interface) {
|
||||
StrategyDefault *strategy_default = new StrategyDefault(type, hw_resource_info, hw_panel_info);
|
||||
|
||||
if (!strategy_default) {
|
||||
return kErrorMemory;
|
||||
}
|
||||
|
||||
*interface = strategy_default;
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError StrategyDefault::DestroyStrategyInterface(StrategyInterface *interface) {
|
||||
StrategyDefault *strategy_default = static_cast<StrategyDefault *>(interface);
|
||||
|
||||
if (!strategy_default) {
|
||||
return kErrorParameters;
|
||||
}
|
||||
|
||||
delete strategy_default;
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
bool StrategyDefault::IsDisplaySplit(uint32_t fb_x_res) {
|
||||
if (fb_x_res > hw_resource_info_.max_mixer_width) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((type_ == kPrimary) && hw_panel_info_.split_info.right_split) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
DisplayError StrategyDefault::Start(HWLayersInfo *hw_layers_info, uint32_t *max_attempts) {
|
||||
if (!hw_layers_info) {
|
||||
return kErrorParameters;
|
||||
}
|
||||
|
||||
hw_layers_info_ = hw_layers_info;
|
||||
*max_attempts = 1;
|
||||
|
||||
const LayerStack *layer_stack = hw_layers_info_->stack;
|
||||
for (uint32_t i = 0; i < layer_stack->layer_count; i++) {
|
||||
LayerComposition &composition = layer_stack->layers[i].composition;
|
||||
if (composition == kCompositionGPUTarget) {
|
||||
fb_layer_index_ = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const LayerRect &src_rect = hw_layers_info_->stack->layers[fb_layer_index_].src_rect;
|
||||
// TODO(user): read panels x_pixels and y_pixels instead of fb_x_res and fb_y_res
|
||||
const float fb_x_res = src_rect.right - src_rect.left;
|
||||
const float fb_y_res = src_rect.bottom - src_rect.top;
|
||||
|
||||
if (IsDisplaySplit(INT(fb_x_res))) {
|
||||
float left_split = FLOAT(hw_panel_info_.split_info.left_split);
|
||||
hw_layers_info->left_partial_update = (LayerRect) {0.0, 0.0, left_split, fb_y_res};
|
||||
hw_layers_info->right_partial_update = (LayerRect) {left_split, 0.0, fb_x_res, fb_y_res};
|
||||
} else {
|
||||
hw_layers_info->left_partial_update = (LayerRect) {0.0, 0.0, fb_x_res, fb_y_res};
|
||||
hw_layers_info->right_partial_update = (LayerRect) {0.0, 0.0, 0.0, 0.0};
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError StrategyDefault::Stop() {
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError StrategyDefault::GetNextStrategy(StrategyConstraints *constraints) {
|
||||
// Mark all layers for GPU composition. Find GPU target buffer and store its index for programming
|
||||
// the hardware.
|
||||
LayerStack *layer_stack = hw_layers_info_->stack;
|
||||
uint32_t &hw_layer_count = hw_layers_info_->count;
|
||||
|
||||
hw_layer_count = 0;
|
||||
for (uint32_t i = 0; i < layer_stack->layer_count; i++) {
|
||||
LayerComposition &composition = layer_stack->layers[i].composition;
|
||||
if (composition != kCompositionGPUTarget) {
|
||||
composition = kCompositionGPU;
|
||||
} else {
|
||||
hw_layers_info_->index[hw_layer_count++] = i;
|
||||
}
|
||||
}
|
||||
|
||||
// There can be one and only one GPU target buffer.
|
||||
if (hw_layer_count != 1) {
|
||||
return kErrorParameters;
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
} // namespace sde
|
||||
|
||||
@@ -30,8 +30,7 @@
|
||||
/*! @file buffer_allocator.h
|
||||
@brief Interface file for platform specific buffer allocator.
|
||||
|
||||
@details Buffer manager in display engine uses this interface to allocate buffer for internal
|
||||
usage.
|
||||
@details This interface is used by SDM to allocate internal buffers.
|
||||
*/
|
||||
|
||||
#ifndef __BUFFER_ALLOCATOR_H__
|
||||
@@ -39,7 +38,7 @@
|
||||
|
||||
#include <core/layer_buffer.h>
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
/*! @brief Input configuration set by the client for buffer allocation.
|
||||
|
||||
@sa BufferInfo::BufferConfig
|
||||
@@ -87,8 +86,8 @@ struct BufferInfo {
|
||||
/*! @brief Buffer allocator implemented by the client
|
||||
|
||||
@details This class declares prototype for BufferAllocator methods which must be
|
||||
implemented by the client. Buffer manager in display engine will use these methods to
|
||||
allocate/deallocate buffers for display engine.
|
||||
implemented by the client. Buffer manager in display manager will use these methods to
|
||||
allocate/deallocate buffers for display manager.
|
||||
|
||||
@sa CoreInterface::CreateCore
|
||||
*/
|
||||
@@ -119,7 +118,7 @@ class BufferAllocator {
|
||||
virtual ~BufferAllocator() { }
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __BUFFER_ALLOCATOR_H__
|
||||
|
||||
@@ -30,20 +30,20 @@
|
||||
/*! @file buffer_sync_handler.h
|
||||
@brief Interface file for platform specific buffer allocator.
|
||||
|
||||
@details Buffer manager in display engine uses this interface to wait for buffer sync fd to be
|
||||
signaled/merge the two buffer sync fds into one
|
||||
@details SDM will use this interface to wait for buffer sync fd to be signaled/merge
|
||||
the two buffer sync fds into one.
|
||||
*/
|
||||
|
||||
#ifndef __BUFFER_SYNC_HANDLER_H__
|
||||
#define __BUFFER_SYNC_HANDLER_H__
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
/*! @brief Buffer sync handler implemented by the client
|
||||
|
||||
@details This class declares prototype for BufferSyncHandler methods which must be
|
||||
implemented by the client. Buffer manager and HWFramebuffer in display engine will use these
|
||||
methods to wait for buffer sync fd to be signaled/merge two buffer sync fds into one.
|
||||
implemented by the client. SDM will use these methods to wait for buffer sync fd to be
|
||||
signaled/merge two buffer sync fds into one.
|
||||
|
||||
@sa CoreInterface::CreateCore
|
||||
*/
|
||||
@@ -78,7 +78,7 @@ class BufferSyncHandler {
|
||||
virtual ~BufferSyncHandler() { }
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __BUFFER_SYNC_HANDLER_H__
|
||||
|
||||
@@ -40,23 +40,23 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "display_interface.h"
|
||||
#include "sde_types.h"
|
||||
#include "sdm_types.h"
|
||||
#include "buffer_allocator.h"
|
||||
|
||||
class BufferSyncHandler;
|
||||
|
||||
/*! @brief Display engine interface version.
|
||||
/*! @brief Display manager interface version.
|
||||
|
||||
@details Display engine interfaces are version tagged to maintain backward compatibility. This
|
||||
@details Display manager interfaces are version tagged to maintain backward compatibility. This
|
||||
version is supplied as a default argument during display core initialization.
|
||||
|
||||
Client may use an older version of interfaces and link to a higher version of display engine
|
||||
Client may use an older version of interfaces and link to a higher version of display manager
|
||||
library, but vice versa is not allowed.
|
||||
|
||||
A 32-bit client must use 32-bit display core library and a 64-bit client must use 64-bit display
|
||||
core library.
|
||||
|
||||
Display engine interfaces follow default data structures alignment. Client must not override the
|
||||
Display manager interfaces follow default data structures alignment. Client must not override the
|
||||
default padding rules while using these interfaces.
|
||||
|
||||
@warning It is assumed that client upgrades or downgrades display core interface all at once
|
||||
@@ -65,13 +65,13 @@ class BufferSyncHandler;
|
||||
|
||||
@sa CoreInterface::CreateCore
|
||||
*/
|
||||
#define SDE_REVISION_MAJOR (1)
|
||||
#define SDE_REVISION_MINOR (0)
|
||||
#define SDM_REVISION_MAJOR (1)
|
||||
#define SDM_REVISION_MINOR (0)
|
||||
|
||||
#define SDE_VERSION_TAG ((uint32_t) ((SDE_REVISION_MAJOR << 24) | (SDE_REVISION_MINOR << 16) | \
|
||||
(sizeof(SDECompatibility) << 8) | sizeof(int *)))
|
||||
#define SDM_VERSION_TAG ((uint32_t) ((SDM_REVISION_MAJOR << 24) | (SDM_REVISION_MINOR << 16) | \
|
||||
(sizeof(SDMCompatibility) << 8) | sizeof(int *)))
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
/*! @brief Forward declaration for debug handler.
|
||||
*/
|
||||
@@ -137,7 +137,7 @@ class CoreInterface {
|
||||
@param[in] buffer_allocator \link BufferAllocator \endlink
|
||||
@param[in] buffer_sync_handler \link BufferSyncHandler \endlink
|
||||
@param[out] interface \link CoreInterface \endlink
|
||||
@param[in] version \link SDE_VERSION_TAG \endlink. Client must not override this argument.
|
||||
@param[in] version \link SDM_VERSION_TAG \endlink. Client must not override this argument.
|
||||
|
||||
@return \link DisplayError \endlink
|
||||
|
||||
@@ -146,7 +146,7 @@ class CoreInterface {
|
||||
static DisplayError CreateCore(CoreEventHandler *event_handler, DebugHandler *debug_handler,
|
||||
BufferAllocator *buffer_allocator,
|
||||
BufferSyncHandler *buffer_sync_handler, CoreInterface **interface,
|
||||
uint32_t version = SDE_VERSION_TAG);
|
||||
uint32_t version = SDM_VERSION_TAG);
|
||||
|
||||
/*! @brief Method to release handle to display core interface.
|
||||
|
||||
@@ -195,7 +195,7 @@ class CoreInterface {
|
||||
virtual ~CoreInterface() { }
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __CORE_INTERFACE_H__
|
||||
|
||||
@@ -28,12 +28,12 @@
|
||||
*/
|
||||
|
||||
/*! @file debug_interface.h
|
||||
@brief This file provides the debug interface for display engine.
|
||||
@brief This file provides the debug interface for display manager.
|
||||
*/
|
||||
#ifndef __DEBUG_INTERFACE_H__
|
||||
#define __DEBUG_INTERFACE_H__
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
/*! @brief This enum represents different modules/logical unit tags that a log message may
|
||||
be associated with. Client may use this to filter messages for dynamic logging.
|
||||
@@ -53,7 +53,7 @@ enum DebugTag {
|
||||
/*! @brief Display debug handler class.
|
||||
|
||||
@details This class defines display debug handler. The handle contains methods which client
|
||||
should implement to get different levels of logging/tracing from display engine. Display engine
|
||||
should implement to get different levels of logging/tracing from display manager. Display manager
|
||||
will call into these methods at appropriate times to send logging/tracing information.
|
||||
|
||||
@sa CoreInterface::CreateCore
|
||||
@@ -120,7 +120,7 @@ class ScopeTracer {
|
||||
~ScopeTracer() { T::Get()->EndTrace(); }
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __DEBUG_INTERFACE_H__
|
||||
|
||||
@@ -36,9 +36,9 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "layer_stack.h"
|
||||
#include "sde_types.h"
|
||||
#include "sdm_types.h"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
/*! @brief This enum represents display device types where contents can be rendered.
|
||||
|
||||
@@ -118,7 +118,7 @@ struct DisplayEventVSync {
|
||||
|
||||
@details This class declares prototype for display device event handler methods which must be
|
||||
implemented by the client. Display device will use these methods to notify events to the client.
|
||||
Client must post heavy-weight event handling to a separate thread and unblock display engine
|
||||
Client must post heavy-weight event handling to a separate thread and unblock display manager
|
||||
thread instantly.
|
||||
|
||||
@sa CoreInterface::CreateDisplay
|
||||
@@ -170,13 +170,13 @@ class DisplayInterface {
|
||||
/*! @brief Method to determine hardware capability to compose layers associated with given frame.
|
||||
|
||||
@details Client shall send all layers associated with a frame targeted for current display
|
||||
using this method and check the layers which can be handled completely in display engine.
|
||||
using this method and check the layers which can be handled completely in display manager.
|
||||
|
||||
Client shall mark composition type for one of the layer as kCompositionGPUTarget; the GPU
|
||||
composed output would be rendered at the specified layer if some of the layers are not handled
|
||||
by SDE.
|
||||
by SDM.
|
||||
|
||||
Display engine will set each layer as kCompositionGPU or kCompositionSDE upon return. Client
|
||||
Display manager will set each layer as kCompositionGPU or kCompositionSDE upon return. Client
|
||||
shall render all the layers marked as kCompositionGPU using GPU.
|
||||
|
||||
This method can be called multiple times but only last call prevails. This method must be
|
||||
@@ -213,7 +213,7 @@ class DisplayInterface {
|
||||
|
||||
/*! @brief Method to flush any pending buffers/fences submitted previously via Commit() call.
|
||||
|
||||
@details Client shall call this method to request the Display Engine to release all buffers and
|
||||
@details Client shall call this method to request the Display manager to release all buffers and
|
||||
respective fences currently in use. This operation may result in a blank display on the panel
|
||||
until a new frame is submitted for composition.
|
||||
|
||||
@@ -359,7 +359,7 @@ class DisplayInterface {
|
||||
virtual ~DisplayInterface() { }
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __DISPLAY_INTERFACE_H__
|
||||
|
||||
12
displayengine/include/core/dump_interface.h → sdm/include/core/dump_interface.h
Executable file → Normal file
12
displayengine/include/core/dump_interface.h → sdm/include/core/dump_interface.h
Executable file → Normal file
@@ -23,7 +23,7 @@
|
||||
*/
|
||||
|
||||
/*! @file dump_interface.h
|
||||
@brief Interface file for dump options provided by display engine.
|
||||
@brief Interface file for dump options provided by display manager.
|
||||
|
||||
*/
|
||||
#ifndef __DUMP_INTERFACE_H__
|
||||
@@ -31,20 +31,20 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "sde_types.h"
|
||||
#include "sdm_types.h"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
/*! @brief Display dump interface.
|
||||
|
||||
@details This class defines dump methods provided by display engine.
|
||||
@details This class defines dump methods provided by display manager.
|
||||
|
||||
*/
|
||||
class DumpInterface {
|
||||
public:
|
||||
/*! @brief Method to get dump information in form of a string.
|
||||
|
||||
@details Client shall use this method to get current snapshot of display engine context as a
|
||||
@details Client shall use this method to get current snapshot of display manager context as a
|
||||
formatted string for logging or dumping purposes.
|
||||
|
||||
@param[inout] buffer String buffer allocated by the client. Filled with null terminated dump
|
||||
@@ -62,7 +62,7 @@ class DumpInterface {
|
||||
virtual ~DumpInterface() { }
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __DUMP_INTERFACE_H__
|
||||
|
||||
@@ -31,11 +31,11 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "sde_types.h"
|
||||
#include "sdm_types.h"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
/*! @brief This enum represents different buffer formats supported by display engine.
|
||||
/*! @brief This enum represents different buffer formats supported by display manager.
|
||||
|
||||
@sa LayerBuffer
|
||||
*/
|
||||
@@ -176,25 +176,25 @@ struct LayerBuffer {
|
||||
//!< on the buffer format specified.
|
||||
|
||||
int acquire_fence_fd; //!< File descriptor referring to a sync fence object which will be
|
||||
//!< signaled when buffer can be read/write by display engine.
|
||||
//!< signaled when buffer can be read/write by display manager.
|
||||
//!< This fence object is set by the client during Commit(). For
|
||||
//!< input buffers client shall signal this fence when buffer
|
||||
//!< content is available and can be read by display engine. For
|
||||
//!< content is available and can be read by display manager. For
|
||||
//!< output buffers, client shall signal fence when buffer is ready
|
||||
//!< to be written by display engine.
|
||||
//!< to be written by display manager.
|
||||
|
||||
//!< This field is used only during Commit() and shall be set to -1
|
||||
//!< by the client when buffer is already available for read/write.
|
||||
|
||||
int release_fence_fd; //!< File descriptor referring to a sync fence object which will be
|
||||
//!< signaled when buffer has been read/written by display engine.
|
||||
//!< This fence object is set by display engine during Commit().
|
||||
//!< For input buffers display engine will signal this fence when
|
||||
//!< buffer has been consumed. For output buffers, display engine
|
||||
//!< signaled when buffer has been read/written by display manager.
|
||||
//!< This fence object is set by display manager during Commit().
|
||||
//!< For input buffers display manager will signal this fence when
|
||||
//!< buffer has been consumed. For output buffers, display manager
|
||||
//!< will signal this fence when buffer is produced.
|
||||
|
||||
//!< This field is used only during Commit() and will be set to -1
|
||||
//!< by display engine when buffer is already available for
|
||||
//!< by display manager when buffer is already available for
|
||||
//!< read/write.
|
||||
|
||||
LayerBufferFlags flags; //!< Flags associated with this buffer.
|
||||
@@ -203,7 +203,7 @@ struct LayerBuffer {
|
||||
release_fence_fd(-1) { }
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __LAYER_BUFFER_H__
|
||||
|
||||
@@ -35,9 +35,9 @@
|
||||
#include <utils/constants.h>
|
||||
|
||||
#include "layer_buffer.h"
|
||||
#include "sde_types.h"
|
||||
#include "sdm_types.h"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
/*! @brief This enum represents display layer blending types.
|
||||
|
||||
@@ -244,7 +244,7 @@ struct LayerStack {
|
||||
LayerStack() : layers(NULL), layer_count(0), retire_fence_fd(-1), output_buffer(NULL) { }
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __LAYER_STACK_H__
|
||||
|
||||
@@ -27,13 +27,13 @@
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*! @file sde_types.h
|
||||
/*! @file sdm_types.h
|
||||
@brief This file contains miscellaneous data types used across display interfaces.
|
||||
*/
|
||||
#ifndef __SDE_TYPES_H__
|
||||
#define __SDE_TYPES_H__
|
||||
#ifndef __SDM_TYPES_H__
|
||||
#define __SDM_TYPES_H__
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
/*! @brief This enum represents different error codes that display interfaces may return.
|
||||
*/
|
||||
@@ -54,17 +54,17 @@ enum DisplayError {
|
||||
};
|
||||
|
||||
/*! @brief This structure is defined for client and library compatibility check purpose only. This
|
||||
structure is used in SDE_VERSION_TAG definition only. Client should not refer it directly for
|
||||
structure is used in SDM_VERSION_TAG definition only. Client should not refer it directly for
|
||||
any purpose.
|
||||
*/
|
||||
struct SDECompatibility {
|
||||
struct SDMCompatibility {
|
||||
char c1;
|
||||
int i1;
|
||||
char c2;
|
||||
int i2;
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __SDE_TYPES_H__
|
||||
#endif // __SDM_TYPES_H__
|
||||
|
||||
79
sdm/include/private/extension_interface.h
Normal file
79
sdm/include/private/extension_interface.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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:
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
|
||||
* endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __EXTENSION_INTERFACE_H__
|
||||
#define __EXTENSION_INTERFACE_H__
|
||||
|
||||
#include <core/sdm_types.h>
|
||||
#include <core/display_interface.h>
|
||||
|
||||
#include "partial_update_interface.h"
|
||||
#include "strategy_interface.h"
|
||||
#include "resource_interface.h"
|
||||
#include "rotator_interface.h"
|
||||
|
||||
namespace sdm {
|
||||
|
||||
#define EXTENSION_LIBRARY_NAME "libsdmextension.so"
|
||||
#define CREATE_EXTENSION_INTERFACE_NAME "CreateExtensionInterface"
|
||||
#define DESTROY_EXTENSION_INTERFACE_NAME "DestroyExtensionInterface"
|
||||
|
||||
#define EXTENSION_REVISION_MAJOR (1)
|
||||
#define EXTENSION_REVISION_MINOR (0)
|
||||
|
||||
#define EXTENSION_VERSION_TAG ((uint16_t) ((EXTENSION_REVISION_MAJOR << 8) \
|
||||
| EXTENSION_REVISION_MINOR))
|
||||
|
||||
class ExtensionInterface;
|
||||
|
||||
typedef DisplayError (*CreateExtensionInterface)(uint16_t version, ExtensionInterface **interface);
|
||||
typedef DisplayError (*DestroyExtensionInterface)(ExtensionInterface *interface);
|
||||
|
||||
class ExtensionInterface {
|
||||
public:
|
||||
virtual DisplayError CreatePartialUpdate(DisplayType type, const HWResourceInfo &hw_resource_info,
|
||||
const HWPanelInfo &hw_panel_info,
|
||||
PartialUpdateInterface **interface) = 0;
|
||||
virtual DisplayError DestroyPartialUpdate(PartialUpdateInterface *interface) = 0;
|
||||
|
||||
virtual DisplayError CreateStrategyExtn(DisplayType type, StrategyInterface **interface) = 0;
|
||||
virtual DisplayError DestroyStrategyExtn(StrategyInterface *interface) = 0;
|
||||
|
||||
virtual DisplayError CreateResourceExtn(const HWResourceInfo &hw_resource_info,
|
||||
ResourceInterface **interface) = 0;
|
||||
virtual DisplayError DestroyResourceExtn(ResourceInterface *interface) = 0;
|
||||
|
||||
virtual DisplayError CreateRotator(BufferAllocator *buffer_allocator,
|
||||
BufferSyncHandler *buffer_sync_handler,
|
||||
RotatorInterface **intf) = 0;
|
||||
virtual DisplayError DestroyRotator(RotatorInterface *intf) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~ExtensionInterface() { }
|
||||
};
|
||||
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __EXTENSION_INTERFACE_H__
|
||||
|
||||
340
sdm/include/private/hw_info_types.h
Normal file
340
sdm/include/private/hw_info_types.h
Normal file
@@ -0,0 +1,340 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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:
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
|
||||
* endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __HW_INFO_TYPES_H__
|
||||
#define __HW_INFO_TYPES_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <core/display_interface.h>
|
||||
|
||||
namespace sdm {
|
||||
|
||||
const int kMaxSDELayers = 16; // Maximum number of layers that can be handled by hardware in a
|
||||
// given layer stack.
|
||||
|
||||
enum HWDeviceType {
|
||||
kDevicePrimary,
|
||||
kDeviceHDMI,
|
||||
kDeviceVirtual,
|
||||
kDeviceRotator,
|
||||
kDeviceMax,
|
||||
};
|
||||
|
||||
enum HWBlockType {
|
||||
kHWPrimary,
|
||||
kHWHDMI,
|
||||
kHWWriteback0,
|
||||
kHWWriteback1,
|
||||
kHWWriteback2,
|
||||
kHWBlockMax
|
||||
};
|
||||
|
||||
enum HWDisplayMode {
|
||||
kModeDefault,
|
||||
kModeVideo,
|
||||
kModeCommand,
|
||||
};
|
||||
|
||||
enum HWDisplayPort {
|
||||
kPortDefault,
|
||||
kPortDSI,
|
||||
kPortDTv,
|
||||
kPortWriteBack,
|
||||
kPortLVDS,
|
||||
kPortEDP,
|
||||
};
|
||||
|
||||
struct HWResourceInfo {
|
||||
uint32_t hw_version;
|
||||
uint32_t hw_revision;
|
||||
uint32_t num_dma_pipe;
|
||||
uint32_t num_vig_pipe;
|
||||
uint32_t num_rgb_pipe;
|
||||
uint32_t num_cursor_pipe;
|
||||
uint32_t num_blending_stages;
|
||||
uint32_t num_rotator;
|
||||
uint32_t num_control;
|
||||
uint32_t num_mixer_to_disp;
|
||||
uint32_t smp_total;
|
||||
uint32_t smp_size;
|
||||
uint32_t num_smp_per_pipe;
|
||||
uint32_t max_scale_up;
|
||||
uint32_t max_scale_down;
|
||||
uint64_t max_bandwidth_low;
|
||||
uint64_t max_bandwidth_high;
|
||||
uint32_t max_mixer_width;
|
||||
uint32_t max_pipe_width;
|
||||
uint32_t max_pipe_bw;
|
||||
uint32_t max_sde_clk;
|
||||
float clk_fudge_factor;
|
||||
bool has_bwc;
|
||||
bool has_ubwc;
|
||||
bool has_decimation;
|
||||
bool has_macrotile;
|
||||
bool has_rotator_downscale;
|
||||
bool has_non_scalar_rgb;
|
||||
bool is_src_split;
|
||||
|
||||
HWResourceInfo()
|
||||
: hw_version(0), hw_revision(0), num_dma_pipe(0), num_vig_pipe(0), num_rgb_pipe(0),
|
||||
num_cursor_pipe(0), num_blending_stages(0), num_rotator(0), num_control(0),
|
||||
num_mixer_to_disp(0), smp_total(0), smp_size(0), num_smp_per_pipe(0), max_scale_up(1),
|
||||
max_scale_down(1), max_bandwidth_low(0), max_bandwidth_high(0), max_mixer_width(2048),
|
||||
max_pipe_width(2048), max_pipe_bw(0), max_sde_clk(0), clk_fudge_factor(1.0f), has_bwc(false),
|
||||
has_ubwc(false), has_decimation(false), has_macrotile(false), has_rotator_downscale(false),
|
||||
has_non_scalar_rgb(false), is_src_split(false) { }
|
||||
|
||||
void Reset() { *this = HWResourceInfo(); }
|
||||
};
|
||||
|
||||
struct HWSplitInfo {
|
||||
uint32_t left_split;
|
||||
uint32_t right_split;
|
||||
bool always_src_split;
|
||||
|
||||
HWSplitInfo() : left_split(0), right_split(0), always_src_split(false) { }
|
||||
|
||||
bool operator !=(const HWSplitInfo &split_info) {
|
||||
return ((left_split != split_info.left_split) || (right_split != split_info.right_split) ||
|
||||
(always_src_split != split_info.always_src_split));
|
||||
}
|
||||
|
||||
bool operator ==(const HWSplitInfo &split_info) {
|
||||
return !(operator !=(split_info));
|
||||
}
|
||||
};
|
||||
|
||||
struct HWPanelInfo {
|
||||
HWDisplayPort port; // Display port
|
||||
HWDisplayMode mode; // Display mode
|
||||
bool partial_update; // Partial update feature
|
||||
int left_align; // ROI left alignment restriction
|
||||
int width_align; // ROI width alignment restriction
|
||||
int top_align;; // ROI top alignment restriction
|
||||
int height_align; // ROI height alignment restriction
|
||||
int min_roi_width; // Min width needed for ROI
|
||||
int min_roi_height; // Min height needed for ROI
|
||||
bool needs_roi_merge; // Merge ROI's of both the DSI's
|
||||
bool dynamic_fps; // Panel Supports dynamic fps
|
||||
uint32_t min_fps; // Min fps supported by panel
|
||||
uint32_t max_fps; // Max fps supported by panel
|
||||
bool is_primary_panel; // Panel is primary display
|
||||
HWSplitInfo split_info; // Panel split configuration
|
||||
|
||||
HWPanelInfo() : port(kPortDefault), mode(kModeDefault), partial_update(false), left_align(false),
|
||||
width_align(false), top_align(false), height_align(false), min_roi_width(0), min_roi_height(0),
|
||||
needs_roi_merge(false), dynamic_fps(false), min_fps(0), max_fps(0) { }
|
||||
|
||||
bool operator !=(const HWPanelInfo &panel_info) {
|
||||
return ((port != panel_info.port) || (mode != panel_info.mode) ||
|
||||
(partial_update != panel_info.partial_update) ||
|
||||
(left_align != panel_info.left_align) || (width_align != panel_info.width_align) ||
|
||||
(top_align != panel_info.top_align) || (height_align != panel_info.height_align) ||
|
||||
(min_roi_width != panel_info.min_roi_width) ||
|
||||
(min_roi_height != panel_info.min_roi_height) ||
|
||||
(needs_roi_merge != panel_info.needs_roi_merge) ||
|
||||
(dynamic_fps != panel_info.dynamic_fps) || (min_fps != panel_info.min_fps) ||
|
||||
(max_fps != panel_info.max_fps) || (is_primary_panel != panel_info.is_primary_panel) ||
|
||||
(split_info != panel_info.split_info));
|
||||
}
|
||||
|
||||
bool operator ==(const HWPanelInfo &panel_info) {
|
||||
return !(operator !=(panel_info));
|
||||
}
|
||||
};
|
||||
|
||||
struct HWSessionConfig {
|
||||
uint32_t src_width;
|
||||
uint32_t src_height;
|
||||
LayerBufferFormat src_format;
|
||||
uint32_t dst_width;
|
||||
uint32_t dst_height;
|
||||
LayerBufferFormat dst_format;
|
||||
uint32_t buffer_count;
|
||||
bool secure;
|
||||
bool cache;
|
||||
uint32_t frame_rate;
|
||||
|
||||
HWSessionConfig()
|
||||
: src_width(0), src_height(0), src_format(kFormatInvalid), dst_width(0), dst_height(0),
|
||||
dst_format(kFormatInvalid), buffer_count(0), secure(false), cache(false), frame_rate(0) { }
|
||||
|
||||
bool operator != (const HWSessionConfig &input_config) const {
|
||||
if ((src_width != input_config.src_width) || (src_height != input_config.src_height) ||
|
||||
(src_format != input_config.src_format) || (dst_width != input_config.dst_width) ||
|
||||
(dst_height != input_config.dst_height) || (dst_format != input_config.dst_format) ||
|
||||
(buffer_count != input_config.buffer_count) || (secure != input_config.secure) ||
|
||||
(cache != input_config.cache) || (frame_rate != input_config.frame_rate)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator == (const HWSessionConfig &input_config) const {
|
||||
return !(operator != (input_config));
|
||||
}
|
||||
};
|
||||
|
||||
struct HWRotateInfo {
|
||||
uint32_t pipe_id;
|
||||
LayerRect src_roi;
|
||||
LayerRect dst_roi;
|
||||
HWBlockType writeback_id;
|
||||
bool valid;
|
||||
int rotate_id;
|
||||
|
||||
HWRotateInfo()
|
||||
: pipe_id(0), writeback_id(kHWWriteback0), valid(false), rotate_id(-1) { }
|
||||
|
||||
void Reset() { *this = HWRotateInfo(); }
|
||||
};
|
||||
|
||||
struct HWRotatorSession {
|
||||
HWRotateInfo hw_rotate_info[kMaxRotatePerLayer];
|
||||
uint32_t hw_block_count; // number of rotator hw blocks used by rotator session
|
||||
float downscale_ratio;
|
||||
LayerTransform transform;
|
||||
HWSessionConfig hw_session_config;
|
||||
LayerBuffer output_buffer;
|
||||
int session_id;
|
||||
float input_compression;
|
||||
float output_compression;
|
||||
|
||||
HWRotatorSession()
|
||||
: hw_block_count(0), downscale_ratio(1.0f), session_id(-1), input_compression(1.0f),
|
||||
output_compression(1.0f) { }
|
||||
};
|
||||
|
||||
struct HWPixelExtension {
|
||||
int extension; // Number of pixels extension in left, right, top and bottom directions for all
|
||||
// color components. This pixel value for each color component should be sum of
|
||||
// fetch and repeat pixels.
|
||||
|
||||
int overfetch; // Number of pixels need to be overfetched in left, right, top and bottom
|
||||
// directions from source image for scaling.
|
||||
|
||||
int repeat; // Number of pixels need to be repeated in left, right, top and bottom directions
|
||||
// for scaling.
|
||||
};
|
||||
|
||||
struct HWPlane {
|
||||
int init_phase_x;
|
||||
int phase_step_x;
|
||||
int init_phase_y;
|
||||
int phase_step_y;
|
||||
HWPixelExtension left;
|
||||
HWPixelExtension top;
|
||||
HWPixelExtension right;
|
||||
HWPixelExtension bottom;
|
||||
uint32_t roi_width;
|
||||
};
|
||||
|
||||
struct ScaleData {
|
||||
uint8_t enable_pixel_ext;
|
||||
uint32_t src_width;
|
||||
uint32_t src_height;
|
||||
HWPlane plane[4];
|
||||
};
|
||||
|
||||
struct HWPipeInfo {
|
||||
uint32_t pipe_id;
|
||||
LayerRect src_roi;
|
||||
LayerRect dst_roi;
|
||||
uint8_t horizontal_decimation;
|
||||
uint8_t vertical_decimation;
|
||||
ScaleData scale_data;
|
||||
bool valid;
|
||||
uint32_t z_order;
|
||||
|
||||
HWPipeInfo()
|
||||
: pipe_id(0), horizontal_decimation(0), vertical_decimation(0), valid(false), z_order(0) { }
|
||||
|
||||
void Reset() { *this = HWPipeInfo(); }
|
||||
};
|
||||
|
||||
struct HWLayerConfig {
|
||||
bool use_non_dma_pipe; // set by client
|
||||
HWPipeInfo left_pipe; // pipe for left side of output
|
||||
HWPipeInfo right_pipe; // pipe for right side of output
|
||||
HWRotatorSession hw_rotator_session;
|
||||
float compression;
|
||||
|
||||
HWLayerConfig() : use_non_dma_pipe(false), compression(1.0f) { }
|
||||
|
||||
void Reset() { *this = HWLayerConfig(); }
|
||||
};
|
||||
|
||||
struct HWLayersInfo {
|
||||
LayerStack *stack; // Input layer stack. Set by the caller.
|
||||
|
||||
uint32_t index[kMaxSDELayers];
|
||||
// Indexes of the layers from the layer stack which need to be
|
||||
// programmed on hardware.
|
||||
|
||||
uint32_t count; // Total number of layers which need to be set on hardware.
|
||||
|
||||
LayerRect left_partial_update;
|
||||
// Left ROI.
|
||||
|
||||
LayerRect right_partial_update;
|
||||
// Right ROI.
|
||||
|
||||
|
||||
HWLayersInfo() : stack(NULL), count(0) { }
|
||||
};
|
||||
|
||||
struct HWLayers {
|
||||
HWLayersInfo info;
|
||||
HWLayerConfig config[kMaxSDELayers];
|
||||
float output_compression;
|
||||
};
|
||||
|
||||
struct HWDisplayAttributes : DisplayConfigVariableInfo {
|
||||
bool is_device_split;
|
||||
uint32_t split_left;
|
||||
bool always_src_split;
|
||||
|
||||
HWDisplayAttributes() : is_device_split(false), split_left(0), always_src_split(false) { }
|
||||
|
||||
void Reset() { *this = HWDisplayAttributes(); }
|
||||
|
||||
bool operator !=(const HWDisplayAttributes &attributes) {
|
||||
return ((is_device_split != attributes.is_device_split) ||
|
||||
(split_left != attributes.split_left) ||
|
||||
(always_src_split != attributes.always_src_split) ||
|
||||
(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_total != attributes.v_total));
|
||||
}
|
||||
|
||||
bool operator ==(const HWDisplayAttributes &attributes) {
|
||||
return !(operator !=(attributes));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __HW_INFO_TYPES_H__
|
||||
|
||||
@@ -22,32 +22,26 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __HW_ROTATOR_INTERFACE_H__
|
||||
#define __HW_ROTATOR_INTERFACE_H__
|
||||
#ifndef __PARTIAL_UPDATE_INTERFACE_H__
|
||||
#define __PARTIAL_UPDATE_INTERFACE_H__
|
||||
|
||||
namespace sde {
|
||||
#include <core/display_interface.h>
|
||||
#include <core/buffer_allocator.h>
|
||||
#include <core/buffer_sync_handler.h>
|
||||
|
||||
class BufferSyncHandler;
|
||||
struct HWRotateInfo;
|
||||
struct HWLayers;
|
||||
struct HWRotatorSession;
|
||||
#include "hw_info_types.h"
|
||||
|
||||
class HWRotatorInterface {
|
||||
namespace sdm {
|
||||
|
||||
class PartialUpdateInterface {
|
||||
public:
|
||||
static DisplayError Create(BufferSyncHandler *buffer_sync_handler, HWRotatorInterface **intf);
|
||||
static DisplayError Destroy(HWRotatorInterface *intf);
|
||||
virtual DisplayError Open() = 0;
|
||||
virtual DisplayError Close() = 0;
|
||||
virtual DisplayError OpenSession(HWRotatorSession *hw_rotator_session) = 0;
|
||||
virtual DisplayError CloseSession(HWRotatorSession *hw_rotator_session) = 0;
|
||||
virtual DisplayError Validate(HWLayers *hw_layers) = 0;
|
||||
virtual DisplayError Commit(HWLayers *hw_layers) = 0;
|
||||
virtual DisplayError GenerateROI(HWLayersInfo *hw_layers_info) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~HWRotatorInterface() { }
|
||||
virtual ~PartialUpdateInterface() { }
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __HW_ROTATOR_INTERFACE_H__
|
||||
#endif // __PARTIAL_UPDATE_INTERFACE_H__
|
||||
|
||||
@@ -22,50 +22,36 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __SCALAR_HELPER_H__
|
||||
#define __SCALAR_HELPER_H__
|
||||
#ifndef __RESOURCE_INTERFACE_H__
|
||||
#define __RESOURCE_INTERFACE_H__
|
||||
|
||||
#include <hw_interface.h>
|
||||
#ifdef USES_SCALAR
|
||||
#include <scalar.h>
|
||||
#endif
|
||||
#include <core/display_interface.h>
|
||||
#include "hw_info_types.h"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
class Scalar {
|
||||
class ResourceInterface {
|
||||
public:
|
||||
static DisplayError CreateScalar(Scalar **scalar);
|
||||
static void Destroy(Scalar *scalar);
|
||||
virtual ~Scalar() { }
|
||||
virtual DisplayError ConfigureScale(HWLayers *hw_layers) { return kErrorNone; }
|
||||
virtual DisplayError RegisterDisplay(DisplayType type, const HWDisplayAttributes &attributes,
|
||||
const HWPanelInfo &hw_panel_info, 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 Start(Handle display_ctx) = 0;
|
||||
virtual DisplayError Stop(Handle display_ctx) = 0;
|
||||
virtual DisplayError Acquire(Handle display_ctx, HWLayers *hw_layers) = 0;
|
||||
virtual DisplayError PostPrepare(Handle display_ctx, HWLayers *hw_layers) = 0;
|
||||
virtual DisplayError PostCommit(Handle display_ctx, HWLayers *hw_layers) = 0;
|
||||
virtual void Purge(Handle display_ctx) = 0;
|
||||
virtual DisplayError SetMaxMixerStages(Handle display_ctx, uint32_t max_mixer_stages) = 0;
|
||||
virtual DisplayError ValidateScaling(const LayerRect &crop, const LayerRect &dst,
|
||||
bool rotate90) = 0;
|
||||
|
||||
protected:
|
||||
virtual DisplayError Init() { return kErrorNone; }
|
||||
virtual void Deinit() { }
|
||||
virtual ~ResourceInterface() { }
|
||||
};
|
||||
|
||||
#ifdef USES_SCALAR
|
||||
class ScalarHelper : public Scalar {
|
||||
public:
|
||||
ScalarHelper();
|
||||
virtual DisplayError ConfigureScale(HWLayers *hw_layers);
|
||||
} // namespace sdm
|
||||
|
||||
protected:
|
||||
virtual DisplayError Init();
|
||||
virtual void Deinit();
|
||||
#endif // __RESOURCE_INTERFACE_H__
|
||||
|
||||
private:
|
||||
const char *scalar_library_name_;
|
||||
const char *configure_scale_api_;
|
||||
void* lib_scalar_;
|
||||
int (*configure_scale_)(scalar::LayerInfo *layer);
|
||||
void SetPipeInfo(const HWPipeInfo &hw_pipe, scalar::PipeInfo *pipe);
|
||||
void UpdateSrcRoi(const scalar::PipeInfo &pipe, HWPipeInfo *hw_pipe);
|
||||
void SetScaleData(const scalar::PipeInfo &pipe, ScaleData *scale_data);
|
||||
uint32_t GetScalarFormat(LayerBufferFormat source);
|
||||
};
|
||||
#endif
|
||||
|
||||
} // namespace sde
|
||||
|
||||
#endif // __SCALAR_HELPER_H__
|
||||
@@ -22,44 +22,31 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __HW_ROTATOR_H__
|
||||
#define __HW_ROTATOR_H__
|
||||
#ifndef __ROTATOR_INTERFACE_H__
|
||||
#define __ROTATOR_INTERFACE_H__
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <linux/msm_mdp_ext.h>
|
||||
#include <video/msm_hdmi_modes.h>
|
||||
#include <linux/mdss_rotator.h>
|
||||
#include <poll.h>
|
||||
#include <pthread.h>
|
||||
#include <core/display_interface.h>
|
||||
#include <core/buffer_allocator.h>
|
||||
#include <core/buffer_sync_handler.h>
|
||||
|
||||
#include "hw_device.h"
|
||||
#include "hw_rotator_interface.h"
|
||||
#include "hw_info_types.h"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
class HWRotator : public HWDevice, public HWRotatorInterface {
|
||||
class RotatorInterface {
|
||||
public:
|
||||
explicit HWRotator(BufferSyncHandler *buffer_sync_handler);
|
||||
virtual DisplayError Open();
|
||||
virtual DisplayError Close();
|
||||
virtual DisplayError OpenSession(HWRotatorSession *hw_session_info);
|
||||
virtual DisplayError CloseSession(HWRotatorSession *hw_session_info);
|
||||
virtual DisplayError Validate(HWLayers *hw_layers);
|
||||
virtual DisplayError Commit(HWLayers *hw_layers);
|
||||
virtual DisplayError RegisterDisplay(DisplayType type, Handle *display_ctx) = 0;
|
||||
virtual void UnregisterDisplay(Handle display_ctx) = 0;
|
||||
virtual DisplayError Prepare(Handle display_ctx, HWLayers *hw_layers) = 0;
|
||||
virtual DisplayError Commit(Handle display_ctx, HWLayers *hw_layers) = 0;
|
||||
virtual DisplayError PostCommit(Handle display_ctx, HWLayers *hw_layers) = 0;
|
||||
virtual DisplayError Purge(Handle display_ctx, HWLayers *hw_layers) = 0;
|
||||
|
||||
private:
|
||||
void ResetParams();
|
||||
void SetCtrlParams(HWLayers *hw_layers);
|
||||
void SetBufferParams(HWLayers *hw_layers);
|
||||
void SetMDPFlags(const Layer &layer, uint32_t *rot_flags);
|
||||
|
||||
struct mdp_rotation_request mdp_rot_request_;
|
||||
struct mdp_rotation_item mdp_rot_layers_[kMaxSDELayers * 2]; // split panel (left + right)
|
||||
protected:
|
||||
virtual ~RotatorInterface() { }
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __HW_ROTATOR_H__
|
||||
#endif // __ROTATOR_INTERFACE_H__
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2014 - 2015, 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:
|
||||
@@ -22,38 +22,37 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __STRATEGY_DEFAULT_H__
|
||||
#define __STRATEGY_DEFAULT_H__
|
||||
#ifndef __STRATEGY_INTERFACE_H__
|
||||
#define __STRATEGY_INTERFACE_H__
|
||||
|
||||
#include <core/sdm_types.h>
|
||||
#include <core/display_interface.h>
|
||||
#include <private/strategy_interface.h>
|
||||
#include "hw_info_types.h"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
class StrategyDefault : public StrategyInterface {
|
||||
public:
|
||||
StrategyDefault(DisplayType type, const HWResourceInfo &hw_resource_info,
|
||||
const HWPanelInfo &hw_panel_info);
|
||||
static DisplayError CreateStrategyInterface(uint16_t version, DisplayType type,
|
||||
const HWResourceInfo &hw_resource_info,
|
||||
const HWPanelInfo &hw_panel_info,
|
||||
StrategyInterface **interface);
|
||||
static DisplayError DestroyStrategyInterface(StrategyInterface *interface);
|
||||
struct StrategyConstraints {
|
||||
bool safe_mode; //!< In this mode, strategy manager chooses the composition strategy
|
||||
//!< that requires minimum number of pipe for the current frame. i.e.,
|
||||
//!< video only composition, secure only composition or GPU composition
|
||||
|
||||
virtual DisplayError Start(HWLayersInfo *hw_layers_info, uint32_t *max_attempts);
|
||||
virtual DisplayError GetNextStrategy(StrategyConstraints *constraints);
|
||||
virtual DisplayError Stop();
|
||||
uint32_t max_layers; //!< Maximum number of layers that shall be programmed on hardware for the
|
||||
//!< given layer stack.
|
||||
|
||||
private:
|
||||
bool IsDisplaySplit(uint32_t fb_x_res);
|
||||
DisplayType type_;
|
||||
HWResourceInfo hw_resource_info_;
|
||||
HWPanelInfo hw_panel_info_;
|
||||
HWLayersInfo *hw_layers_info_;
|
||||
int fb_layer_index_;
|
||||
StrategyConstraints() : safe_mode(false), max_layers(kMaxSDELayers) { }
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
class StrategyInterface {
|
||||
public:
|
||||
virtual DisplayError Start(HWLayersInfo *hw_layers_info, uint32_t *max_attempts) = 0;
|
||||
virtual DisplayError GetNextStrategy(StrategyConstraints *constraints) = 0;
|
||||
virtual DisplayError Stop() = 0;
|
||||
|
||||
#endif // __STRATEGY_DEFAULT_H__
|
||||
protected:
|
||||
virtual ~StrategyInterface() { }
|
||||
};
|
||||
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __STRATEGY_INTERFACE_H__
|
||||
|
||||
@@ -76,14 +76,14 @@ inline T1 CeilToMultipleOf(const T1 &value, const T2 &factor) {
|
||||
return (T1)((value + (factor - 1)) & (~(factor - 1)));
|
||||
}
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
const int kThreadPriorityUrgent = -9;
|
||||
const int kMaxRotatePerLayer = 2;
|
||||
|
||||
typedef void * Handle;
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __CONSTANTS_H__
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#define __DEBUG_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <core/sde_types.h>
|
||||
#include <core/sdm_types.h>
|
||||
#include <core/debug_interface.h>
|
||||
|
||||
#define DLOG(tag, method, format, ...) Debug::Get()->method(tag, __CLASS__ "::%s: " format, \
|
||||
@@ -51,7 +51,7 @@
|
||||
#define DTRACE_END() Debug::Get()->EndTrace()
|
||||
#define DTRACE_SCOPED() ScopeTracer <Debug> scope_tracer(__CLASS__, __FUNCTION__)
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
class Debug {
|
||||
public:
|
||||
@@ -70,8 +70,8 @@ class Debug {
|
||||
private:
|
||||
Debug();
|
||||
|
||||
// By default, drop any log messages/traces coming from Display Engine. It will be overriden by
|
||||
// Display Engine client when core is successfully initialized.
|
||||
// By default, drop any log messages/traces coming from Display manager. It will be overriden by
|
||||
// Display manager client when core is successfully initialized.
|
||||
class DefaultDebugHandler : public DebugHandler {
|
||||
public:
|
||||
virtual void Error(DebugTag /*tag*/, const char */*format*/, ...) { }
|
||||
@@ -89,7 +89,7 @@ class Debug {
|
||||
static Debug debug_;
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __DEBUG_H__
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#define SEQUENCE_WAIT_SCOPE_LOCK(locker) Locker::SequenceWaitScopeLock lock(locker)
|
||||
#define SEQUENCE_CANCEL_SCOPE_LOCK(locker) Locker::SequenceCancelScopeLock lock(locker)
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
class Locker {
|
||||
public:
|
||||
@@ -159,7 +159,7 @@ class Locker {
|
||||
// further processing.
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __LOCKER_H__
|
||||
|
||||
@@ -31,11 +31,11 @@
|
||||
#define __RECT_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <core/sde_types.h>
|
||||
#include <core/sdm_types.h>
|
||||
#include <core/layer_stack.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
bool IsValid(const LayerRect &rect);
|
||||
bool IsCongruent(const LayerRect &rect1, const LayerRect &rect2);
|
||||
@@ -45,7 +45,7 @@ namespace sde {
|
||||
LayerRect Intersection(const LayerRect &rect1, const LayerRect &rect2);
|
||||
LayerRect Subtract(const LayerRect &rect1, const LayerRect &rect2);
|
||||
LayerRect Reposition(const LayerRect &rect1, const int &x_offset, const int &y_offset);
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __RECT_H__
|
||||
|
||||
@@ -1,19 +1,15 @@
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE := libsde
|
||||
LOCAL_MODULE := libsdmcore
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_C_INCLUDES := hardware/qcom/display/displayengine/include/ \
|
||||
LOCAL_C_INCLUDES := hardware/qcom/display/sdm/include/ \
|
||||
$(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
|
||||
LOCAL_CFLAGS := -Wno-missing-field-initializers -Wno-unused-parameter \
|
||||
-Wconversion -Wall -Werror \
|
||||
-DLOG_TAG=\"SDE\"
|
||||
ifeq ($(TARGET_USES_SCALAR), true)
|
||||
LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/scalar/inc
|
||||
LOCAL_CFLAGS += -DUSES_SCALAR
|
||||
endif
|
||||
-DLOG_TAG=\"SDM\"
|
||||
LOCAL_HW_INTF_PATH := fb
|
||||
LOCAL_SHARED_LIBRARIES := libdl libsdeutils libcutils
|
||||
LOCAL_SHARED_LIBRARIES := libdl libsdmutils
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
|
||||
LOCAL_SRC_FILES := core_interface.cpp \
|
||||
core_impl.cpp \
|
||||
@@ -22,17 +18,12 @@ LOCAL_SRC_FILES := core_interface.cpp \
|
||||
display_hdmi.cpp \
|
||||
display_virtual.cpp \
|
||||
comp_manager.cpp \
|
||||
strategy_default.cpp \
|
||||
res_manager.cpp \
|
||||
res_config.cpp \
|
||||
rotator_ctrl.cpp \
|
||||
strategy.cpp \
|
||||
resource_default.cpp \
|
||||
dump_impl.cpp \
|
||||
session_manager.cpp \
|
||||
scalar_helper.cpp \
|
||||
$(LOCAL_HW_INTF_PATH)/hw_info.cpp \
|
||||
$(LOCAL_HW_INTF_PATH)/hw_device.cpp \
|
||||
$(LOCAL_HW_INTF_PATH)/hw_primary.cpp \
|
||||
$(LOCAL_HW_INTF_PATH)/hw_rotator.cpp \
|
||||
$(LOCAL_HW_INTF_PATH)/hw_hdmi.cpp \
|
||||
$(LOCAL_HW_INTF_PATH)/hw_virtual.cpp
|
||||
|
||||
@@ -22,64 +22,41 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <utils/constants.h>
|
||||
#include <utils/debug.h>
|
||||
#include <core/buffer_allocator.h>
|
||||
|
||||
#include "comp_manager.h"
|
||||
#include "strategy_default.h"
|
||||
#include "strategy.h"
|
||||
|
||||
#define __CLASS__ "CompManager"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
CompManager::CompManager()
|
||||
: strategy_lib_(NULL), create_strategy_intf_(NULL), destroy_strategy_intf_(NULL),
|
||||
registered_displays_(0), configured_displays_(0), safe_mode_(false) {
|
||||
: resource_intf_(NULL), registered_displays_(0), configured_displays_(0), safe_mode_(false),
|
||||
extension_intf_(NULL) {
|
||||
}
|
||||
|
||||
DisplayError CompManager::Init(const HWResourceInfo &hw_res_info) {
|
||||
DisplayError CompManager::Init(const HWResourceInfo &hw_res_info,
|
||||
ExtensionInterface *extension_intf) {
|
||||
SCOPE_LOCK(locker_);
|
||||
|
||||
DisplayError error = kErrorNone;
|
||||
|
||||
error = res_mgr_.Init(hw_res_info);
|
||||
if (extension_intf) {
|
||||
error = extension_intf->CreateResourceExtn(hw_res_info, &resource_intf_);
|
||||
} else {
|
||||
resource_intf_ = &resource_default_;
|
||||
error = resource_default_.Init(hw_res_info);
|
||||
}
|
||||
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
|
||||
// Try to load strategy library & get handle to its interface.
|
||||
// Default to GPU only composition on failure.
|
||||
strategy_lib_ = ::dlopen(STRATEGY_LIBRARY_NAME, RTLD_NOW);
|
||||
if (strategy_lib_) {
|
||||
void **create_sym = reinterpret_cast<void **>(&create_strategy_intf_);
|
||||
void **destroy_sym = reinterpret_cast<void **>(&destroy_strategy_intf_);
|
||||
|
||||
*create_sym = ::dlsym(strategy_lib_, CREATE_STRATEGY_INTERFACE_NAME);
|
||||
*destroy_sym = ::dlsym(strategy_lib_, DESTROY_STRATEGY_INTERFACE_NAME);
|
||||
|
||||
if (!create_strategy_intf_) {
|
||||
DLOGE("Unable to find symbol for %s", CREATE_STRATEGY_INTERFACE_NAME);
|
||||
error = kErrorUndefined;
|
||||
}
|
||||
|
||||
if (!destroy_strategy_intf_) {
|
||||
DLOGE("Unable to find symbol for %s", DESTROY_STRATEGY_INTERFACE_NAME);
|
||||
error = kErrorUndefined;
|
||||
}
|
||||
|
||||
if (error != kErrorNone) {
|
||||
::dlclose(strategy_lib_);
|
||||
res_mgr_.Deinit();
|
||||
}
|
||||
} else {
|
||||
DLOGW("Unable to load = %s, using GPU only (default) composition", STRATEGY_LIBRARY_NAME);
|
||||
create_strategy_intf_ = StrategyDefault::CreateStrategyInterface;
|
||||
destroy_strategy_intf_ = StrategyDefault::DestroyStrategyInterface;
|
||||
}
|
||||
|
||||
hw_res_info_ = hw_res_info;
|
||||
extension_intf_ = extension_intf;
|
||||
|
||||
return error;
|
||||
}
|
||||
@@ -87,12 +64,12 @@ DisplayError CompManager::Init(const HWResourceInfo &hw_res_info) {
|
||||
DisplayError CompManager::Deinit() {
|
||||
SCOPE_LOCK(locker_);
|
||||
|
||||
if (strategy_lib_) {
|
||||
::dlclose(strategy_lib_);
|
||||
if (extension_intf_) {
|
||||
extension_intf_->DestroyResourceExtn(resource_intf_);
|
||||
} else {
|
||||
resource_default_.Deinit();
|
||||
}
|
||||
|
||||
res_mgr_.Deinit();
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
@@ -107,18 +84,26 @@ DisplayError CompManager::RegisterDisplay(DisplayType type, const HWDisplayAttri
|
||||
return kErrorMemory;
|
||||
}
|
||||
|
||||
if (create_strategy_intf_(STRATEGY_VERSION_TAG, type, hw_res_info_, hw_panel_info,
|
||||
&display_comp_ctx->strategy_intf) != kErrorNone) {
|
||||
DLOGW("Unable to create strategy interface");
|
||||
Strategy *&strategy = display_comp_ctx->strategy;
|
||||
strategy = new Strategy(extension_intf_, type, hw_res_info_, hw_panel_info);
|
||||
if (!strategy) {
|
||||
DLOGE("Unable to create strategy");
|
||||
delete display_comp_ctx;
|
||||
display_comp_ctx = NULL;
|
||||
return kErrorUndefined;
|
||||
return kErrorMemory;
|
||||
}
|
||||
|
||||
error = res_mgr_.RegisterDisplay(type, attributes, hw_panel_info,
|
||||
error = strategy->Init();
|
||||
if (error != kErrorNone) {
|
||||
delete strategy;
|
||||
delete display_comp_ctx;
|
||||
return error;
|
||||
}
|
||||
|
||||
error = resource_intf_->RegisterDisplay(type, attributes, hw_panel_info,
|
||||
&display_comp_ctx->display_resource_ctx);
|
||||
if (error != kErrorNone) {
|
||||
destroy_strategy_intf_(display_comp_ctx->strategy_intf);
|
||||
strategy->Deinit();
|
||||
delete strategy;
|
||||
delete display_comp_ctx;
|
||||
display_comp_ctx = NULL;
|
||||
return error;
|
||||
@@ -150,8 +135,11 @@ DisplayError CompManager::UnregisterDisplay(Handle comp_handle) {
|
||||
return kErrorParameters;
|
||||
}
|
||||
|
||||
res_mgr_.UnregisterDisplay(display_comp_ctx->display_resource_ctx);
|
||||
destroy_strategy_intf_(display_comp_ctx->strategy_intf);
|
||||
resource_intf_->UnregisterDisplay(display_comp_ctx->display_resource_ctx);
|
||||
|
||||
Strategy *&strategy = display_comp_ctx->strategy;
|
||||
strategy->Deinit();
|
||||
delete strategy;
|
||||
|
||||
CLEAR_BIT(registered_displays_, display_comp_ctx->display_type);
|
||||
CLEAR_BIT(configured_displays_, display_comp_ctx->display_type);
|
||||
@@ -170,7 +158,8 @@ void CompManager::ReconfigureDisplay(Handle comp_handle, const HWDisplayAttribut
|
||||
DisplayCompositionContext *display_comp_ctx =
|
||||
reinterpret_cast<DisplayCompositionContext *>(comp_handle);
|
||||
|
||||
res_mgr_.ReconfigureDisplay(display_comp_ctx->display_resource_ctx, attributes, hw_panel_info);
|
||||
resource_intf_->ReconfigureDisplay(display_comp_ctx->display_resource_ctx, attributes,
|
||||
hw_panel_info);
|
||||
|
||||
// TODO(user): Need to reconfigure strategy with updated panel info
|
||||
}
|
||||
@@ -201,8 +190,7 @@ void CompManager::PrePrepare(Handle display_ctx, HWLayers *hw_layers) {
|
||||
SCOPE_LOCK(locker_);
|
||||
DisplayCompositionContext *display_comp_ctx =
|
||||
reinterpret_cast<DisplayCompositionContext *>(display_ctx);
|
||||
display_comp_ctx->strategy_intf->Start(&hw_layers->info,
|
||||
&display_comp_ctx->max_strategies);
|
||||
display_comp_ctx->strategy->Start(&hw_layers->info, &display_comp_ctx->max_strategies);
|
||||
display_comp_ctx->remaining_strategies = display_comp_ctx->max_strategies;
|
||||
|
||||
// Avoid idle fallback, if there is only one app layer.
|
||||
@@ -225,12 +213,12 @@ DisplayError CompManager::Prepare(Handle display_ctx, HWLayers *hw_layers) {
|
||||
PrepareStrategyConstraints(display_ctx, hw_layers);
|
||||
|
||||
// Select a composition strategy, and try to allocate resources for it.
|
||||
res_mgr_.Start(display_resource_ctx);
|
||||
resource_intf_->Start(display_resource_ctx);
|
||||
|
||||
bool exit = false;
|
||||
uint32_t &count = display_comp_ctx->remaining_strategies;
|
||||
for (; !exit && count > 0; count--) {
|
||||
error = display_comp_ctx->strategy_intf->GetNextStrategy(&display_comp_ctx->constraints);
|
||||
error = display_comp_ctx->strategy->GetNextStrategy(&display_comp_ctx->constraints);
|
||||
if (error != kErrorNone) {
|
||||
// Composition strategies exhausted. Resource Manager could not allocate resources even for
|
||||
// GPU composition. This will never happen.
|
||||
@@ -238,7 +226,7 @@ DisplayError CompManager::Prepare(Handle display_ctx, HWLayers *hw_layers) {
|
||||
}
|
||||
|
||||
if (!exit) {
|
||||
error = res_mgr_.Acquire(display_resource_ctx, hw_layers);
|
||||
error = resource_intf_->Acquire(display_resource_ctx, hw_layers);
|
||||
// Exit if successfully allocated resource, else try next strategy.
|
||||
exit = (error == kErrorNone);
|
||||
}
|
||||
@@ -248,7 +236,7 @@ DisplayError CompManager::Prepare(Handle display_ctx, HWLayers *hw_layers) {
|
||||
DLOGE("Composition strategies exhausted for display = %d", display_comp_ctx->display_type);
|
||||
}
|
||||
|
||||
res_mgr_.Stop(display_resource_ctx);
|
||||
resource_intf_->Stop(display_resource_ctx);
|
||||
|
||||
return error;
|
||||
}
|
||||
@@ -260,12 +248,12 @@ DisplayError CompManager::PostPrepare(Handle display_ctx, HWLayers *hw_layers) {
|
||||
Handle &display_resource_ctx = display_comp_ctx->display_resource_ctx;
|
||||
|
||||
DisplayError error = kErrorNone;
|
||||
error = res_mgr_.PostPrepare(display_resource_ctx, hw_layers);
|
||||
error = resource_intf_->PostPrepare(display_resource_ctx, hw_layers);
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
|
||||
display_comp_ctx->strategy_intf->Stop();
|
||||
display_comp_ctx->strategy->Stop();
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
@@ -281,7 +269,7 @@ DisplayError CompManager::PostCommit(Handle display_ctx, HWLayers *hw_layers) {
|
||||
safe_mode_ = false;
|
||||
}
|
||||
|
||||
error = res_mgr_.PostCommit(display_comp_ctx->display_resource_ctx, hw_layers);
|
||||
error = resource_intf_->PostCommit(display_comp_ctx->display_resource_ctx, hw_layers);
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
@@ -301,7 +289,7 @@ void CompManager::Purge(Handle display_ctx) {
|
||||
DisplayCompositionContext *display_comp_ctx =
|
||||
reinterpret_cast<DisplayCompositionContext *>(display_ctx);
|
||||
|
||||
res_mgr_.Purge(display_comp_ctx->display_resource_ctx);
|
||||
resource_intf_->Purge(display_comp_ctx->display_resource_ctx);
|
||||
}
|
||||
|
||||
bool CompManager::ProcessIdleTimeout(Handle display_ctx) {
|
||||
@@ -351,7 +339,8 @@ DisplayError CompManager::SetMaxMixerStages(Handle display_ctx, uint32_t max_mix
|
||||
reinterpret_cast<DisplayCompositionContext *>(display_ctx);
|
||||
|
||||
if (display_comp_ctx) {
|
||||
error = res_mgr_.SetMaxMixerStages(display_comp_ctx->display_resource_ctx, max_mixer_stages);
|
||||
error = resource_intf_->SetMaxMixerStages(display_comp_ctx->display_resource_ctx,
|
||||
max_mixer_stages);
|
||||
}
|
||||
|
||||
return error;
|
||||
@@ -363,8 +352,8 @@ void CompManager::AppendDump(char *buffer, uint32_t length) {
|
||||
|
||||
DisplayError CompManager::ValidateScaling(const LayerRect &crop, const LayerRect &dst,
|
||||
bool rotate90) {
|
||||
return res_mgr_.ValidateScaling(crop, dst, rotate90);
|
||||
return resource_intf_->ValidateScaling(crop, dst, rotate90);
|
||||
}
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
@@ -26,17 +26,20 @@
|
||||
#define __COMP_MANAGER_H__
|
||||
|
||||
#include <core/display_interface.h>
|
||||
#include <private/extension_interface.h>
|
||||
#include <utils/locker.h>
|
||||
|
||||
#include "strategy.h"
|
||||
#include "resource_default.h"
|
||||
#include "hw_interface.h"
|
||||
#include "res_manager.h"
|
||||
#include "dump_impl.h"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
class CompManager : public DumpImpl {
|
||||
public:
|
||||
CompManager();
|
||||
DisplayError Init(const HWResourceInfo &hw_res_info_);
|
||||
DisplayError Init(const HWResourceInfo &hw_res_info_, ExtensionInterface *extension_intf);
|
||||
DisplayError Deinit();
|
||||
DisplayError RegisterDisplay(DisplayType type, const HWDisplayAttributes &attributes,
|
||||
const HWPanelInfo &hw_panel_info, Handle *res_mgr_hnd);
|
||||
@@ -62,7 +65,7 @@ class CompManager : public DumpImpl {
|
||||
void PrepareStrategyConstraints(Handle display_ctx, HWLayers *hw_layers);
|
||||
|
||||
struct DisplayCompositionContext {
|
||||
StrategyInterface *strategy_intf;
|
||||
Strategy *strategy;
|
||||
StrategyConstraints constraints;
|
||||
Handle display_resource_ctx;
|
||||
DisplayType display_type;
|
||||
@@ -79,19 +82,18 @@ class CompManager : public DumpImpl {
|
||||
};
|
||||
|
||||
Locker locker_;
|
||||
void *strategy_lib_;
|
||||
CreateStrategyInterface create_strategy_intf_;
|
||||
DestroyStrategyInterface destroy_strategy_intf_;
|
||||
ResManager res_mgr_;
|
||||
ResourceInterface *resource_intf_;
|
||||
ResourceDefault resource_default_;
|
||||
uint64_t registered_displays_; // Stores the bit mask of registered displays
|
||||
uint64_t configured_displays_; // Stores the bit mask of sucessfully configured displays
|
||||
bool safe_mode_; // Flag to notify all displays to be in resource crunch
|
||||
// mode, where strategy manager chooses the best strategy
|
||||
// that uses optimal number of pipes for each display
|
||||
HWResourceInfo hw_res_info_;
|
||||
ExtensionInterface *extension_intf_;
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __COMP_MANAGER_H__
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <utils/locker.h>
|
||||
#include <utils/constants.h>
|
||||
#include <utils/debug.h>
|
||||
@@ -31,65 +32,93 @@
|
||||
#include "display_hdmi.h"
|
||||
#include "display_virtual.h"
|
||||
#include "hw_info_interface.h"
|
||||
#include "rotator_ctrl.h"
|
||||
|
||||
#define __CLASS__ "CoreImpl"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
CoreImpl::CoreImpl(CoreEventHandler *event_handler, BufferAllocator *buffer_allocator,
|
||||
BufferSyncHandler *buffer_sync_handler)
|
||||
: event_handler_(event_handler), buffer_allocator_(buffer_allocator),
|
||||
buffer_sync_handler_(buffer_sync_handler), hw_resource_(NULL), rotator_ctrl_(NULL) {
|
||||
buffer_sync_handler_(buffer_sync_handler), hw_resource_(NULL), hw_info_intf_(NULL),
|
||||
rotator_intf_(NULL), extension_lib_(NULL), extension_intf_(NULL),
|
||||
create_extension_intf_(NULL), destroy_extension_intf_(NULL) {
|
||||
}
|
||||
|
||||
DisplayError CoreImpl::Init() {
|
||||
SCOPE_LOCK(locker_);
|
||||
DisplayError error = kErrorNone;
|
||||
|
||||
// Try to load extension library & get handle to its interface.
|
||||
extension_lib_ = ::dlopen(EXTENSION_LIBRARY_NAME, RTLD_NOW);
|
||||
if (extension_lib_) {
|
||||
void **create_sym = reinterpret_cast<void **>(&create_extension_intf_);
|
||||
void **destroy_sym = reinterpret_cast<void **>(&destroy_extension_intf_);
|
||||
|
||||
*create_sym = ::dlsym(extension_lib_, CREATE_EXTENSION_INTERFACE_NAME);
|
||||
*destroy_sym = ::dlsym(extension_lib_, DESTROY_EXTENSION_INTERFACE_NAME);
|
||||
|
||||
if (!create_extension_intf_ || !destroy_extension_intf_) {
|
||||
DLOGE("Unable to load symbols");
|
||||
::dlclose(extension_lib_);
|
||||
return kErrorUndefined;
|
||||
}
|
||||
|
||||
error = create_extension_intf_(EXTENSION_VERSION_TAG, &extension_intf_);
|
||||
if(error != kErrorNone) {
|
||||
DLOGE("Unable to create interface");
|
||||
::dlclose(extension_lib_);
|
||||
return error;
|
||||
}
|
||||
} else {
|
||||
DLOGW("Unable to load = %s", EXTENSION_LIBRARY_NAME);
|
||||
}
|
||||
|
||||
error = HWInfoInterface::Create(&hw_info_intf_);
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
goto CleanupOnError;
|
||||
}
|
||||
|
||||
hw_resource_ = new HWResourceInfo();
|
||||
if (!hw_resource_) {
|
||||
error = kErrorMemory;
|
||||
goto CleanUpOnError;
|
||||
goto CleanupOnError;
|
||||
}
|
||||
|
||||
error = hw_info_intf_->GetHWResourceInfo(hw_resource_);
|
||||
if (error != kErrorNone) {
|
||||
goto CleanUpOnError;
|
||||
goto CleanupOnError;
|
||||
}
|
||||
|
||||
error = comp_mgr_.Init(*hw_resource_);
|
||||
error = comp_mgr_.Init(*hw_resource_, extension_intf_);
|
||||
if (error != kErrorNone) {
|
||||
goto CleanUpOnError;
|
||||
goto CleanupOnError;
|
||||
}
|
||||
|
||||
rotator_ctrl_ = new RotatorCtrl();
|
||||
if (!rotator_ctrl_) {
|
||||
if (extension_intf_) {
|
||||
error = extension_intf_->CreateRotator(buffer_allocator_, buffer_sync_handler_,
|
||||
&rotator_intf_);
|
||||
if (error != kErrorNone) {
|
||||
comp_mgr_.Deinit();
|
||||
error = kErrorMemory;
|
||||
goto CleanUpOnError;
|
||||
goto CleanupOnError;
|
||||
}
|
||||
|
||||
error = rotator_ctrl_->Init(buffer_allocator_, buffer_sync_handler_);
|
||||
if (error != kErrorNone) {
|
||||
delete rotator_ctrl_;
|
||||
rotator_ctrl_ = NULL;
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
|
||||
CleanUpOnError:
|
||||
if (hw_resource_) {
|
||||
delete hw_resource_;
|
||||
hw_resource_ = NULL;
|
||||
CleanupOnError:
|
||||
if (hw_info_intf_) {
|
||||
HWInfoInterface::Destroy(hw_info_intf_);
|
||||
}
|
||||
|
||||
HWInfoInterface::Destroy(hw_info_intf_);
|
||||
if (hw_resource_) {
|
||||
delete hw_resource_;
|
||||
}
|
||||
|
||||
if (extension_lib_) {
|
||||
destroy_extension_intf_(extension_intf_);
|
||||
::dlclose(extension_lib_);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
@@ -97,10 +126,22 @@ CleanUpOnError:
|
||||
DisplayError CoreImpl::Deinit() {
|
||||
SCOPE_LOCK(locker_);
|
||||
|
||||
rotator_ctrl_->Deinit();
|
||||
if (extension_intf_) {
|
||||
extension_intf_->DestroyRotator(rotator_intf_);
|
||||
}
|
||||
|
||||
comp_mgr_.Deinit();
|
||||
HWInfoInterface::Destroy(hw_info_intf_);
|
||||
|
||||
if (hw_resource_) {
|
||||
delete hw_resource_;
|
||||
}
|
||||
|
||||
if (extension_lib_) {
|
||||
destroy_extension_intf_(extension_intf_);
|
||||
::dlclose(extension_lib_);
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
@@ -117,15 +158,15 @@ DisplayError CoreImpl::CreateDisplay(DisplayType type, DisplayEventHandler *even
|
||||
switch (type) {
|
||||
case kPrimary:
|
||||
display_base = new DisplayPrimary(event_handler, hw_info_intf_, buffer_sync_handler_,
|
||||
&comp_mgr_, rotator_ctrl_);
|
||||
&comp_mgr_, rotator_intf_);
|
||||
break;
|
||||
case kHDMI:
|
||||
display_base = new DisplayHDMI(event_handler, hw_info_intf_, buffer_sync_handler_,
|
||||
&comp_mgr_, rotator_ctrl_);
|
||||
&comp_mgr_, rotator_intf_);
|
||||
break;
|
||||
case kVirtual:
|
||||
display_base = new DisplayVirtual(event_handler, hw_info_intf_, buffer_sync_handler_,
|
||||
&comp_mgr_, rotator_ctrl_);
|
||||
&comp_mgr_, rotator_intf_);
|
||||
break;
|
||||
default:
|
||||
DLOGE("Spurious display type %d", type);
|
||||
@@ -163,5 +204,5 @@ DisplayError CoreImpl::DestroyDisplay(DisplayInterface *intf) {
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#define __CORE_IMPL_H__
|
||||
|
||||
#include <core/core_interface.h>
|
||||
#include <private/strategy_interface.h>
|
||||
#include <private/extension_interface.h>
|
||||
#include <utils/locker.h>
|
||||
|
||||
#include "hw_interface.h"
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
#define SET_REVISION(major, minor) ((major << 8) | minor)
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
class HWInfoInterface;
|
||||
class RotatorCtrl;
|
||||
@@ -66,11 +66,15 @@ class CoreImpl : public CoreInterface {
|
||||
BufferSyncHandler *buffer_sync_handler_;
|
||||
HWResourceInfo *hw_resource_;
|
||||
CompManager comp_mgr_;
|
||||
RotatorCtrl *rotator_ctrl_;
|
||||
HWInfoInterface *hw_info_intf_;
|
||||
RotatorInterface *rotator_intf_;
|
||||
void *extension_lib_;
|
||||
ExtensionInterface *extension_intf_;
|
||||
CreateExtensionInterface create_extension_intf_;
|
||||
DestroyExtensionInterface destroy_extension_intf_;
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __CORE_IMPL_H__
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
#define GET_DATA_ALIGNMENT(version) ((version >> 8) & 0xFF)
|
||||
#define GET_INSTRUCTION_SET(version) (version & 0xFF)
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
// Currently, we support only one client and one session for display core. So, create a global
|
||||
// singleton core object.
|
||||
@@ -63,7 +63,7 @@ DisplayError CoreInterface::CreateCore(CoreEventHandler *event_handler, DebugHan
|
||||
}
|
||||
|
||||
// Check compatibility of client and core.
|
||||
uint32_t lib_version = SDE_VERSION_TAG;
|
||||
uint32_t lib_version = SDM_VERSION_TAG;
|
||||
if (GET_REVISION(client_version) > GET_REVISION(lib_version)) {
|
||||
return kErrorVersion;
|
||||
} else if (GET_DATA_ALIGNMENT(client_version) != GET_DATA_ALIGNMENT(lib_version)) {
|
||||
@@ -120,5 +120,5 @@ DisplayError CoreInterface::DestroyCore() {
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
@@ -27,19 +27,18 @@
|
||||
#include <utils/debug.h>
|
||||
|
||||
#include "display_base.h"
|
||||
#include "rotator_ctrl.h"
|
||||
|
||||
#define __CLASS__ "DisplayBase"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
// TODO(user): Have a single structure handle carries all the interface pointers and variables.
|
||||
DisplayBase::DisplayBase(DisplayType display_type, DisplayEventHandler *event_handler,
|
||||
HWDeviceType hw_device_type, BufferSyncHandler *buffer_sync_handler,
|
||||
CompManager *comp_manager, RotatorCtrl *rotator_ctrl)
|
||||
CompManager *comp_manager, RotatorInterface *rotator_intf)
|
||||
: display_type_(display_type), event_handler_(event_handler), hw_device_type_(hw_device_type),
|
||||
buffer_sync_handler_(buffer_sync_handler), comp_manager_(comp_manager),
|
||||
rotator_ctrl_(rotator_ctrl), state_(kStateOff), hw_device_(0), display_comp_ctx_(0),
|
||||
rotator_intf_(rotator_intf), state_(kStateOff), hw_device_(0), display_comp_ctx_(0),
|
||||
display_attributes_(NULL), num_modes_(0), active_mode_index_(0), pending_commit_(false),
|
||||
vsync_enable_(false), underscan_supported_(false) {
|
||||
}
|
||||
@@ -80,8 +79,8 @@ DisplayError DisplayBase::Init() {
|
||||
goto CleanupOnError;
|
||||
}
|
||||
|
||||
if (rotator_ctrl_) {
|
||||
error = rotator_ctrl_->RegisterDisplay(display_type_, &display_rotator_ctx_);
|
||||
if (rotator_intf_) {
|
||||
error = rotator_intf_->RegisterDisplay(display_type_, &display_rotator_ctx_);
|
||||
if (error != kErrorNone) {
|
||||
goto CleanupOnError;
|
||||
}
|
||||
@@ -105,8 +104,8 @@ CleanupOnError:
|
||||
}
|
||||
|
||||
DisplayError DisplayBase::Deinit() {
|
||||
if (rotator_ctrl_) {
|
||||
rotator_ctrl_->UnregisterDisplay(display_rotator_ctx_);
|
||||
if (rotator_intf_) {
|
||||
rotator_intf_->UnregisterDisplay(display_rotator_ctx_);
|
||||
}
|
||||
|
||||
comp_manager_->UnregisterDisplay(display_comp_ctx_);
|
||||
@@ -134,6 +133,7 @@ DisplayError DisplayBase::Prepare(LayerStack *layer_stack) {
|
||||
// Clean hw layers for reuse.
|
||||
hw_layers_.info = HWLayersInfo();
|
||||
hw_layers_.info.stack = layer_stack;
|
||||
hw_layers_.output_compression = 1.0f;
|
||||
|
||||
comp_manager_->PrePrepare(display_comp_ctx_, &hw_layers_);
|
||||
while (true) {
|
||||
@@ -143,14 +143,14 @@ DisplayError DisplayBase::Prepare(LayerStack *layer_stack) {
|
||||
}
|
||||
|
||||
if (IsRotationRequired(&hw_layers_)) {
|
||||
if (!rotator_ctrl_) {
|
||||
if (!rotator_intf_) {
|
||||
continue;
|
||||
}
|
||||
error = rotator_ctrl_->Prepare(display_rotator_ctx_, &hw_layers_);
|
||||
error = rotator_intf_->Prepare(display_rotator_ctx_, &hw_layers_);
|
||||
} else {
|
||||
// Release all the previous rotator sessions.
|
||||
if (rotator_ctrl_) {
|
||||
error = rotator_ctrl_->Purge(display_rotator_ctx_, &hw_layers_);
|
||||
if (rotator_intf_) {
|
||||
error = rotator_intf_->Purge(display_rotator_ctx_, &hw_layers_);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,8 +189,8 @@ DisplayError DisplayBase::Commit(LayerStack *layer_stack) {
|
||||
|
||||
pending_commit_ = false;
|
||||
|
||||
if (rotator_ctrl_ && IsRotationRequired(&hw_layers_)) {
|
||||
error = rotator_ctrl_->Commit(display_rotator_ctx_, &hw_layers_);
|
||||
if (rotator_intf_ && IsRotationRequired(&hw_layers_)) {
|
||||
error = rotator_intf_->Commit(display_rotator_ctx_, &hw_layers_);
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
@@ -201,8 +201,8 @@ DisplayError DisplayBase::Commit(LayerStack *layer_stack) {
|
||||
return error;
|
||||
}
|
||||
|
||||
if (rotator_ctrl_ && IsRotationRequired(&hw_layers_)) {
|
||||
error = rotator_ctrl_->PostCommit(display_rotator_ctx_, &hw_layers_);
|
||||
if (rotator_intf_ && IsRotationRequired(&hw_layers_)) {
|
||||
error = rotator_intf_->PostCommit(display_rotator_ctx_, &hw_layers_);
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
@@ -561,4 +561,4 @@ const char * DisplayBase::GetName(const LayerBufferFormat &format) {
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
@@ -27,13 +27,14 @@
|
||||
|
||||
#include <core/display_interface.h>
|
||||
#include <private/strategy_interface.h>
|
||||
#include <private/rotator_interface.h>
|
||||
#include <utils/locker.h>
|
||||
|
||||
#include "hw_interface.h"
|
||||
#include "comp_manager.h"
|
||||
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
class RotatorCtrl;
|
||||
|
||||
@@ -41,7 +42,7 @@ class DisplayBase : public DisplayInterface {
|
||||
public:
|
||||
DisplayBase(DisplayType display_type, DisplayEventHandler *event_handler,
|
||||
HWDeviceType hw_device_type, BufferSyncHandler *buffer_sync_handler,
|
||||
CompManager *comp_manager, RotatorCtrl *rotator_ctrl);
|
||||
CompManager *comp_manager, RotatorInterface *rotator_intf);
|
||||
virtual ~DisplayBase() { }
|
||||
virtual DisplayError Init();
|
||||
virtual DisplayError Deinit();
|
||||
@@ -77,7 +78,7 @@ class DisplayBase : public DisplayInterface {
|
||||
HWPanelInfo hw_panel_info_;
|
||||
BufferSyncHandler *buffer_sync_handler_;
|
||||
CompManager *comp_manager_;
|
||||
RotatorCtrl *rotator_ctrl_;
|
||||
RotatorInterface *rotator_intf_;
|
||||
DisplayState state_;
|
||||
Handle hw_device_;
|
||||
Handle display_comp_ctx_;
|
||||
@@ -91,7 +92,7 @@ class DisplayBase : public DisplayInterface {
|
||||
bool underscan_supported_;
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __DISPLAY_BASE_H__
|
||||
|
||||
@@ -31,13 +31,13 @@
|
||||
|
||||
#define __CLASS__ "DisplayHDMI"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
DisplayHDMI::DisplayHDMI(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
|
||||
BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager,
|
||||
RotatorCtrl *rotator_ctrl)
|
||||
RotatorInterface *rotator_intf)
|
||||
: DisplayBase(kHDMI, event_handler, kDeviceHDMI, buffer_sync_handler, comp_manager,
|
||||
rotator_ctrl), hw_info_intf_(hw_info_intf) {
|
||||
rotator_intf), hw_info_intf_(hw_info_intf) {
|
||||
}
|
||||
|
||||
DisplayError DisplayHDMI::Init() {
|
||||
@@ -247,5 +247,5 @@ void DisplayHDMI::AppendDump(char *buffer, uint32_t length) {
|
||||
DisplayBase::AppendDump(buffer, length);
|
||||
}
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include "display_base.h"
|
||||
#include "dump_impl.h"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
class HWHDMIInterface;
|
||||
class HWInfoInterface;
|
||||
@@ -37,7 +37,7 @@ class DisplayHDMI : public DisplayBase, DumpImpl {
|
||||
public:
|
||||
DisplayHDMI(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
|
||||
BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager,
|
||||
RotatorCtrl *rotator_ctrl);
|
||||
RotatorInterface *rotator_intf);
|
||||
virtual DisplayError Init();
|
||||
virtual DisplayError Deinit();
|
||||
virtual DisplayError Prepare(LayerStack *layer_stack);
|
||||
@@ -71,7 +71,7 @@ class DisplayHDMI : public DisplayBase, DumpImpl {
|
||||
HWScanSupport scan_support_;
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __DISPLAY_HDMI_H__
|
||||
|
||||
@@ -31,13 +31,13 @@
|
||||
|
||||
#define __CLASS__ "DisplayPrimary"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
DisplayPrimary::DisplayPrimary(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
|
||||
BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager,
|
||||
RotatorCtrl *rotator_ctrl)
|
||||
RotatorInterface *rotator_intf)
|
||||
: DisplayBase(kPrimary, event_handler, kDevicePrimary, buffer_sync_handler, comp_manager,
|
||||
rotator_ctrl), hw_info_intf_(hw_info_intf) {
|
||||
rotator_intf), hw_info_intf_(hw_info_intf) {
|
||||
}
|
||||
|
||||
DisplayError DisplayPrimary::Init() {
|
||||
@@ -288,5 +288,5 @@ void DisplayPrimary::ThermalEvent(int64_t thermal_level) {
|
||||
comp_manager_->ProcessThermalEvent(display_comp_ctx_, thermal_level);
|
||||
}
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include "display_base.h"
|
||||
#include "dump_impl.h"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
class HWPrimaryInterface;
|
||||
class HWInfoInterface;
|
||||
@@ -37,7 +37,7 @@ class DisplayPrimary : public DisplayBase, DumpImpl, HWEventHandler {
|
||||
public:
|
||||
DisplayPrimary(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
|
||||
BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager,
|
||||
RotatorCtrl *rotator_ctrl);
|
||||
RotatorInterface *rotator_intf);
|
||||
virtual DisplayError Init();
|
||||
virtual DisplayError Deinit();
|
||||
virtual DisplayError Prepare(LayerStack *layer_stack);
|
||||
@@ -73,7 +73,7 @@ class DisplayPrimary : public DisplayBase, DumpImpl, HWEventHandler {
|
||||
HWInfoInterface *hw_info_intf_;
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __DISPLAY_PRIMARY_H__
|
||||
|
||||
@@ -31,13 +31,13 @@
|
||||
|
||||
#define __CLASS__ "DisplayVirtual"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
DisplayVirtual::DisplayVirtual(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
|
||||
BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager,
|
||||
RotatorCtrl *rotator_ctrl)
|
||||
RotatorInterface *rotator_intf)
|
||||
: DisplayBase(kVirtual, event_handler, kDeviceVirtual, buffer_sync_handler, comp_manager,
|
||||
rotator_ctrl), hw_info_intf_(hw_info_intf) {
|
||||
rotator_intf), hw_info_intf_(hw_info_intf) {
|
||||
}
|
||||
|
||||
DisplayError DisplayVirtual::Init() {
|
||||
@@ -199,5 +199,5 @@ void DisplayVirtual::AppendDump(char *buffer, uint32_t length) {
|
||||
DisplayBase::AppendDump(buffer, length);
|
||||
}
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include "display_base.h"
|
||||
#include "dump_impl.h"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
class HWVirtualInterface;
|
||||
class HWInfoInterface;
|
||||
@@ -37,7 +37,7 @@ class DisplayVirtual : public DisplayBase, DumpImpl {
|
||||
public:
|
||||
DisplayVirtual(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
|
||||
BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager,
|
||||
RotatorCtrl *rotator_ctrl);
|
||||
RotatorInterface *rotator_intf);
|
||||
virtual DisplayError Init();
|
||||
virtual DisplayError Deinit();
|
||||
virtual DisplayError Prepare(LayerStack *layer_stack);
|
||||
@@ -67,7 +67,7 @@ class DisplayVirtual : public DisplayBase, DumpImpl {
|
||||
HWInfoInterface *hw_info_intf_;
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __DISPLAY_VIRTUAL_H__
|
||||
|
||||
6
displayengine/libs/core/dump_impl.cpp → sdm/libs/core/dump_impl.cpp
Executable file → Normal file
6
displayengine/libs/core/dump_impl.cpp → sdm/libs/core/dump_impl.cpp
Executable file → Normal file
@@ -29,7 +29,7 @@
|
||||
|
||||
#include "dump_impl.h"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
DumpImpl* DumpImpl::dump_list_[] = { 0 };
|
||||
uint32_t DumpImpl::dump_count_ = 0;
|
||||
@@ -40,7 +40,7 @@ DisplayError DumpInterface::GetDump(char *buffer, uint32_t length) {
|
||||
}
|
||||
|
||||
buffer[0] = '\0';
|
||||
DumpImpl::AppendString(buffer, length, "\n-------- Snapdragon Display Engine --------");
|
||||
DumpImpl::AppendString(buffer, length, "\n-------- Snapdragon Display Manager --------");
|
||||
for (uint32_t i = 0; i < DumpImpl::dump_count_; i++) {
|
||||
DumpImpl::dump_list_[i]->AppendDump(buffer, length);
|
||||
}
|
||||
@@ -89,5 +89,5 @@ void DumpImpl::Unregister(DumpImpl *dump_impl) {
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#include <core/dump_interface.h>
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
class DumpImpl {
|
||||
public:
|
||||
@@ -52,7 +52,7 @@ class DumpImpl {
|
||||
friend DumpInterface;
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __DUMP_IMPL_H__
|
||||
|
||||
@@ -53,10 +53,9 @@ extern ssize_t virtual_pwrite(int fd, const void *data, size_t count, off_t offs
|
||||
extern FILE* virtual_fopen(const char *fname, const char *mode);
|
||||
extern int virtual_fclose(FILE* fileptr);
|
||||
extern ssize_t virtual_getline(char **lineptr, size_t *linelen, FILE *stream);
|
||||
|
||||
#endif
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
HWDevice::HWDevice(BufferSyncHandler *buffer_sync_handler)
|
||||
: fb_node_index_(-1), fb_path_("/sys/devices/virtual/graphics/fb"), hotplug_enabled_(false),
|
||||
@@ -205,11 +204,10 @@ DisplayError HWDevice::Validate(HWLayers *hw_layers) {
|
||||
mdp_layer_commit_v1 &mdp_commit = mdp_disp_commit_.commit_v1;
|
||||
uint32_t &mdp_layer_count = mdp_commit.input_layer_cnt;
|
||||
|
||||
DLOGI("left_roi: x = %d, y = %d, w = %d, h = %d", mdp_commit.left_roi.x, mdp_commit.left_roi.y,
|
||||
mdp_commit.left_roi.w, mdp_commit.left_roi.h);
|
||||
DLOGI("right_roi: x = %d, y = %d, w = %d, h = %d", mdp_commit.right_roi.x,
|
||||
mdp_commit.right_roi.y, mdp_commit.right_roi.w,
|
||||
mdp_commit.right_roi.h);
|
||||
DLOGI_IF(kTagDriverConfig, "left_roi: x = %d, y = %d, w = %d, h = %d", mdp_commit.left_roi.x,
|
||||
mdp_commit.left_roi.y, mdp_commit.left_roi.w, mdp_commit.left_roi.h);
|
||||
DLOGI_IF(kTagDriverConfig, "right_roi: x = %d, y = %d, w = %d, h = %d", mdp_commit.right_roi.x,
|
||||
mdp_commit.right_roi.y, mdp_commit.right_roi.w, mdp_commit.right_roi.h);
|
||||
|
||||
for (uint32_t i = 0; i < hw_layer_info.count; i++) {
|
||||
uint32_t layer_index = hw_layer_info.index[i];
|
||||
@@ -235,6 +233,8 @@ DisplayError HWDevice::Validate(HWLayers *hw_layers) {
|
||||
|
||||
mdp_buffer.width = input_buffer->width;
|
||||
mdp_buffer.height = input_buffer->height;
|
||||
mdp_buffer.comp_ratio.denom = 1000;
|
||||
mdp_buffer.comp_ratio.numer = UINT32(hw_layers->config[i].compression * 1000);
|
||||
|
||||
error = SetFormat(input_buffer->format, &mdp_buffer.format);
|
||||
if (error != kErrorNone) {
|
||||
@@ -301,6 +301,8 @@ DisplayError HWDevice::Validate(HWLayers *hw_layers) {
|
||||
mdp_out_layer_.writeback_ndx = 2;
|
||||
mdp_out_layer_.buffer.width = output_buffer->width;
|
||||
mdp_out_layer_.buffer.height = output_buffer->height;
|
||||
mdp_out_layer_.buffer.comp_ratio.denom = 1000;
|
||||
mdp_out_layer_.buffer.comp_ratio.numer = UINT32(hw_layers->output_compression * 1000);
|
||||
SetFormat(output_buffer->format, &mdp_out_layer_.buffer.format);
|
||||
|
||||
DLOGI_IF(kTagDriverConfig, "********************* Output buffer Info ************************");
|
||||
@@ -940,5 +942,5 @@ void HWDevice::SetHWScaleData(const ScaleData &scale, uint32_t index) {
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
#define IOCTL_LOGE(ioctl, type) DLOGE("ioctl %s, device = %d errno = %d, desc = %s", #ioctl, \
|
||||
type, errno, strerror(errno))
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
class HWDevice {
|
||||
protected:
|
||||
@@ -125,7 +125,7 @@ class HWDevice {
|
||||
bool synchronous_commit_;
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __HW_DEVICE_H__
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
#define __CLASS__ "HWHDMI"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
static int ParseLine(char *input, char *tokens[], const uint32_t max_token, uint32_t *count) {
|
||||
char *tmp_token = NULL;
|
||||
@@ -417,5 +417,5 @@ void HWHDMI::ReadScanInfo() {
|
||||
hw_scan_info_.cea_scan_support);
|
||||
}
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include "hw_device.h"
|
||||
#include "hw_hdmi_interface.h"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
class HWHDMI : public HWDevice, public HWHDMIInterface {
|
||||
public:
|
||||
@@ -68,7 +68,7 @@ class HWHDMI : public HWDevice, public HWHDMIInterface {
|
||||
HWScanInfo hw_scan_info_;
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __HW_HDMI_H__
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
#define __CLASS__ "HWInfo"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
int HWInfo::ParseLine(char *input, char *tokens[], const uint32_t max_token, uint32_t *count) {
|
||||
char *tmp_token = NULL;
|
||||
@@ -169,5 +169,5 @@ DisplayError HWInfo::GetHWResourceInfo(HWResourceInfo *hw_resource) {
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
@@ -26,11 +26,11 @@
|
||||
#define __HW_INFO_H__
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <core/sde_types.h>
|
||||
#include <core/sdm_types.h>
|
||||
#include <private/hw_info_types.h>
|
||||
#include "hw_info_interface.h"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
class HWInfo: public HWInfoInterface {
|
||||
public:
|
||||
@@ -48,7 +48,7 @@ class HWInfo: public HWInfoInterface {
|
||||
static int ParseLine(char *input, char *tokens[], const uint32_t max_token, uint32_t *count);
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __HW_INFO_H__
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
#define __CLASS__ "HWPrimary"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
DisplayError HWPrimaryInterface::Create(HWPrimaryInterface **intf, HWInfoInterface *hw_info_intf,
|
||||
BufferSyncHandler *buffer_sync_handler) {
|
||||
@@ -64,7 +64,7 @@ DisplayError HWPrimaryInterface::Destroy(HWPrimaryInterface *intf) {
|
||||
}
|
||||
|
||||
HWPrimary::HWPrimary(BufferSyncHandler *buffer_sync_handler, HWInfoInterface *hw_info_intf)
|
||||
: HWDevice(buffer_sync_handler), event_thread_name_("SDE_EventThread"), fake_vsync_(false),
|
||||
: HWDevice(buffer_sync_handler), event_thread_name_("SDM_EventThread"), fake_vsync_(false),
|
||||
exit_threads_(false), config_changed_(true) {
|
||||
HWDevice::device_type_ = kDevicePrimary;
|
||||
HWDevice::device_name_ = "Primary Display Device";
|
||||
@@ -310,7 +310,7 @@ DisplayError HWPrimary::Validate(HWLayers *hw_layers) {
|
||||
mdp_commit.left_roi.w = INT(left_roi.right - left_roi.left);
|
||||
mdp_commit.left_roi.h = INT(left_roi.bottom - left_roi.top);
|
||||
|
||||
// SDE treats ROI as one full coordinate system.
|
||||
// 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) {
|
||||
@@ -494,5 +494,5 @@ DisplayError HWPrimary::SetDisplayMode(const HWDisplayMode hw_display_mode) {
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include "hw_device.h"
|
||||
#include "hw_primary_interface.h"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
class HWPrimary : public HWDevice, public HWPrimaryInterface {
|
||||
public:
|
||||
@@ -82,7 +82,7 @@ class HWPrimary : public HWDevice, public HWPrimaryInterface {
|
||||
bool config_changed_;
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __HW_PRIMARY_H__
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
#define __CLASS__ "HWVirtual"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
DisplayError HWVirtualInterface::Create(HWVirtualInterface **intf, HWInfoInterface *hw_info_intf,
|
||||
BufferSyncHandler *buffer_sync_handler) {
|
||||
@@ -135,5 +135,5 @@ DisplayError HWVirtual::GetHWPanelInfo(HWPanelInfo *panel_info) {
|
||||
return HWDevice::GetHWPanelInfo(panel_info);
|
||||
}
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include "hw_device.h"
|
||||
#include "hw_virtual_interface.h"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
class HWVirtual : public HWDevice, public HWVirtualInterface {
|
||||
public:
|
||||
@@ -53,7 +53,7 @@ class HWVirtual : public HWDevice, public HWVirtualInterface {
|
||||
virtual DisplayError Flush();
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __HW_VIRTUAL_H__
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#include "hw_interface.h"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
class HWInfoInterface;
|
||||
|
||||
@@ -44,7 +44,7 @@ class HWHDMIInterface: virtual public HWInterface {
|
||||
virtual ~HWHDMIInterface() { }
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __HW_HDMI_INTERFACE_H__
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include <inttypes.h>
|
||||
#include <private/hw_info_types.h>
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
class HWInfoInterface {
|
||||
public:
|
||||
@@ -40,7 +40,7 @@ class HWInfoInterface {
|
||||
virtual ~HWInfoInterface() { }
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __HW_INFO_INTERFACE_H__
|
||||
|
||||
90
sdm/libs/core/hw_interface.h
Normal file
90
sdm/libs/core/hw_interface.h
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2014 - 2015, 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:
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
|
||||
* endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __HW_INTERFACE_H__
|
||||
#define __HW_INTERFACE_H__
|
||||
|
||||
#include <core/display_interface.h>
|
||||
#include <private/strategy_interface.h>
|
||||
#include <private/hw_info_types.h>
|
||||
#include <utils/constants.h>
|
||||
#include <core/buffer_allocator.h>
|
||||
#include <core/buffer_sync_handler.h>
|
||||
|
||||
namespace sdm {
|
||||
|
||||
enum HWScanSupport {
|
||||
kScanNotSupported,
|
||||
kScanAlwaysOverscanned,
|
||||
kScanAlwaysUnderscanned,
|
||||
kScanBoth,
|
||||
};
|
||||
|
||||
struct HWScanInfo {
|
||||
HWScanSupport pt_scan_support; // Scan support for preferred timing
|
||||
HWScanSupport it_scan_support; // Scan support for digital monitor or industry timings
|
||||
HWScanSupport cea_scan_support; // Scan support for CEA resolution timings
|
||||
|
||||
HWScanInfo() : pt_scan_support(kScanNotSupported), it_scan_support(kScanNotSupported),
|
||||
cea_scan_support(kScanNotSupported) { }
|
||||
};
|
||||
|
||||
// HWEventHandler - Implemented in DisplayBase and HWInterface implementation
|
||||
class HWEventHandler {
|
||||
public:
|
||||
virtual DisplayError VSync(int64_t timestamp) = 0;
|
||||
virtual DisplayError Blank(bool blank) = 0;
|
||||
virtual void IdleTimeout() = 0;
|
||||
virtual void ThermalEvent(int64_t thermal_level) = 0;
|
||||
protected:
|
||||
virtual ~HWEventHandler() { }
|
||||
};
|
||||
|
||||
class HWInterface {
|
||||
public:
|
||||
virtual DisplayError Open(HWEventHandler *eventhandler) = 0;
|
||||
virtual DisplayError Close() = 0;
|
||||
virtual DisplayError GetNumDisplayAttributes(uint32_t *count) = 0;
|
||||
virtual DisplayError GetDisplayAttributes(HWDisplayAttributes *display_attributes,
|
||||
uint32_t index) = 0;
|
||||
virtual DisplayError GetHWPanelInfo(HWPanelInfo *panel_info) = 0;
|
||||
virtual DisplayError SetDisplayAttributes(uint32_t index) = 0;
|
||||
virtual DisplayError GetConfigIndex(uint32_t mode, uint32_t *index) = 0;
|
||||
virtual DisplayError PowerOn() = 0;
|
||||
virtual DisplayError PowerOff() = 0;
|
||||
virtual DisplayError Doze() = 0;
|
||||
virtual DisplayError DozeSuspend() = 0;
|
||||
virtual DisplayError Standby() = 0;
|
||||
virtual DisplayError Validate(HWLayers *hw_layers) = 0;
|
||||
virtual DisplayError Commit(HWLayers *hw_layers) = 0;
|
||||
virtual DisplayError Flush() = 0;
|
||||
|
||||
protected:
|
||||
virtual ~HWInterface() { }
|
||||
};
|
||||
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __HW_INTERFACE_H__
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#ifndef __HW_PRIMARY_INTERFACE_H__
|
||||
#define __HW_PRIMARY_INTERFACE_H__
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
class BufferSyncHandler;
|
||||
class HWInfoInterface;
|
||||
@@ -44,7 +44,7 @@ class HWPrimaryInterface: virtual public HWInterface {
|
||||
virtual ~HWPrimaryInterface() { }
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __HW_PRIMARY_INTERFACE_H__
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#include "hw_interface.h"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
class HWInfoInterface;
|
||||
|
||||
@@ -41,7 +41,7 @@ class HWVirtualInterface: virtual public HWInterface {
|
||||
virtual ~HWVirtualInterface() { }
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __HW_VIRTUAL_INTERFACE_H__
|
||||
|
||||
912
sdm/libs/core/resource_default.cpp
Normal file
912
sdm/libs/core/resource_default.cpp
Normal file
@@ -0,0 +1,912 @@
|
||||
/*
|
||||
* Copyright (c) 2014 - 2015, 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:
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
|
||||
* endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <utils/constants.h>
|
||||
#include <utils/debug.h>
|
||||
#include <utils/rect.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include "resource_default.h"
|
||||
|
||||
#define __CLASS__ "ResourceDefault"
|
||||
|
||||
namespace sdm {
|
||||
|
||||
ResourceDefault::ResourceDefault()
|
||||
: num_pipe_(0), vig_pipes_(NULL), rgb_pipes_(NULL), dma_pipes_(NULL) {
|
||||
}
|
||||
|
||||
DisplayError ResourceDefault::Init(const HWResourceInfo &hw_res_info) {
|
||||
DisplayError error = kErrorNone;
|
||||
uint32_t num_pipe = 0;
|
||||
|
||||
num_pipe = hw_res_info.num_vig_pipe + hw_res_info.num_rgb_pipe + hw_res_info.num_dma_pipe;
|
||||
|
||||
if (num_pipe > kPipeIdMax) {
|
||||
DLOGE("Number of pipe is over the limit! %d", num_pipe);
|
||||
return kErrorParameters;
|
||||
}
|
||||
|
||||
num_pipe_ = num_pipe;
|
||||
hw_res_info_ = hw_res_info;
|
||||
// Init pipe info
|
||||
vig_pipes_ = &src_pipes_[0];
|
||||
rgb_pipes_ = &src_pipes_[hw_res_info_.num_vig_pipe];
|
||||
dma_pipes_ = &src_pipes_[hw_res_info_.num_vig_pipe + hw_res_info_.num_rgb_pipe];
|
||||
|
||||
for (uint32_t i = 0; i < hw_res_info_.num_vig_pipe; i++) {
|
||||
vig_pipes_[i].type = kPipeTypeVIG;
|
||||
vig_pipes_[i].index = i;
|
||||
vig_pipes_[i].mdss_pipe_id = GetMdssPipeId(vig_pipes_[i].type, i);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < hw_res_info_.num_rgb_pipe; i++) {
|
||||
rgb_pipes_[i].type = kPipeTypeRGB;
|
||||
rgb_pipes_[i].index = i + hw_res_info_.num_vig_pipe;
|
||||
rgb_pipes_[i].mdss_pipe_id = GetMdssPipeId(rgb_pipes_[i].type, i);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < hw_res_info_.num_dma_pipe; i++) {
|
||||
dma_pipes_[i].type = kPipeTypeDMA;
|
||||
dma_pipes_[i].index = i + hw_res_info_.num_vig_pipe + hw_res_info_.num_rgb_pipe;
|
||||
dma_pipes_[i].mdss_pipe_id = GetMdssPipeId(dma_pipes_[i].type, i);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < num_pipe_; i++) {
|
||||
src_pipes_[i].priority = i;
|
||||
}
|
||||
|
||||
DLOGI("hw_rev=%x, DMA=%d RGB=%d VIG=%d", hw_res_info_.hw_revision, hw_res_info_.num_dma_pipe,
|
||||
hw_res_info_.num_rgb_pipe, hw_res_info_.num_vig_pipe);
|
||||
|
||||
if (hw_res_info_.max_scale_down < 1 || hw_res_info_.max_scale_up < 1) {
|
||||
DLOGE("Max scaling setting is invalid! max_scale_down = %d, max_scale_up = %d",
|
||||
hw_res_info_.max_scale_down, hw_res_info_.max_scale_up);
|
||||
hw_res_info_.max_scale_down = 1;
|
||||
hw_res_info_.max_scale_up = 1;
|
||||
}
|
||||
|
||||
rgb_pipes_[0].owner = kPipeOwnerKernelMode;
|
||||
rgb_pipes_[1].owner = kPipeOwnerKernelMode;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
DisplayError ResourceDefault::Deinit() {
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError ResourceDefault::RegisterDisplay(DisplayType type,
|
||||
const HWDisplayAttributes &attributes,
|
||||
const HWPanelInfo &hw_panel_info,
|
||||
Handle *display_ctx) {
|
||||
DisplayError error = kErrorNone;
|
||||
|
||||
HWBlockType hw_block_id = kHWBlockMax;
|
||||
switch (type) {
|
||||
case kPrimary:
|
||||
if (!hw_block_ctx_[kHWPrimary].is_in_use) {
|
||||
hw_block_id = kHWPrimary;
|
||||
}
|
||||
break;
|
||||
|
||||
case kHDMI:
|
||||
if (!hw_block_ctx_[kHWHDMI].is_in_use) {
|
||||
hw_block_id = kHWHDMI;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
DLOGW("RegisterDisplay, invalid type %d", type);
|
||||
return kErrorParameters;
|
||||
}
|
||||
|
||||
if (hw_block_id == kHWBlockMax) {
|
||||
return kErrorResources;
|
||||
}
|
||||
|
||||
DisplayResourceContext *display_resource_ctx = new DisplayResourceContext();
|
||||
if (!display_resource_ctx) {
|
||||
return kErrorMemory;
|
||||
}
|
||||
|
||||
hw_block_ctx_[hw_block_id].is_in_use = true;
|
||||
|
||||
display_resource_ctx->display_attributes = 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_ctx = display_resource_ctx;
|
||||
return error;
|
||||
}
|
||||
|
||||
DisplayError ResourceDefault::UnregisterDisplay(Handle display_ctx) {
|
||||
DisplayResourceContext *display_resource_ctx =
|
||||
reinterpret_cast<DisplayResourceContext *>(display_ctx);
|
||||
Purge(display_ctx);
|
||||
|
||||
hw_block_ctx_[display_resource_ctx->hw_block_id].is_in_use = false;
|
||||
|
||||
delete display_resource_ctx;
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
void ResourceDefault::ReconfigureDisplay(Handle display_ctx, const HWDisplayAttributes &attributes,
|
||||
const HWPanelInfo &hw_panel_info) {
|
||||
SCOPE_LOCK(locker_);
|
||||
|
||||
DisplayResourceContext *display_resource_ctx =
|
||||
reinterpret_cast<DisplayResourceContext *>(display_ctx);
|
||||
|
||||
display_resource_ctx->display_attributes = attributes;
|
||||
}
|
||||
|
||||
DisplayError ResourceDefault::Start(Handle display_ctx) {
|
||||
locker_.Lock();
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError ResourceDefault::Stop(Handle display_ctx) {
|
||||
locker_.Unlock();
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError ResourceDefault::Acquire(Handle display_ctx, HWLayers *hw_layers) {
|
||||
DisplayResourceContext *display_resource_ctx =
|
||||
reinterpret_cast<DisplayResourceContext *>(display_ctx);
|
||||
|
||||
DisplayError error = kErrorNone;
|
||||
const struct HWLayersInfo &layer_info = hw_layers->info;
|
||||
HWBlockType hw_block_id = display_resource_ctx->hw_block_id;
|
||||
|
||||
DLOGV_IF(kTagResources, "==== Resource reserving start: hw_block = %d ====", hw_block_id);
|
||||
|
||||
if (layer_info.count > 1) {
|
||||
DLOGV_IF(kTagResources, "More than one FB layers");
|
||||
return kErrorResources;
|
||||
}
|
||||
|
||||
Layer &layer = layer_info.stack->layers[layer_info.index[0]];
|
||||
|
||||
if (layer.composition != kCompositionGPUTarget) {
|
||||
DLOGV_IF(kTagResources, "Not an FB layer");
|
||||
return kErrorParameters;
|
||||
}
|
||||
|
||||
error = Config(display_resource_ctx, hw_layers);
|
||||
if (error != kErrorNone) {
|
||||
DLOGV_IF(kTagResources, "Resource config failed");
|
||||
return error;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < num_pipe_; i++) {
|
||||
if (src_pipes_[i].hw_block_id == hw_block_id && src_pipes_[i].owner == kPipeOwnerUserMode) {
|
||||
src_pipes_[i].ResetState();
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t left_index = kPipeIdMax;
|
||||
uint32_t right_index = kPipeIdMax;
|
||||
bool need_scale = false;
|
||||
|
||||
struct HWLayerConfig &layer_config = hw_layers->config[0];
|
||||
|
||||
HWPipeInfo *left_pipe = &layer_config.left_pipe;
|
||||
HWPipeInfo *right_pipe = &layer_config.right_pipe;
|
||||
|
||||
// left pipe is needed
|
||||
if (left_pipe->valid) {
|
||||
need_scale = IsScalingNeeded(left_pipe);
|
||||
left_index = GetPipe(hw_block_id, need_scale);
|
||||
if (left_index >= num_pipe_) {
|
||||
DLOGV_IF(kTagResources, "Get left pipe failed: hw_block_id = %d, need_scale = %d",
|
||||
hw_block_id, need_scale);
|
||||
ResourceStateLog();
|
||||
goto CleanupOnError;
|
||||
}
|
||||
}
|
||||
|
||||
error = SetDecimationFactor(left_pipe);
|
||||
if (error != kErrorNone) {
|
||||
goto CleanupOnError;
|
||||
}
|
||||
|
||||
if (!right_pipe->valid) {
|
||||
// assign single pipe
|
||||
if (left_index < num_pipe_) {
|
||||
left_pipe->pipe_id = src_pipes_[left_index].mdss_pipe_id;
|
||||
}
|
||||
DLOGV_IF(kTagResources, "1 pipe acquired for FB layer, left_pipe = %x", left_pipe->pipe_id);
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
need_scale = IsScalingNeeded(right_pipe);
|
||||
|
||||
right_index = GetPipe(hw_block_id, need_scale);
|
||||
if (right_index >= num_pipe_) {
|
||||
DLOGV_IF(kTagResources, "Get right pipe failed: hw_block_id = %d, need_scale = %d", hw_block_id,
|
||||
need_scale);
|
||||
ResourceStateLog();
|
||||
goto CleanupOnError;
|
||||
}
|
||||
|
||||
if (src_pipes_[right_index].priority < src_pipes_[left_index].priority) {
|
||||
// Swap pipe based on priority
|
||||
Swap(left_index, right_index);
|
||||
}
|
||||
|
||||
// assign dual pipes
|
||||
left_pipe->pipe_id = src_pipes_[left_index].mdss_pipe_id;
|
||||
right_pipe->pipe_id = src_pipes_[right_index].mdss_pipe_id;
|
||||
|
||||
error = SetDecimationFactor(right_pipe);
|
||||
if (error != kErrorNone) {
|
||||
goto CleanupOnError;
|
||||
}
|
||||
|
||||
DLOGV_IF(kTagResources, "2 pipes acquired for FB layer, left_pipe = %x, right_pipe = %x",
|
||||
left_pipe->pipe_id, right_pipe->pipe_id);
|
||||
|
||||
return kErrorNone;
|
||||
|
||||
CleanupOnError:
|
||||
DLOGV_IF(kTagResources, "Resource reserving failed! hw_block = %d", hw_block_id);
|
||||
|
||||
return kErrorResources;
|
||||
}
|
||||
|
||||
DisplayError ResourceDefault::PostPrepare(Handle display_ctx, HWLayers *hw_layers) {
|
||||
SCOPE_LOCK(locker_);
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError ResourceDefault::PostCommit(Handle display_ctx, HWLayers *hw_layers) {
|
||||
SCOPE_LOCK(locker_);
|
||||
DisplayResourceContext *display_resource_ctx =
|
||||
reinterpret_cast<DisplayResourceContext *>(display_ctx);
|
||||
HWBlockType hw_block_id = display_resource_ctx->hw_block_id;
|
||||
uint64_t frame_count = display_resource_ctx->frame_count;
|
||||
DisplayError error = kErrorNone;
|
||||
|
||||
DLOGV_IF(kTagResources, "Resource for hw_block = %d, frame_count = %d", hw_block_id, frame_count);
|
||||
|
||||
// handoff pipes which are used by splash screen
|
||||
if ((frame_count == 0) && (hw_block_id == kHWPrimary)) {
|
||||
for (uint32_t i = 0; i < num_pipe_; i++) {
|
||||
if (src_pipes_[i].hw_block_id == hw_block_id && src_pipes_[i].owner == kPipeOwnerKernelMode) {
|
||||
src_pipes_[i].owner = kPipeOwnerUserMode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
display_resource_ctx->frame_count++;
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
void ResourceDefault::Purge(Handle display_ctx) {
|
||||
SCOPE_LOCK(locker_);
|
||||
|
||||
DisplayResourceContext *display_resource_ctx =
|
||||
reinterpret_cast<DisplayResourceContext *>(display_ctx);
|
||||
HWBlockType hw_block_id = display_resource_ctx->hw_block_id;
|
||||
|
||||
for (uint32_t i = 0; i < num_pipe_; i++) {
|
||||
if (src_pipes_[i].hw_block_id == hw_block_id && src_pipes_[i].owner == kPipeOwnerUserMode) {
|
||||
src_pipes_[i].ResetState();
|
||||
}
|
||||
}
|
||||
DLOGV_IF(kTagResources, "display id = %d", display_resource_ctx->hw_block_id);
|
||||
}
|
||||
|
||||
DisplayError ResourceDefault::SetMaxMixerStages(Handle display_ctx, uint32_t max_mixer_stages) {
|
||||
SCOPE_LOCK(locker_);
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
uint32_t ResourceDefault::GetMdssPipeId(PipeType type, uint32_t index) {
|
||||
uint32_t mdss_id = kPipeIdMax;
|
||||
switch (type) {
|
||||
case kPipeTypeVIG:
|
||||
if (index < 3) {
|
||||
mdss_id = kPipeIdVIG0 + index;
|
||||
} else if (index == 3) {
|
||||
mdss_id = kPipeIdVIG3;
|
||||
} else {
|
||||
DLOGE("vig pipe index is over the limit! %d", index);
|
||||
}
|
||||
break;
|
||||
case kPipeTypeRGB:
|
||||
if (index < 3) {
|
||||
mdss_id = kPipeIdRGB0 + index;
|
||||
} else if (index == 3) {
|
||||
mdss_id = kPipeIdRGB3;
|
||||
} else {
|
||||
DLOGE("rgb pipe index is over the limit! %d", index);
|
||||
}
|
||||
break;
|
||||
case kPipeTypeDMA:
|
||||
if (index < 2) {
|
||||
mdss_id = kPipeIdDMA0 + index;
|
||||
} else {
|
||||
DLOGE("dma pipe index is over the limit! %d", index);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DLOGE("wrong pipe type! %d", type);
|
||||
break;
|
||||
}
|
||||
|
||||
return (1 << mdss_id);
|
||||
}
|
||||
|
||||
uint32_t ResourceDefault::SearchPipe(HWBlockType hw_block_id, SourcePipe *src_pipes,
|
||||
uint32_t num_pipe) {
|
||||
uint32_t index = kPipeIdMax;
|
||||
SourcePipe *src_pipe;
|
||||
|
||||
// search the pipe being used
|
||||
for (uint32_t i = 0; i < num_pipe; i++) {
|
||||
src_pipe = &src_pipes[i];
|
||||
if (src_pipe->owner == kPipeOwnerUserMode && src_pipe->hw_block_id == kHWBlockMax) {
|
||||
index = src_pipe->index;
|
||||
src_pipe->hw_block_id = hw_block_id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
uint32_t ResourceDefault::NextPipe(PipeType type, HWBlockType hw_block_id) {
|
||||
uint32_t num_pipe = 0;
|
||||
SourcePipe *src_pipes = NULL;
|
||||
|
||||
switch (type) {
|
||||
case kPipeTypeVIG:
|
||||
src_pipes = vig_pipes_;
|
||||
num_pipe = hw_res_info_.num_vig_pipe;
|
||||
break;
|
||||
case kPipeTypeRGB:
|
||||
src_pipes = rgb_pipes_;
|
||||
num_pipe = hw_res_info_.num_rgb_pipe;
|
||||
break;
|
||||
case kPipeTypeDMA:
|
||||
default:
|
||||
src_pipes = dma_pipes_;
|
||||
num_pipe = hw_res_info_.num_dma_pipe;
|
||||
break;
|
||||
}
|
||||
|
||||
return SearchPipe(hw_block_id, src_pipes, num_pipe);
|
||||
}
|
||||
|
||||
uint32_t ResourceDefault::GetPipe(HWBlockType hw_block_id, bool need_scale) {
|
||||
uint32_t index = kPipeIdMax;
|
||||
|
||||
// The default behavior is to assume RGB and VG pipes have scalars
|
||||
if (!need_scale) {
|
||||
index = NextPipe(kPipeTypeDMA, hw_block_id);
|
||||
}
|
||||
|
||||
if ((index >= num_pipe_) && (!need_scale || !hw_res_info_.has_non_scalar_rgb)) {
|
||||
index = NextPipe(kPipeTypeRGB, hw_block_id);
|
||||
}
|
||||
|
||||
if (index >= num_pipe_) {
|
||||
index = NextPipe(kPipeTypeVIG, hw_block_id);
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
bool ResourceDefault::IsScalingNeeded(const HWPipeInfo *pipe_info) {
|
||||
const LayerRect &src_roi = pipe_info->src_roi;
|
||||
const LayerRect &dst_roi = pipe_info->dst_roi;
|
||||
|
||||
return ((dst_roi.right - dst_roi.left) != (src_roi.right - src_roi.left)) ||
|
||||
((dst_roi.bottom - dst_roi.top) != (src_roi.bottom - src_roi.top));
|
||||
}
|
||||
|
||||
void ResourceDefault::ResourceStateLog() {
|
||||
DLOGV_IF(kTagResources, "==== resource manager pipe state ====");
|
||||
uint32_t i;
|
||||
for (i = 0; i < num_pipe_; i++) {
|
||||
SourcePipe *src_pipe = &src_pipes_[i];
|
||||
DLOGV_IF(kTagResources, "index = %d, id = %x, hw_block = %d, owner = %s",
|
||||
src_pipe->index, src_pipe->mdss_pipe_id, src_pipe->hw_block_id,
|
||||
(src_pipe->owner == kPipeOwnerUserMode) ? "user mode" : "kernel mode");
|
||||
}
|
||||
}
|
||||
|
||||
DisplayError ResourceDefault::SrcSplitConfig(DisplayResourceContext *display_resource_ctx,
|
||||
const LayerRect &src_rect, const LayerRect &dst_rect,
|
||||
HWLayerConfig *layer_config) {
|
||||
HWDisplayAttributes &display_attributes = display_resource_ctx->display_attributes;
|
||||
HWPipeInfo *left_pipe = &layer_config->left_pipe;
|
||||
HWPipeInfo *right_pipe = &layer_config->right_pipe;
|
||||
float src_width = src_rect.right - src_rect.left;
|
||||
float dst_width = dst_rect.right - dst_rect.left;
|
||||
float src_height = src_rect.bottom - src_rect.top;
|
||||
float dst_height = dst_rect.bottom - dst_rect.top;
|
||||
float left_mixer_width = FLOAT(display_attributes.split_left);
|
||||
|
||||
// Layer cannot qualify for SrcSplit if source or destination width exceeds max pipe width.
|
||||
// For perf/power optimization, even if "always_src_split" is enabled, use 2 pipes only if:
|
||||
// Source width is greater than split_left (left_mixer_width)
|
||||
if ((src_width > hw_res_info_.max_pipe_width) || (dst_width > hw_res_info_.max_pipe_width) ||
|
||||
(display_resource_ctx->display_attributes.always_src_split && src_width > left_mixer_width)) {
|
||||
SplitRect(src_rect, dst_rect, &left_pipe->src_roi, &left_pipe->dst_roi, &right_pipe->src_roi,
|
||||
&right_pipe->dst_roi);
|
||||
left_pipe->valid = true;
|
||||
right_pipe->valid = true;
|
||||
} else {
|
||||
left_pipe->src_roi = src_rect;
|
||||
left_pipe->dst_roi = dst_rect;
|
||||
left_pipe->valid = true;
|
||||
right_pipe->Reset();
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
// 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_right.left = FLOAT(display_attributes.split_left);
|
||||
scissor_right.top = 0.0f;
|
||||
scissor_right.right = FLOAT(display_attributes.x_pixels);
|
||||
scissor_right.bottom = FLOAT(display_attributes.y_pixels);
|
||||
|
||||
crop_left = src_rect;
|
||||
dst_left = dst_rect;
|
||||
crop_right = crop_left;
|
||||
dst_right = dst_left;
|
||||
|
||||
bool crop_left_valid = CalculateCropRects(scissor_left, &crop_left, &dst_left);
|
||||
bool crop_right_valid = false;
|
||||
|
||||
if (IsValid(scissor_right)) {
|
||||
crop_right_valid = CalculateCropRects(scissor_right, &crop_right, &dst_right);
|
||||
}
|
||||
|
||||
// Reset left_pipe and right_pipe to invalid by default
|
||||
left_pipe->Reset();
|
||||
right_pipe->Reset();
|
||||
|
||||
if (crop_left_valid) {
|
||||
// assign left pipe
|
||||
left_pipe->src_roi = crop_left;
|
||||
left_pipe->dst_roi = dst_left;
|
||||
left_pipe->valid = true;
|
||||
}
|
||||
|
||||
// assign right pipe if needed
|
||||
if (crop_right_valid) {
|
||||
right_pipe->src_roi = crop_right;
|
||||
right_pipe->dst_roi = dst_right;
|
||||
right_pipe->valid = true;
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError ResourceDefault::Config(DisplayResourceContext *display_resource_ctx,
|
||||
HWLayers *hw_layers) {
|
||||
HWDisplayAttributes &display_attributes = display_resource_ctx->display_attributes;
|
||||
HWLayersInfo &layer_info = hw_layers->info;
|
||||
DisplayError error = kErrorNone;
|
||||
uint32_t z_order = 0;
|
||||
|
||||
Layer& layer = layer_info.stack->layers[layer_info.index[0]];
|
||||
|
||||
error = ValidateLayerDimensions(layer);
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
|
||||
struct HWLayerConfig *layer_config = &hw_layers->config[0];
|
||||
HWPipeInfo &left_pipe = layer_config->left_pipe;
|
||||
HWPipeInfo &right_pipe = layer_config->right_pipe;
|
||||
|
||||
LayerRect src_rect = layer.src_rect;
|
||||
LayerRect dst_rect = layer.dst_rect;
|
||||
|
||||
error = ValidateDimensions(src_rect, dst_rect);
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
|
||||
error = ValidateScaling(src_rect, dst_rect, false);
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
|
||||
if (hw_res_info_.is_src_split) {
|
||||
error = SrcSplitConfig(display_resource_ctx, src_rect, dst_rect, layer_config);
|
||||
} else {
|
||||
error = DisplaySplitConfig(display_resource_ctx, src_rect, dst_rect, layer_config);
|
||||
}
|
||||
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
|
||||
error = AlignPipeConfig(layer, &left_pipe, &right_pipe);
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
|
||||
// set z_order, left_pipe should always be valid
|
||||
left_pipe.z_order = 0;
|
||||
|
||||
DLOGV_IF(kTagResources, "==== FB layer Config ====");
|
||||
Log(kTagResources, "input layer src_rect", layer.src_rect);
|
||||
Log(kTagResources, "input layer dst_rect", layer.dst_rect);
|
||||
Log(kTagResources, "cropped src_rect", src_rect);
|
||||
Log(kTagResources, "cropped dst_rect", dst_rect);
|
||||
Log(kTagResources, "left pipe src", layer_config->left_pipe.src_roi);
|
||||
Log(kTagResources, "left pipe dst", layer_config->left_pipe.dst_roi);
|
||||
if (right_pipe.valid) {
|
||||
right_pipe.z_order = 0;
|
||||
Log(kTagResources, "right pipe src", layer_config->right_pipe.src_roi);
|
||||
Log(kTagResources, "right pipe dst", layer_config->right_pipe.dst_roi);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
bool ResourceDefault::CalculateCropRects(const LayerRect &scissor, LayerRect *crop,
|
||||
LayerRect *dst) {
|
||||
float &crop_left = crop->left;
|
||||
float &crop_top = crop->top;
|
||||
float &crop_right = crop->right;
|
||||
float &crop_bottom = crop->bottom;
|
||||
float crop_width = crop->right - crop->left;
|
||||
float crop_height = crop->bottom - crop->top;
|
||||
|
||||
float &dst_left = dst->left;
|
||||
float &dst_top = dst->top;
|
||||
float &dst_right = dst->right;
|
||||
float &dst_bottom = dst->bottom;
|
||||
float dst_width = dst->right - dst->left;
|
||||
float dst_height = dst->bottom - dst->top;
|
||||
|
||||
const float &sci_left = scissor.left;
|
||||
const float &sci_top = scissor.top;
|
||||
const float &sci_right = scissor.right;
|
||||
const float &sci_bottom = scissor.bottom;
|
||||
|
||||
float left_cut_ratio = 0.0, right_cut_ratio = 0.0, top_cut_ratio = 0.0, bottom_cut_ratio = 0.0;
|
||||
bool need_cut = false;
|
||||
|
||||
if (dst_left < sci_left) {
|
||||
left_cut_ratio = (sci_left - dst_left) / dst_width;
|
||||
dst_left = sci_left;
|
||||
need_cut = true;
|
||||
}
|
||||
|
||||
if (dst_right > sci_right) {
|
||||
right_cut_ratio = (dst_right - sci_right) / dst_width;
|
||||
dst_right = sci_right;
|
||||
need_cut = true;
|
||||
}
|
||||
|
||||
if (dst_top < sci_top) {
|
||||
top_cut_ratio = (sci_top - dst_top) / (dst_height);
|
||||
dst_top = sci_top;
|
||||
need_cut = true;
|
||||
}
|
||||
|
||||
if (dst_bottom > sci_bottom) {
|
||||
bottom_cut_ratio = (dst_bottom - sci_bottom) / (dst_height);
|
||||
dst_bottom = sci_bottom;
|
||||
need_cut = true;
|
||||
}
|
||||
|
||||
if (!need_cut)
|
||||
return true;
|
||||
|
||||
crop_left += crop_width * left_cut_ratio;
|
||||
crop_top += crop_height * top_cut_ratio;
|
||||
crop_right -= crop_width * right_cut_ratio;
|
||||
crop_bottom -= crop_height * bottom_cut_ratio;
|
||||
Normalize(1, 1, crop);
|
||||
Normalize(1, 1, dst);
|
||||
if (IsValid(*crop) && IsValid(*dst))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
DisplayError ResourceDefault::ValidateLayerDimensions(const Layer &layer) {
|
||||
const LayerRect &src = layer.src_rect;
|
||||
const LayerRect &dst = layer.dst_rect;
|
||||
LayerBuffer *input_buffer = layer.input_buffer;
|
||||
|
||||
if (!IsValid(src) || !IsValid(dst)) {
|
||||
Log(kTagResources, "input layer src_rect", src);
|
||||
Log(kTagResources, "input layer dst_rect", dst);
|
||||
return kErrorNotSupported;
|
||||
}
|
||||
|
||||
// Make sure source in integral only if it is a non secure layer.
|
||||
if (!input_buffer->flags.secure && (src.left - roundf(src.left) || src.top - roundf(src.top) ||
|
||||
src.right - roundf(src.right) || src.bottom - roundf(src.bottom))) {
|
||||
DLOGV_IF(kTagResources, "Input ROI is not integral");
|
||||
return kErrorNotSupported;
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError ResourceDefault::ValidateDimensions(const LayerRect &crop, const LayerRect &dst) {
|
||||
if (!IsValid(crop)) {
|
||||
Log(kTagResources, "Invalid crop rect", crop);
|
||||
return kErrorNotSupported;
|
||||
}
|
||||
|
||||
if (!IsValid(dst)) {
|
||||
Log(kTagResources, "Invalid dst rect", dst);
|
||||
return kErrorNotSupported;
|
||||
}
|
||||
|
||||
float crop_width = crop.right - crop.left;
|
||||
float crop_height = crop.bottom - crop.top;
|
||||
float dst_width = dst.right - dst.left;
|
||||
float dst_height = dst.bottom - dst.top;
|
||||
|
||||
if ((UINT32(crop_width - dst_width) == 1) || (UINT32(crop_height - dst_height) == 1)) {
|
||||
DLOGV_IF(kTagResources, "One pixel downscaling detected crop_w = %.0f, dst_w = %.0f, " \
|
||||
"crop_h = %.0f, dst_h = %.0f", crop_width, dst_width, crop_height, dst_height);
|
||||
return kErrorNotSupported;
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError ResourceDefault::ValidatePipeParams(HWPipeInfo *pipe_info) {
|
||||
DisplayError error = kErrorNone;
|
||||
|
||||
const LayerRect &src_rect = pipe_info->src_roi;
|
||||
const LayerRect &dst_rect = pipe_info->dst_roi;
|
||||
|
||||
error = ValidateDimensions(src_rect, dst_rect);
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
|
||||
error = ValidateScaling(src_rect, dst_rect, false);
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError ResourceDefault::ValidateScaling(const LayerRect &crop, const LayerRect &dst,
|
||||
bool rotate90) {
|
||||
DisplayError error = kErrorNone;
|
||||
|
||||
float scale_x = 1.0f;
|
||||
float scale_y = 1.0f;
|
||||
|
||||
error = GetScaleFactor(crop, dst, &scale_x, &scale_y);
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
|
||||
error = ValidateDownScaling(scale_x, scale_y);
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
|
||||
error = ValidateUpScaling(scale_x, scale_y);
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError ResourceDefault::ValidateDownScaling(float scale_x, float scale_y) {
|
||||
if ((UINT32(scale_x) > 1) || (UINT32(scale_y) > 1)) {
|
||||
float max_scale_down = FLOAT(hw_res_info_.max_scale_down);
|
||||
|
||||
if (hw_res_info_.has_decimation) {
|
||||
max_scale_down *= FLOAT(kMaxDecimationDownScaleRatio);
|
||||
}
|
||||
|
||||
if (scale_x > max_scale_down || scale_y > max_scale_down) {
|
||||
DLOGV_IF(kTagResources,
|
||||
"Scaling down is over the limit: scale_x = %.0f, scale_y = %.0f, " \
|
||||
"has_deci = %d", scale_x, scale_y, hw_res_info_.has_decimation);
|
||||
return kErrorNotSupported;
|
||||
}
|
||||
}
|
||||
|
||||
DLOGV_IF(kTagResources, "scale_x = %.4f, scale_y = %.4f", scale_x, scale_y);
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError ResourceDefault::ValidateUpScaling(float scale_x, float scale_y) {
|
||||
float max_scale_up = FLOAT(hw_res_info_.max_scale_up);
|
||||
|
||||
if (UINT32(scale_x) < 1 && scale_x > 0.0f) {
|
||||
if ((1.0f / scale_x) > max_scale_up) {
|
||||
DLOGV_IF(kTagResources, "Scaling up is over limit scale_x = %f", 1.0f / scale_x);
|
||||
return kErrorNotSupported;
|
||||
}
|
||||
}
|
||||
|
||||
if (UINT32(scale_y) < 1 && scale_y > 0.0f) {
|
||||
if ((1.0f / scale_y) > max_scale_up) {
|
||||
DLOGV_IF(kTagResources, "Scaling up is over limit scale_y = %f", 1.0f / scale_y);
|
||||
return kErrorNotSupported;
|
||||
}
|
||||
}
|
||||
|
||||
DLOGV_IF(kTagResources, "scale_x = %.4f, scale_y = %.4f", scale_x, scale_y);
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError ResourceDefault::GetScaleFactor(const LayerRect &crop, const LayerRect &dst,
|
||||
float *scale_x, float *scale_y) {
|
||||
float crop_width = crop.right - crop.left;
|
||||
float crop_height = crop.bottom - crop.top;
|
||||
float dst_width = dst.right - dst.left;
|
||||
float dst_height = dst.bottom - dst.top;
|
||||
|
||||
*scale_x = crop_width / dst_width;
|
||||
*scale_y = crop_height / dst_height;
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError ResourceDefault::SetDecimationFactor(HWPipeInfo *pipe) {
|
||||
float src_h = pipe->src_roi.bottom - pipe->src_roi.top;
|
||||
float dst_h = pipe->dst_roi.bottom - pipe->dst_roi.top;
|
||||
float down_scale_h = src_h / dst_h;
|
||||
|
||||
float src_w = pipe->src_roi.right - pipe->src_roi.left;
|
||||
float dst_w = pipe->dst_roi.right - pipe->dst_roi.left;
|
||||
float down_scale_w = src_w / dst_w;
|
||||
|
||||
pipe->horizontal_decimation = 0;
|
||||
pipe->vertical_decimation = 0;
|
||||
|
||||
if (CalculateDecimation(down_scale_w, &pipe->horizontal_decimation) != kErrorNone) {
|
||||
return kErrorNotSupported;
|
||||
}
|
||||
|
||||
if (CalculateDecimation(down_scale_h, &pipe->vertical_decimation) != kErrorNone) {
|
||||
return kErrorNotSupported;
|
||||
}
|
||||
|
||||
DLOGI_IF(kTagResources, "horizontal_decimation %d, vertical_decimation %d",
|
||||
pipe->horizontal_decimation, pipe->vertical_decimation);
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
void ResourceDefault::SplitRect(const LayerRect &src_rect, const LayerRect &dst_rect,
|
||||
LayerRect *src_left, LayerRect *dst_left, LayerRect *src_right,
|
||||
LayerRect *dst_right) {
|
||||
// Split rectangle horizontally and evenly into two.
|
||||
float src_width = src_rect.right - src_rect.left;
|
||||
float dst_width = dst_rect.right - dst_rect.left;
|
||||
float src_width_ori = src_width;
|
||||
src_width = ROUND_UP_ALIGN_DOWN(src_width / 2, 1);
|
||||
dst_width = ROUND_UP_ALIGN_DOWN(dst_width * src_width / src_width_ori, 1);
|
||||
|
||||
src_left->left = src_rect.left;
|
||||
src_left->right = src_rect.left + src_width;
|
||||
src_right->left = src_left->right;
|
||||
src_right->right = src_rect.right;
|
||||
|
||||
src_left->top = src_rect.top;
|
||||
src_left->bottom = src_rect.bottom;
|
||||
src_right->top = src_rect.top;
|
||||
src_right->bottom = src_rect.bottom;
|
||||
|
||||
dst_left->top = dst_rect.top;
|
||||
dst_left->bottom = dst_rect.bottom;
|
||||
dst_right->top = dst_rect.top;
|
||||
dst_right->bottom = dst_rect.bottom;
|
||||
|
||||
dst_left->left = dst_rect.left;
|
||||
dst_left->right = dst_rect.left + dst_width;
|
||||
dst_right->left = dst_left->right;
|
||||
dst_right->right = dst_rect.right;
|
||||
}
|
||||
|
||||
DisplayError ResourceDefault::AlignPipeConfig(const Layer &layer, HWPipeInfo *left_pipe,
|
||||
HWPipeInfo *right_pipe) {
|
||||
DisplayError error = kErrorNone;
|
||||
if (!left_pipe->valid) {
|
||||
DLOGE_IF(kTagResources, "left_pipe should not be invalid");
|
||||
return kErrorNotSupported;
|
||||
}
|
||||
|
||||
error = ValidatePipeParams(left_pipe);
|
||||
if (error != kErrorNone) {
|
||||
goto PipeConfigExit;
|
||||
}
|
||||
|
||||
if (right_pipe->valid) {
|
||||
// Make sure the left and right ROI are conjunct
|
||||
right_pipe->src_roi.left = left_pipe->src_roi.right;
|
||||
right_pipe->dst_roi.left = left_pipe->dst_roi.right;
|
||||
error = ValidatePipeParams(right_pipe);
|
||||
}
|
||||
|
||||
PipeConfigExit:
|
||||
if (error != kErrorNone) {
|
||||
DLOGV_IF(kTagResources, "AlignPipeConfig failed");
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
DisplayError ResourceDefault::CalculateDecimation(float downscale, uint8_t *decimation) {
|
||||
float max_down_scale = FLOAT(hw_res_info_.max_scale_down);
|
||||
|
||||
if (downscale <= max_down_scale) {
|
||||
*decimation = 0;
|
||||
return kErrorNone;
|
||||
} else if (!hw_res_info_.has_decimation) {
|
||||
DLOGE("Downscaling exceeds the maximum MDP downscale limit but decimation not enabled");
|
||||
return kErrorNotSupported;
|
||||
}
|
||||
|
||||
// Decimation is the remaining downscale factor after doing max SDE downscale.
|
||||
// In SDE, decimation is supported in powers of 2.
|
||||
// For ex: If a pipe needs downscale of 8 but max_down_scale is 4
|
||||
// So decimation = powf(2.0, ceilf(log2f(8 / 4))) = powf(2.0, 1.0) = 2
|
||||
*decimation = UINT8(ceilf(log2f(downscale / max_down_scale)));
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
} // namespace sdm
|
||||
|
||||
156
sdm/libs/core/resource_default.h
Normal file
156
sdm/libs/core/resource_default.h
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright (c) 2014 - 2015, 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:
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
|
||||
* endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __RESOURCE_DEFAULT_H__
|
||||
#define __RESOURCE_DEFAULT_H__
|
||||
|
||||
#include <core/display_interface.h>
|
||||
#include <private/resource_interface.h>
|
||||
#include <utils/locker.h>
|
||||
|
||||
#include "hw_interface.h"
|
||||
|
||||
namespace sdm {
|
||||
|
||||
class ResourceDefault : public ResourceInterface {
|
||||
public:
|
||||
ResourceDefault();
|
||||
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 UnregisterDisplay(Handle display_ctx);
|
||||
virtual void ReconfigureDisplay(Handle display_ctx, const HWDisplayAttributes &attributes,
|
||||
const HWPanelInfo &hw_panel_info);
|
||||
virtual DisplayError Start(Handle display_ctx);
|
||||
virtual DisplayError Stop(Handle display_ctx);
|
||||
virtual DisplayError Acquire(Handle display_ctx, HWLayers *hw_layers);
|
||||
virtual DisplayError PostPrepare(Handle display_ctx, HWLayers *hw_layers);
|
||||
virtual DisplayError PostCommit(Handle display_ctx, HWLayers *hw_layers);
|
||||
virtual void Purge(Handle display_ctx);
|
||||
virtual DisplayError SetMaxMixerStages(Handle display_ctx, uint32_t max_mixer_stages);
|
||||
virtual DisplayError ValidateScaling(const LayerRect &crop, const LayerRect &dst,
|
||||
bool rotate90);
|
||||
|
||||
private:
|
||||
enum PipeId {
|
||||
kPipeIdVIG0,
|
||||
kPipeIdVIG1,
|
||||
kPipeIdVIG2,
|
||||
kPipeIdRGB0,
|
||||
kPipeIdRGB1,
|
||||
kPipeIdRGB2,
|
||||
kPipeIdDMA0,
|
||||
kPipeIdDMA1,
|
||||
kPipeIdVIG3,
|
||||
kPipeIdRGB3,
|
||||
kPipeIdMax,
|
||||
};
|
||||
|
||||
enum PipeType {
|
||||
kPipeTypeUnused,
|
||||
kPipeTypeVIG,
|
||||
kPipeTypeRGB,
|
||||
kPipeTypeDMA,
|
||||
kPipeTypeMax,
|
||||
};
|
||||
|
||||
enum PipeOwner {
|
||||
kPipeOwnerUserMode, // Pipe state when it is available for reservation
|
||||
kPipeOwnerKernelMode, // Pipe state when pipe is owned by kernel
|
||||
};
|
||||
|
||||
// todo: retrieve all these from kernel
|
||||
enum {
|
||||
kMaxDecimationDownScaleRatio = 8,
|
||||
};
|
||||
|
||||
struct SourcePipe {
|
||||
PipeType type;
|
||||
PipeOwner owner;
|
||||
uint32_t mdss_pipe_id;
|
||||
uint32_t index;
|
||||
HWBlockType hw_block_id;
|
||||
int priority;
|
||||
|
||||
SourcePipe() : type(kPipeTypeUnused), owner(kPipeOwnerUserMode), mdss_pipe_id(kPipeIdMax),
|
||||
index(0), hw_block_id(kHWBlockMax), priority(0) { }
|
||||
|
||||
inline void ResetState() { hw_block_id = kHWBlockMax;}
|
||||
};
|
||||
|
||||
struct DisplayResourceContext {
|
||||
HWDisplayAttributes display_attributes;
|
||||
HWBlockType hw_block_id;
|
||||
uint64_t frame_count;
|
||||
|
||||
DisplayResourceContext() : hw_block_id(kHWBlockMax), frame_count(0) { }
|
||||
};
|
||||
|
||||
struct HWBlockContext {
|
||||
bool is_in_use;
|
||||
HWBlockContext() : is_in_use(false) { }
|
||||
};
|
||||
|
||||
uint32_t GetMdssPipeId(PipeType pipe_type, uint32_t index);
|
||||
uint32_t NextPipe(PipeType pipe_type, HWBlockType hw_block_id);
|
||||
uint32_t SearchPipe(HWBlockType hw_block_id, SourcePipe *src_pipes, uint32_t num_pipe);
|
||||
uint32_t GetPipe(HWBlockType hw_block_id, bool need_scale);
|
||||
bool IsScalingNeeded(const HWPipeInfo *pipe_info);
|
||||
DisplayError Config(DisplayResourceContext *display_resource_ctx, HWLayers *hw_layers);
|
||||
DisplayError DisplaySplitConfig(DisplayResourceContext *display_resource_ctx,
|
||||
const LayerRect &src_rect, const LayerRect &dst_rect,
|
||||
HWLayerConfig *layer_config);
|
||||
DisplayError SrcSplitConfig(DisplayResourceContext *display_resource_ctx,
|
||||
const LayerRect &src_rect, const LayerRect &dst_rect,
|
||||
HWLayerConfig *layer_config);
|
||||
bool CalculateCropRects(const LayerRect &scissor, LayerRect *crop, LayerRect *dst);
|
||||
DisplayError ValidateLayerDimensions(const Layer &layer);
|
||||
DisplayError ValidateDimensions(const LayerRect &crop, const LayerRect &dst);
|
||||
DisplayError ValidatePipeParams(HWPipeInfo *pipe_info);
|
||||
DisplayError ValidateDownScaling(float scale_x, float scale_y);
|
||||
DisplayError ValidateUpScaling(float scale_x, float scale_y);
|
||||
DisplayError GetScaleFactor(const LayerRect &crop, const LayerRect &dst, float *scale_x,
|
||||
float *scale_y);
|
||||
DisplayError SetDecimationFactor(HWPipeInfo *pipe);
|
||||
void SplitRect(const LayerRect &src_rect, const LayerRect &dst_rect, LayerRect *src_left,
|
||||
LayerRect *dst_left, LayerRect *src_right, LayerRect *dst_right);
|
||||
DisplayError AlignPipeConfig(const Layer &layer, HWPipeInfo *left_pipe, HWPipeInfo *right_pipe);
|
||||
void ResourceStateLog(void);
|
||||
DisplayError CalculateDecimation(float downscale, uint8_t *decimation);
|
||||
|
||||
Locker locker_;
|
||||
HWResourceInfo hw_res_info_;
|
||||
HWBlockContext hw_block_ctx_[kHWBlockMax];
|
||||
SourcePipe src_pipes_[kPipeIdMax];
|
||||
uint32_t num_pipe_;
|
||||
SourcePipe *vig_pipes_;
|
||||
SourcePipe *rgb_pipes_;
|
||||
SourcePipe *dma_pipes_;
|
||||
};
|
||||
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __RESOURCE_DEFAULT_H__
|
||||
|
||||
185
sdm/libs/core/strategy.cpp
Normal file
185
sdm/libs/core/strategy.cpp
Normal file
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* Copyright (c) 2014 - 2015, 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:
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
|
||||
* endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <utils/constants.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
#include "strategy.h"
|
||||
|
||||
#define __CLASS__ "Strategy"
|
||||
|
||||
namespace sdm {
|
||||
|
||||
Strategy::Strategy(ExtensionInterface *extension_intf, DisplayType type,
|
||||
const HWResourceInfo &hw_resource_info, const HWPanelInfo &hw_panel_info)
|
||||
: extension_intf_(extension_intf), strategy_intf_(NULL), partial_update_intf_(NULL),
|
||||
display_type_(type),hw_resource_info_(hw_resource_info), hw_panel_info_(hw_panel_info),
|
||||
hw_layers_info_(NULL), fb_layer_index_(0), extn_start_success_(false), tried_default_(false) {
|
||||
}
|
||||
|
||||
DisplayError Strategy::Init() {
|
||||
DisplayError error = kErrorNone;
|
||||
|
||||
if (extension_intf_) {
|
||||
error = extension_intf_->CreateStrategyExtn(display_type_, &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_);
|
||||
if (error != kErrorNone) {
|
||||
DLOGW("Partial Update creation failed, Continue without partial update.");
|
||||
}
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError Strategy::Deinit() {
|
||||
if (strategy_intf_) {
|
||||
if (partial_update_intf_) {
|
||||
extension_intf_->DestroyPartialUpdate(partial_update_intf_);
|
||||
}
|
||||
|
||||
extension_intf_->DestroyStrategyExtn(strategy_intf_);
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError Strategy::Start(HWLayersInfo *hw_layers_info, uint32_t *max_attempts) {
|
||||
DisplayError error = kErrorNone;
|
||||
|
||||
hw_layers_info_ = hw_layers_info;
|
||||
extn_start_success_ = false;
|
||||
tried_default_ = false;
|
||||
|
||||
uint32_t i = 0;
|
||||
LayerStack *layer_stack = hw_layers_info_->stack;
|
||||
for (; i < layer_stack->layer_count; i++) {
|
||||
if (layer_stack->layers[i].composition == kCompositionGPUTarget) {
|
||||
fb_layer_index_ = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == layer_stack->layer_count) {
|
||||
return kErrorUndefined;
|
||||
}
|
||||
|
||||
GenerateROI();
|
||||
|
||||
if (strategy_intf_) {
|
||||
error = strategy_intf_->Start(hw_layers_info_, max_attempts);
|
||||
if (error == kErrorNone) {
|
||||
extn_start_success_ = true;
|
||||
return kErrorNone;
|
||||
}
|
||||
}
|
||||
|
||||
*max_attempts = 1;
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError Strategy::Stop() {
|
||||
if (extn_start_success_) {
|
||||
return strategy_intf_->Stop();
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError Strategy::GetNextStrategy(StrategyConstraints *constraints) {
|
||||
DisplayError error = kErrorNone;
|
||||
|
||||
if (extn_start_success_) {
|
||||
error = strategy_intf_->GetNextStrategy(constraints);
|
||||
if (error == kErrorNone) {
|
||||
return kErrorNone;
|
||||
}
|
||||
}
|
||||
|
||||
// Default composition is already tried.
|
||||
if (tried_default_) {
|
||||
return kErrorUndefined;
|
||||
}
|
||||
|
||||
// Mark all layers for GPU composition. Find GPU target buffer and store its index for
|
||||
// programming the hardware.
|
||||
LayerStack *layer_stack = hw_layers_info_->stack;
|
||||
uint32_t &hw_layer_count = hw_layers_info_->count;
|
||||
hw_layer_count = 0;
|
||||
for (uint32_t i = 0; i < layer_stack->layer_count; i++) {
|
||||
LayerComposition &composition = layer_stack->layers[i].composition;
|
||||
if (composition == kCompositionGPUTarget) {
|
||||
hw_layers_info_->index[hw_layer_count++] = i;
|
||||
} else {
|
||||
composition = kCompositionGPU;
|
||||
}
|
||||
}
|
||||
|
||||
tried_default_ = true;
|
||||
|
||||
// There can be one and only one GPU target buffer.
|
||||
if (hw_layer_count != 1) {
|
||||
return kErrorParameters;
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
void Strategy::GenerateROI() {
|
||||
bool split_display = false;
|
||||
|
||||
if (partial_update_intf_ && partial_update_intf_->GenerateROI(hw_layers_info_) == kErrorNone) {
|
||||
return;
|
||||
}
|
||||
|
||||
LayerStack *layer_stack = hw_layers_info_->stack;
|
||||
LayerRect &src_rect = layer_stack->layers[fb_layer_index_].src_rect;
|
||||
// TODO(user): read panels x_pixels and y_pixels instead of fb_x_res and fb_y_res
|
||||
float fb_x_res = src_rect.right - src_rect.left;
|
||||
float fb_y_res = src_rect.bottom - src_rect.top;
|
||||
|
||||
if (!hw_resource_info_.is_src_split &&
|
||||
((fb_x_res > 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, fb_y_res};
|
||||
hw_layers_info_->right_partial_update = (LayerRect) {left_split, 0.0f, fb_x_res, fb_y_res};
|
||||
} else {
|
||||
hw_layers_info_->left_partial_update = (LayerRect) {0.0f, 0.0f, fb_x_res, fb_y_res};
|
||||
hw_layers_info_->right_partial_update = (LayerRect) {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sdm
|
||||
|
||||
@@ -22,54 +22,42 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __ROTATOR_CTRL_H__
|
||||
#define __ROTATOR_CTRL_H__
|
||||
#ifndef __STRATEGY_H__
|
||||
#define __STRATEGY_H__
|
||||
|
||||
#include <utils/locker.h>
|
||||
#include <utils/debug.h>
|
||||
#include <core/display_interface.h>
|
||||
#include <private/extension_interface.h>
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
class HWRotatorInterface;
|
||||
class BufferAllocator;
|
||||
class BufferSyncHandler;
|
||||
struct HWLayers;
|
||||
class SessionManager;
|
||||
|
||||
class RotatorCtrl {
|
||||
class Strategy {
|
||||
public:
|
||||
RotatorCtrl();
|
||||
DisplayError Init(BufferAllocator *buffer_allocator, BufferSyncHandler *buffer_sync_handler);
|
||||
Strategy(ExtensionInterface *extension_intf, DisplayType type,
|
||||
const HWResourceInfo &hw_resource_info, const HWPanelInfo &hw_panel_info);
|
||||
|
||||
DisplayError Init();
|
||||
DisplayError Deinit();
|
||||
DisplayError RegisterDisplay(DisplayType type, Handle *display_ctx);
|
||||
void UnregisterDisplay(Handle display_ctx);
|
||||
DisplayError Prepare(Handle display_ctx, HWLayers *hw_layers);
|
||||
DisplayError Commit(Handle display_ctx, HWLayers *hw_layers);
|
||||
DisplayError PostCommit(Handle display_ctx, HWLayers *hw_layers);
|
||||
DisplayError Purge(Handle display_ctx, HWLayers *hw_layers);
|
||||
|
||||
DisplayError Start(HWLayersInfo *hw_layers_info, uint32_t *max_attempts);
|
||||
DisplayError GetNextStrategy(StrategyConstraints *constraints);
|
||||
DisplayError Stop();
|
||||
|
||||
private:
|
||||
enum {
|
||||
kSingleBuffering = 1,
|
||||
kDoubleBuffering = 2,
|
||||
kTripleBuffering = 3,
|
||||
void GenerateROI();
|
||||
|
||||
ExtensionInterface *extension_intf_;
|
||||
StrategyInterface *strategy_intf_;
|
||||
PartialUpdateInterface *partial_update_intf_;
|
||||
DisplayType display_type_;
|
||||
HWResourceInfo hw_resource_info_;
|
||||
HWPanelInfo hw_panel_info_;
|
||||
HWLayersInfo *hw_layers_info_;
|
||||
uint32_t fb_layer_index_;
|
||||
bool extn_start_success_;
|
||||
bool tried_default_;
|
||||
};
|
||||
|
||||
struct DisplayRotatorContext {
|
||||
DisplayType display_type;
|
||||
} // namespace sdm
|
||||
|
||||
DisplayRotatorContext() : display_type(kPrimary) { }
|
||||
};
|
||||
|
||||
DisplayError PrepareSessions(DisplayRotatorContext *disp_rotator_ctx, HWLayers *hw_layers);
|
||||
DisplayError GetOutputBuffers(DisplayRotatorContext *disp_rotator_ctx, HWLayers *hw_layers);
|
||||
|
||||
HWRotatorInterface *hw_rotator_intf_;
|
||||
SessionManager *session_manager_;
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
|
||||
#endif // __ROTATOR_CTRL_H__
|
||||
#endif // __STRATEGY_H__
|
||||
|
||||
@@ -4,20 +4,20 @@ include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := hwcomposer.$(TARGET_BOARD_PLATFORM)
|
||||
LOCAL_MODULE_RELATIVE_PATH := hw
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_C_INCLUDES := hardware/qcom/display/displayengine/include/ \
|
||||
LOCAL_C_INCLUDES := hardware/qcom/display/sdm/include/ \
|
||||
hardware/qcom/display/libgralloc/ \
|
||||
hardware/qcom/display/libqservice/ \
|
||||
hardware/qcom/display/libqdutils/
|
||||
LOCAL_CFLAGS := -Wno-missing-field-initializers -Wno-unused-parameter \
|
||||
-Wconversion -Wall -Werror \
|
||||
-DLOG_TAG=\"SDE\"
|
||||
-DLOG_TAG=\"SDM\"
|
||||
|
||||
# TODO: Move this to the common makefile
|
||||
ifeq ($(call is-board-platform-in-list, $(MASTER_SIDE_CP_TARGET_LIST)), true)
|
||||
LOCAL_CFLAGS += -DMASTER_SIDE_CP
|
||||
endif
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := libsde libqservice libbinder libhardware libhardware_legacy \
|
||||
LOCAL_SHARED_LIBRARIES := libsdmcore libqservice libbinder libhardware libhardware_legacy \
|
||||
libutils libcutils libsync libmemalloc libqdutils
|
||||
LOCAL_SRC_FILES := hwc_session.cpp \
|
||||
hwc_display.cpp \
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
#define __CLASS__ "HWCBufferAllocator"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
HWCBufferAllocator::HWCBufferAllocator() {
|
||||
alloc_controller_ = gralloc::IAllocController::getInstance();
|
||||
@@ -184,4 +184,4 @@ int HWCBufferAllocator::SetBufferInfo(LayerBufferFormat format, int *target, int
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
@@ -40,7 +40,7 @@ class IAllocController;
|
||||
|
||||
} // namespace gralloc
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
class HWCBufferAllocator : public BufferAllocator {
|
||||
public:
|
||||
@@ -60,6 +60,6 @@ class HWCBufferAllocator : public BufferAllocator {
|
||||
gralloc::IAllocController *alloc_controller_;
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
#endif // __HWC_BUFFER_ALLOCATOR_H__
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
#define __CLASS__ "HWCBufferSyncHandler"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
DisplayError HWCBufferSyncHandler::SyncWait(int fd) {
|
||||
int error = 0;
|
||||
@@ -67,5 +67,5 @@ DisplayError HWCBufferSyncHandler::SyncMerge(int fd1, int fd2, int *merged_fd) {
|
||||
return error;
|
||||
}
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
@@ -33,10 +33,10 @@
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <core/sde_types.h>
|
||||
#include <core/sdm_types.h>
|
||||
#include <core/buffer_sync_handler.h>
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
class HWCBufferSyncHandler : public BufferSyncHandler {
|
||||
public:
|
||||
@@ -46,7 +46,7 @@ class HWCBufferSyncHandler : public BufferSyncHandler {
|
||||
virtual DisplayError SyncMerge(int fd1, int fd2, int *merged_fd);
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
#endif // __HWC_BUFFER_SYNC_HANDLER_H__
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
#include "hwc_debugger.h"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
HWCDebugHandler HWCDebugHandler::debug_handler_;
|
||||
uint32_t HWCDebugHandler::debug_flags_ = 0x1;
|
||||
@@ -123,5 +123,5 @@ void HWCDebugHandler::EndTrace() {
|
||||
atrace_end(ATRACE_TAG);
|
||||
}
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
|
||||
|
||||
#include <core/sde_types.h>
|
||||
#include <core/sdm_types.h>
|
||||
#include <core/debug_interface.h>
|
||||
#include <cutils/log.h>
|
||||
#include <utils/Trace.h>
|
||||
@@ -49,7 +49,7 @@
|
||||
#define DTRACE_END() HWCDebugHandler::Get()->EndTrace()
|
||||
#define DTRACE_SCOPED() ScopeTracer<HWCDebugHandler> scope_tracer(__CLASS__, __FUNCTION__)
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
class HWCDebugHandler : public DebugHandler {
|
||||
public:
|
||||
@@ -74,7 +74,7 @@ class HWCDebugHandler : public DebugHandler {
|
||||
static uint32_t debug_flags_;
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __HWC_DEBUGGER_H__
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
#define __CLASS__ "HWCDisplay"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
HWCDisplay::HWCDisplay(CoreInterface *core_intf, hwc_procs_t const **hwc_procs, DisplayType type,
|
||||
int id)
|
||||
@@ -357,7 +357,7 @@ int HWCDisplay::PrepareLayerStack(hwc_display_contents_1_t *content_list) {
|
||||
LayerBuffer *layer_buffer = layer.input_buffer;
|
||||
|
||||
if (pvt_handle) {
|
||||
layer_buffer->format = GetSDEFormat(pvt_handle->format, pvt_handle->flags);
|
||||
layer_buffer->format = GetSDMFormat(pvt_handle->format, pvt_handle->flags);
|
||||
if (layer_buffer->format == kFormatInvalid) {
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -540,7 +540,7 @@ int HWCDisplay::PostCommitLayerStack(hwc_display_contents_1_t *content_list) {
|
||||
hwc_layer.releaseFenceFd = layer_buffer->release_fence_fd;
|
||||
}
|
||||
|
||||
// During animation on external/virtual display, Display Engine will use the cached
|
||||
// During animation on external/virtual display, SDM will use the cached
|
||||
// framebuffer layer throughout animation and do not allow framework to do eglswapbuffer on
|
||||
// framebuffer target. So graphics doesn't close the release fence fd of framebuffer target,
|
||||
// Hence close the release fencefd of framebuffer target here.
|
||||
@@ -684,7 +684,7 @@ DisplayError HWCDisplay::SetMaxMixerStages(uint32_t max_mixer_stages) {
|
||||
return error;
|
||||
}
|
||||
|
||||
LayerBufferFormat HWCDisplay::GetSDEFormat(const int32_t &source, const int flags) {
|
||||
LayerBufferFormat HWCDisplay::GetSDMFormat(const int32_t &source, const int flags) {
|
||||
LayerBufferFormat format = kFormatInvalid;
|
||||
if (flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
|
||||
switch (source) {
|
||||
@@ -1004,5 +1004,5 @@ uint32_t HWCDisplay::RoundToStandardFPS(uint32_t fps) {
|
||||
void HWCDisplay::ApplyScanAdjustment(hwc_rect_t *display_frame) {
|
||||
}
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include <hardware/hwcomposer.h>
|
||||
#include <core/core_interface.h>
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
class HWCDisplay : public DisplayEventHandler {
|
||||
public:
|
||||
@@ -60,7 +60,7 @@ class HWCDisplay : public DisplayEventHandler {
|
||||
kDisplayStatusResume,
|
||||
};
|
||||
|
||||
// Maximum number of layers supported by display engine.
|
||||
// Maximum number of layers supported by display manager.
|
||||
static const uint32_t kMaxLayerCount = 32;
|
||||
|
||||
// Structure to track memory allocation for layer stack (layers, rectangles) object.
|
||||
@@ -106,7 +106,7 @@ class HWCDisplay : public DisplayEventHandler {
|
||||
inline void SetComposition(const int32_t &source, int32_t *target);
|
||||
inline void SetBlending(const int32_t &source, LayerBlending *target);
|
||||
int SetFormat(const int32_t &source, const int flags, LayerBufferFormat *target);
|
||||
LayerBufferFormat GetSDEFormat(const int32_t &source, const int flags);
|
||||
LayerBufferFormat GetSDMFormat(const int32_t &source, const int flags);
|
||||
void DumpInputBuffers(hwc_display_contents_1_t *content_list);
|
||||
const char *GetHALPixelFormatString(int format);
|
||||
const char *GetDisplayString();
|
||||
@@ -143,7 +143,7 @@ class HWCDisplay : public DisplayEventHandler {
|
||||
uint32_t metadata_refresh_rate_;
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __HWC_DISPLAY_H__
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
#define __CLASS__ "HWCDisplayExternal"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
HWCDisplayExternal::HWCDisplayExternal(CoreInterface *core_intf, hwc_procs_t const **hwc_procs)
|
||||
: HWCDisplay(core_intf, hwc_procs, kHDMI, HWC_DISPLAY_EXTERNAL) {
|
||||
@@ -137,5 +137,5 @@ void HWCDisplayExternal::ApplyScanAdjustment(hwc_rect_t *display_frame) {
|
||||
display_frame->bottom = display_frame->bottom - y_offset;
|
||||
}
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#include "hwc_display.h"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
class HWCDisplayExternal : public HWCDisplay {
|
||||
public:
|
||||
@@ -40,7 +40,7 @@ class HWCDisplayExternal : public HWCDisplay {
|
||||
virtual void ApplyScanAdjustment(hwc_rect_t *display_frame);
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __HWC_DISPLAY_EXTERNAL_H__
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
#define __CLASS__ "HWCDisplayPrimary"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
HWCDisplayPrimary::HWCDisplayPrimary(CoreInterface *core_intf, hwc_procs_t const **hwc_procs)
|
||||
: HWCDisplay(core_intf, hwc_procs, kPrimary, HWC_DISPLAY_PRIMARY) {
|
||||
@@ -110,5 +110,5 @@ void HWCDisplayPrimary::SetMetaDataRefreshRateFlag(bool enable) {
|
||||
use_metadata_refresh_rate_ = enable;
|
||||
}
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#include "hwc_display.h"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
class HWCDisplayPrimary : public HWCDisplay {
|
||||
public:
|
||||
@@ -40,7 +40,7 @@ class HWCDisplayPrimary : public HWCDisplay {
|
||||
virtual void SetMetaDataRefreshRateFlag(bool enable);
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __HWC_DISPLAY_PRIMARY_H__
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
#define __CLASS__ "HWCDisplayVirtual"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
HWCDisplayVirtual::HWCDisplayVirtual(CoreInterface *core_intf, hwc_procs_t const **hwc_procs)
|
||||
: HWCDisplay(core_intf, hwc_procs, kVirtual, HWC_DISPLAY_VIRTUAL),
|
||||
@@ -139,7 +139,7 @@ int HWCDisplayVirtual::SetActiveConfig(hwc_display_contents_1_t *content_list) {
|
||||
int status = 0;
|
||||
|
||||
if (output_handle) {
|
||||
LayerBufferFormat format = GetSDEFormat(output_handle->format, output_handle->flags);
|
||||
LayerBufferFormat format = GetSDMFormat(output_handle->format, output_handle->flags);
|
||||
if (format == kFormatInvalid) {
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -181,7 +181,7 @@ int HWCDisplayVirtual::SetOutputBuffer(hwc_display_contents_1_t *content_list) {
|
||||
output_buffer_->acquire_fence_fd = content_list->outbufAcquireFenceFd;
|
||||
|
||||
if (output_handle) {
|
||||
output_buffer_->format = GetSDEFormat(output_handle->format, output_handle->flags);
|
||||
output_buffer_->format = GetSDMFormat(output_handle->format, output_handle->flags);
|
||||
if (output_buffer_->format == kFormatInvalid) {
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -274,5 +274,5 @@ int HWCDisplayVirtual::GetHeight(const private_handle_t* handle) {
|
||||
return handle->height;
|
||||
}
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include <gralloc_priv.h>
|
||||
#include "hwc_display.h"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
class HWCDisplayVirtual : public HWCDisplay {
|
||||
public:
|
||||
@@ -50,7 +50,7 @@ class HWCDisplayVirtual : public HWCDisplay {
|
||||
bool dump_output_layer_;
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __HWC_DISPLAY_VIRTUAL_H__
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
#include <QService.h>
|
||||
#include <gr.h>
|
||||
#include <gralloc_priv.h>
|
||||
#include <core/buffer_allocator.h>
|
||||
#include <display_config.h>
|
||||
|
||||
#include "hwc_buffer_allocator.h"
|
||||
@@ -52,7 +51,7 @@
|
||||
#define HWC_UEVENT_SWITCH_HDMI "change@/devices/virtual/switch/hdmi"
|
||||
#define HWC_UEVENT_GRAPHICS_FB0 "change@/devices/virtual/graphics/fb0"
|
||||
|
||||
static sde::HWCSession::HWCModuleMethods g_hwc_module_methods;
|
||||
static sdm::HWCSession::HWCModuleMethods g_hwc_module_methods;
|
||||
|
||||
hwc_module_t HAL_MODULE_INFO_SYM = {
|
||||
common: {
|
||||
@@ -68,7 +67,7 @@ hwc_module_t HAL_MODULE_INFO_SYM = {
|
||||
}
|
||||
};
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
Locker HWCSession::locker_;
|
||||
bool HWCSession::reset_panel_ = false;
|
||||
@@ -1001,5 +1000,5 @@ void HWCSession::AdjustSourceResolution(uint32_t dst_width, uint32_t dst_height,
|
||||
*src_width = dst_width;
|
||||
}
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#include "hwc_display_external.h"
|
||||
#include "hwc_display_virtual.h"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
class HWCSession : hwc_composer_device_1_t, CoreEventHandler, public qClient::BnQClient {
|
||||
public:
|
||||
@@ -110,7 +110,7 @@ class HWCSession : hwc_composer_device_1_t, CoreEventHandler, public qClient::Bn
|
||||
HWCBufferSyncHandler *buffer_sync_handler_;
|
||||
};
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __HWC_SESSION_H__
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE := libsdeutils
|
||||
LOCAL_MODULE := libsdmutils
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_C_INCLUDES := hardware/qcom/display/displayengine/include/
|
||||
LOCAL_C_INCLUDES := hardware/qcom/display/sdm/include/
|
||||
LOCAL_CFLAGS := -Wno-missing-field-initializers -Wno-unused-parameter \
|
||||
-Wconversion -Wall -Werror \
|
||||
-DLOG_TAG=\"SDE\"
|
||||
-DLOG_TAG=\"SDM\"
|
||||
LOCAL_SHARED_LIBRARIES := libcutils
|
||||
LOCAL_SRC_FILES := debug_android.cpp rect.cpp
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#include <cutils/log.h>
|
||||
#include <cutils/properties.h>
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
Debug Debug::debug_;
|
||||
|
||||
@@ -73,7 +73,7 @@ uint32_t Debug::GetIdleTimeoutMs() {
|
||||
|
||||
bool Debug::IsRotatorDownScaleDisabled() {
|
||||
char property[PROPERTY_VALUE_MAX];
|
||||
if (property_get("sde.disable_rotator_downscaling", property, NULL) > 0) {
|
||||
if (property_get("sdm.disable_rotator_downscaling", property, NULL) > 0) {
|
||||
return (atoi(property) ? 0 : false, true);
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ bool Debug::IsRotatorDownScaleDisabled() {
|
||||
|
||||
bool Debug::IsDecimationDisabled() {
|
||||
char property[PROPERTY_VALUE_MAX];
|
||||
if (property_get("sde.disable_decimation", property, NULL) > 0) {
|
||||
if (property_get("sdm.disable_decimation", property, NULL) > 0) {
|
||||
return (atoi(property) ? 0 : false, true);
|
||||
}
|
||||
|
||||
@@ -92,12 +92,12 @@ bool Debug::IsDecimationDisabled() {
|
||||
// This property serves to disable/enable partial update
|
||||
bool Debug::IsPartialUpdateEnabled() {
|
||||
char property[PROPERTY_VALUE_MAX];
|
||||
if (property_get("sde.hwc.partial_update", property, NULL) > 0) {
|
||||
if (property_get("sdm.hwc.partial_update", property, NULL) > 0) {
|
||||
return (atoi(property) ? 1 : true, false);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
#define __CLASS__ "RectUtils"
|
||||
|
||||
namespace sde {
|
||||
namespace sdm {
|
||||
|
||||
bool IsValid(const LayerRect &rect) {
|
||||
return ((rect.bottom > rect.top) && (rect.right > rect.left));
|
||||
@@ -138,5 +138,5 @@ LayerRect Union(const LayerRect &rect1, const LayerRect &rect2) {
|
||||
return res;
|
||||
}
|
||||
|
||||
} // namespace sde
|
||||
} // namespace sdm
|
||||
|
||||
Reference in New Issue
Block a user