blob: 14a9e345563a95a219ee2d94e0737b5f3fb998b0 [file] [log] [blame]
/*
* Copyright (C) 2020 Samsung Electronics Co. Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "ExynosGraphicBufferMali"
#include <ExynosGraphicBufferMali.h>
#include <drmutils.h>
#include <exynos_format.h>
#include <hidl_common/SharedMetadata.h>
#include <log/log.h>
#define HIDL_COMMON_VERSION_SCALED 120
#include <mali_gralloc_usages.h>
using namespace vendor::graphics;
using arm::mapper::common::get_crop_rect;
typedef aidl::android::hardware::graphics::common::Rect aidlRect;
#define convert_handle(gralloc_hnd, buffer_handle, retval) \
const private_handle_t *gralloc_hnd = static_cast<const private_handle_t *>(buffer_handle); \
if (!gralloc_hnd) \
return retval;
int ExynosGraphicBufferMali::get_num_planes(const buffer_handle_t hnd) {
convert_handle(gralloc_hnd, hnd, -EINVAL);
switch (gralloc_hnd->get_alloc_format()) {
case HAL_PIXEL_FORMAT_EXYNOS_YV12_M:
case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P:
case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M:
return 3;
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED:
case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M:
case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL:
case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M:
case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN:
case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B:
case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B:
case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M:
case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC:
case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC:
case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC:
case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC:
case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC:
case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC:
case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50:
case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75:
case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50:
case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75:
case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40:
case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60:
case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80:
case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40:
case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60:
case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80:
return 2;
}
return gralloc_hnd->is_multi_plane() ? (gralloc_hnd->plane_info[2].offset == 0 ? 2 : 3) : 1;
}
uint32_t ExynosGraphicBufferMali::get_offsetInBytes(buffer_handle_t hnd, int plane_num) {
return ExynosGraphicBufferMeta::get_plane_offset(hnd, plane_num);
}
uint32_t ExynosGraphicBufferMali::get_strideInBytes(buffer_handle_t hnd, int plane_num) {
convert_handle(gralloc_hnd, hnd, -EINVAL);
return gralloc_hnd->plane_info[plane_num].byte_stride;
}
uint32_t ExynosGraphicBufferMali::get_widthInSamples(buffer_handle_t hnd, int plane_num) {
convert_handle(gralloc_hnd, hnd, -EINVAL);
return gralloc_hnd->plane_info[plane_num].alloc_width;
}
uint32_t ExynosGraphicBufferMali::get_heightInSamples(buffer_handle_t hnd, int plane_num) {
convert_handle(gralloc_hnd, hnd, -EINVAL);
return gralloc_hnd->plane_info[plane_num].alloc_height;
}
uint32_t ExynosGraphicBufferMali::get_pixel_format_fourcc(buffer_handle_t hnd) {
convert_handle(gralloc_hnd, hnd, -EINVAL);
return drm_fourcc_from_handle(gralloc_hnd);
}
uint64_t ExynosGraphicBufferMali::get_pixel_format_modifier(buffer_handle_t hnd) {
convert_handle(gralloc_hnd, hnd, -EINVAL);
return drm_modifier_from_handle(gralloc_hnd);
}
std::vector<ExynosGraphicBufferMali::Rect> ExynosGraphicBufferMali::get_crop_rects(buffer_handle_t hnd) {
convert_handle(handle, hnd, {});
const int num_planes = get_num_planes(hnd);
std::vector<ExynosGraphicBufferMali::Rect> crops(num_planes);
for (size_t plane_index = 0; plane_index < num_planes; ++plane_index) {
/* Set the default crop rectangle. Android mandates that it must fit [0, 0, widthInSamples, heightInSamples]
* We always require using the requested width and height for the crop rectangle size.
* For planes > 0 the size might need to be scaled, but since we only use plane[0] for crop set it to the
* Android default of [0, 0, widthInSamples, heightInSamples] for other planes.
*/
aidl::android::hardware::graphics::common::Rect rect = {
.top = 0,
.left = 0,
.right = static_cast<int32_t>(handle->plane_info[plane_index].alloc_width),
.bottom = static_cast<int32_t>(handle->plane_info[plane_index].alloc_height)};
if (plane_index == 0) {
std::optional<aidlRect> crop_rect;
get_crop_rect(handle, &crop_rect);
if (crop_rect.has_value()) {
rect = crop_rect.value();
} else {
rect = {.top = 0, .left = 0, .right = handle->width, .bottom = handle->height};
}
}
crops[plane_index].top = rect.top;
crops[plane_index].left = rect.left;
crops[plane_index].right = rect.right;
crops[plane_index].bottom = rect.bottom;
}
return crops;
}
uint64_t ExynosGraphicBufferMali::get_total_alloc_size(buffer_handle_t hnd) {
convert_handle(gralloc_hnd, hnd, -EINVAL);
uint64_t total_size = 0;
for (int fidx = 0; fidx < gralloc_hnd->fd_count; fidx++) {
total_size += gralloc_hnd->alloc_sizes[fidx];
}
return total_size;
}
uint32_t ExynosGraphicBufferMali::get_layer_count(buffer_handle_t hnd) {
convert_handle(gralloc_hnd, hnd, -EINVAL);
return gralloc_hnd->layer_count;
}
bool ExynosGraphicBufferMali::check_plane_is_on_new_fd(buffer_handle_t hnd, int plane) {
convert_handle(gralloc_hnd, hnd, false);
return gralloc_hnd->plane_info[plane].fd_idx == plane;
}
int ExynosGraphicBufferMali::get_plane_fd(buffer_handle_t hnd, int plane) {
convert_handle(gralloc_hnd, hnd, -EINVAL);
//#define MALI_GRALLOC_INTFMT_FMT_MASK 0x00000000ffffffffULL
uint64_t base_format = gralloc_hnd->alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK;
switch (base_format) {
case HAL_PIXEL_FORMAT_EXYNOS_YV12_M: {
if (plane == 1) {
return gralloc_hnd->fds[2];
} else if (plane == 2) {
return gralloc_hnd->fds[1];
}
} break;
case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M: // HAL_PIXEL_FORMAT_I420:
case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B:
case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV:
case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M: // HAL_PIXEL_FORMAT_YCbCr_420_SP: //HAL_PIXEL_FORMAT_NV12:
case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M:
case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL: // HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_FULL
case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M:
case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED: // HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
{
if (plane == 1) {
return gralloc_hnd->fds[1];
} else if (plane == 2) {
return gralloc_hnd->fds[2];
}
}
}
return gralloc_hnd->fds[0];
}
bool ExynosGraphicBufferMali::check_usage_afbc_padding(buffer_handle_t hnd, uint64_t usage) {
convert_handle(gralloc_hnd, hnd, -EINVAL);
return (usage & MALI_GRALLOC_USAGE_AFBC_PADDING) == MALI_GRALLOC_USAGE_AFBC_PADDING;
}
/* Mali interface end */