• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
36 using aidl::android::hardware::graphics::common::ChromaSiting;
37 using aidl::android::hardware::graphics::common::Dataspace;
38 using aidl::android::hardware::graphics::common::ExtendableType;
39 using aidl::android::hardware::graphics::common::PlaneLayout;
40 using aidl::android::hardware::graphics::common::PlaneLayoutComponent;
41 using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
42 using android::hardware::graphics::common::V1_2::BufferUsage;
43 using android::hardware::graphics::mapper::V4_0::Error;
44 using android::hardware::graphics::mapper::V4_0::IMapper;
45 using android::hardware::hidl_handle;
46 using android::hardware::hidl_vec;
47 using MetadataType =
48    android::hardware::graphics::mapper::V4_0::IMapper::MetadataType;
49 
50 Error
GetMetadata(android::sp<IMapper> mapper,const native_handle_t * buffer,MetadataType type,hidl_vec<uint8_t> * metadata)51 GetMetadata(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 
GetPlaneLayouts(android::sp<IMapper> mapper,const native_handle_t * buffer)70 std::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 
92 extern "C"
93 {
94 
95 int
mapper_metadata_get_buffer_info(struct ANativeWindowBuffer * buf,struct buffer_info * out_buf_info)96 mapper_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