Merge "gralloc: Fix a missed unmap."
diff --git a/common.mk b/common.mk
index 464f296..183ee99 100644
--- a/common.mk
+++ b/common.mk
@@ -29,6 +29,10 @@
common_flags += -DVENUS_COLOR_FORMAT
endif
+ifeq ($(call is-board-platform-in-list, $(MASTER_SIDE_CP_TARGET_LIST)), true)
+ common_flags += -DMASTER_SIDE_CP
+endif
+
common_deps :=
kernel_includes :=
diff --git a/displayengine/include/core/layer_buffer.h b/displayengine/include/core/layer_buffer.h
index e4a73c3..2493c13 100644
--- a/displayengine/include/core/layer_buffer.h
+++ b/displayengine/include/core/layer_buffer.h
@@ -54,6 +54,9 @@
kFormatRGB888, //!< 8-bits Red, Green, Blue interleaved in RGB order. No Alpha.
kFormatBGR888, //!< 8-bits Blue, Green, Red interleaved in BGR order. No Alpha.
kFormatRGB565, //!< 5-bit Red, 6-bit Green, 5-bit Blue interleaved in RGB order. No Alpha.
+ kFormatRGBA8888Ubwc, //!< UBWC aligned RGBA8888 format
+ kFormatRGBX8888Ubwc, //!< UBWC aligned RGBX8888 format
+ kFormatRGB565Ubwc, //!< UBWC aligned RGB565 format
/* All YUV-Planar formats, Any new format will be added towards end of this group to maintain
backward compatibility.
@@ -99,6 +102,8 @@
//!< horizontally subsampled interleaved VU-plane:
//!< v(0), u(1), v(2), u(3) ... v(n-1), u(n)
+ kFormatYCbCr420SPVenusUbwc, //!< UBWC aligned YCbCr420SemiPlanarVenus format
+
/* All YUV-Packed formats, Any new format will be added towards end of this group to maintain
backward compatibility.
*/
@@ -107,15 +112,6 @@
//!< y(0), u(0), y(1), v(0), y(2), u(2), y(3), v(2)
//!< y(n-1), u(n-1), y(n), v(n-1)
- /* All UBWC aligned formats. Any new format will be added towards end of this group to maintain
- backward compatibility.
- */
- kFormatRGBA8888Ubwc = 0x400, //!< UBWC aligned RGBA8888 format
-
- kFormatRGB565Ubwc, //!< UBWC aligned RGB565 format
-
- kFormatYCbCr420SPVenusUbwc, //!< UBWC aligned Venus NV12 format
-
kFormatInvalid = 0xFFFFFFFF,
};
@@ -138,14 +134,30 @@
@sa LayerBuffer
*/
struct LayerBufferFlags {
- uint64_t secure : 1; //!< This flag shall be set by client to indicate that the buffer need
- //!< to be handled securely.
- uint64_t video : 1; //!< This flag shall be set by client to indicate that the buffer is
- //!< video/ui buffer
- uint64_t macro_tile : 1; //!< This flag shall be set by client to indicate that the buffer format
- //!< is macro tiled.
+ union {
+ struct {
+ uint32_t secure : 1; //!< This flag shall be set by client to indicate that the
+ //!< buffer need to be handled securely.
- LayerBufferFlags() : secure(0), video(0), macro_tile(0) { }
+ uint32_t video : 1; //!< This flag shall be set by client to indicate that the
+ //!< buffer is video/ui buffer.
+
+ uint32_t macro_tile : 1; //!< This flag shall be set by client to indicate that the
+ //!< buffer format is macro tiled.
+
+ uint32_t interlace : 1; //!< This flag shall be set by the client to indicate that
+ //!< the buffer has interlaced content.
+
+ uint32_t secure_display : 1;
+ //!< This flag shall be set by the client to indicate that the
+ //!< secure display session is in progress. Secure display
+ //!< session can not coexist with non-secure session.
+ };
+
+ uint32_t flags; //!< For initialization purpose only. Client shall not refer it directly.
+ };
+
+ LayerBufferFlags() : flags(0) { }
};
/*! @brief This structure defines a layer buffer handle which contains raw buffer and its associated
diff --git a/displayengine/include/core/layer_stack.h b/displayengine/include/core/layer_stack.h
index d85fd98..66f60e7 100644
--- a/displayengine/include/core/layer_stack.h
+++ b/displayengine/include/core/layer_stack.h
@@ -92,15 +92,22 @@
@sa LayerBuffer
*/
struct LayerFlags {
- uint64_t skip : 1; //!< This flag shall be set by client to indicate that this layer will be
- //!< handled by GPU. Display Device will not consider it for composition.
+ union {
+ struct {
+ uint32_t skip : 1; //!< This flag shall be set by client to indicate that this layer
+ //!< will be handled by GPU. Display Device will not consider it
+ //!< for composition.
- uint64_t updating : 1; //!< This flag shall be set by client to indicate that this is updating/
- //!< non-updating. so strategy manager will mark them for SDE/GPU
- //!< composition respectively when the layer stack qualifies for cache
- //!< based composition.
+ uint32_t updating : 1; //!< This flag shall be set by client to indicate that this is
+ //!< updating non-updating. so strategy manager will mark them for
+ //!< SDE/GPU composition respectively when the layer stack qualifies
+ //!< for cache based composition.
+ };
- LayerFlags() : skip(0), updating(0) { }
+ uint32_t flags; //!< For initialization purpose only. Client shall not refer it directly.
+ };
+
+ LayerFlags() : flags(0) { }
};
/*! @brief This structure defines flags associated with a layer stack. The 1-bit flag can be set to
@@ -109,24 +116,29 @@
@sa LayerBuffer
*/
struct LayerStackFlags {
- uint64_t geometry_changed : 1; //!< This flag shall be set by client to indicate that the layer
- //!< set passed to Prepare() has changed by more than just the
- //!< buffer handles and acquire fences.
+ union {
+ struct {
+ uint32_t geometry_changed : 1; //!< This flag shall be set by client to indicate that the
+ //!< layer set passed to Prepare() has changed by more than
+ //!< just the buffer handles and acquire fences.
- uint64_t skip_present : 1; //!< This flag will be set to true, if the current layer stack
- //!< contains skip layers.
+ uint32_t skip_present : 1; //!< This flag will be set to true, if the current layer
+ //!< stack contains skip layers.
- uint64_t video_present : 1; //!< This flag will be set to true, if current layer stack
- //!< contains video.
+ uint32_t video_present : 1; //!< This flag will be set to true, if current layer stack
+ //!< contains video.
- uint64_t secure_present : 1; //!< This flag will be set to true, if the current layer stack
- //!< contains secure layers.
+ uint32_t secure_present : 1; //!< This flag will be set to true, if the current layer
+ //!< stack contains secure layers.
- uint64_t animating : 1; //!< This flag shall be set by client to indicate that the current
- //!< frame is animating.
+ uint32_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) { }
+ uint32_t flags; //!< For initialization purpose only. Client shall not refer it directly.
+ };
+
+ LayerStackFlags() : flags(0) { }
};
/*! @brief This structure defines a rectanglular area inside a display layer.
diff --git a/displayengine/include/private/hw_info_types.h b/displayengine/include/private/hw_info_types.h
index 49abafe..1740615 100644
--- a/displayengine/include/private/hw_info_types.h
+++ b/displayengine/include/private/hw_info_types.h
@@ -65,6 +65,7 @@
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;
@@ -81,8 +82,8 @@
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_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),
+ 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(); }
diff --git a/displayengine/libs/core/display_base.cpp b/displayengine/libs/core/display_base.cpp
index 8725a7b..47beac0 100644
--- a/displayengine/libs/core/display_base.cpp
+++ b/displayengine/libs/core/display_base.cpp
@@ -22,6 +22,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <stdio.h>
#include <utils/constants.h>
#include <utils/debug.h>
@@ -146,6 +147,11 @@
continue;
}
error = rotator_ctrl_->Prepare(display_rotator_ctx_, &hw_layers_);
+ } else {
+ // Release all the previous rotator sessions.
+ if (rotator_ctrl_) {
+ error = rotator_ctrl_->Purge(display_rotator_ctx_, &hw_layers_);
+ }
}
if (error == kErrorNone) {
@@ -409,9 +415,11 @@
num_modes_, active_mode_index_);
DisplayConfigVariableInfo &info = display_attributes_[active_mode_index_];
- DumpImpl::AppendString(buffer, length, "\nres:%ux%u, dpi:%.2fx%.2f, fps:%.2f, vsync period: %u",
- info.x_pixels, info.y_pixels, info.x_dpi, info.y_dpi, info.fps,
- info.vsync_period_ns);
+ DumpImpl::AppendString(buffer, length, "\nres:%u x %u, dpi:%.2f x %.2f, fps:%.2f,"
+ "vsync period: %u", info.x_pixels, info.y_pixels, info.x_dpi,
+ info.y_dpi, info.fps, info.vsync_period_ns);
+
+ DumpImpl::AppendString(buffer, length, "\n");
uint32_t num_layers = 0;
uint32_t num_hw_layers = 0;
@@ -420,64 +428,101 @@
num_hw_layers = hw_layers_.info.count;
}
- DumpImpl::AppendString(buffer, length, "\n\nnum actual layers: %u, num sde layers: %u",
- num_layers, num_hw_layers);
+ if (num_hw_layers == 0) {
+ DumpImpl::AppendString(buffer, length, "\nNo hardware layers programmed");
+ return;
+ }
+
+ HWLayersInfo &layer_info = hw_layers_.info;
+ LayerRect &l_roi = layer_info.left_partial_update;
+ LayerRect &r_roi = layer_info.right_partial_update;
+ DumpImpl::AppendString(buffer, length, "\nROI(L T R B) : LEFT(%d %d %d %d), RIGHT(%d %d %d %d)",
+ INT(l_roi.left), INT(l_roi.top), INT(l_roi.right), INT(l_roi.bottom),
+ INT(r_roi.left), INT(r_roi.top), INT(r_roi.right), INT(r_roi.bottom));
+
+ const char *header = "\n| Idx | Comp Type | Split | WB | Pipe | W x H | Format | Src Rect (L T R B) | Dst Rect (L T R B) | Z | Flags | Deci(HxV) |"; //NOLINT
+ const char *newline = "\n|-----|-------------|--------|----|-------|-------------|--------------------|---------------------|---------------------|----|------------|-----------|"; //NOLINT
+ const char *format = "\n| %3s | %11s " "| %6s " "| %2s | 0x%03x | %4d x %4d | %18s " "| %4d %4d %4d %4d " "| %4d %4d %4d %4d " "| %2s | %10s " "| %9s |"; //NOLINT
+
+ DumpImpl::AppendString(buffer, length, "\n");
+ DumpImpl::AppendString(buffer, length, newline);
+ DumpImpl::AppendString(buffer, length, header);
+ DumpImpl::AppendString(buffer, length, newline);
for (uint32_t i = 0; i < num_hw_layers; i++) {
- Layer &layer = hw_layers_.info.stack->layers[hw_layers_.info.index[i]];
+ uint32_t layer_index = hw_layers_.info.index[i];
+ Layer &layer = hw_layers_.info.stack->layers[layer_index];
LayerBuffer *input_buffer = layer.input_buffer;
HWLayerConfig &layer_config = hw_layers_.config[i];
-
- HWPipeInfo &left_pipe = hw_layers_.config[i].left_pipe;
- HWPipeInfo &right_pipe = hw_layers_.config[i].right_pipe;
-
HWRotatorSession &hw_rotator_session = layer_config.hw_rotator_session;
- HWRotateInfo &left_rotate = hw_rotator_session.hw_rotate_info[0];
- HWRotateInfo &right_rotate = hw_rotator_session.hw_rotate_info[1];
- DumpImpl::AppendString(buffer, length, "\n\nsde idx: %u, actual idx: %u", i,
- hw_layers_.info.index[i]);
- DumpImpl::AppendString(buffer, length, "\nw: %u, h: %u, fmt: %u",
- input_buffer->width, input_buffer->height, input_buffer->format);
- AppendRect(buffer, length, "\nsrc_rect:", &layer.src_rect);
- AppendRect(buffer, length, "\ndst_rect:", &layer.dst_rect);
+ char idx[8] = { 0 };
+ const char *comp_type = GetName(layer.composition);
+ const char *buffer_format = GetName(input_buffer->format);
+ const char *rotate_split[2] = { "Rot-L", "Rot-R" };
+ const char *comp_split[2] = { "Comp-L", "Comp-R" };
- if (left_rotate.valid) {
- DumpImpl::AppendString(buffer, length, "\n\tleft rotate =>");
- DumpImpl::AppendString(buffer, length, "\n\t pipe id: 0x%x", left_rotate.pipe_id);
- AppendRect(buffer, length, "\n\t src_roi:", &left_rotate.src_roi);
- AppendRect(buffer, length, "\n\t dst_roi:", &left_rotate.dst_roi);
+ snprintf(idx, sizeof(idx), "%d", layer_index);
+
+ for (uint32_t count = 0; count < hw_rotator_session.hw_block_count; count++) {
+ char writeback_id[8];
+ HWRotateInfo &rotate = hw_rotator_session.hw_rotate_info[count];
+ LayerRect &src_roi = rotate.src_roi;
+ LayerRect &dst_roi = rotate.dst_roi;
+
+ snprintf(writeback_id, sizeof(writeback_id), "%d", rotate.writeback_id);
+
+ DumpImpl::AppendString(buffer, length, format, idx, comp_type, rotate_split[count],
+ writeback_id, rotate.pipe_id, input_buffer->width,
+ input_buffer->height, buffer_format, INT(src_roi.left),
+ INT(src_roi.top), INT(src_roi.right), INT(src_roi.bottom),
+ INT(dst_roi.left), INT(dst_roi.top), INT(dst_roi.right),
+ INT(dst_roi.bottom), "-", "- ", "- ");
+
+ // print the below only once per layer block, fill with spaces for rest.
+ idx[0] = 0;
+ comp_type = "";
}
- if (right_rotate.valid) {
- DumpImpl::AppendString(buffer, length, "\n\tright rotate =>");
- DumpImpl::AppendString(buffer, length, "\n\t pipe id: 0x%x", right_rotate.pipe_id);
- AppendRect(buffer, length, "\n\t src_roi:", &right_rotate.src_roi);
- AppendRect(buffer, length, "\n\t dst_roi:", &right_rotate.dst_roi);
+ if (hw_rotator_session.hw_block_count > 0) {
+ input_buffer = &hw_rotator_session.output_buffer;
+ buffer_format = GetName(input_buffer->format);
}
- if (left_pipe.valid) {
- DumpImpl::AppendString(buffer, length, "\n\tleft pipe =>");
- DumpImpl::AppendString(buffer, length, "\n\t pipe id: 0x%x", left_pipe.pipe_id);
- AppendRect(buffer, length, "\n\t src_roi:", &left_pipe.src_roi);
- AppendRect(buffer, length, "\n\t dst_roi:", &left_pipe.dst_roi);
+ for (uint32_t count = 0; count < 2; count++) {
+ char decimation[16];
+ char flags[16];
+ char z_order[8];
+ HWPipeInfo &pipe = (count == 0) ? layer_config.left_pipe : layer_config.right_pipe;
+
+ if (!pipe.valid) {
+ continue;
+ }
+
+ LayerRect &src_roi = pipe.src_roi;
+ LayerRect &dst_roi = pipe.dst_roi;
+
+ snprintf(z_order, sizeof(z_order), "%d", pipe.z_order);
+ snprintf(flags, sizeof(flags), "0x%08x", layer.flags.flags);
+ snprintf(decimation, sizeof(decimation), "%3d x %3d", pipe.horizontal_decimation,
+ pipe.vertical_decimation);
+
+ DumpImpl::AppendString(buffer, length, format, idx, comp_type, comp_split[count],
+ "-", pipe.pipe_id, input_buffer->width, input_buffer->height,
+ buffer_format, INT(src_roi.left), INT(src_roi.top),
+ INT(src_roi.right), INT(src_roi.bottom), INT(dst_roi.left),
+ INT(dst_roi.top), INT(dst_roi.right), INT(dst_roi.bottom),
+ z_order, flags, decimation);
+
+ // print the below only once per layer block, fill with spaces for rest.
+ idx[0] = 0;
+ comp_type = "";
}
- if (right_pipe.valid) {
- DumpImpl::AppendString(buffer, length, "\n\tright pipe =>");
- DumpImpl::AppendString(buffer, length, "\n\t pipe id: 0x%x", right_pipe.pipe_id);
- AppendRect(buffer, length, "\n\t src_roi:", &right_pipe.src_roi);
- AppendRect(buffer, length, "\n\t dst_roi:", &right_pipe.dst_roi);
- }
+ DumpImpl::AppendString(buffer, length, newline);
}
}
-void DisplayBase::AppendRect(char *buffer, uint32_t length, const char *rect_name,
- LayerRect *rect) {
- DumpImpl::AppendString(buffer, length, "%s %.1f, %.1f, %.1f, %.1f",
- rect_name, rect->left, rect->top, rect->right, rect->bottom);
-}
-
int DisplayBase::GetBestConfig() {
return (num_modes_ == 1) ? 0 : -1;
}
@@ -497,5 +542,44 @@
return false;
}
-} // namespace sde
+const char * DisplayBase::GetName(const LayerComposition &composition) {
+ switch (composition) {
+ case kCompositionGPU: return "GPU";
+ case kCompositionSDE: return "SDE";
+ case kCompositionGPUTarget: return "GPU_TARGET";
+ default: return "UNKNOWN";
+ }
+}
+const char * DisplayBase::GetName(const LayerBufferFormat &format) {
+ switch (format) {
+ case kFormatARGB8888: return "ARGB_8888";
+ case kFormatRGBA8888: return "RGBA_8888";
+ case kFormatBGRA8888: return "BGRA_8888";
+ case kFormatXRGB8888: return "XRGB_8888";
+ case kFormatRGBX8888: return "RGBX_8888";
+ case kFormatBGRX8888: return "BGRX_8888";
+ case kFormatRGBA5551: return "RGBA_5551";
+ case kFormatRGBA4444: return "RGBA_4444";
+ case kFormatRGB888: return "RGB_888";
+ case kFormatBGR888: return "BGR_888";
+ case kFormatRGB565: return "RGB_565";
+ case kFormatRGBA8888Ubwc: return "RGBA_8888_UBWC";
+ case kFormatRGBX8888Ubwc: return "RGBX_8888_UBWC";
+ case kFormatRGB565Ubwc: return "RGB_565_UBWC";
+ case kFormatYCbCr420Planar: return "Y_CB_CR_420";
+ case kFormatYCrCb420Planar: return "Y_CR_CB_420";
+ case kFormatYCbCr420SemiPlanar: return "Y_CBCR_420";
+ case kFormatYCrCb420SemiPlanar: return "Y_CRCB_420";
+ case kFormatYCbCr420SemiPlanarVenus: return "Y_CBCR_420_VENUS";
+ case kFormatYCbCr422H1V2SemiPlanar: return "Y_CBCR_422_H1V2";
+ case kFormatYCrCb422H1V2SemiPlanar: return "Y_CRCB_422_H1V2";
+ case kFormatYCbCr422H2V1SemiPlanar: return "Y_CBCR_422_H2V1";
+ case kFormatYCrCb422H2V1SemiPlanar: return "Y_CRCB_422_H2V2";
+ case kFormatYCbCr420SPVenusUbwc: return "Y_CBCR_420_VENUS_UBWC";
+ case kFormatYCbCr422H2V1Packed: return "YCBYCR_422_H2V1";
+ default: return "UNKNOWN";
+ }
+}
+
+} // namespace sde
diff --git a/displayengine/libs/core/display_base.h b/displayengine/libs/core/display_base.h
index 1edef9e..0a33011 100644
--- a/displayengine/libs/core/display_base.h
+++ b/displayengine/libs/core/display_base.h
@@ -60,15 +60,14 @@
virtual DisplayError SetMaxMixerStages(uint32_t max_mixer_stages);
virtual DisplayError SetDisplayMode(uint32_t mode);
- private:
- bool IsRotationRequired(HWLayers *hw_layers);
-
protected:
// DumpImpl method
void AppendDump(char *buffer, uint32_t length);
- void AppendRect(char *buffer, uint32_t length, const char *rect_name, LayerRect *rect);
virtual int GetBestConfig();
+ bool IsRotationRequired(HWLayers *hw_layers);
+ const char * GetName(const LayerComposition &composition);
+ const char * GetName(const LayerBufferFormat &format);
DisplayType display_type_;
DisplayEventHandler *event_handler_;
diff --git a/displayengine/libs/core/display_hdmi.h b/displayengine/libs/core/display_hdmi.h
index 1a96884..ea1b80c 100644
--- a/displayengine/libs/core/display_hdmi.h
+++ b/displayengine/libs/core/display_hdmi.h
@@ -26,6 +26,7 @@
#define __DISPLAY_HDMI_H__
#include "display_base.h"
+#include "dump_impl.h"
namespace sde {
diff --git a/displayengine/libs/core/display_primary.cpp b/displayengine/libs/core/display_primary.cpp
index d6116fa..0fa5d2b 100644
--- a/displayengine/libs/core/display_primary.cpp
+++ b/displayengine/libs/core/display_primary.cpp
@@ -186,7 +186,7 @@
return kErrorNotSupported;
}
- switch(mode) {
+ switch (mode) {
case kModeVideo:
hw_display_mode = kModeVideo;
break;
diff --git a/displayengine/libs/core/display_primary.h b/displayengine/libs/core/display_primary.h
index be422de..1ed28b2 100644
--- a/displayengine/libs/core/display_primary.h
+++ b/displayengine/libs/core/display_primary.h
@@ -26,6 +26,7 @@
#define __DISPLAY_PRIMARY_H__
#include "display_base.h"
+#include "dump_impl.h"
namespace sde {
diff --git a/displayengine/libs/core/display_virtual.h b/displayengine/libs/core/display_virtual.h
index 8e7a764..f868612 100644
--- a/displayengine/libs/core/display_virtual.h
+++ b/displayengine/libs/core/display_virtual.h
@@ -26,6 +26,7 @@
#define __DISPLAY_VIRTUAL_H__
#include "display_base.h"
+#include "dump_impl.h"
namespace sde {
diff --git a/displayengine/libs/core/dump_impl.cpp b/displayengine/libs/core/dump_impl.cpp
index a5aca81..f9219f3 100755
--- a/displayengine/libs/core/dump_impl.cpp
+++ b/displayengine/libs/core/dump_impl.cpp
@@ -44,7 +44,7 @@
for (uint32_t i = 0; i < DumpImpl::dump_count_; i++) {
DumpImpl::dump_list_[i]->AppendDump(buffer, length);
}
- DumpImpl::AppendString(buffer, length, "\n-------------------------------------------\n");
+ DumpImpl::AppendString(buffer, length, "\n\n");
return kErrorNone;
}
diff --git a/displayengine/libs/core/fb/hw_device.cpp b/displayengine/libs/core/fb/hw_device.cpp
index 230092a..6db1370 100644
--- a/displayengine/libs/core/fb/hw_device.cpp
+++ b/displayengine/libs/core/fb/hw_device.cpp
@@ -214,6 +214,7 @@
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;
+ bool is_rotator_used = (hw_rotator_session->hw_block_count != 0);
mdp_input_layer mdp_layer;
for (uint32_t count = 0; count < 2; count++) {
@@ -246,18 +247,7 @@
SetRect(pipe_info->src_roi, &mdp_layer.src_rect);
SetRect(pipe_info->dst_roi, &mdp_layer.dst_rect);
-
- // Flips will be taken care by rotator, if layer requires 90 rotation. So Dont use MDP for
- // flip operation, if layer transform is 90.
- if (!layer.transform.rotation) {
- if (layer.transform.flip_vertical) {
- mdp_layer.flags |= MDP_LAYER_FLIP_UD;
- }
-
- if (layer.transform.flip_horizontal) {
- mdp_layer.flags |= MDP_LAYER_FLIP_LR;
- }
- }
+ SetMDPFlags(layer, is_rotator_used, &mdp_layer.flags);
mdp_scale_data* mdp_scale = GetScaleDataRef(mdp_layer_count);
#ifdef USES_SCALAR
@@ -328,9 +318,9 @@
return kErrorNone;
}
-void HWDevice::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;
+void HWDevice::DumpLayerCommit(const mdp_layer_commit &layer_commit) {
+ const mdp_layer_commit_v1 &mdp_commit = layer_commit.commit_v1;
+ const mdp_input_layer *mdp_layers = mdp_commit.input_layers;
DLOGE("mdp_commit: 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,
@@ -340,10 +330,10 @@
for (uint32_t i = 0; i < mdp_commit.input_layer_cnt; i++) {
DLOGE("mdp_commit: 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;
+ const 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;
+ const 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);
}
@@ -523,6 +513,7 @@
case kFormatYCbCr422H2V1Packed: *target = MDP_YCBYCR_H2V1; break;
case kFormatYCbCr420SemiPlanarVenus: *target = MDP_Y_CBCR_H2V2_VENUS; break;
case kFormatRGBA8888Ubwc: *target = MDP_RGBA_8888_UBWC; break;
+ case kFormatRGBX8888Ubwc: *target = MDP_RGBX_8888_UBWC; break;
case kFormatRGB565Ubwc: *target = MDP_RGB_565_UBWC; break;
case kFormatYCbCr420SPVenusUbwc: *target = MDP_Y_CBCR_H2V2_UBWC; break;
default:
@@ -548,6 +539,8 @@
case kFormatBGRA8888:
case kFormatRGBX8888:
case kFormatBGRX8888:
+ case kFormatRGBA8888Ubwc:
+ case kFormatRGBX8888Ubwc:
*target = width * 4;
break;
case kFormatRGB888:
@@ -555,7 +548,8 @@
*target = width * 3;
break;
case kFormatRGB565:
- *target = width * 3;
+ case kFormatRGB565Ubwc:
+ *target = width * 2;
break;
case kFormatYCbCr420SemiPlanarVenus:
case kFormatYCbCr420SPVenusUbwc:
@@ -597,6 +591,35 @@
target->h = UINT32(source.bottom) - target->y;
}
+void HWDevice::SetMDPFlags(const Layer &layer, const bool &is_rotator_used,
+ uint32_t *mdp_flags) {
+ LayerBuffer *input_buffer = layer.input_buffer;
+
+ // Flips will be taken care by rotator, if layer uses rotator for downscale/rotation. So ignore
+ // flip flags for MDP.
+ if (!is_rotator_used) {
+ if (layer.transform.flip_vertical) {
+ *mdp_flags |= MDP_LAYER_FLIP_UD;
+ }
+
+ if (layer.transform.flip_horizontal) {
+ *mdp_flags |= MDP_LAYER_FLIP_LR;
+ }
+ }
+
+ if (input_buffer->flags.interlace) {
+ *mdp_flags |= MDP_LAYER_DEINTERLACE;
+ }
+
+ if (input_buffer->flags.secure) {
+ *mdp_flags |= MDP_LAYER_SECURE_SESSION;
+ }
+
+ if (input_buffer->flags.secure_display) {
+ *mdp_flags |= MDP_SECURE_DISPLAY_OVERLAY_SESSION;
+ }
+}
+
void HWDevice::SyncMerge(const int &fd1, const int &fd2, int *target) {
if (fd1 >= 0 && fd2 >= 0) {
buffer_sync_handler_->SyncMerge(fd1, fd2, target);
diff --git a/displayengine/libs/core/fb/hw_device.h b/displayengine/libs/core/fb/hw_device.h
index 8dca6f9..734b69d 100644
--- a/displayengine/libs/core/fb/hw_device.h
+++ b/displayengine/libs/core/fb/hw_device.h
@@ -72,12 +72,13 @@
static const int kNumPhysicalDisplays = 2;
static const int kNumDisplayEvents = 4;
- void DumpLayerCommit(mdp_layer_commit &layer_commit);
+ void DumpLayerCommit(const mdp_layer_commit &layer_commit);
DisplayError SetFormat(const LayerBufferFormat &source, uint32_t *target);
DisplayError SetStride(HWDeviceType device_type, LayerBufferFormat format,
uint32_t width, uint32_t *target);
void SetBlending(const LayerBlending &source, mdss_mdp_blend_op *target);
void SetRect(const LayerRect &source, mdp_rect *target);
+ void SetMDPFlags(const Layer &layer, const bool &is_rotator_used, uint32_t *mdp_flags);
void SyncMerge(const int &fd1, const int &fd2, int *target);
// Retrieves HW FrameBuffer Node Index
diff --git a/displayengine/libs/core/fb/hw_info.cpp b/displayengine/libs/core/fb/hw_info.cpp
index cddb590..7833c3c 100644
--- a/displayengine/libs/core/fb/hw_info.cpp
+++ b/displayengine/libs/core/fb/hw_info.cpp
@@ -123,6 +123,8 @@
hw_resource->max_bandwidth_high = atol(tokens[1]);
} else if (!strncmp(tokens[0], "max_mixer_width", strlen("max_mixer_width"))) {
hw_resource->max_mixer_width = atoi(tokens[1]);
+ } else if (!strncmp(tokens[0], "max_pipe_width", strlen("max_pipe_width"))) {
+ hw_resource->max_pipe_width = atoi(tokens[1]);
} else if (!strncmp(tokens[0], "max_pipe_bw", strlen("max_pipe_bw"))) {
hw_resource->max_pipe_bw = atoi(tokens[1]);
} else if (!strncmp(tokens[0], "max_mdp_clk", strlen("max_mdp_clk"))) {
diff --git a/displayengine/libs/core/fb/hw_rotator.cpp b/displayengine/libs/core/fb/hw_rotator.cpp
index cc9bd1a..c698445 100644
--- a/displayengine/libs/core/fb/hw_rotator.cpp
+++ b/displayengine/libs/core/fb/hw_rotator.cpp
@@ -173,17 +173,7 @@
if (hw_rotate_info->valid) {
mdp_rotation_item *mdp_rot_item = &mdp_rot_request_.list[rot_count];
- if (rot90) {
- mdp_rot_item->flags |= MDP_ROTATION_90;
- }
-
- if (layer.transform.flip_horizontal) {
- mdp_rot_item->flags |= MDP_ROTATION_FLIP_LR;
- }
-
- if (layer.transform.flip_vertical) {
- mdp_rot_item->flags |= MDP_ROTATION_FLIP_UD;
- }
+ 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);
@@ -274,6 +264,27 @@
}
}
+ 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);
diff --git a/displayengine/libs/core/fb/hw_rotator.h b/displayengine/libs/core/fb/hw_rotator.h
index 3b4eebe..b78b657 100644
--- a/displayengine/libs/core/fb/hw_rotator.h
+++ b/displayengine/libs/core/fb/hw_rotator.h
@@ -53,6 +53,7 @@
void ResetParams();
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)
diff --git a/displayengine/libs/core/res_config.cpp b/displayengine/libs/core/res_config.cpp
index 3cea3db..c5a8a06 100644
--- a/displayengine/libs/core/res_config.cpp
+++ b/displayengine/libs/core/res_config.cpp
@@ -122,7 +122,7 @@
// 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 > kMaxSourcePipeWidth) || (dst_width > kMaxSourcePipeWidth) ||
+ 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,
@@ -169,7 +169,7 @@
crop_right_valid = CalculateCropRects(scissor, transform, &crop_right, &dst_right);
}
- if (crop_left_valid && (crop_left.right - crop_left.left) > kMaxSourcePipeWidth) {
+ 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);
@@ -181,7 +181,8 @@
left_pipe->valid = true;
right_pipe->valid = true;
crop_right_valid = true;
- } else if (crop_right_valid && (crop_right.right - crop_right.left) > kMaxSourcePipeWidth) {
+ } 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);
@@ -234,12 +235,11 @@
for (uint32_t i = 0; i < layer_info.count; i++) {
Layer& layer = layer_info.stack->layers[layer_info.index[i]];
- float rot_scale = 1.0f;
- if (!IsValidDimension(layer.src_rect, layer.dst_rect)) {
- DLOGV_IF(kTagResources, "Input is invalid");
- Log(kTagResources, "input layer src_rect", layer.src_rect);
- Log(kTagResources, "input layer dst_rect", layer.dst_rect);
- return kErrorNotSupported;
+ float rotator_scale_factor = 1.0f;
+
+ error = ValidateLayerDimensions(layer);
+ if (error != kErrorNone) {
+ return error;
}
LayerRect scissor, src_rect, dst_rect;
@@ -253,7 +253,7 @@
HWPipeInfo &right_pipe = layer_config->right_pipe;
HWRotatorSession *hw_rotator_session = &layer_config->hw_rotator_session;
LayerTransform transform = layer.transform;
- bool rot90 = IsRotationNeeded(transform.rotation);
+ bool rotated90 = IsRotationNeeded(transform.rotation);
if (!CalculateCropRects(scissor, layer.transform, &src_rect, &dst_rect)) {
layer_config->Reset();
@@ -268,8 +268,19 @@
Normalize(align_x, align_y, &src_rect);
}
- if (ValidateScaling(layer, src_rect, dst_rect, &rot_scale)) {
- return kErrorNotSupported;
+ 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
@@ -278,8 +289,8 @@
}
hw_rotator_session->hw_block_count = 0;
- if (rot90 || UINT32(rot_scale) != 1) {
- RotationConfig(layer, rot_scale, &src_rect, layer_config, rotate_count);
+ 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();
}
@@ -306,7 +317,7 @@
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, rot_scale);
+ 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);
}
@@ -343,91 +354,6 @@
return error;
}
-DisplayError ResManager::ValidateScaling(const Layer &layer, const LayerRect &crop,
- const LayerRect &dst, float *rot_scale) {
- bool rotated90 = IsRotationNeeded(layer.transform.rotation) && (rot_scale != NULL);
- float crop_width = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
- float crop_height = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
- float dst_width = dst.right - dst.left;
- float dst_height = dst.bottom - dst.top;
-
- 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;
- }
-
- float scale_x = crop_width / dst_width;
- float scale_y = crop_height / dst_height;
- uint32_t rot_scale_local = 1;
-
- 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_rotator_downscale && !property_setting_.disable_rotator_downscaling &&
- rot_scale && !IsMacroTileFormat(layer.input_buffer)) {
- float scale_min = MIN(scale_x, scale_y);
- float scale_max = MAX(scale_x, scale_y);
- // 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.
- rot_scale_local = 1 << UINT32(ceilf(log2f(scale_min / max_scale_down)));
- if (rot_scale_local > kMaxRotateDownScaleRatio)
- rot_scale_local = kMaxRotateDownScaleRatio;
- scale_x /= FLOAT(rot_scale_local);
- scale_y /= FLOAT(rot_scale_local);
- }
- *rot_scale = FLOAT(rot_scale_local);
- }
-
- if (hw_res_info_.has_decimation && !property_setting_.disable_decimation &&
- !IsMacroTileFormat(layer.input_buffer)) {
- 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: is_tile = %d, scale_x = %.0f, scale_y = %.0f, " \
- "crop_w = %.0f, dst_w = %.0f, has_deci = %d, disable_deci = %d, rot_scale = %d",
- IsMacroTileFormat(layer.input_buffer), scale_x, scale_y, crop_width, dst_width,
- hw_res_info_.has_decimation, property_setting_.disable_decimation, rot_scale_local);
- return kErrorNotSupported;
- }
- }
-
- 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, rot_scale = %d",
- scale_x, scale_y, rot_scale_local);
-
- return kErrorNone;
-}
-
void ResManager::CalculateCut(const LayerTransform &transform, float *left_cut_ratio,
float *top_cut_ratio, float *right_cut_ratio,
float *bottom_cut_ratio) {
@@ -514,22 +440,239 @@
return false;
}
-bool ResManager::IsValidDimension(const LayerRect &src, const LayerRect &dst) {
- // Make sure source in integral
- if (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 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;
}
- if (src.left > src.right || src.top > src.bottom || dst.left > dst.right ||
- dst.top > dst.bottom) {
- return false;
- } else {
- return true;
+ // 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) {
@@ -628,13 +771,14 @@
}
right_pipe->dst_roi.left = left_pipe->dst_roi.right;
}
- error = ValidateScaling(layer, left_pipe->src_roi, left_pipe->dst_roi, NULL);
+
+ error = ValidatePipeParams(left_pipe);
if (error != kErrorNone) {
goto PipeConfigExit;
}
if (right_pipe->valid) {
- error = ValidateScaling(layer, right_pipe->src_roi, right_pipe->dst_roi, NULL);
+ error = ValidatePipeParams(right_pipe);
}
PipeConfigExit:
if (error != kErrorNone) {
diff --git a/displayengine/libs/core/res_manager.cpp b/displayengine/libs/core/res_manager.cpp
index 08b055b..261155f 100644
--- a/displayengine/libs/core/res_manager.cpp
+++ b/displayengine/libs/core/res_manager.cpp
@@ -40,20 +40,18 @@
}
DisplayError ResManager::Init(const HWResourceInfo &hw_res_info) {
- hw_res_info_ = hw_res_info;
-
- if (!hw_res_info_.max_mixer_width)
- hw_res_info_.max_mixer_width = kMaxSourcePipeWidth;
-
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;
+ 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_);
+ 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];
@@ -1043,9 +1041,17 @@
break;
}
- // TODO(user): UBWC RGB formats will be handled separately
if (downscale) {
switch (input_format) {
+ case kFormatRGBA8888Ubwc:
+ *output_format = is_opaque ? kFormatRGB888 : kFormatRGBA8888;
+ break;
+ case kFormatRGBX8888Ubwc:
+ *output_format = kFormatRGB888;
+ break;
+ case kFormatRGB565Ubwc:
+ *output_format = kFormatRGB565;
+ break;
case kFormatYCbCr420SPVenusUbwc:
*output_format = kFormatYCbCr420SemiPlanar;
break;
@@ -1055,6 +1061,15 @@
} else {
if (hw_res_info_.has_ubwc) {
switch (input_format) {
+ case kFormatRGBA8888:
+ *output_format = kFormatRGBA8888Ubwc;
+ break;
+ case kFormatRGBX8888:
+ *output_format = kFormatRGBX8888Ubwc;
+ break;
+ case kFormatRGB565:
+ *output_format = kFormatRGB565Ubwc;
+ break;
case kFormatYCrCb420SemiPlanar:
case kFormatYCbCr420SemiPlanar:
case kFormatYCbCr420SemiPlanarVenus:
diff --git a/displayengine/libs/core/res_manager.h b/displayengine/libs/core/res_manager.h
index a127645..7fa5260 100644
--- a/displayengine/libs/core/res_manager.h
+++ b/displayengine/libs/core/res_manager.h
@@ -49,6 +49,7 @@
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);
@@ -85,7 +86,6 @@
// todo: retrieve all these from kernel
enum {
- kMaxSourcePipeWidth = 2048,
kMaxInterfaceWidth = 2048,
kMaxRotateDownScaleRatio = 8,
kMaxDecimationDownScaleRatio = 8,
@@ -164,8 +164,6 @@
const LayerTransform &transform, const LayerRect &src_rect,
const LayerRect &dst_rect, 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,
@@ -174,7 +172,19 @@
float *right_cut_ratio, float *bottom_cut_ratio);
bool CalculateCropRects(const LayerRect &scissor, const LayerTransform &transform,
LayerRect *crop, LayerRect *dst);
- bool IsValidDimension(const LayerRect &src, const 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);
@@ -200,7 +210,7 @@
HWPipeInfo *left_pipe, HWPipeInfo *right_pipe,
uint32_t align_x, uint32_t align_y);
void ResourceStateLog(void);
- DisplayError CalculateDecimation(float downscale, uint8_t* decimation);
+ DisplayError CalculateDecimation(float downscale, uint8_t *decimation);
Locker locker_;
HWResourceInfo hw_res_info_;
diff --git a/displayengine/libs/core/rotator_ctrl.cpp b/displayengine/libs/core/rotator_ctrl.cpp
index 701006c..8018e31 100644
--- a/displayengine/libs/core/rotator_ctrl.cpp
+++ b/displayengine/libs/core/rotator_ctrl.cpp
@@ -84,7 +84,7 @@
}
DisplayError RotatorCtrl::RegisterDisplay(DisplayType type, Handle *display_ctx) {
- DisplaRotatorContext *disp_rotator_ctx = new DisplaRotatorContext();
+ DisplayRotatorContext *disp_rotator_ctx = new DisplayRotatorContext();
if (disp_rotator_ctx == NULL) {
return kErrorMemory;
}
@@ -96,7 +96,7 @@
}
void RotatorCtrl::UnregisterDisplay(Handle display_ctx) {
- DisplaRotatorContext *disp_rotator_ctx = reinterpret_cast<DisplaRotatorContext *>(display_ctx);
+ DisplayRotatorContext *disp_rotator_ctx = reinterpret_cast<DisplayRotatorContext *>(display_ctx);
delete disp_rotator_ctx;
disp_rotator_ctx = NULL;
@@ -106,9 +106,9 @@
DisplayError RotatorCtrl::Prepare(Handle display_ctx, HWLayers *hw_layers) {
DisplayError error = kErrorNone;
- DisplaRotatorContext *disp_rotator_ctx = reinterpret_cast<DisplaRotatorContext *>(display_ctx);
+ DisplayRotatorContext *disp_rotator_ctx = reinterpret_cast<DisplayRotatorContext *>(display_ctx);
- error = PrepareSessions(hw_layers);
+ 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;
@@ -126,9 +126,9 @@
DisplayError RotatorCtrl::Commit(Handle display_ctx, HWLayers *hw_layers) {
DisplayError error = kErrorNone;
- DisplaRotatorContext *disp_rotator_ctx = reinterpret_cast<DisplaRotatorContext *>(display_ctx);
+ DisplayRotatorContext *disp_rotator_ctx = reinterpret_cast<DisplayRotatorContext *>(display_ctx);
- error = GetOutputBuffers(hw_layers);
+ error = GetOutputBuffers(disp_rotator_ctx, hw_layers);
if (error != kErrorNone) {
return error;
}
@@ -145,7 +145,8 @@
DisplayError RotatorCtrl::PostCommit(Handle display_ctx, HWLayers *hw_layers) {
HWLayersInfo &hw_layer_info = hw_layers->info;
DisplayError error = kErrorNone;
- DisplaRotatorContext *disp_rotator_ctx = reinterpret_cast<DisplaRotatorContext *>(display_ctx);
+ 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]];
@@ -155,7 +156,7 @@
continue;
}
- error = session_manager_->SetReleaseFd(hw_rotator_session);
+ 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;
@@ -165,11 +166,22 @@
return kErrorNone;
}
-DisplayError RotatorCtrl::PrepareSessions(HWLayers *hw_layers) {
+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();
+ 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]];
@@ -197,20 +209,25 @@
hw_session_config.secure = layer.input_buffer->flags.secure;
hw_session_config.frame_rate = layer.frame_rate;
- error = session_manager_->OpenSession(hw_rotator_session);
+ error = session_manager_->OpenSession(client_id, hw_rotator_session);
if (error != kErrorNone) {
return error;
}
}
- session_manager_->Stop();
+ error = session_manager_->Stop(client_id);
+ if (error != kErrorNone) {
+ return error;
+ }
return kErrorNone;
}
-DisplayError RotatorCtrl::GetOutputBuffers(HWLayers *hw_layers) {
+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]];
@@ -220,7 +237,7 @@
continue;
}
- error = session_manager_->GetNextBuffer(hw_rotator_session);
+ error = session_manager_->GetNextBuffer(client_id, hw_rotator_session);
if (error != kErrorNone) {
return error;
}
diff --git a/displayengine/libs/core/rotator_ctrl.h b/displayengine/libs/core/rotator_ctrl.h
index 083f4ca..3e5deaf 100644
--- a/displayengine/libs/core/rotator_ctrl.h
+++ b/displayengine/libs/core/rotator_ctrl.h
@@ -47,6 +47,7 @@
DisplayError Prepare(Handle display_ctx, HWLayers *hw_layers);
DisplayError Commit(Handle display_ctx, HWLayers *hw_layers);
DisplayError PostCommit(Handle display_ctx, HWLayers *hw_layers);
+ DisplayError Purge(Handle display_ctx, HWLayers *hw_layers);
private:
enum {
@@ -55,14 +56,14 @@
kTripleBuffering = 3,
};
- struct DisplaRotatorContext {
+ struct DisplayRotatorContext {
DisplayType display_type;
- DisplaRotatorContext() : display_type(kPrimary) { }
+ DisplayRotatorContext() : display_type(kPrimary) { }
};
- DisplayError PrepareSessions(HWLayers *hw_layers);
- DisplayError GetOutputBuffers(HWLayers *hw_layers);
+ DisplayError PrepareSessions(DisplayRotatorContext *disp_rotator_ctx, HWLayers *hw_layers);
+ DisplayError GetOutputBuffers(DisplayRotatorContext *disp_rotator_ctx, HWLayers *hw_layers);
HWRotatorInterface *hw_rotator_intf_;
SessionManager *session_manager_;
diff --git a/displayengine/libs/core/scalar_helper.cpp b/displayengine/libs/core/scalar_helper.cpp
index c81e343..b5d8989 100644
--- a/displayengine/libs/core/scalar_helper.cpp
+++ b/displayengine/libs/core/scalar_helper.cpp
@@ -91,6 +91,7 @@
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:
diff --git a/displayengine/libs/core/session_manager.cpp b/displayengine/libs/core/session_manager.cpp
index f87bf10..dd4c29a 100644
--- a/displayengine/libs/core/session_manager.cpp
+++ b/displayengine/libs/core/session_manager.cpp
@@ -59,23 +59,28 @@
buffer_sync_handler_(buffer_sync_handler), active_session_count_(0) {
}
-void SessionManager::Start() {
+void SessionManager::Start(const int &client_id) {
+ SCOPE_LOCK(locker_);
+
uint32_t session_count = 0;
- uint32_t ready_session_count = 0;
+ uint32_t acquired_session_count = 0;
// Change the state of acquired session to kSessionReady
- while ((ready_session_count < active_session_count_) && (session_count < kMaxSessionCount)) {
- if (session_list_[session_count].state == kSessionReleased) {
- session_count++;
- continue;
+ 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_list_[session_count++].state = kSessionReady;
- ready_session_count++;
+ session_count++;
}
}
-DisplayError SessionManager::OpenSession(HWRotatorSession *hw_rotator_session) {
+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;
@@ -90,12 +95,12 @@
uint32_t free_session = active_session_count_;
uint32_t acquired_session = kMaxSessionCount;
- uint32_t ready_session_count = 0;
+ 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 &&
- ready_session_count < active_session_count_; session_count++) {
+ active_session_count < active_session_count_; session_count++) {
HWSessionConfig &hw_session_config =
session_list_[session_count].hw_rotator_session.hw_session_config;
@@ -104,17 +109,15 @@
continue;
}
- if (session_list_[session_count].state != kSessionReady) {
- 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;
+ }
}
-
- if (input_config == hw_session_config) {
- session_list_[session_count].state = kSessionAcquired;
- acquired_session = session_count;
- break;
- }
-
- ready_session_count++;
+ active_session_count++;
}
// If the input config does not match with existing config, then add new session and change the
@@ -131,31 +134,31 @@
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", hw_rotator_session->output_buffer.width,
+ "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);
+ hw_rotator_session->session_id, client_id);
return kErrorNone;
}
- 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;
- hw_rotator_session->session_id = acquired_session;
+ *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", hw_rotator_session->output_buffer.width,
+ "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);
+ hw_rotator_session->session_id, client_id);
return kErrorNone;
}
-DisplayError SessionManager::GetNextBuffer(HWRotatorSession *hw_rotator_session) {
+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;
@@ -166,7 +169,7 @@
Session *session = &session_list_[session_id];
if (session->state != kSessionAcquired) {
DLOGE("Invalid session state %d", session->state);
- kErrorParameters;
+ return kErrorParameters;
}
uint32_t curr_index = session->curr_index;
@@ -195,33 +198,38 @@
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,",
+ "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, hw_rotator_session->session_id);
+ hw_rotator_session->output_buffer.planes[0].fd, session_id, client_id);
return kErrorNone;
}
-DisplayError SessionManager::Stop() {
+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) {
+ 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", session_id,
- 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++;
}
@@ -229,7 +237,10 @@
return kErrorNone;
}
-DisplayError SessionManager::SetReleaseFd(HWRotatorSession *hw_rotator_session) {
+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;
@@ -238,7 +249,7 @@
Session *session = &session_list_[session_id];
if (session->state != kSessionAcquired) {
DLOGE("Invalid session state %d", session->state);
- kErrorParameters;
+ return kErrorParameters;
}
uint32_t &curr_index = session->curr_index;
@@ -251,8 +262,8 @@
curr_index = (curr_index + 1) % buffer_count;
- DLOGI_IF(kTagRotator, "session_id %d, curr_index = %d, release fd %d", session_id,
- curr_index, hw_rotator_session->output_buffer.release_fence_fd);
+ 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;
}
@@ -333,7 +344,9 @@
session->release_fd[idx] = -1;
}
}
+
session->state = kSessionReleased;
+ session->client_id == -1;
if (session->offset) {
delete[] session->offset;
diff --git a/displayengine/libs/core/session_manager.h b/displayengine/libs/core/session_manager.h
index b27ba8b..3324c3e 100644
--- a/displayengine/libs/core/session_manager.h
+++ b/displayengine/libs/core/session_manager.h
@@ -43,11 +43,11 @@
SessionManager(HWRotatorInterface *hw_intf, BufferAllocator *buffer_allocator,
BufferSyncHandler *buffer_sync_handler);
- void Start();
- DisplayError Stop();
- DisplayError OpenSession(HWRotatorSession *hw_rotator_session);
- DisplayError GetNextBuffer(HWRotatorSession *hw_rotator_session);
- DisplayError SetReleaseFd(HWRotatorSession *hw_rotator_session);
+ 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
@@ -66,13 +66,16 @@
int *release_fd;
uint32_t *offset;
uint32_t curr_index;
+ int client_id;
- Session() : state(kSessionReleased), release_fd(NULL), offset(NULL), curr_index(0) { }
+ 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_;
diff --git a/displayengine/libs/hwc/hwc_buffer_allocator.cpp b/displayengine/libs/hwc/hwc_buffer_allocator.cpp
index 2adfc3a..61d9913 100644
--- a/displayengine/libs/hwc/hwc_buffer_allocator.cpp
+++ b/displayengine/libs/hwc/hwc_buffer_allocator.cpp
@@ -63,11 +63,6 @@
int height = INT(buffer_config.height);
int format;
- error = SetHALFormat(buffer_config.format, &format);
- if (error != 0) {
- return kErrorParameters;
- }
-
if (buffer_config.secure) {
alloc_flags = GRALLOC_USAGE_PRIVATE_MM_HEAP;
alloc_flags |= GRALLOC_USAGE_PROTECTED;
@@ -81,11 +76,16 @@
alloc_flags |= GRALLOC_USAGE_PRIVATE_UNCACHED;
}
+ error = SetBufferInfo(buffer_config.format, &format, &alloc_flags);
+ if (error != 0) {
+ return kErrorParameters;
+ }
+
int aligned_width = 0, aligned_height = 0;
uint32_t buffer_size = getBufferSizeAndDimensions(width, height, format, alloc_flags,
aligned_width, aligned_height);
- buffer_size = ROUND_UP((buffer_size * buffer_config.buffer_count), data.align);
+ buffer_size = ROUND_UP(buffer_size, data.align) * buffer_config.buffer_count;
data.base = 0;
data.fd = -1;
@@ -116,8 +116,9 @@
AllocatedBufferInfo *alloc_buffer_info = &buffer_info->alloc_buffer_info;
MetaBufferInfo *meta_buffer_info = static_cast<MetaBufferInfo *> (buffer_info->private_data);
- if ((alloc_buffer_info->fd < 0) || (meta_buffer_info->base_addr == NULL)) {
- return kErrorNone;
+ if (alloc_buffer_info->fd < 0) {
+ DLOGE("Invalid parameters: fd %d", alloc_buffer_info->fd);
+ return kErrorParameters;
}
gralloc::IMemAlloc *memalloc = alloc_controller_->getAllocator(meta_buffer_info->alloc_type);
@@ -147,7 +148,7 @@
return kErrorNone;
}
-int HWCBufferAllocator::SetHALFormat(LayerBufferFormat format, int *target) {
+int HWCBufferAllocator::SetBufferInfo(LayerBufferFormat format, int *target, int *flags) {
switch (format) {
case kFormatRGBA8888: *target = HAL_PIXEL_FORMAT_RGBA_8888; break;
case kFormatRGBX8888: *target = HAL_PIXEL_FORMAT_RGBX_8888; break;
@@ -163,7 +164,18 @@
case kFormatYCbCr420SPVenusUbwc: *target = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC; break;
case kFormatRGBA5551: *target = HAL_PIXEL_FORMAT_RGBA_5551; break;
case kFormatRGBA4444: *target = HAL_PIXEL_FORMAT_RGBA_4444; break;
-
+ case kFormatRGBA8888Ubwc:
+ *target = HAL_PIXEL_FORMAT_RGBA_8888;
+ *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
+ break;
+ case kFormatRGBX8888Ubwc:
+ *target = HAL_PIXEL_FORMAT_RGBX_8888;
+ *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
+ break;
+ case kFormatRGB565Ubwc:
+ *target = HAL_PIXEL_FORMAT_RGB_565;
+ *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
+ break;
default:
DLOGE("Unsupported format = 0x%x", format);
return -EINVAL;
diff --git a/displayengine/libs/hwc/hwc_buffer_allocator.h b/displayengine/libs/hwc/hwc_buffer_allocator.h
index 123f04a..eb3d1fd 100644
--- a/displayengine/libs/hwc/hwc_buffer_allocator.h
+++ b/displayengine/libs/hwc/hwc_buffer_allocator.h
@@ -57,7 +57,7 @@
void *base_addr; //!< Specifies the base address of the allocated output buffer.
};
- int SetHALFormat(LayerBufferFormat format, int *target);
+ int SetBufferInfo(LayerBufferFormat format, int *target, int *flags);
gralloc::IAllocController *alloc_controller_;
};
diff --git a/displayengine/libs/hwc/hwc_display.cpp b/displayengine/libs/hwc/hwc_display.cpp
index 124310a..8a73d3c 100644
--- a/displayengine/libs/hwc/hwc_display.cpp
+++ b/displayengine/libs/hwc/hwc_display.cpp
@@ -350,6 +350,14 @@
if (meta_data && meta_data->operation & UPDATE_REFRESH_RATE) {
layer.frame_rate = meta_data->refreshrate;
}
+
+ if (meta_data && meta_data->operation == PP_PARAM_INTERLACED && meta_data->interlaced) {
+ layer_buffer->flags.interlace = true;
+ }
+
+ if (pvt_handle->flags & private_handle_t::PRIV_FLAGS_SECURE_DISPLAY) {
+ layer_buffer->flags.secure_display = true;
+ }
}
SetRect(hwc_layer.displayFrame, &layer.dst_rect);
@@ -625,6 +633,7 @@
if (flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
switch (source) {
case HAL_PIXEL_FORMAT_RGBA_8888: format = kFormatRGBA8888Ubwc; break;
+ case HAL_PIXEL_FORMAT_RGBX_8888: format = kFormatRGBX8888Ubwc; break;
case HAL_PIXEL_FORMAT_RGB_565: format = kFormatRGB565Ubwc; break;
case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
@@ -755,6 +764,8 @@
return "INTERLACE";
case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
return "YCbCr_420_SP_VENUS";
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+ return "YCbCr_420_SP_VENUS_UBWC";
default:
return "Unknown pixel format";
}
diff --git a/libgralloc/adreno_utils.h b/libgralloc/adreno_utils.h
index 78f49da..31f9d52 100644
--- a/libgralloc/adreno_utils.h
+++ b/libgralloc/adreno_utils.h
@@ -26,7 +26,7 @@
typedef enum {
ADRENO_PIXELFORMAT_UNKNOWN = 0,
- ADRENO_PIXELFORMAT_R8G8B8A8 = 27,
+ ADRENO_PIXELFORMAT_R8G8B8A8 = 28,
ADRENO_PIXELFORMAT_R8G8B8A8_SRGB = 29,
ADRENO_PIXELFORMAT_B5G6R5 = 85,
ADRENO_PIXELFORMAT_B5G5R5A1 = 86,
@@ -37,6 +37,7 @@
ADRENO_PIXELFORMAT_YUY2 = 107,
ADRENO_PIXELFORMAT_B4G4R4A4 = 115,
ADRENO_PIXELFORMAT_NV12_EXT = 506, // NV12 with non-std alignment and offsets
+ ADRENO_PIXELFORMAT_R8G8B8X8 = 507, // GL_RGB8 (Internal)
ADRENO_PIXELFORMAT_R8G8B8 = 508, // GL_RGB8
ADRENO_PIXELFORMAT_A1B5G5R5 = 519, // GL_RGB5_A1
ADRENO_PIXELFORMAT_R8G8B8X8_SRGB = 520, // GL_SRGB8
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index 3e17061..e37cddd 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -49,17 +49,28 @@
#define ASTC_BLOCK_SIZE 16
-#ifdef ION_FLAG_CP_PIXEL
-#define CP_HEAP_ID ION_SECURE_HEAP_ID
-#else
+#ifndef ION_FLAG_CP_PIXEL
#define ION_FLAG_CP_PIXEL 0
-#define CP_HEAP_ID ION_CP_MM_HEAP_ID
#endif
#ifndef ION_FLAG_ALLOW_NON_CONTIG
#define ION_FLAG_ALLOW_NON_CONTIG 0
#endif
+#ifdef MASTER_SIDE_CP
+#define CP_HEAP_ID ION_SECURE_HEAP_ID
+/* Please Add the new SD ION Heap here */
+#define SD_HEAP_ID 0
+#define ION_CP_FLAGS (ION_SECURE | ION_FLAG_CP_PIXEL)
+/* Please Add the new SD ION Flag here */
+#define ION_SD_FLAGS ION_SECURE
+#else // SLAVE_SIDE_CP
+#define CP_HEAP_ID ION_CP_MM_HEAP_ID
+#define SD_HEAP_ID CP_HEAP_ID
+#define ION_CP_FLAGS (ION_SECURE | ION_FLAG_ALLOW_NON_CONTIG)
+#define ION_SD_FLAGS ION_SECURE
+#endif
+
using namespace gralloc;
using namespace qdutils;
@@ -108,6 +119,16 @@
*(void **)&LINK_adreno_isUBWCSupportedByGpu =
::dlsym(libadreno_utils, "isUBWCSupportedByGpu");
}
+
+ // Check if the overriding property debug.gralloc.gfx_ubwc_disable
+ // that disables UBWC allocations for the graphics stack is set
+ gfx_ubwc_disable = 0;
+ char property[PROPERTY_VALUE_MAX];
+ property_get("debug.gralloc.gfx_ubwc_disable", property, "0");
+ if(!(strncmp(property, "1", PROPERTY_VALUE_MAX)) ||
+ !(strncmp(property, "true", PROPERTY_VALUE_MAX))) {
+ gfx_ubwc_disable = 1;
+ }
}
AdrenoMemInfo::~AdrenoMemInfo()
@@ -282,7 +303,7 @@
int AdrenoMemInfo::isUBWCSupportedByGPU(int format)
{
- if (libadreno_utils) {
+ if (!gfx_ubwc_disable && libadreno_utils) {
if (LINK_adreno_isUBWCSupportedByGpu) {
ADRENOPIXELFORMAT gpu_format = getGpuPixelFormat(format);
return LINK_adreno_isUBWCSupportedByGpu(gpu_format);
@@ -296,6 +317,8 @@
switch (hal_format) {
case HAL_PIXEL_FORMAT_RGBA_8888:
return ADRENO_PIXELFORMAT_R8G8B8A8;
+ case HAL_PIXEL_FORMAT_RGBX_8888:
+ return ADRENO_PIXELFORMAT_R8G8B8X8;
case HAL_PIXEL_FORMAT_RGB_565:
return ADRENO_PIXELFORMAT_B5G6R5;
case HAL_PIXEL_FORMAT_sRGB_A_8888:
@@ -345,21 +368,16 @@
if(usage & GRALLOC_USAGE_PROTECTED) {
if (usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) {
- ionHeapId = ION_HEAP(CP_HEAP_ID);
- ionFlags |= ION_SECURE;
if (usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY) {
+ ionHeapId = ION_HEAP(SD_HEAP_ID);
/*
* There is currently no flag in ION for Secure Display
- * VM. Please add it here once available.
- *
- ionFlags |= <Ion flag for Secure Display>;
+ * VM. Please add it to the define once available.
*/
+ ionFlags |= ION_SD_FLAGS;
} else {
- ionFlags |= ION_FLAG_CP_PIXEL;
- }
-
- if (!(usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY)) {
- ionFlags |= ION_FLAG_ALLOW_NON_CONTIG;
+ ionHeapId = ION_HEAP(CP_HEAP_ID);
+ ionFlags |= ION_CP_FLAGS;
}
} else {
// for targets/OEMs which do not need HW level protection
@@ -787,6 +805,7 @@
{
case HAL_PIXEL_FORMAT_RGB_565:
case HAL_PIXEL_FORMAT_RGBA_8888:
+ case HAL_PIXEL_FORMAT_RGBX_8888:
case HAL_PIXEL_FORMAT_sRGB_A_8888:
case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
@@ -893,6 +912,7 @@
size += getUBwcMetaBufferSize(width, height, 2);
break;
case HAL_PIXEL_FORMAT_RGBA_8888:
+ case HAL_PIXEL_FORMAT_RGBX_8888:
case HAL_PIXEL_FORMAT_sRGB_A_8888:
size = alignedw * alignedh * 4;
size += getUBwcMetaBufferSize(width, height, 4);
@@ -908,3 +928,38 @@
}
return size;
}
+
+int getRgbDataAddress(private_handle_t* hnd, void* rgb_data)
+{
+ int err = 0;
+
+ // This api is for RGB* formats
+ if (hnd->format > HAL_PIXEL_FORMAT_sRGB_X_8888) {
+ return -EINVAL;
+ }
+
+ // linear buffer
+ if (!(hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED)) {
+ rgb_data = (void*)hnd->base;
+ return err;
+ }
+
+ unsigned int meta_size = 0;
+ switch (hnd->format) {
+ case HAL_PIXEL_FORMAT_RGB_565:
+ meta_size = getUBwcMetaBufferSize(hnd->width, hnd->height, 2);
+ break;
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ case HAL_PIXEL_FORMAT_RGBX_8888:
+ case HAL_PIXEL_FORMAT_sRGB_A_8888:
+ meta_size = getUBwcMetaBufferSize(hnd->width, hnd->height, 4);
+ break;
+ default:
+ ALOGE("%s:Unsupported RGB format: 0x%x", __FUNCTION__, hnd->format);
+ err = -EINVAL;
+ break;
+ }
+
+ rgb_data = (void*)(hnd->base + meta_size);
+ return err;
+}
diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp
index a6f7874..0fd6e3b 100644
--- a/libgralloc/gpu.cpp
+++ b/libgralloc/gpu.cpp
@@ -34,7 +34,7 @@
#define SZ_1M 0x100000
#define SZ_4K 0x1000
-#ifdef ION_FLAG_CP_PIXEL
+#ifdef MASTER_SIDE_CP
#define SECURE_ALIGN SZ_4K
#else
#define SECURE_ALIGN SZ_1M
@@ -155,8 +155,8 @@
flags |= private_handle_t::PRIV_FLAGS_TILE_RENDERED;
}
- if (AdrenoMemInfo::getInstance().isUBWCSupportedByGPU(format) &&
- isUBwcEnabled(format, usage)) {
+ if (isUBwcEnabled(format, usage) &&
+ AdrenoMemInfo::getInstance().isUBWCSupportedByGPU(format)) {
flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
}
@@ -308,6 +308,25 @@
grallocFormat = HAL_PIXEL_FORMAT_RGBA_8888;
}
+ bool useFbMem = false;
+ char property[PROPERTY_VALUE_MAX];
+ char isUBWC[PROPERTY_VALUE_MAX];
+ if (usage & GRALLOC_USAGE_HW_FB) {
+ if ((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
+ (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
+ (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
+ useFbMem = true;
+ } else {
+ if (property_get("debug.gralloc.enable_fb_ubwc", isUBWC, NULL) > 0){
+ if ((!strncmp(isUBWC, "1", PROPERTY_VALUE_MAX)) ||
+ (!strncasecmp(isUBWC, "true", PROPERTY_VALUE_MAX))) {
+ // Allocate UBWC aligned framebuffer
+ usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
+ }
+ }
+ }
+ }
+
getGrallocInformationFromFormat(grallocFormat, &bufferType);
size = getBufferSizeAndDimensions(w, h, grallocFormat, usage, alignedw,
alignedh);
@@ -316,15 +335,6 @@
return -EINVAL;
size = (bufferSize >= size)? bufferSize : size;
- bool useFbMem = false;
- char property[PROPERTY_VALUE_MAX];
- if((usage & GRALLOC_USAGE_HW_FB) &&
- (property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
- (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
- (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
- useFbMem = true;
- }
-
int err = 0;
if(useFbMem) {
err = gralloc_alloc_framebuffer(usage, pHandle);
diff --git a/libgralloc/gr.h b/libgralloc/gr.h
index 5ee0cf8..98b4eec 100644
--- a/libgralloc/gr.h
+++ b/libgralloc/gr.h
@@ -71,6 +71,7 @@
int alloc_buffer(private_handle_t **pHnd, int w, int h, int format, int usage);
void free_buffer(private_handle_t *hnd);
int getYUVPlaneInfo(private_handle_t* pHnd, struct android_ycbcr* ycbcr);
+int getRgbDataAddress(private_handle_t* pHnd, void* rgb_data);
// To query if UBWC is enabled, based on format and usage flags
bool isUBwcEnabled(int format, int usage);
@@ -148,6 +149,8 @@
ADRENOPIXELFORMAT getGpuPixelFormat(int hal_format);
private:
+ // Overriding flag to disable UBWC alloc for graphics stack
+ int gfx_ubwc_disable;
// Pointer to the padding library.
void *libadreno_utils;
diff --git a/libgralloc/gralloc_priv.h b/libgralloc/gralloc_priv.h
index 676c3bc..6998296 100755
--- a/libgralloc/gralloc_priv.h
+++ b/libgralloc/gralloc_priv.h
@@ -85,6 +85,7 @@
#define GRALLOC_MODULE_PERFORM_GET_YUV_PLANE_INFO 7
#define GRALLOC_MODULE_PERFORM_GET_MAP_SECURE_BUFFER_INFO 8
#define GRALLOC_MODULE_PERFORM_GET_UBWC_FLAG 9
+#define GRALLOC_MODULE_PERFORM_GET_RGB_DATA_ADDRESS 10
/* OEM specific HAL formats */
diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp
index bd2c735..7d4e8ce 100644
--- a/libgralloc/mapper.cpp
+++ b/libgralloc/mapper.cpp
@@ -442,6 +442,15 @@
res = 0;
} break;
+ case GRALLOC_MODULE_PERFORM_GET_RGB_DATA_ADDRESS:
+ {
+ private_handle_t* hnd = va_arg(args, private_handle_t*);
+ void* rgb_data = va_arg(args, void*);
+ if (!private_handle_t::validate(hnd)) {
+ res = getRgbDataAddress(hnd, rgb_data);
+ }
+ } break;
+
default:
break;
}
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index 1fa40ce..093b950 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -284,8 +284,9 @@
if (!ctx->mBootAnimCompleted)
processBootAnimCompleted(ctx);
- if (LIKELY(list && list->numHwLayers > 1) && ctx->dpyAttr[dpy].connected &&
- (ctx->dpyAttr[dpy].isActive ||
+ if (LIKELY(list && (list->numHwLayers > 1 ||
+ ctx->mMDP.version < qdutils::MDP_V4_0)) &&
+ ctx->dpyAttr[dpy].connected && (ctx->dpyAttr[dpy].isActive ||
ctx->mHDMIDisplay->isHDMIPrimaryDisplay())
&& !ctx->dpyAttr[dpy].isPause) {
diff --git a/libhwcomposer/hwc_copybit.cpp b/libhwcomposer/hwc_copybit.cpp
index 208fd3e..00bd643 100644
--- a/libhwcomposer/hwc_copybit.cpp
+++ b/libhwcomposer/hwc_copybit.cpp
@@ -562,17 +562,13 @@
mDirtyLayerIndex = checkDirtyRect(ctx, list, dpy);
ALOGD_IF (DEBUG_COPYBIT, "%s:Dirty Layer Index: %d",
__FUNCTION__, mDirtyLayerIndex);
- // repetitive frame will have mDirtyLayerIndex as NO_UPDATING_LAYER
- if (mDirtyLayerIndex == NO_UPDATING_LAYER) {
- ALOGD_IF (DEBUG_COPYBIT, "%s: No Updating Layers", __FUNCTION__);
- return true;
- }
hwc_rect_t clearRegion = {0,0,0,0};
mDirtyRect = list->hwLayers[last].displayFrame;
- if (CBUtils::getuiClearRegion(list, clearRegion, layerProp,
- mDirtyLayerIndex)) {
+ if (mDirtyLayerIndex != NO_UPDATING_LAYER &&
+ CBUtils::getuiClearRegion(list, clearRegion, layerProp,
+ mDirtyLayerIndex)) {
int clear_w = clearRegion.right - clearRegion.left;
int clear_h = clearRegion.bottom - clearRegion.top;
//mdp can't handle solid fill for one line
@@ -584,8 +580,13 @@
}else
clear(renderBuffer, clearRegion);
}
- if (mDirtyLayerIndex != -1)
- mDirtyRect = list->hwLayers[mDirtyLayerIndex].displayFrame;
+ if (mDirtyLayerIndex != -1) {
+ if (mDirtyLayerIndex == NO_UPDATING_LAYER) {
+ mDirtyRect = clearRegion;
+ } else {
+ mDirtyRect = list->hwLayers[mDirtyLayerIndex].displayFrame;
+ }
+ }
// numAppLayers-1, as we iterate from 0th layer index with HWC_COPYBIT flag
for (int i = 0; i <= (ctx->listStats[dpy].numAppLayers-1); i++) {
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 5bd7931..e2c4677 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -55,6 +55,7 @@
int (*MDPComp::sPerfLockAcquire)(int, int, int*, int) = NULL;
int (*MDPComp::sPerfLockRelease)(int value) = NULL;
int MDPComp::sPerfHintWindow = -1;
+float MDPComp::sDownscaleThreshold = 1.0;
enum AllocOrder { FORMAT_YUV, FORMAT_RGB, FORMAT_MAX };
@@ -212,6 +213,10 @@
}
}
+ if(property_get("persist.hwc.downscale_threshold", property, "1.0") > 0) {
+ sDownscaleThreshold = (float)atof(property);
+ }
+
return true;
}
@@ -430,6 +435,24 @@
//More conditions here, sRGB+Blend etc
return false;
}
+
+ //In targets with fewer pipes, frequent composition switch between MDP/GPU
+ //can happen for a layer due to lack of pipes. When this switch happens
+ //continuously for RGB downscaled layer with downscale greater than
+ //threshold, it appears as flicker as output
+ //of MDP and GPU are different as they use different filters for downscale.
+ //To avoid this flicker, punt RGB downscaled layer with downscale greater
+ //than threshold value to GPU always.
+ if((sDownscaleThreshold > 1.0)) {
+ if(((not isYuvBuffer(hnd))
+ and (not isDownscaleWithinThreshold(layer,
+ sDownscaleThreshold)))) {
+ ALOGD_IF(isDebug(), "%s: required downscale is greater than \
+ threshold %f", __FUNCTION__, sDownscaleThreshold);
+ return false;
+ }
+ }
+
return true;
}
diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index db68e82..5c43aa7 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -283,6 +283,7 @@
static int (*sPerfLockAcquire)(int, int, int*, int);
static int (*sPerfLockRelease)(int value);
static int sPerfHintWindow;
+ static float sDownscaleThreshold;
};
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index aeda428..79235ff 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -972,6 +972,27 @@
return false;
}
+
+bool isDownscaleWithinThreshold(hwc_layer_1_t const* layer, float threshold) {
+ hwc_rect_t displayFrame = layer->displayFrame;
+ hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
+ int dst_w, dst_h, src_w, src_h;
+ float downscale = 1.0;
+ dst_w = displayFrame.right - displayFrame.left;
+ dst_h = displayFrame.bottom - displayFrame.top;
+ src_w = sourceCrop.right - sourceCrop.left;
+ src_h = sourceCrop.bottom - sourceCrop.top;
+ if(dst_w && dst_h) {
+ float w_scale = ((float)src_w / (float)dst_w);
+ float h_scale = ((float)src_h / (float)dst_h);
+
+ if((w_scale > threshold) or (h_scale > threshold))
+ return false;
+ }
+
+ return true;
+}
+
bool needsScaling(hwc_layer_1_t const* layer) {
int dst_w, dst_h, src_w, src_h;
hwc_rect_t displayFrame = layer->displayFrame;
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index da0182b..4849baf 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -309,6 +309,7 @@
bool isAlphaScaled(hwc_layer_1_t const* layer);
bool needsScaling(hwc_layer_1_t const* layer);
bool isDownscaleRequired(hwc_layer_1_t const* layer);
+bool isDownscaleWithinThreshold(hwc_layer_1_t const* layer, float threshold);
bool needsScalingWithSplit(hwc_context_t* ctx, hwc_layer_1_t const* layer,
const int& dpy);
void sanitizeSourceCrop(hwc_rect_t& cropL, hwc_rect_t& cropR,
diff --git a/liboverlay/overlay.cpp b/liboverlay/overlay.cpp
index 113bd48..da24382 100644
--- a/liboverlay/overlay.cpp
+++ b/liboverlay/overlay.cpp
@@ -153,8 +153,6 @@
return getPipe_8x52(pipeSpecs);
} else if(MDPVersion::getInstance().is8994()) {
return getPipe_8994(pipeSpecs);
- } else if(MDPVersion::getInstance().is8992()) {
- return getPipe_8992(pipeSpecs);
}
eDest dest = OV_INVALID;
@@ -261,13 +259,6 @@
//supported since we at least need 1 round in between where the DMA is
//unused
eDest dest = OV_INVALID;
-
- // Reset format type to FORMAT_NONE to select the pipe irrespective of the
- // format specifed by the client. This is required for the device where
- // SMP starvation is unlikely, we need not keep track of formats
- // programmed in the pipes to avoid potential pipe crunching.
- resetPipeBookFormat(pipeSpecs.dpy);
-
if(pipeSpecs.formatClass == FORMAT_YUV) {
return nextPipe(OV_MDP_PIPE_VG, pipeSpecs);
} else {
@@ -279,14 +270,9 @@
dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs);
}
}
-
return dest;
}
-utils::eDest Overlay::getPipe_8992(const PipeSpecs& pipeSpecs) {
- return getPipe_8994(pipeSpecs);
-}
-
void Overlay::endAllSessions() {
for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
if(mPipeBook[i].valid() && mPipeBook[i].mSession==PipeBook::START)
diff --git a/liboverlay/overlay.h b/liboverlay/overlay.h
index 2782fc2..affb4db 100644
--- a/liboverlay/overlay.h
+++ b/liboverlay/overlay.h
@@ -179,9 +179,6 @@
utils::eDest getPipe_8x39(const PipeSpecs& pipeSpecs);
utils::eDest getPipe_8x52(const PipeSpecs& pipeSpecs);
utils::eDest getPipe_8994(const PipeSpecs& pipeSpecs);
- utils::eDest getPipe_8992(const PipeSpecs& pipeSpecs);
-
- void resetPipeBookFormat(const int &dpy);
/* Returns the handle to libscale.so's programScale function */
static int (*getFnProgramScale())(struct mdp_overlay_list *);
@@ -448,14 +445,6 @@
return "Invalid";
}
-inline void Overlay::resetPipeBookFormat(const int &dpy) {
- for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
- if (mPipeBook[i].mDisplay == dpy) {
- mPipeBook[i].mFormatType = FORMAT_NONE;
- }
- }
-}
-
}; // overlay
#endif // OVERLAY_H
diff --git a/liboverlay/overlayMdp.cpp b/liboverlay/overlayMdp.cpp
index 828f4fc..95bdc23 100644
--- a/liboverlay/overlayMdp.cpp
+++ b/liboverlay/overlayMdp.cpp
@@ -399,7 +399,7 @@
int errVal = mdp_wrapper::validateAndSet(fbFd, list);
if(errVal) {
/* No dump for failure due to insufficient resource */
- if(errVal != E2BIG) {
+ if(errVal != E2BIG && errVal != EBADSLT) {
//ENODEV is returned when the driver cannot satisfy a pipe request.
//This could happen if previous round's UNSET hasn't been commited
//yet, either because of a missed vsync or because of difference in