sde: resource: rotator yuv downscaling output alignment
For YUV 420 format, align the source crop with rotator
downscale factor * 2 so that the rotator output width and
height are even. This is the requirement of the rotator.
For simplification, apply this to all non RGB format.
Change-Id: I15e27bfba782873e7a6e6c378845df04eeaadccd
diff --git a/displayengine/include/utils/constants.h b/displayengine/include/utils/constants.h
index 8630d45..5dfcc59 100644
--- a/displayengine/include/utils/constants.h
+++ b/displayengine/include/utils/constants.h
@@ -59,6 +59,8 @@
#define IDLE_TIMEOUT_DEFAULT_MS 70
+#define IS_RGB_FORMAT(format) (((format) < kFormatYCbCr420Planar) ? true: false)
+
template <class T>
inline void Swap(T &a, T &b) {
T c(a);
diff --git a/displayengine/libs/core/res_config.cpp b/displayengine/libs/core/res_config.cpp
index 037bf58..d5d3c58 100644
--- a/displayengine/libs/core/res_config.cpp
+++ b/displayengine/libs/core/res_config.cpp
@@ -33,6 +33,15 @@
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(LayerBufferFormat format, const LayerTransform &transform,
const float &downscale, LayerRect *src_rect,
struct HWLayerConfig *layer_config, uint32_t *rotate_count) {
@@ -46,22 +55,24 @@
dst_rect.left = 0.0f;
rotate->downscale_ratio = downscale;
+ uint32_t align_x, align_y;
+ GetAlignFactor(format, &align_x, &align_y);
// downscale when doing rotation
if (rot90) {
if (downscale > 1.0f) {
- src_height = ROUND_UP_ALIGN_DOWN(src_height, downscale);
+ 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);
+ 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);
+ 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);
+ 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;
@@ -250,11 +261,9 @@
continue;
}
- uint32_t align_x = 1, align_y = 1;
- if (IsYuvFormat(layer.input_buffer->format)) {
- // TODO(user) Select x and y alignment according to the format
- align_x = 2;
- align_y = 2;
+ uint32_t align_x, align_y;
+ GetAlignFactor(layer.input_buffer->format, &align_x, &align_y);
+ if (align_x > 1 || align_y > 1) {
NormalizeRect(align_x, align_y, &src_rect);
}
diff --git a/displayengine/libs/core/res_manager.cpp b/displayengine/libs/core/res_manager.cpp
index 238dfa8..262d7e1 100644
--- a/displayengine/libs/core/res_manager.cpp
+++ b/displayengine/libs/core/res_manager.cpp
@@ -325,8 +325,7 @@
HWPipeInfo *pipe_info = &layer_config.left_pipe;
- // Should have a generic macro
- bool is_yuv = IsYuvFormat(layer.input_buffer->format);
+ bool is_yuv = !IS_RGB_FORMAT(layer.input_buffer->format);
// left pipe is needed
if (pipe_info->valid) {
diff --git a/displayengine/libs/core/res_manager.h b/displayengine/libs/core/res_manager.h
index 8cf08f5..3287224 100644
--- a/displayengine/libs/core/res_manager.h
+++ b/displayengine/libs/core/res_manager.h
@@ -193,7 +193,6 @@
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 IsYuvFormat(LayerBufferFormat format) { return (format >= kFormatYCbCr420Planar); }
bool IsRotationNeeded(float rotation)
{ return (UINT32(rotation) == 90 || UINT32(rotation) == 270); }
void RotationConfig(LayerBufferFormat format, const LayerTransform &transform,