Merge "sde: Remove redundant PostPrepare in Prepare function"
diff --git a/displayengine/include/core/debug_interface.h b/displayengine/include/core/debug_interface.h
index c90e1ff..ff72321 100644
--- a/displayengine/include/core/debug_interface.h
+++ b/displayengine/include/core/debug_interface.h
@@ -48,6 +48,7 @@
kTagDriverConfig, //!< Debug log is tagged for driver config.
kTagBufferManager, //!< Debug log is tagged for buffer manager state transitions.
kTagOfflineCtrl, //!< Debug log is tagged for offline controller.
+ kTagScalar, //!< Debug log is tagged for Scalar Helper.
};
/*! @brief Display debug handler class.
diff --git a/displayengine/libs/core/Android.mk b/displayengine/libs/core/Android.mk
index c4c3d87..b7d2478 100644
--- a/displayengine/libs/core/Android.mk
+++ b/displayengine/libs/core/Android.mk
@@ -4,11 +4,14 @@
LOCAL_MODULE := libsde
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES := hardware/qcom/display/displayengine/include/ \
- $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include \
- $(TARGET_OUT_HEADERS)/scalar/inc
+ $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
LOCAL_CFLAGS := -Wno-missing-field-initializers -Wno-unused-parameter \
-Wconversion -Wall -Werror \
-DLOG_TAG=\"SDE\"
+ifeq ($(TARGET_USES_SCALAR), true)
+ LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/scalar/inc
+ LOCAL_CFLAGS += -DUSES_SCALAR
+endif
LOCAL_SHARED_LIBRARIES := libdl libsdeutils libcutils
LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
LOCAL_SRC_FILES := core_interface.cpp \
@@ -25,6 +28,7 @@
hw_interface.cpp \
hw_framebuffer.cpp \
dump_impl.cpp \
- buffer_manager.cpp
+ buffer_manager.cpp \
+ scalar_helper.cpp
include $(BUILD_SHARED_LIBRARY)
diff --git a/displayengine/libs/core/hw_framebuffer.cpp b/displayengine/libs/core/hw_framebuffer.cpp
index 73f371e..f3cdb8b 100644
--- a/displayengine/libs/core/hw_framebuffer.cpp
+++ b/displayengine/libs/core/hw_framebuffer.cpp
@@ -43,7 +43,7 @@
#include <utils/debug.h>
#include "hw_framebuffer.h"
-
+#include "scalar_helper.h"
#define __CLASS__ "HWFrameBuffer"
@@ -706,14 +706,16 @@
}
}
- if (pipe_info->scale_data.enable_pxl_ext) {
+ mdp_scale_data* mdp_scale = hw_display->GetScaleDataRef(mdp_layer_count);
+#ifdef USES_SCALAR
+ // Set the configured scale data for MDP driver
+ ScalarHelper::GetInstance()->SetScaleData(i, !count, mdp_scale);
+ if (mdp_scale->enable_pxl_ext) {
if ((mdp_layer.flags & MDP_LAYER_DEINTERLACE) && (layer.transform.rotation == 90.0f))
- mdp_buffer.width = pipe_info->scale_data.src_width;
- hw_display->SetScaleData(pipe_info->scale_data, mdp_layer_count);
+ ScalarHelper::GetInstance()->UpdateSrcWidth(i, !count, &mdp_buffer.width);
}
-
- // Send scale data to MDP driver
- mdp_layer.scale = hw_display->GetScaleRef(mdp_layer_count);
+#endif
+ mdp_layer.scale = mdp_scale;
mdp_layer_count++;
DLOGV_IF(kTagDriverConfig, "******************* Layer[%d] %s pipe Input ******************",
@@ -764,12 +766,34 @@
mdp_commit.flags |= MDP_VALIDATE_LAYER;
if (ioctl_(hw_context->device_fd, MSMFB_ATOMIC_COMMIT, &hw_display->mdp_disp_commit) < 0) {
IOCTL_LOGE(MSMFB_ATOMIC_COMMIT, hw_context->type);
+ DumpLayerCommit(hw_display->mdp_disp_commit);
return kErrorHardware;
}
return kErrorNone;
}
+void HWFrameBuffer::DumpLayerCommit(mdp_layer_commit &layer_commit) {
+ mdp_layer_commit_v1 &mdp_commit = layer_commit.commit_v1;
+ mdp_input_layer *mdp_layers = mdp_commit.input_layers;
+
+ DLOGE("mdp_commt: flags = %x, release fence = %x", mdp_commit.flags, mdp_commit.release_fence);
+ DLOGE("left_roi: x = %d, y = %d, w = %d, h = %d", mdp_commit.left_roi.x, mdp_commit.left_roi.y,
+ mdp_commit.left_roi.w, mdp_commit.left_roi.h);
+ DLOGE("right_roi: x = %d, y = %d, w = %d, h = %d", mdp_commit.right_roi.x,
+ mdp_commit.right_roi.y, mdp_commit.right_roi.w, mdp_commit.right_roi.h);
+ for (uint32_t i = 0; i < mdp_commit.input_layer_cnt; i++) {
+ DLOGE("mdp_commt: layer_cnt = %d, pipe_ndx = %x, zorder = %d, flags = %x",
+ i, mdp_layers[i].pipe_ndx, mdp_layers[i].z_order, mdp_layers[i].flags);
+ mdp_rect &src_rect = mdp_layers[i].src_rect;
+ DLOGE("src rect: x = %d, y = %d, w = %d, h = %d",
+ src_rect.x, src_rect.y, src_rect.w, src_rect.h);
+ mdp_rect &dst_rect = mdp_layers[i].dst_rect;
+ DLOGE("dst rect: x = %d, y = %d, w = %d, h = %d",
+ dst_rect.x, dst_rect.y, dst_rect.w, dst_rect.h);
+ }
+}
+
DisplayError HWFrameBuffer::DisplayCommit(HWContext *hw_context, HWLayers *hw_layers) {
DTRACE_SCOPED();
@@ -857,6 +881,7 @@
mdp_commit.flags &= ~MDP_VALIDATE_LAYER;
if (ioctl_(hw_context->device_fd, MSMFB_ATOMIC_COMMIT, &hw_display->mdp_disp_commit) < 0) {
IOCTL_LOGE(MSMFB_ATOMIC_COMMIT, hw_context->type);
+ DumpLayerCommit(hw_display->mdp_disp_commit);
return kErrorHardware;
}
@@ -1090,6 +1115,7 @@
mdp_commit.flags &= ~MDP_VALIDATE_LAYER;
if (ioctl_(hw_context->device_fd, MSMFB_ATOMIC_COMMIT, &hw_display->mdp_disp_commit) < 0) {
IOCTL_LOGE(MSMFB_ATOMIC_COMMIT, hw_context->type);
+ DumpLayerCommit(hw_display->mdp_disp_commit);
return kErrorHardware;
}
}
@@ -1152,6 +1178,7 @@
*target = width * 3;
break;
case kFormatYCbCr420SemiPlanarVenus:
+ case kFormatYCbCr420SPVenusUbwc:
case kFormatYCbCr420Planar:
case kFormatYCrCb420Planar:
case kFormatYCbCr420SemiPlanar:
diff --git a/displayengine/libs/core/hw_framebuffer.h b/displayengine/libs/core/hw_framebuffer.h
index 68a0674..b2a37ab 100644
--- a/displayengine/libs/core/hw_framebuffer.h
+++ b/displayengine/libs/core/hw_framebuffer.h
@@ -89,36 +89,7 @@
mdp_disp_commit.commit_v1.retire_fence = -1;
}
- mdp_scale_data* GetScaleRef(uint32_t index) { return &scale_data[index]; }
-
- void SetScaleData(scalar::Scale scale, uint32_t index) {
- mdp_scale_data *mdp_scale = &scale_data[index];
- mdp_scale->enable_pxl_ext = scale.enable_pxl_ext;
-
- for (int i = 0; i < MAX_PLANES; i++) {
- mdp_scale->init_phase_x[i] = scale.init_phase_x[i];
- mdp_scale->phase_step_x[i] = scale.phase_step_x[i];
- mdp_scale->init_phase_y[i] = scale.init_phase_y[i];
- mdp_scale->phase_step_y[i] = scale.phase_step_y[i];
-
- mdp_scale->num_ext_pxls_left[i] = scale.left.extension[i];
- mdp_scale->num_ext_pxls_top[i] = scale.top.extension[i];
- mdp_scale->num_ext_pxls_right[i] = scale.right.extension[i];
- mdp_scale->num_ext_pxls_btm[i] = scale.bottom.extension[i];
-
- mdp_scale->left_ftch[i] = scale.left.overfetch[i];
- mdp_scale->top_ftch[i] = scale.top.overfetch[i];
- mdp_scale->right_ftch[i] = scale.right.overfetch[i];
- mdp_scale->btm_ftch[i] = scale.bottom.overfetch[i];
-
- mdp_scale->left_rpt[i] = scale.left.repeat[i];
- mdp_scale->top_rpt[i] = scale.top.repeat[i];
- mdp_scale->right_rpt[i] = scale.right.repeat[i];
- mdp_scale->btm_rpt[i] = scale.bottom.repeat[i];
-
- mdp_scale->roi_w[i] = scale.roi_width[i];
- }
- }
+ mdp_scale_data* GetScaleDataRef(uint32_t index) { return &scale_data[index]; }
};
struct HWRotator {
@@ -198,7 +169,7 @@
DisplayError RotatorValidate(HWContext *device_ctx, HWLayers *hw_layers);
DisplayError RotatorCommit(HWContext *device_ctx, HWLayers *hw_layers);
-
+ void DumpLayerCommit(mdp_layer_commit &layer_commit);
inline DisplayError SetFormat(const LayerBufferFormat &source, uint32_t *target);
inline DisplayError SetStride(HWDeviceType device_type, LayerBufferFormat format,
uint32_t width, uint32_t *target);
diff --git a/displayengine/libs/core/hw_interface.h b/displayengine/libs/core/hw_interface.h
index 9a60d8c..b92846f 100644
--- a/displayengine/libs/core/hw_interface.h
+++ b/displayengine/libs/core/hw_interface.h
@@ -30,7 +30,6 @@
#include <utils/constants.h>
#include <core/buffer_allocator.h>
#include <core/buffer_sync_handler.h>
-#include <scalar.h>
namespace sde {
@@ -131,7 +130,6 @@
LayerRect dst_roi;
uint8_t horizontal_decimation;
uint8_t vertical_decimation;
- scalar::Scale scale_data;
bool valid;
uint32_t z_order;
diff --git a/displayengine/libs/core/res_config.cpp b/displayengine/libs/core/res_config.cpp
index 32d9891..1b5bb6d 100644
--- a/displayengine/libs/core/res_config.cpp
+++ b/displayengine/libs/core/res_config.cpp
@@ -31,17 +31,15 @@
#define __CLASS__ "ResManager"
-using scalar::PipeInfo;
-using scalar::LayerInfo;
-
namespace sde {
-void ResManager::RotationConfig(const LayerTransform &transform, const float &downscale,
- LayerRect *src_rect, struct HWLayerConfig *layer_config,
- uint32_t *rotate_count) {
+void ResManager::RotationConfig(LayerBufferFormat format, const LayerTransform &transform,
+ const float &downscale, LayerRect *src_rect,
+ struct HWLayerConfig *layer_config, uint32_t *rotate_count) {
HWRotateInfo *rotate = &layer_config->rotates[0];
float src_width = src_rect->right - src_rect->left;
float src_height = src_rect->bottom - src_rect->top;
+ bool rot90 = IsRotationNeeded(transform.rotation);
LayerRect dst_rect;
// Rotate output is a temp buffer, always output to the top left corner for saving memory
dst_rect.top = 0.0f;
@@ -50,7 +48,7 @@
rotate->downscale_ratio = downscale;
// downscale when doing rotation
- if (IsRotationNeeded(transform.rotation)) {
+ if (rot90) {
if (downscale > 1.0f) {
src_height = ROUND_UP_ALIGN_DOWN(src_height, downscale);
src_rect->bottom = src_rect->top + src_height;
@@ -74,6 +72,14 @@
rotate->valid = true;
rotate->dst_roi = dst_rect;
+ // Set WHF for Rotator output
+ LayerBufferFormat ouput_format;
+ SetRotatorOutputFormat(format, false /* bwc */, rot90, downscale, &ouput_format);
+ HWBufferInfo *hw_buffer_info = &rotate->hw_buffer_info;
+ hw_buffer_info->buffer_config.format = ouput_format;
+ hw_buffer_info->buffer_config.width = UINT32(rotate->dst_roi.right);
+ hw_buffer_info->buffer_config.height = UINT32(rotate->dst_roi.bottom);
+
*src_rect = dst_rect;
layer_config->num_rotate = 1;
(*rotate_count)++;
@@ -243,7 +249,8 @@
LayerTransform transform = layer.transform;
if (IsRotationNeeded(transform.rotation) || UINT32(rot_scale) != 1) {
- RotationConfig(layer.transform, rot_scale, &src_rect, layer_config, rotate_count);
+ RotationConfig(layer.input_buffer->format, layer.transform, rot_scale, &src_rect,
+ layer_config, rotate_count);
// rotator will take care of flipping, reset tranform
transform = LayerTransform();
}
@@ -586,125 +593,6 @@
}
}
-// Scalar helper functions
-static void SetPipeInfo(HWPipeInfo* hw_pipe, PipeInfo* pipe) {
- pipe->id = hw_pipe->pipe_id;
- pipe->scale_data = &hw_pipe->scale_data;
- 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;
-}
-
-static void UpdateSrcRoi(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);
-}
-
-static uint32_t 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 kFormatRGB888: format = scalar::RGB_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 kFormatYCbCr422Packed: format = scalar::YCBYCR_H2V1; break;
- case kFormatYCbCr420SemiPlanarVenus: format = scalar::Y_CBCR_H2V2_VENUS; break;
- case kFormatRGBA8888Ubwc: format = scalar::RGBA_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;
-}
-
-bool ResManager::ConfigureScaling(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]];
- LayerBuffer *input_buffer = layer.input_buffer;
- HWPipeInfo* left_pipe = &hw_layers->config[i].left_pipe;
- HWPipeInfo* right_pipe = &hw_layers->config[i].right_pipe;
-
- // Prepare data structure for lib scalar
- uint32_t flags = 0;
- struct LayerInfo layer_info;
-
- 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++) {
- HWPipeInfo* hw_pipe = (count == 0) ? left_pipe : right_pipe;
- HWRotateInfo* rotate_info = &hw_layers->config[i].rotates[count];
- PipeInfo* scalar_pipe = (count == 0) ? &layer_info.left_pipe : &layer_info.right_pipe;
-
- if (rotate_info->valid)
- input_buffer = &rotate_info->hw_buffer_info.output_buffer;
-
- scalar_pipe->flags = flags;
- hw_pipe->scale_data.src_width = input_buffer->width;
- SetPipeInfo(hw_pipe, scalar_pipe);
- }
- layer_info.src_format = GetScalarFormat(input_buffer->format);
-
- DLOGV_IF(kTagResources, "Scalar Input[%d] flags=%x format=%x", i, flags, layer_info.src_format);
- DLOGV_IF(kTagResources, "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(kTagResources, "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 (ScalarConfigureScale(&layer_info) < 0) {
- DLOGE("Scalar library failed to configure scale data!");
- return false;
- }
-
- // Update Src Roi in HWPipeInfo
- if (left_pipe->scale_data.enable_pxl_ext)
- UpdateSrcRoi(&layer_info.left_pipe, left_pipe);
- if (right_pipe->scale_data.enable_pxl_ext)
- UpdateSrcRoi(&layer_info.right_pipe, right_pipe);
- }
-
- return true;
-}
-
DisplayError ResManager::AlignPipeConfig(const Layer &layer, const LayerTransform &transform,
HWPipeInfo *left_pipe, HWPipeInfo *right_pipe,
uint32_t align_x, uint32_t align_y) {
diff --git a/displayengine/libs/core/res_manager.cpp b/displayengine/libs/core/res_manager.cpp
index 336087e..dbb41e5 100644
--- a/displayengine/libs/core/res_manager.cpp
+++ b/displayengine/libs/core/res_manager.cpp
@@ -28,9 +28,9 @@
#include <dlfcn.h>
#include "res_manager.h"
+#include "scalar_helper.h"
#define __CLASS__ "ResManager"
-#define SCALAR_LIBRARY_NAME "libscalar.so"
namespace sde {
@@ -121,23 +121,16 @@
rgb_pipes_[0].state = kPipeStateOwnedByKernel;
rgb_pipes_[1].state = kPipeStateOwnedByKernel;
- ScalarConfigureScale = NULL;
- lib_scalar_handle_ = dlopen(SCALAR_LIBRARY_NAME, RTLD_NOW);
- if (lib_scalar_handle_) {
- void **scalar_func = reinterpret_cast<void **>(&ScalarConfigureScale);
- *scalar_func = ::dlsym(lib_scalar_handle_, "configureScale");
- } else {
- DLOGW("Unable to load %s !", SCALAR_LIBRARY_NAME);
- }
-
+#ifdef USES_SCALAR
+ ScalarHelper::GetInstance()->Init();
+#endif
return kErrorNone;
}
DisplayError ResManager::Deinit() {
- if (lib_scalar_handle_) {
- dlclose(lib_scalar_handle_);
- lib_scalar_handle_ = NULL;
- }
+#ifdef USES_SCALAR
+ ScalarHelper::GetInstance()->Deinit();
+#endif
return kErrorNone;
}
@@ -392,24 +385,24 @@
i, layer_config.left_pipe.pipe_id, pipe_info->pipe_id);
}
- error = AllocRotatorBuffer(display_ctx, hw_layers);
- if (error != kErrorNone) {
- DLOGV_IF(kTagResources, "Rotator buffer allocation failed");
+#ifdef USES_SCALAR
+ if (!ScalarHelper::GetInstance()->ConfigureScale(hw_layers)) {
+ DLOGV_IF(kTagResources, "Scale data configuration has failed!");
goto CleanupOnError;
}
-
- if (lib_scalar_handle_ && ScalarConfigureScale) {
- if (!ConfigureScaling(hw_layers)) {
- DLOGV_IF(kTagResources, "Scale data configuration has failed!");
- goto CleanupOnError;
- }
- }
+#endif
if (!CheckBandwidth(display_resource_ctx, hw_layers)) {
DLOGV_IF(kTagResources, "Bandwidth check failed!");
goto CleanupOnError;
}
+ error = AllocRotatorBuffer(display_ctx, hw_layers);
+ if (error != kErrorNone) {
+ DLOGV_IF(kTagResources, "Rotator buffer allocation failed");
+ goto CleanupOnError;
+ }
+
return kErrorNone;
CleanupOnError:
@@ -628,6 +621,7 @@
case kFormatYCbCr420SemiPlanar:
case kFormatYCrCb420SemiPlanar:
case kFormatYCbCr420SemiPlanarVenus:
+ case kFormatYCbCr420SPVenusUbwc:
return 1.5f;
default:
DLOGE("GetBpp: Invalid buffer format: %x", format);
@@ -650,16 +644,9 @@
for (uint32_t i = 0; i < layer_info.count; i++) {
Layer& layer = layer_info.stack->layers[layer_info.index[i]];
HWRotateInfo *rotate = &hw_layers->config[i].rotates[0];
- bool rot90 = (layer.transform.rotation == 90.0f);
if (rotate->valid) {
- LayerBufferFormat rot_ouput_format;
- SetRotatorOutputFormat(layer.input_buffer->format, false, rot90, &rot_ouput_format);
-
HWBufferInfo *hw_buffer_info = &rotate->hw_buffer_info;
- hw_buffer_info->buffer_config.width = UINT32(rotate->dst_roi.right - rotate->dst_roi.left);
- hw_buffer_info->buffer_config.height = UINT32(rotate->dst_roi.bottom - rotate->dst_roi.top);
- hw_buffer_info->buffer_config.format = rot_ouput_format;
// Allocate two rotator output buffers by default for double buffering.
hw_buffer_info->buffer_config.buffer_count = 2;
hw_buffer_info->buffer_config.secure = layer.input_buffer->flags.secure;
@@ -672,13 +659,7 @@
rotate = &hw_layers->config[i].rotates[1];
if (rotate->valid) {
- LayerBufferFormat rot_ouput_format;
- SetRotatorOutputFormat(layer.input_buffer->format, false, rot90, &rot_ouput_format);
-
HWBufferInfo *hw_buffer_info = &rotate->hw_buffer_info;
- hw_buffer_info->buffer_config.width = UINT32(rotate->dst_roi.right - rotate->dst_roi.left);
- hw_buffer_info->buffer_config.height = UINT32(rotate->dst_roi.bottom - rotate->dst_roi.top);
- hw_buffer_info->buffer_config.format = rot_ouput_format;
// Allocate two rotator output buffers by default for double buffering.
hw_buffer_info->buffer_config.buffer_count = 2;
hw_buffer_info->buffer_config.secure = layer.input_buffer->flags.secure;
@@ -1100,33 +1081,32 @@
}
void ResManager::SetRotatorOutputFormat(const LayerBufferFormat &input_format, bool bwc, bool rot90,
- LayerBufferFormat *output_format) {
+ bool downscale, LayerBufferFormat *output_format) {
+ *output_format = input_format;
+
switch (input_format) {
case kFormatRGB565:
if (rot90)
*output_format = kFormatRGB888;
- else
- *output_format = input_format;
break;
case kFormatRGBA8888:
if (bwc)
*output_format = kFormatBGRA8888;
- else
- *output_format = input_format;
break;
case kFormatYCbCr420SemiPlanarVenus:
case kFormatYCbCr420SemiPlanar:
if (rot90)
*output_format = kFormatYCrCb420SemiPlanar;
- else
- *output_format = input_format;
+ break;
+ case kFormatYCbCr420SPVenusUbwc:
+ if (downscale)
+ *output_format = kFormatYCrCb420SemiPlanar;
break;
case kFormatYCbCr420Planar:
case kFormatYCrCb420Planar:
*output_format = kFormatYCrCb420SemiPlanar;
break;
default:
- *output_format = input_format;
break;
}
@@ -1136,8 +1116,5 @@
return;
}
-void* ResManager::lib_scalar_handle_ = NULL;
-int (*ResManager::ScalarConfigureScale)(struct scalar::LayerInfo* layer) = NULL;
-
} // namespace sde
diff --git a/displayengine/libs/core/res_manager.h b/displayengine/libs/core/res_manager.h
index 0244cfb..be785c1 100644
--- a/displayengine/libs/core/res_manager.h
+++ b/displayengine/libs/core/res_manager.h
@@ -194,17 +194,16 @@
bool IsYuvFormat(LayerBufferFormat format) { return (format >= kFormatYCbCr420Planar); }
bool IsRotationNeeded(float rotation)
{ return (UINT32(rotation) == 90 || UINT32(rotation) == 270); }
- void RotationConfig(const LayerTransform &transform, const float &downscale,
- LayerRect *src_rect, struct HWLayerConfig *layer_config,
- uint32_t *rotate_count);
+ void RotationConfig(LayerBufferFormat format, const LayerTransform &transform,
+ const float &downscale, LayerRect *src_rect,
+ struct 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);
DisplayError AllocRotatorBuffer(Handle display_ctx, HWLayers *hw_layers);
void SetRotatorOutputFormat(const LayerBufferFormat &input_format, bool bwc, bool rot90,
- LayerBufferFormat *output_format);
- bool ConfigureScaling(HWLayers *hw_layers);
+ bool downscale, LayerBufferFormat *output_format);
DisplayError AlignPipeConfig(const Layer &layer, const LayerTransform &transform,
HWPipeInfo *left_pipe, HWPipeInfo *right_pipe,
uint32_t align_x, uint32_t align_y);
@@ -227,8 +226,6 @@
BufferAllocator *buffer_allocator_;
BufferSyncHandler *buffer_sync_handler_; // Pointer to buffer sync handler that was defined by
// the display engine's client
- static void* lib_scalar_handle_; // Scalar library handle
- static int (*ScalarConfigureScale)(struct scalar::LayerInfo* layer);
PropertySetting property_setting_;
};
diff --git a/displayengine/libs/core/scalar_helper.cpp b/displayengine/libs/core/scalar_helper.cpp
new file mode 100755
index 0000000..22488b3
--- /dev/null
+++ b/displayengine/libs/core/scalar_helper.cpp
@@ -0,0 +1,231 @@
+/*
+* 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.
+*/
+
+#ifdef USES_SCALAR
+
+#include <dlfcn.h>
+#include <utils/debug.h>
+#include "scalar_helper.h"
+
+#define __CLASS__ "ScalarHelper"
+
+namespace sde {
+
+ScalarHelper* ScalarHelper::scalar_helper_ = NULL;
+
+ScalarHelper* ScalarHelper::GetInstance() {
+ if (scalar_helper_ == NULL) {
+ scalar_helper_ = new ScalarHelper();
+ }
+ return scalar_helper_;
+}
+
+// Scalar helper functions
+static void SetPipeInfo(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;
+}
+
+static void UpdateSrcRoi(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);
+}
+
+static uint32_t 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 kFormatRGB888: format = scalar::RGB_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 kFormatYCbCr422Packed: format = scalar::YCBYCR_H2V1; break;
+ case kFormatYCbCr420SemiPlanarVenus: format = scalar::Y_CBCR_H2V2_VENUS; break;
+ case kFormatRGBA8888Ubwc: format = scalar::RGBA_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;
+}
+
+void ScalarHelper::Init() {
+ lib_scalar_handle_ = NULL;
+ ScalarConfigureScale = NULL;
+
+ lib_scalar_handle_ = dlopen(SCALAR_LIBRARY_NAME, RTLD_NOW);
+ if (lib_scalar_handle_) {
+ void **scalar_func = reinterpret_cast<void **>(&ScalarConfigureScale);
+ *scalar_func = ::dlsym(lib_scalar_handle_, "configureScale");
+ } else {
+ DLOGW("Unable to load %s !", SCALAR_LIBRARY_NAME);
+ }
+}
+
+void ScalarHelper::Deinit() {
+ if (lib_scalar_handle_) {
+ dlclose(lib_scalar_handle_);
+ lib_scalar_handle_ = NULL;
+ }
+}
+
+bool ScalarHelper::ConfigureScale(HWLayers *hw_layers) {
+
+ if (!lib_scalar_handle_ || !ScalarConfigureScale) {
+ // No scalar library
+ return true;
+ }
+
+ // Reset scale data
+ memset(&scale_data_, 0, sizeof(scale_data_));
+ 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;
+ LayerBufferFormat format = layer.input_buffer->format;
+ HWPipeInfo* left_pipe = &hw_layers->config[i].left_pipe;
+ HWPipeInfo* right_pipe = &hw_layers->config[i].right_pipe;
+
+ // Prepare data structure for lib scalar
+ uint32_t flags = 0;
+ struct scalar::LayerInfo layer_info;
+
+ 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++) {
+ HWPipeInfo* hw_pipe = (count == 0) ? left_pipe : right_pipe;
+ HWRotateInfo* rotate_info = &hw_layers->config[i].rotates[count];
+ scalar::PipeInfo* pipe = (count == 0) ? &layer_info.left_pipe : &layer_info.right_pipe;
+
+ if (rotate_info->valid) {
+ width = rotate_info->hw_buffer_info.buffer_config.width;
+ format = rotate_info->hw_buffer_info.buffer_config.format;
+ }
+
+ pipe->flags = flags;
+ pipe->scale_data = GetScaleRef(i, !count);
+ pipe->scale_data->src_width = width;
+ 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 (ScalarConfigureScale(&layer_info) < 0) {
+ DLOGE("Scalar library failed to configure scale data!");
+ return false;
+ }
+
+ // Update Src Roi in HWPipeInfo
+ if (layer_info.left_pipe.scale_data->enable_pxl_ext)
+ UpdateSrcRoi(&layer_info.left_pipe, left_pipe);
+ if (layer_info.right_pipe.scale_data->enable_pxl_ext)
+ UpdateSrcRoi(&layer_info.right_pipe, right_pipe);
+ }
+ return true;
+}
+
+void ScalarHelper::UpdateSrcWidth(uint32_t index, bool left, uint32_t* width) {
+ *width = GetScaleRef(index, left)->src_width;
+}
+
+void ScalarHelper::SetScaleData(uint32_t index, bool left, mdp_scale_data* mdp_scale) {
+
+ if (!lib_scalar_handle_ || !ScalarConfigureScale)
+ return;
+
+ scalar::Scale* scale = GetScaleRef(index, left);
+ mdp_scale->enable_pxl_ext = scale->enable_pxl_ext;
+
+ for (int i = 0; i < MAX_PLANES; i++) {
+ mdp_scale->init_phase_x[i] = scale->init_phase_x[i];
+ mdp_scale->phase_step_x[i] = scale->phase_step_x[i];
+ mdp_scale->init_phase_y[i] = scale->init_phase_y[i];
+ mdp_scale->phase_step_y[i] = scale->phase_step_y[i];
+
+ mdp_scale->num_ext_pxls_left[i] = scale->left.extension[i];
+ mdp_scale->num_ext_pxls_top[i] = scale->top.extension[i];
+ mdp_scale->num_ext_pxls_right[i] = scale->right.extension[i];
+ mdp_scale->num_ext_pxls_btm[i] = scale->bottom.extension[i];
+
+ mdp_scale->left_ftch[i] = scale->left.overfetch[i];
+ mdp_scale->top_ftch[i] = scale->top.overfetch[i];
+ mdp_scale->right_ftch[i] = scale->right.overfetch[i];
+ mdp_scale->btm_ftch[i] = scale->bottom.overfetch[i];
+
+ mdp_scale->left_rpt[i] = scale->left.repeat[i];
+ mdp_scale->top_rpt[i] = scale->top.repeat[i];
+ mdp_scale->right_rpt[i] = scale->right.repeat[i];
+ mdp_scale->btm_rpt[i] = scale->bottom.repeat[i];
+
+ mdp_scale->roi_w[i] = scale->roi_width[i];
+ }
+}
+
+} // namespace sde
+
+#endif
diff --git a/displayengine/libs/core/scalar_helper.h b/displayengine/libs/core/scalar_helper.h
new file mode 100755
index 0000000..a54cb0c
--- /dev/null
+++ b/displayengine/libs/core/scalar_helper.h
@@ -0,0 +1,67 @@
+/*
+* 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 __SCALAR_HELPER_H__
+#define __SCALAR_HELPER_H__
+
+#ifdef USES_SCALAR
+
+#include <sys/types.h>
+#include <linux/msm_mdp_ext.h>
+#include <hw_interface.h>
+#include <scalar.h>
+
+#define SCALAR_LIBRARY_NAME "libscalar.so"
+
+namespace sde {
+
+class ScalarHelper {
+
+ public:
+ void Init();
+ void Deinit();
+ bool ConfigureScale(HWLayers *hw_layers);
+ void UpdateSrcWidth(uint32_t index, bool left, uint32_t* src_width);
+ void SetScaleData(uint32_t index, bool left, mdp_scale_data* mdp_scale);
+ static ScalarHelper* GetInstance();
+
+ private:
+ explicit ScalarHelper() { }
+ struct ScaleData {
+ scalar::Scale left_scale;
+ scalar::Scale right_scale;
+ };
+ struct ScaleData scale_data_[kMaxSDELayers];
+ void* lib_scalar_handle_;
+ int (*ScalarConfigureScale)(struct scalar::LayerInfo* layer);
+ scalar::Scale* GetScaleRef(uint32_t index, bool left) {
+ return (left ? &scale_data_[index].left_scale : &scale_data_[index].right_scale);
+ }
+ static ScalarHelper* scalar_helper_; // Singleton Instance
+};
+
+} // namespace sde
+
+#endif
+#endif // __SCALAR_HELPER_H__
diff --git a/displayengine/libs/hwc/hwc_buffer_allocator.cpp b/displayengine/libs/hwc/hwc_buffer_allocator.cpp
index d4f4bac..f2383b2 100644
--- a/displayengine/libs/hwc/hwc_buffer_allocator.cpp
+++ b/displayengine/libs/hwc/hwc_buffer_allocator.cpp
@@ -159,6 +159,7 @@
case kFormatYCbCr420SemiPlanar: *target = HAL_PIXEL_FORMAT_YCbCr_420_SP; break;
case kFormatYCbCr422Packed: *target = HAL_PIXEL_FORMAT_YCbCr_422_I; break;
case kFormatYCbCr420SemiPlanarVenus: *target = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS; break;
+ case kFormatYCbCr420SPVenusUbwc: *target = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC; break;
default:
DLOGE("Unsupported format = 0x%x", format);
diff --git a/libcopybit/copybit.cpp b/libcopybit/copybit.cpp
index 9783896..02f0c7e 100644
--- a/libcopybit/copybit.cpp
+++ b/libcopybit/copybit.cpp
@@ -64,6 +64,7 @@
int relFence;
struct mdp_buf_sync sync;
struct blitReq list;
+ uint8_t dynamic_fps;
};
/**
@@ -122,6 +123,10 @@
out->b = min(lhs->b, rhs->b);
}
+static bool validateCopybitRect(struct copybit_rect_t *rect) {
+ return ((rect->b > rect->t) && (rect->r > rect->l)) ;
+}
+
/** convert COPYBIT_FORMAT to MDP format */
static int get_format(int format) {
switch (format) {
@@ -161,7 +166,7 @@
img->memory_id = hnd->fd;
}
/** setup rectangles */
-static void set_rects(struct copybit_context_t *dev,
+static bool set_rects(struct copybit_context_t *dev,
struct mdp_blit_req *e,
const struct copybit_rect_t *dst,
const struct copybit_rect_t *src,
@@ -169,6 +174,9 @@
struct copybit_rect_t clip;
intersect(&clip, scissor, dst);
+ if (!validateCopybitRect(&clip))
+ return false;
+
e->dst_rect.x = clip.l;
e->dst_rect.y = clip.t;
e->dst_rect.w = clip.r - clip.l;
@@ -212,6 +220,7 @@
e->src_rect.x = (src->l + src->r) - (e->src_rect.x + e->src_rect.w);
}
}
+ return true;
}
/** setup mdp request */
@@ -219,6 +228,7 @@
struct mdp_blit_req *req, int flags)
{
req->alpha = dev->mAlpha;
+ req->fps = dev->dynamic_fps;
req->transp_mask = MDP_TRANSP_NOP;
req->flags = dev->mFlags | flags;
// check if we are blitting to f/b
@@ -250,7 +260,7 @@
for (unsigned int i=0 ; i<l->count ; i++) {
ALOGE("%d: src={w=%d, h=%d, f=%d, rect={%d,%d,%d,%d}}\n"
" dst={w=%d, h=%d, f=%d, rect={%d,%d,%d,%d}}\n"
- " flags=%08x"
+ " flags=%08x, fps=%d"
,
i,
l->req[i].src.width,
@@ -267,7 +277,8 @@
l->req[i].dst_rect.y,
l->req[i].dst_rect.w,
l->req[i].dst_rect.h,
- l->req[i].flags
+ l->req[i].flags,
+ l->req[i].fps
);
}
#endif
@@ -315,6 +326,9 @@
if (value >= 256) value = 255;
ctx->mAlpha = (uint8_t)value;
break;
+ case COPYBIT_DYNAMIC_FPS:
+ ctx->dynamic_fps = (uint8_t)value;
+ break;
case COPYBIT_DITHER:
if (value == COPYBIT_ENABLE) {
ctx->mFlags |= MDP_DITHER;
@@ -524,7 +538,8 @@
set_infos(ctx, req, flags);
set_image(&req->dst, dst);
set_image(&req->src, src);
- set_rects(ctx, req, dst_rect, src_rect, &clip);
+ if (set_rects(ctx, req, dst_rect, src_rect, &clip) == false)
+ continue;
if (req->src_rect.w<=0 || req->src_rect.h<=0)
continue;
@@ -747,6 +762,9 @@
ctx->device.flush_get_fence = flush_get_fence;
ctx->device.clear = clear_copybit;
ctx->mAlpha = MDP_ALPHA_NOP;
+ //dynamic_fps is zero means default
+ //panel refresh rate for driver.
+ ctx->dynamic_fps = 0;
ctx->mFlags = 0;
ctx->sync.flags = 0;
ctx->relFence = -1;
diff --git a/libcopybit/copybit.h b/libcopybit/copybit.h
index 6428023..1fc17ed 100644
--- a/libcopybit/copybit.h
+++ b/libcopybit/copybit.h
@@ -79,6 +79,7 @@
/* FB height */
COPYBIT_FRAMEBUFFER_HEIGHT = 8,
COPYBIT_FG_LAYER = 9,
+ COPYBIT_DYNAMIC_FPS = 10,
};
/* values for copybit_set_parameter(COPYBIT_TRANSFORM) */
diff --git a/libhdmi/hdmi.cpp b/libhdmi/hdmi.cpp
index 1b2ffe0..fb6493a 100644
--- a/libhdmi/hdmi.cpp
+++ b/libhdmi/hdmi.cpp
@@ -412,8 +412,9 @@
// for all the timing info read, get the best config
for (int configIndex = 0; configIndex < mModeCount; configIndex++) {
currentModeInfo = mDisplayConfigs[configIndex];
+ edidMode = mEDIDModes[configIndex];
- if (!currentModeInfo.supported) {
+ if (!isValidMode(edidMode)) {
ALOGD("%s EDID Mode %d is not supported", __FUNCTION__, edidMode);
continue;
}
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index bf59217..928f3b8 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -893,6 +893,7 @@
dumpsys_log(aBuf, ovDump);
ovDump[0] = '\0';
}
+ dumpsys_log(aBuf, "Copybit::isAbcInUse=%d\n\n",isAbcInUse(ctx) ? 1 : 0);
strlcpy(buff, aBuf.string(), buff_len);
}
@@ -966,7 +967,11 @@
memset(dev, 0, sizeof(*dev));
//Initialize hwc context
- initContext(dev);
+ status = initContext(dev);
+ if (status < 0) {
+ free(dev);
+ return status;
+ }
//Setup HWC methods
dev->device.common.tag = HARDWARE_DEVICE_TAG;
diff --git a/libhwcomposer/hwc_copybit.cpp b/libhwcomposer/hwc_copybit.cpp
index 68f168a..7bb5f60 100644
--- a/libhwcomposer/hwc_copybit.cpp
+++ b/libhwcomposer/hwc_copybit.cpp
@@ -354,10 +354,18 @@
dx = (float)dst_w/(float)src_w;
dy = (float)dst_h/(float)src_h;
- if (dx > MAX_SCALE_FACTOR || dx < MIN_SCALE_FACTOR)
+ float scale_factor_max = MAX_SCALE_FACTOR;
+ float scale_factor_min = MIN_SCALE_FACTOR;
+
+ if (isAlphaPresent(layer)) {
+ scale_factor_max = MAX_SCALE_FACTOR/4;
+ scale_factor_min = MIN_SCALE_FACTOR*4;
+ }
+
+ if (dx > scale_factor_max || dx < scale_factor_min)
return false;
- if (dy > MAX_SCALE_FACTOR || dy < MIN_SCALE_FACTOR)
+ if (dy > scale_factor_max || dy < scale_factor_min)
return false;
}
}
@@ -810,7 +818,13 @@
ALOGE("%s: Framebuffer handle is NULL", __FUNCTION__);
return -1;
}
-
+ uint32_t dynamic_fps = 0;
+#ifdef DYNAMIC_FPS
+ MetaData_t *mdata = hnd ? (MetaData_t *)hnd->base_metadata : NULL;
+ if (mdata && (mdata->operation & UPDATE_REFRESH_RATE)) {
+ dynamic_fps = roundOff(mdata->refreshrate);
+ }
+#endif
// Set the copybit source:
copybit_image_t src;
src.w = getWidth(hnd);
@@ -1025,6 +1039,7 @@
layerTransform);
//TODO: once, we are able to read layer alpha, update this
copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 255);
+ copybit->set_parameter(copybit, COPYBIT_DYNAMIC_FPS, dynamic_fps);
copybit->set_parameter(copybit, COPYBIT_BLEND_MODE,
layer->blending);
copybit->set_parameter(copybit, COPYBIT_DITHER,
diff --git a/libhwcomposer/hwc_uevents.cpp b/libhwcomposer/hwc_uevents.cpp
index 4d94647..b387642 100644
--- a/libhwcomposer/hwc_uevents.cpp
+++ b/libhwcomposer/hwc_uevents.cpp
@@ -131,7 +131,7 @@
//On 8994, 8992 due to hardware limitations, we disable bwc
//when HDMI intf is active
if((qdutils::MDPVersion::getInstance().is8994() or
- qdutils::MDPVersion::getInstance().is8092()) and
+ qdutils::MDPVersion::getInstance().is8992()) and
qdutils::MDPVersion::getInstance().supportsBWC()) {
Locker::Autolock _l(ctx->mDrawLock);
ctx->mBWCEnabled = true;
@@ -151,7 +151,7 @@
//On 8994, 8992 due to hardware limitations, we disable bwc
//when HDMI intf is active
if((qdutils::MDPVersion::getInstance().is8994() or
- qdutils::MDPVersion::getInstance().is8092()) and
+ qdutils::MDPVersion::getInstance().is8992()) and
qdutils::MDPVersion::getInstance().supportsBWC()) {
Locker::Autolock _l(ctx->mDrawLock);
ctx->mBWCEnabled = false;
@@ -202,7 +202,15 @@
"uevent thread", __FUNCTION__);
ctx->mWfdSyncLock.unlock();
}
- ctx->mHDMIDisplay->configure();
+ // If FB open fails ignore this hotplug event
+ int error = ctx->mHDMIDisplay->configure();
+ if (error < 0) {
+ ALOGE("%s: Open Framebuffer for dpy = %d", __FUNCTION__, dpy);
+ ctx->mDrawLock.lock();
+ ctx->dpyAttr[dpy].isConfiguring = false;
+ ctx->mDrawLock.unlock();
+ break;
+ }
ctx->mHDMIDisplay->activateDisplay();
ctx->mDrawLock.lock();
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index d176cd3..9c94b2f 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -76,7 +76,7 @@
#endif
#endif
-#define PROP_DEFAULT_APPBUFFER "sf.default.app_buffer_count"
+#define PROP_DEFAULT_APPBUFFER "hw.sf.app_buff_count"
#define MAX_RAM_SIZE 512*1024*1024
#define qHD_WIDTH 540
@@ -266,8 +266,26 @@
}
}
-void initContext(hwc_context_t *ctx)
+int initContext(hwc_context_t *ctx)
{
+ int error = -1;
+ int compositionType = 0;
+
+ //Right now hwc starts the service but anybody could do it, or it could be
+ //independent process as well.
+ QService::init();
+ sp<IQClient> client = new QClient(ctx);
+ sp<IQService> iqs = interface_cast<IQService>(
+ defaultServiceManager()->getService(
+ String16("display.qservice")));
+ if (iqs.get()) {
+ iqs->connect(client);
+ ctx->mQService = reinterpret_cast<QService* >(iqs.get());
+ } else {
+ ALOGE("%s: Failed to acquire service pointer", __FUNCTION__);
+ return error;
+ }
+
overlay::Overlay::initOverlay();
ctx->mHDMIDisplay = new HDMIDisplay();
uint32_t priW = 0, priH = 0;
@@ -280,15 +298,24 @@
if(ctx->mHDMIDisplay->isHDMIPrimaryDisplay()) {
int connected = ctx->mHDMIDisplay->getConnectedState();
if(connected == 1) {
- ctx->mHDMIDisplay->configure();
+ error = ctx->mHDMIDisplay->configure();
+ if (error < 0) {
+ goto OpenFBError;
+ }
updateDisplayInfo(ctx, HWC_DISPLAY_PRIMARY);
ctx->dpyAttr[HWC_DISPLAY_PRIMARY].connected = true;
} else {
- openFramebufferDevice(ctx);
+ error = openFramebufferDevice(ctx);
+ if(error < 0) {
+ goto OpenFBError;
+ }
ctx->dpyAttr[HWC_DISPLAY_PRIMARY].connected = false;
}
} else {
- openFramebufferDevice(ctx);
+ error = openFramebufferDevice(ctx);
+ if(error < 0) {
+ goto OpenFBError;
+ }
ctx->dpyAttr[HWC_DISPLAY_PRIMARY].connected = true;
// Send the primary resolution to the hdmi display class
// to be used for MDP scaling functionality
@@ -314,8 +341,8 @@
// Check if the target supports copybit compostion (dyn/mdp) to
// decide if we need to open the copybit module.
- int compositionType =
- qdutils::QCCompositionType::getInstance().getCompositionType();
+ compositionType =
+ qdutils::QCCompositionType::getInstance().getCompositionType();
// Only MDP copybit is used
if ((compositionType & (qdutils::COMPOSITION_TYPE_DYN |
@@ -372,21 +399,6 @@
ctx->mExtOrientation = 0;
ctx->numActiveDisplays = 1;
- //Right now hwc starts the service but anybody could do it, or it could be
- //independent process as well.
- QService::init();
- sp<IQClient> client = new QClient(ctx);
- sp<IQService> iqs = interface_cast<IQService>(
- defaultServiceManager()->getService(
- String16("display.qservice")));
- if (iqs.get()) {
- iqs->connect(client);
- ctx->mQService = reinterpret_cast<QService* >(iqs.get());
- } else {
- ALOGE("%s: Failed to acquire service pointer", __FUNCTION__);
- return;
- }
-
// Initialize device orientation to its default orientation
ctx->deviceOrientation = 0;
ctx->mBufferMirrorMode = false;
@@ -428,6 +440,13 @@
ctx->mHPDEnabled = false;
ALOGI("Initializing Qualcomm Hardware Composer");
ALOGI("MDP version: %d", ctx->mMDP.version);
+
+ return 0;
+
+OpenFBError:
+ ALOGE("%s: Fatal Error: FB Open failed!!!", __FUNCTION__);
+ delete ctx->mHDMIDisplay;
+ return error;
}
void closeContext(hwc_context_t *ctx)
@@ -2932,7 +2951,11 @@
// TODO: If HDMI is connected after the display has booted up,
// and the best configuration is different from the default
// then we need to deal with this appropriately.
- ctx->mHDMIDisplay->configure();
+ int error = ctx->mHDMIDisplay->configure();
+ if (error < 0) {
+ ALOGE("Error opening FrameBuffer");
+ return;
+ }
updateDisplayInfo(ctx, dpy);
initCompositionResources(ctx, dpy);
ctx->dpyAttr[dpy].connected = true;
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 23157d4..ea8d652 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -280,7 +280,7 @@
void dumpLayer(hwc_layer_1_t const* l);
void setListStats(hwc_context_t *ctx, hwc_display_contents_1_t *list,
int dpy);
-void initContext(hwc_context_t *ctx);
+int initContext(hwc_context_t *ctx);
void closeContext(hwc_context_t *ctx);
//Crops source buffer against destination and FB boundaries
void calculate_crop_rects(hwc_rect_t& crop, hwc_rect_t& dst,
diff --git a/liboverlay/overlayMdp.cpp b/liboverlay/overlayMdp.cpp
index 1290f32..0c31dd3 100644
--- a/liboverlay/overlayMdp.cpp
+++ b/liboverlay/overlayMdp.cpp
@@ -353,8 +353,31 @@
mdp_overlay* ovArray[count];
memset(&ovArray, 0, sizeof(ovArray));
+ uint8_t max_horz_deci = 0, max_vert_deci = 0;
+
+ // Decimation factor for the left and right pipe differs, when there is a
+ // one pixel difference in the dst width of right pipe and the left pipe.
+ // libscalar returns a failure as it expects decimation on both the pipe
+ // to be same. So compare the decimation factor on both the pipes and assign
+ // the maximum of it.
for(int i = 0; i < count; i++) {
- ovArray[i] = &mdpCtrlArray[i]->mOVInfo;
+ mdp_overlay *ov_current = &mdpCtrlArray[i]->mOVInfo;
+ for(int j = i + 1; j < count; j++) {
+ mdp_overlay *ov_next = &mdpCtrlArray[j]->mOVInfo;
+ if(ov_current->z_order == ov_next->z_order) {
+ max_horz_deci = utils::max(ov_current->horz_deci,
+ ov_next->horz_deci);
+ max_vert_deci = utils::max(ov_current->vert_deci,
+ ov_next->vert_deci);
+
+ ov_current->horz_deci = max_horz_deci;
+ ov_next->horz_deci = max_horz_deci;
+ ov_current->vert_deci = max_vert_deci;
+ ov_next->vert_deci = max_vert_deci;
+ break;
+ }
+ }
+ ovArray[i] = ov_current;
}
struct mdp_overlay_list list;
diff --git a/libqservice/QService.cpp b/libqservice/QService.cpp
index 5276695..ddb4b18 100644
--- a/libqservice/QService.cpp
+++ b/libqservice/QService.cpp
@@ -64,11 +64,15 @@
status_t err = (status_t) FAILED_TRANSACTION;
IPCThreadState* ipc = IPCThreadState::self();
//Rewind parcel in case we're calling from the same process
- if (ipc->getCallingPid() == getpid())
+ bool sameProcess = (ipc->getCallingPid() == getpid());
+ if(sameProcess)
inParcel->setDataPosition(0);
if (mClient.get()) {
ALOGD_IF(QSERVICE_DEBUG, "Dispatching command: %d", command);
err = mClient->notifyCallback(command, inParcel, outParcel);
+ //Rewind parcel in case we're calling from the same process
+ if (sameProcess)
+ outParcel->setDataPosition(0);
}
return err;
}