• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Mesa 3-D graphics library
3  *
4  * Copyright (C) 2021 GlobalLogic Ukraine
5  * Copyright (C) 2021-2022 Roman Stratiienko (r.stratiienko@gmail.com)
6  * SPDX-License-Identifier: MIT
7  */
8 #include <aidl/android/hardware/graphics/common/BufferUsage.h>
9 #include <aidl/android/hardware/graphics/common/ChromaSiting.h>
10 #include <aidl/android/hardware/graphics/common/Dataspace.h>
11 #include <aidl/android/hardware/graphics/common/ExtendableType.h>
12 #include <aidl/android/hardware/graphics/common/PlaneLayoutComponent.h>
13 #include <aidl/android/hardware/graphics/common/PlaneLayoutComponentType.h>
14 #include <ui/GraphicBufferMapper.h>
15 
16 #include <system/window.h>
17 
18 #include "util/log.h"
19 #include "u_gralloc_internal.h"
20 
21 using aidl::android::hardware::graphics::common::BufferUsage;
22 using aidl::android::hardware::graphics::common::ChromaSiting;
23 using aidl::android::hardware::graphics::common::ExtendableType;
24 using aidl::android::hardware::graphics::common::PlaneLayout;
25 using aidl::android::hardware::graphics::common::PlaneLayoutComponent;
26 using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
27 using android::hardware::graphics::common::V1_2::Dataspace;
28 using android::GraphicBufferMapper;
29 using android::OK;
30 using android::status_t;
31 
32 std::optional<std::vector<PlaneLayout>>
GetPlaneLayouts(const native_handle_t * buffer)33 GetPlaneLayouts(const native_handle_t *buffer)
34 {
35    std::vector<PlaneLayout> plane_layouts;
36    status_t  error = GraphicBufferMapper::get().getPlaneLayouts(buffer, &plane_layouts);
37 
38    if (error != OK)
39       return std::nullopt;
40 
41    return plane_layouts;
42 }
43 
44 struct gralloc_mapper {
45    struct u_gralloc base;
46 };
47 
48 extern "C" {
49 
50 static int
mapper5_get_buffer_basic_info(struct u_gralloc * gralloc,struct u_gralloc_buffer_handle * hnd,struct u_gralloc_buffer_basic_info * out)51 mapper5_get_buffer_basic_info(struct u_gralloc *gralloc,
52                               struct u_gralloc_buffer_handle *hnd,
53                               struct u_gralloc_buffer_basic_info *out)
54 {
55    if (!hnd->handle)
56       return -EINVAL;
57 
58    uint32_t drm_fourcc;
59    status_t error = GraphicBufferMapper::get().getPixelFormatFourCC(hnd->handle, &drm_fourcc);
60    if (error != OK)
61       return -EINVAL;
62 
63    uint64_t modifier;
64    error = GraphicBufferMapper::get().getPixelFormatModifier(hnd->handle,&modifier);
65    if (error != OK)
66       return  -EINVAL;
67 
68 
69    out->drm_fourcc = drm_fourcc;
70    out->modifier = modifier;
71 
72    auto layouts_opt = GetPlaneLayouts(hnd->handle);
73 
74    if (!layouts_opt)
75       return  -EINVAL;
76 
77    std::vector<PlaneLayout> &layouts = *layouts_opt;
78 
79    out->num_planes = layouts.size();
80 
81    int fd_index = 0;
82 
83    for (uint32_t i = 0; i < layouts.size(); i++) {
84       out->strides[i] = layouts[i].strideInBytes;
85       out->offsets[i] = layouts[i].offsetInBytes;
86 
87       /* offset == 0 means layer is located in different dma-buf */
88       if (out->offsets[i] == 0 && i > 0)
89          fd_index++;
90 
91       if (fd_index >= hnd->handle->numFds)
92          return -EINVAL;
93 
94       out->fds[i] = hnd->handle->data[fd_index];
95    }
96 
97    return 0;
98 }
99 
100 static int
mapper5_get_buffer_color_info(struct u_gralloc * gralloc,struct u_gralloc_buffer_handle * hnd,struct u_gralloc_buffer_color_info * out)101 mapper5_get_buffer_color_info(struct u_gralloc *gralloc,
102                               struct u_gralloc_buffer_handle *hnd,
103                               struct u_gralloc_buffer_color_info *out)
104 {
105    if (!hnd->handle)
106       return  -EINVAL;
107 
108    /* optional attributes */
109    ChromaSiting chroma_siting;
110    status_t error = GraphicBufferMapper::get().getChromaSiting(hnd->handle, &chroma_siting);
111    if (error != OK)
112       return  -EINVAL;
113 
114    Dataspace dataspace;
115    error = GraphicBufferMapper::get().getDataspace(hnd->handle, &dataspace);
116    if (error != OK)
117       return  -EINVAL;
118 
119    Dataspace standard =
120       (Dataspace)((int)dataspace & (uint32_t)Dataspace::STANDARD_MASK);
121    switch (standard) {
122       case Dataspace::STANDARD_BT709:
123          out->yuv_color_space = __DRI_YUV_COLOR_SPACE_ITU_REC709;
124          break;
125       case Dataspace::STANDARD_BT601_625:
126       case Dataspace::STANDARD_BT601_625_UNADJUSTED:
127       case Dataspace::STANDARD_BT601_525:
128       case Dataspace::STANDARD_BT601_525_UNADJUSTED:
129          out->yuv_color_space = __DRI_YUV_COLOR_SPACE_ITU_REC601;
130          break;
131       case Dataspace::STANDARD_BT2020:
132       case Dataspace::STANDARD_BT2020_CONSTANT_LUMINANCE:
133          out->yuv_color_space = __DRI_YUV_COLOR_SPACE_ITU_REC2020;
134          break;
135       default:
136          break;
137       }
138 
139       Dataspace range =
140          (Dataspace)((int)dataspace & (uint32_t)Dataspace::RANGE_MASK);
141       switch (range) {
142          case Dataspace::RANGE_FULL:
143             out->sample_range = __DRI_YUV_FULL_RANGE;
144             break;
145          case Dataspace::RANGE_LIMITED:
146             out->sample_range = __DRI_YUV_NARROW_RANGE;
147             break;
148          default:
149             break;
150       }
151 
152       switch (chroma_siting) {
153       case ChromaSiting::SITED_INTERSTITIAL:
154          out->horizontal_siting = __DRI_YUV_CHROMA_SITING_0_5;
155          out->vertical_siting = __DRI_YUV_CHROMA_SITING_0_5;
156          break;
157       case ChromaSiting::COSITED_HORIZONTAL:
158          out->horizontal_siting = __DRI_YUV_CHROMA_SITING_0;
159          out->vertical_siting = __DRI_YUV_CHROMA_SITING_0_5;
160          break;
161       case ChromaSiting::COSITED_VERTICAL:
162          out->horizontal_siting = __DRI_YUV_CHROMA_SITING_0_5;
163          out->vertical_siting = __DRI_YUV_CHROMA_SITING_0;
164          break;
165       case ChromaSiting::COSITED_BOTH:
166          out->horizontal_siting = __DRI_YUV_CHROMA_SITING_0;
167          out->vertical_siting = __DRI_YUV_CHROMA_SITING_0;
168          break;
169       default:
170          break;
171       }
172 
173    return 0;
174 }
175 
176 static int
mapper5_get_front_rendering_usage(struct u_gralloc * gralloc,uint64_t * out_usage)177 mapper5_get_front_rendering_usage(struct u_gralloc *gralloc,
178                                   uint64_t *out_usage)
179 {
180    assert(out_usage);
181 #if ANDROID_API_LEVEL >= 33
182    *out_usage = static_cast<uint64_t>(BufferUsage::FRONT_BUFFER);
183 
184    return 0;
185 #else
186    return -ENOTSUP;
187 #endif
188 }
189 
190 static int
destroy(struct u_gralloc * gralloc)191 destroy(struct u_gralloc *gralloc)
192 {
193    gralloc_mapper *gr = (struct gralloc_mapper *)gralloc;
194    delete gr;
195 
196    return 0;
197 }
198 
199 struct u_gralloc *
u_gralloc_imapper_api_create()200 u_gralloc_imapper_api_create()
201 {
202    auto &mapper = GraphicBufferMapper::get();
203    if(mapper.getMapperVersion() < GraphicBufferMapper::GRALLOC_4) {
204       mesa_logi("Could not find IMapper v4/v5 API");
205       return NULL;
206    }
207    auto gr = new gralloc_mapper;
208    gr->base.ops.get_buffer_basic_info = mapper5_get_buffer_basic_info;
209    gr->base.ops.get_buffer_color_info = mapper5_get_buffer_color_info;
210    gr->base.ops.get_front_rendering_usage = mapper5_get_front_rendering_usage;
211    gr->base.ops.destroy = destroy;
212 
213    mesa_logi("Using IMapper %d API", mapper.getMapperVersion());
214 
215    return &gr->base;
216 }
217 } // extern "C"
218 
219