1/* 2 * Mesa 3-D graphics library 3 * 4 * Copyright (C) 2021 GlobalLogic Ukraine 5 * Copyright (C) 2021 Roman Stratiienko (r.stratiienko@gmail.com) 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 * DEALINGS IN THE SOFTWARE. 24 */ 25 26#include "platform_android.h" 27 28#include <system/window.h> 29#include <aidl/android/hardware/graphics/common/ChromaSiting.h> 30#include <aidl/android/hardware/graphics/common/Dataspace.h> 31#include <aidl/android/hardware/graphics/common/ExtendableType.h> 32#include <aidl/android/hardware/graphics/common/PlaneLayoutComponent.h> 33#include <aidl/android/hardware/graphics/common/PlaneLayoutComponentType.h> 34#include <gralloctypes/Gralloc4.h> 35 36using aidl::android::hardware::graphics::common::ChromaSiting; 37using aidl::android::hardware::graphics::common::Dataspace; 38using aidl::android::hardware::graphics::common::ExtendableType; 39using aidl::android::hardware::graphics::common::PlaneLayout; 40using aidl::android::hardware::graphics::common::PlaneLayoutComponent; 41using aidl::android::hardware::graphics::common::PlaneLayoutComponentType; 42using android::hardware::graphics::common::V1_2::BufferUsage; 43using android::hardware::graphics::mapper::V4_0::Error; 44using android::hardware::graphics::mapper::V4_0::IMapper; 45using android::hardware::hidl_handle; 46using android::hardware::hidl_vec; 47using MetadataType = 48 android::hardware::graphics::mapper::V4_0::IMapper::MetadataType; 49 50Error 51GetMetadata(android::sp<IMapper> mapper, const native_handle_t *buffer, 52 MetadataType type, hidl_vec<uint8_t>* metadata) 53{ 54 Error error = Error::NONE; 55 56 auto native_handle = const_cast<native_handle_t*>(buffer); 57 58 auto ret = mapper->get(native_handle, type, 59 [&](const auto& get_error, const auto& get_metadata) { 60 error = get_error; 61 *metadata = get_metadata; 62 }); 63 64 if (!ret.isOk()) 65 error = Error::NO_RESOURCES; 66 67 return error; 68} 69 70std::optional<std::vector<PlaneLayout>> GetPlaneLayouts( 71 android::sp<IMapper> mapper, const native_handle_t *buffer) 72{ 73 hidl_vec<uint8_t> encoded_layouts; 74 75 Error error = GetMetadata(mapper, buffer, 76 android::gralloc4::MetadataType_PlaneLayouts, 77 &encoded_layouts); 78 79 if (error != Error::NONE) 80 return std::nullopt; 81 82 std::vector<PlaneLayout> plane_layouts; 83 84 auto status = android::gralloc4::decodePlaneLayouts(encoded_layouts, &plane_layouts); 85 86 if (status != android::OK) 87 return std::nullopt; 88 89 return plane_layouts; 90} 91 92extern "C" 93{ 94 95int 96mapper_metadata_get_buffer_info(struct ANativeWindowBuffer *buf, 97 struct buffer_info *out_buf_info) 98{ 99 static android::sp<IMapper> mapper = IMapper::getService(); 100 struct buffer_info buf_info = *out_buf_info; 101 if (mapper == nullptr) 102 return -EINVAL; 103 104 if (!buf->handle) 105 return -EINVAL; 106 107 buf_info.width = buf->width; 108 buf_info.height = buf->height; 109 110 hidl_vec<uint8_t> encoded_format; 111 auto err = GetMetadata(mapper, buf->handle, android::gralloc4::MetadataType_PixelFormatFourCC, &encoded_format); 112 if (err != Error::NONE) 113 return -EINVAL; 114 115 auto status = android::gralloc4::decodePixelFormatFourCC(encoded_format, &buf_info.drm_fourcc); 116 if (status != android::OK) 117 return -EINVAL; 118 119 hidl_vec<uint8_t> encoded_modifier; 120 err = GetMetadata(mapper, buf->handle, android::gralloc4::MetadataType_PixelFormatModifier, &encoded_modifier); 121 if (err != Error::NONE) 122 return -EINVAL; 123 124 status = android::gralloc4::decodePixelFormatModifier(encoded_modifier, &buf_info.modifier); 125 if (status != android::OK) 126 return -EINVAL; 127 128 auto layouts_opt = GetPlaneLayouts(mapper, buf->handle); 129 130 if (!layouts_opt) 131 return -EINVAL; 132 133 std::vector<PlaneLayout>& layouts = *layouts_opt; 134 135 buf_info.num_planes = layouts.size(); 136 137 bool per_plane_unique_fd = buf->handle->numFds == buf_info.num_planes; 138 139 for (uint32_t i = 0; i < layouts.size(); i++) { 140 buf_info.fds[i] = per_plane_unique_fd ? buf->handle->data[i] : buf->handle->data[0]; 141 buf_info.pitches[i] = layouts[i].strideInBytes; 142 buf_info.offsets[i] = layouts[i].offsetInBytes; 143 } 144 145 /* optional attributes */ 146 hidl_vec<uint8_t> encoded_chroma_siting; 147 err = GetMetadata(mapper, buf->handle, android::gralloc4::MetadataType_ChromaSiting, &encoded_chroma_siting); 148 if (err == Error::NONE) { 149 ExtendableType chroma_siting_ext; 150 status = android::gralloc4::decodeChromaSiting(encoded_chroma_siting, &chroma_siting_ext); 151 if (status != android::OK) 152 return -EINVAL; 153 154 ChromaSiting chroma_siting = android::gralloc4::getStandardChromaSitingValue(chroma_siting_ext); 155 switch (chroma_siting) { 156 case ChromaSiting::SITED_INTERSTITIAL: 157 buf_info.horizontal_siting = __DRI_YUV_CHROMA_SITING_0_5; 158 buf_info.vertical_siting = __DRI_YUV_CHROMA_SITING_0_5; 159 break; 160 case ChromaSiting::COSITED_HORIZONTAL: 161 buf_info.horizontal_siting = __DRI_YUV_CHROMA_SITING_0; 162 buf_info.vertical_siting = __DRI_YUV_CHROMA_SITING_0_5; 163 break; 164 default: 165 break; 166 } 167 } 168 169 hidl_vec<uint8_t> encoded_dataspace; 170 err = GetMetadata(mapper, buf->handle, android::gralloc4:: MetadataType_Dataspace, &encoded_dataspace); 171 if (err == Error::NONE) { 172 Dataspace dataspace; 173 status = android::gralloc4::decodeDataspace(encoded_dataspace, &dataspace); 174 if (status != android::OK) 175 return -EINVAL; 176 177 Dataspace standard = (Dataspace)((int)dataspace & (uint32_t)Dataspace::STANDARD_MASK); 178 switch (standard) { 179 case Dataspace::STANDARD_BT709: 180 buf_info.yuv_color_space = __DRI_YUV_COLOR_SPACE_ITU_REC709; 181 break; 182 case Dataspace::STANDARD_BT601_625: 183 case Dataspace::STANDARD_BT601_625_UNADJUSTED: 184 case Dataspace::STANDARD_BT601_525: 185 case Dataspace::STANDARD_BT601_525_UNADJUSTED: 186 buf_info.yuv_color_space = __DRI_YUV_COLOR_SPACE_ITU_REC601; 187 break; 188 case Dataspace::STANDARD_BT2020: 189 case Dataspace::STANDARD_BT2020_CONSTANT_LUMINANCE: 190 buf_info.yuv_color_space = __DRI_YUV_COLOR_SPACE_ITU_REC2020; 191 break; 192 default: 193 break; 194 } 195 196 Dataspace range = (Dataspace)((int)dataspace & (uint32_t)Dataspace::RANGE_MASK); 197 switch (range) { 198 case Dataspace::RANGE_FULL: 199 buf_info.sample_range = __DRI_YUV_FULL_RANGE; 200 break; 201 case Dataspace::RANGE_LIMITED: 202 buf_info.sample_range = __DRI_YUV_NARROW_RANGE; 203 break; 204 default: 205 break; 206 } 207 } 208 209 *out_buf_info = buf_info; 210 211 return 0; 212} 213 214} // extern "C" 215