summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordianlujitao <dianlujitao@gmail.com>2016-09-29 12:07:11 +0800
committerdianlujitao <dianlujitao@gmail.com>2016-09-29 12:07:21 +0800
commit3906c6b9e26cb32e4561df4f09ee4b483d587f5a (patch)
tree82a608d13016cb271b145eef15eaae94d7280f9d
parentb2ef0dbddc90ea70d3240c2ddc25c93fc111204f (diff)
parent57aaa5e09827b47df67e08ec165173327a7e6ed8 (diff)
downloadhardware_qcom_display-3906c6b9e26cb32e4561df4f09ee4b483d587f5a.tar.gz
hardware_qcom_display-3906c6b9e26cb32e4561df4f09ee4b483d587f5a.tar.bz2
hardware_qcom_display-3906c6b9e26cb32e4561df4f09ee4b483d587f5a.zip
Merge tag 'LA.HB.1.3.2-27800-8x96.0' of https://source.codeaurora.org/quic/la/platform/hardware/qcom/display into HEAD
"LA.HB.1.3.2-27800-8x96.0" Change-Id: I1d8a78563eae62ca46ac66009d69e78976a93bee
-rw-r--r--libcopybit/copybit_c2d.cpp2
-rw-r--r--libgralloc/alloc_controller.cpp46
-rw-r--r--libgralloc/framebuffer.cpp5
-rw-r--r--libgralloc/gpu.cpp18
-rw-r--r--libgralloc/gr.h8
-rw-r--r--libgralloc/gralloc_priv.h13
-rw-r--r--libgralloc/mapper.cpp9
-rw-r--r--libqdutils/qdMetaData.cpp6
-rw-r--r--libqdutils/qdMetaData.h14
-rw-r--r--sdm/include/core/layer_buffer.h6
-rw-r--r--sdm/include/core/layer_stack.h19
-rw-r--r--sdm/include/private/hw_info_types.h1
-rw-r--r--sdm/include/utils/debug.h3
-rw-r--r--sdm/include/utils/rect.h2
-rw-r--r--sdm/libs/core/display_base.cpp28
-rw-r--r--sdm/libs/core/display_base.h2
-rw-r--r--sdm/libs/core/display_hdmi.cpp5
-rw-r--r--sdm/libs/core/fb/hw_device.cpp14
-rw-r--r--sdm/libs/core/fb/hw_device.h2
-rw-r--r--sdm/libs/core/fb/hw_hdmi.cpp24
-rw-r--r--sdm/libs/hwc/hwc_color_manager.cpp3
-rw-r--r--sdm/libs/hwc/hwc_display.cpp31
-rw-r--r--sdm/libs/hwc/hwc_display_virtual.cpp17
-rw-r--r--sdm/libs/utils/debug.cpp9
-rw-r--r--sdm/libs/utils/rect.cpp20
25 files changed, 260 insertions, 47 deletions
diff --git a/libcopybit/copybit_c2d.cpp b/libcopybit/copybit_c2d.cpp
index 240ba26c6..ffe5a0aca 100644
--- a/libcopybit/copybit_c2d.cpp
+++ b/libcopybit/copybit_c2d.cpp
@@ -1174,6 +1174,7 @@ static int stretch_copybit_internal(
bufferInfo dst_info;
populate_buffer_info(dst, dst_info);
private_handle_t* dst_hnd = new private_handle_t(-1, 0, 0, 0, dst_info.format,
+ dst_info.width, dst_info.height,
dst_info.width, dst_info.height);
if (dst_hnd == NULL) {
ALOGE("%s: dst_hnd is null", __FUNCTION__);
@@ -1254,6 +1255,7 @@ static int stretch_copybit_internal(
bufferInfo src_info;
populate_buffer_info(src, src_info);
private_handle_t* src_hnd = new private_handle_t(-1, 0, 0, 0, src_info.format,
+ src_info.width, src_info.height,
src_info.width, src_info.height);
if (NULL == src_hnd) {
ALOGE("%s: src_hnd is null", __FUNCTION__);
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index 39acf6624..4ca4e2d55 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -173,6 +173,17 @@ void AdrenoMemInfo::getAlignedWidthAndHeight(const private_handle_t *hnd, int& a
}
+void AdrenoMemInfo::getRealWidthAndHeight(const private_handle_t *hnd, int& real_w, int& real_h) {
+ MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
+ if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
+ real_w = metadata->bufferDim.sliceWidth;
+ real_h = metadata->bufferDim.sliceHeight;
+ } else {
+ real_w = hnd->real_width;
+ real_h = hnd->real_height;
+ }
+}
+
bool isUncompressedRgbFormat(int format)
{
bool is_rgb_format = false;
@@ -693,6 +704,16 @@ unsigned int getBufferSizeAndDimensions(int width, int height, int format,
return size;
}
+void getAlignedWidthAndHeight(int width, int height, int format,
+ int usage, int& alignedw, int &alignedh)
+{
+ AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
+ height,
+ format,
+ usage,
+ alignedw,
+ alignedh);
+}
void getBufferAttributes(int width, int height, int format, int usage,
int& alignedw, int &alignedh, int& tiled, unsigned int& size)
@@ -714,6 +735,8 @@ int getYUVPlaneInfo(private_handle_t* hnd, struct android_ycbcr* ycbcr)
int width = hnd->width;
int height = hnd->height;
int format = hnd->format;
+ int real_width = hnd->real_width;
+ int real_height = hnd->real_height;
unsigned int ystride, cstride;
unsigned int alignment = 4096;
@@ -734,8 +757,11 @@ int getYUVPlaneInfo(private_handle_t* hnd, struct android_ycbcr* ycbcr)
usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
}
- AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(metadata->bufferDim.sliceWidth,
- metadata->bufferDim.sliceHeight, format, usage, width, height);
+ real_width = metadata->bufferDim.sliceWidth;
+ real_height = metadata->bufferDim.sliceHeight;
+
+ AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(real_width, real_height,
+ format, usage, width, height);
}
// Get the chroma offsets from the handle width/height. We take advantage
@@ -762,16 +788,16 @@ int getYUVPlaneInfo(private_handle_t* hnd, struct android_ycbcr* ycbcr)
unsigned int y_stride, y_height, y_size;
unsigned int c_meta_stride, c_meta_height, c_meta_size;
- y_meta_stride = VENUS_Y_META_STRIDE(COLOR_FMT_NV12_UBWC, width);
- y_meta_height = VENUS_Y_META_SCANLINES(COLOR_FMT_NV12_UBWC, height);
+ y_meta_stride = VENUS_Y_META_STRIDE(COLOR_FMT_NV12_UBWC, real_width);
+ y_meta_height = VENUS_Y_META_SCANLINES(COLOR_FMT_NV12_UBWC, real_height);
y_meta_size = ALIGN((y_meta_stride * y_meta_height), alignment);
- y_stride = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, width);
- y_height = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, height);
+ y_stride = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, real_width);
+ y_height = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, real_height);
y_size = ALIGN((y_stride * y_height), alignment);
- c_meta_stride = VENUS_UV_META_STRIDE(COLOR_FMT_NV12_UBWC, width);
- c_meta_height = VENUS_UV_META_SCANLINES(COLOR_FMT_NV12_UBWC, height);
+ c_meta_stride = VENUS_UV_META_STRIDE(COLOR_FMT_NV12_UBWC, real_width);
+ c_meta_height = VENUS_UV_META_SCANLINES(COLOR_FMT_NV12_UBWC, real_height);
c_meta_size = ALIGN((c_meta_stride * c_meta_height), alignment);
ycbcr->y = (void*)(hnd->base + y_meta_size);
@@ -779,7 +805,7 @@ int getYUVPlaneInfo(private_handle_t* hnd, struct android_ycbcr* ycbcr)
ycbcr->cr = (void*)(hnd->base + y_meta_size + y_size +
c_meta_size + 1);
ycbcr->ystride = y_stride;
- ycbcr->cstride = VENUS_UV_STRIDE(COLOR_FMT_NV12_UBWC, width);
+ ycbcr->cstride = VENUS_UV_STRIDE(COLOR_FMT_NV12_UBWC, real_width);
ycbcr->chroma_step = 2;
break;
@@ -856,7 +882,7 @@ int alloc_buffer(private_handle_t **pHnd, int w, int h, int format, int usage)
private_handle_t* hnd = new private_handle_t(data.fd, data.size,
data.allocType, 0, format,
- alignedw, alignedh);
+ alignedw, alignedh, w, h);
hnd->base = (uint64_t) data.base;
hnd->offset = data.offset;
hnd->gpuaddr = 0;
diff --git a/libgralloc/framebuffer.cpp b/libgralloc/framebuffer.cpp
index 5c297c1f8..94a72a757 100644
--- a/libgralloc/framebuffer.cpp
+++ b/libgralloc/framebuffer.cpp
@@ -352,8 +352,9 @@ int mapFrameBufferLocked(framebuffer_device_t *dev)
// Create framebuffer handle using the ION fd
module->framebuffer = new private_handle_t(fd, fbSize,
private_handle_t::PRIV_FLAGS_USES_ION,
- BUFFER_TYPE_UI,
- module->fbFormat, info.xres, info.yres);
+ BUFFER_TYPE_UI, module->fbFormat,
+ info.xres, info.yres,
+ info.xres, info.yres);
module->framebuffer->base = uint64_t(vaddr);
memset(vaddr, 0, fbSize);
//Enable vsync
diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp
index 0eee65e53..4f29a7003 100644
--- a/libgralloc/gpu.cpp
+++ b/libgralloc/gpu.cpp
@@ -53,6 +53,16 @@ int gpu_context_t::gralloc_alloc_buffer(unsigned int size, int usage,
{
int err = 0;
int flags = 0;
+ int alignedw = 0;
+ int alignedh = 0;
+
+ AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
+ height,
+ format,
+ usage,
+ alignedw,
+ alignedh);
+
size = roundUpToPageSize(size);
alloc_data data;
data.offset = 0;
@@ -159,8 +169,8 @@ int gpu_context_t::gralloc_alloc_buffer(unsigned int size, int usage,
flags |= data.allocType;
uint64_t eBaseAddr = (uint64_t)(eData.base) + eData.offset;
private_handle_t *hnd = new private_handle_t(data.fd, size, flags,
- bufferType, format, width, height, eData.fd, eData.offset,
- eBaseAddr);
+ bufferType, format, alignedw, alignedh, width, height, eData.fd,
+ eData.offset, eBaseAddr);
hnd->offset = data.offset;
hnd->base = (uint64_t)(data.base) + data.offset;
@@ -228,7 +238,7 @@ int gpu_context_t::gralloc_alloc_framebuffer_locked(int usage,
private_handle_t::PRIV_FLAGS_USES_ION |
private_handle_t::PRIV_FLAGS_FRAMEBUFFER,
BUFFER_TYPE_UI, m->fbFormat, m->info.xres,
- m->info.yres);
+ m->info.yres, m->info.xres, m->info.yres);
// find a free slot
for (uint32_t i=0 ; i<numBuffers ; i++) {
@@ -328,7 +338,7 @@ int gpu_context_t::alloc_impl(int w, int h, int format, int usage,
err = gralloc_alloc_framebuffer(usage, pHandle);
} else {
err = gralloc_alloc_buffer(size, usage, pHandle, bufferType,
- grallocFormat, alignedw, alignedh);
+ grallocFormat, w, h);
}
if (err < 0) {
diff --git a/libgralloc/gr.h b/libgralloc/gr.h
index 1b8d9b4a5..d05055bfa 100644
--- a/libgralloc/gr.h
+++ b/libgralloc/gr.h
@@ -140,6 +140,14 @@ class AdrenoMemInfo : public android::Singleton <AdrenoMemInfo>
int tileEnabled, int& alignedw, int &alignedh);
/*
+ * Function to compute real width and real height based on
+ * private handle
+ *
+ * @return real width, real height
+ */
+ void getRealWidthAndHeight(const private_handle_t *hnd, int& real_w, int& real_h);
+
+ /*
* Function to return whether GPU support MacroTile feature
*
* @return >0 : supported
diff --git a/libgralloc/gralloc_priv.h b/libgralloc/gralloc_priv.h
index 7a5fc845a..4aa47541b 100644
--- a/libgralloc/gralloc_priv.h
+++ b/libgralloc/gralloc_priv.h
@@ -222,8 +222,10 @@ struct private_handle_t : public native_handle {
// The gpu address mapped into the mmu.
uint64_t gpuaddr __attribute__((aligned(8)));
int format;
- int width;
- int height;
+ int width; // specifies aligned width
+ int height; // specifies aligned height
+ int real_width;
+ int real_height;
uint64_t base_metadata __attribute__((aligned(8)));
#ifdef __cplusplus
@@ -235,13 +237,14 @@ struct private_handle_t : public native_handle {
static const int sMagic = 'gmsm';
private_handle_t(int fd, unsigned int size, int flags, int bufferType,
- int format, int width, int height, int eFd = -1,
+ int format, int aligned_width, int aligned_height,
+ int width, int height, int eFd = -1,
unsigned int eOffset = 0, uint64_t eBase = 0) :
fd(fd), fd_metadata(eFd), magic(sMagic),
flags(flags), size(size), offset(0), bufferType(bufferType),
base(0), offset_metadata(eOffset), gpuaddr(0),
- format(format), width(width), height(height),
- base_metadata(eBase)
+ format(format), width(aligned_width), height(aligned_height),
+ real_width(width), real_height(height), base_metadata(eBase)
{
version = (int) sizeof(native_handle);
numInts = sNumInts();
diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp
index 142586b83..549951bc3 100644
--- a/libgralloc/mapper.cpp
+++ b/libgralloc/mapper.cpp
@@ -309,6 +309,7 @@ int gralloc_perform(struct gralloc_module_t const* module,
int width = va_arg(args, int);
int height = va_arg(args, int);
int format = va_arg(args, int);
+ int alignedw = 0, alignedh = 0;
native_handle_t** handle = va_arg(args, native_handle_t**);
private_handle_t* hnd = (private_handle_t*)native_handle_create(
@@ -321,8 +322,12 @@ int gralloc_perform(struct gralloc_module_t const* module,
hnd->offset = offset;
hnd->base = uint64_t(base) + offset;
hnd->gpuaddr = 0;
- hnd->width = width;
- hnd->height = height;
+ AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
+ height, format, 0, alignedw, alignedh);
+ hnd->width = alignedw;
+ hnd->height = alignedh;
+ hnd->real_width = width;
+ hnd->real_height = height;
hnd->format = format;
*handle = (native_handle_t *)hnd;
res = 0;
diff --git a/libqdutils/qdMetaData.cpp b/libqdutils/qdMetaData.cpp
index 279a4d803..e51575a11 100644
--- a/libqdutils/qdMetaData.cpp
+++ b/libqdutils/qdMetaData.cpp
@@ -90,6 +90,9 @@ int setMetaData(private_handle_t *handle, DispParamType paramType,
case SET_S3D_RENDER:
data->s3dRender = *((S3DSFRender_t *)param);
break;
+ case SET_FRC_INFO:
+ data->frc = *((FrameRateControl_t *)param);
+ break;
default:
ALOGE("Unknown paramType %d", paramType);
break;
@@ -189,6 +192,9 @@ int getMetaData(private_handle_t *handle, DispFetchParamType paramType,
case GET_S3D_RENDER:
*((S3DSFRender_t *)param) = data->s3dRender;
break;
+ case GET_FRC_INFO:
+ *((FrameRateControl_t *)param) = data->frc;
+ break;
default:
ALOGE("Unknown paramType %d", paramType);
break;
diff --git a/libqdutils/qdMetaData.h b/libqdutils/qdMetaData.h
index 9a33eee8d..1d71b394e 100644
--- a/libqdutils/qdMetaData.h
+++ b/libqdutils/qdMetaData.h
@@ -63,6 +63,15 @@ struct S3DSFRender_t {
uint32_t GpuS3dFormat;
};
+struct FrameRateControl_t {
+ /* Deterministic Frame Rate Control (FRC) */
+ int32_t enable;
+ /* video frame count */
+ uint32_t counter;
+ /* video timestamp */
+ int64_t timestamp;
+};
+
struct MetaData_t {
int32_t operation;
int32_t interlaced;
@@ -87,10 +96,12 @@ struct MetaData_t {
uint32_t isSingleBufferMode;
/* Indicate GPU to help draw S3D layer on dedicate display device */
struct S3DSFRender_t s3dRender;
+ /* Video frame info used by FRC */
+ struct FrameRateControl_t frc;
};
enum DispParamType {
- UNUSED0 = 0x0001,
+ SET_FRC_INFO = 0x0001,
UNUSED1 = 0x0002,
PP_PARAM_INTERLACED = 0x0004,
UNUSED2 = 0x0008,
@@ -109,6 +120,7 @@ enum DispParamType {
};
enum DispFetchParamType {
+ GET_FRC_INFO = 0x0001,
GET_PP_PARAM_INTERLACED = 0x0004,
GET_BUFFER_GEOMETRY = 0x0080,
GET_REFRESH_RATE = 0x0100,
diff --git a/sdm/include/core/layer_buffer.h b/sdm/include/core/layer_buffer.h
index c437dab29..5ee441e4d 100644
--- a/sdm/include/core/layer_buffer.h
+++ b/sdm/include/core/layer_buffer.h
@@ -183,8 +183,10 @@ struct LayerBufferFlags {
@sa LayerStack
*/
struct LayerBuffer {
- uint32_t width = 0; //!< Actual width of the Layer that this buffer is for.
- uint32_t height = 0; //!< Actual height of the Layer that this buffer is for.
+ uint32_t width = 0; //!< Aligned width of the Layer that this buffer is for.
+ uint32_t height = 0; //!< Aligned height of the Layer that this buffer is for.
+ uint32_t real_width = 0; //!< Real width of the Layer that this buffer is for.
+ uint32_t real_height = 0; //!< Real height of the Layer that this buffer is for.
LayerBufferFormat format = kFormatRGBA8888; //!< Format of the buffer content.
LayerBufferPlane planes[4]; //!< Array of planes that this buffer contains. RGB buffer formats
//!< have 1 plane whereas YUV buffer formats may have upto 4 planes.
diff --git a/sdm/include/core/layer_stack.h b/sdm/include/core/layer_stack.h
index 2e3015f34..a73679506 100644
--- a/sdm/include/core/layer_stack.h
+++ b/sdm/include/core/layer_stack.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014 - 2015, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2016, 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:
@@ -230,6 +230,20 @@ struct LayerRectArray {
uint32_t count = 0; //!< Number of elements in the array.
};
+/*! @brief This structure defines FRC info of display layer.
+
+ @sa LayerFrcInfo
+*/
+
+struct LayerFrcInfo {
+ /* Deterministic Frame Rate Control (FRC) */
+ int32_t enable;
+ /* video frame count */
+ uint32_t frame_cnt;
+ /* video timestamp */
+ int64_t timestamp;
+};
+
/*! @brief This structure defines display layer object which contains layer properties and a drawing
buffer.
@@ -294,6 +308,9 @@ struct Layer {
LayerIGC igc = kIGCNotSpecified; //!< IGC that will be applied on this layer.
+ LayerFrcInfo frc_info; //!< FRC info which contains video frame count
+ //!< and timestamp of this layer.
+
uint32_t solid_fill_color = 0; //!< Solid color used to fill the layer when
//!< no content is associated with the layer.
diff --git a/sdm/include/private/hw_info_types.h b/sdm/include/private/hw_info_types.h
index ec1b6e57e..8b5d4df29 100644
--- a/sdm/include/private/hw_info_types.h
+++ b/sdm/include/private/hw_info_types.h
@@ -310,6 +310,7 @@ struct HWLayersInfo {
LayerRect right_partial_update; // Right ROI.
bool use_hw_cursor = false; // Indicates that HWCursor pipe needs to be used for cursor layer
+ LayerFrcInfo frc_info; // FRC info of this layer stack
};
struct HWLayers {
diff --git a/sdm/include/utils/debug.h b/sdm/include/utils/debug.h
index d34d282c3..50fdd717b 100644
--- a/sdm/include/utils/debug.h
+++ b/sdm/include/utils/debug.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014 - 2015, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2016, 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
@@ -73,6 +73,7 @@ class Debug {
static bool IsRotatorSplitDisabled();
static bool IsScalarDisabled();
static bool IsUbwcTiledFrameBuffer();
+ static bool IsFrcEnabled();
static bool GetProperty(const char *property_name, char *value);
static bool SetProperty(const char *property_name, const char *value);
diff --git a/sdm/include/utils/rect.h b/sdm/include/utils/rect.h
index c19864560..7153f2b47 100644
--- a/sdm/include/utils/rect.h
+++ b/sdm/include/utils/rect.h
@@ -49,6 +49,8 @@ namespace sdm {
bool flip_horizontal, LayerRect *out_rects);
void SplitTopBottom(const LayerRect &in_rect, uint32_t split_count, uint32_t align_y,
bool flip_horizontal, LayerRect *out_rects);
+ void MapRect(const LayerRect &src_domain, const LayerRect &dst_domain, const LayerRect &in_rect,
+ LayerRect *out_rect);
} // namespace sdm
#endif // __RECT_H__
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index 91cede7b0..a0bc0a2ff 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -160,6 +160,27 @@ DisplayError DisplayBase::ValidateGPUTarget(LayerStack *layer_stack) {
return kErrorNone;
}
+DisplayError DisplayBase::UpdateFrcInfo(LayerStack *layer_stack) {
+ Layer *layers = layer_stack->layers;
+ uint32_t layer_count = layer_stack->layer_count;
+ uint32_t frc_layer_index = 0;
+ uint32_t frc_layer_cnt = 0;
+
+ for (uint32_t i = 0; i < layer_count; i++) {
+ if (layers[i].frc_info.enable) {
+ frc_layer_index = i;
+ frc_layer_cnt++;
+ }
+ }
+
+ /* only single FRC layer can be supported */
+ if (frc_layer_cnt == 1) {
+ hw_layers_.info.frc_info = layers[frc_layer_index].frc_info;
+ }
+
+ return kErrorNone;
+}
+
DisplayError DisplayBase::Prepare(LayerStack *layer_stack) {
DisplayError error = kErrorNone;
bool disable_partial_update = false;
@@ -197,6 +218,13 @@ DisplayError DisplayBase::Prepare(LayerStack *layer_stack) {
hw_layers_.info.stack = layer_stack;
hw_layers_.output_compression = 1.0f;
+ if (frc_supported_) {
+ error = UpdateFrcInfo(layer_stack);
+ if (error != kErrorNone) {
+ return error;
+ }
+ }
+
comp_manager_->PrePrepare(display_comp_ctx_, &hw_layers_);
while (true) {
error = comp_manager_->Prepare(display_comp_ctx_, &hw_layers_);
diff --git a/sdm/libs/core/display_base.h b/sdm/libs/core/display_base.h
index 55e1713d7..20848d836 100644
--- a/sdm/libs/core/display_base.h
+++ b/sdm/libs/core/display_base.h
@@ -84,6 +84,7 @@ class DisplayBase : public DisplayInterface {
const char *GetName(const LayerComposition &composition);
const char *GetName(const LayerBufferFormat &format);
DisplayError ValidateGPUTarget(LayerStack *layer_stack);
+ DisplayError UpdateFrcInfo(LayerStack *layer_stack);
DisplayType display_type_;
DisplayEventHandler *event_handler_ = NULL;
@@ -103,6 +104,7 @@ class DisplayBase : public DisplayInterface {
bool pending_commit_ = false;
bool vsync_enable_ = false;
bool underscan_supported_ = false;
+ bool frc_supported_ = false;
uint32_t max_mixer_stages_ = 0;
HWInfoInterface *hw_info_intf_ = NULL;
ColorManagerProxy *color_mgr_ = NULL; // each display object owns its ColorManagerProxy
diff --git a/sdm/libs/core/display_hdmi.cpp b/sdm/libs/core/display_hdmi.cpp
index 0e9cbeb97..d37103bd2 100644
--- a/sdm/libs/core/display_hdmi.cpp
+++ b/sdm/libs/core/display_hdmi.cpp
@@ -87,6 +87,11 @@ DisplayError DisplayHDMI::Init() {
s3d_format_to_mode_.insert(std::pair<LayerBufferS3DFormat, HWS3DMode>
(kS3dFormatFramePacking, kS3DModeFP));
+ /* currently FRC is only supported by HDMI as primary devices */
+ if (Debug::IsFrcEnabled()) {
+ frc_supported_ = hw_panel_info_.is_primary_panel;
+ }
+
error = HWEventsInterface::Create(INT(display_type_), this, &event_list_, &hw_events_intf_);
if (error != kErrorNone) {
DisplayBase::Deinit();
diff --git a/sdm/libs/core/fb/hw_device.cpp b/sdm/libs/core/fb/hw_device.cpp
index 097ad8bfc..60bf27743 100644
--- a/sdm/libs/core/fb/hw_device.cpp
+++ b/sdm/libs/core/fb/hw_device.cpp
@@ -289,6 +289,8 @@ DisplayError HWDevice::Validate(HWLayers *hw_layers) {
DLOGI_IF(kTagDriverConfig, "*****************************************************************");
}
+ // set deterministic frame rate info per layer stack
+ SetFRC(hw_layers);
mdp_commit.flags |= MDP_VALIDATE_LAYER;
if (Sys::ioctl_(device_fd_, MSMFB_ATOMIC_COMMIT, &mdp_disp_commit_) < 0) {
if (errno == ESHUTDOWN) {
@@ -937,6 +939,7 @@ void HWDevice::ResetDisplayParams() {
memset(&scale_data_, 0, sizeof(scale_data_));
memset(&pp_params_, 0, sizeof(pp_params_));
memset(&igc_lut_data_, 0, sizeof(igc_lut_data_));
+ memset(&mdp_frc_info_, 0, sizeof(mdp_frc_info_));
for (uint32_t i = 0; i < kMaxSDELayers * 2; i++) {
mdp_in_layers_[i].buffer.fence = -1;
@@ -947,6 +950,7 @@ void HWDevice::ResetDisplayParams() {
mdp_disp_commit_.commit_v1.output_layer = &mdp_out_layer_;
mdp_disp_commit_.commit_v1.release_fence = -1;
mdp_disp_commit_.commit_v1.retire_fence = -1;
+ mdp_disp_commit_.commit_v1.frc_info = &mdp_frc_info_;
}
void HWDevice::SetHWScaleData(const ScaleData &scale, uint32_t index) {
@@ -1012,6 +1016,16 @@ void HWDevice::SetIGC(const Layer &layer, uint32_t index) {
mdp_layer.flags |= MDP_LAYER_PP;
}
+void HWDevice::SetFRC(HWLayers *hw_layers) {
+ LayerFrcInfo &frc_info = hw_layers->info.frc_info;
+
+ if (frc_info.enable) {
+ mdp_frc_info_.flags |= MDP_VIDEO_FRC_ENABLE;
+ mdp_frc_info_.frame_cnt = frc_info.frame_cnt;
+ mdp_frc_info_.timestamp = frc_info.timestamp;
+ }
+}
+
DisplayError HWDevice::SetCursorPosition(HWLayers *hw_layers, int x, int y) {
DTRACE_SCOPED();
diff --git a/sdm/libs/core/fb/hw_device.h b/sdm/libs/core/fb/hw_device.h
index 6d9c5af4c..2cb4d431b 100644
--- a/sdm/libs/core/fb/hw_device.h
+++ b/sdm/libs/core/fb/hw_device.h
@@ -112,6 +112,7 @@ class HWDevice : public HWInterface {
void ResetDisplayParams();
void SetCSC(LayerCSC source, mdp_color_space *color_space);
void SetIGC(const Layer &layer, uint32_t index);
+ void SetFRC(HWLayers *hw_layers);
bool EnableHotPlugDetection(int enable);
ssize_t SysFsWrite(const char* file_node, const char* value, ssize_t length);
@@ -133,6 +134,7 @@ class HWDevice : public HWInterface {
mdp_output_layer mdp_out_layer_;
const char *device_name_;
bool synchronous_commit_;
+ mdp_frc_info mdp_frc_info_;
};
} // namespace sdm
diff --git a/sdm/libs/core/fb/hw_hdmi.cpp b/sdm/libs/core/fb/hw_hdmi.cpp
index 6fb727197..3c176077c 100644
--- a/sdm/libs/core/fb/hw_hdmi.cpp
+++ b/sdm/libs/core/fb/hw_hdmi.cpp
@@ -75,6 +75,16 @@ static bool MapHDMIDisplayTiming(const msm_hdmi_mode_timing_info *mode,
info->grayscale = V4L2_PIX_FMT_NV12;
}
+ if (!mode->active_low_h)
+ info->sync |= FB_SYNC_HOR_HIGH_ACT;
+ else
+ info->sync &= ~FB_SYNC_HOR_HIGH_ACT;
+
+ if (!mode->active_low_v)
+ info->sync |= FB_SYNC_VERT_HIGH_ACT;
+ else
+ info->sync &= ~FB_SYNC_VERT_HIGH_ACT;
+
return true;
}
@@ -733,8 +743,7 @@ DisplayError HWHDMI::GetDynamicFrameRateMode(uint32_t refresh_rate, uint32_t *mo
for (i = 0; i < hdmi_mode_count_; i++) {
msm_hdmi_mode_timing_info *timing_mode = &supported_video_modes_[i];
if (cur->active_h == timing_mode->active_h &&
- cur->active_v == timing_mode->active_v &&
- cur->pixel_formats == timing_mode->pixel_formats ) {
+ cur->active_v == timing_mode->active_v) {
int cur_refresh_rate_diff = static_cast<int>(timing_mode->refresh_rate) -
static_cast<int>(refresh_rate);
if (abs(pre_refresh_rate_diff) > abs(cur_refresh_rate_diff)) {
@@ -750,6 +759,12 @@ DisplayError HWHDMI::GetDynamicFrameRateMode(uint32_t refresh_rate, uint32_t *mo
GetConfigIndex(dst->video_format, config_index);
+ // When there is a change in pixel format set the mode using FBIOPUT_VSCREENINFO info ioctl.
+ if (cur->pixel_formats != dst->pixel_formats) {
+ *mode = kModeSuspendResume;
+ return kErrorNone;
+ }
+
data->hor_front_porch = dst->front_porch_h;
data->hor_back_porch = dst->back_porch_h;
data->hor_pulse_width = dst->pulse_width_h;
@@ -796,6 +811,11 @@ DisplayError HWHDMI::SetRefreshRate(uint32_t refresh_rate) {
return error;
}
+ if (mode == kModeSuspendResume) {
+ SetDisplayAttributes(config_index);
+ return kErrorNone;
+ }
+
snprintf(mode_path, sizeof(mode_path), "%s%d/msm_fb_dfps_mode", fb_path_, fb_node_index_);
snprintf(node_path, sizeof(node_path), "%s%d/dynamic_fps", fb_path_, fb_node_index_);
diff --git a/sdm/libs/hwc/hwc_color_manager.cpp b/sdm/libs/hwc/hwc_color_manager.cpp
index 5abe94a42..844c2b873 100644
--- a/sdm/libs/hwc/hwc_color_manager.cpp
+++ b/sdm/libs/hwc/hwc_color_manager.cpp
@@ -259,7 +259,8 @@ int HWCColorManager::CreateSolidFillLayers(HWCDisplay *hwc_display) {
// handle for solid fill layer with fd = -1.
private_handle_t *handle =
new private_handle_t(-1, 0, private_handle_t::PRIV_FLAGS_FRAMEBUFFER, BUFFER_TYPE_UI,
- HAL_PIXEL_FORMAT_RGBA_8888, primary_width, primary_height);
+ HAL_PIXEL_FORMAT_RGBA_8888, primary_width, primary_height,
+ primary_width, primary_height);
if (!buf || !handle) {
DLOGE("Failed to allocate memory.");
diff --git a/sdm/libs/hwc/hwc_display.cpp b/sdm/libs/hwc/hwc_display.cpp
index afae70dcf..270e8f393 100644
--- a/sdm/libs/hwc/hwc_display.cpp
+++ b/sdm/libs/hwc/hwc_display.cpp
@@ -414,8 +414,17 @@ int HWCDisplay::PrepareLayerParams(hwc_layer_1_t *hwc_layer, Layer *layer) {
if (pvt_handle) {
layer_buffer->format = GetSDMFormat(pvt_handle->format, pvt_handle->flags);
- layer_buffer->width = pvt_handle->width;
- layer_buffer->height = pvt_handle->height;
+ int aligned_width, aligned_height;
+ int real_width, real_height;
+
+ AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(pvt_handle, aligned_width,
+ aligned_height);
+ AdrenoMemInfo::getInstance().getRealWidthAndHeight(pvt_handle, real_width, real_height);
+
+ layer_buffer->width = aligned_width;
+ layer_buffer->height = aligned_height;
+ layer_buffer->real_width = real_width;
+ layer_buffer->real_height = real_height;
if (SetMetaData(pvt_handle, layer) != kErrorNone) {
return -EINVAL;
@@ -466,6 +475,8 @@ int HWCDisplay::PrepareLayerParams(hwc_layer_1_t *hwc_layer, Layer *layer) {
usage, aligned_width, aligned_height);
layer_buffer->width = aligned_width;
layer_buffer->height = aligned_height;
+ layer_buffer->real_width = x_pixels;
+ layer_buffer->real_height = y_pixels;
layer_buffer->format = GetSDMFormat(format, flags);
}
}
@@ -569,6 +580,8 @@ int HWCDisplay::PrePrepareLayerStack(hwc_display_contents_1_t *content_list) {
LayerBuffer *input_buffer = layer.input_buffer;
input_buffer->width = layer.dst_rect.right - layer.dst_rect.left;
input_buffer->height = layer.dst_rect.bottom - layer.dst_rect.top;
+ input_buffer->real_width = input_buffer->width;
+ input_buffer->real_height = input_buffer->height;
layer.src_rect.left = 0;
layer.src_rect.top = 0;
layer.src_rect.right = input_buffer->width;
@@ -1362,14 +1375,6 @@ DisplayError HWCDisplay::SetMetaData(const private_handle_t *pvt_handle, Layer *
layer_buffer->format = GetSDMFormat(meta_data->linearFormat, 0);
}
- if (meta_data->operation & UPDATE_BUFFER_GEOMETRY) {
- int actual_width = pvt_handle->width;
- int actual_height = pvt_handle->height;
- AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(pvt_handle, actual_width, actual_height);
- layer_buffer->width = actual_width;
- layer_buffer->height = actual_height;
- }
-
if (meta_data->operation & SET_SINGLE_BUFFER_MODE) {
layer->flags.single_buffer = meta_data->isSingleBufferMode;
// Graphics can set this operation on all types of layers including FB and set the actual value
@@ -1387,6 +1392,12 @@ DisplayError HWCDisplay::SetMetaData(const private_handle_t *pvt_handle, Layer *
}
}
+ if (meta_data->operation & SET_FRC_INFO) {
+ layer->frc_info.enable = meta_data->frc.enable;
+ layer->frc_info.frame_cnt = meta_data->frc.counter;
+ layer->frc_info.timestamp = meta_data->frc.timestamp;
+ }
+
return kErrorNone;
}
diff --git a/sdm/libs/hwc/hwc_display_virtual.cpp b/sdm/libs/hwc/hwc_display_virtual.cpp
index 47d78f257..712f02421 100644
--- a/sdm/libs/hwc/hwc_display_virtual.cpp
+++ b/sdm/libs/hwc/hwc_display_virtual.cpp
@@ -269,12 +269,19 @@ int HWCDisplayVirtual::SetOutputBuffer(hwc_display_contents_1_t *content_list) {
return -EINVAL;
}
- int output_buffer_width, output_buffer_height;
- AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(output_handle, output_buffer_width,
- output_buffer_height);
+ int aligned_width, aligned_height;
+ int real_width, real_height;
+
+ AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(output_handle, aligned_width,
+ aligned_height);
+ AdrenoMemInfo::getInstance().getRealWidthAndHeight(output_handle, real_width, real_height);
+
+ output_buffer_->width = aligned_width;
+ output_buffer_->height = aligned_height;
+
+ output_buffer_->real_width = real_width;
+ output_buffer_->real_height = real_height;
- output_buffer_->width = output_buffer_width;
- output_buffer_->height = output_buffer_height;
output_buffer_->flags.secure = 0;
output_buffer_->flags.video = 0;
diff --git a/sdm/libs/utils/debug.cpp b/sdm/libs/utils/debug.cpp
index 9e128ba75..4691b08dd 100644
--- a/sdm/libs/utils/debug.cpp
+++ b/sdm/libs/utils/debug.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014 - 2015, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2016, 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
@@ -127,6 +127,13 @@ bool Debug::IsScalarDisabled() {
return (value == 1);
}
+bool Debug::IsFrcEnabled() {
+ int value = 0;
+ debug_.debug_handler_->GetProperty("sdm.debug.enable_frc", &value);
+
+ return (value == 1);
+}
+
bool Debug::IsUbwcTiledFrameBuffer() {
int ubwc_disabled = 0;
int ubwc_framebuffer = 0;
diff --git a/sdm/libs/utils/rect.cpp b/sdm/libs/utils/rect.cpp
index e756464e6..5392aaa4b 100644
--- a/sdm/libs/utils/rect.cpp
+++ b/sdm/libs/utils/rect.cpp
@@ -198,5 +198,25 @@ void SplitTopBottom(const LayerRect &in_rect, uint32_t split_count, uint32_t ali
}
}
+void MapRect(const LayerRect &src_domain, const LayerRect &dst_domain, const LayerRect &in_rect,
+ LayerRect *out_rect) {
+ if (!IsValid(src_domain) || !IsValid(dst_domain) || !IsValid(in_rect)) {
+ return;
+ }
+
+ float src_domain_width = src_domain.right - src_domain.left;
+ float src_domain_height = src_domain.bottom - src_domain.top;
+ float dst_domain_width = dst_domain.right - dst_domain.left;
+ float dst_domain_height = dst_domain.bottom - dst_domain.top;
+
+ float width_ratio = dst_domain_width / src_domain_width;
+ float height_ratio = dst_domain_height / src_domain_height;
+
+ out_rect->left = dst_domain.left + (width_ratio * in_rect.left);
+ out_rect->top = dst_domain.top + (height_ratio * in_rect.top);
+ out_rect->right = dst_domain.left + (width_ratio * in_rect.right);
+ out_rect->bottom = dst_domain.top + (height_ratio * in_rect.bottom);
+}
+
} // namespace sdm