Merge "hwc: Handle worm hole region for one line"
diff --git a/displayengine/include/core/layer_stack.h b/displayengine/include/core/layer_stack.h
index 0a37c79..96ec20f 100644
--- a/displayengine/include/core/layer_stack.h
+++ b/displayengine/include/core/layer_stack.h
@@ -124,7 +124,11 @@
uint64_t secure_present : 1; //!< This flag will be set to true, if the current layer stack
//!< contains secure layers.
- LayerStackFlags() : geometry_changed(0), skip_present(0), video_present(0), secure_present(0) { }
+ uint64_t animating : 1; //!< This flag shall be set by client to indicate that the current
+ //!< frame is animating.
+
+ LayerStackFlags()
+ : geometry_changed(0), skip_present(0), video_present(0), secure_present(0), animating(0) { }
};
/*! @brief This structure defines a rectanglular area inside a display layer.
diff --git a/displayengine/include/utils/constants.h b/displayengine/include/utils/constants.h
index 04a5f77..6f98b07 100644
--- a/displayengine/include/utils/constants.h
+++ b/displayengine/include/utils/constants.h
@@ -53,6 +53,24 @@
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+template <class T>
+inline void Swap(T &a, T &b) {
+ T c(a);
+ a = b;
+ b = c;
+}
+
+// factor value should be in powers of 2(eg: 1, 2, 4, 8)
+template <class T1, class T2>
+inline T1 FloorToMultipleOf(const T1 &value, const T2 &factor) {
+ return (T1)(value & (~(factor - 1)));
+}
+
+template <class T1, class T2>
+inline T1 CeilToMultipleOf(const T1 &value, const T2 &factor) {
+ return (T1)((value + (factor - 1)) & (~(factor - 1)));
+}
+
namespace sde {
const int kThreadPriorityUrgent = -9;
diff --git a/displayengine/include/utils/rect.h b/displayengine/include/utils/rect.h
new file mode 100644
index 0000000..f009cfd
--- /dev/null
+++ b/displayengine/include/utils/rect.h
@@ -0,0 +1,48 @@
+/*
+* 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 __RECT_H__
+#define __RECT_H__
+
+#include <stdint.h>
+#include <core/sde_types.h>
+#include <core/layer_stack.h>
+#include <utils/debug.h>
+
+namespace sde {
+
+ bool IsValidRect(const LayerRect &rect);
+ LayerRect GetIntersection(const LayerRect &rect1, const LayerRect &rect2);
+ void LogRect(DebugTag debug_tag, const char *prefix, const LayerRect &roi);
+ void NormalizeRect(const uint32_t &factor, LayerRect *rect);
+
+} // namespace sde
+
+#endif // __RECT_H__
+
diff --git a/displayengine/libs/core/Android.mk b/displayengine/libs/core/Android.mk
index 1623c13..56167e1 100644
--- a/displayengine/libs/core/Android.mk
+++ b/displayengine/libs/core/Android.mk
@@ -4,7 +4,8 @@
LOCAL_MODULE := libsde
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES := hardware/qcom/display/displayengine/include/ \
- $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
+ $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include \
+ $(TARGET_OUT_HEADERS)/scalar/inc
LOCAL_CFLAGS := -Wno-missing-field-initializers -Wno-unused-parameter \
-Wconversion -Wall -Werror \
-DLOG_TAG=\"SDE\"
diff --git a/displayengine/libs/core/hw_framebuffer.cpp b/displayengine/libs/core/hw_framebuffer.cpp
index 5d1f725..4a361da 100644
--- a/displayengine/libs/core/hw_framebuffer.cpp
+++ b/displayengine/libs/core/hw_framebuffer.cpp
@@ -722,6 +722,14 @@
}
}
+ if (pipe_info->scale_data.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);
+ }
+
+ // Send scale data to MDP driver
+ mdp_layer.scale = hw_display->GetScaleRef(mdp_layer_count);
mdp_layer_count++;
DLOGV_IF(kTagDriverConfig, "******************* Layer[%d] %s pipe Input ******************",
@@ -735,6 +743,19 @@
mdp_layer.src_rect.y, mdp_layer.src_rect.w, mdp_layer.src_rect.h);
DLOGV_IF(kTagDriverConfig, "dst_rect [%d, %d, %d, %d]", mdp_layer.dst_rect.x,
mdp_layer.dst_rect.y, mdp_layer.dst_rect.w, mdp_layer.dst_rect.h);
+ for (int j = 0; j < MAX_PLANES; j++) {
+ DLOGV_IF(kTagDriverConfig, "Scale Data[%d]: Phase=[%x %x %x %x] Pixel_Ext=[%d %d %d %d]",
+ j, mdp_layer.scale->init_phase_x[j], mdp_layer.scale->phase_step_x[j],
+ mdp_layer.scale->init_phase_y[j], mdp_layer.scale->phase_step_y[j],
+ mdp_layer.scale->num_ext_pxls_left[j], mdp_layer.scale->num_ext_pxls_top[j],
+ mdp_layer.scale->num_ext_pxls_right[j], mdp_layer.scale->num_ext_pxls_btm[j]);
+ DLOGV_IF(kTagDriverConfig, "Fetch=[%d %d %d %d] Repeat=[%d %d %d %d] roi_width = %d",
+ mdp_layer.scale->left_ftch[j], mdp_layer.scale->top_ftch[j],
+ mdp_layer.scale->right_ftch[j], mdp_layer.scale->btm_ftch[j],
+ mdp_layer.scale->left_rpt[j], mdp_layer.scale->top_rpt[j],
+ mdp_layer.scale->right_rpt[j], mdp_layer.scale->btm_rpt[j],
+ mdp_layer.scale->roi_w[j]);
+ }
DLOGV_IF(kTagDriverConfig, "*************************************************************");
}
}
diff --git a/displayengine/libs/core/hw_framebuffer.h b/displayengine/libs/core/hw_framebuffer.h
index 6df705d..5c01e5f 100644
--- a/displayengine/libs/core/hw_framebuffer.h
+++ b/displayengine/libs/core/hw_framebuffer.h
@@ -67,6 +67,7 @@
struct HWDisplay {
mdp_layer_commit mdp_disp_commit;
mdp_input_layer mdp_in_layers[kMaxSDELayers * 2]; // split panel (left + right)
+ mdp_scale_data scale_data[kMaxSDELayers * 2];
mdp_output_layer mdp_out_layer;
HWDisplay() { Reset(); }
@@ -75,6 +76,7 @@
memset(&mdp_disp_commit, 0, sizeof(mdp_disp_commit));
memset(&mdp_in_layers, 0, sizeof(mdp_in_layers));
memset(&mdp_out_layer, 0, sizeof(mdp_out_layer));
+ memset(&scale_data, 0, sizeof(scale_data));
for (uint32_t i = 0; i < kMaxSDELayers * 2; i++) {
mdp_in_layers[i].buffer.fence = -1;
@@ -85,6 +87,37 @@
mdp_disp_commit.commit_v1.output_layer = &mdp_out_layer;
mdp_disp_commit.commit_v1.release_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];
+ }
+ }
};
struct HWRotator {
diff --git a/displayengine/libs/core/hw_interface.h b/displayengine/libs/core/hw_interface.h
index 1217b95..084768e 100644
--- a/displayengine/libs/core/hw_interface.h
+++ b/displayengine/libs/core/hw_interface.h
@@ -30,6 +30,7 @@
#include <utils/constants.h>
#include <core/buffer_allocator.h>
#include <core/buffer_sync_handler.h>
+#include <scalar.h>
namespace sde {
@@ -128,6 +129,7 @@
LayerRect dst_roi;
uint8_t horizontal_decimation;
uint8_t vertical_decimation;
+ scalar::Scale scale_data;
bool valid;
HWPipeInfo() : pipe_id(0), horizontal_decimation(0), vertical_decimation(0), valid(false) { }
diff --git a/displayengine/libs/core/res_config.cpp b/displayengine/libs/core/res_config.cpp
index cf2a5c7..d3c2d26 100644
--- a/displayengine/libs/core/res_config.cpp
+++ b/displayengine/libs/core/res_config.cpp
@@ -25,11 +25,15 @@
#include <math.h>
#include <utils/constants.h>
#include <utils/debug.h>
+#include <utils/rect.h>
#include "res_manager.h"
#define __CLASS__ "ResManager"
+using scalar::PipeInfo;
+using scalar::LayerInfo;
+
namespace sde {
void ResManager::RotationConfig(const LayerTransform &transform, const float &scale_x,
@@ -179,8 +183,8 @@
float rot_scale_x = 1.0f, rot_scale_y = 1.0f;
if (!IsValidDimension(layer.src_rect, layer.dst_rect)) {
DLOGV_IF(kTagResources, "Input is invalid");
- LogRectVerbose("input layer src_rect", layer.src_rect);
- LogRectVerbose("input layer dst_rect", layer.dst_rect);
+ LogRect(kTagResources, "input layer src_rect", layer.src_rect);
+ LogRect(kTagResources, "input layer dst_rect", layer.dst_rect);
return kErrorNotSupported;
}
@@ -239,21 +243,21 @@
DLOGV_IF(kTagResources, "layer = %d, left pipe_id = %x",
i, layer_config->left_pipe.pipe_id);
- LogRectVerbose("input layer src_rect", layer.src_rect);
- LogRectVerbose("input layer dst_rect", layer.dst_rect);
+ LogRect(kTagResources, "input layer src_rect", layer.src_rect);
+ LogRect(kTagResources, "input layer dst_rect", layer.dst_rect);
for (uint32_t k = 0; k < layer_config->num_rotate; k++) {
DLOGV_IF(kTagResources, "rotate num = %d, scale_x = %.2f, scale_y = %.2f",
k, rot_scale_x, rot_scale_y);
- LogRectVerbose("rotate src", layer_config->rotates[k].src_roi);
- LogRectVerbose("rotate dst", layer_config->rotates[k].dst_roi);
+ LogRect(kTagResources, "rotate src", layer_config->rotates[k].src_roi);
+ LogRect(kTagResources, "rotate dst", layer_config->rotates[k].dst_roi);
}
- LogRectVerbose("cropped src_rect", src_rect);
- LogRectVerbose("cropped dst_rect", dst_rect);
- LogRectVerbose("left pipe src", layer_config->left_pipe.src_roi);
- LogRectVerbose("left pipe dst", layer_config->left_pipe.dst_roi);
+ LogRect(kTagResources, "cropped src_rect", src_rect);
+ LogRect(kTagResources, "cropped dst_rect", dst_rect);
+ LogRect(kTagResources, "left pipe src", layer_config->left_pipe.src_roi);
+ LogRect(kTagResources, "left pipe dst", layer_config->left_pipe.dst_roi);
if (hw_layers->config[i].right_pipe.pipe_id) {
- LogRectVerbose("right pipe src", layer_config->right_pipe.src_roi);
- LogRectVerbose("right pipe dst", layer_config->right_pipe.dst_roi);
+ LogRect(kTagResources, "right pipe src", layer_config->right_pipe.src_roi);
+ LogRect(kTagResources, "right pipe dst", layer_config->right_pipe.dst_roi);
}
}
@@ -529,21 +533,123 @@
}
}
-void ResManager::LogRectVerbose(const char *prefix, const LayerRect &roi) {
- DLOGV_IF(kTagResources, "%s: left = %.0f, top = %.0f, right = %.0f, bottom = %.0f",
- prefix, roi.left, roi.top, roi.right, roi.bottom);
+// 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;
}
-void ResManager::NormalizeRect(const uint32_t &factor, LayerRect *rect) {
- uint32_t left = UINT32(ceilf(rect->left));
- uint32_t top = UINT32(ceilf(rect->top));
- uint32_t right = UINT32(floorf(rect->right));
- uint32_t bottom = UINT32(floorf(rect->bottom));
+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);
+}
- rect->left = FLOAT(CeilToMultipleOf(left, factor));
- rect->top = FLOAT(CeilToMultipleOf(top, factor));
- rect->right = FLOAT(FloorToMultipleOf(right, factor));
- rect->bottom = FLOAT(FloorToMultipleOf(bottom, factor));
+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;
}
} // namespace sde
diff --git a/displayengine/libs/core/res_manager.cpp b/displayengine/libs/core/res_manager.cpp
index 16fc8b4..fb8f2eb 100644
--- a/displayengine/libs/core/res_manager.cpp
+++ b/displayengine/libs/core/res_manager.cpp
@@ -25,10 +25,12 @@
#include <math.h>
#include <utils/constants.h>
#include <utils/debug.h>
+#include <dlfcn.h>
#include "res_manager.h"
#define __CLASS__ "ResManager"
+#define SCALAR_LIBRARY_NAME "libscalar.so"
namespace sde {
@@ -112,10 +114,23 @@
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);
+ }
+
return kErrorNone;
}
DisplayError ResManager::Deinit() {
+ if (lib_scalar_handle_) {
+ dlclose(lib_scalar_handle_);
+ lib_scalar_handle_ = NULL;
+ }
return kErrorNone;
}
@@ -353,17 +368,24 @@
i, layer_config.left_pipe.pipe_id, pipe_info->pipe_id);
}
- 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;
}
+ if (lib_scalar_handle_ && ScalarConfigureScale) {
+ if (!ConfigureScaling(hw_layers)) {
+ DLOGV_IF(kTagResources, "Scale data configuration has failed!");
+ goto CleanupOnError;
+ }
+ }
+
+ if (!CheckBandwidth(display_resource_ctx, hw_layers)) {
+ DLOGV_IF(kTagResources, "Bandwidth check failed!");
+ goto CleanupOnError;
+ }
+
return kErrorNone;
CleanupOnError:
@@ -1065,6 +1087,8 @@
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 926b2b7..c80dc2c 100644
--- a/displayengine/libs/core/res_manager.h
+++ b/displayengine/libs/core/res_manager.h
@@ -187,7 +187,6 @@
bool IsYuvFormat(LayerBufferFormat format) { return (format >= kFormatYCbCr420Planar); }
bool IsRotationNeeded(float rotation)
{ return (UINT32(rotation) == 90 || UINT32(rotation) == 270); }
- void LogRectVerbose(const char *prefix, const LayerRect &roi);
void RotationConfig(const LayerTransform &transform, const float &scale_x,
const float &scale_y, LayerRect *src_rect,
struct HWLayerConfig *layer_config, uint32_t *rotate_count);
@@ -195,28 +194,10 @@
const uint32_t roate_cnt);
void AssignRotator(HWRotateInfo *rotate, uint32_t *rotate_cnt);
void ClearRotator(DisplayResourceContext *display_resource_ctx);
- void NormalizeRect(const uint32_t &factor, LayerRect *rect);
DisplayError AllocRotatorBuffer(Handle display_ctx, HWLayers *hw_layers);
void SetRotatorOutputFormat(const LayerBufferFormat &input_format, bool bwc, bool rot90,
LayerBufferFormat *output_format);
-
- template <class T>
- inline void Swap(T &a, T &b) {
- T c(a);
- a = b;
- b = c;
- }
-
- // factor value should be in powers of 2(eg: 1, 2, 4, 8)
- template <class T1, class T2>
- inline T1 FloorToMultipleOf(const T1 &value, const T2 &factor) {
- return (T1)(value & (~(factor - 1)));
- }
-
- template <class T1, class T2>
- inline T1 CeilToMultipleOf(const T1 &value, const T2 &factor) {
- return (T1)((value + (factor - 1)) & (~(factor - 1)));
- }
+ bool ConfigureScaling(HWLayers *hw_layers);
Locker locker_;
HWResourceInfo hw_res_info_;
@@ -235,6 +216,8 @@
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);
};
} // namespace sde
diff --git a/displayengine/libs/hwc/hwc_display.cpp b/displayengine/libs/hwc/hwc_display.cpp
index 452bff1..dd1beac 100644
--- a/displayengine/libs/hwc/hwc_display.cpp
+++ b/displayengine/libs/hwc/hwc_display.cpp
@@ -361,6 +361,10 @@
layer.flags.skip = ((hwc_layer.flags & HWC_SKIP_LAYER) > 0);
layer.flags.updating = (layer_stack_cache_.layer_cache[i].handle != hwc_layer.handle);
+ if (hwc_layer.flags & HWC_SCREENSHOT_ANIMATOR_LAYER) {
+ layer_stack_.flags.animating = true;
+ }
+
if (layer.flags.skip) {
layer_stack_.flags.skip_present = true;
}
@@ -462,17 +466,31 @@
Layer &layer = layer_stack_.layers[i];
LayerBuffer *layer_buffer = layer_stack_.layers[i].input_buffer;
- if (!flush_ && (layer.composition == kCompositionSDE ||
- layer.composition == kCompositionGPUTarget)) {
- hwc_layer.releaseFenceFd = layer_buffer->release_fence_fd;
+ if (!flush_) {
+ if (layer.composition != kCompositionGPU) {
+ hwc_layer.releaseFenceFd = layer_buffer->release_fence_fd;
+ }
+
+ // During animation on external/virtual display, Display Engine will use the cached
+ // framebuffer layer throughout animation and do not allow framework to do eglswapbuffer on
+ // framebuffer target. So graphics doesn't close the release fence fd of framebuffer target,
+ // Hence close the release fencefd of framebuffer target here.
+ if (layer.composition == kCompositionGPUTarget && layer_stack_cache_.animating) {
+ close(hwc_layer.releaseFenceFd);
+ hwc_layer.releaseFenceFd = -1;
+ }
}
if (hwc_layer.acquireFenceFd >= 0) {
close(hwc_layer.acquireFenceFd);
+ hwc_layer.acquireFenceFd = -1;
}
}
+
if (!flush_) {
+ layer_stack_cache_.animating = layer_stack_.flags.animating;
+
content_list->retireFenceFd = layer_stack_.retire_fence_fd;
if (dump_frame_count_) {
@@ -495,8 +513,8 @@
// 2. Any layer is added/removed/layer properties changes in the current layer stack.
// 3. Any layer handle is changed and it is marked for GPU composition
// 4. Any layer's current composition is different from previous composition.
- if ((layer_stack_cache_.layer_count != layer_count) || layer_stack_.flags.skip_present ||
- layer_stack_.flags.geometry_changed) {
+ if (((layer_stack_cache_.layer_count != layer_count) || layer_stack_.flags.skip_present ||
+ layer_stack_.flags.geometry_changed) && !layer_stack_cache_.animating) {
return true;
}
@@ -513,7 +531,8 @@
return true;
}
- if ((layer.composition == kCompositionGPU) && (layer_cache.handle != hwc_layer.handle)) {
+ if ((layer.composition == kCompositionGPU) && (layer_cache.handle != hwc_layer.handle) &&
+ !layer_stack_cache_.animating) {
return true;
}
}
diff --git a/displayengine/libs/hwc/hwc_display.h b/displayengine/libs/hwc/hwc_display.h
index 3934078..a574d6b 100644
--- a/displayengine/libs/hwc/hwc_display.h
+++ b/displayengine/libs/hwc/hwc_display.h
@@ -69,8 +69,9 @@
struct LayerStackCache {
LayerCache layer_cache[kMaxLayerCount];
uint32_t layer_count;
+ bool animating;
- LayerStackCache() : layer_count(0) { }
+ LayerStackCache() : layer_count(0), animating(false) { }
};
HWCDisplay(CoreInterface *core_intf, hwc_procs_t const **hwc_procs, DisplayType type, int id);
diff --git a/displayengine/libs/utils/Android.mk b/displayengine/libs/utils/Android.mk
index db97dd5..264c40a 100644
--- a/displayengine/libs/utils/Android.mk
+++ b/displayengine/libs/utils/Android.mk
@@ -8,6 +8,6 @@
-Wconversion -Wall -Werror \
-DLOG_TAG=\"SDE\"
LOCAL_SHARED_LIBRARIES := libcutils
-LOCAL_SRC_FILES := debug_android.cpp
+LOCAL_SRC_FILES := debug_android.cpp rect.cpp
include $(BUILD_SHARED_LIBRARY)
diff --git a/displayengine/libs/utils/rect.cpp b/displayengine/libs/utils/rect.cpp
new file mode 100644
index 0000000..2725750
--- /dev/null
+++ b/displayengine/libs/utils/rect.cpp
@@ -0,0 +1,80 @@
+/*
+* 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 <math.h>
+#include <utils/rect.h>
+#include <utils/constants.h>
+
+#define __CLASS__ "RectUtils"
+
+namespace sde {
+
+bool IsValidRect(const LayerRect &rect) {
+ return ((rect.bottom > rect.top) && (rect.right > rect.left));
+}
+
+
+LayerRect GetIntersection(const LayerRect &rect1, const LayerRect &rect2) {
+ LayerRect res;
+
+ if (!IsValidRect(rect1) || !IsValidRect(rect2)) {
+ return LayerRect();
+ }
+
+ res.left = MAX(rect1.left, rect2.left);
+ res.top = MAX(rect1.top, rect2.top);
+ res.right = MIN(rect1.right, rect2.right);
+ res.bottom = MIN(rect1.bottom, rect2.bottom);
+
+ if (!IsValidRect(res)) {
+ return LayerRect();
+ }
+
+ return res;
+}
+
+void LogRect(DebugTag debug_tag, const char *prefix, const LayerRect &roi) {
+ DLOGV_IF(debug_tag, "%s: left = %.0f, top = %.0f, right = %.0f, bottom = %.0f",
+ prefix, roi.left, roi.top, roi.right, roi.bottom);
+}
+
+void NormalizeRect(const uint32_t &factor, LayerRect *rect) {
+ uint32_t left = UINT32(ceilf(rect->left));
+ uint32_t top = UINT32(ceilf(rect->top));
+ uint32_t right = UINT32(floorf(rect->right));
+ uint32_t bottom = UINT32(floorf(rect->bottom));
+
+ rect->left = FLOAT(CeilToMultipleOf(left, factor));
+ rect->top = FLOAT(CeilToMultipleOf(top, factor));
+ rect->right = FLOAT(FloorToMultipleOf(right, factor));
+ rect->bottom = FLOAT(FloorToMultipleOf(bottom, factor));
+}
+
+} // namespace sde
+
diff --git a/libgralloc/gralloc_priv.h b/libgralloc/gralloc_priv.h
index 8b134ea..e9b9d9d 100755
--- a/libgralloc/gralloc_priv.h
+++ b/libgralloc/gralloc_priv.h
@@ -91,7 +91,6 @@
GRALLOC_USAGE_PRIVATE_ADSP_HEAP)
#define INTERLACE_MASK 0x80
-#define S3D_FORMAT_MASK 0xFF000
/*****************************************************************************/
/* OEM specific HAL formats */
@@ -155,15 +154,11 @@
/* possible formats for 3D content*/
enum {
- HAL_NO_3D = 0x0000,
- HAL_3D_IN_SIDE_BY_SIDE_L_R = 0x10000,
- HAL_3D_IN_TOP_BOTTOM = 0x20000,
- HAL_3D_IN_INTERLEAVE = 0x40000,
- HAL_3D_IN_SIDE_BY_SIDE_R_L = 0x80000,
- HAL_3D_OUT_SIDE_BY_SIDE = 0x1000,
- HAL_3D_OUT_TOP_BOTTOM = 0x2000,
- HAL_3D_OUT_INTERLEAVE = 0x4000,
- HAL_3D_OUT_MONOSCOPIC = 0x8000
+ HAL_NO_3D = 0x0,
+ HAL_3D_SIDE_BY_SIDE_L_R = 0x1,
+ HAL_3D_SIDE_BY_SIDE_R_L = 0x2,
+ HAL_3D_TOP_BOTTOM = 0x4,
+ HAL_3D_IN_SIDE_BY_SIDE_L_R = 0x10000, //unused legacy format
};
enum {
diff --git a/libhwcomposer/hwc_copybit.cpp b/libhwcomposer/hwc_copybit.cpp
index 1891c46..65482d7 100644
--- a/libhwcomposer/hwc_copybit.cpp
+++ b/libhwcomposer/hwc_copybit.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2012-2015, The Linux Foundation. All rights reserved.
*
* Not a Contribution.
*
@@ -948,16 +948,18 @@
int tmp_w = src_crop_width;
int tmp_h = src_crop_height;
- if (dsdx > copybitsMaxScale || dtdy > copybitsMaxScale ){
+ if (dsdx > copybitsMaxScale)
tmp_w = (int)((float)src_crop_width*copybitsMaxScale);
+ if (dtdy > copybitsMaxScale)
tmp_h = (int)((float)src_crop_height*copybitsMaxScale);
- }else if (dsdx < 1/copybitsMinScale ||dtdy < 1/copybitsMinScale ){
- // ceil the tmp_w and tmp_h value to maintain proper ratio
- // b/w src and dst (should not cross the desired scale limit
- // due to float -> int )
+ // ceil the tmp_w and tmp_h value to maintain proper ratio
+ // b/w src and dst (should not cross the desired scale limit
+ // due to float -> int )
+ if (dsdx < 1/copybitsMinScale)
tmp_w = (int)ceil((float)src_crop_width/copybitsMinScale);
+ if (dtdy < 1/copybitsMinScale)
tmp_h = (int)ceil((float)src_crop_height/copybitsMinScale);
- }
+
ALOGD("%s:%d::tmp_w = %d,tmp_h = %d",__FUNCTION__,__LINE__,tmp_w,tmp_h);
int usage = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP;
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 4f1b5e6..a97c59b 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -245,10 +245,10 @@
inline hwc_rect_t integerizeSourceCrop(const hwc_frect_t& cropF) {
hwc_rect_t cropI = {0,0,0,0};
- cropI.left = int(ceilf(cropF.left));
- cropI.top = int(ceilf(cropF.top));
- cropI.right = int(floorf(cropF.right));
- cropI.bottom = int(floorf(cropF.bottom));
+ cropI.left = int(floorf(cropF.left));
+ cropI.top = int(floorf(cropF.top));
+ cropI.right = int(ceilf(cropF.right));
+ cropI.bottom = int(ceilf(cropF.bottom));
return cropI;
}
diff --git a/libqdutils/qdMetaData.cpp b/libqdutils/qdMetaData.cpp
index 88109c9..aae0a47 100644
--- a/libqdutils/qdMetaData.cpp
+++ b/libqdutils/qdMetaData.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-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
@@ -93,6 +93,9 @@
case MAP_SECURE_BUFFER:
data->mapSecureBuffer = *((int32_t *)param);
break;
+ case S3D_FORMAT:
+ data->s3dFormat = *((uint32_t *)param);
+ break;
default:
ALOGE("Unknown paramType %d", paramType);
break;
diff --git a/libqdutils/qdMetaData.h b/libqdutils/qdMetaData.h
index 32d788e..a1afa38 100644
--- a/libqdutils/qdMetaData.h
+++ b/libqdutils/qdMetaData.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-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
@@ -86,6 +86,9 @@
* for clients to set, and GPU will to read and know when to map the
* SECURE_BUFFER(ION) */
int32_t mapSecureBuffer;
+ /* The supported formats are defined in gralloc_priv.h to
+ * support legacy code*/
+ uint32_t s3dFormat;
};
enum DispParamType {
@@ -100,6 +103,7 @@
UPDATE_REFRESH_RATE = 0x0100,
UPDATE_COLOR_SPACE = 0x0200,
MAP_SECURE_BUFFER = 0x400,
+ S3D_FORMAT = 0x800,
};
struct private_handle_t;