diff options
Diffstat (limited to 'gralloc/QtiGralloc.cpp')
-rw-r--r-- | gralloc/QtiGralloc.cpp | 469 |
1 files changed, 469 insertions, 0 deletions
diff --git a/gralloc/QtiGralloc.cpp b/gralloc/QtiGralloc.cpp new file mode 100644 index 00000000..348e097a --- /dev/null +++ b/gralloc/QtiGralloc.cpp @@ -0,0 +1,469 @@ +/* + * Copyright (c) 2020, 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: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "QtiGralloc.h" + +#include <log/log.h> +namespace qtigralloc { + +using android::hardware::graphics::mapper::V4_0::IMapper; + +static sp<IMapper> getInstance() { + static sp<IMapper> mapper = IMapper::getService(); + return mapper; +} + +Error decodeMetadataState(hidl_vec<uint8_t> &in, bool *out) { + if (!in.size() || !out) { + return Error::BAD_VALUE; + } + memcpy(out, in.data(), METADATA_SET_SIZE); + return Error::NONE; +} + +Error encodeMetadataState(bool *in, hidl_vec<uint8_t> *out) { + if (!in || !out) { + return Error::BAD_VALUE; + } + out->resize(sizeof(bool) * METADATA_SET_SIZE); + memcpy(out->data(), in, sizeof(bool) * METADATA_SET_SIZE); + return Error::NONE; +} + +Error decodeColorMetadata(hidl_vec<uint8_t> &in, ColorMetaData *out) { + if (!in.size() || !out) { + return Error::BAD_VALUE; + } + memcpy(out, in.data(), sizeof(ColorMetaData)); + return Error::NONE; +} + +Error encodeColorMetadata(ColorMetaData &in, hidl_vec<uint8_t> *out) { + if (!out) { + return Error::BAD_VALUE; + } + out->resize(sizeof(ColorMetaData)); + memcpy(out->data(), &in, sizeof(ColorMetaData)); + return Error::NONE; +} + +// decode the raw graphics metadata from bytestream and store it in 'data' member of +// GraphicsMetadata struct during mapper->set call, 'size' member is unused. +Error decodeGraphicsMetadata(hidl_vec<uint8_t> &in, GraphicsMetadata *out) { + if (!in.size() || !out) { + return Error::BAD_VALUE; + } + memcpy(&(out->data), in.data(), GRAPHICS_METADATA_SIZE_IN_BYTES); + return Error::NONE; +} + +// encode only 'data' member of GraphicsMetadata struct for retrieval of +// graphics metadata during mapper->get call +Error encodeGraphicsMetadata(GraphicsMetadata &in, hidl_vec<uint8_t> *out) { + if (!out) { + return Error::BAD_VALUE; + } + out->resize(GRAPHICS_METADATA_SIZE_IN_BYTES); + memcpy(out->data(), &(in.data), GRAPHICS_METADATA_SIZE_IN_BYTES); + return Error::NONE; +} + +// decode the raw graphics metadata from bytestream before presenting it to caller +Error decodeGraphicsMetadataRaw(hidl_vec<uint8_t> &in, void *out) { + if (!in.size() || !out) { + return Error::BAD_VALUE; + } + memcpy(out, in.data(), GRAPHICS_METADATA_SIZE_IN_BYTES); + return Error::NONE; +} + +// encode the raw graphics metadata in bytestream before calling mapper->set +Error encodeGraphicsMetadataRaw(void *in, hidl_vec<uint8_t> *out) { + if (!in || !out) { + return Error::BAD_VALUE; + } + out->resize(GRAPHICS_METADATA_SIZE_IN_BYTES); + memcpy(out->data(), in, GRAPHICS_METADATA_SIZE_IN_BYTES); + return Error::NONE; +} + +Error decodeUBWCStats(hidl_vec<uint8_t> &in, UBWCStats *out) { + if (!in.size() || !out) { + return Error::BAD_VALUE; + } + memcpy(out, in.data(), UBWC_STATS_ARRAY_SIZE * sizeof(UBWCStats)); + return Error::NONE; +} + +Error encodeUBWCStats(UBWCStats *in, hidl_vec<uint8_t> *out) { + if (!in || !out) { + return Error::BAD_VALUE; + } + out->resize(UBWC_STATS_ARRAY_SIZE * sizeof(UBWCStats)); + memcpy(out->data(), in, UBWC_STATS_ARRAY_SIZE * sizeof(UBWCStats)); + return Error::NONE; +} + +Error decodeCVPMetadata(hidl_vec<uint8_t> &in, CVPMetadata *out) { + if (!in.size() || !out) { + return Error::BAD_VALUE; + } + memcpy(out, in.data(), sizeof(CVPMetadata)); + return Error::NONE; +} + +Error encodeCVPMetadata(CVPMetadata &in, hidl_vec<uint8_t> *out) { + if (!out) { + return Error::BAD_VALUE; + } + out->resize(sizeof(CVPMetadata)); + memcpy(out->data(), &in, sizeof(CVPMetadata)); + return Error::NONE; +} + +Error decodeVideoHistogramMetadata(hidl_vec<uint8_t> &in, VideoHistogramMetadata *out) { + if (!in.size() || !out) { + return Error::BAD_VALUE; + } + memcpy(out, in.data(), sizeof(VideoHistogramMetadata)); + return Error::NONE; +} + +Error encodeVideoHistogramMetadata(VideoHistogramMetadata &in, hidl_vec<uint8_t> *out) { + if (!out) { + return Error::BAD_VALUE; + } + out->resize(sizeof(VideoHistogramMetadata)); + memcpy(out->data(), &in, sizeof(VideoHistogramMetadata)); + return Error::NONE; +} + +Error decodeVideoTimestampInfo(hidl_vec<uint8_t> &in, VideoTimestampInfo *out) { + if (!in.size() || !out) { + return Error::BAD_VALUE; + } + memcpy(out, in.data(), sizeof(VideoTimestampInfo)); + return Error::NONE; +} + +Error encodeVideoTimestampInfo(VideoTimestampInfo &in, hidl_vec<uint8_t> *out) { + if (!out) { + return Error::BAD_VALUE; + } + out->resize(sizeof(VideoTimestampInfo)); + memcpy(out->data(), &in, sizeof(VideoTimestampInfo)); + return Error::NONE; +} + +Error decodeYUVPlaneInfoMetadata(hidl_vec<uint8_t> &in, qti_ycbcr *out) { + if (!in.size() || !out) { + return Error::BAD_VALUE; + } + qti_ycbcr *p = reinterpret_cast<qti_ycbcr *>(in.data()); + memcpy(out, in.data(), (YCBCR_LAYOUT_ARRAY_SIZE * sizeof(qti_ycbcr))); + return Error::NONE; +} + +Error encodeYUVPlaneInfoMetadata(qti_ycbcr *in, hidl_vec<uint8_t> *out) { + if (!out) { + return Error::BAD_VALUE; + } + out->resize(YCBCR_LAYOUT_ARRAY_SIZE * sizeof(qti_ycbcr)); + memcpy(out->data(), in, YCBCR_LAYOUT_ARRAY_SIZE * sizeof(qti_ycbcr)); + return Error::NONE; +} + +MetadataType getMetadataType(uint32_t in) { + switch (in) { + case QTI_VT_TIMESTAMP: + return MetadataType_VTTimestamp; + case QTI_VIDEO_PERF_MODE: + return MetadataType_VideoPerfMode; + case QTI_LINEAR_FORMAT: + return MetadataType_LinearFormat; + case QTI_SINGLE_BUFFER_MODE: + return MetadataType_SingleBufferMode; + case QTI_PP_PARAM_INTERLACED: + return MetadataType_PPParamInterlaced; + case QTI_MAP_SECURE_BUFFER: + return MetadataType_MapSecureBuffer; + case QTI_COLOR_METADATA: + return MetadataType_ColorMetadata; + case QTI_GRAPHICS_METADATA: + return MetadataType_GraphicsMetadata; + case QTI_UBWC_CR_STATS_INFO: + return MetadataType_UBWCCRStatsInfo; + case QTI_REFRESH_RATE: + return MetadataType_RefreshRate; + case QTI_CVP_METADATA: + return MetadataType_CVPMetadata; + case QTI_VIDEO_HISTOGRAM_STATS: + return MetadataType_VideoHistogramStats; + case QTI_VIDEO_TS_INFO: + return MetadataType_VideoTimestampInfo; + case QTI_FD: + return MetadataType_FD; + case QTI_PRIVATE_FLAGS: + return MetadataType_PrivateFlags; + case QTI_ALIGNED_WIDTH_IN_PIXELS: + return MetadataType_AlignedWidthInPixels; + case QTI_ALIGNED_HEIGHT_IN_PIXELS: + return MetadataType_AlignedHeightInPixels; + case QTI_STANDARD_METADATA_STATUS: + return MetadataType_StandardMetadataStatus; + case QTI_VENDOR_METADATA_STATUS: + return MetadataType_VendorMetadataStatus; + case QTI_BUFFER_TYPE: + return MetadataType_BufferType; + case QTI_CUSTOM_DIMENSIONS_STRIDE: + return MetadataType_CustomDimensionsStride; + case QTI_CUSTOM_DIMENSIONS_HEIGHT: + return MetadataType_CustomDimensionsHeight; + case QTI_RGB_DATA_ADDRESS: + return MetadataType_RgbDataAddress; + case QTI_COLORSPACE: + return MetadataType_ColorSpace; + case QTI_YUV_PLANE_INFO: + return MetadataType_YuvPlaneInfo; + default: + return MetadataType_Invalid; + } +} + +Error get(void *buffer, uint32_t type, void *param) { + hidl_vec<uint8_t> bytestream; + sp<IMapper> mapper = getInstance(); + + MetadataType metadata_type = getMetadataType(type); + if (metadata_type == MetadataType_Invalid) { + param = nullptr; + return Error::UNSUPPORTED; + } + + auto err = Error::UNSUPPORTED; + mapper->get(buffer, metadata_type, [&](const auto &tmpError, const auto &tmpByteStream) { + err = tmpError; + bytestream = tmpByteStream; + }); + + if (err != Error::NONE) { + return err; + } + + switch (type) { + case QTI_VT_TIMESTAMP: + err = static_cast<Error>(android::gralloc4::decodeUint64(qtigralloc::MetadataType_VTTimestamp, + bytestream, (uint64_t *)param)); + break; + case QTI_VIDEO_PERF_MODE: + err = static_cast<Error>(android::gralloc4::decodeUint32( + qtigralloc::MetadataType_VideoPerfMode, bytestream, (uint32_t *)param)); + break; + case QTI_LINEAR_FORMAT: + err = static_cast<Error>(android::gralloc4::decodeUint32( + qtigralloc::MetadataType_LinearFormat, bytestream, (uint32_t *)param)); + break; + case QTI_SINGLE_BUFFER_MODE: + err = static_cast<Error>(android::gralloc4::decodeUint32( + qtigralloc::MetadataType_SingleBufferMode, bytestream, (uint32_t *)param)); + break; + case QTI_PP_PARAM_INTERLACED: + err = static_cast<Error>(android::gralloc4::decodeInt32( + qtigralloc::MetadataType_PPParamInterlaced, bytestream, (int32_t *)param)); + break; + case QTI_MAP_SECURE_BUFFER: + err = static_cast<Error>(android::gralloc4::decodeInt32( + qtigralloc::MetadataType_MapSecureBuffer, bytestream, (int32_t *)param)); + break; + case QTI_COLOR_METADATA: + err = decodeColorMetadata(bytestream, (ColorMetaData *)param); + break; + case QTI_GRAPHICS_METADATA: + err = decodeGraphicsMetadataRaw(bytestream, param); + break; + case QTI_UBWC_CR_STATS_INFO: + err = decodeUBWCStats(bytestream, (UBWCStats *)param); + break; + case QTI_REFRESH_RATE: + err = static_cast<Error>(android::gralloc4::decodeFloat(qtigralloc::MetadataType_RefreshRate, + bytestream, (float *)param)); + break; + case QTI_CVP_METADATA: + err = decodeCVPMetadata(bytestream, (CVPMetadata *)param); + break; + case QTI_VIDEO_HISTOGRAM_STATS: + err = decodeVideoHistogramMetadata(bytestream, (VideoHistogramMetadata *)param); + break; + case QTI_VIDEO_TS_INFO: + err = decodeVideoTimestampInfo(bytestream, (VideoTimestampInfo *)param); + break; + case QTI_FD: + err = static_cast<Error>(android::gralloc4::decodeInt32(qtigralloc::MetadataType_FD, + bytestream, (int32_t *)param)); + break; + case QTI_PRIVATE_FLAGS: + err = static_cast<Error>(android::gralloc4::decodeInt32(qtigralloc::MetadataType_PrivateFlags, + bytestream, (int32_t *)param)); + break; + case QTI_ALIGNED_WIDTH_IN_PIXELS: + err = static_cast<Error>(android::gralloc4::decodeUint32( + qtigralloc::MetadataType_AlignedWidthInPixels, bytestream, (uint32_t *)param)); + break; + case QTI_ALIGNED_HEIGHT_IN_PIXELS: + err = static_cast<Error>(android::gralloc4::decodeUint32( + qtigralloc::MetadataType_AlignedHeightInPixels, bytestream, (uint32_t *)param)); + break; + case QTI_STANDARD_METADATA_STATUS: + case QTI_VENDOR_METADATA_STATUS: + err = decodeMetadataState(bytestream, (bool *)param); + break; + case QTI_BUFFER_TYPE: + err = static_cast<Error>(android::gralloc4::decodeUint32( + qtigralloc::MetadataType_BufferType, bytestream, (uint32_t *)param)); + break; + case QTI_CUSTOM_DIMENSIONS_STRIDE: + err = static_cast<Error>(android::gralloc4::decodeUint32( + qtigralloc::MetadataType_CustomDimensionsStride, bytestream, (uint32_t *)param)); + break; + case QTI_CUSTOM_DIMENSIONS_HEIGHT: + err = static_cast<Error>(android::gralloc4::decodeUint32( + qtigralloc::MetadataType_CustomDimensionsHeight, bytestream, (uint32_t *)param)); + break; + case QTI_RGB_DATA_ADDRESS: + err = static_cast<Error>(android::gralloc4::decodeUint64( + qtigralloc::MetadataType_RgbDataAddress, bytestream, (uint64_t *)param)); + break; + case QTI_COLORSPACE: + err = static_cast<Error>(android::gralloc4::decodeUint32(qtigralloc::MetadataType_ColorSpace, + bytestream, (uint32_t *)param)); + break; + case QTI_YUV_PLANE_INFO: + err = decodeYUVPlaneInfoMetadata(bytestream, (qti_ycbcr *)param); + break; + default: + param = nullptr; + return Error::UNSUPPORTED; + } + + return err; +} + +Error set(void *buffer, uint32_t type, void *param) { + hidl_vec<uint8_t> bytestream; + sp<IMapper> mapper = getInstance(); + + Error err = Error::UNSUPPORTED; + MetadataType metadata_type = getMetadataType(type); + if (metadata_type == MetadataType_Invalid) { + return err; + } + + switch (type) { + case QTI_VT_TIMESTAMP: + err = static_cast<Error>(android::gralloc4::encodeUint64(qtigralloc::MetadataType_VTTimestamp, + *(uint64_t *)param, &bytestream)); + break; + case QTI_VIDEO_PERF_MODE: + err = static_cast<Error>(android::gralloc4::encodeUint32( + qtigralloc::MetadataType_VideoPerfMode, *(uint32_t *)param, &bytestream)); + break; + case QTI_LINEAR_FORMAT: + err = static_cast<Error>(android::gralloc4::encodeUint32( + qtigralloc::MetadataType_LinearFormat, *(uint32_t *)param, &bytestream)); + break; + case QTI_SINGLE_BUFFER_MODE: + err = static_cast<Error>(android::gralloc4::encodeUint32( + qtigralloc::MetadataType_SingleBufferMode, *(uint32_t *)param, &bytestream)); + break; + case QTI_PP_PARAM_INTERLACED: + err = static_cast<Error>(android::gralloc4::encodeInt32( + qtigralloc::MetadataType_PPParamInterlaced, *(int32_t *)param, &bytestream)); + break; + case QTI_MAP_SECURE_BUFFER: + err = static_cast<Error>(android::gralloc4::encodeInt32( + qtigralloc::MetadataType_MapSecureBuffer, *(int32_t *)param, &bytestream)); + break; + case QTI_COLOR_METADATA: + err = encodeColorMetadata(*(ColorMetaData *)param, &bytestream); + break; + case QTI_GRAPHICS_METADATA: + err = encodeGraphicsMetadataRaw(param, &bytestream); + break; + case QTI_UBWC_CR_STATS_INFO: + err = encodeUBWCStats((UBWCStats *)param, &bytestream); + break; + case QTI_REFRESH_RATE: + err = static_cast<Error>(android::gralloc4::encodeFloat(qtigralloc::MetadataType_RefreshRate, + *(float *)param, &bytestream)); + break; + case QTI_CVP_METADATA: + err = encodeCVPMetadata(*(CVPMetadata *)param, &bytestream); + break; + case QTI_VIDEO_HISTOGRAM_STATS: + err = encodeVideoHistogramMetadata(*(VideoHistogramMetadata *)param, &bytestream); + break; + case QTI_VIDEO_TS_INFO: + err = encodeVideoTimestampInfo(*(VideoTimestampInfo *)param, &bytestream); + break; + default: + param = nullptr; + return Error::UNSUPPORTED; + } + + if (err != Error::NONE) { + return err; + } + + return mapper->set((void *)buffer, metadata_type, bytestream); +} + +int getMetadataState(void *buffer, uint32_t type) { + bool metadata_set[METADATA_SET_SIZE]; + Error err; + if (IS_VENDOR_METADATA_TYPE(type)) { + err = get(buffer, QTI_VENDOR_METADATA_STATUS, &metadata_set); + } else { + err = get(buffer, QTI_STANDARD_METADATA_STATUS, &metadata_set); + } + + if (err != Error::NONE) { + ALOGE("Unable to get metadata state"); + return -1; + } + + if (IS_VENDOR_METADATA_TYPE(type)) { + return metadata_set[GET_VENDOR_METADATA_STATUS_INDEX(type)]; + } else if (GET_STANDARD_METADATA_STATUS_INDEX(type) < METADATA_SET_SIZE) { + return metadata_set[GET_STANDARD_METADATA_STATUS_INDEX(type)]; + } else { + return -1; + } +} + +} // namespace qtigralloc |