sdm: Align to new SDM design.

- Align code base to new SDM design.

Change-Id: I38d7d138ae704cf036e2b96c16453aea63bc333f
This commit is contained in:
Dileep Marchya
2015-05-08 18:58:33 -07:00
parent 8c6b491d19
commit 73d002e57c
87 changed files with 2248 additions and 4782 deletions

View File

@@ -1,15 +1,15 @@
ifeq ($(call is-board-platform-in-list, msm8996),true) ifeq ($(call is-board-platform-in-list, msm8996),true)
TARGET_USES_SDE = true TARGET_USES_SDM = true
else else
TARGET_USES_SDE = false TARGET_USES_SDM = false
endif endif
display-hals := libgralloc libcopybit liblight libmemtrack libqservice libqdutils display-hals := libgralloc libcopybit liblight libmemtrack libqservice libqdutils
display-hals += hdmi_cec display-hals += hdmi_cec
ifeq ($(TARGET_USES_SDE), true) ifeq ($(TARGET_USES_SDM), true)
sde-libs := displayengine/libs sdm-libs := sdm/libs
display-hals += $(sde-libs)/utils $(sde-libs)/core $(sde-libs)/hwc display-hals += $(sdm-libs)/utils $(sdm-libs)/core $(sdm-libs)/hwc
else else
display-hals += libgenlock libhwcomposer liboverlay libhdmi display-hals += libgenlock libhwcomposer liboverlay libhdmi
endif endif

View File

@@ -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__

View File

@@ -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__

View File

@@ -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

View File

@@ -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__

View File

@@ -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

View File

@@ -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__

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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__

View File

@@ -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

View File

@@ -30,8 +30,7 @@
/*! @file buffer_allocator.h /*! @file buffer_allocator.h
@brief Interface file for platform specific buffer allocator. @brief Interface file for platform specific buffer allocator.
@details Buffer manager in display engine uses this interface to allocate buffer for internal @details This interface is used by SDM to allocate internal buffers.
usage.
*/ */
#ifndef __BUFFER_ALLOCATOR_H__ #ifndef __BUFFER_ALLOCATOR_H__
@@ -39,7 +38,7 @@
#include <core/layer_buffer.h> #include <core/layer_buffer.h>
namespace sde { namespace sdm {
/*! @brief Input configuration set by the client for buffer allocation. /*! @brief Input configuration set by the client for buffer allocation.
@sa BufferInfo::BufferConfig @sa BufferInfo::BufferConfig
@@ -87,8 +86,8 @@ struct BufferInfo {
/*! @brief Buffer allocator implemented by the client /*! @brief Buffer allocator implemented by the client
@details This class declares prototype for BufferAllocator methods which must be @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 implemented by the client. Buffer manager in display manager will use these methods to
allocate/deallocate buffers for display engine. allocate/deallocate buffers for display manager.
@sa CoreInterface::CreateCore @sa CoreInterface::CreateCore
*/ */
@@ -119,7 +118,7 @@ class BufferAllocator {
virtual ~BufferAllocator() { } virtual ~BufferAllocator() { }
}; };
} // namespace sde } // namespace sdm
#endif // __BUFFER_ALLOCATOR_H__ #endif // __BUFFER_ALLOCATOR_H__

View File

@@ -30,20 +30,20 @@
/*! @file buffer_sync_handler.h /*! @file buffer_sync_handler.h
@brief Interface file for platform specific buffer allocator. @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 @details SDM will use this interface to wait for buffer sync fd to be signaled/merge
signaled/merge the two buffer sync fds into one the two buffer sync fds into one.
*/ */
#ifndef __BUFFER_SYNC_HANDLER_H__ #ifndef __BUFFER_SYNC_HANDLER_H__
#define __BUFFER_SYNC_HANDLER_H__ #define __BUFFER_SYNC_HANDLER_H__
namespace sde { namespace sdm {
/*! @brief Buffer sync handler implemented by the client /*! @brief Buffer sync handler implemented by the client
@details This class declares prototype for BufferSyncHandler methods which must be @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 implemented by the client. SDM will use these methods to wait for buffer sync fd to be
methods to wait for buffer sync fd to be signaled/merge two buffer sync fds into one. signaled/merge two buffer sync fds into one.
@sa CoreInterface::CreateCore @sa CoreInterface::CreateCore
*/ */
@@ -78,7 +78,7 @@ class BufferSyncHandler {
virtual ~BufferSyncHandler() { } virtual ~BufferSyncHandler() { }
}; };
} // namespace sde } // namespace sdm
#endif // __BUFFER_SYNC_HANDLER_H__ #endif // __BUFFER_SYNC_HANDLER_H__

View File

@@ -40,23 +40,23 @@
#include <stdint.h> #include <stdint.h>
#include "display_interface.h" #include "display_interface.h"
#include "sde_types.h" #include "sdm_types.h"
#include "buffer_allocator.h" #include "buffer_allocator.h"
class BufferSyncHandler; 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. 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. 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 A 32-bit client must use 32-bit display core library and a 64-bit client must use 64-bit display
core library. 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. default padding rules while using these interfaces.
@warning It is assumed that client upgrades or downgrades display core interface all at once @warning It is assumed that client upgrades or downgrades display core interface all at once
@@ -65,13 +65,13 @@ class BufferSyncHandler;
@sa CoreInterface::CreateCore @sa CoreInterface::CreateCore
*/ */
#define SDE_REVISION_MAJOR (1) #define SDM_REVISION_MAJOR (1)
#define SDE_REVISION_MINOR (0) #define SDM_REVISION_MINOR (0)
#define SDE_VERSION_TAG ((uint32_t) ((SDE_REVISION_MAJOR << 24) | (SDE_REVISION_MINOR << 16) | \ #define SDM_VERSION_TAG ((uint32_t) ((SDM_REVISION_MAJOR << 24) | (SDM_REVISION_MINOR << 16) | \
(sizeof(SDECompatibility) << 8) | sizeof(int *))) (sizeof(SDMCompatibility) << 8) | sizeof(int *)))
namespace sde { namespace sdm {
/*! @brief Forward declaration for debug handler. /*! @brief Forward declaration for debug handler.
*/ */
@@ -137,7 +137,7 @@ class CoreInterface {
@param[in] buffer_allocator \link BufferAllocator \endlink @param[in] buffer_allocator \link BufferAllocator \endlink
@param[in] buffer_sync_handler \link BufferSyncHandler \endlink @param[in] buffer_sync_handler \link BufferSyncHandler \endlink
@param[out] interface \link CoreInterface \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 @return \link DisplayError \endlink
@@ -146,7 +146,7 @@ class CoreInterface {
static DisplayError CreateCore(CoreEventHandler *event_handler, DebugHandler *debug_handler, static DisplayError CreateCore(CoreEventHandler *event_handler, DebugHandler *debug_handler,
BufferAllocator *buffer_allocator, BufferAllocator *buffer_allocator,
BufferSyncHandler *buffer_sync_handler, CoreInterface **interface, 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. /*! @brief Method to release handle to display core interface.
@@ -195,7 +195,7 @@ class CoreInterface {
virtual ~CoreInterface() { } virtual ~CoreInterface() { }
}; };
} // namespace sde } // namespace sdm
#endif // __CORE_INTERFACE_H__ #endif // __CORE_INTERFACE_H__

View File

@@ -28,12 +28,12 @@
*/ */
/*! @file debug_interface.h /*! @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__ #ifndef __DEBUG_INTERFACE_H__
#define __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 /*! @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. be associated with. Client may use this to filter messages for dynamic logging.
@@ -53,7 +53,7 @@ enum DebugTag {
/*! @brief Display debug handler class. /*! @brief Display debug handler class.
@details This class defines display debug handler. The handle contains methods which client @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. will call into these methods at appropriate times to send logging/tracing information.
@sa CoreInterface::CreateCore @sa CoreInterface::CreateCore
@@ -120,7 +120,7 @@ class ScopeTracer {
~ScopeTracer() { T::Get()->EndTrace(); } ~ScopeTracer() { T::Get()->EndTrace(); }
}; };
} // namespace sde } // namespace sdm
#endif // __DEBUG_INTERFACE_H__ #endif // __DEBUG_INTERFACE_H__

View File

@@ -36,9 +36,9 @@
#include <stdint.h> #include <stdint.h>
#include "layer_stack.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. /*! @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 @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. 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. thread instantly.
@sa CoreInterface::CreateDisplay @sa CoreInterface::CreateDisplay
@@ -170,13 +170,13 @@ class DisplayInterface {
/*! @brief Method to determine hardware capability to compose layers associated with given frame. /*! @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 @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 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 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. 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 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. /*! @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 respective fences currently in use. This operation may result in a blank display on the panel
until a new frame is submitted for composition. until a new frame is submitted for composition.
@@ -359,7 +359,7 @@ class DisplayInterface {
virtual ~DisplayInterface() { } virtual ~DisplayInterface() { }
}; };
} // namespace sde } // namespace sdm
#endif // __DISPLAY_INTERFACE_H__ #endif // __DISPLAY_INTERFACE_H__

View File

@@ -23,7 +23,7 @@
*/ */
/*! @file dump_interface.h /*! @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__ #ifndef __DUMP_INTERFACE_H__
@@ -31,20 +31,20 @@
#include <stdint.h> #include <stdint.h>
#include "sde_types.h" #include "sdm_types.h"
namespace sde { namespace sdm {
/*! @brief Display dump interface. /*! @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 { class DumpInterface {
public: public:
/*! @brief Method to get dump information in form of a string. /*! @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. formatted string for logging or dumping purposes.
@param[inout] buffer String buffer allocated by the client. Filled with null terminated dump @param[inout] buffer String buffer allocated by the client. Filled with null terminated dump
@@ -62,7 +62,7 @@ class DumpInterface {
virtual ~DumpInterface() { } virtual ~DumpInterface() { }
}; };
} // namespace sde } // namespace sdm
#endif // __DUMP_INTERFACE_H__ #endif // __DUMP_INTERFACE_H__

View File

@@ -31,11 +31,11 @@
#include <stdint.h> #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 @sa LayerBuffer
*/ */
@@ -176,25 +176,25 @@ struct LayerBuffer {
//!< on the buffer format specified. //!< on the buffer format specified.
int acquire_fence_fd; //!< File descriptor referring to a sync fence object which will be 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 //!< This fence object is set by the client during Commit(). For
//!< input buffers client shall signal this fence when buffer //!< 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 //!< 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 //!< This field is used only during Commit() and shall be set to -1
//!< by the client when buffer is already available for read/write. //!< 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 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. //!< signaled when buffer has been read/written by display manager.
//!< This fence object is set by display engine during Commit(). //!< This fence object is set by display manager during Commit().
//!< For input buffers display engine will signal this fence when //!< For input buffers display manager will signal this fence when
//!< buffer has been consumed. For output buffers, display engine //!< buffer has been consumed. For output buffers, display manager
//!< will signal this fence when buffer is produced. //!< will signal this fence when buffer is produced.
//!< This field is used only during Commit() and will be set to -1 //!< 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. //!< read/write.
LayerBufferFlags flags; //!< Flags associated with this buffer. LayerBufferFlags flags; //!< Flags associated with this buffer.
@@ -203,7 +203,7 @@ struct LayerBuffer {
release_fence_fd(-1) { } release_fence_fd(-1) { }
}; };
} // namespace sde } // namespace sdm
#endif // __LAYER_BUFFER_H__ #endif // __LAYER_BUFFER_H__

View File

@@ -35,9 +35,9 @@
#include <utils/constants.h> #include <utils/constants.h>
#include "layer_buffer.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. /*! @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) { } LayerStack() : layers(NULL), layer_count(0), retire_fence_fd(-1), output_buffer(NULL) { }
}; };
} // namespace sde } // namespace sdm
#endif // __LAYER_STACK_H__ #endif // __LAYER_STACK_H__

View File

@@ -27,13 +27,13 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 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. @brief This file contains miscellaneous data types used across display interfaces.
*/ */
#ifndef __SDE_TYPES_H__ #ifndef __SDM_TYPES_H__
#define __SDE_TYPES_H__ #define __SDM_TYPES_H__
namespace sde { namespace sdm {
/*! @brief This enum represents different error codes that display interfaces may return. /*! @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 /*! @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. any purpose.
*/ */
struct SDECompatibility { struct SDMCompatibility {
char c1; char c1;
int i1; int i1;
char c2; char c2;
int i2; int i2;
}; };
} // namespace sde } // namespace sdm
#endif // __SDE_TYPES_H__ #endif // __SDM_TYPES_H__

View 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__

View 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__

View File

@@ -22,32 +22,26 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef __HW_ROTATOR_INTERFACE_H__ #ifndef __PARTIAL_UPDATE_INTERFACE_H__
#define __HW_ROTATOR_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; #include "hw_info_types.h"
struct HWRotateInfo;
struct HWLayers;
struct HWRotatorSession;
class HWRotatorInterface { namespace sdm {
class PartialUpdateInterface {
public: public:
static DisplayError Create(BufferSyncHandler *buffer_sync_handler, HWRotatorInterface **intf); virtual DisplayError GenerateROI(HWLayersInfo *hw_layers_info) = 0;
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;
protected: protected:
virtual ~HWRotatorInterface() { } virtual ~PartialUpdateInterface() { }
}; };
} // namespace sde } // namespace sdm
#endif // __HW_ROTATOR_INTERFACE_H__ #endif // __PARTIAL_UPDATE_INTERFACE_H__

View File

@@ -22,50 +22,36 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef __SCALAR_HELPER_H__ #ifndef __RESOURCE_INTERFACE_H__
#define __SCALAR_HELPER_H__ #define __RESOURCE_INTERFACE_H__
#include <hw_interface.h> #include <core/display_interface.h>
#ifdef USES_SCALAR #include "hw_info_types.h"
#include <scalar.h>
#endif
namespace sde { namespace sdm {
class Scalar { class ResourceInterface {
public: public:
static DisplayError CreateScalar(Scalar **scalar); virtual DisplayError RegisterDisplay(DisplayType type, const HWDisplayAttributes &attributes,
static void Destroy(Scalar *scalar); const HWPanelInfo &hw_panel_info, Handle *display_ctx) = 0;
virtual ~Scalar() { } virtual DisplayError UnregisterDisplay(Handle display_ctx) = 0;
virtual DisplayError ConfigureScale(HWLayers *hw_layers) { return kErrorNone; } 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: protected:
virtual DisplayError Init() { return kErrorNone; } virtual ~ResourceInterface() { }
virtual void Deinit() { }
}; };
#ifdef USES_SCALAR } // namespace sdm
class ScalarHelper : public Scalar {
public:
ScalarHelper();
virtual DisplayError ConfigureScale(HWLayers *hw_layers);
protected: #endif // __RESOURCE_INTERFACE_H__
virtual DisplayError Init();
virtual void Deinit();
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__

View File

@@ -22,44 +22,31 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef __HW_ROTATOR_H__ #ifndef __ROTATOR_INTERFACE_H__
#define __HW_ROTATOR_H__ #define __ROTATOR_INTERFACE_H__
#include <errno.h> #include <core/display_interface.h>
#include <stdio.h> #include <core/buffer_allocator.h>
#include <stdlib.h> #include <core/buffer_sync_handler.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 "hw_device.h" #include "hw_info_types.h"
#include "hw_rotator_interface.h"
namespace sde { namespace sdm {
class HWRotator : public HWDevice, public HWRotatorInterface { class RotatorInterface {
public: public:
explicit HWRotator(BufferSyncHandler *buffer_sync_handler); virtual DisplayError RegisterDisplay(DisplayType type, Handle *display_ctx) = 0;
virtual DisplayError Open(); virtual void UnregisterDisplay(Handle display_ctx) = 0;
virtual DisplayError Close(); virtual DisplayError Prepare(Handle display_ctx, HWLayers *hw_layers) = 0;
virtual DisplayError OpenSession(HWRotatorSession *hw_session_info); virtual DisplayError Commit(Handle display_ctx, HWLayers *hw_layers) = 0;
virtual DisplayError CloseSession(HWRotatorSession *hw_session_info); virtual DisplayError PostCommit(Handle display_ctx, HWLayers *hw_layers) = 0;
virtual DisplayError Validate(HWLayers *hw_layers); virtual DisplayError Purge(Handle display_ctx, HWLayers *hw_layers) = 0;
virtual DisplayError Commit(HWLayers *hw_layers);
private: protected:
void ResetParams(); virtual ~RotatorInterface() { }
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)
}; };
} // namespace sde } // namespace sdm
#endif // __HW_ROTATOR_H__ #endif // __ROTATOR_INTERFACE_H__

View File

@@ -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 * Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met: * provided that the following conditions are met:
@@ -22,38 +22,37 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef __STRATEGY_DEFAULT_H__ #ifndef __STRATEGY_INTERFACE_H__
#define __STRATEGY_DEFAULT_H__ #define __STRATEGY_INTERFACE_H__
#include <core/sdm_types.h>
#include <core/display_interface.h> #include <core/display_interface.h>
#include <private/strategy_interface.h> #include "hw_info_types.h"
namespace sde { namespace sdm {
class StrategyDefault : public StrategyInterface { struct StrategyConstraints {
public: bool safe_mode; //!< In this mode, strategy manager chooses the composition strategy
StrategyDefault(DisplayType type, const HWResourceInfo &hw_resource_info, //!< that requires minimum number of pipe for the current frame. i.e.,
const HWPanelInfo &hw_panel_info); //!< video only composition, secure only composition or GPU composition
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);
virtual DisplayError Start(HWLayersInfo *hw_layers_info, uint32_t *max_attempts); uint32_t max_layers; //!< Maximum number of layers that shall be programmed on hardware for the
virtual DisplayError GetNextStrategy(StrategyConstraints *constraints); //!< given layer stack.
virtual DisplayError Stop();
private: StrategyConstraints() : safe_mode(false), max_layers(kMaxSDELayers) { }
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_;
}; };
} // 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__

View File

@@ -76,14 +76,14 @@ inline T1 CeilToMultipleOf(const T1 &value, const T2 &factor) {
return (T1)((value + (factor - 1)) & (~(factor - 1))); return (T1)((value + (factor - 1)) & (~(factor - 1)));
} }
namespace sde { namespace sdm {
const int kThreadPriorityUrgent = -9; const int kThreadPriorityUrgent = -9;
const int kMaxRotatePerLayer = 2; const int kMaxRotatePerLayer = 2;
typedef void * Handle; typedef void * Handle;
} // namespace sde } // namespace sdm
#endif // __CONSTANTS_H__ #endif // __CONSTANTS_H__

View File

@@ -31,7 +31,7 @@
#define __DEBUG_H__ #define __DEBUG_H__
#include <stdint.h> #include <stdint.h>
#include <core/sde_types.h> #include <core/sdm_types.h>
#include <core/debug_interface.h> #include <core/debug_interface.h>
#define DLOG(tag, method, format, ...) Debug::Get()->method(tag, __CLASS__ "::%s: " format, \ #define DLOG(tag, method, format, ...) Debug::Get()->method(tag, __CLASS__ "::%s: " format, \
@@ -51,7 +51,7 @@
#define DTRACE_END() Debug::Get()->EndTrace() #define DTRACE_END() Debug::Get()->EndTrace()
#define DTRACE_SCOPED() ScopeTracer <Debug> scope_tracer(__CLASS__, __FUNCTION__) #define DTRACE_SCOPED() ScopeTracer <Debug> scope_tracer(__CLASS__, __FUNCTION__)
namespace sde { namespace sdm {
class Debug { class Debug {
public: public:
@@ -70,8 +70,8 @@ class Debug {
private: private:
Debug(); Debug();
// By default, drop any log messages/traces coming from Display Engine. It will be overriden by // By default, drop any log messages/traces coming from Display manager. It will be overriden by
// Display Engine client when core is successfully initialized. // Display manager client when core is successfully initialized.
class DefaultDebugHandler : public DebugHandler { class DefaultDebugHandler : public DebugHandler {
public: public:
virtual void Error(DebugTag /*tag*/, const char */*format*/, ...) { } virtual void Error(DebugTag /*tag*/, const char */*format*/, ...) { }
@@ -89,7 +89,7 @@ class Debug {
static Debug debug_; static Debug debug_;
}; };
} // namespace sde } // namespace sdm
#endif // __DEBUG_H__ #endif // __DEBUG_H__

View File

@@ -34,7 +34,7 @@
#define SEQUENCE_WAIT_SCOPE_LOCK(locker) Locker::SequenceWaitScopeLock lock(locker) #define SEQUENCE_WAIT_SCOPE_LOCK(locker) Locker::SequenceWaitScopeLock lock(locker)
#define SEQUENCE_CANCEL_SCOPE_LOCK(locker) Locker::SequenceCancelScopeLock lock(locker) #define SEQUENCE_CANCEL_SCOPE_LOCK(locker) Locker::SequenceCancelScopeLock lock(locker)
namespace sde { namespace sdm {
class Locker { class Locker {
public: public:
@@ -159,7 +159,7 @@ class Locker {
// further processing. // further processing.
}; };
} // namespace sde } // namespace sdm
#endif // __LOCKER_H__ #endif // __LOCKER_H__

View File

@@ -31,11 +31,11 @@
#define __RECT_H__ #define __RECT_H__
#include <stdint.h> #include <stdint.h>
#include <core/sde_types.h> #include <core/sdm_types.h>
#include <core/layer_stack.h> #include <core/layer_stack.h>
#include <utils/debug.h> #include <utils/debug.h>
namespace sde { namespace sdm {
bool IsValid(const LayerRect &rect); bool IsValid(const LayerRect &rect);
bool IsCongruent(const LayerRect &rect1, const LayerRect &rect2); bool IsCongruent(const LayerRect &rect1, const LayerRect &rect2);
@@ -45,7 +45,7 @@ namespace sde {
LayerRect Intersection(const LayerRect &rect1, const LayerRect &rect2); LayerRect Intersection(const LayerRect &rect1, const LayerRect &rect2);
LayerRect Subtract(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); LayerRect Reposition(const LayerRect &rect1, const int &x_offset, const int &y_offset);
} // namespace sde } // namespace sdm
#endif // __RECT_H__ #endif // __RECT_H__

View File

@@ -1,19 +1,15 @@
LOCAL_PATH := $(call my-dir) LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS) include $(CLEAR_VARS)
LOCAL_MODULE := libsde LOCAL_MODULE := libsdmcore
LOCAL_MODULE_TAGS := optional 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 $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
LOCAL_CFLAGS := -Wno-missing-field-initializers -Wno-unused-parameter \ LOCAL_CFLAGS := -Wno-missing-field-initializers -Wno-unused-parameter \
-Wconversion -Wall -Werror \ -Wconversion -Wall -Werror \
-DLOG_TAG=\"SDE\" -DLOG_TAG=\"SDM\"
ifeq ($(TARGET_USES_SCALAR), true)
LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/scalar/inc
LOCAL_CFLAGS += -DUSES_SCALAR
endif
LOCAL_HW_INTF_PATH := fb 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_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
LOCAL_SRC_FILES := core_interface.cpp \ LOCAL_SRC_FILES := core_interface.cpp \
core_impl.cpp \ core_impl.cpp \
@@ -22,17 +18,12 @@ LOCAL_SRC_FILES := core_interface.cpp \
display_hdmi.cpp \ display_hdmi.cpp \
display_virtual.cpp \ display_virtual.cpp \
comp_manager.cpp \ comp_manager.cpp \
strategy_default.cpp \ strategy.cpp \
res_manager.cpp \ resource_default.cpp \
res_config.cpp \
rotator_ctrl.cpp \
dump_impl.cpp \ dump_impl.cpp \
session_manager.cpp \
scalar_helper.cpp \
$(LOCAL_HW_INTF_PATH)/hw_info.cpp \ $(LOCAL_HW_INTF_PATH)/hw_info.cpp \
$(LOCAL_HW_INTF_PATH)/hw_device.cpp \ $(LOCAL_HW_INTF_PATH)/hw_device.cpp \
$(LOCAL_HW_INTF_PATH)/hw_primary.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_hdmi.cpp \
$(LOCAL_HW_INTF_PATH)/hw_virtual.cpp $(LOCAL_HW_INTF_PATH)/hw_virtual.cpp

View File

@@ -22,64 +22,41 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <dlfcn.h>
#include <utils/constants.h> #include <utils/constants.h>
#include <utils/debug.h> #include <utils/debug.h>
#include <core/buffer_allocator.h> #include <core/buffer_allocator.h>
#include "comp_manager.h" #include "comp_manager.h"
#include "strategy_default.h" #include "strategy.h"
#define __CLASS__ "CompManager" #define __CLASS__ "CompManager"
namespace sde { namespace sdm {
CompManager::CompManager() CompManager::CompManager()
: strategy_lib_(NULL), create_strategy_intf_(NULL), destroy_strategy_intf_(NULL), : resource_intf_(NULL), registered_displays_(0), configured_displays_(0), safe_mode_(false),
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_); SCOPE_LOCK(locker_);
DisplayError error = kErrorNone; 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) { if (error != kErrorNone) {
return error; 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; hw_res_info_ = hw_res_info;
extension_intf_ = extension_intf;
return error; return error;
} }
@@ -87,12 +64,12 @@ DisplayError CompManager::Init(const HWResourceInfo &hw_res_info) {
DisplayError CompManager::Deinit() { DisplayError CompManager::Deinit() {
SCOPE_LOCK(locker_); SCOPE_LOCK(locker_);
if (strategy_lib_) { if (extension_intf_) {
::dlclose(strategy_lib_); extension_intf_->DestroyResourceExtn(resource_intf_);
} else {
resource_default_.Deinit();
} }
res_mgr_.Deinit();
return kErrorNone; return kErrorNone;
} }
@@ -107,18 +84,26 @@ DisplayError CompManager::RegisterDisplay(DisplayType type, const HWDisplayAttri
return kErrorMemory; return kErrorMemory;
} }
if (create_strategy_intf_(STRATEGY_VERSION_TAG, type, hw_res_info_, hw_panel_info, Strategy *&strategy = display_comp_ctx->strategy;
&display_comp_ctx->strategy_intf) != kErrorNone) { strategy = new Strategy(extension_intf_, type, hw_res_info_, hw_panel_info);
DLOGW("Unable to create strategy interface"); if (!strategy) {
DLOGE("Unable to create strategy");
delete display_comp_ctx; delete display_comp_ctx;
display_comp_ctx = NULL; return kErrorMemory;
return kErrorUndefined;
} }
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); &display_comp_ctx->display_resource_ctx);
if (error != kErrorNone) { if (error != kErrorNone) {
destroy_strategy_intf_(display_comp_ctx->strategy_intf); strategy->Deinit();
delete strategy;
delete display_comp_ctx; delete display_comp_ctx;
display_comp_ctx = NULL; display_comp_ctx = NULL;
return error; return error;
@@ -150,8 +135,11 @@ DisplayError CompManager::UnregisterDisplay(Handle comp_handle) {
return kErrorParameters; return kErrorParameters;
} }
res_mgr_.UnregisterDisplay(display_comp_ctx->display_resource_ctx); resource_intf_->UnregisterDisplay(display_comp_ctx->display_resource_ctx);
destroy_strategy_intf_(display_comp_ctx->strategy_intf);
Strategy *&strategy = display_comp_ctx->strategy;
strategy->Deinit();
delete strategy;
CLEAR_BIT(registered_displays_, display_comp_ctx->display_type); CLEAR_BIT(registered_displays_, display_comp_ctx->display_type);
CLEAR_BIT(configured_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 = DisplayCompositionContext *display_comp_ctx =
reinterpret_cast<DisplayCompositionContext *>(comp_handle); 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 // 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_); SCOPE_LOCK(locker_);
DisplayCompositionContext *display_comp_ctx = DisplayCompositionContext *display_comp_ctx =
reinterpret_cast<DisplayCompositionContext *>(display_ctx); reinterpret_cast<DisplayCompositionContext *>(display_ctx);
display_comp_ctx->strategy_intf->Start(&hw_layers->info, display_comp_ctx->strategy->Start(&hw_layers->info, &display_comp_ctx->max_strategies);
&display_comp_ctx->max_strategies);
display_comp_ctx->remaining_strategies = 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. // 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); PrepareStrategyConstraints(display_ctx, hw_layers);
// Select a composition strategy, and try to allocate resources for it. // 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; bool exit = false;
uint32_t &count = display_comp_ctx->remaining_strategies; uint32_t &count = display_comp_ctx->remaining_strategies;
for (; !exit && count > 0; count--) { 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) { if (error != kErrorNone) {
// Composition strategies exhausted. Resource Manager could not allocate resources even for // Composition strategies exhausted. Resource Manager could not allocate resources even for
// GPU composition. This will never happen. // GPU composition. This will never happen.
@@ -238,7 +226,7 @@ DisplayError CompManager::Prepare(Handle display_ctx, HWLayers *hw_layers) {
} }
if (!exit) { 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 if successfully allocated resource, else try next strategy.
exit = (error == kErrorNone); 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); 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; 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; Handle &display_resource_ctx = display_comp_ctx->display_resource_ctx;
DisplayError error = kErrorNone; DisplayError error = kErrorNone;
error = res_mgr_.PostPrepare(display_resource_ctx, hw_layers); error = resource_intf_->PostPrepare(display_resource_ctx, hw_layers);
if (error != kErrorNone) { if (error != kErrorNone) {
return error; return error;
} }
display_comp_ctx->strategy_intf->Stop(); display_comp_ctx->strategy->Stop();
return kErrorNone; return kErrorNone;
} }
@@ -281,7 +269,7 @@ DisplayError CompManager::PostCommit(Handle display_ctx, HWLayers *hw_layers) {
safe_mode_ = false; 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) { if (error != kErrorNone) {
return error; return error;
} }
@@ -301,7 +289,7 @@ void CompManager::Purge(Handle display_ctx) {
DisplayCompositionContext *display_comp_ctx = DisplayCompositionContext *display_comp_ctx =
reinterpret_cast<DisplayCompositionContext *>(display_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) { 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); reinterpret_cast<DisplayCompositionContext *>(display_ctx);
if (display_comp_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; return error;
@@ -363,8 +352,8 @@ void CompManager::AppendDump(char *buffer, uint32_t length) {
DisplayError CompManager::ValidateScaling(const LayerRect &crop, const LayerRect &dst, DisplayError CompManager::ValidateScaling(const LayerRect &crop, const LayerRect &dst,
bool rotate90) { bool rotate90) {
return res_mgr_.ValidateScaling(crop, dst, rotate90); return resource_intf_->ValidateScaling(crop, dst, rotate90);
} }
} // namespace sde } // namespace sdm

View File

@@ -26,17 +26,20 @@
#define __COMP_MANAGER_H__ #define __COMP_MANAGER_H__
#include <core/display_interface.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 "hw_interface.h"
#include "res_manager.h"
#include "dump_impl.h" #include "dump_impl.h"
namespace sde { namespace sdm {
class CompManager : public DumpImpl { class CompManager : public DumpImpl {
public: public:
CompManager(); CompManager();
DisplayError Init(const HWResourceInfo &hw_res_info_); DisplayError Init(const HWResourceInfo &hw_res_info_, ExtensionInterface *extension_intf);
DisplayError Deinit(); DisplayError Deinit();
DisplayError RegisterDisplay(DisplayType type, const HWDisplayAttributes &attributes, DisplayError RegisterDisplay(DisplayType type, const HWDisplayAttributes &attributes,
const HWPanelInfo &hw_panel_info, Handle *res_mgr_hnd); 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); void PrepareStrategyConstraints(Handle display_ctx, HWLayers *hw_layers);
struct DisplayCompositionContext { struct DisplayCompositionContext {
StrategyInterface *strategy_intf; Strategy *strategy;
StrategyConstraints constraints; StrategyConstraints constraints;
Handle display_resource_ctx; Handle display_resource_ctx;
DisplayType display_type; DisplayType display_type;
@@ -79,19 +82,18 @@ class CompManager : public DumpImpl {
}; };
Locker locker_; Locker locker_;
void *strategy_lib_; ResourceInterface *resource_intf_;
CreateStrategyInterface create_strategy_intf_; ResourceDefault resource_default_;
DestroyStrategyInterface destroy_strategy_intf_;
ResManager res_mgr_;
uint64_t registered_displays_; // Stores the bit mask of registered displays uint64_t registered_displays_; // Stores the bit mask of registered displays
uint64_t configured_displays_; // Stores the bit mask of sucessfully configured 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 bool safe_mode_; // Flag to notify all displays to be in resource crunch
// mode, where strategy manager chooses the best strategy // mode, where strategy manager chooses the best strategy
// that uses optimal number of pipes for each display // that uses optimal number of pipes for each display
HWResourceInfo hw_res_info_; HWResourceInfo hw_res_info_;
ExtensionInterface *extension_intf_;
}; };
} // namespace sde } // namespace sdm
#endif // __COMP_MANAGER_H__ #endif // __COMP_MANAGER_H__

View File

@@ -22,6 +22,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <dlfcn.h>
#include <utils/locker.h> #include <utils/locker.h>
#include <utils/constants.h> #include <utils/constants.h>
#include <utils/debug.h> #include <utils/debug.h>
@@ -31,65 +32,93 @@
#include "display_hdmi.h" #include "display_hdmi.h"
#include "display_virtual.h" #include "display_virtual.h"
#include "hw_info_interface.h" #include "hw_info_interface.h"
#include "rotator_ctrl.h"
#define __CLASS__ "CoreImpl" #define __CLASS__ "CoreImpl"
namespace sde { namespace sdm {
CoreImpl::CoreImpl(CoreEventHandler *event_handler, BufferAllocator *buffer_allocator, CoreImpl::CoreImpl(CoreEventHandler *event_handler, BufferAllocator *buffer_allocator,
BufferSyncHandler *buffer_sync_handler) BufferSyncHandler *buffer_sync_handler)
: event_handler_(event_handler), buffer_allocator_(buffer_allocator), : 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() { DisplayError CoreImpl::Init() {
SCOPE_LOCK(locker_); SCOPE_LOCK(locker_);
DisplayError error = kErrorNone; 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_); error = HWInfoInterface::Create(&hw_info_intf_);
if (error != kErrorNone) { if (error != kErrorNone) {
return error; goto CleanupOnError;
} }
hw_resource_ = new HWResourceInfo(); hw_resource_ = new HWResourceInfo();
if (!hw_resource_) { if (!hw_resource_) {
error = kErrorMemory; error = kErrorMemory;
goto CleanUpOnError; goto CleanupOnError;
} }
error = hw_info_intf_->GetHWResourceInfo(hw_resource_); error = hw_info_intf_->GetHWResourceInfo(hw_resource_);
if (error != kErrorNone) { if (error != kErrorNone) {
goto CleanUpOnError; goto CleanupOnError;
} }
error = comp_mgr_.Init(*hw_resource_); error = comp_mgr_.Init(*hw_resource_, extension_intf_);
if (error != kErrorNone) { if (error != kErrorNone) {
goto CleanUpOnError; goto CleanupOnError;
} }
rotator_ctrl_ = new RotatorCtrl(); if (extension_intf_) {
if (!rotator_ctrl_) { error = extension_intf_->CreateRotator(buffer_allocator_, buffer_sync_handler_,
&rotator_intf_);
if (error != kErrorNone) {
comp_mgr_.Deinit(); 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; return kErrorNone;
CleanUpOnError: CleanupOnError:
if (hw_resource_) { if (hw_info_intf_) {
delete hw_resource_; HWInfoInterface::Destroy(hw_info_intf_);
hw_resource_ = NULL;
} }
HWInfoInterface::Destroy(hw_info_intf_); if (hw_resource_) {
delete hw_resource_;
}
if (extension_lib_) {
destroy_extension_intf_(extension_intf_);
::dlclose(extension_lib_);
}
return error; return error;
} }
@@ -97,10 +126,22 @@ CleanUpOnError:
DisplayError CoreImpl::Deinit() { DisplayError CoreImpl::Deinit() {
SCOPE_LOCK(locker_); SCOPE_LOCK(locker_);
rotator_ctrl_->Deinit(); if (extension_intf_) {
extension_intf_->DestroyRotator(rotator_intf_);
}
comp_mgr_.Deinit(); comp_mgr_.Deinit();
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 kErrorNone; return kErrorNone;
} }
@@ -117,15 +158,15 @@ DisplayError CoreImpl::CreateDisplay(DisplayType type, DisplayEventHandler *even
switch (type) { switch (type) {
case kPrimary: case kPrimary:
display_base = new DisplayPrimary(event_handler, hw_info_intf_, buffer_sync_handler_, display_base = new DisplayPrimary(event_handler, hw_info_intf_, buffer_sync_handler_,
&comp_mgr_, rotator_ctrl_); &comp_mgr_, rotator_intf_);
break; break;
case kHDMI: case kHDMI:
display_base = new DisplayHDMI(event_handler, hw_info_intf_, buffer_sync_handler_, display_base = new DisplayHDMI(event_handler, hw_info_intf_, buffer_sync_handler_,
&comp_mgr_, rotator_ctrl_); &comp_mgr_, rotator_intf_);
break; break;
case kVirtual: case kVirtual:
display_base = new DisplayVirtual(event_handler, hw_info_intf_, buffer_sync_handler_, display_base = new DisplayVirtual(event_handler, hw_info_intf_, buffer_sync_handler_,
&comp_mgr_, rotator_ctrl_); &comp_mgr_, rotator_intf_);
break; break;
default: default:
DLOGE("Spurious display type %d", type); DLOGE("Spurious display type %d", type);
@@ -163,5 +204,5 @@ DisplayError CoreImpl::DestroyDisplay(DisplayInterface *intf) {
return kErrorNone; return kErrorNone;
} }
} // namespace sde } // namespace sdm

View File

@@ -26,7 +26,7 @@
#define __CORE_IMPL_H__ #define __CORE_IMPL_H__
#include <core/core_interface.h> #include <core/core_interface.h>
#include <private/strategy_interface.h> #include <private/extension_interface.h>
#include <utils/locker.h> #include <utils/locker.h>
#include "hw_interface.h" #include "hw_interface.h"
@@ -34,7 +34,7 @@
#define SET_REVISION(major, minor) ((major << 8) | minor) #define SET_REVISION(major, minor) ((major << 8) | minor)
namespace sde { namespace sdm {
class HWInfoInterface; class HWInfoInterface;
class RotatorCtrl; class RotatorCtrl;
@@ -66,11 +66,15 @@ class CoreImpl : public CoreInterface {
BufferSyncHandler *buffer_sync_handler_; BufferSyncHandler *buffer_sync_handler_;
HWResourceInfo *hw_resource_; HWResourceInfo *hw_resource_;
CompManager comp_mgr_; CompManager comp_mgr_;
RotatorCtrl *rotator_ctrl_;
HWInfoInterface *hw_info_intf_; 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__ #endif // __CORE_IMPL_H__

View File

@@ -40,7 +40,7 @@
#define GET_DATA_ALIGNMENT(version) ((version >> 8) & 0xFF) #define GET_DATA_ALIGNMENT(version) ((version >> 8) & 0xFF)
#define GET_INSTRUCTION_SET(version) (version & 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 // Currently, we support only one client and one session for display core. So, create a global
// singleton core object. // singleton core object.
@@ -63,7 +63,7 @@ DisplayError CoreInterface::CreateCore(CoreEventHandler *event_handler, DebugHan
} }
// Check compatibility of client and core. // 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)) { if (GET_REVISION(client_version) > GET_REVISION(lib_version)) {
return kErrorVersion; return kErrorVersion;
} else if (GET_DATA_ALIGNMENT(client_version) != GET_DATA_ALIGNMENT(lib_version)) { } else if (GET_DATA_ALIGNMENT(client_version) != GET_DATA_ALIGNMENT(lib_version)) {
@@ -120,5 +120,5 @@ DisplayError CoreInterface::DestroyCore() {
return kErrorNone; return kErrorNone;
} }
} // namespace sde } // namespace sdm

View File

@@ -27,19 +27,18 @@
#include <utils/debug.h> #include <utils/debug.h>
#include "display_base.h" #include "display_base.h"
#include "rotator_ctrl.h"
#define __CLASS__ "DisplayBase" #define __CLASS__ "DisplayBase"
namespace sde { namespace sdm {
// TODO(user): Have a single structure handle carries all the interface pointers and variables. // TODO(user): Have a single structure handle carries all the interface pointers and variables.
DisplayBase::DisplayBase(DisplayType display_type, DisplayEventHandler *event_handler, DisplayBase::DisplayBase(DisplayType display_type, DisplayEventHandler *event_handler,
HWDeviceType hw_device_type, BufferSyncHandler *buffer_sync_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), : display_type_(display_type), event_handler_(event_handler), hw_device_type_(hw_device_type),
buffer_sync_handler_(buffer_sync_handler), comp_manager_(comp_manager), 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), display_attributes_(NULL), num_modes_(0), active_mode_index_(0), pending_commit_(false),
vsync_enable_(false), underscan_supported_(false) { vsync_enable_(false), underscan_supported_(false) {
} }
@@ -80,8 +79,8 @@ DisplayError DisplayBase::Init() {
goto CleanupOnError; goto CleanupOnError;
} }
if (rotator_ctrl_) { if (rotator_intf_) {
error = rotator_ctrl_->RegisterDisplay(display_type_, &display_rotator_ctx_); error = rotator_intf_->RegisterDisplay(display_type_, &display_rotator_ctx_);
if (error != kErrorNone) { if (error != kErrorNone) {
goto CleanupOnError; goto CleanupOnError;
} }
@@ -105,8 +104,8 @@ CleanupOnError:
} }
DisplayError DisplayBase::Deinit() { DisplayError DisplayBase::Deinit() {
if (rotator_ctrl_) { if (rotator_intf_) {
rotator_ctrl_->UnregisterDisplay(display_rotator_ctx_); rotator_intf_->UnregisterDisplay(display_rotator_ctx_);
} }
comp_manager_->UnregisterDisplay(display_comp_ctx_); comp_manager_->UnregisterDisplay(display_comp_ctx_);
@@ -134,6 +133,7 @@ DisplayError DisplayBase::Prepare(LayerStack *layer_stack) {
// Clean hw layers for reuse. // Clean hw layers for reuse.
hw_layers_.info = HWLayersInfo(); hw_layers_.info = HWLayersInfo();
hw_layers_.info.stack = layer_stack; hw_layers_.info.stack = layer_stack;
hw_layers_.output_compression = 1.0f;
comp_manager_->PrePrepare(display_comp_ctx_, &hw_layers_); comp_manager_->PrePrepare(display_comp_ctx_, &hw_layers_);
while (true) { while (true) {
@@ -143,14 +143,14 @@ DisplayError DisplayBase::Prepare(LayerStack *layer_stack) {
} }
if (IsRotationRequired(&hw_layers_)) { if (IsRotationRequired(&hw_layers_)) {
if (!rotator_ctrl_) { if (!rotator_intf_) {
continue; continue;
} }
error = rotator_ctrl_->Prepare(display_rotator_ctx_, &hw_layers_); error = rotator_intf_->Prepare(display_rotator_ctx_, &hw_layers_);
} else { } else {
// Release all the previous rotator sessions. // Release all the previous rotator sessions.
if (rotator_ctrl_) { if (rotator_intf_) {
error = rotator_ctrl_->Purge(display_rotator_ctx_, &hw_layers_); error = rotator_intf_->Purge(display_rotator_ctx_, &hw_layers_);
} }
} }
@@ -189,8 +189,8 @@ DisplayError DisplayBase::Commit(LayerStack *layer_stack) {
pending_commit_ = false; pending_commit_ = false;
if (rotator_ctrl_ && IsRotationRequired(&hw_layers_)) { if (rotator_intf_ && IsRotationRequired(&hw_layers_)) {
error = rotator_ctrl_->Commit(display_rotator_ctx_, &hw_layers_); error = rotator_intf_->Commit(display_rotator_ctx_, &hw_layers_);
if (error != kErrorNone) { if (error != kErrorNone) {
return error; return error;
} }
@@ -201,8 +201,8 @@ DisplayError DisplayBase::Commit(LayerStack *layer_stack) {
return error; return error;
} }
if (rotator_ctrl_ && IsRotationRequired(&hw_layers_)) { if (rotator_intf_ && IsRotationRequired(&hw_layers_)) {
error = rotator_ctrl_->PostCommit(display_rotator_ctx_, &hw_layers_); error = rotator_intf_->PostCommit(display_rotator_ctx_, &hw_layers_);
if (error != kErrorNone) { if (error != kErrorNone) {
return error; return error;
} }
@@ -561,4 +561,4 @@ const char * DisplayBase::GetName(const LayerBufferFormat &format) {
} }
} }
} // namespace sde } // namespace sdm

View File

@@ -27,13 +27,14 @@
#include <core/display_interface.h> #include <core/display_interface.h>
#include <private/strategy_interface.h> #include <private/strategy_interface.h>
#include <private/rotator_interface.h>
#include <utils/locker.h> #include <utils/locker.h>
#include "hw_interface.h" #include "hw_interface.h"
#include "comp_manager.h" #include "comp_manager.h"
namespace sde { namespace sdm {
class RotatorCtrl; class RotatorCtrl;
@@ -41,7 +42,7 @@ class DisplayBase : public DisplayInterface {
public: public:
DisplayBase(DisplayType display_type, DisplayEventHandler *event_handler, DisplayBase(DisplayType display_type, DisplayEventHandler *event_handler,
HWDeviceType hw_device_type, BufferSyncHandler *buffer_sync_handler, HWDeviceType hw_device_type, BufferSyncHandler *buffer_sync_handler,
CompManager *comp_manager, RotatorCtrl *rotator_ctrl); CompManager *comp_manager, RotatorInterface *rotator_intf);
virtual ~DisplayBase() { } virtual ~DisplayBase() { }
virtual DisplayError Init(); virtual DisplayError Init();
virtual DisplayError Deinit(); virtual DisplayError Deinit();
@@ -77,7 +78,7 @@ class DisplayBase : public DisplayInterface {
HWPanelInfo hw_panel_info_; HWPanelInfo hw_panel_info_;
BufferSyncHandler *buffer_sync_handler_; BufferSyncHandler *buffer_sync_handler_;
CompManager *comp_manager_; CompManager *comp_manager_;
RotatorCtrl *rotator_ctrl_; RotatorInterface *rotator_intf_;
DisplayState state_; DisplayState state_;
Handle hw_device_; Handle hw_device_;
Handle display_comp_ctx_; Handle display_comp_ctx_;
@@ -91,7 +92,7 @@ class DisplayBase : public DisplayInterface {
bool underscan_supported_; bool underscan_supported_;
}; };
} // namespace sde } // namespace sdm
#endif // __DISPLAY_BASE_H__ #endif // __DISPLAY_BASE_H__

View File

@@ -31,13 +31,13 @@
#define __CLASS__ "DisplayHDMI" #define __CLASS__ "DisplayHDMI"
namespace sde { namespace sdm {
DisplayHDMI::DisplayHDMI(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf, DisplayHDMI::DisplayHDMI(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager, BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager,
RotatorCtrl *rotator_ctrl) RotatorInterface *rotator_intf)
: DisplayBase(kHDMI, event_handler, kDeviceHDMI, buffer_sync_handler, comp_manager, : 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() { DisplayError DisplayHDMI::Init() {
@@ -247,5 +247,5 @@ void DisplayHDMI::AppendDump(char *buffer, uint32_t length) {
DisplayBase::AppendDump(buffer, length); DisplayBase::AppendDump(buffer, length);
} }
} // namespace sde } // namespace sdm

View File

@@ -28,7 +28,7 @@
#include "display_base.h" #include "display_base.h"
#include "dump_impl.h" #include "dump_impl.h"
namespace sde { namespace sdm {
class HWHDMIInterface; class HWHDMIInterface;
class HWInfoInterface; class HWInfoInterface;
@@ -37,7 +37,7 @@ class DisplayHDMI : public DisplayBase, DumpImpl {
public: public:
DisplayHDMI(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf, DisplayHDMI(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager, BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager,
RotatorCtrl *rotator_ctrl); RotatorInterface *rotator_intf);
virtual DisplayError Init(); virtual DisplayError Init();
virtual DisplayError Deinit(); virtual DisplayError Deinit();
virtual DisplayError Prepare(LayerStack *layer_stack); virtual DisplayError Prepare(LayerStack *layer_stack);
@@ -71,7 +71,7 @@ class DisplayHDMI : public DisplayBase, DumpImpl {
HWScanSupport scan_support_; HWScanSupport scan_support_;
}; };
} // namespace sde } // namespace sdm
#endif // __DISPLAY_HDMI_H__ #endif // __DISPLAY_HDMI_H__

View File

@@ -31,13 +31,13 @@
#define __CLASS__ "DisplayPrimary" #define __CLASS__ "DisplayPrimary"
namespace sde { namespace sdm {
DisplayPrimary::DisplayPrimary(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf, DisplayPrimary::DisplayPrimary(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager, BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager,
RotatorCtrl *rotator_ctrl) RotatorInterface *rotator_intf)
: DisplayBase(kPrimary, event_handler, kDevicePrimary, buffer_sync_handler, comp_manager, : 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() { DisplayError DisplayPrimary::Init() {
@@ -288,5 +288,5 @@ void DisplayPrimary::ThermalEvent(int64_t thermal_level) {
comp_manager_->ProcessThermalEvent(display_comp_ctx_, thermal_level); comp_manager_->ProcessThermalEvent(display_comp_ctx_, thermal_level);
} }
} // namespace sde } // namespace sdm

View File

@@ -28,7 +28,7 @@
#include "display_base.h" #include "display_base.h"
#include "dump_impl.h" #include "dump_impl.h"
namespace sde { namespace sdm {
class HWPrimaryInterface; class HWPrimaryInterface;
class HWInfoInterface; class HWInfoInterface;
@@ -37,7 +37,7 @@ class DisplayPrimary : public DisplayBase, DumpImpl, HWEventHandler {
public: public:
DisplayPrimary(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf, DisplayPrimary(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager, BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager,
RotatorCtrl *rotator_ctrl); RotatorInterface *rotator_intf);
virtual DisplayError Init(); virtual DisplayError Init();
virtual DisplayError Deinit(); virtual DisplayError Deinit();
virtual DisplayError Prepare(LayerStack *layer_stack); virtual DisplayError Prepare(LayerStack *layer_stack);
@@ -73,7 +73,7 @@ class DisplayPrimary : public DisplayBase, DumpImpl, HWEventHandler {
HWInfoInterface *hw_info_intf_; HWInfoInterface *hw_info_intf_;
}; };
} // namespace sde } // namespace sdm
#endif // __DISPLAY_PRIMARY_H__ #endif // __DISPLAY_PRIMARY_H__

View File

@@ -31,13 +31,13 @@
#define __CLASS__ "DisplayVirtual" #define __CLASS__ "DisplayVirtual"
namespace sde { namespace sdm {
DisplayVirtual::DisplayVirtual(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf, DisplayVirtual::DisplayVirtual(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager, BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager,
RotatorCtrl *rotator_ctrl) RotatorInterface *rotator_intf)
: DisplayBase(kVirtual, event_handler, kDeviceVirtual, buffer_sync_handler, comp_manager, : 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() { DisplayError DisplayVirtual::Init() {
@@ -199,5 +199,5 @@ void DisplayVirtual::AppendDump(char *buffer, uint32_t length) {
DisplayBase::AppendDump(buffer, length); DisplayBase::AppendDump(buffer, length);
} }
} // namespace sde } // namespace sdm

View File

@@ -28,7 +28,7 @@
#include "display_base.h" #include "display_base.h"
#include "dump_impl.h" #include "dump_impl.h"
namespace sde { namespace sdm {
class HWVirtualInterface; class HWVirtualInterface;
class HWInfoInterface; class HWInfoInterface;
@@ -37,7 +37,7 @@ class DisplayVirtual : public DisplayBase, DumpImpl {
public: public:
DisplayVirtual(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf, DisplayVirtual(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager, BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager,
RotatorCtrl *rotator_ctrl); RotatorInterface *rotator_intf);
virtual DisplayError Init(); virtual DisplayError Init();
virtual DisplayError Deinit(); virtual DisplayError Deinit();
virtual DisplayError Prepare(LayerStack *layer_stack); virtual DisplayError Prepare(LayerStack *layer_stack);
@@ -67,7 +67,7 @@ class DisplayVirtual : public DisplayBase, DumpImpl {
HWInfoInterface *hw_info_intf_; HWInfoInterface *hw_info_intf_;
}; };
} // namespace sde } // namespace sdm
#endif // __DISPLAY_VIRTUAL_H__ #endif // __DISPLAY_VIRTUAL_H__

View File

@@ -29,7 +29,7 @@
#include "dump_impl.h" #include "dump_impl.h"
namespace sde { namespace sdm {
DumpImpl* DumpImpl::dump_list_[] = { 0 }; DumpImpl* DumpImpl::dump_list_[] = { 0 };
uint32_t DumpImpl::dump_count_ = 0; uint32_t DumpImpl::dump_count_ = 0;
@@ -40,7 +40,7 @@ DisplayError DumpInterface::GetDump(char *buffer, uint32_t length) {
} }
buffer[0] = '\0'; 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++) { for (uint32_t i = 0; i < DumpImpl::dump_count_; i++) {
DumpImpl::dump_list_[i]->AppendDump(buffer, length); DumpImpl::dump_list_[i]->AppendDump(buffer, length);
} }
@@ -89,5 +89,5 @@ void DumpImpl::Unregister(DumpImpl *dump_impl) {
} }
} }
} // namespace sde } // namespace sdm

View File

@@ -27,7 +27,7 @@
#include <core/dump_interface.h> #include <core/dump_interface.h>
namespace sde { namespace sdm {
class DumpImpl { class DumpImpl {
public: public:
@@ -52,7 +52,7 @@ class DumpImpl {
friend DumpInterface; friend DumpInterface;
}; };
} // namespace sde } // namespace sdm
#endif // __DUMP_IMPL_H__ #endif // __DUMP_IMPL_H__

View File

@@ -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 FILE* virtual_fopen(const char *fname, const char *mode);
extern int virtual_fclose(FILE* fileptr); extern int virtual_fclose(FILE* fileptr);
extern ssize_t virtual_getline(char **lineptr, size_t *linelen, FILE *stream); extern ssize_t virtual_getline(char **lineptr, size_t *linelen, FILE *stream);
#endif #endif
namespace sde { namespace sdm {
HWDevice::HWDevice(BufferSyncHandler *buffer_sync_handler) HWDevice::HWDevice(BufferSyncHandler *buffer_sync_handler)
: fb_node_index_(-1), fb_path_("/sys/devices/virtual/graphics/fb"), hotplug_enabled_(false), : 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; mdp_layer_commit_v1 &mdp_commit = mdp_disp_commit_.commit_v1;
uint32_t &mdp_layer_count = mdp_commit.input_layer_cnt; 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, DLOGI_IF(kTagDriverConfig, "left_roi: x = %d, y = %d, w = %d, h = %d", mdp_commit.left_roi.x,
mdp_commit.left_roi.w, mdp_commit.left_roi.h); 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, 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.y, mdp_commit.right_roi.w, mdp_commit.right_roi.h);
mdp_commit.right_roi.h);
for (uint32_t i = 0; i < hw_layer_info.count; i++) { for (uint32_t i = 0; i < hw_layer_info.count; i++) {
uint32_t layer_index = hw_layer_info.index[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.width = input_buffer->width;
mdp_buffer.height = input_buffer->height; 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); error = SetFormat(input_buffer->format, &mdp_buffer.format);
if (error != kErrorNone) { if (error != kErrorNone) {
@@ -301,6 +301,8 @@ DisplayError HWDevice::Validate(HWLayers *hw_layers) {
mdp_out_layer_.writeback_ndx = 2; mdp_out_layer_.writeback_ndx = 2;
mdp_out_layer_.buffer.width = output_buffer->width; mdp_out_layer_.buffer.width = output_buffer->width;
mdp_out_layer_.buffer.height = output_buffer->height; 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); SetFormat(output_buffer->format, &mdp_out_layer_.buffer.format);
DLOGI_IF(kTagDriverConfig, "********************* Output buffer Info ************************"); DLOGI_IF(kTagDriverConfig, "********************* Output buffer Info ************************");
@@ -940,5 +942,5 @@ void HWDevice::SetHWScaleData(const ScaleData &scale, uint32_t index) {
} }
} }
} // namespace sde } // namespace sdm

View File

@@ -39,7 +39,7 @@
#define IOCTL_LOGE(ioctl, type) DLOGE("ioctl %s, device = %d errno = %d, desc = %s", #ioctl, \ #define IOCTL_LOGE(ioctl, type) DLOGE("ioctl %s, device = %d errno = %d, desc = %s", #ioctl, \
type, errno, strerror(errno)) type, errno, strerror(errno))
namespace sde { namespace sdm {
class HWDevice { class HWDevice {
protected: protected:
@@ -125,7 +125,7 @@ class HWDevice {
bool synchronous_commit_; bool synchronous_commit_;
}; };
} // namespace sde } // namespace sdm
#endif // __HW_DEVICE_H__ #endif // __HW_DEVICE_H__

View File

@@ -35,7 +35,7 @@
#define __CLASS__ "HWHDMI" #define __CLASS__ "HWHDMI"
namespace sde { namespace sdm {
static int ParseLine(char *input, char *tokens[], const uint32_t max_token, uint32_t *count) { static int ParseLine(char *input, char *tokens[], const uint32_t max_token, uint32_t *count) {
char *tmp_token = NULL; char *tmp_token = NULL;
@@ -417,5 +417,5 @@ void HWHDMI::ReadScanInfo() {
hw_scan_info_.cea_scan_support); hw_scan_info_.cea_scan_support);
} }
} // namespace sde } // namespace sdm

View File

@@ -29,7 +29,7 @@
#include "hw_device.h" #include "hw_device.h"
#include "hw_hdmi_interface.h" #include "hw_hdmi_interface.h"
namespace sde { namespace sdm {
class HWHDMI : public HWDevice, public HWHDMIInterface { class HWHDMI : public HWDevice, public HWHDMIInterface {
public: public:
@@ -68,7 +68,7 @@ class HWHDMI : public HWDevice, public HWHDMIInterface {
HWScanInfo hw_scan_info_; HWScanInfo hw_scan_info_;
}; };
} // namespace sde } // namespace sdm
#endif // __HW_HDMI_H__ #endif // __HW_HDMI_H__

View File

@@ -33,7 +33,7 @@
#define __CLASS__ "HWInfo" #define __CLASS__ "HWInfo"
namespace sde { namespace sdm {
int HWInfo::ParseLine(char *input, char *tokens[], const uint32_t max_token, uint32_t *count) { int HWInfo::ParseLine(char *input, char *tokens[], const uint32_t max_token, uint32_t *count) {
char *tmp_token = NULL; char *tmp_token = NULL;
@@ -169,5 +169,5 @@ DisplayError HWInfo::GetHWResourceInfo(HWResourceInfo *hw_resource) {
return kErrorNone; return kErrorNone;
} }
} // namespace sde } // namespace sdm

View File

@@ -26,11 +26,11 @@
#define __HW_INFO_H__ #define __HW_INFO_H__
#include <inttypes.h> #include <inttypes.h>
#include <core/sde_types.h> #include <core/sdm_types.h>
#include <private/hw_info_types.h> #include <private/hw_info_types.h>
#include "hw_info_interface.h" #include "hw_info_interface.h"
namespace sde { namespace sdm {
class HWInfo: public HWInfoInterface { class HWInfo: public HWInfoInterface {
public: public:
@@ -48,7 +48,7 @@ class HWInfo: public HWInfoInterface {
static int ParseLine(char *input, char *tokens[], const uint32_t max_token, uint32_t *count); static int ParseLine(char *input, char *tokens[], const uint32_t max_token, uint32_t *count);
}; };
} // namespace sde } // namespace sdm
#endif // __HW_INFO_H__ #endif // __HW_INFO_H__

View File

@@ -37,7 +37,7 @@
#define __CLASS__ "HWPrimary" #define __CLASS__ "HWPrimary"
namespace sde { namespace sdm {
DisplayError HWPrimaryInterface::Create(HWPrimaryInterface **intf, HWInfoInterface *hw_info_intf, DisplayError HWPrimaryInterface::Create(HWPrimaryInterface **intf, HWInfoInterface *hw_info_intf,
BufferSyncHandler *buffer_sync_handler) { BufferSyncHandler *buffer_sync_handler) {
@@ -64,7 +64,7 @@ DisplayError HWPrimaryInterface::Destroy(HWPrimaryInterface *intf) {
} }
HWPrimary::HWPrimary(BufferSyncHandler *buffer_sync_handler, HWInfoInterface *hw_info_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) { exit_threads_(false), config_changed_(true) {
HWDevice::device_type_ = kDevicePrimary; HWDevice::device_type_ = kDevicePrimary;
HWDevice::device_name_ = "Primary Display Device"; 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.w = INT(left_roi.right - left_roi.left);
mdp_commit.left_roi.h = INT(left_roi.bottom - left_roi.top); 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 // In case source split is disabled, However, Driver assumes Mixer to operate in
// different co-ordinate system. // different co-ordinate system.
if (!hw_resource_.is_src_split) { if (!hw_resource_.is_src_split) {
@@ -494,5 +494,5 @@ DisplayError HWPrimary::SetDisplayMode(const HWDisplayMode hw_display_mode) {
return kErrorNone; return kErrorNone;
} }
} // namespace sde } // namespace sdm

View File

@@ -28,7 +28,7 @@
#include "hw_device.h" #include "hw_device.h"
#include "hw_primary_interface.h" #include "hw_primary_interface.h"
namespace sde { namespace sdm {
class HWPrimary : public HWDevice, public HWPrimaryInterface { class HWPrimary : public HWDevice, public HWPrimaryInterface {
public: public:
@@ -82,7 +82,7 @@ class HWPrimary : public HWDevice, public HWPrimaryInterface {
bool config_changed_; bool config_changed_;
}; };
} // namespace sde } // namespace sdm
#endif // __HW_PRIMARY_H__ #endif // __HW_PRIMARY_H__

View File

@@ -32,7 +32,7 @@
#define __CLASS__ "HWVirtual" #define __CLASS__ "HWVirtual"
namespace sde { namespace sdm {
DisplayError HWVirtualInterface::Create(HWVirtualInterface **intf, HWInfoInterface *hw_info_intf, DisplayError HWVirtualInterface::Create(HWVirtualInterface **intf, HWInfoInterface *hw_info_intf,
BufferSyncHandler *buffer_sync_handler) { BufferSyncHandler *buffer_sync_handler) {
@@ -135,5 +135,5 @@ DisplayError HWVirtual::GetHWPanelInfo(HWPanelInfo *panel_info) {
return HWDevice::GetHWPanelInfo(panel_info); return HWDevice::GetHWPanelInfo(panel_info);
} }
} // namespace sde } // namespace sdm

View File

@@ -28,7 +28,7 @@
#include "hw_device.h" #include "hw_device.h"
#include "hw_virtual_interface.h" #include "hw_virtual_interface.h"
namespace sde { namespace sdm {
class HWVirtual : public HWDevice, public HWVirtualInterface { class HWVirtual : public HWDevice, public HWVirtualInterface {
public: public:
@@ -53,7 +53,7 @@ class HWVirtual : public HWDevice, public HWVirtualInterface {
virtual DisplayError Flush(); virtual DisplayError Flush();
}; };
} // namespace sde } // namespace sdm
#endif // __HW_VIRTUAL_H__ #endif // __HW_VIRTUAL_H__

View File

@@ -27,7 +27,7 @@
#include "hw_interface.h" #include "hw_interface.h"
namespace sde { namespace sdm {
class HWInfoInterface; class HWInfoInterface;
@@ -44,7 +44,7 @@ class HWHDMIInterface: virtual public HWInterface {
virtual ~HWHDMIInterface() { } virtual ~HWHDMIInterface() { }
}; };
} // namespace sde } // namespace sdm
#endif // __HW_HDMI_INTERFACE_H__ #endif // __HW_HDMI_INTERFACE_H__

View File

@@ -28,7 +28,7 @@
#include <inttypes.h> #include <inttypes.h>
#include <private/hw_info_types.h> #include <private/hw_info_types.h>
namespace sde { namespace sdm {
class HWInfoInterface { class HWInfoInterface {
public: public:
@@ -40,7 +40,7 @@ class HWInfoInterface {
virtual ~HWInfoInterface() { } virtual ~HWInfoInterface() { }
}; };
} // namespace sde } // namespace sdm
#endif // __HW_INFO_INTERFACE_H__ #endif // __HW_INFO_INTERFACE_H__

View 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__

View File

@@ -25,7 +25,7 @@
#ifndef __HW_PRIMARY_INTERFACE_H__ #ifndef __HW_PRIMARY_INTERFACE_H__
#define __HW_PRIMARY_INTERFACE_H__ #define __HW_PRIMARY_INTERFACE_H__
namespace sde { namespace sdm {
class BufferSyncHandler; class BufferSyncHandler;
class HWInfoInterface; class HWInfoInterface;
@@ -44,7 +44,7 @@ class HWPrimaryInterface: virtual public HWInterface {
virtual ~HWPrimaryInterface() { } virtual ~HWPrimaryInterface() { }
}; };
} // namespace sde } // namespace sdm
#endif // __HW_PRIMARY_INTERFACE_H__ #endif // __HW_PRIMARY_INTERFACE_H__

View File

@@ -27,7 +27,7 @@
#include "hw_interface.h" #include "hw_interface.h"
namespace sde { namespace sdm {
class HWInfoInterface; class HWInfoInterface;
@@ -41,7 +41,7 @@ class HWVirtualInterface: virtual public HWInterface {
virtual ~HWVirtualInterface() { } virtual ~HWVirtualInterface() { }
}; };
} // namespace sde } // namespace sdm
#endif // __HW_VIRTUAL_INTERFACE_H__ #endif // __HW_VIRTUAL_INTERFACE_H__

View 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

View 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
View 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

View File

@@ -22,54 +22,42 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef __ROTATOR_CTRL_H__ #ifndef __STRATEGY_H__
#define __ROTATOR_CTRL_H__ #define __STRATEGY_H__
#include <utils/locker.h>
#include <utils/debug.h>
#include <core/display_interface.h> #include <core/display_interface.h>
#include <private/extension_interface.h>
namespace sde { namespace sdm {
class HWRotatorInterface; class Strategy {
class BufferAllocator;
class BufferSyncHandler;
struct HWLayers;
class SessionManager;
class RotatorCtrl {
public: public:
RotatorCtrl(); Strategy(ExtensionInterface *extension_intf, DisplayType type,
DisplayError Init(BufferAllocator *buffer_allocator, BufferSyncHandler *buffer_sync_handler); const HWResourceInfo &hw_resource_info, const HWPanelInfo &hw_panel_info);
DisplayError Init();
DisplayError Deinit(); DisplayError Deinit();
DisplayError RegisterDisplay(DisplayType type, Handle *display_ctx);
void UnregisterDisplay(Handle display_ctx); DisplayError Start(HWLayersInfo *hw_layers_info, uint32_t *max_attempts);
DisplayError Prepare(Handle display_ctx, HWLayers *hw_layers); DisplayError GetNextStrategy(StrategyConstraints *constraints);
DisplayError Commit(Handle display_ctx, HWLayers *hw_layers); DisplayError Stop();
DisplayError PostCommit(Handle display_ctx, HWLayers *hw_layers);
DisplayError Purge(Handle display_ctx, HWLayers *hw_layers);
private: private:
enum { void GenerateROI();
kSingleBuffering = 1,
kDoubleBuffering = 2, ExtensionInterface *extension_intf_;
kTripleBuffering = 3, 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 { } // namespace sdm
DisplayType display_type;
DisplayRotatorContext() : display_type(kPrimary) { } #endif // __STRATEGY_H__
};
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__

View File

@@ -4,20 +4,20 @@ include $(CLEAR_VARS)
LOCAL_MODULE := hwcomposer.$(TARGET_BOARD_PLATFORM) LOCAL_MODULE := hwcomposer.$(TARGET_BOARD_PLATFORM)
LOCAL_MODULE_RELATIVE_PATH := hw LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_MODULE_TAGS := optional 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/libgralloc/ \
hardware/qcom/display/libqservice/ \ hardware/qcom/display/libqservice/ \
hardware/qcom/display/libqdutils/ hardware/qcom/display/libqdutils/
LOCAL_CFLAGS := -Wno-missing-field-initializers -Wno-unused-parameter \ LOCAL_CFLAGS := -Wno-missing-field-initializers -Wno-unused-parameter \
-Wconversion -Wall -Werror \ -Wconversion -Wall -Werror \
-DLOG_TAG=\"SDE\" -DLOG_TAG=\"SDM\"
# TODO: Move this to the common makefile # TODO: Move this to the common makefile
ifeq ($(call is-board-platform-in-list, $(MASTER_SIDE_CP_TARGET_LIST)), true) ifeq ($(call is-board-platform-in-list, $(MASTER_SIDE_CP_TARGET_LIST)), true)
LOCAL_CFLAGS += -DMASTER_SIDE_CP LOCAL_CFLAGS += -DMASTER_SIDE_CP
endif endif
LOCAL_SHARED_LIBRARIES := libsde libqservice libbinder libhardware libhardware_legacy \ LOCAL_SHARED_LIBRARIES := libsdmcore libqservice libbinder libhardware libhardware_legacy \
libutils libcutils libsync libmemalloc libqdutils libutils libcutils libsync libmemalloc libqdutils
LOCAL_SRC_FILES := hwc_session.cpp \ LOCAL_SRC_FILES := hwc_session.cpp \
hwc_display.cpp \ hwc_display.cpp \

View File

@@ -39,7 +39,7 @@
#define __CLASS__ "HWCBufferAllocator" #define __CLASS__ "HWCBufferAllocator"
namespace sde { namespace sdm {
HWCBufferAllocator::HWCBufferAllocator() { HWCBufferAllocator::HWCBufferAllocator() {
alloc_controller_ = gralloc::IAllocController::getInstance(); alloc_controller_ = gralloc::IAllocController::getInstance();
@@ -184,4 +184,4 @@ int HWCBufferAllocator::SetBufferInfo(LayerBufferFormat format, int *target, int
return 0; return 0;
} }
} // namespace sde } // namespace sdm

View File

@@ -40,7 +40,7 @@ class IAllocController;
} // namespace gralloc } // namespace gralloc
namespace sde { namespace sdm {
class HWCBufferAllocator : public BufferAllocator { class HWCBufferAllocator : public BufferAllocator {
public: public:
@@ -60,6 +60,6 @@ class HWCBufferAllocator : public BufferAllocator {
gralloc::IAllocController *alloc_controller_; gralloc::IAllocController *alloc_controller_;
}; };
} // namespace sde } // namespace sdm
#endif // __HWC_BUFFER_ALLOCATOR_H__ #endif // __HWC_BUFFER_ALLOCATOR_H__

View File

@@ -35,7 +35,7 @@
#define __CLASS__ "HWCBufferSyncHandler" #define __CLASS__ "HWCBufferSyncHandler"
namespace sde { namespace sdm {
DisplayError HWCBufferSyncHandler::SyncWait(int fd) { DisplayError HWCBufferSyncHandler::SyncWait(int fd) {
int error = 0; int error = 0;
@@ -67,5 +67,5 @@ DisplayError HWCBufferSyncHandler::SyncMerge(int fd1, int fd2, int *merged_fd) {
return error; return error;
} }
} // namespace sde } // namespace sdm

View File

@@ -33,10 +33,10 @@
#include <sys/mman.h> #include <sys/mman.h>
#include <fcntl.h> #include <fcntl.h>
#include <core/sde_types.h> #include <core/sdm_types.h>
#include <core/buffer_sync_handler.h> #include <core/buffer_sync_handler.h>
namespace sde { namespace sdm {
class HWCBufferSyncHandler : public BufferSyncHandler { class HWCBufferSyncHandler : public BufferSyncHandler {
public: public:
@@ -46,7 +46,7 @@ class HWCBufferSyncHandler : public BufferSyncHandler {
virtual DisplayError SyncMerge(int fd1, int fd2, int *merged_fd); virtual DisplayError SyncMerge(int fd1, int fd2, int *merged_fd);
}; };
} // namespace sde } // namespace sdm
#endif // __HWC_BUFFER_SYNC_HANDLER_H__ #endif // __HWC_BUFFER_SYNC_HANDLER_H__

View File

@@ -31,7 +31,7 @@
#include "hwc_debugger.h" #include "hwc_debugger.h"
namespace sde { namespace sdm {
HWCDebugHandler HWCDebugHandler::debug_handler_; HWCDebugHandler HWCDebugHandler::debug_handler_;
uint32_t HWCDebugHandler::debug_flags_ = 0x1; uint32_t HWCDebugHandler::debug_flags_ = 0x1;
@@ -123,5 +123,5 @@ void HWCDebugHandler::EndTrace() {
atrace_end(ATRACE_TAG); atrace_end(ATRACE_TAG);
} }
} // namespace sde } // namespace sdm

View File

@@ -32,7 +32,7 @@
#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL) #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 <core/debug_interface.h>
#include <cutils/log.h> #include <cutils/log.h>
#include <utils/Trace.h> #include <utils/Trace.h>
@@ -49,7 +49,7 @@
#define DTRACE_END() HWCDebugHandler::Get()->EndTrace() #define DTRACE_END() HWCDebugHandler::Get()->EndTrace()
#define DTRACE_SCOPED() ScopeTracer<HWCDebugHandler> scope_tracer(__CLASS__, __FUNCTION__) #define DTRACE_SCOPED() ScopeTracer<HWCDebugHandler> scope_tracer(__CLASS__, __FUNCTION__)
namespace sde { namespace sdm {
class HWCDebugHandler : public DebugHandler { class HWCDebugHandler : public DebugHandler {
public: public:
@@ -74,7 +74,7 @@ class HWCDebugHandler : public DebugHandler {
static uint32_t debug_flags_; static uint32_t debug_flags_;
}; };
} // namespace sde } // namespace sdm
#endif // __HWC_DEBUGGER_H__ #endif // __HWC_DEBUGGER_H__

View File

@@ -40,7 +40,7 @@
#define __CLASS__ "HWCDisplay" #define __CLASS__ "HWCDisplay"
namespace sde { namespace sdm {
HWCDisplay::HWCDisplay(CoreInterface *core_intf, hwc_procs_t const **hwc_procs, DisplayType type, HWCDisplay::HWCDisplay(CoreInterface *core_intf, hwc_procs_t const **hwc_procs, DisplayType type,
int id) int id)
@@ -357,7 +357,7 @@ int HWCDisplay::PrepareLayerStack(hwc_display_contents_1_t *content_list) {
LayerBuffer *layer_buffer = layer.input_buffer; LayerBuffer *layer_buffer = layer.input_buffer;
if (pvt_handle) { 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) { if (layer_buffer->format == kFormatInvalid) {
return -EINVAL; return -EINVAL;
} }
@@ -540,7 +540,7 @@ int HWCDisplay::PostCommitLayerStack(hwc_display_contents_1_t *content_list) {
hwc_layer.releaseFenceFd = layer_buffer->release_fence_fd; 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 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, // framebuffer target. So graphics doesn't close the release fence fd of framebuffer target,
// Hence close the release fencefd of framebuffer target here. // Hence close the release fencefd of framebuffer target here.
@@ -684,7 +684,7 @@ DisplayError HWCDisplay::SetMaxMixerStages(uint32_t max_mixer_stages) {
return error; 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; LayerBufferFormat format = kFormatInvalid;
if (flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) { if (flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
switch (source) { switch (source) {
@@ -1004,5 +1004,5 @@ uint32_t HWCDisplay::RoundToStandardFPS(uint32_t fps) {
void HWCDisplay::ApplyScanAdjustment(hwc_rect_t *display_frame) { void HWCDisplay::ApplyScanAdjustment(hwc_rect_t *display_frame) {
} }
} // namespace sde } // namespace sdm

View File

@@ -28,7 +28,7 @@
#include <hardware/hwcomposer.h> #include <hardware/hwcomposer.h>
#include <core/core_interface.h> #include <core/core_interface.h>
namespace sde { namespace sdm {
class HWCDisplay : public DisplayEventHandler { class HWCDisplay : public DisplayEventHandler {
public: public:
@@ -60,7 +60,7 @@ class HWCDisplay : public DisplayEventHandler {
kDisplayStatusResume, kDisplayStatusResume,
}; };
// Maximum number of layers supported by display engine. // Maximum number of layers supported by display manager.
static const uint32_t kMaxLayerCount = 32; static const uint32_t kMaxLayerCount = 32;
// Structure to track memory allocation for layer stack (layers, rectangles) object. // 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 SetComposition(const int32_t &source, int32_t *target);
inline void SetBlending(const int32_t &source, LayerBlending *target); inline void SetBlending(const int32_t &source, LayerBlending *target);
int SetFormat(const int32_t &source, const int flags, LayerBufferFormat *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); void DumpInputBuffers(hwc_display_contents_1_t *content_list);
const char *GetHALPixelFormatString(int format); const char *GetHALPixelFormatString(int format);
const char *GetDisplayString(); const char *GetDisplayString();
@@ -143,7 +143,7 @@ class HWCDisplay : public DisplayEventHandler {
uint32_t metadata_refresh_rate_; uint32_t metadata_refresh_rate_;
}; };
} // namespace sde } // namespace sdm
#endif // __HWC_DISPLAY_H__ #endif // __HWC_DISPLAY_H__

View File

@@ -35,7 +35,7 @@
#define __CLASS__ "HWCDisplayExternal" #define __CLASS__ "HWCDisplayExternal"
namespace sde { namespace sdm {
HWCDisplayExternal::HWCDisplayExternal(CoreInterface *core_intf, hwc_procs_t const **hwc_procs) HWCDisplayExternal::HWCDisplayExternal(CoreInterface *core_intf, hwc_procs_t const **hwc_procs)
: HWCDisplay(core_intf, hwc_procs, kHDMI, HWC_DISPLAY_EXTERNAL) { : 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; display_frame->bottom = display_frame->bottom - y_offset;
} }
} // namespace sde } // namespace sdm

View File

@@ -27,7 +27,7 @@
#include "hwc_display.h" #include "hwc_display.h"
namespace sde { namespace sdm {
class HWCDisplayExternal : public HWCDisplay { class HWCDisplayExternal : public HWCDisplay {
public: public:
@@ -40,7 +40,7 @@ class HWCDisplayExternal : public HWCDisplay {
virtual void ApplyScanAdjustment(hwc_rect_t *display_frame); virtual void ApplyScanAdjustment(hwc_rect_t *display_frame);
}; };
} // namespace sde } // namespace sdm
#endif // __HWC_DISPLAY_EXTERNAL_H__ #endif // __HWC_DISPLAY_EXTERNAL_H__

View File

@@ -34,7 +34,7 @@
#define __CLASS__ "HWCDisplayPrimary" #define __CLASS__ "HWCDisplayPrimary"
namespace sde { namespace sdm {
HWCDisplayPrimary::HWCDisplayPrimary(CoreInterface *core_intf, hwc_procs_t const **hwc_procs) HWCDisplayPrimary::HWCDisplayPrimary(CoreInterface *core_intf, hwc_procs_t const **hwc_procs)
: HWCDisplay(core_intf, hwc_procs, kPrimary, HWC_DISPLAY_PRIMARY) { : HWCDisplay(core_intf, hwc_procs, kPrimary, HWC_DISPLAY_PRIMARY) {
@@ -110,5 +110,5 @@ void HWCDisplayPrimary::SetMetaDataRefreshRateFlag(bool enable) {
use_metadata_refresh_rate_ = enable; use_metadata_refresh_rate_ = enable;
} }
} // namespace sde } // namespace sdm

View File

@@ -27,7 +27,7 @@
#include "hwc_display.h" #include "hwc_display.h"
namespace sde { namespace sdm {
class HWCDisplayPrimary : public HWCDisplay { class HWCDisplayPrimary : public HWCDisplay {
public: public:
@@ -40,7 +40,7 @@ class HWCDisplayPrimary : public HWCDisplay {
virtual void SetMetaDataRefreshRateFlag(bool enable); virtual void SetMetaDataRefreshRateFlag(bool enable);
}; };
} // namespace sde } // namespace sdm
#endif // __HWC_DISPLAY_PRIMARY_H__ #endif // __HWC_DISPLAY_PRIMARY_H__

View File

@@ -35,7 +35,7 @@
#define __CLASS__ "HWCDisplayVirtual" #define __CLASS__ "HWCDisplayVirtual"
namespace sde { namespace sdm {
HWCDisplayVirtual::HWCDisplayVirtual(CoreInterface *core_intf, hwc_procs_t const **hwc_procs) HWCDisplayVirtual::HWCDisplayVirtual(CoreInterface *core_intf, hwc_procs_t const **hwc_procs)
: HWCDisplay(core_intf, hwc_procs, kVirtual, HWC_DISPLAY_VIRTUAL), : 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; int status = 0;
if (output_handle) { if (output_handle) {
LayerBufferFormat format = GetSDEFormat(output_handle->format, output_handle->flags); LayerBufferFormat format = GetSDMFormat(output_handle->format, output_handle->flags);
if (format == kFormatInvalid) { if (format == kFormatInvalid) {
return -EINVAL; return -EINVAL;
} }
@@ -181,7 +181,7 @@ int HWCDisplayVirtual::SetOutputBuffer(hwc_display_contents_1_t *content_list) {
output_buffer_->acquire_fence_fd = content_list->outbufAcquireFenceFd; output_buffer_->acquire_fence_fd = content_list->outbufAcquireFenceFd;
if (output_handle) { 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) { if (output_buffer_->format == kFormatInvalid) {
return -EINVAL; return -EINVAL;
} }
@@ -274,5 +274,5 @@ int HWCDisplayVirtual::GetHeight(const private_handle_t* handle) {
return handle->height; return handle->height;
} }
} // namespace sde } // namespace sdm

View File

@@ -29,7 +29,7 @@
#include <gralloc_priv.h> #include <gralloc_priv.h>
#include "hwc_display.h" #include "hwc_display.h"
namespace sde { namespace sdm {
class HWCDisplayVirtual : public HWCDisplay { class HWCDisplayVirtual : public HWCDisplay {
public: public:
@@ -50,7 +50,7 @@ class HWCDisplayVirtual : public HWCDisplay {
bool dump_output_layer_; bool dump_output_layer_;
}; };
} // namespace sde } // namespace sdm
#endif // __HWC_DISPLAY_VIRTUAL_H__ #endif // __HWC_DISPLAY_VIRTUAL_H__

View File

@@ -39,7 +39,6 @@
#include <QService.h> #include <QService.h>
#include <gr.h> #include <gr.h>
#include <gralloc_priv.h> #include <gralloc_priv.h>
#include <core/buffer_allocator.h>
#include <display_config.h> #include <display_config.h>
#include "hwc_buffer_allocator.h" #include "hwc_buffer_allocator.h"
@@ -52,7 +51,7 @@
#define HWC_UEVENT_SWITCH_HDMI "change@/devices/virtual/switch/hdmi" #define HWC_UEVENT_SWITCH_HDMI "change@/devices/virtual/switch/hdmi"
#define HWC_UEVENT_GRAPHICS_FB0 "change@/devices/virtual/graphics/fb0" #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 = { hwc_module_t HAL_MODULE_INFO_SYM = {
common: { common: {
@@ -68,7 +67,7 @@ hwc_module_t HAL_MODULE_INFO_SYM = {
} }
}; };
namespace sde { namespace sdm {
Locker HWCSession::locker_; Locker HWCSession::locker_;
bool HWCSession::reset_panel_ = false; bool HWCSession::reset_panel_ = false;
@@ -1001,5 +1000,5 @@ void HWCSession::AdjustSourceResolution(uint32_t dst_width, uint32_t dst_height,
*src_width = dst_width; *src_width = dst_width;
} }
} // namespace sde } // namespace sdm

View File

@@ -34,7 +34,7 @@
#include "hwc_display_external.h" #include "hwc_display_external.h"
#include "hwc_display_virtual.h" #include "hwc_display_virtual.h"
namespace sde { namespace sdm {
class HWCSession : hwc_composer_device_1_t, CoreEventHandler, public qClient::BnQClient { class HWCSession : hwc_composer_device_1_t, CoreEventHandler, public qClient::BnQClient {
public: public:
@@ -110,7 +110,7 @@ class HWCSession : hwc_composer_device_1_t, CoreEventHandler, public qClient::Bn
HWCBufferSyncHandler *buffer_sync_handler_; HWCBufferSyncHandler *buffer_sync_handler_;
}; };
} // namespace sde } // namespace sdm
#endif // __HWC_SESSION_H__ #endif // __HWC_SESSION_H__

View File

@@ -1,12 +1,12 @@
LOCAL_PATH := $(call my-dir) LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS) include $(CLEAR_VARS)
LOCAL_MODULE := libsdeutils LOCAL_MODULE := libsdmutils
LOCAL_MODULE_TAGS := optional 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 \ LOCAL_CFLAGS := -Wno-missing-field-initializers -Wno-unused-parameter \
-Wconversion -Wall -Werror \ -Wconversion -Wall -Werror \
-DLOG_TAG=\"SDE\" -DLOG_TAG=\"SDM\"
LOCAL_SHARED_LIBRARIES := libcutils LOCAL_SHARED_LIBRARIES := libcutils
LOCAL_SRC_FILES := debug_android.cpp rect.cpp LOCAL_SRC_FILES := debug_android.cpp rect.cpp

View File

@@ -33,7 +33,7 @@
#include <cutils/log.h> #include <cutils/log.h>
#include <cutils/properties.h> #include <cutils/properties.h>
namespace sde { namespace sdm {
Debug Debug::debug_; Debug Debug::debug_;
@@ -73,7 +73,7 @@ uint32_t Debug::GetIdleTimeoutMs() {
bool Debug::IsRotatorDownScaleDisabled() { bool Debug::IsRotatorDownScaleDisabled() {
char property[PROPERTY_VALUE_MAX]; 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); return (atoi(property) ? 0 : false, true);
} }
@@ -82,7 +82,7 @@ bool Debug::IsRotatorDownScaleDisabled() {
bool Debug::IsDecimationDisabled() { bool Debug::IsDecimationDisabled() {
char property[PROPERTY_VALUE_MAX]; 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); return (atoi(property) ? 0 : false, true);
} }
@@ -92,12 +92,12 @@ bool Debug::IsDecimationDisabled() {
// This property serves to disable/enable partial update // This property serves to disable/enable partial update
bool Debug::IsPartialUpdateEnabled() { bool Debug::IsPartialUpdateEnabled() {
char property[PROPERTY_VALUE_MAX]; 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 (atoi(property) ? 1 : true, false);
} }
return false; return false;
} }
} // namespace sde } // namespace sdm

View File

@@ -33,7 +33,7 @@
#define __CLASS__ "RectUtils" #define __CLASS__ "RectUtils"
namespace sde { namespace sdm {
bool IsValid(const LayerRect &rect) { bool IsValid(const LayerRect &rect) {
return ((rect.bottom > rect.top) && (rect.right > rect.left)); return ((rect.bottom > rect.top) && (rect.right > rect.left));
@@ -138,5 +138,5 @@ LayerRect Union(const LayerRect &rect1, const LayerRect &rect2) {
return res; return res;
} }
} // namespace sde } // namespace sdm