diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp index 87d4c1e9..42416e84 100644 --- a/libgralloc/alloc_controller.cpp +++ b/libgralloc/alloc_controller.cpp @@ -27,6 +27,9 @@ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#ifdef COMPILE_DRM +#include +#endif #include #include #include @@ -73,6 +76,12 @@ #define ION_SC_PREVIEW_FLAGS ION_SECURE #endif +#ifdef COMPILE_DRM +#ifndef DRM_FORMAT_MOD_QCOM_COMPRESSED +#define DRM_FORMAT_MOD_QCOM_COMPRESSED fourcc_mod_code(QCOM, 1) +#endif +#endif + using namespace gralloc; using namespace qdutils; using namespace android; @@ -1098,3 +1107,195 @@ int getRgbDataAddress(private_handle_t* hnd, void** rgb_data) *rgb_data = (void*)(hnd->base + meta_size); return err; } + +#ifdef COMPILE_DRM +int getPlaneStrideOffset(private_handle_t *hnd, uint32_t *stride, + uint32_t *offset, uint32_t *num_planes) { + if (!hnd || !stride || !offset || !num_planes) { + return -EINVAL; + } + + struct android_ycbcr yuvInfo = {}; + *num_planes = 1; + stride[0] = 0; + + switch (hnd->format) { + case HAL_PIXEL_FORMAT_RGB_565: + case HAL_PIXEL_FORMAT_BGR_565: + case HAL_PIXEL_FORMAT_RGBA_5551: + case HAL_PIXEL_FORMAT_RGBA_4444: + stride[0] = hnd->width * 2; + break; + case HAL_PIXEL_FORMAT_RGB_888: + stride[0] = hnd->width * 3; + break; + case HAL_PIXEL_FORMAT_RGBA_8888: + case HAL_PIXEL_FORMAT_BGRA_8888: + case HAL_PIXEL_FORMAT_RGBX_8888: + case HAL_PIXEL_FORMAT_BGRX_8888: + case HAL_PIXEL_FORMAT_RGBA_1010102: + case HAL_PIXEL_FORMAT_ARGB_2101010: + case HAL_PIXEL_FORMAT_RGBX_1010102: + case HAL_PIXEL_FORMAT_XRGB_2101010: + case HAL_PIXEL_FORMAT_BGRA_1010102: + case HAL_PIXEL_FORMAT_ABGR_2101010: + case HAL_PIXEL_FORMAT_BGRX_1010102: + case HAL_PIXEL_FORMAT_XBGR_2101010: + stride[0] = hnd->width * 4; + break; + } + + // Format is RGB + if (stride[0]) { + return 0; + } + + (*num_planes)++; + int ret = getYUVPlaneInfo(hnd, &yuvInfo); + if (ret < 0) { + ALOGE("%s failed", __FUNCTION__); + return ret; + } + + stride[0] = static_cast(yuvInfo.ystride); + offset[0] = static_cast( + reinterpret_cast(yuvInfo.y) - hnd->base); + stride[1] = static_cast(yuvInfo.cstride); + switch (hnd->format) { + case HAL_PIXEL_FORMAT_YCbCr_420_SP: + case HAL_PIXEL_FORMAT_YCbCr_422_SP: + case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: + case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: + case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: + case HAL_PIXEL_FORMAT_YCbCr_420_P010: + case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: + offset[1] = static_cast( + reinterpret_cast(yuvInfo.cb) - hnd->base); + break; + case HAL_PIXEL_FORMAT_YCrCb_420_SP: + case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS: + case HAL_PIXEL_FORMAT_YCrCb_422_SP: + offset[1] = static_cast( + reinterpret_cast(yuvInfo.cr) - hnd->base); + break; + case HAL_PIXEL_FORMAT_YV12: + offset[1] = static_cast( + reinterpret_cast(yuvInfo.cr) - hnd->base); + stride[2] = static_cast(yuvInfo.cstride); + offset[2] = static_cast( + reinterpret_cast(yuvInfo.cb) - hnd->base); + (*num_planes)++; + break; + default: + ALOGW("%s: Unsupported format %s", __FUNCTION__, + qdutils::GetHALPixelFormatString(hnd->format)); + ret = -EINVAL; + } + + if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) { + std::fill(offset, offset + 4, 0); + } + + return 0; +} + +void getDRMFormat(int hal_format, int flags, uint32_t *drm_format, + uint64_t *drm_format_modifier) { + + if (flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) { + *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED; + } + + switch (hal_format) { + case HAL_PIXEL_FORMAT_RGBA_8888: + *drm_format = DRM_FORMAT_RGBA8888; + break; + case HAL_PIXEL_FORMAT_RGBA_5551: + *drm_format = DRM_FORMAT_RGBA5551; + break; + case HAL_PIXEL_FORMAT_RGBA_4444: + *drm_format = DRM_FORMAT_RGBA4444; + break; + case HAL_PIXEL_FORMAT_BGRA_8888: + *drm_format = DRM_FORMAT_BGRA8888; + break; + case HAL_PIXEL_FORMAT_RGBX_8888: + *drm_format = DRM_FORMAT_RGBX8888; + break; + case HAL_PIXEL_FORMAT_BGRX_8888: + *drm_format = DRM_FORMAT_BGRX8888; + break; + case HAL_PIXEL_FORMAT_RGB_888: + *drm_format = DRM_FORMAT_RGB888; + break; + case HAL_PIXEL_FORMAT_RGB_565: + *drm_format = DRM_FORMAT_RGB565; + break; + case HAL_PIXEL_FORMAT_BGR_565: + *drm_format = DRM_FORMAT_BGR565; + break; + case HAL_PIXEL_FORMAT_RGBA_1010102: + *drm_format = DRM_FORMAT_RGBA1010102; + break; + case HAL_PIXEL_FORMAT_ARGB_2101010: + *drm_format = DRM_FORMAT_ARGB2101010; + break; + case HAL_PIXEL_FORMAT_RGBX_1010102: + *drm_format = DRM_FORMAT_RGBX1010102; + break; + case HAL_PIXEL_FORMAT_XRGB_2101010: + *drm_format = DRM_FORMAT_XRGB2101010; + break; + case HAL_PIXEL_FORMAT_BGRA_1010102: + *drm_format = DRM_FORMAT_BGRA1010102; + break; + case HAL_PIXEL_FORMAT_ABGR_2101010: + *drm_format = DRM_FORMAT_ABGR2101010; + break; + case HAL_PIXEL_FORMAT_BGRX_1010102: + *drm_format = DRM_FORMAT_BGRX1010102; + break; + case HAL_PIXEL_FORMAT_XBGR_2101010: + *drm_format = DRM_FORMAT_XBGR2101010; + break; + case HAL_PIXEL_FORMAT_YCbCr_420_SP: + *drm_format = DRM_FORMAT_NV12; + break; + case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: + case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: + *drm_format = DRM_FORMAT_NV12; + break; + case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: + *drm_format = DRM_FORMAT_NV12; + *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED; + break; + case HAL_PIXEL_FORMAT_YCrCb_420_SP: + *drm_format = DRM_FORMAT_NV21; + break; + case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS: + *drm_format = DRM_FORMAT_NV21; + break; + case HAL_PIXEL_FORMAT_YCbCr_420_P010: + // TODO *drm_format = DRM_FORMAT_P010; + break; + case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: + // TODO *drm_format = DRM_FORMAT_P010; + // *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED | + // DRM_FORMAT_MOD_QCOM_TIGHT; + break; + case HAL_PIXEL_FORMAT_YCbCr_422_SP: + *drm_format = DRM_FORMAT_NV16; + break; + case HAL_PIXEL_FORMAT_YCrCb_422_SP: + *drm_format = DRM_FORMAT_NV61; + break; + case HAL_PIXEL_FORMAT_YV12: + *drm_format = DRM_FORMAT_YVU420; + break; + default: + ALOGW("%s: Unsupported format %s", __FUNCTION__, + qdutils::GetHALPixelFormatString(hal_format)); + } +} +#endif + diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp index 848c741e..641712c8 100644 --- a/libgralloc/gpu.cpp +++ b/libgralloc/gpu.cpp @@ -22,7 +22,6 @@ #include #include #ifdef COMPILE_DRM -#include #include #endif #include @@ -36,200 +35,11 @@ #include "alloc_controller.h" #ifdef COMPILE_DRM -#ifndef DRM_FORMAT_MOD_QCOM_COMPRESSED -#define DRM_FORMAT_MOD_QCOM_COMPRESSED fourcc_mod_code(QCOM, 1) -#endif +using namespace drm_utils; #endif using namespace gralloc; -#ifdef COMPILE_DRM -using namespace drm_utils; - -static int getPlaneStrideOffset(private_handle_t *hnd, uint32_t *stride, - uint32_t *offset, uint32_t *num_planes) { - struct android_ycbcr yuvInfo = {}; - *num_planes = 1; - - switch (hnd->format) { - case HAL_PIXEL_FORMAT_RGB_565: - case HAL_PIXEL_FORMAT_BGR_565: - case HAL_PIXEL_FORMAT_RGBA_5551: - case HAL_PIXEL_FORMAT_RGBA_4444: - stride[0] = hnd->width * 2; - break; - case HAL_PIXEL_FORMAT_RGB_888: - stride[0] = hnd->width * 3; - break; - case HAL_PIXEL_FORMAT_RGBA_8888: - case HAL_PIXEL_FORMAT_BGRA_8888: - case HAL_PIXEL_FORMAT_RGBX_8888: - case HAL_PIXEL_FORMAT_BGRX_8888: - case HAL_PIXEL_FORMAT_RGBA_1010102: - case HAL_PIXEL_FORMAT_ARGB_2101010: - case HAL_PIXEL_FORMAT_RGBX_1010102: - case HAL_PIXEL_FORMAT_XRGB_2101010: - case HAL_PIXEL_FORMAT_BGRA_1010102: - case HAL_PIXEL_FORMAT_ABGR_2101010: - case HAL_PIXEL_FORMAT_BGRX_1010102: - case HAL_PIXEL_FORMAT_XBGR_2101010: - stride[0] = hnd->width * 4; - break; - } - - // Format is RGB - if (stride[0]) { - return 0; - } - - (*num_planes)++; - int ret = getYUVPlaneInfo(hnd, &yuvInfo); - if (ret < 0) { - ALOGE("%s failed", __FUNCTION__); - return ret; - } - - stride[0] = static_cast(yuvInfo.ystride); - offset[0] = static_cast( - reinterpret_cast(yuvInfo.y) - hnd->base); - stride[1] = static_cast(yuvInfo.cstride); - switch (hnd->format) { - case HAL_PIXEL_FORMAT_YCbCr_420_SP: - case HAL_PIXEL_FORMAT_YCbCr_422_SP: - case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: - case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: - case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: - case HAL_PIXEL_FORMAT_YCbCr_420_P010: - case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: - offset[1] = static_cast( - reinterpret_cast(yuvInfo.cb) - hnd->base); - break; - case HAL_PIXEL_FORMAT_YCrCb_420_SP: - case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS: - case HAL_PIXEL_FORMAT_YCrCb_422_SP: - offset[1] = static_cast( - reinterpret_cast(yuvInfo.cr) - hnd->base); - break; - case HAL_PIXEL_FORMAT_YV12: - offset[1] = static_cast( - reinterpret_cast(yuvInfo.cr) - hnd->base); - stride[2] = static_cast(yuvInfo.cstride); - offset[2] = static_cast( - reinterpret_cast(yuvInfo.cb) - hnd->base); - (*num_planes)++; - break; - default: - ALOGW("%s: Unsupported format %s", __FUNCTION__, - qdutils::GetHALPixelFormatString(hnd->format)); - } - - if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) { - std::fill(offset, offset + 4, 0); - } - - return 0; -} - -static void getDRMFormat(int hal_format, int flags, uint32_t *drm_format, - uint64_t *drm_format_modifier) { - - if (flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) { - *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED; - } - - switch (hal_format) { - case HAL_PIXEL_FORMAT_RGBA_8888: - *drm_format = DRM_FORMAT_RGBA8888; - break; - case HAL_PIXEL_FORMAT_RGBA_5551: - *drm_format = DRM_FORMAT_RGBA5551; - break; - case HAL_PIXEL_FORMAT_RGBA_4444: - *drm_format = DRM_FORMAT_RGBA4444; - break; - case HAL_PIXEL_FORMAT_BGRA_8888: - *drm_format = DRM_FORMAT_BGRA8888; - break; - case HAL_PIXEL_FORMAT_RGBX_8888: - *drm_format = DRM_FORMAT_RGBX8888; - break; - case HAL_PIXEL_FORMAT_BGRX_8888: - *drm_format = DRM_FORMAT_BGRX8888; - break; - case HAL_PIXEL_FORMAT_RGB_888: - *drm_format = DRM_FORMAT_RGB888; - break; - case HAL_PIXEL_FORMAT_RGB_565: - *drm_format = DRM_FORMAT_RGB565; - break; - case HAL_PIXEL_FORMAT_BGR_565: - *drm_format = DRM_FORMAT_BGR565; - break; - case HAL_PIXEL_FORMAT_RGBA_1010102: - *drm_format = DRM_FORMAT_RGBA1010102; - break; - case HAL_PIXEL_FORMAT_ARGB_2101010: - *drm_format = DRM_FORMAT_ARGB2101010; - break; - case HAL_PIXEL_FORMAT_RGBX_1010102: - *drm_format = DRM_FORMAT_RGBX1010102; - break; - case HAL_PIXEL_FORMAT_XRGB_2101010: - *drm_format = DRM_FORMAT_XRGB2101010; - break; - case HAL_PIXEL_FORMAT_BGRA_1010102: - *drm_format = DRM_FORMAT_BGRA1010102; - break; - case HAL_PIXEL_FORMAT_ABGR_2101010: - *drm_format = DRM_FORMAT_ABGR2101010; - break; - case HAL_PIXEL_FORMAT_BGRX_1010102: - *drm_format = DRM_FORMAT_BGRX1010102; - break; - case HAL_PIXEL_FORMAT_XBGR_2101010: - *drm_format = DRM_FORMAT_XBGR2101010; - break; - case HAL_PIXEL_FORMAT_YCbCr_420_SP: - *drm_format = DRM_FORMAT_NV12; - break; - case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: - case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: - *drm_format = DRM_FORMAT_NV12; - break; - case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: - *drm_format = DRM_FORMAT_NV12; - *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED; - break; - case HAL_PIXEL_FORMAT_YCrCb_420_SP: - *drm_format = DRM_FORMAT_NV21; - break; - case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS: - *drm_format = DRM_FORMAT_NV21; - break; - case HAL_PIXEL_FORMAT_YCbCr_420_P010: - // TODO *drm_format = DRM_FORMAT_P010; - break; - case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: - // TODO *drm_format = DRM_FORMAT_P010; - // *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED | - // DRM_FORMAT_MOD_QCOM_TIGHT; - break; - case HAL_PIXEL_FORMAT_YCbCr_422_SP: - *drm_format = DRM_FORMAT_NV16; - break; - case HAL_PIXEL_FORMAT_YCrCb_422_SP: - *drm_format = DRM_FORMAT_NV61; - break; - case HAL_PIXEL_FORMAT_YV12: - *drm_format = DRM_FORMAT_YVU420; - break; - default: - ALOGW("%s: Unsupported format %s", __FUNCTION__, - qdutils::GetHALPixelFormatString(hal_format)); - } -} -#endif - gpu_context_t::gpu_context_t(const private_module_t* module, IAllocController* alloc_ctrl ) : mAllocCtrl(alloc_ctrl) diff --git a/libgralloc/gr.h b/libgralloc/gr.h index ae26df9a..edeca3f6 100644 --- a/libgralloc/gr.h +++ b/libgralloc/gr.h @@ -71,6 +71,13 @@ bool isUBwcEnabled(int format, int usage); // Function to check if the format is an RGB format bool isUncompressedRgbFormat(int format); +#ifdef COMPILE_DRM +int getPlaneStrideOffset(private_handle_t *hnd, uint32_t *stride, + uint32_t *offset, uint32_t *num_planes); + +void getDRMFormat(int hal_format, int flags, uint32_t *drm_format, + uint64_t *drm_format_modifier); +#endif /*****************************************************************************/ class Locker { diff --git a/sdm/include/core/buffer_allocator.h b/sdm/include/core/buffer_allocator.h index 4dc41254..3d805ae2 100644 --- a/sdm/include/core/buffer_allocator.h +++ b/sdm/include/core/buffer_allocator.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2015 - 2016, The Linux Foundation. All rights reserved. +* Copyright (c) 2015 - 2017, 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 @@ -68,6 +68,8 @@ struct AllocatedBufferInfo { uint32_t aligned_width = 0; //!< Specifies aligned allocated buffer width in pixels. uint32_t aligned_height = 0; //!< Specifies aligned allocated buffer height in pixels. uint32_t size = 0; //!< Specifies the size of the allocated buffer. + uint32_t fb_id = 0; // Registered id with the DRM driver + uint32_t gem_handle = 0; // GEM driver handle for correspoding import of ION buffer }; /*! @brief Holds the information about the input/output configuration of an output buffer. diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp index a72aae7b..a33738d1 100644 --- a/sdm/libs/core/drm/hw_device_drm.cpp +++ b/sdm/libs/core/drm/hw_device_drm.cpp @@ -368,9 +368,11 @@ void HWDeviceDRM::SetupAtomic(HWLayers *hw_layers, bool validate) { for (uint32_t i = 0; i < hw_layer_count; i++) { Layer &layer = hw_layer_info.hw_layers.at(i); - LayerBuffer &input_buffer = layer.input_buffer; + LayerBuffer *input_buffer = &layer.input_buffer; 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 needs_rotation = false; // TODO(user): Add support for solid fill if (layer.flags.solid_fill) { @@ -379,9 +381,16 @@ void HWDeviceDRM::SetupAtomic(HWLayers *hw_layers, bool validate) { for (uint32_t count = 0; count < 2; count++) { HWPipeInfo *pipe_info = (count == 0) ? left_pipe : right_pipe; + HWRotateInfo *hw_rotate_info = &hw_rotator_session->hw_rotate_info[count]; + + if (hw_rotate_info->valid) { + input_buffer = &hw_rotator_session->output_buffer; + needs_rotation = true; + } + if (pipe_info->valid) { uint32_t pipe_id = pipe_info->pipe_id; - if (input_buffer.fb_id == 0) { + if (input_buffer->fb_id == 0) { // We set these to 0 to clear any previous cycle's state from another buffer. // Unfortunately this layer will be skipped from validation because it's dimensions are // tied to fb_id which is not available yet. @@ -400,24 +409,28 @@ void HWDeviceDRM::SetupAtomic(HWLayers *hw_layers, bool validate) { DRMRect dst = {}; SetRect(pipe_info->dst_roi, &dst); drm_atomic_intf_->Perform(DRMOps::PLANE_SET_DST_RECT, pipe_id, dst); + uint32_t rot_bit_mask = 0; - if (layer.transform.flip_horizontal) { - rot_bit_mask |= 1 << DRM_REFLECT_X; - } - if (layer.transform.flip_vertical) { - rot_bit_mask |= 1 << DRM_REFLECT_Y; + // In case of rotation, rotator handles flips + if (!needs_rotation) { + if (layer.transform.flip_horizontal) { + rot_bit_mask |= 1 << DRM_REFLECT_X; + } + if (layer.transform.flip_vertical) { + rot_bit_mask |= 1 << DRM_REFLECT_Y; + } } + drm_atomic_intf_->Perform(DRMOps::PLANE_SET_ROTATION, pipe_id, rot_bit_mask); drm_atomic_intf_->Perform(DRMOps::PLANE_SET_H_DECIMATION, pipe_id, pipe_info->horizontal_decimation); drm_atomic_intf_->Perform(DRMOps::PLANE_SET_V_DECIMATION, pipe_id, pipe_info->vertical_decimation); - drm_atomic_intf_->Perform(DRMOps::PLANE_SET_ROTATION, pipe_id, rot_bit_mask); - drm_atomic_intf_->Perform(DRMOps::PLANE_SET_FB_ID, pipe_id, input_buffer.fb_id); + drm_atomic_intf_->Perform(DRMOps::PLANE_SET_FB_ID, pipe_id, input_buffer->fb_id); drm_atomic_intf_->Perform(DRMOps::PLANE_SET_CRTC, pipe_id, token_.crtc_id); - if (!validate && input_buffer.acquire_fence_fd >= 0) { + if (!validate && input_buffer->acquire_fence_fd >= 0) { drm_atomic_intf_->Perform(DRMOps::PLANE_SET_INPUT_FENCE, pipe_id, - input_buffer.acquire_fence_fd); + input_buffer->acquire_fence_fd); } } } @@ -518,8 +531,14 @@ DisplayError HWDeviceDRM::AtomicCommit(HWLayers *hw_layers) { LayerStack *stack = hw_layer_info.stack; stack->retire_fence_fd = retire_fence; - for (Layer &layer : hw_layer_info.hw_layers) { - layer.input_buffer.release_fence_fd = Sys::dup_(release_fence); + for (uint32_t i = 0; i < hw_layer_info.hw_layers.size(); i++) { + Layer &layer = hw_layer_info.hw_layers.at(i); + HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session; + if (hw_rotator_session->hw_block_count) { + hw_rotator_session->output_buffer.release_fence_fd = Sys::dup_(release_fence); + } else { + layer.input_buffer.release_fence_fd = Sys::dup_(release_fence); + } } hw_layer_info.sync_handle = release_fence; diff --git a/sdm/libs/core/drm/hw_info_drm.cpp b/sdm/libs/core/drm/hw_info_drm.cpp index 4bcd791b..d41206f8 100644 --- a/sdm/libs/core/drm/hw_info_drm.cpp +++ b/sdm/libs/core/drm/hw_info_drm.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -342,6 +343,93 @@ void HWInfoDRM::GetWBInfo(HWResourceInfo *hw_resource) { drm_mgr_intf_->UnregisterDisplay(token); } +void HWInfoDRM::GetSDMFormat(uint32_t v4l2_format, LayerBufferFormat *sdm_format) { + switch (v4l2_format) { + case SDE_PIX_FMT_ARGB_8888: *sdm_format = kFormatARGB8888; break; + case SDE_PIX_FMT_RGBA_8888: *sdm_format = kFormatRGBA8888; break; + case SDE_PIX_FMT_BGRA_8888: *sdm_format = kFormatBGRA8888; break; + case SDE_PIX_FMT_RGBX_8888: *sdm_format = kFormatRGBX8888; break; + case SDE_PIX_FMT_BGRX_8888: *sdm_format = kFormatBGRX8888; break; + case SDE_PIX_FMT_RGBA_5551: *sdm_format = kFormatRGBA5551; break; + case SDE_PIX_FMT_RGBA_4444: *sdm_format = kFormatRGBA4444; break; + case SDE_PIX_FMT_RGB_888: *sdm_format = kFormatRGB888; break; + case SDE_PIX_FMT_BGR_888: *sdm_format = kFormatBGR888; break; + case SDE_PIX_FMT_RGB_565: *sdm_format = kFormatRGB565; break; + case SDE_PIX_FMT_BGR_565: *sdm_format = kFormatBGR565; break; + case SDE_PIX_FMT_Y_CB_CR_H2V2: *sdm_format = kFormatYCbCr420Planar; break; + case SDE_PIX_FMT_Y_CR_CB_H2V2: *sdm_format = kFormatYCrCb420Planar; break; + case SDE_PIX_FMT_Y_CR_CB_GH2V2: *sdm_format = kFormatYCrCb420PlanarStride16; break; + case SDE_PIX_FMT_Y_CBCR_H2V2: *sdm_format = kFormatYCbCr420SemiPlanar; break; + case SDE_PIX_FMT_Y_CRCB_H2V2: *sdm_format = kFormatYCrCb420SemiPlanar; break; + case SDE_PIX_FMT_Y_CBCR_H1V2: *sdm_format = kFormatYCbCr422H1V2SemiPlanar; break; + case SDE_PIX_FMT_Y_CRCB_H1V2: *sdm_format = kFormatYCrCb422H1V2SemiPlanar; break; + case SDE_PIX_FMT_Y_CBCR_H2V1: *sdm_format = kFormatYCbCr422H2V1SemiPlanar; break; + case SDE_PIX_FMT_Y_CRCB_H2V1: *sdm_format = kFormatYCrCb422H2V1SemiPlanar; break; + case SDE_PIX_FMT_YCBYCR_H2V1: *sdm_format = kFormatYCbCr422H2V1Packed; break; + case SDE_PIX_FMT_Y_CBCR_H2V2_VENUS: *sdm_format = kFormatYCbCr420SemiPlanarVenus; break; + case SDE_PIX_FMT_Y_CRCB_H2V2_VENUS: *sdm_format = kFormatYCrCb420SemiPlanarVenus; break; + case SDE_PIX_FMT_RGBA_8888_UBWC: *sdm_format = kFormatRGBA8888Ubwc; break; + case SDE_PIX_FMT_RGBX_8888_UBWC: *sdm_format = kFormatRGBX8888Ubwc; break; + case SDE_PIX_FMT_RGB_565_UBWC: *sdm_format = kFormatBGR565Ubwc; break; + case SDE_PIX_FMT_Y_CBCR_H2V2_UBWC: *sdm_format = kFormatYCbCr420SPVenusUbwc; break; + case SDE_PIX_FMT_RGBA_1010102: *sdm_format = kFormatRGBA1010102; break; + case SDE_PIX_FMT_ARGB_2101010: *sdm_format = kFormatARGB2101010; break; + case SDE_PIX_FMT_RGBX_1010102: *sdm_format = kFormatRGBX1010102; break; + case SDE_PIX_FMT_XRGB_2101010: *sdm_format = kFormatXRGB2101010; break; + case SDE_PIX_FMT_BGRA_1010102: *sdm_format = kFormatBGRA1010102; break; + case SDE_PIX_FMT_ABGR_2101010: *sdm_format = kFormatABGR2101010; break; + case SDE_PIX_FMT_BGRX_1010102: *sdm_format = kFormatBGRX1010102; break; + case SDE_PIX_FMT_XBGR_2101010: *sdm_format = kFormatXBGR2101010; break; + case SDE_PIX_FMT_RGBA_1010102_UBWC: *sdm_format = kFormatRGBA1010102Ubwc; break; + case SDE_PIX_FMT_RGBX_1010102_UBWC: *sdm_format = kFormatRGBX1010102Ubwc; break; + case SDE_PIX_FMT_Y_CBCR_H2V2_P010: *sdm_format = kFormatYCbCr420P010; break; + case SDE_PIX_FMT_Y_CBCR_H2V2_TP10_UBWC: *sdm_format = kFormatYCbCr420TP10Ubwc; break; + default: *sdm_format = kFormatInvalid; + } +} + +void HWInfoDRM::GetRotatorFormatsForType(int fd, uint32_t type, + vector *supported_formats) { + int ret = 0; + struct v4l2_fmtdesc fmtdesc = {}; + fmtdesc.type = type; + while (!ret) { + ret = Sys::ioctl_(fd, static_cast(VIDIOC_ENUM_FMT), &fmtdesc); + if (!ret) { + LayerBufferFormat sdm_format = kFormatInvalid; + GetSDMFormat(fmtdesc.pixelformat, &sdm_format); + if (sdm_format != kFormatInvalid) { + supported_formats->push_back(sdm_format); + } + } + fmtdesc.index++; + } +} + +DisplayError HWInfoDRM::GetRotatorSupportedFormats(uint32_t v4l2_index, + HWResourceInfo *hw_resource) { + string path = "/dev/video" + to_string(v4l2_index); + int fd = Sys::open_(path.c_str(), O_RDONLY); + if (fd < 0) { + DLOGE("Failed to open %s with error %d", path.c_str(), errno); + return kErrorNotSupported; + } + + vector supported_formats = {}; + GetRotatorFormatsForType(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT, &supported_formats); + hw_resource->supported_formats_map.erase(kHWRotatorInput); + hw_resource->supported_formats_map.insert(make_pair(kHWRotatorInput, supported_formats)); + + supported_formats = {}; + GetRotatorFormatsForType(fd, V4L2_BUF_TYPE_VIDEO_CAPTURE, &supported_formats); + hw_resource->supported_formats_map.erase(kHWRotatorOutput); + hw_resource->supported_formats_map.insert(make_pair(kHWRotatorOutput, supported_formats)); + + Sys::close_(fd); + + return kErrorNone; +} + DisplayError HWInfoDRM::GetHWRotatorInfo(HWResourceInfo *hw_resource) { const uint32_t kMaxV4L2Nodes = 64; bool found = false; @@ -361,6 +449,7 @@ DisplayError HWInfoDRM::GetHWRotatorInfo(HWResourceInfo *hw_resource) { hw_resource->hw_rot_info.has_downscale = true; // We support only 1 rotator found = true; + GetRotatorSupportedFormats(i, hw_resource); } } diff --git a/sdm/libs/core/drm/hw_info_drm.h b/sdm/libs/core/drm/hw_info_drm.h index 9c9a0e00..b955e637 100644 --- a/sdm/libs/core/drm/hw_info_drm.h +++ b/sdm/libs/core/drm/hw_info_drm.h @@ -56,6 +56,10 @@ class HWInfoDRM: public HWInfoInterface { DisplayError GetDynamicBWLimits(HWResourceInfo *hw_resource); void GetSDMFormat(uint32_t drm_format, uint64_t drm_format_modifier, std::vector *sdm_formats); + void GetSDMFormat(uint32_t v4l2_format, LayerBufferFormat *sdm_format); + void GetRotatorFormatsForType(int fd, uint32_t type, + std::vector *supported_formats); + DisplayError GetRotatorSupportedFormats(uint32_t v4l2_index, HWResourceInfo *hw_resource); sde_drm::DRMManagerInterface *drm_mgr_intf_ = {}; bool default_mode_ = false; diff --git a/sdm/libs/hwc/Android.mk b/sdm/libs/hwc/Android.mk index c39e1f90..9c78cd33 100644 --- a/sdm/libs/hwc/Android.mk +++ b/sdm/libs/hwc/Android.mk @@ -15,7 +15,8 @@ LOCAL_CLANG := true LOCAL_SHARED_LIBRARIES := libsdmcore libqservice libbinder libhardware libhardware_legacy \ libutils libcutils libsync libmemalloc libqdutils libdl \ - libpowermanager libsdmutils libgpu_tonemapper libc++ liblog + libpowermanager libsdmutils libgpu_tonemapper libc++ liblog \ + libdrmutils LOCAL_SRC_FILES := hwc_session.cpp \ hwc_display.cpp \ diff --git a/sdm/libs/hwc/hwc_buffer_allocator.cpp b/sdm/libs/hwc/hwc_buffer_allocator.cpp index 7e32d65b..8e5c5bdc 100644 --- a/sdm/libs/hwc/hwc_buffer_allocator.cpp +++ b/sdm/libs/hwc/hwc_buffer_allocator.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2015 - 2016, The Linux Foundation. All rights reserved. +* Copyright (c) 2015 - 2017, 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 @@ -34,12 +34,17 @@ #include #include #include +#include +#include #include "hwc_debugger.h" #include "hwc_buffer_allocator.h" #define __CLASS__ "HWCBufferAllocator" +using drm_utils::DRMMaster; +using drm_utils::DRMBuffer; + namespace sdm { HWCBufferAllocator::HWCBufferAllocator() { @@ -118,12 +123,54 @@ DisplayError HWCBufferAllocator::AllocateBuffer(BufferInfo *buffer_info) { buffer_info->private_data = meta_buffer_info; + if (qdutils::getDriverType() == qdutils::DriverType::DRM) { + private_handle_t handle(-1, 0, 0, 0, 0, 0, 0); + // Setup only the required stuff, skip rest + handle.base = reinterpret_cast(data.base); + handle.format = format; + handle.width = aligned_width; + handle.height = aligned_height; + if (alloc_flags & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) { + handle.flags = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED; + } + private_handle_t *hnd = &handle; + DRMBuffer buf = {}; + int ret = getPlaneStrideOffset(hnd, buf.stride, buf.offset, + &buf.num_planes); + if (ret < 0) { + DLOGE("getPlaneStrideOffset failed"); + return kErrorParameters; + } + + buf.fd = data.fd; + buf.width = UINT32(hnd->width); + buf.height = UINT32(hnd->height); + getDRMFormat(hnd->format, hnd->flags, &buf.drm_format, + &buf.drm_format_modifier); + + DRMMaster *master = nullptr; + ret = DRMMaster::GetInstance(&master); + if (ret < 0) { + DLOGE("Failed to acquire DRMMaster instance"); + return kErrorParameters; + } + + ret = master->CreateFbId(buf, &alloc_buffer_info->gem_handle, &alloc_buffer_info->fb_id); + if (ret < 0) { + DLOGE("CreateFbId failed. width %d, height %d, " \ + "format: %s, stride %u, error %d", + buf.width, buf.height, + qdutils::GetHALPixelFormatString(hnd->format), + buf.stride[0], errno); + return kErrorParameters; + } + } + return kErrorNone; } DisplayError HWCBufferAllocator::FreeBuffer(BufferInfo *buffer_info) { int ret = 0; - AllocatedBufferInfo *alloc_buffer_info = &buffer_info->alloc_buffer_info; // Deallocate the buffer, only if the buffer fd is valid. @@ -154,6 +201,25 @@ DisplayError HWCBufferAllocator::FreeBuffer(BufferInfo *buffer_info) { delete meta_buffer_info; meta_buffer_info = NULL; + + if (alloc_buffer_info->fb_id) { + DRMMaster *master = nullptr; + int ret = DRMMaster::GetInstance(&master); + if (ret < 0) { + DLOGE("Failed to acquire DRMMaster instance"); + return kErrorParameters; + } + + ret = master->RemoveFbId(alloc_buffer_info->gem_handle, alloc_buffer_info->fb_id); + if (ret < 0) { + DLOGE("Removing fb_id %d failed with error %d", + alloc_buffer_info->fb_id, errno); + return kErrorParameters; + } + + alloc_buffer_info->fb_id = 0; + alloc_buffer_info->gem_handle = 0; + } } return kErrorNone; @@ -215,7 +281,10 @@ int HWCBufferAllocator::SetBufferInfo(LayerBufferFormat format, int *target, int case kFormatYCbCr422H2V1SemiPlanar: *target = HAL_PIXEL_FORMAT_YCbCr_422_SP; break; case kFormatYCbCr420SemiPlanarVenus: *target = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS; break; case kFormatYCrCb420SemiPlanarVenus: *target = HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS; break; - case kFormatYCbCr420SPVenusUbwc: *target = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC; break; + case kFormatYCbCr420SPVenusUbwc: + *target = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC; + *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC; + break; case kFormatRGBA5551: *target = HAL_PIXEL_FORMAT_RGBA_5551; break; case kFormatRGBA4444: *target = HAL_PIXEL_FORMAT_RGBA_4444; break; case kFormatRGBA1010102: *target = HAL_PIXEL_FORMAT_RGBA_1010102; break; @@ -227,7 +296,10 @@ int HWCBufferAllocator::SetBufferInfo(LayerBufferFormat format, int *target, int case kFormatBGRX1010102: *target = HAL_PIXEL_FORMAT_BGRX_1010102; break; case kFormatXBGR2101010: *target = HAL_PIXEL_FORMAT_XBGR_2101010; break; case kFormatYCbCr420P010: *target = HAL_PIXEL_FORMAT_YCbCr_420_P010; break; - case kFormatYCbCr420TP10Ubwc: *target = HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC; break; + case kFormatYCbCr420TP10Ubwc: + *target = HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC; + *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC; + break; case kFormatRGBA8888Ubwc: *target = HAL_PIXEL_FORMAT_RGBA_8888; *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;