diff options
author | dianlujitao <dianlujitao@gmail.com> | 2016-09-29 12:07:11 +0800 |
---|---|---|
committer | dianlujitao <dianlujitao@gmail.com> | 2016-09-29 12:07:21 +0800 |
commit | 3906c6b9e26cb32e4561df4f09ee4b483d587f5a (patch) | |
tree | 82a608d13016cb271b145eef15eaae94d7280f9d | |
parent | b2ef0dbddc90ea70d3240c2ddc25c93fc111204f (diff) | |
parent | 57aaa5e09827b47df67e08ec165173327a7e6ed8 (diff) | |
download | hardware_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.cpp | 2 | ||||
-rw-r--r-- | libgralloc/alloc_controller.cpp | 46 | ||||
-rw-r--r-- | libgralloc/framebuffer.cpp | 5 | ||||
-rw-r--r-- | libgralloc/gpu.cpp | 18 | ||||
-rw-r--r-- | libgralloc/gr.h | 8 | ||||
-rw-r--r-- | libgralloc/gralloc_priv.h | 13 | ||||
-rw-r--r-- | libgralloc/mapper.cpp | 9 | ||||
-rw-r--r-- | libqdutils/qdMetaData.cpp | 6 | ||||
-rw-r--r-- | libqdutils/qdMetaData.h | 14 | ||||
-rw-r--r-- | sdm/include/core/layer_buffer.h | 6 | ||||
-rw-r--r-- | sdm/include/core/layer_stack.h | 19 | ||||
-rw-r--r-- | sdm/include/private/hw_info_types.h | 1 | ||||
-rw-r--r-- | sdm/include/utils/debug.h | 3 | ||||
-rw-r--r-- | sdm/include/utils/rect.h | 2 | ||||
-rw-r--r-- | sdm/libs/core/display_base.cpp | 28 | ||||
-rw-r--r-- | sdm/libs/core/display_base.h | 2 | ||||
-rw-r--r-- | sdm/libs/core/display_hdmi.cpp | 5 | ||||
-rw-r--r-- | sdm/libs/core/fb/hw_device.cpp | 14 | ||||
-rw-r--r-- | sdm/libs/core/fb/hw_device.h | 2 | ||||
-rw-r--r-- | sdm/libs/core/fb/hw_hdmi.cpp | 24 | ||||
-rw-r--r-- | sdm/libs/hwc/hwc_color_manager.cpp | 3 | ||||
-rw-r--r-- | sdm/libs/hwc/hwc_display.cpp | 31 | ||||
-rw-r--r-- | sdm/libs/hwc/hwc_display_virtual.cpp | 17 | ||||
-rw-r--r-- | sdm/libs/utils/debug.cpp | 9 | ||||
-rw-r--r-- | sdm/libs/utils/rect.cpp | 20 |
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 |