| /* |
| * 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; |
| } |
| |
| 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_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; |
| 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_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; |
| 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; |
| 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 |