sdm: Align to new SDM design.
- Align code base to new SDM design. Change-Id: I38d7d138ae704cf036e2b96c16453aea63bc333f
This commit is contained in:
10
Android.mk
10
Android.mk
@@ -1,15 +1,15 @@
|
|||||||
ifeq ($(call is-board-platform-in-list, msm8996),true)
|
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
|
||||||
|
|||||||
@@ -1,188 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
|
||||||
* provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
|
||||||
* conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright notice, this list of
|
|
||||||
* conditions and the following disclaimer in the documentation and/or other materials provided
|
|
||||||
* with the distribution.
|
|
||||||
* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
|
|
||||||
* endorse or promote products derived from this software without specific prior written
|
|
||||||
* permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
||||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|
||||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*! @file hw_info_types.h
|
|
||||||
@brief Definitions for types that contain information pertaining to hardware devices.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __HW_INFO_TYPES_H__
|
|
||||||
#define __HW_INFO_TYPES_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <core/sde_types.h>
|
|
||||||
|
|
||||||
namespace sde {
|
|
||||||
|
|
||||||
/*! @brief This enumeration holds the possible hardware device types. */
|
|
||||||
enum HWDeviceType {
|
|
||||||
kDevicePrimary,
|
|
||||||
kDeviceHDMI,
|
|
||||||
kDeviceVirtual,
|
|
||||||
kDeviceRotator,
|
|
||||||
kDeviceMax,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*! @brief This structure is a representation of hardware capabilities of the target device display
|
|
||||||
driver.
|
|
||||||
*/
|
|
||||||
struct HWResourceInfo {
|
|
||||||
uint32_t hw_version;
|
|
||||||
uint32_t hw_revision;
|
|
||||||
uint32_t num_dma_pipe;
|
|
||||||
uint32_t num_vig_pipe;
|
|
||||||
uint32_t num_rgb_pipe;
|
|
||||||
uint32_t num_cursor_pipe;
|
|
||||||
uint32_t num_blending_stages;
|
|
||||||
uint32_t num_rotator;
|
|
||||||
uint32_t num_control;
|
|
||||||
uint32_t num_mixer_to_disp;
|
|
||||||
uint32_t smp_total;
|
|
||||||
uint32_t smp_size;
|
|
||||||
uint32_t num_smp_per_pipe;
|
|
||||||
uint32_t max_scale_up;
|
|
||||||
uint32_t max_scale_down;
|
|
||||||
uint64_t max_bandwidth_low;
|
|
||||||
uint64_t max_bandwidth_high;
|
|
||||||
uint32_t max_mixer_width;
|
|
||||||
uint32_t max_pipe_width;
|
|
||||||
uint32_t max_pipe_bw;
|
|
||||||
uint32_t max_sde_clk;
|
|
||||||
float clk_fudge_factor;
|
|
||||||
bool has_bwc;
|
|
||||||
bool has_ubwc;
|
|
||||||
bool has_decimation;
|
|
||||||
bool has_macrotile;
|
|
||||||
bool has_rotator_downscale;
|
|
||||||
bool has_non_scalar_rgb;
|
|
||||||
bool is_src_split;
|
|
||||||
|
|
||||||
HWResourceInfo()
|
|
||||||
: hw_version(0), hw_revision(0), num_dma_pipe(0), num_vig_pipe(0), num_rgb_pipe(0),
|
|
||||||
num_cursor_pipe(0), num_blending_stages(0), num_rotator(0), num_control(0),
|
|
||||||
num_mixer_to_disp(0), smp_total(0), smp_size(0), num_smp_per_pipe(0), max_scale_up(1),
|
|
||||||
max_scale_down(1), max_bandwidth_low(0), max_bandwidth_high(0), max_mixer_width(2048),
|
|
||||||
max_pipe_width(2048), max_pipe_bw(0), max_sde_clk(0), clk_fudge_factor(1.0f), has_bwc(false),
|
|
||||||
has_ubwc(false), has_decimation(false), has_macrotile(false), has_rotator_downscale(false),
|
|
||||||
has_non_scalar_rgb(false), is_src_split(false) { }
|
|
||||||
|
|
||||||
void Reset() { *this = HWResourceInfo(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
/*! @brief This enumeration holds the possible display modes. */
|
|
||||||
enum HWDisplayMode {
|
|
||||||
kModeDefault,
|
|
||||||
kModeVideo,
|
|
||||||
kModeCommand,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*! @brief This enumeration holds the all possible display port types. */
|
|
||||||
enum HWDisplayPort {
|
|
||||||
kPortDefault,
|
|
||||||
kPortDSI,
|
|
||||||
kPortDTv,
|
|
||||||
kPortWriteBack,
|
|
||||||
kPortLVDS,
|
|
||||||
kPortEDP,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*! @brief This enumeration holds the all possible scan types. */
|
|
||||||
enum HWScanSupport {
|
|
||||||
kScanNotSupported,
|
|
||||||
kScanAlwaysOverscanned,
|
|
||||||
kScanAlwaysUnderscanned,
|
|
||||||
kScanBoth,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*! @brief This structure holds the scan support for different timing modes. */
|
|
||||||
struct HWScanInfo {
|
|
||||||
HWScanSupport pt_scan_support; //!< Scan support for preferred timing
|
|
||||||
HWScanSupport it_scan_support; //!< Scan support for digital monitor or industry timings
|
|
||||||
HWScanSupport cea_scan_support; //!< Scan support for CEA resolution timings
|
|
||||||
|
|
||||||
HWScanInfo() : pt_scan_support(kScanNotSupported), it_scan_support(kScanNotSupported),
|
|
||||||
cea_scan_support(kScanNotSupported) { }
|
|
||||||
};
|
|
||||||
|
|
||||||
/*! @brief This structure describes the split configuration of a display panel. */
|
|
||||||
struct HWSplitInfo {
|
|
||||||
uint32_t left_split;
|
|
||||||
uint32_t right_split;
|
|
||||||
bool always_src_split;
|
|
||||||
|
|
||||||
HWSplitInfo() : left_split(0), right_split(0), always_src_split(false) { }
|
|
||||||
|
|
||||||
bool operator !=(const HWSplitInfo &split_info) {
|
|
||||||
return ((left_split != split_info.left_split) || (right_split != split_info.right_split) ||
|
|
||||||
(always_src_split != split_info.always_src_split));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator ==(const HWSplitInfo &split_info) {
|
|
||||||
return !(operator !=(split_info));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*! @brief This structure describes properties of a display panel. */
|
|
||||||
struct HWPanelInfo {
|
|
||||||
HWDisplayPort port; //!< Display port
|
|
||||||
HWDisplayMode mode; //!< Display mode
|
|
||||||
bool partial_update; //!< Partial update feature
|
|
||||||
int left_align; //!< ROI left alignment restriction
|
|
||||||
int width_align; //!< ROI width alignment restriction
|
|
||||||
int top_align;; //!< ROI top alignment restriction
|
|
||||||
int height_align; //!< ROI height alignment restriction
|
|
||||||
int min_roi_width; //!< Min width needed for ROI
|
|
||||||
int min_roi_height; //!< Min height needed for ROI
|
|
||||||
bool needs_roi_merge; //!< Merge ROI's of both the DSI's
|
|
||||||
bool dynamic_fps; //!< Panel Supports dynamic fps
|
|
||||||
uint32_t min_fps; //!< Min fps supported by panel
|
|
||||||
uint32_t max_fps; //!< Max fps supported by panel
|
|
||||||
bool is_primary_panel; //!< Panel is primary display
|
|
||||||
HWSplitInfo split_info; //!< Panel split configuration
|
|
||||||
|
|
||||||
HWPanelInfo() : port(kPortDefault), mode(kModeDefault), partial_update(false), left_align(false),
|
|
||||||
width_align(false), top_align(false), height_align(false), min_roi_width(0), min_roi_height(0),
|
|
||||||
needs_roi_merge(false), dynamic_fps(false), min_fps(0), max_fps(0) { }
|
|
||||||
|
|
||||||
bool operator !=(const HWPanelInfo &panel_info) {
|
|
||||||
return ((port != panel_info.port) || (mode != panel_info.mode) ||
|
|
||||||
(partial_update != panel_info.partial_update) ||
|
|
||||||
(left_align != panel_info.left_align) || (width_align != panel_info.width_align) ||
|
|
||||||
(top_align != panel_info.top_align) || (height_align != panel_info.height_align) ||
|
|
||||||
(min_roi_width != panel_info.min_roi_width) ||
|
|
||||||
(min_roi_height != panel_info.min_roi_height) ||
|
|
||||||
(needs_roi_merge != panel_info.needs_roi_merge) ||
|
|
||||||
(dynamic_fps != panel_info.dynamic_fps) || (min_fps != panel_info.min_fps) ||
|
|
||||||
(max_fps != panel_info.max_fps) || (is_primary_panel != panel_info.is_primary_panel) ||
|
|
||||||
(split_info != panel_info.split_info));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator ==(const HWPanelInfo &panel_info) {
|
|
||||||
return !(operator !=(panel_info));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace sde
|
|
||||||
|
|
||||||
#endif // __HW_INFO_TYPES_H__
|
|
||||||
|
|
||||||
@@ -1,201 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014, The Linux Foundation. All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
|
||||||
* provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
|
||||||
* conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright notice, this list of
|
|
||||||
* conditions and the following disclaimer in the documentation and/or other materials provided
|
|
||||||
* with the distribution.
|
|
||||||
* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
|
|
||||||
* endorse or promote products derived from this software without specific prior written
|
|
||||||
* permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
||||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|
||||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*! @file strategy_interface.h
|
|
||||||
@brief Interface file for strategy manager which will be used by display core to select a
|
|
||||||
composition strategy for a frame to be displayed on target.
|
|
||||||
*/
|
|
||||||
#ifndef __STRATEGY_INTERFACE_H__
|
|
||||||
#define __STRATEGY_INTERFACE_H__
|
|
||||||
|
|
||||||
#include <core/sde_types.h>
|
|
||||||
#include <core/display_interface.h>
|
|
||||||
#include "hw_info_types.h"
|
|
||||||
|
|
||||||
namespace sde {
|
|
||||||
|
|
||||||
/*! @brief Strategy library name
|
|
||||||
|
|
||||||
@details This macro defines name for the composition strategy library. This macro shall be used
|
|
||||||
to load library using dlopen().
|
|
||||||
|
|
||||||
@sa CreateStrategyInterface
|
|
||||||
@sa DestoryStrategyInterface
|
|
||||||
*/
|
|
||||||
#define STRATEGY_LIBRARY_NAME "libsdestrategy.so"
|
|
||||||
|
|
||||||
/*! @brief Function name to create composer strategy interface
|
|
||||||
|
|
||||||
@details This macro defines function name for CreateStrategyInterface() which is implemented in
|
|
||||||
the composition strategy library. This macro shall be used to specify name of the function in
|
|
||||||
dlsym().
|
|
||||||
|
|
||||||
@sa CreateStrategyInterface
|
|
||||||
*/
|
|
||||||
#define CREATE_STRATEGY_INTERFACE_NAME "CreateStrategyInterface"
|
|
||||||
|
|
||||||
/*! @brief Function name to destroy composer strategy interface
|
|
||||||
|
|
||||||
@details This macro defines function name for DestroyStrategyInterface() which is implemented in
|
|
||||||
the composition strategy library. This macro shall be used to specify name of the function in
|
|
||||||
dlsym().
|
|
||||||
|
|
||||||
@sa DestroyStrategyInterface
|
|
||||||
*/
|
|
||||||
#define DESTROY_STRATEGY_INTERFACE_NAME "DestroyStrategyInterface"
|
|
||||||
|
|
||||||
/*! @brief Strategy interface version.
|
|
||||||
|
|
||||||
@details Strategy interface is version tagged to maintain backward compatibility. This version is
|
|
||||||
supplied as a default argument during strategy library initialization.
|
|
||||||
|
|
||||||
Client may use an older version of interfaces and link to a higher version of strategy library,
|
|
||||||
but vice versa is not allowed.
|
|
||||||
|
|
||||||
@sa CreateStrategyInterface
|
|
||||||
*/
|
|
||||||
#define STRATEGY_REVISION_MAJOR (1)
|
|
||||||
#define STRATEGY_REVISION_MINOR (0)
|
|
||||||
|
|
||||||
#define STRATEGY_VERSION_TAG ((uint16_t) ((STRATEGY_REVISION_MAJOR << 8) | STRATEGY_REVISION_MINOR))
|
|
||||||
|
|
||||||
class StrategyInterface;
|
|
||||||
|
|
||||||
/*! @brief Function to create composer strategy interface.
|
|
||||||
|
|
||||||
@details This function is used to create StrategyInterface object which resides in the composer
|
|
||||||
strategy library loaded at runtime.
|
|
||||||
|
|
||||||
@param[in] version \link STRATEGY_VERSION_TAG \endlink
|
|
||||||
@param[in] type \link DisplayType \endlink
|
|
||||||
@param[in] hw_resource_info \link HWResourceInfo \endlink
|
|
||||||
@param[in] hw_panel_info \link HWPanelInfo \endlink
|
|
||||||
@param[out] interface \link StrategyInterface \endlink
|
|
||||||
|
|
||||||
@return \link DisplayError \endlink
|
|
||||||
*/
|
|
||||||
typedef DisplayError (*CreateStrategyInterface)(uint16_t version, DisplayType type,
|
|
||||||
const HWResourceInfo &hw_resource_info, const HWPanelInfo &hw_panel_info,
|
|
||||||
StrategyInterface **interface);
|
|
||||||
|
|
||||||
/*! @brief Function to destroy composer strategy interface.
|
|
||||||
|
|
||||||
@details This function is used to destroy StrategyInterface object.
|
|
||||||
|
|
||||||
@param[in] interface \link StrategyInterface \endlink
|
|
||||||
|
|
||||||
@return \link DisplayError \endlink
|
|
||||||
*/
|
|
||||||
typedef DisplayError (*DestroyStrategyInterface)(StrategyInterface *interface);
|
|
||||||
|
|
||||||
/*! @brief Maximum number of layers that can be handled by hardware in a given layer stack.
|
|
||||||
*/
|
|
||||||
const int kMaxSDELayers = 16;
|
|
||||||
|
|
||||||
/*! @brief This structure defines constraints and display properties that shall be considered for
|
|
||||||
deciding a composition strategy.
|
|
||||||
|
|
||||||
@sa GetNextStrategy
|
|
||||||
*/
|
|
||||||
struct StrategyConstraints {
|
|
||||||
bool safe_mode; //!< In this mode, strategy manager chooses the composition strategy
|
|
||||||
//!< that requires minimum number of pipe for the current frame. i.e.,
|
|
||||||
//!< video only composition, secure only composition or GPU composition
|
|
||||||
|
|
||||||
uint32_t max_layers; //!< Maximum number of layers that shall be programmed on hardware for the
|
|
||||||
//!< given layer stack.
|
|
||||||
|
|
||||||
StrategyConstraints() : safe_mode(false), max_layers(kMaxSDELayers) { }
|
|
||||||
};
|
|
||||||
|
|
||||||
/*! @brief This structure encapsulates information about the input layer stack and the layers which
|
|
||||||
shall be programmed on hardware.
|
|
||||||
|
|
||||||
@sa Start
|
|
||||||
*/
|
|
||||||
struct HWLayersInfo {
|
|
||||||
LayerStack *stack; //!< Input layer stack. Set by the caller.
|
|
||||||
|
|
||||||
uint32_t index[kMaxSDELayers];
|
|
||||||
//!< Indexes of the layers from the layer stack which need to be
|
|
||||||
//!< programmed on hardware.
|
|
||||||
|
|
||||||
uint32_t count; //!< Total number of layers which need to be set on hardware.
|
|
||||||
|
|
||||||
LayerRect left_partial_update;
|
|
||||||
//!< Left ROI.
|
|
||||||
|
|
||||||
LayerRect right_partial_update;
|
|
||||||
//!< Right ROI.
|
|
||||||
|
|
||||||
|
|
||||||
HWLayersInfo() : stack(NULL), count(0) { }
|
|
||||||
};
|
|
||||||
|
|
||||||
/*! @brief Strategy interface.
|
|
||||||
|
|
||||||
@details This class defines Strategy interface. It contains methods which client shall use to
|
|
||||||
determine which strategy to be used for layer composition. This interface is created during
|
|
||||||
display device creation and remains valid until destroyed.
|
|
||||||
*/
|
|
||||||
|
|
||||||
class StrategyInterface {
|
|
||||||
public:
|
|
||||||
/*! @brief Method to indicate start of a new strategy selection iteration for a layer stack.
|
|
||||||
|
|
||||||
@details Client shall call this method at beginning of each draw cycle before iterating
|
|
||||||
through strategy selection. Strategy interface implementation uses this method to do
|
|
||||||
preprocessing for a given layer stack.
|
|
||||||
|
|
||||||
@param[in] layers_info \link HWLayersInfo \endlink
|
|
||||||
@param[out] max_attempts Maximum calls to \link GetNextStrategy \endlink
|
|
||||||
|
|
||||||
@return \link DisplayError \endlink
|
|
||||||
*/
|
|
||||||
virtual DisplayError Start(HWLayersInfo *hw_layers_info, uint32_t *max_attempts) = 0;
|
|
||||||
|
|
||||||
|
|
||||||
/*! @brief Method to get strategy for a layer stack. Caller can loop through this method to try
|
|
||||||
get all applicable strategies.
|
|
||||||
|
|
||||||
@param[in] constraints \link StrategyConstraints \endlink
|
|
||||||
|
|
||||||
@return \link DisplayError \endlink
|
|
||||||
*/
|
|
||||||
virtual DisplayError GetNextStrategy(StrategyConstraints *constraints) = 0;
|
|
||||||
|
|
||||||
/*! @brief Method to indicate end of a strategy selection cycle.
|
|
||||||
|
|
||||||
@return \link DisplayError \endlink
|
|
||||||
*/
|
|
||||||
virtual DisplayError Stop() = 0;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual ~StrategyInterface() { }
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace sde
|
|
||||||
|
|
||||||
#endif // __STRATEGY_INTERFACE_H__
|
|
||||||
|
|
||||||
@@ -1,354 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are
|
|
||||||
* met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above
|
|
||||||
* copyright notice, this list of conditions and the following
|
|
||||||
* disclaimer in the documentation and/or other materials provided
|
|
||||||
* with the distribution.
|
|
||||||
* * Neither the name of The Linux Foundation nor the names of its
|
|
||||||
* contributors may be used to endorse or promote products derived
|
|
||||||
* from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
|
||||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
|
||||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|
||||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
||||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
|
||||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
|
||||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <utils/debug.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include "hw_rotator.h"
|
|
||||||
|
|
||||||
#define __CLASS__ "HWRotator"
|
|
||||||
|
|
||||||
namespace sde {
|
|
||||||
|
|
||||||
DisplayError HWRotatorInterface::Create(BufferSyncHandler *buffer_sync_handler,
|
|
||||||
HWRotatorInterface **intf) {
|
|
||||||
DisplayError error = kErrorNone;
|
|
||||||
HWRotator *hw_rotator = NULL;
|
|
||||||
|
|
||||||
hw_rotator = new HWRotator(buffer_sync_handler);
|
|
||||||
if (!hw_rotator) {
|
|
||||||
error = kErrorMemory;
|
|
||||||
} else {
|
|
||||||
*intf = hw_rotator;
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError HWRotatorInterface::Destroy(HWRotatorInterface *intf) {
|
|
||||||
delete intf;
|
|
||||||
intf = NULL;
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
HWRotator::HWRotator(BufferSyncHandler *buffer_sync_handler) : HWDevice(buffer_sync_handler) {
|
|
||||||
HWDevice::device_type_ = kDeviceRotator;
|
|
||||||
HWDevice::device_name_ = "Rotator Device";
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError HWRotator::Open() {
|
|
||||||
DisplayError error = kErrorNone;
|
|
||||||
|
|
||||||
char device_name[64] = {0};
|
|
||||||
snprintf(device_name, sizeof(device_name), "%s", "/dev/mdss_rotator");
|
|
||||||
|
|
||||||
HWDevice::device_fd_ = open_(device_name, O_RDWR);
|
|
||||||
if (HWDevice::device_fd_ < 0) {
|
|
||||||
DLOGE("open %s failed err = %d errstr = %s", device_name, errno, strerror(errno));
|
|
||||||
return kErrorResources;
|
|
||||||
}
|
|
||||||
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError HWRotator::Close() {
|
|
||||||
if (HWDevice::device_fd_ > 0) {
|
|
||||||
close_(HWDevice::device_fd_);
|
|
||||||
}
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError HWRotator::OpenSession(HWRotatorSession *hw_rotator_session) {
|
|
||||||
uint32_t frame_rate = hw_rotator_session->hw_session_config.frame_rate;
|
|
||||||
LayerBufferFormat src_format = hw_rotator_session->hw_session_config.src_format;
|
|
||||||
LayerBufferFormat dst_format = hw_rotator_session->hw_session_config.dst_format;
|
|
||||||
bool rot90 = (hw_rotator_session->transform.rotation == 90.0f);
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < hw_rotator_session->hw_block_count; i++) {
|
|
||||||
HWRotateInfo *hw_rotate_info = &hw_rotator_session->hw_rotate_info[i];
|
|
||||||
|
|
||||||
if (!hw_rotate_info->valid) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t src_width = UINT32(hw_rotate_info->src_roi.right - hw_rotate_info->src_roi.left);
|
|
||||||
uint32_t src_height =
|
|
||||||
UINT32(hw_rotate_info->src_roi.bottom - hw_rotate_info->src_roi.top);
|
|
||||||
|
|
||||||
uint32_t dst_width = UINT32(hw_rotate_info->dst_roi.right - hw_rotate_info->dst_roi.left);
|
|
||||||
uint32_t dst_height =
|
|
||||||
UINT32(hw_rotate_info->dst_roi.bottom - hw_rotate_info->dst_roi.top);
|
|
||||||
|
|
||||||
STRUCT_VAR(mdp_rotation_config, mdp_rot_config);
|
|
||||||
|
|
||||||
mdp_rot_config.version = MDP_ROTATION_REQUEST_VERSION_1_0;
|
|
||||||
mdp_rot_config.input.width = src_width;
|
|
||||||
mdp_rot_config.input.height = src_height;
|
|
||||||
SetFormat(src_format, &mdp_rot_config.input.format);
|
|
||||||
mdp_rot_config.output.width = dst_width;
|
|
||||||
mdp_rot_config.output.height = dst_height;
|
|
||||||
SetFormat(dst_format, &mdp_rot_config.output.format);
|
|
||||||
mdp_rot_config.frame_rate = frame_rate;
|
|
||||||
|
|
||||||
if (rot90) {
|
|
||||||
mdp_rot_config.flags |= MDP_ROTATION_90;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ioctl_(device_fd_, MDSS_ROTATION_OPEN, &mdp_rot_config) < 0) {
|
|
||||||
IOCTL_LOGE(MDSS_ROTATION_OPEN, device_type_);
|
|
||||||
return kErrorHardware;
|
|
||||||
}
|
|
||||||
|
|
||||||
hw_rotate_info->rotate_id = mdp_rot_config.session_id;
|
|
||||||
|
|
||||||
DLOGV_IF(kTagDriverConfig, "session_id %d", hw_rotate_info->rotate_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError HWRotator::CloseSession(HWRotatorSession *hw_rotator_session) {
|
|
||||||
for (uint32_t i = 0; i < hw_rotator_session->hw_block_count; i++) {
|
|
||||||
HWRotateInfo *hw_rotate_info = &hw_rotator_session->hw_rotate_info[i];
|
|
||||||
|
|
||||||
if (!hw_rotate_info->valid) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ioctl_(device_fd_, MDSS_ROTATION_CLOSE, UINT32(hw_rotate_info->rotate_id)) < 0) {
|
|
||||||
IOCTL_LOGE(MDSS_ROTATION_CLOSE, device_type_);
|
|
||||||
return kErrorHardware;
|
|
||||||
}
|
|
||||||
|
|
||||||
DLOGV_IF(kTagDriverConfig, "session_id %d", hw_rotate_info->rotate_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
void HWRotator::SetCtrlParams(HWLayers *hw_layers) {
|
|
||||||
DLOGV_IF(kTagDriverConfig, "************************* %s Validate Input ************************",
|
|
||||||
HWDevice::device_name_);
|
|
||||||
|
|
||||||
ResetParams();
|
|
||||||
|
|
||||||
HWLayersInfo &hw_layer_info = hw_layers->info;
|
|
||||||
|
|
||||||
uint32_t &rot_count = mdp_rot_request_.count;
|
|
||||||
for (uint32_t i = 0; i < hw_layer_info.count; i++) {
|
|
||||||
Layer& layer = hw_layer_info.stack->layers[hw_layer_info.index[i]];
|
|
||||||
HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
|
|
||||||
bool rot90 = (layer.transform.rotation == 90.0f);
|
|
||||||
|
|
||||||
for (uint32_t count = 0; count < hw_rotator_session->hw_block_count; count++) {
|
|
||||||
HWRotateInfo *hw_rotate_info = &hw_rotator_session->hw_rotate_info[count];
|
|
||||||
|
|
||||||
if (hw_rotate_info->valid) {
|
|
||||||
mdp_rotation_item *mdp_rot_item = &mdp_rot_request_.list[rot_count];
|
|
||||||
|
|
||||||
SetMDPFlags(layer, &mdp_rot_item->flags);
|
|
||||||
|
|
||||||
SetRect(hw_rotate_info->src_roi, &mdp_rot_item->src_rect);
|
|
||||||
SetRect(hw_rotate_info->dst_roi, &mdp_rot_item->dst_rect);
|
|
||||||
|
|
||||||
// TODO(user): Need to assign the writeback id and pipe id returned from resource manager.
|
|
||||||
mdp_rot_item->pipe_idx = 0;
|
|
||||||
mdp_rot_item->wb_idx = 0;
|
|
||||||
|
|
||||||
mdp_rot_item->input.width = layer.input_buffer->width;
|
|
||||||
mdp_rot_item->input.height = layer.input_buffer->height;
|
|
||||||
SetFormat(layer.input_buffer->format, &mdp_rot_item->input.format);
|
|
||||||
|
|
||||||
mdp_rot_item->output.width = hw_rotator_session->output_buffer.width;
|
|
||||||
mdp_rot_item->output.height = hw_rotator_session->output_buffer.height;
|
|
||||||
SetFormat(hw_rotator_session->output_buffer.format, &mdp_rot_item->output.format);
|
|
||||||
|
|
||||||
mdp_rot_item->session_id = hw_rotate_info->rotate_id;
|
|
||||||
|
|
||||||
rot_count++;
|
|
||||||
|
|
||||||
DLOGV_IF(kTagDriverConfig, "******************** Layer[%d] %s rotate ********************",
|
|
||||||
i, count ? "Right" : "Left");
|
|
||||||
DLOGV_IF(kTagDriverConfig, "in_w %d, in_h %d, in_f %d,\t out_w %d, out_h %d, out_f %d",
|
|
||||||
mdp_rot_item->input.width, mdp_rot_item->input.height, mdp_rot_item->input.format,
|
|
||||||
mdp_rot_item->output.width, mdp_rot_item->output.height,
|
|
||||||
mdp_rot_item->output.format);
|
|
||||||
DLOGV_IF(kTagDriverConfig, "pipe_id 0x%x, wb_id %d, rot_flag 0x%x, session_id %d",
|
|
||||||
mdp_rot_item->pipe_idx, mdp_rot_item->wb_idx, mdp_rot_item->flags,
|
|
||||||
mdp_rot_item->session_id);
|
|
||||||
DLOGV_IF(kTagDriverConfig, "src_rect [%d, %d, %d, %d]", mdp_rot_item->src_rect.x,
|
|
||||||
mdp_rot_item->src_rect.y, mdp_rot_item->src_rect.w, mdp_rot_item->src_rect.h);
|
|
||||||
DLOGV_IF(kTagDriverConfig, "dst_rect [%d, %d, %d, %d]", mdp_rot_item->dst_rect.x,
|
|
||||||
mdp_rot_item->dst_rect.y, mdp_rot_item->dst_rect.w, mdp_rot_item->dst_rect.h);
|
|
||||||
DLOGV_IF(kTagDriverConfig, "*************************************************************");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void HWRotator::SetBufferParams(HWLayers *hw_layers) {
|
|
||||||
HWLayersInfo &hw_layer_info = hw_layers->info;
|
|
||||||
uint32_t rot_count = 0;
|
|
||||||
|
|
||||||
DLOGV_IF(kTagDriverConfig, "************************* %s Commit Input **************************",
|
|
||||||
HWDevice::device_name_);
|
|
||||||
DLOGV_IF(kTagDriverConfig, "Rotate layer count is %d", mdp_rot_request_.count);
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < hw_layer_info.count; i++) {
|
|
||||||
Layer& layer = hw_layer_info.stack->layers[hw_layer_info.index[i]];
|
|
||||||
HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
|
|
||||||
|
|
||||||
for (uint32_t count = 0; count < hw_rotator_session->hw_block_count; count++) {
|
|
||||||
HWRotateInfo *hw_rotate_info = &hw_rotator_session->hw_rotate_info[count];
|
|
||||||
|
|
||||||
if (hw_rotate_info->valid) {
|
|
||||||
mdp_rotation_item *mdp_rot_item = &mdp_rot_request_.list[rot_count];
|
|
||||||
|
|
||||||
mdp_rot_item->input.planes[0].fd = layer.input_buffer->planes[0].fd;
|
|
||||||
mdp_rot_item->input.planes[0].offset = layer.input_buffer->planes[0].offset;
|
|
||||||
SetStride(device_type_, layer.input_buffer->format, layer.input_buffer->width,
|
|
||||||
&mdp_rot_item->input.planes[0].stride);
|
|
||||||
mdp_rot_item->input.plane_count = 1;
|
|
||||||
mdp_rot_item->input.fence = layer.input_buffer->acquire_fence_fd;
|
|
||||||
|
|
||||||
mdp_rot_item->output.planes[0].fd = hw_rotator_session->output_buffer.planes[0].fd;
|
|
||||||
mdp_rot_item->output.planes[0].offset = hw_rotator_session->output_buffer.planes[0].offset;
|
|
||||||
SetStride(device_type_, hw_rotator_session->output_buffer.format,
|
|
||||||
hw_rotator_session->output_buffer.planes[0].stride,
|
|
||||||
&mdp_rot_item->output.planes[0].stride);
|
|
||||||
mdp_rot_item->output.plane_count = 1;
|
|
||||||
mdp_rot_item->output.fence = -1;
|
|
||||||
|
|
||||||
rot_count++;
|
|
||||||
|
|
||||||
DLOGV_IF(kTagDriverConfig, "******************** Layer[%d] %s rotate ********************",
|
|
||||||
i, count ? "Right" : "Left");
|
|
||||||
DLOGV_IF(kTagDriverConfig, "in_buf_fd %d, in_buf_offset %d, in_stride %d, " \
|
|
||||||
"in_plane_count %d, in_fence %d", mdp_rot_item->input.planes[0].fd,
|
|
||||||
mdp_rot_item->input.planes[0].offset, mdp_rot_item->input.planes[0].stride,
|
|
||||||
mdp_rot_item->input.plane_count, mdp_rot_item->input.fence);
|
|
||||||
DLOGV_IF(kTagDriverConfig, "out_fd %d, out_offset %d, out_stride %d, out_plane_count %d, " \
|
|
||||||
"out_fence %d", mdp_rot_item->output.planes[0].fd,
|
|
||||||
mdp_rot_item->output.planes[0].offset, mdp_rot_item->output.planes[0].stride,
|
|
||||||
mdp_rot_item->output.plane_count, mdp_rot_item->output.fence);
|
|
||||||
DLOGV_IF(kTagDriverConfig, "*************************************************************");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void HWRotator::SetMDPFlags(const Layer &layer, uint32_t *mdp_flags) {
|
|
||||||
LayerTransform transform = layer.transform;
|
|
||||||
bool rot90 = (transform.rotation == 90.0f);
|
|
||||||
|
|
||||||
if (rot90) {
|
|
||||||
*mdp_flags |= MDP_ROTATION_90;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (transform.flip_horizontal) {
|
|
||||||
*mdp_flags |= MDP_ROTATION_FLIP_LR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (transform.flip_vertical) {
|
|
||||||
*mdp_flags |= MDP_ROTATION_FLIP_UD;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (layer.input_buffer->flags.secure) {
|
|
||||||
*mdp_flags |= MDP_ROTATION_SECURE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError HWRotator::Validate(HWLayers *hw_layers) {
|
|
||||||
SetCtrlParams(hw_layers);
|
|
||||||
|
|
||||||
mdp_rot_request_.flags = MDSS_ROTATION_REQUEST_VALIDATE;
|
|
||||||
if (ioctl_(HWDevice::device_fd_, MDSS_ROTATION_REQUEST, &mdp_rot_request_) < 0) {
|
|
||||||
IOCTL_LOGE(MDSS_ROTATION_REQUEST, HWDevice::device_type_);
|
|
||||||
return kErrorHardware;
|
|
||||||
}
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError HWRotator::Commit(HWLayers *hw_layers) {
|
|
||||||
HWLayersInfo &hw_layer_info = hw_layers->info;
|
|
||||||
uint32_t rot_count = 0;
|
|
||||||
|
|
||||||
SetCtrlParams(hw_layers);
|
|
||||||
|
|
||||||
SetBufferParams(hw_layers);
|
|
||||||
|
|
||||||
mdp_rot_request_.flags &= ~MDSS_ROTATION_REQUEST_VALIDATE;
|
|
||||||
if (ioctl_(HWDevice::device_fd_, MDSS_ROTATION_REQUEST, &mdp_rot_request_) < 0) {
|
|
||||||
IOCTL_LOGE(MDSS_ROTATION_REQUEST, HWDevice::device_type_);
|
|
||||||
return kErrorHardware;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < hw_layer_info.count; i++) {
|
|
||||||
Layer& layer = hw_layer_info.stack->layers[hw_layer_info.index[i]];
|
|
||||||
HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
|
|
||||||
|
|
||||||
layer.input_buffer->release_fence_fd = -1;
|
|
||||||
|
|
||||||
for (uint32_t count = 0; count < hw_rotator_session->hw_block_count; count++) {
|
|
||||||
HWRotateInfo *hw_rotate_info = &hw_rotator_session->hw_rotate_info[count];
|
|
||||||
|
|
||||||
if (hw_rotate_info->valid) {
|
|
||||||
mdp_rotation_item *mdp_rot_item = &mdp_rot_request_.list[rot_count];
|
|
||||||
|
|
||||||
HWDevice::SyncMerge(layer.input_buffer->release_fence_fd, dup(mdp_rot_item->output.fence),
|
|
||||||
&layer.input_buffer->release_fence_fd);
|
|
||||||
|
|
||||||
hw_rotator_session->output_buffer.acquire_fence_fd = dup(mdp_rot_item->output.fence);
|
|
||||||
|
|
||||||
close_(mdp_rot_item->output.fence);
|
|
||||||
rot_count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
void HWRotator::ResetParams() {
|
|
||||||
memset(&mdp_rot_request_, 0, sizeof(mdp_rot_request_));
|
|
||||||
memset(&mdp_rot_layers_, 0, sizeof(mdp_rot_layers_));
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < kMaxSDELayers * 2; i++) {
|
|
||||||
mdp_rot_layers_[i].input.fence = -1;
|
|
||||||
mdp_rot_layers_[i].output.fence = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
mdp_rot_request_.version = MDP_ROTATION_REQUEST_VERSION_1_0;
|
|
||||||
mdp_rot_request_.list = mdp_rot_layers_;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace sde
|
|
||||||
|
|
||||||
@@ -1,229 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014 - 2015, The Linux Foundation. All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
|
||||||
* provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
|
||||||
* conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright notice, this list of
|
|
||||||
* conditions and the following disclaimer in the documentation and/or other materials provided
|
|
||||||
* with the distribution.
|
|
||||||
* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
|
|
||||||
* endorse or promote products derived from this software without specific prior written
|
|
||||||
* permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
||||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|
||||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __HW_INTERFACE_H__
|
|
||||||
#define __HW_INTERFACE_H__
|
|
||||||
|
|
||||||
#include <core/display_interface.h>
|
|
||||||
#include <private/strategy_interface.h>
|
|
||||||
#include <private/hw_info_types.h>
|
|
||||||
#include <utils/constants.h>
|
|
||||||
#include <core/buffer_allocator.h>
|
|
||||||
#include <core/buffer_sync_handler.h>
|
|
||||||
|
|
||||||
namespace sde {
|
|
||||||
|
|
||||||
enum HWBlockType {
|
|
||||||
kHWPrimary,
|
|
||||||
kHWHDMI,
|
|
||||||
kHWWriteback0,
|
|
||||||
kHWWriteback1,
|
|
||||||
kHWWriteback2,
|
|
||||||
kHWBlockMax
|
|
||||||
};
|
|
||||||
|
|
||||||
struct HWSessionConfig {
|
|
||||||
uint32_t src_width;
|
|
||||||
uint32_t src_height;
|
|
||||||
LayerBufferFormat src_format;
|
|
||||||
uint32_t dst_width;
|
|
||||||
uint32_t dst_height;
|
|
||||||
LayerBufferFormat dst_format;
|
|
||||||
uint32_t buffer_count;
|
|
||||||
bool secure;
|
|
||||||
bool cache;
|
|
||||||
uint32_t frame_rate;
|
|
||||||
|
|
||||||
HWSessionConfig()
|
|
||||||
: src_width(0), src_height(0), src_format(kFormatInvalid), dst_width(0), dst_height(0),
|
|
||||||
dst_format(kFormatInvalid), buffer_count(0), secure(false), cache(false), frame_rate(0) { }
|
|
||||||
|
|
||||||
bool operator != (const HWSessionConfig &input_config) const {
|
|
||||||
if ((src_width != input_config.src_width) || (src_height != input_config.src_height) ||
|
|
||||||
(src_format != input_config.src_format) || (dst_width != input_config.dst_width) ||
|
|
||||||
(dst_height != input_config.dst_height) || (dst_format != input_config.dst_format) ||
|
|
||||||
(buffer_count != input_config.buffer_count) || (secure != input_config.secure) ||
|
|
||||||
(cache != input_config.cache) || (frame_rate != input_config.frame_rate)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator == (const HWSessionConfig &input_config) const {
|
|
||||||
return !(operator != (input_config));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct HWRotateInfo {
|
|
||||||
uint32_t pipe_id;
|
|
||||||
LayerRect src_roi;
|
|
||||||
LayerRect dst_roi;
|
|
||||||
HWBlockType writeback_id;
|
|
||||||
bool valid;
|
|
||||||
int rotate_id;
|
|
||||||
|
|
||||||
HWRotateInfo()
|
|
||||||
: pipe_id(0), writeback_id(kHWWriteback0), valid(false), rotate_id(-1) { }
|
|
||||||
|
|
||||||
void Reset() { *this = HWRotateInfo(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct HWRotatorSession {
|
|
||||||
HWRotateInfo hw_rotate_info[kMaxRotatePerLayer];
|
|
||||||
uint32_t hw_block_count; // number of rotator hw blocks used by rotator session
|
|
||||||
float downscale_ratio;
|
|
||||||
LayerTransform transform;
|
|
||||||
HWSessionConfig hw_session_config;
|
|
||||||
LayerBuffer output_buffer;
|
|
||||||
int session_id;
|
|
||||||
|
|
||||||
HWRotatorSession() : hw_block_count(0), downscale_ratio(1.0f), session_id(-1) { }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct HWPixelExtension {
|
|
||||||
// Number of pixels extension in left, right, top and bottom directions for all color components.
|
|
||||||
// This pixel value for each color component should be sum of fetch and repeat pixels.
|
|
||||||
int extension;
|
|
||||||
|
|
||||||
// Number of pixels need to be overfetched in left, right, top and bottom directions from source
|
|
||||||
// image for scaling.
|
|
||||||
int overfetch;
|
|
||||||
|
|
||||||
// Number of pixels need to be repeated in left, right, top and bottom directions for scaling.
|
|
||||||
int repeat;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct HWPlane {
|
|
||||||
int init_phase_x;
|
|
||||||
int phase_step_x;
|
|
||||||
int init_phase_y;
|
|
||||||
int phase_step_y;
|
|
||||||
HWPixelExtension left;
|
|
||||||
HWPixelExtension top;
|
|
||||||
HWPixelExtension right;
|
|
||||||
HWPixelExtension bottom;
|
|
||||||
uint32_t roi_width;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ScaleData {
|
|
||||||
uint8_t enable_pixel_ext;
|
|
||||||
uint32_t src_width;
|
|
||||||
uint32_t src_height;
|
|
||||||
HWPlane plane[4];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct HWPipeInfo {
|
|
||||||
uint32_t pipe_id;
|
|
||||||
LayerRect src_roi;
|
|
||||||
LayerRect dst_roi;
|
|
||||||
uint8_t horizontal_decimation;
|
|
||||||
uint8_t vertical_decimation;
|
|
||||||
ScaleData scale_data;
|
|
||||||
bool valid;
|
|
||||||
uint32_t z_order;
|
|
||||||
|
|
||||||
HWPipeInfo()
|
|
||||||
: pipe_id(0), horizontal_decimation(0), vertical_decimation(0), valid(false), z_order(0) { }
|
|
||||||
|
|
||||||
void Reset() { *this = HWPipeInfo(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct HWLayerConfig {
|
|
||||||
bool use_non_dma_pipe; // set by client
|
|
||||||
HWPipeInfo left_pipe; // pipe for left side of output
|
|
||||||
HWPipeInfo right_pipe; // pipe for right side of output
|
|
||||||
HWRotatorSession hw_rotator_session;
|
|
||||||
|
|
||||||
HWLayerConfig() : use_non_dma_pipe(false) { }
|
|
||||||
|
|
||||||
void Reset() { *this = HWLayerConfig(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct HWLayers {
|
|
||||||
HWLayersInfo info;
|
|
||||||
HWLayerConfig config[kMaxSDELayers];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct HWDisplayAttributes : DisplayConfigVariableInfo {
|
|
||||||
bool is_device_split;
|
|
||||||
uint32_t split_left;
|
|
||||||
bool always_src_split;
|
|
||||||
|
|
||||||
HWDisplayAttributes() : is_device_split(false), split_left(0), always_src_split(false) { }
|
|
||||||
|
|
||||||
void Reset() { *this = HWDisplayAttributes(); }
|
|
||||||
|
|
||||||
bool operator !=(const HWDisplayAttributes &attributes) {
|
|
||||||
return ((is_device_split != attributes.is_device_split) ||
|
|
||||||
(split_left != attributes.split_left) ||
|
|
||||||
(always_src_split != attributes.always_src_split) ||
|
|
||||||
(x_pixels != attributes.x_pixels) || (y_pixels != attributes.y_pixels) ||
|
|
||||||
(x_dpi != attributes.x_dpi) || (y_dpi != attributes.y_dpi) || (fps != attributes.fps) ||
|
|
||||||
(vsync_period_ns != attributes.vsync_period_ns) || (v_total != attributes.v_total));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator ==(const HWDisplayAttributes &attributes) {
|
|
||||||
return !(operator !=(attributes));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// HWEventHandler - Implemented in DisplayBase and HWInterface implementation
|
|
||||||
class HWEventHandler {
|
|
||||||
public:
|
|
||||||
virtual DisplayError VSync(int64_t timestamp) = 0;
|
|
||||||
virtual DisplayError Blank(bool blank) = 0;
|
|
||||||
virtual void IdleTimeout() = 0;
|
|
||||||
virtual void ThermalEvent(int64_t thermal_level) = 0;
|
|
||||||
protected:
|
|
||||||
virtual ~HWEventHandler() { }
|
|
||||||
};
|
|
||||||
|
|
||||||
class HWInterface {
|
|
||||||
public:
|
|
||||||
virtual DisplayError Open(HWEventHandler *eventhandler) = 0;
|
|
||||||
virtual DisplayError Close() = 0;
|
|
||||||
virtual DisplayError GetNumDisplayAttributes(uint32_t *count) = 0;
|
|
||||||
virtual DisplayError GetDisplayAttributes(HWDisplayAttributes *display_attributes,
|
|
||||||
uint32_t index) = 0;
|
|
||||||
virtual DisplayError GetHWPanelInfo(HWPanelInfo *panel_info) = 0;
|
|
||||||
virtual DisplayError SetDisplayAttributes(uint32_t index) = 0;
|
|
||||||
virtual DisplayError GetConfigIndex(uint32_t mode, uint32_t *index) = 0;
|
|
||||||
virtual DisplayError PowerOn() = 0;
|
|
||||||
virtual DisplayError PowerOff() = 0;
|
|
||||||
virtual DisplayError Doze() = 0;
|
|
||||||
virtual DisplayError DozeSuspend() = 0;
|
|
||||||
virtual DisplayError Standby() = 0;
|
|
||||||
virtual DisplayError Validate(HWLayers *hw_layers) = 0;
|
|
||||||
virtual DisplayError Commit(HWLayers *hw_layers) = 0;
|
|
||||||
virtual DisplayError Flush() = 0;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual ~HWInterface() { }
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace sde
|
|
||||||
|
|
||||||
#endif // __HW_INTERFACE_H__
|
|
||||||
|
|
||||||
@@ -1,825 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014 - 2015, The Linux Foundation. All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
|
||||||
* provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
|
||||||
* conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright notice, this list of
|
|
||||||
* conditions and the following disclaimer in the documentation and/or other materials provided
|
|
||||||
* with the distribution.
|
|
||||||
* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
|
|
||||||
* endorse or promote products derived from this software without specific prior written
|
|
||||||
* permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
||||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|
||||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
#include <utils/constants.h>
|
|
||||||
#include <utils/debug.h>
|
|
||||||
#include <utils/rect.h>
|
|
||||||
|
|
||||||
#include "res_manager.h"
|
|
||||||
|
|
||||||
#define __CLASS__ "ResManager"
|
|
||||||
|
|
||||||
namespace sde {
|
|
||||||
|
|
||||||
static void GetAlignFactor(const LayerBufferFormat &format, uint32_t *align_x, uint32_t *align_y) {
|
|
||||||
*align_x = 1;
|
|
||||||
*align_y = 1;
|
|
||||||
if (!IS_RGB_FORMAT(format)) {
|
|
||||||
*align_x = 2;
|
|
||||||
*align_y = 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ResManager::RotationConfig(const Layer &layer, const float &downscale, LayerRect *src_rect,
|
|
||||||
struct HWLayerConfig *layer_config, uint32_t *rotate_count) {
|
|
||||||
HWRotatorSession *hw_rotator_session = &layer_config->hw_rotator_session;
|
|
||||||
HWRotateInfo *hw_rotate_info = &hw_rotator_session->hw_rotate_info[0];
|
|
||||||
float src_width = src_rect->right - src_rect->left;
|
|
||||||
float src_height = src_rect->bottom - src_rect->top;
|
|
||||||
bool rot90 = IsRotationNeeded(layer.transform.rotation);
|
|
||||||
bool is_opaque = (layer.blending == kBlendingOpaque);
|
|
||||||
LayerRect dst_rect;
|
|
||||||
// Rotate output is a temp buffer, always output to the top left corner for saving memory
|
|
||||||
dst_rect.top = 0.0f;
|
|
||||||
dst_rect.left = 0.0f;
|
|
||||||
|
|
||||||
hw_rotator_session->downscale_ratio = downscale;
|
|
||||||
uint32_t align_x, align_y;
|
|
||||||
GetAlignFactor(layer.input_buffer->format, &align_x, &align_y);
|
|
||||||
|
|
||||||
// downscale when doing rotation
|
|
||||||
if (rot90) {
|
|
||||||
if (downscale > 1.0f) {
|
|
||||||
src_height = ROUND_UP_ALIGN_DOWN(src_height, downscale * FLOAT(align_x));
|
|
||||||
src_rect->bottom = src_rect->top + src_height;
|
|
||||||
src_width = ROUND_UP_ALIGN_DOWN(src_width, downscale * FLOAT(align_y));
|
|
||||||
src_rect->right = src_rect->left + src_width;
|
|
||||||
}
|
|
||||||
dst_rect.right = src_height / downscale;
|
|
||||||
dst_rect.bottom = src_width / downscale;
|
|
||||||
} else {
|
|
||||||
if (downscale > 1.0f) {
|
|
||||||
src_width = ROUND_UP_ALIGN_DOWN(src_width, downscale * FLOAT(align_x));
|
|
||||||
src_rect->right = src_rect->left + src_width;
|
|
||||||
src_height = ROUND_UP_ALIGN_DOWN(src_height, downscale * FLOAT(align_y));
|
|
||||||
src_rect->bottom = src_rect->top + src_height;
|
|
||||||
}
|
|
||||||
dst_rect.right = src_width / downscale;
|
|
||||||
dst_rect.bottom = src_height / downscale;
|
|
||||||
}
|
|
||||||
|
|
||||||
hw_rotate_info->src_roi = *src_rect;
|
|
||||||
hw_rotate_info->valid = true;
|
|
||||||
hw_rotate_info->dst_roi = dst_rect;
|
|
||||||
|
|
||||||
LayerBufferFormat *output_format = &hw_rotator_session->output_buffer.format;
|
|
||||||
SetRotatorOutputFormat(layer.input_buffer->format, is_opaque, rot90, (downscale > 1.0f),
|
|
||||||
output_format);
|
|
||||||
|
|
||||||
*src_rect = dst_rect;
|
|
||||||
hw_rotator_session->hw_block_count = 1;
|
|
||||||
hw_rotator_session->transform = layer.transform;
|
|
||||||
(*rotate_count)++;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError ResManager::SrcSplitConfig(DisplayResourceContext *display_resource_ctx,
|
|
||||||
const LayerTransform &transform, const LayerRect &src_rect,
|
|
||||||
const LayerRect &dst_rect, HWLayerConfig *layer_config,
|
|
||||||
uint32_t align_x) {
|
|
||||||
HWDisplayAttributes &display_attributes = display_resource_ctx->display_attributes;
|
|
||||||
HWPipeInfo *left_pipe = &layer_config->left_pipe;
|
|
||||||
HWPipeInfo *right_pipe = &layer_config->right_pipe;
|
|
||||||
float src_width = src_rect.right - src_rect.left;
|
|
||||||
float dst_width = dst_rect.right - dst_rect.left;
|
|
||||||
float src_height = src_rect.bottom - src_rect.top;
|
|
||||||
float dst_height = dst_rect.bottom - dst_rect.top;
|
|
||||||
float left_mixer_width = FLOAT(display_attributes.split_left);
|
|
||||||
|
|
||||||
uint8_t decimation = 0;
|
|
||||||
if (CalculateDecimation((src_height / dst_height), &decimation) != kErrorNone) {
|
|
||||||
return kErrorNotSupported;
|
|
||||||
}
|
|
||||||
// Adjust source height to consider decimation
|
|
||||||
src_height /= powf(2.0f, decimation);
|
|
||||||
|
|
||||||
// No need to include common factors in clock calculation of pipe & mixer
|
|
||||||
float pipe_clock = MAX(dst_width, (dst_width * src_height / dst_height));
|
|
||||||
float mixer_clock = left_mixer_width;
|
|
||||||
|
|
||||||
// Layer cannot qualify for SrcSplit if source or destination width exceeds max pipe width.
|
|
||||||
// For perf/power optimization, even if "always_src_split" is enabled, use 2 pipes only if:
|
|
||||||
// 1. Source width is greater than split_left (left_mixer_width)
|
|
||||||
// 2. Pipe clock exceeds the mixer clock
|
|
||||||
if ((src_width > hw_res_info_.max_pipe_width) || (dst_width > hw_res_info_.max_pipe_width) ||
|
|
||||||
(display_resource_ctx->display_attributes.always_src_split &&
|
|
||||||
((src_width > left_mixer_width) || (pipe_clock > mixer_clock)))) {
|
|
||||||
SplitRect(transform.flip_horizontal, src_rect, dst_rect, &left_pipe->src_roi,
|
|
||||||
&left_pipe->dst_roi, &right_pipe->src_roi, &right_pipe->dst_roi, align_x);
|
|
||||||
left_pipe->valid = true;
|
|
||||||
right_pipe->valid = true;
|
|
||||||
} else {
|
|
||||||
left_pipe->src_roi = src_rect;
|
|
||||||
left_pipe->dst_roi = dst_rect;
|
|
||||||
left_pipe->valid = true;
|
|
||||||
right_pipe->Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError ResManager::DisplaySplitConfig(DisplayResourceContext *display_resource_ctx,
|
|
||||||
const LayerTransform &transform,
|
|
||||||
const LayerRect &src_rect, const LayerRect &dst_rect,
|
|
||||||
const HWLayers &hw_layers, HWLayerConfig *layer_config,
|
|
||||||
uint32_t align_x) {
|
|
||||||
LayerRect scissor_dst_left, scissor_dst_right;
|
|
||||||
HWDisplayAttributes &display_attributes = display_resource_ctx->display_attributes;
|
|
||||||
|
|
||||||
// for display split case
|
|
||||||
HWPipeInfo *left_pipe = &layer_config->left_pipe;
|
|
||||||
HWPipeInfo *right_pipe = &layer_config->right_pipe;
|
|
||||||
LayerRect scissor_left, scissor_right, dst_left, crop_left, crop_right, dst_right;
|
|
||||||
|
|
||||||
scissor_left.right = FLOAT(display_attributes.split_left);
|
|
||||||
scissor_left.bottom = FLOAT(display_attributes.y_pixels);
|
|
||||||
|
|
||||||
scissor_right.left = FLOAT(display_attributes.split_left);
|
|
||||||
scissor_right.top = 0.0f;
|
|
||||||
scissor_right.right = FLOAT(display_attributes.x_pixels);
|
|
||||||
scissor_right.bottom = FLOAT(display_attributes.y_pixels);
|
|
||||||
|
|
||||||
if (IsValid(hw_layers.info.left_partial_update) ||
|
|
||||||
IsValid(hw_layers.info.right_partial_update)) {
|
|
||||||
scissor_left = hw_layers.info.left_partial_update;
|
|
||||||
scissor_right = hw_layers.info.right_partial_update;
|
|
||||||
}
|
|
||||||
|
|
||||||
crop_left = src_rect;
|
|
||||||
dst_left = dst_rect;
|
|
||||||
crop_right = crop_left;
|
|
||||||
dst_right = dst_left;
|
|
||||||
bool crop_left_valid = CalculateCropRects(scissor_left, transform, &crop_left, &dst_left);
|
|
||||||
bool crop_right_valid = false;
|
|
||||||
|
|
||||||
if (IsValid(scissor_right)) {
|
|
||||||
crop_right_valid = CalculateCropRects(scissor_right, transform, &crop_right, &dst_right);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (crop_left_valid && (crop_left.right - crop_left.left) > hw_res_info_.max_pipe_width) {
|
|
||||||
if (crop_right_valid) {
|
|
||||||
DLOGV_IF(kTagResources, "Need more than 2 pipes: left width = %.0f, right width = %.0f",
|
|
||||||
crop_left.right - crop_left.left, crop_right.right - crop_right.left);
|
|
||||||
return kErrorNotSupported;
|
|
||||||
}
|
|
||||||
// 2 pipes both are on the left
|
|
||||||
SplitRect(transform.flip_horizontal, crop_left, dst_left, &left_pipe->src_roi,
|
|
||||||
&left_pipe->dst_roi, &right_pipe->src_roi, &right_pipe->dst_roi, align_x);
|
|
||||||
left_pipe->valid = true;
|
|
||||||
right_pipe->valid = true;
|
|
||||||
crop_right_valid = true;
|
|
||||||
} else if (crop_right_valid &&
|
|
||||||
(crop_right.right - crop_right.left) > hw_res_info_.max_pipe_width) {
|
|
||||||
if (crop_left_valid) {
|
|
||||||
DLOGV_IF(kTagResources, "Need more than 2 pipes: left width = %.0f, right width = %.0f",
|
|
||||||
crop_left.right - crop_left.left, crop_right.right - crop_right.left);
|
|
||||||
return kErrorNotSupported;
|
|
||||||
}
|
|
||||||
// 2 pipes both are on the right
|
|
||||||
SplitRect(transform.flip_horizontal, crop_right, dst_right, &left_pipe->src_roi,
|
|
||||||
&left_pipe->dst_roi, &right_pipe->src_roi, &right_pipe->dst_roi, align_x);
|
|
||||||
left_pipe->valid = true;
|
|
||||||
right_pipe->valid = true;
|
|
||||||
crop_left_valid = true;
|
|
||||||
} else if (crop_left_valid) {
|
|
||||||
// assign left pipe
|
|
||||||
left_pipe->src_roi = crop_left;
|
|
||||||
left_pipe->dst_roi = dst_left;
|
|
||||||
left_pipe->valid = true;
|
|
||||||
} else {
|
|
||||||
// Set default value, left_pipe is not needed.
|
|
||||||
left_pipe->Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
// assign right pipe if needed
|
|
||||||
if (crop_right_valid) {
|
|
||||||
if (left_pipe->valid) {
|
|
||||||
right_pipe->src_roi = crop_right;
|
|
||||||
right_pipe->dst_roi = dst_right;
|
|
||||||
right_pipe->valid = true;
|
|
||||||
} else {
|
|
||||||
// If left pipe is not used, use left pipe first.
|
|
||||||
left_pipe->src_roi = crop_right;
|
|
||||||
left_pipe->dst_roi = dst_right;
|
|
||||||
left_pipe->valid = true;
|
|
||||||
right_pipe->Reset();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// need not right pipe
|
|
||||||
right_pipe->Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError ResManager::Config(DisplayResourceContext *display_resource_ctx, HWLayers *hw_layers,
|
|
||||||
uint32_t *rotate_count) {
|
|
||||||
HWBlockType hw_block_id = display_resource_ctx->hw_block_id;
|
|
||||||
HWDisplayAttributes &display_attributes = display_resource_ctx->display_attributes;
|
|
||||||
HWLayersInfo &layer_info = hw_layers->info;
|
|
||||||
DisplayError error = kErrorNone;
|
|
||||||
uint32_t z_order = 0;
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < layer_info.count; i++) {
|
|
||||||
Layer& layer = layer_info.stack->layers[layer_info.index[i]];
|
|
||||||
float rotator_scale_factor = 1.0f;
|
|
||||||
|
|
||||||
error = ValidateLayerDimensions(layer);
|
|
||||||
if (error != kErrorNone) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
LayerRect scissor, src_rect, dst_rect;
|
|
||||||
src_rect = layer.src_rect;
|
|
||||||
dst_rect = layer.dst_rect;
|
|
||||||
scissor.right = FLOAT(display_attributes.x_pixels);
|
|
||||||
scissor.bottom = FLOAT(display_attributes.y_pixels);
|
|
||||||
|
|
||||||
if (IsValid(hw_layers->info.left_partial_update)) {
|
|
||||||
scissor = hw_layers->info.left_partial_update;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct HWLayerConfig *layer_config = &hw_layers->config[i];
|
|
||||||
HWPipeInfo &left_pipe = layer_config->left_pipe;
|
|
||||||
HWPipeInfo &right_pipe = layer_config->right_pipe;
|
|
||||||
HWRotatorSession *hw_rotator_session = &layer_config->hw_rotator_session;
|
|
||||||
LayerTransform transform = layer.transform;
|
|
||||||
bool rotated90 = IsRotationNeeded(transform.rotation);
|
|
||||||
|
|
||||||
if (!CalculateCropRects(scissor, layer.transform, &src_rect, &dst_rect)) {
|
|
||||||
layer_config->Reset();
|
|
||||||
left_pipe.Reset();
|
|
||||||
right_pipe.Reset();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t align_x, align_y;
|
|
||||||
GetAlignFactor(layer.input_buffer->format, &align_x, &align_y);
|
|
||||||
if (align_x > 1 || align_y > 1) {
|
|
||||||
Normalize(align_x, align_y, &src_rect);
|
|
||||||
}
|
|
||||||
|
|
||||||
error = ValidateDimensions(src_rect, dst_rect, rotated90);
|
|
||||||
if (error != kErrorNone) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
error = ValidateScaling(src_rect, dst_rect, rotated90);
|
|
||||||
if (error != kErrorNone) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
error = GetRotatorScaleFactor(src_rect, dst_rect, rotated90, &rotator_scale_factor);
|
|
||||||
if (error != kErrorNone) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// config rotator first
|
|
||||||
for (uint32_t j = 0; j < kMaxRotatePerLayer; j++) {
|
|
||||||
hw_rotator_session->hw_rotate_info[j].Reset();
|
|
||||||
}
|
|
||||||
hw_rotator_session->hw_block_count = 0;
|
|
||||||
|
|
||||||
if (rotated90 || UINT32(rotator_scale_factor) != 1) {
|
|
||||||
RotationConfig(layer, rotator_scale_factor, &src_rect, layer_config, rotate_count);
|
|
||||||
// rotator will take care of flipping, reset tranform
|
|
||||||
transform = LayerTransform();
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(user): need to revisit this logic
|
|
||||||
if (hw_res_info_.is_src_split) {
|
|
||||||
error = SrcSplitConfig(display_resource_ctx, transform, src_rect, dst_rect, layer_config,
|
|
||||||
align_x);
|
|
||||||
} else {
|
|
||||||
error = DisplaySplitConfig(display_resource_ctx, transform, src_rect, dst_rect, *hw_layers,
|
|
||||||
layer_config, align_x);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error != kErrorNone) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
error = AlignPipeConfig(layer, transform, *hw_layers, &left_pipe, &right_pipe, align_x,
|
|
||||||
align_y);
|
|
||||||
if (error != kErrorNone) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
DLOGV_IF(kTagResources, "==== layer = %d, left pipe valid = %d ====",
|
|
||||||
i, layer_config->left_pipe.valid);
|
|
||||||
Log(kTagResources, "input layer src_rect", layer.src_rect);
|
|
||||||
Log(kTagResources, "input layer dst_rect", layer.dst_rect);
|
|
||||||
for (uint32_t k = 0; k < hw_rotator_session->hw_block_count; k++) {
|
|
||||||
DLOGV_IF(kTagResources, "rotate num = %d, scale_x = %.2f", k, rotator_scale_factor);
|
|
||||||
Log(kTagResources, "rotate src", hw_rotator_session->hw_rotate_info[k].src_roi);
|
|
||||||
Log(kTagResources, "rotate dst", hw_rotator_session->hw_rotate_info[k].dst_roi);
|
|
||||||
}
|
|
||||||
|
|
||||||
Log(kTagResources, "cropped src_rect", src_rect);
|
|
||||||
Log(kTagResources, "cropped dst_rect", dst_rect);
|
|
||||||
Log(kTagResources, "left pipe src", layer_config->left_pipe.src_roi);
|
|
||||||
Log(kTagResources, "left pipe dst", layer_config->left_pipe.dst_roi);
|
|
||||||
if (hw_layers->config[i].right_pipe.valid) {
|
|
||||||
Log(kTagResources, "right pipe src", layer_config->right_pipe.src_roi);
|
|
||||||
Log(kTagResources, "right pipe dst", layer_config->right_pipe.dst_roi);
|
|
||||||
}
|
|
||||||
// set z_order, left_pipe should always be valid
|
|
||||||
left_pipe.z_order = z_order;
|
|
||||||
if (layer_config->right_pipe.valid) {
|
|
||||||
// use different z_order if 2 pipes are on one mixer and without src split support
|
|
||||||
if (!hw_res_info_.is_src_split &&
|
|
||||||
((left_pipe.dst_roi.right <= display_attributes.split_left &&
|
|
||||||
right_pipe.dst_roi.right <= display_attributes.split_left) ||
|
|
||||||
(left_pipe.dst_roi.left >= display_attributes.split_left &&
|
|
||||||
right_pipe.dst_roi.left >= display_attributes.split_left))) {
|
|
||||||
z_order++;
|
|
||||||
}
|
|
||||||
layer_config->right_pipe.z_order = z_order;
|
|
||||||
}
|
|
||||||
z_order++;
|
|
||||||
if (z_order > display_resource_ctx->max_mixer_stages) {
|
|
||||||
DLOGV_IF(kTagResources, "z_order is over the limit of max_mixer_stages = %d",
|
|
||||||
display_resource_ctx->max_mixer_stages);
|
|
||||||
return kErrorResources;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ResManager::CalculateCut(const LayerTransform &transform, float *left_cut_ratio,
|
|
||||||
float *top_cut_ratio, float *right_cut_ratio,
|
|
||||||
float *bottom_cut_ratio) {
|
|
||||||
if (transform.flip_horizontal) {
|
|
||||||
Swap(*left_cut_ratio, *right_cut_ratio);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (transform.flip_vertical) {
|
|
||||||
Swap(*top_cut_ratio, *bottom_cut_ratio);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsRotationNeeded(transform.rotation)) {
|
|
||||||
// Anti clock swapping
|
|
||||||
float tmp_cut_ratio = *left_cut_ratio;
|
|
||||||
*left_cut_ratio = *top_cut_ratio;
|
|
||||||
*top_cut_ratio = *right_cut_ratio;
|
|
||||||
*right_cut_ratio = *bottom_cut_ratio;
|
|
||||||
*bottom_cut_ratio = tmp_cut_ratio;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ResManager::CalculateCropRects(const LayerRect &scissor, const LayerTransform &transform,
|
|
||||||
LayerRect *crop, LayerRect *dst) {
|
|
||||||
float &crop_left = crop->left;
|
|
||||||
float &crop_top = crop->top;
|
|
||||||
float &crop_right = crop->right;
|
|
||||||
float &crop_bottom = crop->bottom;
|
|
||||||
float crop_width = crop->right - crop->left;
|
|
||||||
float crop_height = crop->bottom - crop->top;
|
|
||||||
|
|
||||||
float &dst_left = dst->left;
|
|
||||||
float &dst_top = dst->top;
|
|
||||||
float &dst_right = dst->right;
|
|
||||||
float &dst_bottom = dst->bottom;
|
|
||||||
float dst_width = dst->right - dst->left;
|
|
||||||
float dst_height = dst->bottom - dst->top;
|
|
||||||
|
|
||||||
const float &sci_left = scissor.left;
|
|
||||||
const float &sci_top = scissor.top;
|
|
||||||
const float &sci_right = scissor.right;
|
|
||||||
const float &sci_bottom = scissor.bottom;
|
|
||||||
|
|
||||||
float left_cut_ratio = 0.0, right_cut_ratio = 0.0, top_cut_ratio = 0.0, bottom_cut_ratio = 0.0;
|
|
||||||
bool need_cut = false;
|
|
||||||
|
|
||||||
if (dst_left < sci_left) {
|
|
||||||
left_cut_ratio = (sci_left - dst_left) / dst_width;
|
|
||||||
dst_left = sci_left;
|
|
||||||
need_cut = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dst_right > sci_right) {
|
|
||||||
right_cut_ratio = (dst_right - sci_right) / dst_width;
|
|
||||||
dst_right = sci_right;
|
|
||||||
need_cut = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dst_top < sci_top) {
|
|
||||||
top_cut_ratio = (sci_top - dst_top) / (dst_height);
|
|
||||||
dst_top = sci_top;
|
|
||||||
need_cut = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dst_bottom > sci_bottom) {
|
|
||||||
bottom_cut_ratio = (dst_bottom - sci_bottom) / (dst_height);
|
|
||||||
dst_bottom = sci_bottom;
|
|
||||||
need_cut = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!need_cut)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
CalculateCut(transform, &left_cut_ratio, &top_cut_ratio, &right_cut_ratio, &bottom_cut_ratio);
|
|
||||||
|
|
||||||
crop_left += crop_width * left_cut_ratio;
|
|
||||||
crop_top += crop_height * top_cut_ratio;
|
|
||||||
crop_right -= crop_width * right_cut_ratio;
|
|
||||||
crop_bottom -= crop_height * bottom_cut_ratio;
|
|
||||||
Normalize(1, 1, crop);
|
|
||||||
Normalize(1, 1, dst);
|
|
||||||
if (IsValid(*crop) && IsValid(*dst))
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError ResManager::ValidateLayerDimensions(const Layer &layer) {
|
|
||||||
const LayerRect &src = layer.src_rect;
|
|
||||||
const LayerRect &dst = layer.dst_rect;
|
|
||||||
LayerBuffer *input_buffer = layer.input_buffer;
|
|
||||||
|
|
||||||
if (!IsValid(src) || !IsValid(dst)) {
|
|
||||||
Log(kTagResources, "input layer src_rect", src);
|
|
||||||
Log(kTagResources, "input layer dst_rect", dst);
|
|
||||||
return kErrorNotSupported;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure source in integral only if it is a non secure layer.
|
|
||||||
if (!input_buffer->flags.secure && (src.left - roundf(src.left) || src.top - roundf(src.top) ||
|
|
||||||
src.right - roundf(src.right) || src.bottom - roundf(src.bottom))) {
|
|
||||||
DLOGV_IF(kTagResources, "Input ROI is not integral");
|
|
||||||
return kErrorNotSupported;
|
|
||||||
}
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError ResManager::ValidateDimensions(const LayerRect &crop, const LayerRect &dst,
|
|
||||||
bool rotated90) {
|
|
||||||
float crop_width = 0.0f, crop_height = 0.0f, dst_width = 0.0f, dst_height = 0.0f;
|
|
||||||
|
|
||||||
DisplayError error = GetCropAndDestination(crop, dst, rotated90, &crop_width, &crop_height,
|
|
||||||
&dst_width, &dst_height);
|
|
||||||
if (error != kErrorNone) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((dst_width < 1.0f) || (dst_height < 1.0f)) {
|
|
||||||
DLOGV_IF(kTagResources, "dst ROI is too small w = %.0f, h = %.0f, right = %.0f, bottom = %.0f",
|
|
||||||
dst_width, dst_height, dst.right, dst.bottom);
|
|
||||||
return kErrorNotSupported;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((crop_width < 1.0f) || (crop_height < 1.0f)) {
|
|
||||||
DLOGV_IF(kTagResources, "src ROI is too small w = %.0f, h = %.0f, right = %.0f, bottom = %.0f",
|
|
||||||
crop_width, crop_height, crop.right, crop.bottom);
|
|
||||||
return kErrorNotSupported;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((UINT32(crop_width - dst_width) == 1) || (UINT32(crop_height - dst_height) == 1)) {
|
|
||||||
DLOGV_IF(kTagResources, "One pixel downscaling detected crop_w = %.0f, dst_w = %.0f, " \
|
|
||||||
"crop_h = %.0f, dst_h = %.0f", crop_width, dst_width, crop_height, dst_height);
|
|
||||||
return kErrorNotSupported;
|
|
||||||
}
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError ResManager::ValidatePipeParams(HWPipeInfo *pipe_info) {
|
|
||||||
DisplayError error = kErrorNone;
|
|
||||||
|
|
||||||
const LayerRect &src_rect = pipe_info->src_roi;
|
|
||||||
const LayerRect &dst_rect = pipe_info->dst_roi;
|
|
||||||
|
|
||||||
error = ValidateDimensions(src_rect, dst_rect, false /* rotated90 */);
|
|
||||||
if (error != kErrorNone) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
error = ValidateScaling(src_rect, dst_rect, false /* rotated90 */);
|
|
||||||
if (error != kErrorNone) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError ResManager::ValidateScaling(const LayerRect &crop, const LayerRect &dst,
|
|
||||||
bool rotated90) {
|
|
||||||
DisplayError error = kErrorNone;
|
|
||||||
|
|
||||||
float scale_x = 1.0f;
|
|
||||||
float scale_y = 1.0f;
|
|
||||||
|
|
||||||
error = GetScaleFactor(crop, dst, rotated90, &scale_x, &scale_y);
|
|
||||||
if (error != kErrorNone) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
error = ValidateDownScaling(scale_x, scale_y);
|
|
||||||
if (error != kErrorNone) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
error = ValidateUpScaling(scale_x, scale_y);
|
|
||||||
if (error != kErrorNone) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError ResManager::ValidateDownScaling(float scale_x, float scale_y) {
|
|
||||||
if ((UINT32(scale_x) > 1) || (UINT32(scale_y) > 1)) {
|
|
||||||
float max_scale_down = FLOAT(hw_res_info_.max_scale_down);
|
|
||||||
float rotator_scale_factor = 1.0f;
|
|
||||||
|
|
||||||
if (hw_res_info_.has_rotator_downscale && !property_setting_.disable_rotator_downscaling) {
|
|
||||||
rotator_scale_factor = GetRotatorScaleFactor(scale_x, scale_y);
|
|
||||||
scale_x /= rotator_scale_factor;
|
|
||||||
scale_y /= rotator_scale_factor;
|
|
||||||
|
|
||||||
DLOGV_IF(kTagResources, "scale_x = %.4f, scale_y = %.4f, rotator_scale_factor = %d",
|
|
||||||
scale_x, scale_y, rotator_scale_factor);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hw_res_info_.has_decimation && !property_setting_.disable_decimation) {
|
|
||||||
max_scale_down *= FLOAT(kMaxDecimationDownScaleRatio);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scale_x > max_scale_down || scale_y > max_scale_down) {
|
|
||||||
DLOGV_IF(kTagResources,
|
|
||||||
"Scaling down is over the limit: scale_x = %.0f, scale_y = %.0f, " \
|
|
||||||
"has_deci = %d, disable_deci = %d, rotator_scale_factor= %.0f",
|
|
||||||
scale_x, scale_y, hw_res_info_.has_decimation, property_setting_.disable_decimation,
|
|
||||||
rotator_scale_factor);
|
|
||||||
return kErrorNotSupported;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DLOGV_IF(kTagResources, "scale_x = %.4f, scale_y = %.4f", scale_x, scale_y);
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError ResManager::ValidateUpScaling(float scale_x, float scale_y) {
|
|
||||||
float max_scale_up = FLOAT(hw_res_info_.max_scale_up);
|
|
||||||
|
|
||||||
if (UINT32(scale_x) < 1 && scale_x > 0.0f) {
|
|
||||||
if ((1.0f / scale_x) > max_scale_up) {
|
|
||||||
DLOGV_IF(kTagResources, "Scaling up is over limit scale_x = %f", 1.0f / scale_x);
|
|
||||||
return kErrorNotSupported;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (UINT32(scale_y) < 1 && scale_y > 0.0f) {
|
|
||||||
if ((1.0f / scale_y) > max_scale_up) {
|
|
||||||
DLOGV_IF(kTagResources, "Scaling up is over limit scale_y = %f", 1.0f / scale_y);
|
|
||||||
return kErrorNotSupported;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DLOGV_IF(kTagResources, "scale_x = %.4f, scale_y = %.4f", scale_x, scale_y);
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError ResManager::GetCropAndDestination(const LayerRect &crop, const LayerRect &dst,
|
|
||||||
const bool rotated90, float *crop_width,
|
|
||||||
float *crop_height, float *dst_width,
|
|
||||||
float *dst_height) {
|
|
||||||
if (!IsValid(crop)) {
|
|
||||||
Log(kTagResources, "Invalid crop rect", crop);
|
|
||||||
return kErrorNotSupported;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!IsValid(dst)) {
|
|
||||||
Log(kTagResources, "Invalid dst rect", dst);
|
|
||||||
return kErrorNotSupported;
|
|
||||||
}
|
|
||||||
|
|
||||||
*crop_width = crop.right - crop.left;
|
|
||||||
*crop_height = crop.bottom - crop.top;
|
|
||||||
if (rotated90) {
|
|
||||||
Swap(*crop_width, *crop_height);
|
|
||||||
}
|
|
||||||
|
|
||||||
*dst_width = dst.right - dst.left;
|
|
||||||
*dst_height = dst.bottom - dst.top;
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError ResManager::GetRotatorScaleFactor(const LayerRect &crop, const LayerRect &dst,
|
|
||||||
bool rotated90, float *rotator_scale_factor) {
|
|
||||||
DisplayError error = kErrorNone;
|
|
||||||
|
|
||||||
float scale_x = 1.0f;
|
|
||||||
float scale_y = 1.0f;
|
|
||||||
|
|
||||||
if (hw_res_info_.has_rotator_downscale && !property_setting_.disable_rotator_downscaling) {
|
|
||||||
error = GetScaleFactor(crop, dst, rotated90, &scale_x, &scale_y);
|
|
||||||
if (error != kErrorNone) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
*rotator_scale_factor = GetRotatorScaleFactor(scale_x, scale_y);
|
|
||||||
} else {
|
|
||||||
*rotator_scale_factor = 1.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
float ResManager::GetRotatorScaleFactor(float scale_x, float scale_y) {
|
|
||||||
float max_scale_down = FLOAT(hw_res_info_.max_scale_down);
|
|
||||||
float scale_min = MIN(scale_x, scale_y);
|
|
||||||
float scale_max = MAX(scale_x, scale_y);
|
|
||||||
uint32_t rotator_scale_factor = 1;
|
|
||||||
|
|
||||||
// use rotator to downscale when over the pipe scaling ability
|
|
||||||
if (UINT32(scale_min) >= 2 && scale_max > max_scale_down) {
|
|
||||||
// downscaling ratio needs be the same for both direction, use the smaller one.
|
|
||||||
rotator_scale_factor = 1 << UINT32(ceilf(log2f(scale_min / max_scale_down)));
|
|
||||||
if (rotator_scale_factor > kMaxRotateDownScaleRatio) {
|
|
||||||
rotator_scale_factor = kMaxRotateDownScaleRatio;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DLOGV_IF(kTagResources, "scale_x = %.4f, scale_y = %.4f, rotator_scale_factor = %d",
|
|
||||||
scale_x, scale_y, rotator_scale_factor);
|
|
||||||
|
|
||||||
return FLOAT(rotator_scale_factor);
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError ResManager::GetScaleFactor(const LayerRect &crop, const LayerRect &dst,
|
|
||||||
bool rotated90, float *scale_x, float *scale_y) {
|
|
||||||
float crop_width = 1.0f, crop_height = 1.0f, dst_width = 1.0f, dst_height = 1.0f;
|
|
||||||
|
|
||||||
DisplayError error = GetCropAndDestination(crop, dst, rotated90, &crop_width, &crop_height,
|
|
||||||
&dst_width, &dst_height);
|
|
||||||
if (error != kErrorNone) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
*scale_x = crop_width / dst_width;
|
|
||||||
*scale_y = crop_height / dst_height;
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError ResManager::SetDecimationFactor(HWPipeInfo *pipe) {
|
|
||||||
float src_h = pipe->src_roi.bottom - pipe->src_roi.top;
|
|
||||||
float dst_h = pipe->dst_roi.bottom - pipe->dst_roi.top;
|
|
||||||
float down_scale_h = src_h / dst_h;
|
|
||||||
|
|
||||||
float src_w = pipe->src_roi.right - pipe->src_roi.left;
|
|
||||||
float dst_w = pipe->dst_roi.right - pipe->dst_roi.left;
|
|
||||||
float down_scale_w = src_w / dst_w;
|
|
||||||
|
|
||||||
pipe->horizontal_decimation = 0;
|
|
||||||
pipe->vertical_decimation = 0;
|
|
||||||
|
|
||||||
if (CalculateDecimation(down_scale_w, &pipe->horizontal_decimation) != kErrorNone) {
|
|
||||||
return kErrorNotSupported;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CalculateDecimation(down_scale_h, &pipe->vertical_decimation) != kErrorNone) {
|
|
||||||
return kErrorNotSupported;
|
|
||||||
}
|
|
||||||
|
|
||||||
DLOGI_IF(kTagResources, "horizontal_decimation %d, vertical_decimation %d",
|
|
||||||
pipe->horizontal_decimation, pipe->vertical_decimation);
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ResManager::SplitRect(bool flip_horizontal, const LayerRect &src_rect,
|
|
||||||
const LayerRect &dst_rect, LayerRect *src_left, LayerRect *dst_left,
|
|
||||||
LayerRect *src_right, LayerRect *dst_right, uint32_t align_x) {
|
|
||||||
// Split rectangle horizontally and evenly into two.
|
|
||||||
float src_width = src_rect.right - src_rect.left;
|
|
||||||
float dst_width = dst_rect.right - dst_rect.left;
|
|
||||||
float src_width_ori = src_width;
|
|
||||||
src_width = ROUND_UP_ALIGN_DOWN(src_width / 2, align_x);
|
|
||||||
dst_width = ROUND_UP_ALIGN_DOWN(dst_width * src_width / src_width_ori, 1);
|
|
||||||
|
|
||||||
if (flip_horizontal) {
|
|
||||||
src_left->left = src_rect.right - src_width;
|
|
||||||
src_left->right = src_rect.right;
|
|
||||||
|
|
||||||
src_right->left = src_rect.left;
|
|
||||||
src_right->right = src_left->left;
|
|
||||||
} else {
|
|
||||||
src_left->left = src_rect.left;
|
|
||||||
src_left->right = src_rect.left + src_width;
|
|
||||||
|
|
||||||
src_right->left = src_left->right;
|
|
||||||
src_right->right = src_rect.right;
|
|
||||||
}
|
|
||||||
|
|
||||||
src_left->top = src_rect.top;
|
|
||||||
src_left->bottom = src_rect.bottom;
|
|
||||||
dst_left->top = dst_rect.top;
|
|
||||||
dst_left->bottom = dst_rect.bottom;
|
|
||||||
|
|
||||||
src_right->top = src_rect.top;
|
|
||||||
src_right->bottom = src_rect.bottom;
|
|
||||||
dst_right->top = dst_rect.top;
|
|
||||||
dst_right->bottom = dst_rect.bottom;
|
|
||||||
|
|
||||||
dst_left->left = dst_rect.left;
|
|
||||||
dst_left->right = dst_rect.left + dst_width;
|
|
||||||
dst_right->left = dst_left->right;
|
|
||||||
dst_right->right = dst_rect.right;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError ResManager::AlignPipeConfig(const Layer &layer, const LayerTransform &transform,
|
|
||||||
const HWLayers &hw_layers, HWPipeInfo *left_pipe,
|
|
||||||
HWPipeInfo *right_pipe, uint32_t align_x,
|
|
||||||
uint32_t align_y) {
|
|
||||||
DisplayError error = kErrorNone;
|
|
||||||
if (!left_pipe->valid) {
|
|
||||||
DLOGE_IF(kTagResources, "left_pipe should not be invalid");
|
|
||||||
return kErrorNotSupported;
|
|
||||||
}
|
|
||||||
// 1. Normalize video layer source rectangle to multiple of 2, as MDP hardware require source
|
|
||||||
// rectangle of video layer to be even.
|
|
||||||
// 2. Normalize source and destination rect of a layer to multiple of 1.
|
|
||||||
// TODO(user) Check buffer format and check if rotate is involved.
|
|
||||||
Normalize(align_x, align_y, &left_pipe->src_roi);
|
|
||||||
Normalize(1, 1, &left_pipe->dst_roi);
|
|
||||||
|
|
||||||
if (right_pipe->valid) {
|
|
||||||
Normalize(align_x, align_y, &right_pipe->src_roi);
|
|
||||||
Normalize(1, 1, &right_pipe->dst_roi);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure the left and right ROI are conjunct, then make pipes ROI conjunct.
|
|
||||||
if (right_pipe->valid &&
|
|
||||||
(!IsValid(hw_layers.info.right_partial_update) ||
|
|
||||||
(hw_layers.info.left_partial_update.right == hw_layers.info.right_partial_update.left))) {
|
|
||||||
if (transform.flip_horizontal) {
|
|
||||||
left_pipe->src_roi.left = right_pipe->src_roi.right;
|
|
||||||
} else {
|
|
||||||
right_pipe->src_roi.left = left_pipe->src_roi.right;
|
|
||||||
}
|
|
||||||
right_pipe->dst_roi.left = left_pipe->dst_roi.right;
|
|
||||||
}
|
|
||||||
|
|
||||||
error = ValidatePipeParams(left_pipe);
|
|
||||||
if (error != kErrorNone) {
|
|
||||||
goto PipeConfigExit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (right_pipe->valid) {
|
|
||||||
error = ValidatePipeParams(right_pipe);
|
|
||||||
}
|
|
||||||
PipeConfigExit:
|
|
||||||
if (error != kErrorNone) {
|
|
||||||
DLOGV_IF(kTagResources, "AlignPipeConfig failed");
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError ResManager::CalculateDecimation(float downscale, uint8_t *decimation) {
|
|
||||||
float max_down_scale = FLOAT(hw_res_info_.max_scale_down);
|
|
||||||
|
|
||||||
if (downscale <= max_down_scale) {
|
|
||||||
*decimation = 0;
|
|
||||||
return kErrorNone;
|
|
||||||
} else if (!hw_res_info_.has_decimation) {
|
|
||||||
DLOGE("Downscaling exceeds the maximum MDP downscale limit but decimation not enabled");
|
|
||||||
return kErrorNotSupported;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decimation is the remaining downscale factor after doing max SDE downscale.
|
|
||||||
// In SDE, decimation is supported in powers of 2.
|
|
||||||
// For ex: If a pipe needs downscale of 8 but max_down_scale is 4
|
|
||||||
// So decimation = powf(2.0, ceilf(log2f(8 / 4))) = powf(2.0, 1.0) = 2
|
|
||||||
*decimation = UINT8(ceilf(log2f(downscale / max_down_scale)));
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace sde
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,246 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014 - 2015, The Linux Foundation. All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
|
||||||
* provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
|
||||||
* conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright notice, this list of
|
|
||||||
* conditions and the following disclaimer in the documentation and/or other materials provided
|
|
||||||
* with the distribution.
|
|
||||||
* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
|
|
||||||
* endorse or promote products derived from this software without specific prior written
|
|
||||||
* permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
||||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|
||||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __RES_MANAGER_H__
|
|
||||||
#define __RES_MANAGER_H__
|
|
||||||
|
|
||||||
#include <core/display_interface.h>
|
|
||||||
#include <private/hw_info_types.h>
|
|
||||||
#include <utils/locker.h>
|
|
||||||
|
|
||||||
#include "hw_interface.h"
|
|
||||||
#include "dump_impl.h"
|
|
||||||
#include "scalar_helper.h"
|
|
||||||
|
|
||||||
namespace sde {
|
|
||||||
|
|
||||||
class ResManager : public DumpImpl {
|
|
||||||
public:
|
|
||||||
ResManager();
|
|
||||||
DisplayError Init(const HWResourceInfo &hw_res_info);
|
|
||||||
DisplayError Deinit();
|
|
||||||
DisplayError RegisterDisplay(DisplayType type, const HWDisplayAttributes &attributes,
|
|
||||||
const HWPanelInfo &hw_panel_info, Handle *display_ctx);
|
|
||||||
DisplayError UnregisterDisplay(Handle display_ctx);
|
|
||||||
void ReconfigureDisplay(Handle display_ctx, const HWDisplayAttributes &attributes,
|
|
||||||
const HWPanelInfo &hw_panel_info);
|
|
||||||
DisplayError Start(Handle display_ctx);
|
|
||||||
DisplayError Stop(Handle display_ctx);
|
|
||||||
DisplayError Acquire(Handle display_ctx, HWLayers *hw_layers);
|
|
||||||
DisplayError PostPrepare(Handle display_ctx, HWLayers *hw_layers);
|
|
||||||
DisplayError PostCommit(Handle display_ctx, HWLayers *hw_layers);
|
|
||||||
void Purge(Handle display_ctx);
|
|
||||||
DisplayError SetMaxMixerStages(Handle display_ctx, uint32_t max_mixer_stages);
|
|
||||||
DisplayError ValidateScaling(const LayerRect &crop, const LayerRect &dst, bool rotate90);
|
|
||||||
|
|
||||||
// DumpImpl method
|
|
||||||
virtual void AppendDump(char *buffer, uint32_t length);
|
|
||||||
|
|
||||||
private:
|
|
||||||
enum PipeId {
|
|
||||||
kPipeIdVIG0,
|
|
||||||
kPipeIdVIG1,
|
|
||||||
kPipeIdVIG2,
|
|
||||||
kPipeIdRGB0,
|
|
||||||
kPipeIdRGB1,
|
|
||||||
kPipeIdRGB2,
|
|
||||||
kPipeIdDMA0,
|
|
||||||
kPipeIdDMA1,
|
|
||||||
kPipeIdVIG3,
|
|
||||||
kPipeIdRGB3,
|
|
||||||
kPipeIdMax,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum PipeType {
|
|
||||||
kPipeTypeUnused,
|
|
||||||
kPipeTypeVIG,
|
|
||||||
kPipeTypeRGB,
|
|
||||||
kPipeTypeDMA,
|
|
||||||
kPipeTypeMax,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum PipeState {
|
|
||||||
kPipeStateIdle, // Pipe state when it is available for reservation
|
|
||||||
kPipeStateAcquired, // Pipe state after successful commit
|
|
||||||
kPipeStateToRelease, // Pipe state that can be moved to Idle when releasefence is signaled
|
|
||||||
kPipeStateOwnedByKernel, // Pipe state when pipe is owned by kernel
|
|
||||||
};
|
|
||||||
|
|
||||||
// todo: retrieve all these from kernel
|
|
||||||
enum {
|
|
||||||
kMaxInterfaceWidth = 2048,
|
|
||||||
kMaxRotateDownScaleRatio = 8,
|
|
||||||
kMaxDecimationDownScaleRatio = 8,
|
|
||||||
kMaxNumRotator = 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SourcePipe {
|
|
||||||
PipeType type;
|
|
||||||
uint32_t mdss_pipe_id;
|
|
||||||
uint32_t index;
|
|
||||||
PipeState state;
|
|
||||||
HWBlockType hw_block_id;
|
|
||||||
bool at_right;
|
|
||||||
uint64_t state_frame_count;
|
|
||||||
int priority;
|
|
||||||
HWBlockType reserved_hw_block;
|
|
||||||
HWBlockType dedicated_hw_block;
|
|
||||||
|
|
||||||
SourcePipe() : type(kPipeTypeUnused), mdss_pipe_id(kPipeIdMax), index(0),
|
|
||||||
state(kPipeStateIdle), hw_block_id(kHWBlockMax), at_right(false),
|
|
||||||
state_frame_count(0), priority(0), reserved_hw_block(kHWBlockMax),
|
|
||||||
dedicated_hw_block(kHWBlockMax) { }
|
|
||||||
|
|
||||||
inline void ResetState() { state = kPipeStateIdle; hw_block_id = kHWBlockMax;
|
|
||||||
at_right = false; reserved_hw_block = kHWBlockMax; dedicated_hw_block = kHWBlockMax; }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DisplayResourceContext {
|
|
||||||
HWDisplayAttributes display_attributes;
|
|
||||||
DisplayType display_type;
|
|
||||||
HWBlockType hw_block_id;
|
|
||||||
HWPanelInfo hw_panel_info_;
|
|
||||||
uint64_t frame_count;
|
|
||||||
int32_t session_id; // applicable for virtual display sessions only
|
|
||||||
uint32_t rotate_count;
|
|
||||||
bool frame_start;
|
|
||||||
uint32_t max_mixer_stages;
|
|
||||||
|
|
||||||
DisplayResourceContext() : hw_block_id(kHWBlockMax), frame_count(0), session_id(-1),
|
|
||||||
rotate_count(0), frame_start(false), max_mixer_stages(0) { }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct HWBlockContext {
|
|
||||||
bool is_in_use;
|
|
||||||
HWBlockContext() : is_in_use(false) { }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct HWRotator {
|
|
||||||
uint32_t pipe_index;
|
|
||||||
HWBlockType writeback_id;
|
|
||||||
uint32_t client_bit_mask;
|
|
||||||
uint32_t request_bit_mask;
|
|
||||||
HWRotator() : pipe_index(0), writeback_id(kHWBlockMax), client_bit_mask(0),
|
|
||||||
request_bit_mask(0) { }
|
|
||||||
|
|
||||||
inline void ClearState(HWBlockType block) { CLEAR_BIT(client_bit_mask, block);
|
|
||||||
CLEAR_BIT(request_bit_mask, block); }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PropertySetting {
|
|
||||||
bool disable_rotator_downscaling;
|
|
||||||
bool disable_decimation;
|
|
||||||
PropertySetting() : disable_rotator_downscaling(false), disable_decimation(false) { }
|
|
||||||
};
|
|
||||||
|
|
||||||
uint32_t GetMdssPipeId(PipeType pipe_type, uint32_t index);
|
|
||||||
uint32_t NextPipe(PipeType pipe_type, HWBlockType hw_block_id, bool at_right);
|
|
||||||
uint32_t SearchPipe(HWBlockType hw_block_id, SourcePipe *src_pipes, uint32_t num_pipe,
|
|
||||||
bool at_right);
|
|
||||||
uint32_t GetPipe(HWBlockType hw_block_id, bool is_yuv, bool need_scale, bool at_right,
|
|
||||||
bool use_non_dma_pipe);
|
|
||||||
bool IsScalingNeeded(const HWPipeInfo *pipe_info);
|
|
||||||
DisplayError Config(DisplayResourceContext *display_resource_ctx, HWLayers *hw_layers,
|
|
||||||
uint32_t *rotate_count);
|
|
||||||
DisplayError DisplaySplitConfig(DisplayResourceContext *display_resource_ctx,
|
|
||||||
const LayerTransform &transform,
|
|
||||||
const LayerRect &src_rect, const LayerRect &dst_rect,
|
|
||||||
const HWLayers &hw_layers, HWLayerConfig *layer_config,
|
|
||||||
uint32_t align_x);
|
|
||||||
DisplayError ValidateScaling(const Layer &layer, const LayerRect &crop,
|
|
||||||
const LayerRect &dst, float *rot_scale);
|
|
||||||
DisplayError SrcSplitConfig(DisplayResourceContext *display_resource_ctx,
|
|
||||||
const LayerTransform &transform, const LayerRect &src_rect,
|
|
||||||
const LayerRect &dst_rect, HWLayerConfig *layer_config,
|
|
||||||
uint32_t align_x);
|
|
||||||
void CalculateCut(const LayerTransform &transform, float *left_cut_ratio, float *top_cut_ratio,
|
|
||||||
float *right_cut_ratio, float *bottom_cut_ratio);
|
|
||||||
bool CalculateCropRects(const LayerRect &scissor, const LayerTransform &transform,
|
|
||||||
LayerRect *crop, LayerRect *dst);
|
|
||||||
DisplayError ValidateLayerDimensions(const Layer &layer);
|
|
||||||
DisplayError ValidateDimensions(const LayerRect &crop, const LayerRect &dst, bool rotate90);
|
|
||||||
DisplayError ValidatePipeParams(HWPipeInfo *pipe_info);
|
|
||||||
DisplayError ValidateDownScaling(float scale_x, float scale_y);
|
|
||||||
DisplayError ValidateUpScaling(float scale_x, float scale_y);
|
|
||||||
DisplayError GetCropAndDestination(const LayerRect &crop, const LayerRect &dst,
|
|
||||||
bool rotate90, float *crop_width, float *crop_height,
|
|
||||||
float *dst_width, float *dst_height);
|
|
||||||
DisplayError GetRotatorScaleFactor(const LayerRect &crop, const LayerRect &dst,
|
|
||||||
bool rotate90, float *rotator_scale_factor);
|
|
||||||
float GetRotatorScaleFactor(float scale_x, float scale_y);
|
|
||||||
DisplayError GetScaleFactor(const LayerRect &crop, const LayerRect &dst, bool rotate90,
|
|
||||||
float *scale_x, float *scale_y);
|
|
||||||
bool CheckBandwidth(DisplayResourceContext *display_ctx, HWLayers *hw_layers);
|
|
||||||
float GetPipeBw(DisplayResourceContext *display_ctx, HWPipeInfo *pipe, float bpp);
|
|
||||||
float GetClockForPipe(DisplayResourceContext *display_ctx, HWPipeInfo *pipe);
|
|
||||||
float GetOverlapBw(HWLayers *hw_layers, float *pipe_bw, bool left_mixer);
|
|
||||||
DisplayError SetDecimationFactor(HWPipeInfo *pipe);
|
|
||||||
float GetBpp(LayerBufferFormat format);
|
|
||||||
void SplitRect(bool flip_horizontal, const LayerRect &src_rect, const LayerRect &dst_rect,
|
|
||||||
LayerRect *src_left, LayerRect *dst_left, LayerRect *src_right,
|
|
||||||
LayerRect *dst_right, uint32_t align_x);
|
|
||||||
bool IsMacroTileFormat(const LayerBuffer *buffer) { return buffer->flags.macro_tile; }
|
|
||||||
bool IsRotationNeeded(float rotation)
|
|
||||||
{ return (UINT32(rotation) == 90 || UINT32(rotation) == 270); }
|
|
||||||
void RotationConfig(const Layer &layer, const float &downscale, LayerRect *src_rect,
|
|
||||||
HWLayerConfig *layer_config, uint32_t *rotate_count);
|
|
||||||
DisplayError AcquireRotator(DisplayResourceContext *display_resource_ctx,
|
|
||||||
const uint32_t roate_cnt);
|
|
||||||
void AssignRotator(HWRotateInfo *rotate, uint32_t *rotate_cnt);
|
|
||||||
void ClearRotator(DisplayResourceContext *display_resource_ctx);
|
|
||||||
void SetRotatorOutputFormat(const LayerBufferFormat &input_format, const bool &is_opaque,
|
|
||||||
const bool &rot90, const bool &downscale,
|
|
||||||
LayerBufferFormat *output_format);
|
|
||||||
DisplayError AlignPipeConfig(const Layer &layer, const LayerTransform &transform,
|
|
||||||
const HWLayers &hw_layers, HWPipeInfo *left_pipe,
|
|
||||||
HWPipeInfo *right_pipe, uint32_t align_x, uint32_t align_y);
|
|
||||||
void ResourceStateLog(void);
|
|
||||||
DisplayError CalculateDecimation(float downscale, uint8_t *decimation);
|
|
||||||
|
|
||||||
Locker locker_;
|
|
||||||
HWResourceInfo hw_res_info_;
|
|
||||||
HWBlockContext hw_block_ctx_[kHWBlockMax];
|
|
||||||
SourcePipe src_pipes_[kPipeIdMax];
|
|
||||||
uint32_t num_pipe_;
|
|
||||||
SourcePipe *vig_pipes_;
|
|
||||||
SourcePipe *rgb_pipes_;
|
|
||||||
SourcePipe *dma_pipes_;
|
|
||||||
bool frame_start_;
|
|
||||||
float bw_claimed_; // Bandwidth claimed by other display
|
|
||||||
float clk_claimed_; // Clock claimed by other display
|
|
||||||
float last_primary_bw_;
|
|
||||||
float max_system_bw_;
|
|
||||||
uint32_t virtual_count_;
|
|
||||||
struct HWRotator rotators_[kMaxNumRotator];
|
|
||||||
BufferAllocator *buffer_allocator_;
|
|
||||||
BufferSyncHandler *buffer_sync_handler_; // Pointer to buffer sync handler that was defined by
|
|
||||||
// the display engine's client
|
|
||||||
PropertySetting property_setting_;
|
|
||||||
Scalar *scalar_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace sde
|
|
||||||
|
|
||||||
#endif // __RES_MANAGER_H__
|
|
||||||
|
|
||||||
@@ -1,250 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014 - 2015, The Linux Foundation. All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
|
||||||
* provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
|
||||||
* conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright notice, this list of
|
|
||||||
* conditions and the following disclaimer in the documentation and/or other materials provided
|
|
||||||
* with the distribution.
|
|
||||||
* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
|
|
||||||
* endorse or promote products derived from this software without specific prior written
|
|
||||||
* permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
||||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|
||||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <utils/constants.h>
|
|
||||||
#include <utils/debug.h>
|
|
||||||
#include <utils/rect.h>
|
|
||||||
#include <core/buffer_allocator.h>
|
|
||||||
#include <core/buffer_sync_handler.h>
|
|
||||||
|
|
||||||
#include "rotator_ctrl.h"
|
|
||||||
#include "hw_rotator_interface.h"
|
|
||||||
#include "hw_interface.h"
|
|
||||||
#include "session_manager.h"
|
|
||||||
|
|
||||||
#define __CLASS__ "RotatorCtrl"
|
|
||||||
|
|
||||||
namespace sde {
|
|
||||||
|
|
||||||
RotatorCtrl::RotatorCtrl() : hw_rotator_intf_(NULL) {
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError RotatorCtrl::Init(BufferAllocator *buffer_allocator,
|
|
||||||
BufferSyncHandler *buffer_sync_handler) {
|
|
||||||
DisplayError error = kErrorNone;
|
|
||||||
|
|
||||||
error = HWRotatorInterface::Create(buffer_sync_handler, &hw_rotator_intf_);
|
|
||||||
if (error != kErrorNone) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
error = hw_rotator_intf_->Open();
|
|
||||||
if (error != kErrorNone) {
|
|
||||||
DLOGE("Failed to open rotator device");
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
session_manager_ = new SessionManager(hw_rotator_intf_, buffer_allocator, buffer_sync_handler);
|
|
||||||
if (session_manager_ == NULL) {
|
|
||||||
HWRotatorInterface::Destroy(hw_rotator_intf_);
|
|
||||||
return kErrorMemory;
|
|
||||||
}
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError RotatorCtrl::Deinit() {
|
|
||||||
DisplayError error = kErrorNone;
|
|
||||||
|
|
||||||
error = hw_rotator_intf_->Close();
|
|
||||||
if (error != kErrorNone) {
|
|
||||||
DLOGW("Failed to close rotator device");
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (session_manager_) {
|
|
||||||
delete session_manager_;
|
|
||||||
session_manager_ = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
HWRotatorInterface::Destroy(hw_rotator_intf_);
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError RotatorCtrl::RegisterDisplay(DisplayType type, Handle *display_ctx) {
|
|
||||||
DisplayRotatorContext *disp_rotator_ctx = new DisplayRotatorContext();
|
|
||||||
if (disp_rotator_ctx == NULL) {
|
|
||||||
return kErrorMemory;
|
|
||||||
}
|
|
||||||
|
|
||||||
disp_rotator_ctx->display_type = type;
|
|
||||||
*display_ctx = disp_rotator_ctx;
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RotatorCtrl::UnregisterDisplay(Handle display_ctx) {
|
|
||||||
DisplayRotatorContext *disp_rotator_ctx = reinterpret_cast<DisplayRotatorContext *>(display_ctx);
|
|
||||||
|
|
||||||
delete disp_rotator_ctx;
|
|
||||||
disp_rotator_ctx = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DisplayError RotatorCtrl::Prepare(Handle display_ctx, HWLayers *hw_layers) {
|
|
||||||
DisplayError error = kErrorNone;
|
|
||||||
|
|
||||||
DisplayRotatorContext *disp_rotator_ctx = reinterpret_cast<DisplayRotatorContext *>(display_ctx);
|
|
||||||
|
|
||||||
error = PrepareSessions(disp_rotator_ctx, hw_layers);
|
|
||||||
if (error != kErrorNone) {
|
|
||||||
DLOGE("Prepare rotator session failed for display %d", disp_rotator_ctx->display_type);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
error = hw_rotator_intf_->Validate(hw_layers);
|
|
||||||
if (error != kErrorNone) {
|
|
||||||
DLOGE("Rotator validation failed for display %d", disp_rotator_ctx->display_type);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError RotatorCtrl::Commit(Handle display_ctx, HWLayers *hw_layers) {
|
|
||||||
DisplayError error = kErrorNone;
|
|
||||||
|
|
||||||
DisplayRotatorContext *disp_rotator_ctx = reinterpret_cast<DisplayRotatorContext *>(display_ctx);
|
|
||||||
|
|
||||||
error = GetOutputBuffers(disp_rotator_ctx, hw_layers);
|
|
||||||
if (error != kErrorNone) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
error = hw_rotator_intf_->Commit(hw_layers);
|
|
||||||
if (error != kErrorNone) {
|
|
||||||
DLOGE("Rotator commit failed for display %d", disp_rotator_ctx->display_type);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError RotatorCtrl::PostCommit(Handle display_ctx, HWLayers *hw_layers) {
|
|
||||||
HWLayersInfo &hw_layer_info = hw_layers->info;
|
|
||||||
DisplayError error = kErrorNone;
|
|
||||||
DisplayRotatorContext *disp_rotator_ctx = reinterpret_cast<DisplayRotatorContext *>(display_ctx);
|
|
||||||
int client_id = INT(disp_rotator_ctx->display_type);
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < hw_layer_info.count; i++) {
|
|
||||||
Layer& layer = hw_layer_info.stack->layers[hw_layer_info.index[i]];
|
|
||||||
HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
|
|
||||||
|
|
||||||
if (!hw_rotator_session->hw_block_count) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
error = session_manager_->SetReleaseFd(client_id, hw_rotator_session);
|
|
||||||
if (error != kErrorNone) {
|
|
||||||
DLOGE("Rotator Post commit failed for display %d", disp_rotator_ctx->display_type);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError RotatorCtrl::Purge(Handle display_ctx, HWLayers *hw_layers) {
|
|
||||||
DisplayRotatorContext *disp_rotator_ctx = reinterpret_cast<DisplayRotatorContext *>(display_ctx);
|
|
||||||
int client_id = INT(disp_rotator_ctx->display_type);
|
|
||||||
|
|
||||||
session_manager_->Start(client_id);
|
|
||||||
|
|
||||||
return session_manager_->Stop(client_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError RotatorCtrl::PrepareSessions(DisplayRotatorContext *disp_rotator_ctx,
|
|
||||||
HWLayers *hw_layers) {
|
|
||||||
HWLayersInfo &hw_layer_info = hw_layers->info;
|
|
||||||
DisplayError error = kErrorNone;
|
|
||||||
int client_id = INT(disp_rotator_ctx->display_type);
|
|
||||||
|
|
||||||
session_manager_->Start(client_id);
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < hw_layer_info.count; i++) {
|
|
||||||
Layer& layer = hw_layer_info.stack->layers[hw_layer_info.index[i]];
|
|
||||||
HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
|
|
||||||
HWSessionConfig &hw_session_config = hw_rotator_session->hw_session_config;
|
|
||||||
HWRotateInfo *left_rotate = &hw_rotator_session->hw_rotate_info[0];
|
|
||||||
HWRotateInfo *right_rotate = &hw_rotator_session->hw_rotate_info[1];
|
|
||||||
|
|
||||||
if (!hw_rotator_session->hw_block_count) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
hw_session_config.src_width = UINT32(layer.src_rect.right - layer.src_rect.left);
|
|
||||||
hw_session_config.src_height = UINT32(layer.src_rect.bottom - layer.src_rect.top);
|
|
||||||
hw_session_config.src_format = layer.input_buffer->format;
|
|
||||||
|
|
||||||
LayerRect dst_rect = Union(left_rotate->dst_roi, right_rotate->dst_roi);
|
|
||||||
|
|
||||||
hw_session_config.dst_width = UINT32(dst_rect.right - dst_rect.left);
|
|
||||||
hw_session_config.dst_height = UINT32(dst_rect.bottom - dst_rect.top);
|
|
||||||
hw_session_config.dst_format = hw_rotator_session->output_buffer.format;
|
|
||||||
|
|
||||||
// Allocate two rotator output buffers by default for double buffering.
|
|
||||||
hw_session_config.buffer_count = kDoubleBuffering;
|
|
||||||
hw_session_config.secure = layer.input_buffer->flags.secure;
|
|
||||||
hw_session_config.frame_rate = layer.frame_rate;
|
|
||||||
|
|
||||||
error = session_manager_->OpenSession(client_id, hw_rotator_session);
|
|
||||||
if (error != kErrorNone) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
error = session_manager_->Stop(client_id);
|
|
||||||
if (error != kErrorNone) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError RotatorCtrl::GetOutputBuffers(DisplayRotatorContext *disp_rotator_ctx,
|
|
||||||
HWLayers *hw_layers) {
|
|
||||||
HWLayersInfo &hw_layer_info = hw_layers->info;
|
|
||||||
DisplayError error = kErrorNone;
|
|
||||||
int client_id = INT(disp_rotator_ctx->display_type);
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < hw_layer_info.count; i++) {
|
|
||||||
Layer& layer = hw_layer_info.stack->layers[hw_layer_info.index[i]];
|
|
||||||
HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
|
|
||||||
|
|
||||||
if (!hw_rotator_session->hw_block_count) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
error = session_manager_->GetNextBuffer(client_id, hw_rotator_session);
|
|
||||||
if (error != kErrorNone) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace sde
|
|
||||||
|
|
||||||
@@ -1,267 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
|
||||||
* provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
|
||||||
* conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright notice, this list of
|
|
||||||
* conditions and the following disclaimer in the documentation and/or other materials provided
|
|
||||||
* with the distribution.
|
|
||||||
* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
|
|
||||||
* endorse or promote products derived from this software without specific prior written
|
|
||||||
* permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
||||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|
||||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <dlfcn.h>
|
|
||||||
#include <utils/debug.h>
|
|
||||||
#include "scalar_helper.h"
|
|
||||||
|
|
||||||
#define __CLASS__ "ScalarHelper"
|
|
||||||
|
|
||||||
namespace sde {
|
|
||||||
|
|
||||||
#ifdef USES_SCALAR
|
|
||||||
ScalarHelper::ScalarHelper()
|
|
||||||
: scalar_library_name_("libscalar.so"), configure_scale_api_("configureScale"),
|
|
||||||
lib_scalar_(NULL), configure_scale_(NULL) {
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError ScalarHelper::Init() {
|
|
||||||
lib_scalar_ = dlopen(scalar_library_name_, RTLD_NOW);
|
|
||||||
if (lib_scalar_) {
|
|
||||||
void **scalar_func = reinterpret_cast<void **>(&configure_scale_);
|
|
||||||
*scalar_func = ::dlsym(lib_scalar_, configure_scale_api_);
|
|
||||||
if (!configure_scale_) {
|
|
||||||
DLOGE("Unable to find symbol for %s API!", configure_scale_api_);
|
|
||||||
dlclose(lib_scalar_);
|
|
||||||
return kErrorUndefined;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
DLOGW("Unable to load %s !", scalar_library_name_);
|
|
||||||
return kErrorNotSupported;
|
|
||||||
}
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScalarHelper::Deinit() {
|
|
||||||
if (lib_scalar_) {
|
|
||||||
dlclose(lib_scalar_);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper functions
|
|
||||||
void ScalarHelper::SetPipeInfo(const HWPipeInfo &hw_pipe, scalar::PipeInfo *pipe) {
|
|
||||||
pipe->id = hw_pipe.pipe_id;
|
|
||||||
pipe->horz_deci = hw_pipe.horizontal_decimation;
|
|
||||||
pipe->vert_deci = hw_pipe.vertical_decimation;
|
|
||||||
|
|
||||||
pipe->src_rect.x = UINT32(hw_pipe.src_roi.left);
|
|
||||||
pipe->src_rect.y = UINT32(hw_pipe.src_roi.top);
|
|
||||||
pipe->src_rect.w = UINT32(hw_pipe.src_roi.right) - pipe->src_rect.x;
|
|
||||||
pipe->src_rect.h = UINT32(hw_pipe.src_roi.bottom) - pipe->src_rect.y;
|
|
||||||
|
|
||||||
pipe->dst_rect.x = UINT32(hw_pipe.dst_roi.left);
|
|
||||||
pipe->dst_rect.y = UINT32(hw_pipe.dst_roi.top);
|
|
||||||
pipe->dst_rect.w = UINT32(hw_pipe.dst_roi.right) - pipe->dst_rect.x;
|
|
||||||
pipe->dst_rect.h = UINT32(hw_pipe.dst_roi.bottom) - pipe->dst_rect.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScalarHelper::UpdateSrcRoi(const scalar::PipeInfo &pipe, HWPipeInfo *hw_pipe) {
|
|
||||||
hw_pipe->src_roi.left = FLOAT(pipe.src_rect.x);
|
|
||||||
hw_pipe->src_roi.top = FLOAT(pipe.src_rect.y);
|
|
||||||
hw_pipe->src_roi.right = FLOAT(pipe.src_rect.x + pipe.src_rect.w);
|
|
||||||
hw_pipe->src_roi.bottom = FLOAT(pipe.src_rect.y + pipe.src_rect.h);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScalarHelper::SetScaleData(const scalar::PipeInfo &pipe, ScaleData *scale_data) {
|
|
||||||
scalar::Scale *scale = pipe.scale_data;
|
|
||||||
scale_data->src_width = pipe.src_width;
|
|
||||||
scale_data->src_height = pipe.src_height;
|
|
||||||
scale_data->enable_pixel_ext = scale->enable_pxl_ext;
|
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
HWPlane &plane = scale_data->plane[i];
|
|
||||||
plane.init_phase_x = scale->init_phase_x[i];
|
|
||||||
plane.phase_step_x = scale->phase_step_x[i];
|
|
||||||
plane.init_phase_y = scale->init_phase_y[i];
|
|
||||||
plane.phase_step_y = scale->phase_step_y[i];
|
|
||||||
|
|
||||||
plane.left.extension = scale->left.extension[i];
|
|
||||||
plane.left.overfetch = scale->left.overfetch[i];
|
|
||||||
plane.left.repeat = scale->left.repeat[i];
|
|
||||||
|
|
||||||
plane.top.extension = scale->top.extension[i];
|
|
||||||
plane.top.overfetch = scale->top.overfetch[i];
|
|
||||||
plane.top.repeat = scale->top.repeat[i];
|
|
||||||
|
|
||||||
plane.right.extension = scale->right.extension[i];
|
|
||||||
plane.right.overfetch = scale->right.overfetch[i];
|
|
||||||
plane.right.repeat = scale->right.repeat[i];
|
|
||||||
|
|
||||||
plane.bottom.extension = scale->bottom.extension[i];
|
|
||||||
plane.bottom.overfetch = scale->bottom.overfetch[i];
|
|
||||||
plane.bottom.repeat = scale->bottom.repeat[i];
|
|
||||||
|
|
||||||
plane.roi_width = scale->roi_width[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t ScalarHelper::GetScalarFormat(LayerBufferFormat source) {
|
|
||||||
uint32_t format = scalar::UNKNOWN_FORMAT;
|
|
||||||
|
|
||||||
switch (source) {
|
|
||||||
case kFormatARGB8888: format = scalar::ARGB_8888; break;
|
|
||||||
case kFormatRGBA8888: format = scalar::RGBA_8888; break;
|
|
||||||
case kFormatBGRA8888: format = scalar::BGRA_8888; break;
|
|
||||||
case kFormatXRGB8888: format = scalar::XRGB_8888; break;
|
|
||||||
case kFormatRGBX8888: format = scalar::RGBX_8888; break;
|
|
||||||
case kFormatBGRX8888: format = scalar::BGRX_8888; break;
|
|
||||||
case kFormatRGBA5551: format = scalar::RGBA_5551; break;
|
|
||||||
case kFormatRGBA4444: format = scalar::RGBA_4444; break;
|
|
||||||
case kFormatRGB888: format = scalar::RGB_888; break;
|
|
||||||
case kFormatBGR888: format = scalar::BGR_888; break;
|
|
||||||
case kFormatRGB565: format = scalar::RGB_565; break;
|
|
||||||
case kFormatYCbCr420Planar: format = scalar::Y_CB_CR_H2V2; break;
|
|
||||||
case kFormatYCrCb420Planar: format = scalar::Y_CR_CB_H2V2; break;
|
|
||||||
case kFormatYCbCr420SemiPlanar: format = scalar::Y_CBCR_H2V2; break;
|
|
||||||
case kFormatYCrCb420SemiPlanar: format = scalar::Y_CRCB_H2V2; break;
|
|
||||||
case kFormatYCbCr422H1V2SemiPlanar: format = scalar::Y_CBCR_H1V2; break;
|
|
||||||
case kFormatYCrCb422H1V2SemiPlanar: format = scalar::Y_CRCB_H1V2; break;
|
|
||||||
case kFormatYCbCr422H2V1SemiPlanar: format = scalar::Y_CBCR_H2V1; break;
|
|
||||||
case kFormatYCrCb422H2V1SemiPlanar: format = scalar::Y_CRCB_H2V1; break;
|
|
||||||
case kFormatYCbCr422H2V1Packed: format = scalar::YCBYCR_H2V1; break;
|
|
||||||
case kFormatYCbCr420SemiPlanarVenus: format = scalar::Y_CBCR_H2V2_VENUS; break;
|
|
||||||
case kFormatRGBA8888Ubwc: format = scalar::RGBA_8888_UBWC; break;
|
|
||||||
case kFormatRGBX8888Ubwc: format = scalar::RGBX_8888_UBWC; break;
|
|
||||||
case kFormatRGB565Ubwc: format = scalar::RGB_565_UBWC; break;
|
|
||||||
case kFormatYCbCr420SPVenusUbwc: format = scalar::Y_CBCR_H2V2_UBWC; break;
|
|
||||||
default:
|
|
||||||
DLOGE("Unsupported source format: %x", source);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return format;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError ScalarHelper::ConfigureScale(HWLayers *hw_layers) {
|
|
||||||
HWLayersInfo &hw_layer_info = hw_layers->info;
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < hw_layer_info.count; i++) {
|
|
||||||
Layer &layer = hw_layer_info.stack->layers[hw_layer_info.index[i]];
|
|
||||||
uint32_t width = layer.input_buffer->width;
|
|
||||||
uint32_t height = layer.input_buffer->height;
|
|
||||||
LayerBufferFormat format = layer.input_buffer->format;
|
|
||||||
HWPipeInfo &left_pipe = hw_layers->config[i].left_pipe;
|
|
||||||
HWPipeInfo &right_pipe = hw_layers->config[i].right_pipe;
|
|
||||||
HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
|
|
||||||
|
|
||||||
// Reset scale data
|
|
||||||
memset(&left_pipe.scale_data, 0, sizeof(ScaleData));
|
|
||||||
memset(&right_pipe.scale_data, 0, sizeof(ScaleData));
|
|
||||||
|
|
||||||
// Prepare data structure for lib scalar
|
|
||||||
uint32_t flags = 0;
|
|
||||||
struct scalar::LayerInfo layer_info;
|
|
||||||
struct scalar::Scale left_scale, right_scale;
|
|
||||||
|
|
||||||
if (layer.transform.rotation == 90.0f) {
|
|
||||||
// Flips will be taken care by rotator, if layer requires 90 rotation
|
|
||||||
flags |= scalar::SCALAR_SOURCE_ROTATED_90;
|
|
||||||
} else {
|
|
||||||
flags |= layer.transform.flip_vertical ? scalar::SCALAR_FLIP_UD : 0;
|
|
||||||
flags |= layer.transform.flip_horizontal ? scalar::SCALAR_FLIP_LR : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint32_t count = 0; count < 2; count++) {
|
|
||||||
const HWPipeInfo &hw_pipe = (count == 0) ? left_pipe : right_pipe;
|
|
||||||
HWRotateInfo* hw_rotate_info = &hw_rotator_session->hw_rotate_info[count];
|
|
||||||
scalar::PipeInfo* pipe = (count == 0) ? &layer_info.left_pipe : &layer_info.right_pipe;
|
|
||||||
|
|
||||||
if (hw_rotate_info->valid) {
|
|
||||||
width = UINT32(hw_rotate_info->dst_roi.right - hw_rotate_info->dst_roi.left);
|
|
||||||
height = UINT32(hw_rotate_info->dst_roi.bottom - hw_rotate_info->dst_roi.top);
|
|
||||||
format = hw_rotator_session->output_buffer.format;
|
|
||||||
}
|
|
||||||
|
|
||||||
pipe->flags = flags;
|
|
||||||
pipe->scale_data = (count == 0) ? &left_scale : &right_scale;
|
|
||||||
pipe->src_width = width;
|
|
||||||
pipe->src_height = height;
|
|
||||||
SetPipeInfo(hw_pipe, pipe);
|
|
||||||
}
|
|
||||||
layer_info.src_format = GetScalarFormat(format);
|
|
||||||
|
|
||||||
DLOGV_IF(kTagScalar, "Scalar Input[%d] flags=%x format=%x", i, flags, layer_info.src_format);
|
|
||||||
DLOGV_IF(kTagScalar, "Left: id=%d hD=%d vD=%d srcRect=[%d %d %d %d] dstRect=[%d %d %d %d]",
|
|
||||||
layer_info.left_pipe.id, layer_info.left_pipe.horz_deci, layer_info.left_pipe.vert_deci,
|
|
||||||
layer_info.left_pipe.src_rect.x, layer_info.left_pipe.src_rect.y,
|
|
||||||
layer_info.left_pipe.src_rect.w, layer_info.left_pipe.src_rect.h,
|
|
||||||
layer_info.left_pipe.dst_rect.x, layer_info.left_pipe.dst_rect.y,
|
|
||||||
layer_info.left_pipe.dst_rect.w, layer_info.left_pipe.dst_rect.h);
|
|
||||||
DLOGV_IF(kTagScalar, "Right: id=%d hD=%d vD=%d srcRect=[%d %d %d %d] dstRect=[%d %d %d %d]",
|
|
||||||
layer_info.right_pipe.id, layer_info.right_pipe.horz_deci, layer_info.right_pipe.vert_deci,
|
|
||||||
layer_info.right_pipe.src_rect.x, layer_info.right_pipe.src_rect.y,
|
|
||||||
layer_info.right_pipe.src_rect.w, layer_info.right_pipe.src_rect.h,
|
|
||||||
layer_info.right_pipe.dst_rect.x, layer_info.right_pipe.dst_rect.y,
|
|
||||||
layer_info.right_pipe.dst_rect.w, layer_info.right_pipe.dst_rect.h);
|
|
||||||
|
|
||||||
// Configure scale data structure
|
|
||||||
if (configure_scale_(&layer_info) < 0) {
|
|
||||||
DLOGE("Scalar library failed to configure scale data!");
|
|
||||||
return kErrorParameters;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set ScaleData and update SrcRoi in HWPipeInfo
|
|
||||||
if (left_scale.enable_pxl_ext) {
|
|
||||||
SetScaleData(layer_info.left_pipe, &left_pipe.scale_data);
|
|
||||||
UpdateSrcRoi(layer_info.left_pipe, &left_pipe);
|
|
||||||
}
|
|
||||||
if (right_scale.enable_pxl_ext) {
|
|
||||||
SetScaleData(layer_info.right_pipe, &right_pipe.scale_data);
|
|
||||||
UpdateSrcRoi(layer_info.right_pipe, &right_pipe);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
DisplayError Scalar::CreateScalar(Scalar **scalar) {
|
|
||||||
Scalar *scalar_obj = NULL;
|
|
||||||
|
|
||||||
#ifdef USES_SCALAR
|
|
||||||
scalar_obj = new ScalarHelper();
|
|
||||||
if (scalar_obj) {
|
|
||||||
if (scalar_obj->Init() == kErrorNone) {
|
|
||||||
goto OnSuccess;
|
|
||||||
} else {
|
|
||||||
delete scalar_obj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
scalar_obj = new Scalar();
|
|
||||||
if (!scalar_obj) {
|
|
||||||
return kErrorMemory;
|
|
||||||
}
|
|
||||||
|
|
||||||
OnSuccess:
|
|
||||||
*scalar = scalar_obj;
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Scalar::Destroy(Scalar *scalar) {
|
|
||||||
scalar->Deinit();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace sde
|
|
||||||
@@ -1,364 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are
|
|
||||||
* met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above
|
|
||||||
* copyright notice, this list of conditions and the following
|
|
||||||
* disclaimer in the documentation and/or other materials provided
|
|
||||||
* with the distribution.
|
|
||||||
* * Neither the name of The Linux Foundation nor the names of its
|
|
||||||
* contributors may be used to endorse or promote products derived
|
|
||||||
* from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
|
||||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
|
||||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|
||||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
||||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
|
||||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
|
||||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <utils/debug.h>
|
|
||||||
#include <utils/constants.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
#include "session_manager.h"
|
|
||||||
#include "hw_rotator_interface.h"
|
|
||||||
|
|
||||||
#define __CLASS__ "SessionManager"
|
|
||||||
|
|
||||||
namespace sde {
|
|
||||||
|
|
||||||
// SessionManager State Transition
|
|
||||||
// *******************************************************
|
|
||||||
// Current State * Next State
|
|
||||||
// *****************************************
|
|
||||||
// * RELEASED READY ACQUIRED
|
|
||||||
// *******************************************************
|
|
||||||
// RELEASED * NA NA OpenSession()
|
|
||||||
// READY * Stop() NA OpenSession()
|
|
||||||
// ACQUIRED * NA Start() NA
|
|
||||||
//********************************************************
|
|
||||||
|
|
||||||
// ------------------------------- SessionManager Implementation -----------------------------------
|
|
||||||
|
|
||||||
SessionManager::SessionManager(HWRotatorInterface *hw_rotator_intf,
|
|
||||||
BufferAllocator *buffer_allocator,
|
|
||||||
BufferSyncHandler *buffer_sync_handler)
|
|
||||||
: hw_rotator_intf_(hw_rotator_intf), buffer_allocator_(buffer_allocator),
|
|
||||||
buffer_sync_handler_(buffer_sync_handler), active_session_count_(0) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void SessionManager::Start(const int &client_id) {
|
|
||||||
SCOPE_LOCK(locker_);
|
|
||||||
|
|
||||||
uint32_t session_count = 0;
|
|
||||||
uint32_t acquired_session_count = 0;
|
|
||||||
|
|
||||||
// Change the state of acquired session to kSessionReady
|
|
||||||
while ((acquired_session_count < active_session_count_) && (session_count < kMaxSessionCount)) {
|
|
||||||
if (session_list_[session_count].state == kSessionAcquired) {
|
|
||||||
if (session_list_[session_count].client_id == client_id) {
|
|
||||||
session_list_[session_count].state = kSessionReady;
|
|
||||||
}
|
|
||||||
acquired_session_count++;
|
|
||||||
}
|
|
||||||
session_count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError SessionManager::OpenSession(const int &client_id,
|
|
||||||
HWRotatorSession *hw_rotator_session) {
|
|
||||||
SCOPE_LOCK(locker_);
|
|
||||||
|
|
||||||
DisplayError error = kErrorNone;
|
|
||||||
|
|
||||||
const HWSessionConfig &input_config = hw_rotator_session->hw_session_config;
|
|
||||||
|
|
||||||
DLOGI_IF(kTagRotator, "Src buffer: width = %d, height = %d, format = %d",
|
|
||||||
input_config.src_width, input_config.src_height, input_config.src_format);
|
|
||||||
DLOGI_IF(kTagRotator, "Dst buffer: width = %d, height = %d, format = %d",
|
|
||||||
input_config.dst_width, input_config.dst_height, input_config.dst_format);
|
|
||||||
DLOGI_IF(kTagRotator, "buffer_count = %d, secure = %d, cache = %d, frame_rate = %d",
|
|
||||||
input_config.buffer_count, input_config.secure, input_config.cache,
|
|
||||||
input_config.frame_rate);
|
|
||||||
|
|
||||||
uint32_t free_session = active_session_count_;
|
|
||||||
uint32_t acquired_session = kMaxSessionCount;
|
|
||||||
uint32_t active_session_count = 0;
|
|
||||||
|
|
||||||
// First look for a session in ready state, if no session found in ready state matching
|
|
||||||
// with current input session config, assign a session in released state.
|
|
||||||
for (uint32_t session_count = 0; session_count < kMaxSessionCount &&
|
|
||||||
active_session_count < active_session_count_; session_count++) {
|
|
||||||
HWSessionConfig &hw_session_config =
|
|
||||||
session_list_[session_count].hw_rotator_session.hw_session_config;
|
|
||||||
|
|
||||||
if (session_list_[session_count].state == kSessionReleased) {
|
|
||||||
free_session = session_count;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (session_list_[session_count].state == kSessionReady) {
|
|
||||||
if (session_list_[session_count].client_id == client_id &&
|
|
||||||
input_config == hw_session_config) {
|
|
||||||
session_list_[session_count].state = kSessionAcquired;
|
|
||||||
acquired_session = session_count;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
active_session_count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the input config does not match with existing config, then add new session and change the
|
|
||||||
// state to kSessionAcquired
|
|
||||||
if (acquired_session == kMaxSessionCount) {
|
|
||||||
if (free_session >= kMaxSessionCount) {
|
|
||||||
return kErrorMemory;
|
|
||||||
}
|
|
||||||
|
|
||||||
error = AcquireSession(hw_rotator_session, &session_list_[free_session]);
|
|
||||||
if (error !=kErrorNone) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
acquired_session = free_session;
|
|
||||||
hw_rotator_session->session_id = acquired_session;
|
|
||||||
session_list_[acquired_session].client_id = client_id;
|
|
||||||
active_session_count_++;
|
|
||||||
|
|
||||||
DLOGV_IF(kTagRotator, "Acquire new session Output: width = %d, height = %d, format = %d, " \
|
|
||||||
"session_id %d, client_id %d", hw_rotator_session->output_buffer.width,
|
|
||||||
hw_rotator_session->output_buffer.height, hw_rotator_session->output_buffer.format,
|
|
||||||
hw_rotator_session->session_id, client_id);
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
*hw_rotator_session = session_list_[acquired_session].hw_rotator_session;
|
|
||||||
|
|
||||||
DLOGV_IF(kTagRotator, "Acquire existing session Output: width = %d, height = %d, format = %d, " \
|
|
||||||
"session_id %d, client_id %d", hw_rotator_session->output_buffer.width,
|
|
||||||
hw_rotator_session->output_buffer.height, hw_rotator_session->output_buffer.format,
|
|
||||||
hw_rotator_session->session_id, client_id);
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError SessionManager::GetNextBuffer(const int &client_id,
|
|
||||||
HWRotatorSession *hw_rotator_session) {
|
|
||||||
SCOPE_LOCK(locker_);
|
|
||||||
|
|
||||||
DisplayError error = kErrorNone;
|
|
||||||
|
|
||||||
int session_id = hw_rotator_session->session_id;
|
|
||||||
if (session_id > kMaxSessionCount) {
|
|
||||||
return kErrorParameters;
|
|
||||||
}
|
|
||||||
|
|
||||||
Session *session = &session_list_[session_id];
|
|
||||||
if (session->state != kSessionAcquired) {
|
|
||||||
DLOGE("Invalid session state %d", session->state);
|
|
||||||
return kErrorParameters;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t curr_index = session->curr_index;
|
|
||||||
|
|
||||||
BufferInfo *buffer_info = &session->buffer_info;
|
|
||||||
if (buffer_info->alloc_buffer_info.fd < 0) {
|
|
||||||
const uint32_t &buffer_count = buffer_info->buffer_config.buffer_count;
|
|
||||||
const size_t &buffer_size = buffer_info->alloc_buffer_info.size;
|
|
||||||
|
|
||||||
error = buffer_allocator_->AllocateBuffer(buffer_info);
|
|
||||||
if (error != kErrorNone) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint32_t idx = 0; idx < buffer_count; idx++) {
|
|
||||||
session->offset[idx] = UINT32((buffer_size / buffer_count) * idx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait for the release fence fd before the session being given to the client.
|
|
||||||
buffer_sync_handler_->SyncWait(session->release_fd[curr_index]);
|
|
||||||
close(session->release_fd[curr_index]);
|
|
||||||
session->release_fd[curr_index] = -1;
|
|
||||||
|
|
||||||
hw_rotator_session->output_buffer.planes[0].stride = buffer_info->alloc_buffer_info.stride;
|
|
||||||
hw_rotator_session->output_buffer.planes[0].fd = buffer_info->alloc_buffer_info.fd;
|
|
||||||
hw_rotator_session->output_buffer.planes[0].offset = session->offset[curr_index];
|
|
||||||
|
|
||||||
session->hw_rotator_session = *hw_rotator_session;
|
|
||||||
|
|
||||||
DLOGI_IF(kTagRotator, "Output: width = %d, height = %d, format = %d, stride %d, " \
|
|
||||||
"curr_index = %d, offset %d, fd %d, session_id %d, client_id %d",
|
|
||||||
hw_rotator_session->output_buffer.width, hw_rotator_session->output_buffer.height,
|
|
||||||
hw_rotator_session->output_buffer.format,
|
|
||||||
hw_rotator_session->output_buffer.planes[0].stride, curr_index,
|
|
||||||
hw_rotator_session->output_buffer.planes[0].offset,
|
|
||||||
hw_rotator_session->output_buffer.planes[0].fd, session_id, client_id);
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError SessionManager::Stop(const int &client_id) {
|
|
||||||
SCOPE_LOCK(locker_);
|
|
||||||
|
|
||||||
DisplayError error = kErrorNone;
|
|
||||||
uint32_t session_id = 0;
|
|
||||||
|
|
||||||
// Release all the sessions which were not acquired in the current cycle and deallocate the
|
|
||||||
// buffers associated with it.
|
|
||||||
while ((active_session_count_ > 0) && (session_id < kMaxSessionCount)) {
|
|
||||||
if (session_list_[session_id].state == kSessionReady &&
|
|
||||||
session_list_[session_id].client_id == client_id) {
|
|
||||||
error = ReleaseSession(&session_list_[session_id]);
|
|
||||||
if (error != kErrorNone) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
active_session_count_--;
|
|
||||||
|
|
||||||
DLOGI_IF(kTagRotator, "session_id = %d, active_session_count = %d, client_id %d", session_id,
|
|
||||||
active_session_count_, client_id);
|
|
||||||
}
|
|
||||||
session_id++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError SessionManager::SetReleaseFd(const int &client_id,
|
|
||||||
HWRotatorSession *hw_rotator_session) {
|
|
||||||
SCOPE_LOCK(locker_);
|
|
||||||
|
|
||||||
int session_id = hw_rotator_session->session_id;
|
|
||||||
if (session_id > kMaxSessionCount) {
|
|
||||||
return kErrorParameters;
|
|
||||||
}
|
|
||||||
|
|
||||||
Session *session = &session_list_[session_id];
|
|
||||||
if (session->state != kSessionAcquired) {
|
|
||||||
DLOGE("Invalid session state %d", session->state);
|
|
||||||
return kErrorParameters;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t &curr_index = session->curr_index;
|
|
||||||
uint32_t buffer_count = hw_rotator_session->hw_session_config.buffer_count;
|
|
||||||
|
|
||||||
// 1. Store the release fence fd, so that session manager waits for the release fence fd
|
|
||||||
// to be signaled and populates the session info to the client.
|
|
||||||
// 2. Modify the curr_index to point to next buffer.
|
|
||||||
session->release_fd[curr_index] = hw_rotator_session->output_buffer.release_fence_fd;
|
|
||||||
|
|
||||||
curr_index = (curr_index + 1) % buffer_count;
|
|
||||||
|
|
||||||
DLOGI_IF(kTagRotator, "session_id %d, curr_index = %d, release fd %d, client_id %d", session_id,
|
|
||||||
curr_index, hw_rotator_session->output_buffer.release_fence_fd, client_id);
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError SessionManager::AcquireSession(HWRotatorSession *hw_rotator_session,
|
|
||||||
Session *session) {
|
|
||||||
DisplayError error = kErrorNone;
|
|
||||||
const HWSessionConfig &input_config = hw_rotator_session->hw_session_config;
|
|
||||||
|
|
||||||
error = hw_rotator_intf_->OpenSession(hw_rotator_session);
|
|
||||||
if (error != kErrorNone) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
hw_rotator_session->output_buffer = LayerBuffer();
|
|
||||||
hw_rotator_session->output_buffer.width = input_config.dst_width;
|
|
||||||
hw_rotator_session->output_buffer.height = input_config.dst_height;
|
|
||||||
hw_rotator_session->output_buffer.format = input_config.dst_format;
|
|
||||||
hw_rotator_session->output_buffer.flags.secure = input_config.secure;
|
|
||||||
|
|
||||||
uint32_t buffer_count = hw_rotator_session->hw_session_config.buffer_count;
|
|
||||||
|
|
||||||
session->release_fd = new int[buffer_count];
|
|
||||||
if (session->release_fd == NULL) {
|
|
||||||
return kErrorMemory;
|
|
||||||
}
|
|
||||||
|
|
||||||
session->offset = new uint32_t[buffer_count];
|
|
||||||
if (session->offset == NULL) {
|
|
||||||
delete[] session->release_fd;
|
|
||||||
session->release_fd = NULL;
|
|
||||||
return kErrorMemory;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint32_t idx = 0; idx < buffer_count; idx++) {
|
|
||||||
session->release_fd[idx] = -1;
|
|
||||||
session->offset[idx] = 0;
|
|
||||||
}
|
|
||||||
session->curr_index = 0;
|
|
||||||
|
|
||||||
session->hw_rotator_session = HWRotatorSession();
|
|
||||||
session->buffer_info = BufferInfo();
|
|
||||||
|
|
||||||
BufferInfo *buffer_info = &session->buffer_info;
|
|
||||||
buffer_info->buffer_config.buffer_count = hw_rotator_session->hw_session_config.buffer_count;
|
|
||||||
buffer_info->buffer_config.secure = hw_rotator_session->hw_session_config.secure;
|
|
||||||
buffer_info->buffer_config.cache = hw_rotator_session->hw_session_config.cache;
|
|
||||||
buffer_info->buffer_config.width = hw_rotator_session->hw_session_config.dst_width;
|
|
||||||
buffer_info->buffer_config.height = hw_rotator_session->hw_session_config.dst_height;
|
|
||||||
buffer_info->buffer_config.format = hw_rotator_session->hw_session_config.dst_format;
|
|
||||||
|
|
||||||
session->state = kSessionAcquired;
|
|
||||||
session->hw_rotator_session = *hw_rotator_session;
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError SessionManager::ReleaseSession(Session *session) {
|
|
||||||
DisplayError error = kErrorNone;
|
|
||||||
|
|
||||||
BufferInfo *buffer_info = &session->buffer_info;
|
|
||||||
|
|
||||||
error = buffer_allocator_->FreeBuffer(buffer_info);
|
|
||||||
if (error != kErrorNone) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
error = hw_rotator_intf_->CloseSession(&session->hw_rotator_session);
|
|
||||||
if (error != kErrorNone) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t buffer_count = buffer_info->buffer_config.buffer_count;
|
|
||||||
|
|
||||||
for (uint32_t idx = 0; idx < buffer_count; idx++) {
|
|
||||||
if (session->release_fd[idx] >= 0) {
|
|
||||||
close(session->release_fd[idx]);
|
|
||||||
session->release_fd[idx] = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
session->state = kSessionReleased;
|
|
||||||
session->client_id == -1;
|
|
||||||
|
|
||||||
if (session->offset) {
|
|
||||||
delete[] session->offset;
|
|
||||||
session->offset = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (session->release_fd) {
|
|
||||||
delete[] session->release_fd;
|
|
||||||
session->release_fd = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace sde
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are
|
|
||||||
* met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above
|
|
||||||
* copyright notice, this list of conditions and the following
|
|
||||||
* disclaimer in the documentation and/or other materials provided
|
|
||||||
* with the distribution.
|
|
||||||
* * Neither the name of The Linux Foundation nor the names of its
|
|
||||||
* contributors may be used to endorse or promote products derived
|
|
||||||
* from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
|
||||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
|
||||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|
||||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
||||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
|
||||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
|
||||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __SESSION_MANAGER_H__
|
|
||||||
#define __SESSION_MANAGER_H__
|
|
||||||
|
|
||||||
#include <utils/locker.h>
|
|
||||||
#include <core/buffer_allocator.h>
|
|
||||||
#include "hw_interface.h"
|
|
||||||
|
|
||||||
namespace sde {
|
|
||||||
|
|
||||||
class HWRotatorInterface;
|
|
||||||
|
|
||||||
class SessionManager {
|
|
||||||
public:
|
|
||||||
SessionManager(HWRotatorInterface *hw_intf, BufferAllocator *buffer_allocator,
|
|
||||||
BufferSyncHandler *buffer_sync_handler);
|
|
||||||
|
|
||||||
void Start(const int &client_id);
|
|
||||||
DisplayError Stop(const int &client_id);
|
|
||||||
DisplayError OpenSession(const int &client_id, HWRotatorSession *hw_rotator_session);
|
|
||||||
DisplayError GetNextBuffer(const int &client_id, HWRotatorSession *hw_rotator_session);
|
|
||||||
DisplayError SetReleaseFd(const int &client_id, HWRotatorSession *hw_rotator_session);
|
|
||||||
|
|
||||||
private:
|
|
||||||
// TODO(user): Read from hw capability instead of hardcoding
|
|
||||||
static const int kMaxSessionCount = 32;
|
|
||||||
|
|
||||||
enum SessionState {
|
|
||||||
kSessionReleased = 0,
|
|
||||||
kSessionReady = 1,
|
|
||||||
kSessionAcquired = 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Session {
|
|
||||||
HWRotatorSession hw_rotator_session;
|
|
||||||
BufferInfo buffer_info;
|
|
||||||
SessionState state;
|
|
||||||
int *release_fd;
|
|
||||||
uint32_t *offset;
|
|
||||||
uint32_t curr_index;
|
|
||||||
int client_id;
|
|
||||||
|
|
||||||
Session() : state(kSessionReleased), release_fd(NULL), offset(NULL), curr_index(0),
|
|
||||||
client_id(-1) { }
|
|
||||||
};
|
|
||||||
|
|
||||||
DisplayError AcquireSession(HWRotatorSession *hw_rotator_session, Session *session);
|
|
||||||
DisplayError ReleaseSession(Session *session);
|
|
||||||
|
|
||||||
Locker locker_;
|
|
||||||
Session session_list_[kMaxSessionCount];
|
|
||||||
HWRotatorInterface *hw_rotator_intf_;
|
|
||||||
BufferAllocator *buffer_allocator_;
|
|
||||||
BufferSyncHandler *buffer_sync_handler_;
|
|
||||||
uint32_t active_session_count_; // number of sessions in ready/acquired state.
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace sde
|
|
||||||
|
|
||||||
#endif // __SESSION_MANAGER_H__
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,142 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014, The Linux Foundation. All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
|
||||||
* provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
|
||||||
* conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright notice, this list of
|
|
||||||
* conditions and the following disclaimer in the documentation and/or other materials provided
|
|
||||||
* with the distribution.
|
|
||||||
* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
|
|
||||||
* endorse or promote products derived from this software without specific prior written
|
|
||||||
* permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
||||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|
||||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <utils/constants.h>
|
|
||||||
#include <utils/debug.h>
|
|
||||||
|
|
||||||
#include "strategy_default.h"
|
|
||||||
|
|
||||||
#define __CLASS__ "StrategyDefault"
|
|
||||||
|
|
||||||
namespace sde {
|
|
||||||
|
|
||||||
StrategyDefault::StrategyDefault(DisplayType type, const HWResourceInfo &hw_resource_info,
|
|
||||||
const HWPanelInfo &hw_panel_info) : type_(type),
|
|
||||||
hw_resource_info_(hw_resource_info),
|
|
||||||
hw_panel_info_(hw_panel_info), hw_layers_info_(NULL) {
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError StrategyDefault::CreateStrategyInterface(uint16_t version, DisplayType type,
|
|
||||||
const HWResourceInfo &hw_resource_info,
|
|
||||||
const HWPanelInfo &hw_panel_info,
|
|
||||||
StrategyInterface **interface) {
|
|
||||||
StrategyDefault *strategy_default = new StrategyDefault(type, hw_resource_info, hw_panel_info);
|
|
||||||
|
|
||||||
if (!strategy_default) {
|
|
||||||
return kErrorMemory;
|
|
||||||
}
|
|
||||||
|
|
||||||
*interface = strategy_default;
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError StrategyDefault::DestroyStrategyInterface(StrategyInterface *interface) {
|
|
||||||
StrategyDefault *strategy_default = static_cast<StrategyDefault *>(interface);
|
|
||||||
|
|
||||||
if (!strategy_default) {
|
|
||||||
return kErrorParameters;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete strategy_default;
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool StrategyDefault::IsDisplaySplit(uint32_t fb_x_res) {
|
|
||||||
if (fb_x_res > hw_resource_info_.max_mixer_width) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((type_ == kPrimary) && hw_panel_info_.split_info.right_split) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError StrategyDefault::Start(HWLayersInfo *hw_layers_info, uint32_t *max_attempts) {
|
|
||||||
if (!hw_layers_info) {
|
|
||||||
return kErrorParameters;
|
|
||||||
}
|
|
||||||
|
|
||||||
hw_layers_info_ = hw_layers_info;
|
|
||||||
*max_attempts = 1;
|
|
||||||
|
|
||||||
const LayerStack *layer_stack = hw_layers_info_->stack;
|
|
||||||
for (uint32_t i = 0; i < layer_stack->layer_count; i++) {
|
|
||||||
LayerComposition &composition = layer_stack->layers[i].composition;
|
|
||||||
if (composition == kCompositionGPUTarget) {
|
|
||||||
fb_layer_index_ = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const LayerRect &src_rect = hw_layers_info_->stack->layers[fb_layer_index_].src_rect;
|
|
||||||
// TODO(user): read panels x_pixels and y_pixels instead of fb_x_res and fb_y_res
|
|
||||||
const float fb_x_res = src_rect.right - src_rect.left;
|
|
||||||
const float fb_y_res = src_rect.bottom - src_rect.top;
|
|
||||||
|
|
||||||
if (IsDisplaySplit(INT(fb_x_res))) {
|
|
||||||
float left_split = FLOAT(hw_panel_info_.split_info.left_split);
|
|
||||||
hw_layers_info->left_partial_update = (LayerRect) {0.0, 0.0, left_split, fb_y_res};
|
|
||||||
hw_layers_info->right_partial_update = (LayerRect) {left_split, 0.0, fb_x_res, fb_y_res};
|
|
||||||
} else {
|
|
||||||
hw_layers_info->left_partial_update = (LayerRect) {0.0, 0.0, fb_x_res, fb_y_res};
|
|
||||||
hw_layers_info->right_partial_update = (LayerRect) {0.0, 0.0, 0.0, 0.0};
|
|
||||||
}
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError StrategyDefault::Stop() {
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayError StrategyDefault::GetNextStrategy(StrategyConstraints *constraints) {
|
|
||||||
// Mark all layers for GPU composition. Find GPU target buffer and store its index for programming
|
|
||||||
// the hardware.
|
|
||||||
LayerStack *layer_stack = hw_layers_info_->stack;
|
|
||||||
uint32_t &hw_layer_count = hw_layers_info_->count;
|
|
||||||
|
|
||||||
hw_layer_count = 0;
|
|
||||||
for (uint32_t i = 0; i < layer_stack->layer_count; i++) {
|
|
||||||
LayerComposition &composition = layer_stack->layers[i].composition;
|
|
||||||
if (composition != kCompositionGPUTarget) {
|
|
||||||
composition = kCompositionGPU;
|
|
||||||
} else {
|
|
||||||
hw_layers_info_->index[hw_layer_count++] = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// There can be one and only one GPU target buffer.
|
|
||||||
if (hw_layer_count != 1) {
|
|
||||||
return kErrorParameters;
|
|
||||||
}
|
|
||||||
|
|
||||||
return kErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace sde
|
|
||||||
|
|
||||||
@@ -30,8 +30,7 @@
|
|||||||
/*! @file buffer_allocator.h
|
/*! @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,11 +38,11 @@
|
|||||||
|
|
||||||
#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
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct BufferConfig {
|
struct BufferConfig {
|
||||||
uint32_t width; //!< Specifies buffer width for buffer allocation.
|
uint32_t width; //!< Specifies buffer width for buffer allocation.
|
||||||
@@ -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__
|
||||||
|
|
||||||
@@ -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__
|
||||||
|
|
||||||
@@ -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__
|
||||||
|
|
||||||
@@ -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__
|
||||||
|
|
||||||
@@ -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__
|
||||||
|
|
||||||
12
displayengine/include/core/dump_interface.h → sdm/include/core/dump_interface.h
Executable file → Normal file
12
displayengine/include/core/dump_interface.h → sdm/include/core/dump_interface.h
Executable file → Normal file
@@ -23,7 +23,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*! @file dump_interface.h
|
/*! @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__
|
||||||
|
|
||||||
@@ -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__
|
||||||
|
|
||||||
@@ -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__
|
||||||
|
|
||||||
@@ -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__
|
||||||
|
|
||||||
79
sdm/include/private/extension_interface.h
Normal file
79
sdm/include/private/extension_interface.h
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||||
|
* provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
|
||||||
|
* endorse or promote products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __EXTENSION_INTERFACE_H__
|
||||||
|
#define __EXTENSION_INTERFACE_H__
|
||||||
|
|
||||||
|
#include <core/sdm_types.h>
|
||||||
|
#include <core/display_interface.h>
|
||||||
|
|
||||||
|
#include "partial_update_interface.h"
|
||||||
|
#include "strategy_interface.h"
|
||||||
|
#include "resource_interface.h"
|
||||||
|
#include "rotator_interface.h"
|
||||||
|
|
||||||
|
namespace sdm {
|
||||||
|
|
||||||
|
#define EXTENSION_LIBRARY_NAME "libsdmextension.so"
|
||||||
|
#define CREATE_EXTENSION_INTERFACE_NAME "CreateExtensionInterface"
|
||||||
|
#define DESTROY_EXTENSION_INTERFACE_NAME "DestroyExtensionInterface"
|
||||||
|
|
||||||
|
#define EXTENSION_REVISION_MAJOR (1)
|
||||||
|
#define EXTENSION_REVISION_MINOR (0)
|
||||||
|
|
||||||
|
#define EXTENSION_VERSION_TAG ((uint16_t) ((EXTENSION_REVISION_MAJOR << 8) \
|
||||||
|
| EXTENSION_REVISION_MINOR))
|
||||||
|
|
||||||
|
class ExtensionInterface;
|
||||||
|
|
||||||
|
typedef DisplayError (*CreateExtensionInterface)(uint16_t version, ExtensionInterface **interface);
|
||||||
|
typedef DisplayError (*DestroyExtensionInterface)(ExtensionInterface *interface);
|
||||||
|
|
||||||
|
class ExtensionInterface {
|
||||||
|
public:
|
||||||
|
virtual DisplayError CreatePartialUpdate(DisplayType type, const HWResourceInfo &hw_resource_info,
|
||||||
|
const HWPanelInfo &hw_panel_info,
|
||||||
|
PartialUpdateInterface **interface) = 0;
|
||||||
|
virtual DisplayError DestroyPartialUpdate(PartialUpdateInterface *interface) = 0;
|
||||||
|
|
||||||
|
virtual DisplayError CreateStrategyExtn(DisplayType type, StrategyInterface **interface) = 0;
|
||||||
|
virtual DisplayError DestroyStrategyExtn(StrategyInterface *interface) = 0;
|
||||||
|
|
||||||
|
virtual DisplayError CreateResourceExtn(const HWResourceInfo &hw_resource_info,
|
||||||
|
ResourceInterface **interface) = 0;
|
||||||
|
virtual DisplayError DestroyResourceExtn(ResourceInterface *interface) = 0;
|
||||||
|
|
||||||
|
virtual DisplayError CreateRotator(BufferAllocator *buffer_allocator,
|
||||||
|
BufferSyncHandler *buffer_sync_handler,
|
||||||
|
RotatorInterface **intf) = 0;
|
||||||
|
virtual DisplayError DestroyRotator(RotatorInterface *intf) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual ~ExtensionInterface() { }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace sdm
|
||||||
|
|
||||||
|
#endif // __EXTENSION_INTERFACE_H__
|
||||||
|
|
||||||
340
sdm/include/private/hw_info_types.h
Normal file
340
sdm/include/private/hw_info_types.h
Normal file
@@ -0,0 +1,340 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||||
|
* provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
|
||||||
|
* endorse or promote products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __HW_INFO_TYPES_H__
|
||||||
|
#define __HW_INFO_TYPES_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <core/display_interface.h>
|
||||||
|
|
||||||
|
namespace sdm {
|
||||||
|
|
||||||
|
const int kMaxSDELayers = 16; // Maximum number of layers that can be handled by hardware in a
|
||||||
|
// given layer stack.
|
||||||
|
|
||||||
|
enum HWDeviceType {
|
||||||
|
kDevicePrimary,
|
||||||
|
kDeviceHDMI,
|
||||||
|
kDeviceVirtual,
|
||||||
|
kDeviceRotator,
|
||||||
|
kDeviceMax,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum HWBlockType {
|
||||||
|
kHWPrimary,
|
||||||
|
kHWHDMI,
|
||||||
|
kHWWriteback0,
|
||||||
|
kHWWriteback1,
|
||||||
|
kHWWriteback2,
|
||||||
|
kHWBlockMax
|
||||||
|
};
|
||||||
|
|
||||||
|
enum HWDisplayMode {
|
||||||
|
kModeDefault,
|
||||||
|
kModeVideo,
|
||||||
|
kModeCommand,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum HWDisplayPort {
|
||||||
|
kPortDefault,
|
||||||
|
kPortDSI,
|
||||||
|
kPortDTv,
|
||||||
|
kPortWriteBack,
|
||||||
|
kPortLVDS,
|
||||||
|
kPortEDP,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct HWResourceInfo {
|
||||||
|
uint32_t hw_version;
|
||||||
|
uint32_t hw_revision;
|
||||||
|
uint32_t num_dma_pipe;
|
||||||
|
uint32_t num_vig_pipe;
|
||||||
|
uint32_t num_rgb_pipe;
|
||||||
|
uint32_t num_cursor_pipe;
|
||||||
|
uint32_t num_blending_stages;
|
||||||
|
uint32_t num_rotator;
|
||||||
|
uint32_t num_control;
|
||||||
|
uint32_t num_mixer_to_disp;
|
||||||
|
uint32_t smp_total;
|
||||||
|
uint32_t smp_size;
|
||||||
|
uint32_t num_smp_per_pipe;
|
||||||
|
uint32_t max_scale_up;
|
||||||
|
uint32_t max_scale_down;
|
||||||
|
uint64_t max_bandwidth_low;
|
||||||
|
uint64_t max_bandwidth_high;
|
||||||
|
uint32_t max_mixer_width;
|
||||||
|
uint32_t max_pipe_width;
|
||||||
|
uint32_t max_pipe_bw;
|
||||||
|
uint32_t max_sde_clk;
|
||||||
|
float clk_fudge_factor;
|
||||||
|
bool has_bwc;
|
||||||
|
bool has_ubwc;
|
||||||
|
bool has_decimation;
|
||||||
|
bool has_macrotile;
|
||||||
|
bool has_rotator_downscale;
|
||||||
|
bool has_non_scalar_rgb;
|
||||||
|
bool is_src_split;
|
||||||
|
|
||||||
|
HWResourceInfo()
|
||||||
|
: hw_version(0), hw_revision(0), num_dma_pipe(0), num_vig_pipe(0), num_rgb_pipe(0),
|
||||||
|
num_cursor_pipe(0), num_blending_stages(0), num_rotator(0), num_control(0),
|
||||||
|
num_mixer_to_disp(0), smp_total(0), smp_size(0), num_smp_per_pipe(0), max_scale_up(1),
|
||||||
|
max_scale_down(1), max_bandwidth_low(0), max_bandwidth_high(0), max_mixer_width(2048),
|
||||||
|
max_pipe_width(2048), max_pipe_bw(0), max_sde_clk(0), clk_fudge_factor(1.0f), has_bwc(false),
|
||||||
|
has_ubwc(false), has_decimation(false), has_macrotile(false), has_rotator_downscale(false),
|
||||||
|
has_non_scalar_rgb(false), is_src_split(false) { }
|
||||||
|
|
||||||
|
void Reset() { *this = HWResourceInfo(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct HWSplitInfo {
|
||||||
|
uint32_t left_split;
|
||||||
|
uint32_t right_split;
|
||||||
|
bool always_src_split;
|
||||||
|
|
||||||
|
HWSplitInfo() : left_split(0), right_split(0), always_src_split(false) { }
|
||||||
|
|
||||||
|
bool operator !=(const HWSplitInfo &split_info) {
|
||||||
|
return ((left_split != split_info.left_split) || (right_split != split_info.right_split) ||
|
||||||
|
(always_src_split != split_info.always_src_split));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator ==(const HWSplitInfo &split_info) {
|
||||||
|
return !(operator !=(split_info));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct HWPanelInfo {
|
||||||
|
HWDisplayPort port; // Display port
|
||||||
|
HWDisplayMode mode; // Display mode
|
||||||
|
bool partial_update; // Partial update feature
|
||||||
|
int left_align; // ROI left alignment restriction
|
||||||
|
int width_align; // ROI width alignment restriction
|
||||||
|
int top_align;; // ROI top alignment restriction
|
||||||
|
int height_align; // ROI height alignment restriction
|
||||||
|
int min_roi_width; // Min width needed for ROI
|
||||||
|
int min_roi_height; // Min height needed for ROI
|
||||||
|
bool needs_roi_merge; // Merge ROI's of both the DSI's
|
||||||
|
bool dynamic_fps; // Panel Supports dynamic fps
|
||||||
|
uint32_t min_fps; // Min fps supported by panel
|
||||||
|
uint32_t max_fps; // Max fps supported by panel
|
||||||
|
bool is_primary_panel; // Panel is primary display
|
||||||
|
HWSplitInfo split_info; // Panel split configuration
|
||||||
|
|
||||||
|
HWPanelInfo() : port(kPortDefault), mode(kModeDefault), partial_update(false), left_align(false),
|
||||||
|
width_align(false), top_align(false), height_align(false), min_roi_width(0), min_roi_height(0),
|
||||||
|
needs_roi_merge(false), dynamic_fps(false), min_fps(0), max_fps(0) { }
|
||||||
|
|
||||||
|
bool operator !=(const HWPanelInfo &panel_info) {
|
||||||
|
return ((port != panel_info.port) || (mode != panel_info.mode) ||
|
||||||
|
(partial_update != panel_info.partial_update) ||
|
||||||
|
(left_align != panel_info.left_align) || (width_align != panel_info.width_align) ||
|
||||||
|
(top_align != panel_info.top_align) || (height_align != panel_info.height_align) ||
|
||||||
|
(min_roi_width != panel_info.min_roi_width) ||
|
||||||
|
(min_roi_height != panel_info.min_roi_height) ||
|
||||||
|
(needs_roi_merge != panel_info.needs_roi_merge) ||
|
||||||
|
(dynamic_fps != panel_info.dynamic_fps) || (min_fps != panel_info.min_fps) ||
|
||||||
|
(max_fps != panel_info.max_fps) || (is_primary_panel != panel_info.is_primary_panel) ||
|
||||||
|
(split_info != panel_info.split_info));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator ==(const HWPanelInfo &panel_info) {
|
||||||
|
return !(operator !=(panel_info));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct HWSessionConfig {
|
||||||
|
uint32_t src_width;
|
||||||
|
uint32_t src_height;
|
||||||
|
LayerBufferFormat src_format;
|
||||||
|
uint32_t dst_width;
|
||||||
|
uint32_t dst_height;
|
||||||
|
LayerBufferFormat dst_format;
|
||||||
|
uint32_t buffer_count;
|
||||||
|
bool secure;
|
||||||
|
bool cache;
|
||||||
|
uint32_t frame_rate;
|
||||||
|
|
||||||
|
HWSessionConfig()
|
||||||
|
: src_width(0), src_height(0), src_format(kFormatInvalid), dst_width(0), dst_height(0),
|
||||||
|
dst_format(kFormatInvalid), buffer_count(0), secure(false), cache(false), frame_rate(0) { }
|
||||||
|
|
||||||
|
bool operator != (const HWSessionConfig &input_config) const {
|
||||||
|
if ((src_width != input_config.src_width) || (src_height != input_config.src_height) ||
|
||||||
|
(src_format != input_config.src_format) || (dst_width != input_config.dst_width) ||
|
||||||
|
(dst_height != input_config.dst_height) || (dst_format != input_config.dst_format) ||
|
||||||
|
(buffer_count != input_config.buffer_count) || (secure != input_config.secure) ||
|
||||||
|
(cache != input_config.cache) || (frame_rate != input_config.frame_rate)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator == (const HWSessionConfig &input_config) const {
|
||||||
|
return !(operator != (input_config));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct HWRotateInfo {
|
||||||
|
uint32_t pipe_id;
|
||||||
|
LayerRect src_roi;
|
||||||
|
LayerRect dst_roi;
|
||||||
|
HWBlockType writeback_id;
|
||||||
|
bool valid;
|
||||||
|
int rotate_id;
|
||||||
|
|
||||||
|
HWRotateInfo()
|
||||||
|
: pipe_id(0), writeback_id(kHWWriteback0), valid(false), rotate_id(-1) { }
|
||||||
|
|
||||||
|
void Reset() { *this = HWRotateInfo(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct HWRotatorSession {
|
||||||
|
HWRotateInfo hw_rotate_info[kMaxRotatePerLayer];
|
||||||
|
uint32_t hw_block_count; // number of rotator hw blocks used by rotator session
|
||||||
|
float downscale_ratio;
|
||||||
|
LayerTransform transform;
|
||||||
|
HWSessionConfig hw_session_config;
|
||||||
|
LayerBuffer output_buffer;
|
||||||
|
int session_id;
|
||||||
|
float input_compression;
|
||||||
|
float output_compression;
|
||||||
|
|
||||||
|
HWRotatorSession()
|
||||||
|
: hw_block_count(0), downscale_ratio(1.0f), session_id(-1), input_compression(1.0f),
|
||||||
|
output_compression(1.0f) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct HWPixelExtension {
|
||||||
|
int extension; // Number of pixels extension in left, right, top and bottom directions for all
|
||||||
|
// color components. This pixel value for each color component should be sum of
|
||||||
|
// fetch and repeat pixels.
|
||||||
|
|
||||||
|
int overfetch; // Number of pixels need to be overfetched in left, right, top and bottom
|
||||||
|
// directions from source image for scaling.
|
||||||
|
|
||||||
|
int repeat; // Number of pixels need to be repeated in left, right, top and bottom directions
|
||||||
|
// for scaling.
|
||||||
|
};
|
||||||
|
|
||||||
|
struct HWPlane {
|
||||||
|
int init_phase_x;
|
||||||
|
int phase_step_x;
|
||||||
|
int init_phase_y;
|
||||||
|
int phase_step_y;
|
||||||
|
HWPixelExtension left;
|
||||||
|
HWPixelExtension top;
|
||||||
|
HWPixelExtension right;
|
||||||
|
HWPixelExtension bottom;
|
||||||
|
uint32_t roi_width;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ScaleData {
|
||||||
|
uint8_t enable_pixel_ext;
|
||||||
|
uint32_t src_width;
|
||||||
|
uint32_t src_height;
|
||||||
|
HWPlane plane[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct HWPipeInfo {
|
||||||
|
uint32_t pipe_id;
|
||||||
|
LayerRect src_roi;
|
||||||
|
LayerRect dst_roi;
|
||||||
|
uint8_t horizontal_decimation;
|
||||||
|
uint8_t vertical_decimation;
|
||||||
|
ScaleData scale_data;
|
||||||
|
bool valid;
|
||||||
|
uint32_t z_order;
|
||||||
|
|
||||||
|
HWPipeInfo()
|
||||||
|
: pipe_id(0), horizontal_decimation(0), vertical_decimation(0), valid(false), z_order(0) { }
|
||||||
|
|
||||||
|
void Reset() { *this = HWPipeInfo(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct HWLayerConfig {
|
||||||
|
bool use_non_dma_pipe; // set by client
|
||||||
|
HWPipeInfo left_pipe; // pipe for left side of output
|
||||||
|
HWPipeInfo right_pipe; // pipe for right side of output
|
||||||
|
HWRotatorSession hw_rotator_session;
|
||||||
|
float compression;
|
||||||
|
|
||||||
|
HWLayerConfig() : use_non_dma_pipe(false), compression(1.0f) { }
|
||||||
|
|
||||||
|
void Reset() { *this = HWLayerConfig(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct HWLayersInfo {
|
||||||
|
LayerStack *stack; // Input layer stack. Set by the caller.
|
||||||
|
|
||||||
|
uint32_t index[kMaxSDELayers];
|
||||||
|
// Indexes of the layers from the layer stack which need to be
|
||||||
|
// programmed on hardware.
|
||||||
|
|
||||||
|
uint32_t count; // Total number of layers which need to be set on hardware.
|
||||||
|
|
||||||
|
LayerRect left_partial_update;
|
||||||
|
// Left ROI.
|
||||||
|
|
||||||
|
LayerRect right_partial_update;
|
||||||
|
// Right ROI.
|
||||||
|
|
||||||
|
|
||||||
|
HWLayersInfo() : stack(NULL), count(0) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct HWLayers {
|
||||||
|
HWLayersInfo info;
|
||||||
|
HWLayerConfig config[kMaxSDELayers];
|
||||||
|
float output_compression;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct HWDisplayAttributes : DisplayConfigVariableInfo {
|
||||||
|
bool is_device_split;
|
||||||
|
uint32_t split_left;
|
||||||
|
bool always_src_split;
|
||||||
|
|
||||||
|
HWDisplayAttributes() : is_device_split(false), split_left(0), always_src_split(false) { }
|
||||||
|
|
||||||
|
void Reset() { *this = HWDisplayAttributes(); }
|
||||||
|
|
||||||
|
bool operator !=(const HWDisplayAttributes &attributes) {
|
||||||
|
return ((is_device_split != attributes.is_device_split) ||
|
||||||
|
(split_left != attributes.split_left) ||
|
||||||
|
(always_src_split != attributes.always_src_split) ||
|
||||||
|
(x_pixels != attributes.x_pixels) || (y_pixels != attributes.y_pixels) ||
|
||||||
|
(x_dpi != attributes.x_dpi) || (y_dpi != attributes.y_dpi) || (fps != attributes.fps) ||
|
||||||
|
(vsync_period_ns != attributes.vsync_period_ns) || (v_total != attributes.v_total));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator ==(const HWDisplayAttributes &attributes) {
|
||||||
|
return !(operator !=(attributes));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace sdm
|
||||||
|
|
||||||
|
#endif // __HW_INFO_TYPES_H__
|
||||||
|
|
||||||
@@ -22,32 +22,26 @@
|
|||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* 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__
|
||||||
|
|
||||||
@@ -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__
|
|
||||||
@@ -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__
|
||||||
|
|
||||||
@@ -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__
|
||||||
|
|
||||||
@@ -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__
|
||||||
|
|
||||||
@@ -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__
|
||||||
|
|
||||||
@@ -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__
|
||||||
|
|
||||||
@@ -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__
|
||||||
|
|
||||||
@@ -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_HW_INTF_PATH := fb
|
||||||
LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/scalar/inc
|
LOCAL_SHARED_LIBRARIES := libdl libsdmutils
|
||||||
LOCAL_CFLAGS += -DUSES_SCALAR
|
|
||||||
endif
|
|
||||||
LOCAL_HW_INTF_PATH := fb
|
|
||||||
LOCAL_SHARED_LIBRARIES := libdl libsdeutils libcutils
|
|
||||||
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
|
||||||
|
|
||||||
@@ -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();
|
||||||
&display_comp_ctx->display_resource_ctx);
|
|
||||||
if (error != kErrorNone) {
|
if (error != kErrorNone) {
|
||||||
destroy_strategy_intf_(display_comp_ctx->strategy_intf);
|
delete strategy;
|
||||||
|
delete display_comp_ctx;
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = resource_intf_->RegisterDisplay(type, attributes, hw_panel_info,
|
||||||
|
&display_comp_ctx->display_resource_ctx);
|
||||||
|
if (error != kErrorNone) {
|
||||||
|
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
|
||||||
|
|
||||||
@@ -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__
|
||||||
|
|
||||||
@@ -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_,
|
||||||
comp_mgr_.Deinit();
|
&rotator_intf_);
|
||||||
error = kErrorMemory;
|
if (error != kErrorNone) {
|
||||||
goto CleanUpOnError;
|
comp_mgr_.Deinit();
|
||||||
}
|
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
|
||||||
|
|
||||||
@@ -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__
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -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
|
||||||
@@ -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__
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -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__
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -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__
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -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__
|
||||||
|
|
||||||
6
displayengine/libs/core/dump_impl.cpp → sdm/libs/core/dump_impl.cpp
Executable file → Normal file
6
displayengine/libs/core/dump_impl.cpp → sdm/libs/core/dump_impl.cpp
Executable file → Normal file
@@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
#include "dump_impl.h"
|
#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
|
||||||
|
|
||||||
@@ -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__
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -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__
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -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__
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -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__
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -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__
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -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__
|
||||||
|
|
||||||
@@ -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__
|
||||||
|
|
||||||
@@ -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__
|
||||||
|
|
||||||
90
sdm/libs/core/hw_interface.h
Normal file
90
sdm/libs/core/hw_interface.h
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014 - 2015, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||||
|
* provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
|
||||||
|
* endorse or promote products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __HW_INTERFACE_H__
|
||||||
|
#define __HW_INTERFACE_H__
|
||||||
|
|
||||||
|
#include <core/display_interface.h>
|
||||||
|
#include <private/strategy_interface.h>
|
||||||
|
#include <private/hw_info_types.h>
|
||||||
|
#include <utils/constants.h>
|
||||||
|
#include <core/buffer_allocator.h>
|
||||||
|
#include <core/buffer_sync_handler.h>
|
||||||
|
|
||||||
|
namespace sdm {
|
||||||
|
|
||||||
|
enum HWScanSupport {
|
||||||
|
kScanNotSupported,
|
||||||
|
kScanAlwaysOverscanned,
|
||||||
|
kScanAlwaysUnderscanned,
|
||||||
|
kScanBoth,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct HWScanInfo {
|
||||||
|
HWScanSupport pt_scan_support; // Scan support for preferred timing
|
||||||
|
HWScanSupport it_scan_support; // Scan support for digital monitor or industry timings
|
||||||
|
HWScanSupport cea_scan_support; // Scan support for CEA resolution timings
|
||||||
|
|
||||||
|
HWScanInfo() : pt_scan_support(kScanNotSupported), it_scan_support(kScanNotSupported),
|
||||||
|
cea_scan_support(kScanNotSupported) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
// HWEventHandler - Implemented in DisplayBase and HWInterface implementation
|
||||||
|
class HWEventHandler {
|
||||||
|
public:
|
||||||
|
virtual DisplayError VSync(int64_t timestamp) = 0;
|
||||||
|
virtual DisplayError Blank(bool blank) = 0;
|
||||||
|
virtual void IdleTimeout() = 0;
|
||||||
|
virtual void ThermalEvent(int64_t thermal_level) = 0;
|
||||||
|
protected:
|
||||||
|
virtual ~HWEventHandler() { }
|
||||||
|
};
|
||||||
|
|
||||||
|
class HWInterface {
|
||||||
|
public:
|
||||||
|
virtual DisplayError Open(HWEventHandler *eventhandler) = 0;
|
||||||
|
virtual DisplayError Close() = 0;
|
||||||
|
virtual DisplayError GetNumDisplayAttributes(uint32_t *count) = 0;
|
||||||
|
virtual DisplayError GetDisplayAttributes(HWDisplayAttributes *display_attributes,
|
||||||
|
uint32_t index) = 0;
|
||||||
|
virtual DisplayError GetHWPanelInfo(HWPanelInfo *panel_info) = 0;
|
||||||
|
virtual DisplayError SetDisplayAttributes(uint32_t index) = 0;
|
||||||
|
virtual DisplayError GetConfigIndex(uint32_t mode, uint32_t *index) = 0;
|
||||||
|
virtual DisplayError PowerOn() = 0;
|
||||||
|
virtual DisplayError PowerOff() = 0;
|
||||||
|
virtual DisplayError Doze() = 0;
|
||||||
|
virtual DisplayError DozeSuspend() = 0;
|
||||||
|
virtual DisplayError Standby() = 0;
|
||||||
|
virtual DisplayError Validate(HWLayers *hw_layers) = 0;
|
||||||
|
virtual DisplayError Commit(HWLayers *hw_layers) = 0;
|
||||||
|
virtual DisplayError Flush() = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual ~HWInterface() { }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace sdm
|
||||||
|
|
||||||
|
#endif // __HW_INTERFACE_H__
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
#ifndef __HW_PRIMARY_INTERFACE_H__
|
#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__
|
||||||
|
|
||||||
@@ -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__
|
||||||
|
|
||||||
912
sdm/libs/core/resource_default.cpp
Normal file
912
sdm/libs/core/resource_default.cpp
Normal file
@@ -0,0 +1,912 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014 - 2015, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||||
|
* provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
|
||||||
|
* endorse or promote products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include <utils/constants.h>
|
||||||
|
#include <utils/debug.h>
|
||||||
|
#include <utils/rect.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
|
#include "resource_default.h"
|
||||||
|
|
||||||
|
#define __CLASS__ "ResourceDefault"
|
||||||
|
|
||||||
|
namespace sdm {
|
||||||
|
|
||||||
|
ResourceDefault::ResourceDefault()
|
||||||
|
: num_pipe_(0), vig_pipes_(NULL), rgb_pipes_(NULL), dma_pipes_(NULL) {
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayError ResourceDefault::Init(const HWResourceInfo &hw_res_info) {
|
||||||
|
DisplayError error = kErrorNone;
|
||||||
|
uint32_t num_pipe = 0;
|
||||||
|
|
||||||
|
num_pipe = hw_res_info.num_vig_pipe + hw_res_info.num_rgb_pipe + hw_res_info.num_dma_pipe;
|
||||||
|
|
||||||
|
if (num_pipe > kPipeIdMax) {
|
||||||
|
DLOGE("Number of pipe is over the limit! %d", num_pipe);
|
||||||
|
return kErrorParameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
num_pipe_ = num_pipe;
|
||||||
|
hw_res_info_ = hw_res_info;
|
||||||
|
// Init pipe info
|
||||||
|
vig_pipes_ = &src_pipes_[0];
|
||||||
|
rgb_pipes_ = &src_pipes_[hw_res_info_.num_vig_pipe];
|
||||||
|
dma_pipes_ = &src_pipes_[hw_res_info_.num_vig_pipe + hw_res_info_.num_rgb_pipe];
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < hw_res_info_.num_vig_pipe; i++) {
|
||||||
|
vig_pipes_[i].type = kPipeTypeVIG;
|
||||||
|
vig_pipes_[i].index = i;
|
||||||
|
vig_pipes_[i].mdss_pipe_id = GetMdssPipeId(vig_pipes_[i].type, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < hw_res_info_.num_rgb_pipe; i++) {
|
||||||
|
rgb_pipes_[i].type = kPipeTypeRGB;
|
||||||
|
rgb_pipes_[i].index = i + hw_res_info_.num_vig_pipe;
|
||||||
|
rgb_pipes_[i].mdss_pipe_id = GetMdssPipeId(rgb_pipes_[i].type, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < hw_res_info_.num_dma_pipe; i++) {
|
||||||
|
dma_pipes_[i].type = kPipeTypeDMA;
|
||||||
|
dma_pipes_[i].index = i + hw_res_info_.num_vig_pipe + hw_res_info_.num_rgb_pipe;
|
||||||
|
dma_pipes_[i].mdss_pipe_id = GetMdssPipeId(dma_pipes_[i].type, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < num_pipe_; i++) {
|
||||||
|
src_pipes_[i].priority = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
DLOGI("hw_rev=%x, DMA=%d RGB=%d VIG=%d", hw_res_info_.hw_revision, hw_res_info_.num_dma_pipe,
|
||||||
|
hw_res_info_.num_rgb_pipe, hw_res_info_.num_vig_pipe);
|
||||||
|
|
||||||
|
if (hw_res_info_.max_scale_down < 1 || hw_res_info_.max_scale_up < 1) {
|
||||||
|
DLOGE("Max scaling setting is invalid! max_scale_down = %d, max_scale_up = %d",
|
||||||
|
hw_res_info_.max_scale_down, hw_res_info_.max_scale_up);
|
||||||
|
hw_res_info_.max_scale_down = 1;
|
||||||
|
hw_res_info_.max_scale_up = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rgb_pipes_[0].owner = kPipeOwnerKernelMode;
|
||||||
|
rgb_pipes_[1].owner = kPipeOwnerKernelMode;
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayError ResourceDefault::Deinit() {
|
||||||
|
return kErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayError ResourceDefault::RegisterDisplay(DisplayType type,
|
||||||
|
const HWDisplayAttributes &attributes,
|
||||||
|
const HWPanelInfo &hw_panel_info,
|
||||||
|
Handle *display_ctx) {
|
||||||
|
DisplayError error = kErrorNone;
|
||||||
|
|
||||||
|
HWBlockType hw_block_id = kHWBlockMax;
|
||||||
|
switch (type) {
|
||||||
|
case kPrimary:
|
||||||
|
if (!hw_block_ctx_[kHWPrimary].is_in_use) {
|
||||||
|
hw_block_id = kHWPrimary;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kHDMI:
|
||||||
|
if (!hw_block_ctx_[kHWHDMI].is_in_use) {
|
||||||
|
hw_block_id = kHWHDMI;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
DLOGW("RegisterDisplay, invalid type %d", type);
|
||||||
|
return kErrorParameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hw_block_id == kHWBlockMax) {
|
||||||
|
return kErrorResources;
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayResourceContext *display_resource_ctx = new DisplayResourceContext();
|
||||||
|
if (!display_resource_ctx) {
|
||||||
|
return kErrorMemory;
|
||||||
|
}
|
||||||
|
|
||||||
|
hw_block_ctx_[hw_block_id].is_in_use = true;
|
||||||
|
|
||||||
|
display_resource_ctx->display_attributes = attributes;
|
||||||
|
display_resource_ctx->hw_block_id = hw_block_id;
|
||||||
|
|
||||||
|
if (!display_resource_ctx->display_attributes.is_device_split) {
|
||||||
|
display_resource_ctx->display_attributes.split_left = attributes.x_pixels;
|
||||||
|
}
|
||||||
|
|
||||||
|
*display_ctx = display_resource_ctx;
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayError ResourceDefault::UnregisterDisplay(Handle display_ctx) {
|
||||||
|
DisplayResourceContext *display_resource_ctx =
|
||||||
|
reinterpret_cast<DisplayResourceContext *>(display_ctx);
|
||||||
|
Purge(display_ctx);
|
||||||
|
|
||||||
|
hw_block_ctx_[display_resource_ctx->hw_block_id].is_in_use = false;
|
||||||
|
|
||||||
|
delete display_resource_ctx;
|
||||||
|
|
||||||
|
return kErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceDefault::ReconfigureDisplay(Handle display_ctx, const HWDisplayAttributes &attributes,
|
||||||
|
const HWPanelInfo &hw_panel_info) {
|
||||||
|
SCOPE_LOCK(locker_);
|
||||||
|
|
||||||
|
DisplayResourceContext *display_resource_ctx =
|
||||||
|
reinterpret_cast<DisplayResourceContext *>(display_ctx);
|
||||||
|
|
||||||
|
display_resource_ctx->display_attributes = attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayError ResourceDefault::Start(Handle display_ctx) {
|
||||||
|
locker_.Lock();
|
||||||
|
|
||||||
|
return kErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayError ResourceDefault::Stop(Handle display_ctx) {
|
||||||
|
locker_.Unlock();
|
||||||
|
|
||||||
|
return kErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayError ResourceDefault::Acquire(Handle display_ctx, HWLayers *hw_layers) {
|
||||||
|
DisplayResourceContext *display_resource_ctx =
|
||||||
|
reinterpret_cast<DisplayResourceContext *>(display_ctx);
|
||||||
|
|
||||||
|
DisplayError error = kErrorNone;
|
||||||
|
const struct HWLayersInfo &layer_info = hw_layers->info;
|
||||||
|
HWBlockType hw_block_id = display_resource_ctx->hw_block_id;
|
||||||
|
|
||||||
|
DLOGV_IF(kTagResources, "==== Resource reserving start: hw_block = %d ====", hw_block_id);
|
||||||
|
|
||||||
|
if (layer_info.count > 1) {
|
||||||
|
DLOGV_IF(kTagResources, "More than one FB layers");
|
||||||
|
return kErrorResources;
|
||||||
|
}
|
||||||
|
|
||||||
|
Layer &layer = layer_info.stack->layers[layer_info.index[0]];
|
||||||
|
|
||||||
|
if (layer.composition != kCompositionGPUTarget) {
|
||||||
|
DLOGV_IF(kTagResources, "Not an FB layer");
|
||||||
|
return kErrorParameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = Config(display_resource_ctx, hw_layers);
|
||||||
|
if (error != kErrorNone) {
|
||||||
|
DLOGV_IF(kTagResources, "Resource config failed");
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < num_pipe_; i++) {
|
||||||
|
if (src_pipes_[i].hw_block_id == hw_block_id && src_pipes_[i].owner == kPipeOwnerUserMode) {
|
||||||
|
src_pipes_[i].ResetState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t left_index = kPipeIdMax;
|
||||||
|
uint32_t right_index = kPipeIdMax;
|
||||||
|
bool need_scale = false;
|
||||||
|
|
||||||
|
struct HWLayerConfig &layer_config = hw_layers->config[0];
|
||||||
|
|
||||||
|
HWPipeInfo *left_pipe = &layer_config.left_pipe;
|
||||||
|
HWPipeInfo *right_pipe = &layer_config.right_pipe;
|
||||||
|
|
||||||
|
// left pipe is needed
|
||||||
|
if (left_pipe->valid) {
|
||||||
|
need_scale = IsScalingNeeded(left_pipe);
|
||||||
|
left_index = GetPipe(hw_block_id, need_scale);
|
||||||
|
if (left_index >= num_pipe_) {
|
||||||
|
DLOGV_IF(kTagResources, "Get left pipe failed: hw_block_id = %d, need_scale = %d",
|
||||||
|
hw_block_id, need_scale);
|
||||||
|
ResourceStateLog();
|
||||||
|
goto CleanupOnError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
error = SetDecimationFactor(left_pipe);
|
||||||
|
if (error != kErrorNone) {
|
||||||
|
goto CleanupOnError;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!right_pipe->valid) {
|
||||||
|
// assign single pipe
|
||||||
|
if (left_index < num_pipe_) {
|
||||||
|
left_pipe->pipe_id = src_pipes_[left_index].mdss_pipe_id;
|
||||||
|
}
|
||||||
|
DLOGV_IF(kTagResources, "1 pipe acquired for FB layer, left_pipe = %x", left_pipe->pipe_id);
|
||||||
|
return kErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
need_scale = IsScalingNeeded(right_pipe);
|
||||||
|
|
||||||
|
right_index = GetPipe(hw_block_id, need_scale);
|
||||||
|
if (right_index >= num_pipe_) {
|
||||||
|
DLOGV_IF(kTagResources, "Get right pipe failed: hw_block_id = %d, need_scale = %d", hw_block_id,
|
||||||
|
need_scale);
|
||||||
|
ResourceStateLog();
|
||||||
|
goto CleanupOnError;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src_pipes_[right_index].priority < src_pipes_[left_index].priority) {
|
||||||
|
// Swap pipe based on priority
|
||||||
|
Swap(left_index, right_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
// assign dual pipes
|
||||||
|
left_pipe->pipe_id = src_pipes_[left_index].mdss_pipe_id;
|
||||||
|
right_pipe->pipe_id = src_pipes_[right_index].mdss_pipe_id;
|
||||||
|
|
||||||
|
error = SetDecimationFactor(right_pipe);
|
||||||
|
if (error != kErrorNone) {
|
||||||
|
goto CleanupOnError;
|
||||||
|
}
|
||||||
|
|
||||||
|
DLOGV_IF(kTagResources, "2 pipes acquired for FB layer, left_pipe = %x, right_pipe = %x",
|
||||||
|
left_pipe->pipe_id, right_pipe->pipe_id);
|
||||||
|
|
||||||
|
return kErrorNone;
|
||||||
|
|
||||||
|
CleanupOnError:
|
||||||
|
DLOGV_IF(kTagResources, "Resource reserving failed! hw_block = %d", hw_block_id);
|
||||||
|
|
||||||
|
return kErrorResources;
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayError ResourceDefault::PostPrepare(Handle display_ctx, HWLayers *hw_layers) {
|
||||||
|
SCOPE_LOCK(locker_);
|
||||||
|
|
||||||
|
return kErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayError ResourceDefault::PostCommit(Handle display_ctx, HWLayers *hw_layers) {
|
||||||
|
SCOPE_LOCK(locker_);
|
||||||
|
DisplayResourceContext *display_resource_ctx =
|
||||||
|
reinterpret_cast<DisplayResourceContext *>(display_ctx);
|
||||||
|
HWBlockType hw_block_id = display_resource_ctx->hw_block_id;
|
||||||
|
uint64_t frame_count = display_resource_ctx->frame_count;
|
||||||
|
DisplayError error = kErrorNone;
|
||||||
|
|
||||||
|
DLOGV_IF(kTagResources, "Resource for hw_block = %d, frame_count = %d", hw_block_id, frame_count);
|
||||||
|
|
||||||
|
// handoff pipes which are used by splash screen
|
||||||
|
if ((frame_count == 0) && (hw_block_id == kHWPrimary)) {
|
||||||
|
for (uint32_t i = 0; i < num_pipe_; i++) {
|
||||||
|
if (src_pipes_[i].hw_block_id == hw_block_id && src_pipes_[i].owner == kPipeOwnerKernelMode) {
|
||||||
|
src_pipes_[i].owner = kPipeOwnerUserMode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
display_resource_ctx->frame_count++;
|
||||||
|
|
||||||
|
return kErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceDefault::Purge(Handle display_ctx) {
|
||||||
|
SCOPE_LOCK(locker_);
|
||||||
|
|
||||||
|
DisplayResourceContext *display_resource_ctx =
|
||||||
|
reinterpret_cast<DisplayResourceContext *>(display_ctx);
|
||||||
|
HWBlockType hw_block_id = display_resource_ctx->hw_block_id;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < num_pipe_; i++) {
|
||||||
|
if (src_pipes_[i].hw_block_id == hw_block_id && src_pipes_[i].owner == kPipeOwnerUserMode) {
|
||||||
|
src_pipes_[i].ResetState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DLOGV_IF(kTagResources, "display id = %d", display_resource_ctx->hw_block_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayError ResourceDefault::SetMaxMixerStages(Handle display_ctx, uint32_t max_mixer_stages) {
|
||||||
|
SCOPE_LOCK(locker_);
|
||||||
|
|
||||||
|
return kErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ResourceDefault::GetMdssPipeId(PipeType type, uint32_t index) {
|
||||||
|
uint32_t mdss_id = kPipeIdMax;
|
||||||
|
switch (type) {
|
||||||
|
case kPipeTypeVIG:
|
||||||
|
if (index < 3) {
|
||||||
|
mdss_id = kPipeIdVIG0 + index;
|
||||||
|
} else if (index == 3) {
|
||||||
|
mdss_id = kPipeIdVIG3;
|
||||||
|
} else {
|
||||||
|
DLOGE("vig pipe index is over the limit! %d", index);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case kPipeTypeRGB:
|
||||||
|
if (index < 3) {
|
||||||
|
mdss_id = kPipeIdRGB0 + index;
|
||||||
|
} else if (index == 3) {
|
||||||
|
mdss_id = kPipeIdRGB3;
|
||||||
|
} else {
|
||||||
|
DLOGE("rgb pipe index is over the limit! %d", index);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case kPipeTypeDMA:
|
||||||
|
if (index < 2) {
|
||||||
|
mdss_id = kPipeIdDMA0 + index;
|
||||||
|
} else {
|
||||||
|
DLOGE("dma pipe index is over the limit! %d", index);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DLOGE("wrong pipe type! %d", type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (1 << mdss_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ResourceDefault::SearchPipe(HWBlockType hw_block_id, SourcePipe *src_pipes,
|
||||||
|
uint32_t num_pipe) {
|
||||||
|
uint32_t index = kPipeIdMax;
|
||||||
|
SourcePipe *src_pipe;
|
||||||
|
|
||||||
|
// search the pipe being used
|
||||||
|
for (uint32_t i = 0; i < num_pipe; i++) {
|
||||||
|
src_pipe = &src_pipes[i];
|
||||||
|
if (src_pipe->owner == kPipeOwnerUserMode && src_pipe->hw_block_id == kHWBlockMax) {
|
||||||
|
index = src_pipe->index;
|
||||||
|
src_pipe->hw_block_id = hw_block_id;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ResourceDefault::NextPipe(PipeType type, HWBlockType hw_block_id) {
|
||||||
|
uint32_t num_pipe = 0;
|
||||||
|
SourcePipe *src_pipes = NULL;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case kPipeTypeVIG:
|
||||||
|
src_pipes = vig_pipes_;
|
||||||
|
num_pipe = hw_res_info_.num_vig_pipe;
|
||||||
|
break;
|
||||||
|
case kPipeTypeRGB:
|
||||||
|
src_pipes = rgb_pipes_;
|
||||||
|
num_pipe = hw_res_info_.num_rgb_pipe;
|
||||||
|
break;
|
||||||
|
case kPipeTypeDMA:
|
||||||
|
default:
|
||||||
|
src_pipes = dma_pipes_;
|
||||||
|
num_pipe = hw_res_info_.num_dma_pipe;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SearchPipe(hw_block_id, src_pipes, num_pipe);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ResourceDefault::GetPipe(HWBlockType hw_block_id, bool need_scale) {
|
||||||
|
uint32_t index = kPipeIdMax;
|
||||||
|
|
||||||
|
// The default behavior is to assume RGB and VG pipes have scalars
|
||||||
|
if (!need_scale) {
|
||||||
|
index = NextPipe(kPipeTypeDMA, hw_block_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((index >= num_pipe_) && (!need_scale || !hw_res_info_.has_non_scalar_rgb)) {
|
||||||
|
index = NextPipe(kPipeTypeRGB, hw_block_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index >= num_pipe_) {
|
||||||
|
index = NextPipe(kPipeTypeVIG, hw_block_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ResourceDefault::IsScalingNeeded(const HWPipeInfo *pipe_info) {
|
||||||
|
const LayerRect &src_roi = pipe_info->src_roi;
|
||||||
|
const LayerRect &dst_roi = pipe_info->dst_roi;
|
||||||
|
|
||||||
|
return ((dst_roi.right - dst_roi.left) != (src_roi.right - src_roi.left)) ||
|
||||||
|
((dst_roi.bottom - dst_roi.top) != (src_roi.bottom - src_roi.top));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceDefault::ResourceStateLog() {
|
||||||
|
DLOGV_IF(kTagResources, "==== resource manager pipe state ====");
|
||||||
|
uint32_t i;
|
||||||
|
for (i = 0; i < num_pipe_; i++) {
|
||||||
|
SourcePipe *src_pipe = &src_pipes_[i];
|
||||||
|
DLOGV_IF(kTagResources, "index = %d, id = %x, hw_block = %d, owner = %s",
|
||||||
|
src_pipe->index, src_pipe->mdss_pipe_id, src_pipe->hw_block_id,
|
||||||
|
(src_pipe->owner == kPipeOwnerUserMode) ? "user mode" : "kernel mode");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayError ResourceDefault::SrcSplitConfig(DisplayResourceContext *display_resource_ctx,
|
||||||
|
const LayerRect &src_rect, const LayerRect &dst_rect,
|
||||||
|
HWLayerConfig *layer_config) {
|
||||||
|
HWDisplayAttributes &display_attributes = display_resource_ctx->display_attributes;
|
||||||
|
HWPipeInfo *left_pipe = &layer_config->left_pipe;
|
||||||
|
HWPipeInfo *right_pipe = &layer_config->right_pipe;
|
||||||
|
float src_width = src_rect.right - src_rect.left;
|
||||||
|
float dst_width = dst_rect.right - dst_rect.left;
|
||||||
|
float src_height = src_rect.bottom - src_rect.top;
|
||||||
|
float dst_height = dst_rect.bottom - dst_rect.top;
|
||||||
|
float left_mixer_width = FLOAT(display_attributes.split_left);
|
||||||
|
|
||||||
|
// Layer cannot qualify for SrcSplit if source or destination width exceeds max pipe width.
|
||||||
|
// For perf/power optimization, even if "always_src_split" is enabled, use 2 pipes only if:
|
||||||
|
// Source width is greater than split_left (left_mixer_width)
|
||||||
|
if ((src_width > hw_res_info_.max_pipe_width) || (dst_width > hw_res_info_.max_pipe_width) ||
|
||||||
|
(display_resource_ctx->display_attributes.always_src_split && src_width > left_mixer_width)) {
|
||||||
|
SplitRect(src_rect, dst_rect, &left_pipe->src_roi, &left_pipe->dst_roi, &right_pipe->src_roi,
|
||||||
|
&right_pipe->dst_roi);
|
||||||
|
left_pipe->valid = true;
|
||||||
|
right_pipe->valid = true;
|
||||||
|
} else {
|
||||||
|
left_pipe->src_roi = src_rect;
|
||||||
|
left_pipe->dst_roi = dst_rect;
|
||||||
|
left_pipe->valid = true;
|
||||||
|
right_pipe->Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
return kErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayError ResourceDefault::DisplaySplitConfig(DisplayResourceContext *display_resource_ctx,
|
||||||
|
const LayerRect &src_rect, const LayerRect &dst_rect,
|
||||||
|
HWLayerConfig *layer_config) {
|
||||||
|
HWDisplayAttributes &display_attributes = display_resource_ctx->display_attributes;
|
||||||
|
|
||||||
|
// for display split case
|
||||||
|
HWPipeInfo *left_pipe = &layer_config->left_pipe;
|
||||||
|
HWPipeInfo *right_pipe = &layer_config->right_pipe;
|
||||||
|
LayerRect scissor_left, scissor_right, dst_left, crop_left, crop_right, dst_right;
|
||||||
|
|
||||||
|
scissor_left.right = FLOAT(display_attributes.split_left);
|
||||||
|
scissor_left.bottom = FLOAT(display_attributes.y_pixels);
|
||||||
|
|
||||||
|
scissor_right.left = FLOAT(display_attributes.split_left);
|
||||||
|
scissor_right.top = 0.0f;
|
||||||
|
scissor_right.right = FLOAT(display_attributes.x_pixels);
|
||||||
|
scissor_right.bottom = FLOAT(display_attributes.y_pixels);
|
||||||
|
|
||||||
|
crop_left = src_rect;
|
||||||
|
dst_left = dst_rect;
|
||||||
|
crop_right = crop_left;
|
||||||
|
dst_right = dst_left;
|
||||||
|
|
||||||
|
bool crop_left_valid = CalculateCropRects(scissor_left, &crop_left, &dst_left);
|
||||||
|
bool crop_right_valid = false;
|
||||||
|
|
||||||
|
if (IsValid(scissor_right)) {
|
||||||
|
crop_right_valid = CalculateCropRects(scissor_right, &crop_right, &dst_right);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset left_pipe and right_pipe to invalid by default
|
||||||
|
left_pipe->Reset();
|
||||||
|
right_pipe->Reset();
|
||||||
|
|
||||||
|
if (crop_left_valid) {
|
||||||
|
// assign left pipe
|
||||||
|
left_pipe->src_roi = crop_left;
|
||||||
|
left_pipe->dst_roi = dst_left;
|
||||||
|
left_pipe->valid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// assign right pipe if needed
|
||||||
|
if (crop_right_valid) {
|
||||||
|
right_pipe->src_roi = crop_right;
|
||||||
|
right_pipe->dst_roi = dst_right;
|
||||||
|
right_pipe->valid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return kErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayError ResourceDefault::Config(DisplayResourceContext *display_resource_ctx,
|
||||||
|
HWLayers *hw_layers) {
|
||||||
|
HWDisplayAttributes &display_attributes = display_resource_ctx->display_attributes;
|
||||||
|
HWLayersInfo &layer_info = hw_layers->info;
|
||||||
|
DisplayError error = kErrorNone;
|
||||||
|
uint32_t z_order = 0;
|
||||||
|
|
||||||
|
Layer& layer = layer_info.stack->layers[layer_info.index[0]];
|
||||||
|
|
||||||
|
error = ValidateLayerDimensions(layer);
|
||||||
|
if (error != kErrorNone) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct HWLayerConfig *layer_config = &hw_layers->config[0];
|
||||||
|
HWPipeInfo &left_pipe = layer_config->left_pipe;
|
||||||
|
HWPipeInfo &right_pipe = layer_config->right_pipe;
|
||||||
|
|
||||||
|
LayerRect src_rect = layer.src_rect;
|
||||||
|
LayerRect dst_rect = layer.dst_rect;
|
||||||
|
|
||||||
|
error = ValidateDimensions(src_rect, dst_rect);
|
||||||
|
if (error != kErrorNone) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = ValidateScaling(src_rect, dst_rect, false);
|
||||||
|
if (error != kErrorNone) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hw_res_info_.is_src_split) {
|
||||||
|
error = SrcSplitConfig(display_resource_ctx, src_rect, dst_rect, layer_config);
|
||||||
|
} else {
|
||||||
|
error = DisplaySplitConfig(display_resource_ctx, src_rect, dst_rect, layer_config);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error != kErrorNone) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = AlignPipeConfig(layer, &left_pipe, &right_pipe);
|
||||||
|
if (error != kErrorNone) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set z_order, left_pipe should always be valid
|
||||||
|
left_pipe.z_order = 0;
|
||||||
|
|
||||||
|
DLOGV_IF(kTagResources, "==== FB layer Config ====");
|
||||||
|
Log(kTagResources, "input layer src_rect", layer.src_rect);
|
||||||
|
Log(kTagResources, "input layer dst_rect", layer.dst_rect);
|
||||||
|
Log(kTagResources, "cropped src_rect", src_rect);
|
||||||
|
Log(kTagResources, "cropped dst_rect", dst_rect);
|
||||||
|
Log(kTagResources, "left pipe src", layer_config->left_pipe.src_roi);
|
||||||
|
Log(kTagResources, "left pipe dst", layer_config->left_pipe.dst_roi);
|
||||||
|
if (right_pipe.valid) {
|
||||||
|
right_pipe.z_order = 0;
|
||||||
|
Log(kTagResources, "right pipe src", layer_config->right_pipe.src_roi);
|
||||||
|
Log(kTagResources, "right pipe dst", layer_config->right_pipe.dst_roi);
|
||||||
|
}
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ResourceDefault::CalculateCropRects(const LayerRect &scissor, LayerRect *crop,
|
||||||
|
LayerRect *dst) {
|
||||||
|
float &crop_left = crop->left;
|
||||||
|
float &crop_top = crop->top;
|
||||||
|
float &crop_right = crop->right;
|
||||||
|
float &crop_bottom = crop->bottom;
|
||||||
|
float crop_width = crop->right - crop->left;
|
||||||
|
float crop_height = crop->bottom - crop->top;
|
||||||
|
|
||||||
|
float &dst_left = dst->left;
|
||||||
|
float &dst_top = dst->top;
|
||||||
|
float &dst_right = dst->right;
|
||||||
|
float &dst_bottom = dst->bottom;
|
||||||
|
float dst_width = dst->right - dst->left;
|
||||||
|
float dst_height = dst->bottom - dst->top;
|
||||||
|
|
||||||
|
const float &sci_left = scissor.left;
|
||||||
|
const float &sci_top = scissor.top;
|
||||||
|
const float &sci_right = scissor.right;
|
||||||
|
const float &sci_bottom = scissor.bottom;
|
||||||
|
|
||||||
|
float left_cut_ratio = 0.0, right_cut_ratio = 0.0, top_cut_ratio = 0.0, bottom_cut_ratio = 0.0;
|
||||||
|
bool need_cut = false;
|
||||||
|
|
||||||
|
if (dst_left < sci_left) {
|
||||||
|
left_cut_ratio = (sci_left - dst_left) / dst_width;
|
||||||
|
dst_left = sci_left;
|
||||||
|
need_cut = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dst_right > sci_right) {
|
||||||
|
right_cut_ratio = (dst_right - sci_right) / dst_width;
|
||||||
|
dst_right = sci_right;
|
||||||
|
need_cut = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dst_top < sci_top) {
|
||||||
|
top_cut_ratio = (sci_top - dst_top) / (dst_height);
|
||||||
|
dst_top = sci_top;
|
||||||
|
need_cut = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dst_bottom > sci_bottom) {
|
||||||
|
bottom_cut_ratio = (dst_bottom - sci_bottom) / (dst_height);
|
||||||
|
dst_bottom = sci_bottom;
|
||||||
|
need_cut = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!need_cut)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
crop_left += crop_width * left_cut_ratio;
|
||||||
|
crop_top += crop_height * top_cut_ratio;
|
||||||
|
crop_right -= crop_width * right_cut_ratio;
|
||||||
|
crop_bottom -= crop_height * bottom_cut_ratio;
|
||||||
|
Normalize(1, 1, crop);
|
||||||
|
Normalize(1, 1, dst);
|
||||||
|
if (IsValid(*crop) && IsValid(*dst))
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayError ResourceDefault::ValidateLayerDimensions(const Layer &layer) {
|
||||||
|
const LayerRect &src = layer.src_rect;
|
||||||
|
const LayerRect &dst = layer.dst_rect;
|
||||||
|
LayerBuffer *input_buffer = layer.input_buffer;
|
||||||
|
|
||||||
|
if (!IsValid(src) || !IsValid(dst)) {
|
||||||
|
Log(kTagResources, "input layer src_rect", src);
|
||||||
|
Log(kTagResources, "input layer dst_rect", dst);
|
||||||
|
return kErrorNotSupported;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure source in integral only if it is a non secure layer.
|
||||||
|
if (!input_buffer->flags.secure && (src.left - roundf(src.left) || src.top - roundf(src.top) ||
|
||||||
|
src.right - roundf(src.right) || src.bottom - roundf(src.bottom))) {
|
||||||
|
DLOGV_IF(kTagResources, "Input ROI is not integral");
|
||||||
|
return kErrorNotSupported;
|
||||||
|
}
|
||||||
|
|
||||||
|
return kErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayError ResourceDefault::ValidateDimensions(const LayerRect &crop, const LayerRect &dst) {
|
||||||
|
if (!IsValid(crop)) {
|
||||||
|
Log(kTagResources, "Invalid crop rect", crop);
|
||||||
|
return kErrorNotSupported;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsValid(dst)) {
|
||||||
|
Log(kTagResources, "Invalid dst rect", dst);
|
||||||
|
return kErrorNotSupported;
|
||||||
|
}
|
||||||
|
|
||||||
|
float crop_width = crop.right - crop.left;
|
||||||
|
float crop_height = crop.bottom - crop.top;
|
||||||
|
float dst_width = dst.right - dst.left;
|
||||||
|
float dst_height = dst.bottom - dst.top;
|
||||||
|
|
||||||
|
if ((UINT32(crop_width - dst_width) == 1) || (UINT32(crop_height - dst_height) == 1)) {
|
||||||
|
DLOGV_IF(kTagResources, "One pixel downscaling detected crop_w = %.0f, dst_w = %.0f, " \
|
||||||
|
"crop_h = %.0f, dst_h = %.0f", crop_width, dst_width, crop_height, dst_height);
|
||||||
|
return kErrorNotSupported;
|
||||||
|
}
|
||||||
|
|
||||||
|
return kErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayError ResourceDefault::ValidatePipeParams(HWPipeInfo *pipe_info) {
|
||||||
|
DisplayError error = kErrorNone;
|
||||||
|
|
||||||
|
const LayerRect &src_rect = pipe_info->src_roi;
|
||||||
|
const LayerRect &dst_rect = pipe_info->dst_roi;
|
||||||
|
|
||||||
|
error = ValidateDimensions(src_rect, dst_rect);
|
||||||
|
if (error != kErrorNone) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = ValidateScaling(src_rect, dst_rect, false);
|
||||||
|
if (error != kErrorNone) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return kErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayError ResourceDefault::ValidateScaling(const LayerRect &crop, const LayerRect &dst,
|
||||||
|
bool rotate90) {
|
||||||
|
DisplayError error = kErrorNone;
|
||||||
|
|
||||||
|
float scale_x = 1.0f;
|
||||||
|
float scale_y = 1.0f;
|
||||||
|
|
||||||
|
error = GetScaleFactor(crop, dst, &scale_x, &scale_y);
|
||||||
|
if (error != kErrorNone) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = ValidateDownScaling(scale_x, scale_y);
|
||||||
|
if (error != kErrorNone) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = ValidateUpScaling(scale_x, scale_y);
|
||||||
|
if (error != kErrorNone) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return kErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayError ResourceDefault::ValidateDownScaling(float scale_x, float scale_y) {
|
||||||
|
if ((UINT32(scale_x) > 1) || (UINT32(scale_y) > 1)) {
|
||||||
|
float max_scale_down = FLOAT(hw_res_info_.max_scale_down);
|
||||||
|
|
||||||
|
if (hw_res_info_.has_decimation) {
|
||||||
|
max_scale_down *= FLOAT(kMaxDecimationDownScaleRatio);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scale_x > max_scale_down || scale_y > max_scale_down) {
|
||||||
|
DLOGV_IF(kTagResources,
|
||||||
|
"Scaling down is over the limit: scale_x = %.0f, scale_y = %.0f, " \
|
||||||
|
"has_deci = %d", scale_x, scale_y, hw_res_info_.has_decimation);
|
||||||
|
return kErrorNotSupported;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DLOGV_IF(kTagResources, "scale_x = %.4f, scale_y = %.4f", scale_x, scale_y);
|
||||||
|
|
||||||
|
return kErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayError ResourceDefault::ValidateUpScaling(float scale_x, float scale_y) {
|
||||||
|
float max_scale_up = FLOAT(hw_res_info_.max_scale_up);
|
||||||
|
|
||||||
|
if (UINT32(scale_x) < 1 && scale_x > 0.0f) {
|
||||||
|
if ((1.0f / scale_x) > max_scale_up) {
|
||||||
|
DLOGV_IF(kTagResources, "Scaling up is over limit scale_x = %f", 1.0f / scale_x);
|
||||||
|
return kErrorNotSupported;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UINT32(scale_y) < 1 && scale_y > 0.0f) {
|
||||||
|
if ((1.0f / scale_y) > max_scale_up) {
|
||||||
|
DLOGV_IF(kTagResources, "Scaling up is over limit scale_y = %f", 1.0f / scale_y);
|
||||||
|
return kErrorNotSupported;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DLOGV_IF(kTagResources, "scale_x = %.4f, scale_y = %.4f", scale_x, scale_y);
|
||||||
|
|
||||||
|
return kErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayError ResourceDefault::GetScaleFactor(const LayerRect &crop, const LayerRect &dst,
|
||||||
|
float *scale_x, float *scale_y) {
|
||||||
|
float crop_width = crop.right - crop.left;
|
||||||
|
float crop_height = crop.bottom - crop.top;
|
||||||
|
float dst_width = dst.right - dst.left;
|
||||||
|
float dst_height = dst.bottom - dst.top;
|
||||||
|
|
||||||
|
*scale_x = crop_width / dst_width;
|
||||||
|
*scale_y = crop_height / dst_height;
|
||||||
|
|
||||||
|
return kErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayError ResourceDefault::SetDecimationFactor(HWPipeInfo *pipe) {
|
||||||
|
float src_h = pipe->src_roi.bottom - pipe->src_roi.top;
|
||||||
|
float dst_h = pipe->dst_roi.bottom - pipe->dst_roi.top;
|
||||||
|
float down_scale_h = src_h / dst_h;
|
||||||
|
|
||||||
|
float src_w = pipe->src_roi.right - pipe->src_roi.left;
|
||||||
|
float dst_w = pipe->dst_roi.right - pipe->dst_roi.left;
|
||||||
|
float down_scale_w = src_w / dst_w;
|
||||||
|
|
||||||
|
pipe->horizontal_decimation = 0;
|
||||||
|
pipe->vertical_decimation = 0;
|
||||||
|
|
||||||
|
if (CalculateDecimation(down_scale_w, &pipe->horizontal_decimation) != kErrorNone) {
|
||||||
|
return kErrorNotSupported;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CalculateDecimation(down_scale_h, &pipe->vertical_decimation) != kErrorNone) {
|
||||||
|
return kErrorNotSupported;
|
||||||
|
}
|
||||||
|
|
||||||
|
DLOGI_IF(kTagResources, "horizontal_decimation %d, vertical_decimation %d",
|
||||||
|
pipe->horizontal_decimation, pipe->vertical_decimation);
|
||||||
|
|
||||||
|
return kErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceDefault::SplitRect(const LayerRect &src_rect, const LayerRect &dst_rect,
|
||||||
|
LayerRect *src_left, LayerRect *dst_left, LayerRect *src_right,
|
||||||
|
LayerRect *dst_right) {
|
||||||
|
// Split rectangle horizontally and evenly into two.
|
||||||
|
float src_width = src_rect.right - src_rect.left;
|
||||||
|
float dst_width = dst_rect.right - dst_rect.left;
|
||||||
|
float src_width_ori = src_width;
|
||||||
|
src_width = ROUND_UP_ALIGN_DOWN(src_width / 2, 1);
|
||||||
|
dst_width = ROUND_UP_ALIGN_DOWN(dst_width * src_width / src_width_ori, 1);
|
||||||
|
|
||||||
|
src_left->left = src_rect.left;
|
||||||
|
src_left->right = src_rect.left + src_width;
|
||||||
|
src_right->left = src_left->right;
|
||||||
|
src_right->right = src_rect.right;
|
||||||
|
|
||||||
|
src_left->top = src_rect.top;
|
||||||
|
src_left->bottom = src_rect.bottom;
|
||||||
|
src_right->top = src_rect.top;
|
||||||
|
src_right->bottom = src_rect.bottom;
|
||||||
|
|
||||||
|
dst_left->top = dst_rect.top;
|
||||||
|
dst_left->bottom = dst_rect.bottom;
|
||||||
|
dst_right->top = dst_rect.top;
|
||||||
|
dst_right->bottom = dst_rect.bottom;
|
||||||
|
|
||||||
|
dst_left->left = dst_rect.left;
|
||||||
|
dst_left->right = dst_rect.left + dst_width;
|
||||||
|
dst_right->left = dst_left->right;
|
||||||
|
dst_right->right = dst_rect.right;
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayError ResourceDefault::AlignPipeConfig(const Layer &layer, HWPipeInfo *left_pipe,
|
||||||
|
HWPipeInfo *right_pipe) {
|
||||||
|
DisplayError error = kErrorNone;
|
||||||
|
if (!left_pipe->valid) {
|
||||||
|
DLOGE_IF(kTagResources, "left_pipe should not be invalid");
|
||||||
|
return kErrorNotSupported;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = ValidatePipeParams(left_pipe);
|
||||||
|
if (error != kErrorNone) {
|
||||||
|
goto PipeConfigExit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (right_pipe->valid) {
|
||||||
|
// Make sure the left and right ROI are conjunct
|
||||||
|
right_pipe->src_roi.left = left_pipe->src_roi.right;
|
||||||
|
right_pipe->dst_roi.left = left_pipe->dst_roi.right;
|
||||||
|
error = ValidatePipeParams(right_pipe);
|
||||||
|
}
|
||||||
|
|
||||||
|
PipeConfigExit:
|
||||||
|
if (error != kErrorNone) {
|
||||||
|
DLOGV_IF(kTagResources, "AlignPipeConfig failed");
|
||||||
|
}
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayError ResourceDefault::CalculateDecimation(float downscale, uint8_t *decimation) {
|
||||||
|
float max_down_scale = FLOAT(hw_res_info_.max_scale_down);
|
||||||
|
|
||||||
|
if (downscale <= max_down_scale) {
|
||||||
|
*decimation = 0;
|
||||||
|
return kErrorNone;
|
||||||
|
} else if (!hw_res_info_.has_decimation) {
|
||||||
|
DLOGE("Downscaling exceeds the maximum MDP downscale limit but decimation not enabled");
|
||||||
|
return kErrorNotSupported;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decimation is the remaining downscale factor after doing max SDE downscale.
|
||||||
|
// In SDE, decimation is supported in powers of 2.
|
||||||
|
// For ex: If a pipe needs downscale of 8 but max_down_scale is 4
|
||||||
|
// So decimation = powf(2.0, ceilf(log2f(8 / 4))) = powf(2.0, 1.0) = 2
|
||||||
|
*decimation = UINT8(ceilf(log2f(downscale / max_down_scale)));
|
||||||
|
return kErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace sdm
|
||||||
|
|
||||||
156
sdm/libs/core/resource_default.h
Normal file
156
sdm/libs/core/resource_default.h
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014 - 2015, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||||
|
* provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
|
||||||
|
* endorse or promote products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __RESOURCE_DEFAULT_H__
|
||||||
|
#define __RESOURCE_DEFAULT_H__
|
||||||
|
|
||||||
|
#include <core/display_interface.h>
|
||||||
|
#include <private/resource_interface.h>
|
||||||
|
#include <utils/locker.h>
|
||||||
|
|
||||||
|
#include "hw_interface.h"
|
||||||
|
|
||||||
|
namespace sdm {
|
||||||
|
|
||||||
|
class ResourceDefault : public ResourceInterface {
|
||||||
|
public:
|
||||||
|
ResourceDefault();
|
||||||
|
DisplayError Init(const HWResourceInfo &hw_resource_info);
|
||||||
|
DisplayError Deinit();
|
||||||
|
virtual DisplayError RegisterDisplay(DisplayType type, const HWDisplayAttributes &attributes,
|
||||||
|
const HWPanelInfo &hw_panel_info, Handle *display_ctx);
|
||||||
|
virtual DisplayError UnregisterDisplay(Handle display_ctx);
|
||||||
|
virtual void ReconfigureDisplay(Handle display_ctx, const HWDisplayAttributes &attributes,
|
||||||
|
const HWPanelInfo &hw_panel_info);
|
||||||
|
virtual DisplayError Start(Handle display_ctx);
|
||||||
|
virtual DisplayError Stop(Handle display_ctx);
|
||||||
|
virtual DisplayError Acquire(Handle display_ctx, HWLayers *hw_layers);
|
||||||
|
virtual DisplayError PostPrepare(Handle display_ctx, HWLayers *hw_layers);
|
||||||
|
virtual DisplayError PostCommit(Handle display_ctx, HWLayers *hw_layers);
|
||||||
|
virtual void Purge(Handle display_ctx);
|
||||||
|
virtual DisplayError SetMaxMixerStages(Handle display_ctx, uint32_t max_mixer_stages);
|
||||||
|
virtual DisplayError ValidateScaling(const LayerRect &crop, const LayerRect &dst,
|
||||||
|
bool rotate90);
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum PipeId {
|
||||||
|
kPipeIdVIG0,
|
||||||
|
kPipeIdVIG1,
|
||||||
|
kPipeIdVIG2,
|
||||||
|
kPipeIdRGB0,
|
||||||
|
kPipeIdRGB1,
|
||||||
|
kPipeIdRGB2,
|
||||||
|
kPipeIdDMA0,
|
||||||
|
kPipeIdDMA1,
|
||||||
|
kPipeIdVIG3,
|
||||||
|
kPipeIdRGB3,
|
||||||
|
kPipeIdMax,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum PipeType {
|
||||||
|
kPipeTypeUnused,
|
||||||
|
kPipeTypeVIG,
|
||||||
|
kPipeTypeRGB,
|
||||||
|
kPipeTypeDMA,
|
||||||
|
kPipeTypeMax,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum PipeOwner {
|
||||||
|
kPipeOwnerUserMode, // Pipe state when it is available for reservation
|
||||||
|
kPipeOwnerKernelMode, // Pipe state when pipe is owned by kernel
|
||||||
|
};
|
||||||
|
|
||||||
|
// todo: retrieve all these from kernel
|
||||||
|
enum {
|
||||||
|
kMaxDecimationDownScaleRatio = 8,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SourcePipe {
|
||||||
|
PipeType type;
|
||||||
|
PipeOwner owner;
|
||||||
|
uint32_t mdss_pipe_id;
|
||||||
|
uint32_t index;
|
||||||
|
HWBlockType hw_block_id;
|
||||||
|
int priority;
|
||||||
|
|
||||||
|
SourcePipe() : type(kPipeTypeUnused), owner(kPipeOwnerUserMode), mdss_pipe_id(kPipeIdMax),
|
||||||
|
index(0), hw_block_id(kHWBlockMax), priority(0) { }
|
||||||
|
|
||||||
|
inline void ResetState() { hw_block_id = kHWBlockMax;}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DisplayResourceContext {
|
||||||
|
HWDisplayAttributes display_attributes;
|
||||||
|
HWBlockType hw_block_id;
|
||||||
|
uint64_t frame_count;
|
||||||
|
|
||||||
|
DisplayResourceContext() : hw_block_id(kHWBlockMax), frame_count(0) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct HWBlockContext {
|
||||||
|
bool is_in_use;
|
||||||
|
HWBlockContext() : is_in_use(false) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
uint32_t GetMdssPipeId(PipeType pipe_type, uint32_t index);
|
||||||
|
uint32_t NextPipe(PipeType pipe_type, HWBlockType hw_block_id);
|
||||||
|
uint32_t SearchPipe(HWBlockType hw_block_id, SourcePipe *src_pipes, uint32_t num_pipe);
|
||||||
|
uint32_t GetPipe(HWBlockType hw_block_id, bool need_scale);
|
||||||
|
bool IsScalingNeeded(const HWPipeInfo *pipe_info);
|
||||||
|
DisplayError Config(DisplayResourceContext *display_resource_ctx, HWLayers *hw_layers);
|
||||||
|
DisplayError DisplaySplitConfig(DisplayResourceContext *display_resource_ctx,
|
||||||
|
const LayerRect &src_rect, const LayerRect &dst_rect,
|
||||||
|
HWLayerConfig *layer_config);
|
||||||
|
DisplayError SrcSplitConfig(DisplayResourceContext *display_resource_ctx,
|
||||||
|
const LayerRect &src_rect, const LayerRect &dst_rect,
|
||||||
|
HWLayerConfig *layer_config);
|
||||||
|
bool CalculateCropRects(const LayerRect &scissor, LayerRect *crop, LayerRect *dst);
|
||||||
|
DisplayError ValidateLayerDimensions(const Layer &layer);
|
||||||
|
DisplayError ValidateDimensions(const LayerRect &crop, const LayerRect &dst);
|
||||||
|
DisplayError ValidatePipeParams(HWPipeInfo *pipe_info);
|
||||||
|
DisplayError ValidateDownScaling(float scale_x, float scale_y);
|
||||||
|
DisplayError ValidateUpScaling(float scale_x, float scale_y);
|
||||||
|
DisplayError GetScaleFactor(const LayerRect &crop, const LayerRect &dst, float *scale_x,
|
||||||
|
float *scale_y);
|
||||||
|
DisplayError SetDecimationFactor(HWPipeInfo *pipe);
|
||||||
|
void SplitRect(const LayerRect &src_rect, const LayerRect &dst_rect, LayerRect *src_left,
|
||||||
|
LayerRect *dst_left, LayerRect *src_right, LayerRect *dst_right);
|
||||||
|
DisplayError AlignPipeConfig(const Layer &layer, HWPipeInfo *left_pipe, HWPipeInfo *right_pipe);
|
||||||
|
void ResourceStateLog(void);
|
||||||
|
DisplayError CalculateDecimation(float downscale, uint8_t *decimation);
|
||||||
|
|
||||||
|
Locker locker_;
|
||||||
|
HWResourceInfo hw_res_info_;
|
||||||
|
HWBlockContext hw_block_ctx_[kHWBlockMax];
|
||||||
|
SourcePipe src_pipes_[kPipeIdMax];
|
||||||
|
uint32_t num_pipe_;
|
||||||
|
SourcePipe *vig_pipes_;
|
||||||
|
SourcePipe *rgb_pipes_;
|
||||||
|
SourcePipe *dma_pipes_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace sdm
|
||||||
|
|
||||||
|
#endif // __RESOURCE_DEFAULT_H__
|
||||||
|
|
||||||
185
sdm/libs/core/strategy.cpp
Normal file
185
sdm/libs/core/strategy.cpp
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014 - 2015, The Linux Foundation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||||
|
* provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
|
||||||
|
* endorse or promote products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <utils/constants.h>
|
||||||
|
#include <utils/debug.h>
|
||||||
|
|
||||||
|
#include "strategy.h"
|
||||||
|
|
||||||
|
#define __CLASS__ "Strategy"
|
||||||
|
|
||||||
|
namespace sdm {
|
||||||
|
|
||||||
|
Strategy::Strategy(ExtensionInterface *extension_intf, DisplayType type,
|
||||||
|
const HWResourceInfo &hw_resource_info, const HWPanelInfo &hw_panel_info)
|
||||||
|
: extension_intf_(extension_intf), strategy_intf_(NULL), partial_update_intf_(NULL),
|
||||||
|
display_type_(type),hw_resource_info_(hw_resource_info), hw_panel_info_(hw_panel_info),
|
||||||
|
hw_layers_info_(NULL), fb_layer_index_(0), extn_start_success_(false), tried_default_(false) {
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayError Strategy::Init() {
|
||||||
|
DisplayError error = kErrorNone;
|
||||||
|
|
||||||
|
if (extension_intf_) {
|
||||||
|
error = extension_intf_->CreateStrategyExtn(display_type_, &strategy_intf_);
|
||||||
|
if (error != kErrorNone) {
|
||||||
|
DLOGE("Failed to create strategy");
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = extension_intf_->CreatePartialUpdate(display_type_, hw_resource_info_,
|
||||||
|
hw_panel_info_, &partial_update_intf_);
|
||||||
|
if (error != kErrorNone) {
|
||||||
|
DLOGW("Partial Update creation failed, Continue without partial update.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return kErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayError Strategy::Deinit() {
|
||||||
|
if (strategy_intf_) {
|
||||||
|
if (partial_update_intf_) {
|
||||||
|
extension_intf_->DestroyPartialUpdate(partial_update_intf_);
|
||||||
|
}
|
||||||
|
|
||||||
|
extension_intf_->DestroyStrategyExtn(strategy_intf_);
|
||||||
|
}
|
||||||
|
|
||||||
|
return kErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayError Strategy::Start(HWLayersInfo *hw_layers_info, uint32_t *max_attempts) {
|
||||||
|
DisplayError error = kErrorNone;
|
||||||
|
|
||||||
|
hw_layers_info_ = hw_layers_info;
|
||||||
|
extn_start_success_ = false;
|
||||||
|
tried_default_ = false;
|
||||||
|
|
||||||
|
uint32_t i = 0;
|
||||||
|
LayerStack *layer_stack = hw_layers_info_->stack;
|
||||||
|
for (; i < layer_stack->layer_count; i++) {
|
||||||
|
if (layer_stack->layers[i].composition == kCompositionGPUTarget) {
|
||||||
|
fb_layer_index_ = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == layer_stack->layer_count) {
|
||||||
|
return kErrorUndefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
GenerateROI();
|
||||||
|
|
||||||
|
if (strategy_intf_) {
|
||||||
|
error = strategy_intf_->Start(hw_layers_info_, max_attempts);
|
||||||
|
if (error == kErrorNone) {
|
||||||
|
extn_start_success_ = true;
|
||||||
|
return kErrorNone;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*max_attempts = 1;
|
||||||
|
|
||||||
|
return kErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayError Strategy::Stop() {
|
||||||
|
if (extn_start_success_) {
|
||||||
|
return strategy_intf_->Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
return kErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayError Strategy::GetNextStrategy(StrategyConstraints *constraints) {
|
||||||
|
DisplayError error = kErrorNone;
|
||||||
|
|
||||||
|
if (extn_start_success_) {
|
||||||
|
error = strategy_intf_->GetNextStrategy(constraints);
|
||||||
|
if (error == kErrorNone) {
|
||||||
|
return kErrorNone;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default composition is already tried.
|
||||||
|
if (tried_default_) {
|
||||||
|
return kErrorUndefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark all layers for GPU composition. Find GPU target buffer and store its index for
|
||||||
|
// programming the hardware.
|
||||||
|
LayerStack *layer_stack = hw_layers_info_->stack;
|
||||||
|
uint32_t &hw_layer_count = hw_layers_info_->count;
|
||||||
|
hw_layer_count = 0;
|
||||||
|
for (uint32_t i = 0; i < layer_stack->layer_count; i++) {
|
||||||
|
LayerComposition &composition = layer_stack->layers[i].composition;
|
||||||
|
if (composition == kCompositionGPUTarget) {
|
||||||
|
hw_layers_info_->index[hw_layer_count++] = i;
|
||||||
|
} else {
|
||||||
|
composition = kCompositionGPU;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tried_default_ = true;
|
||||||
|
|
||||||
|
// There can be one and only one GPU target buffer.
|
||||||
|
if (hw_layer_count != 1) {
|
||||||
|
return kErrorParameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
return kErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Strategy::GenerateROI() {
|
||||||
|
bool split_display = false;
|
||||||
|
|
||||||
|
if (partial_update_intf_ && partial_update_intf_->GenerateROI(hw_layers_info_) == kErrorNone) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LayerStack *layer_stack = hw_layers_info_->stack;
|
||||||
|
LayerRect &src_rect = layer_stack->layers[fb_layer_index_].src_rect;
|
||||||
|
// TODO(user): read panels x_pixels and y_pixels instead of fb_x_res and fb_y_res
|
||||||
|
float fb_x_res = src_rect.right - src_rect.left;
|
||||||
|
float fb_y_res = src_rect.bottom - src_rect.top;
|
||||||
|
|
||||||
|
if (!hw_resource_info_.is_src_split &&
|
||||||
|
((fb_x_res > hw_resource_info_.max_mixer_width) ||
|
||||||
|
((display_type_ == kPrimary) && hw_panel_info_.split_info.right_split))) {
|
||||||
|
split_display = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (split_display) {
|
||||||
|
float left_split = FLOAT(hw_panel_info_.split_info.left_split);
|
||||||
|
hw_layers_info_->left_partial_update = (LayerRect) {0.0f, 0.0f, left_split, fb_y_res};
|
||||||
|
hw_layers_info_->right_partial_update = (LayerRect) {left_split, 0.0f, fb_x_res, fb_y_res};
|
||||||
|
} else {
|
||||||
|
hw_layers_info_->left_partial_update = (LayerRect) {0.0f, 0.0f, fb_x_res, fb_y_res};
|
||||||
|
hw_layers_info_->right_partial_update = (LayerRect) {0.0f, 0.0f, 0.0f, 0.0f};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace sdm
|
||||||
|
|
||||||
@@ -22,54 +22,42 @@
|
|||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* 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,
|
|
||||||
kTripleBuffering = 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DisplayRotatorContext {
|
ExtensionInterface *extension_intf_;
|
||||||
DisplayType display_type;
|
StrategyInterface *strategy_intf_;
|
||||||
|
PartialUpdateInterface *partial_update_intf_;
|
||||||
DisplayRotatorContext() : display_type(kPrimary) { }
|
DisplayType display_type_;
|
||||||
};
|
HWResourceInfo hw_resource_info_;
|
||||||
|
HWPanelInfo hw_panel_info_;
|
||||||
DisplayError PrepareSessions(DisplayRotatorContext *disp_rotator_ctx, HWLayers *hw_layers);
|
HWLayersInfo *hw_layers_info_;
|
||||||
DisplayError GetOutputBuffers(DisplayRotatorContext *disp_rotator_ctx, HWLayers *hw_layers);
|
uint32_t fb_layer_index_;
|
||||||
|
bool extn_start_success_;
|
||||||
HWRotatorInterface *hw_rotator_intf_;
|
bool tried_default_;
|
||||||
SessionManager *session_manager_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sde
|
} // namespace sdm
|
||||||
|
|
||||||
#endif // __ROTATOR_CTRL_H__
|
#endif // __STRATEGY_H__
|
||||||
|
|
||||||
@@ -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 \
|
||||||
@@ -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
|
||||||
@@ -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__
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -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__
|
||||||
|
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -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__
|
||||||
|
|
||||||
@@ -40,14 +40,14 @@
|
|||||||
|
|
||||||
#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)
|
||||||
: core_intf_(core_intf), hwc_procs_(hwc_procs), type_(type), id_(id), display_intf_(NULL),
|
: core_intf_(core_intf), hwc_procs_(hwc_procs), type_(type), id_(id), display_intf_(NULL),
|
||||||
flush_(false), output_buffer_(NULL), dump_frame_count_(0), dump_frame_index_(0),
|
flush_(false), output_buffer_(NULL), dump_frame_count_(0), dump_frame_index_(0),
|
||||||
dump_input_layers_(false), swap_interval_zero_(false), framebuffer_config_(NULL),
|
dump_input_layers_(false), swap_interval_zero_(false), framebuffer_config_(NULL),
|
||||||
display_paused_(false), use_metadata_refresh_rate_(false),metadata_refresh_rate_(0) {
|
display_paused_(false), use_metadata_refresh_rate_(false), metadata_refresh_rate_(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int HWCDisplay::Init() {
|
int HWCDisplay::Init() {
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -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__
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -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__
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -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__
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -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__
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -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__
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|
||||||
Reference in New Issue
Block a user