xref: /aosp_15_r20/external/drm_hwcomposer/bufferinfo/BufferInfoMapperMetadata.cpp (revision 0a9764fe0a15e71ebbeb85e87e10990c23aab47f)
1*0a9764feSAndroid Build Coastguard Worker /*
2*0a9764feSAndroid Build Coastguard Worker  * Copyright (C) 2020 The Android Open Source Project
3*0a9764feSAndroid Build Coastguard Worker  *
4*0a9764feSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*0a9764feSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*0a9764feSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*0a9764feSAndroid Build Coastguard Worker  *
8*0a9764feSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*0a9764feSAndroid Build Coastguard Worker  *
10*0a9764feSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*0a9764feSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*0a9764feSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*0a9764feSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*0a9764feSAndroid Build Coastguard Worker  * limitations under the License.
15*0a9764feSAndroid Build Coastguard Worker  */
16*0a9764feSAndroid Build Coastguard Worker 
17*0a9764feSAndroid Build Coastguard Worker #if __ANDROID_API__ >= 30
18*0a9764feSAndroid Build Coastguard Worker 
19*0a9764feSAndroid Build Coastguard Worker #define LOG_TAG "drmhwc"
20*0a9764feSAndroid Build Coastguard Worker 
21*0a9764feSAndroid Build Coastguard Worker #include "BufferInfoMapperMetadata.h"
22*0a9764feSAndroid Build Coastguard Worker 
23*0a9764feSAndroid Build Coastguard Worker #include <drm/drm_fourcc.h>
24*0a9764feSAndroid Build Coastguard Worker #include <ui/GraphicBufferMapper.h>
25*0a9764feSAndroid Build Coastguard Worker #include <xf86drm.h>
26*0a9764feSAndroid Build Coastguard Worker #include <xf86drmMode.h>
27*0a9764feSAndroid Build Coastguard Worker 
28*0a9764feSAndroid Build Coastguard Worker #include <cinttypes>
29*0a9764feSAndroid Build Coastguard Worker 
30*0a9764feSAndroid Build Coastguard Worker #include "utils/log.h"
31*0a9764feSAndroid Build Coastguard Worker 
32*0a9764feSAndroid Build Coastguard Worker namespace android {
33*0a9764feSAndroid Build Coastguard Worker 
CreateInstance()34*0a9764feSAndroid Build Coastguard Worker BufferInfoGetter *BufferInfoMapperMetadata::CreateInstance() {
35*0a9764feSAndroid Build Coastguard Worker   if (GraphicBufferMapper::getInstance().getMapperVersion() <
36*0a9764feSAndroid Build Coastguard Worker       GraphicBufferMapper::GRALLOC_4)
37*0a9764feSAndroid Build Coastguard Worker     return nullptr;
38*0a9764feSAndroid Build Coastguard Worker 
39*0a9764feSAndroid Build Coastguard Worker   return new BufferInfoMapperMetadata();
40*0a9764feSAndroid Build Coastguard Worker }
41*0a9764feSAndroid Build Coastguard Worker 
42*0a9764feSAndroid Build Coastguard Worker /* The implementation below makes assumptions on the order and number of file
43*0a9764feSAndroid Build Coastguard Worker  * descriptors that Gralloc places in the native_handle_t and as such it very
44*0a9764feSAndroid Build Coastguard Worker  * likely needs to be adapted to match the particular Gralloc implementation
45*0a9764feSAndroid Build Coastguard Worker  * used in the system. For this reason it is been declared as a weak symbol,
46*0a9764feSAndroid Build Coastguard Worker  * so that it can be overridden.
47*0a9764feSAndroid Build Coastguard Worker  */
48*0a9764feSAndroid Build Coastguard Worker int __attribute__((weak))
GetFds(buffer_handle_t handle,BufferInfo * bo)49*0a9764feSAndroid Build Coastguard Worker BufferInfoMapperMetadata::GetFds(buffer_handle_t handle, BufferInfo *bo) {
50*0a9764feSAndroid Build Coastguard Worker   int fd_index = 0;
51*0a9764feSAndroid Build Coastguard Worker 
52*0a9764feSAndroid Build Coastguard Worker   if (handle->numFds <= 0) {
53*0a9764feSAndroid Build Coastguard Worker     ALOGE("Handle has no fds");
54*0a9764feSAndroid Build Coastguard Worker     return android::BAD_VALUE;
55*0a9764feSAndroid Build Coastguard Worker   }
56*0a9764feSAndroid Build Coastguard Worker 
57*0a9764feSAndroid Build Coastguard Worker   for (int i = 0; i < kBufferMaxPlanes; i++) {
58*0a9764feSAndroid Build Coastguard Worker     /* If no size, we're out of usable planes */
59*0a9764feSAndroid Build Coastguard Worker     if (bo->sizes[i] <= 0) {
60*0a9764feSAndroid Build Coastguard Worker       if (i == 0) {
61*0a9764feSAndroid Build Coastguard Worker         ALOGE("Bad handle metadata");
62*0a9764feSAndroid Build Coastguard Worker         return android::BAD_VALUE;
63*0a9764feSAndroid Build Coastguard Worker       }
64*0a9764feSAndroid Build Coastguard Worker       break;
65*0a9764feSAndroid Build Coastguard Worker     }
66*0a9764feSAndroid Build Coastguard Worker 
67*0a9764feSAndroid Build Coastguard Worker     /*
68*0a9764feSAndroid Build Coastguard Worker      * If the offset is zero, its multi-buffer
69*0a9764feSAndroid Build Coastguard Worker      * so move to the next fd
70*0a9764feSAndroid Build Coastguard Worker      */
71*0a9764feSAndroid Build Coastguard Worker     if (i != 0 && bo->offsets[i] == 0) {
72*0a9764feSAndroid Build Coastguard Worker       fd_index++;
73*0a9764feSAndroid Build Coastguard Worker       if (fd_index >= handle->numFds) {
74*0a9764feSAndroid Build Coastguard Worker         ALOGE("Handle has no more fds");
75*0a9764feSAndroid Build Coastguard Worker         return android::BAD_VALUE;
76*0a9764feSAndroid Build Coastguard Worker       }
77*0a9764feSAndroid Build Coastguard Worker     }
78*0a9764feSAndroid Build Coastguard Worker 
79*0a9764feSAndroid Build Coastguard Worker     bo->prime_fds[i] = handle->data[fd_index];
80*0a9764feSAndroid Build Coastguard Worker     if (bo->prime_fds[i] <= 0) {
81*0a9764feSAndroid Build Coastguard Worker       ALOGE("Invalid prime fd");
82*0a9764feSAndroid Build Coastguard Worker       return android::BAD_VALUE;
83*0a9764feSAndroid Build Coastguard Worker     }
84*0a9764feSAndroid Build Coastguard Worker   }
85*0a9764feSAndroid Build Coastguard Worker 
86*0a9764feSAndroid Build Coastguard Worker   return 0;
87*0a9764feSAndroid Build Coastguard Worker }
88*0a9764feSAndroid Build Coastguard Worker 
GetBoInfo(buffer_handle_t handle)89*0a9764feSAndroid Build Coastguard Worker auto BufferInfoMapperMetadata::GetBoInfo(buffer_handle_t handle)
90*0a9764feSAndroid Build Coastguard Worker     -> std::optional<BufferInfo> {
91*0a9764feSAndroid Build Coastguard Worker   GraphicBufferMapper &mapper = GraphicBufferMapper::getInstance();
92*0a9764feSAndroid Build Coastguard Worker   if (handle == nullptr)
93*0a9764feSAndroid Build Coastguard Worker     return {};
94*0a9764feSAndroid Build Coastguard Worker 
95*0a9764feSAndroid Build Coastguard Worker   BufferInfo bi{};
96*0a9764feSAndroid Build Coastguard Worker 
97*0a9764feSAndroid Build Coastguard Worker   int err = mapper.getPixelFormatFourCC(handle, &bi.format);
98*0a9764feSAndroid Build Coastguard Worker   if (err != 0) {
99*0a9764feSAndroid Build Coastguard Worker     ALOGE("Failed to get FourCC format err=%d", err);
100*0a9764feSAndroid Build Coastguard Worker     return {};
101*0a9764feSAndroid Build Coastguard Worker   }
102*0a9764feSAndroid Build Coastguard Worker 
103*0a9764feSAndroid Build Coastguard Worker   err = mapper.getPixelFormatModifier(handle, &bi.modifiers[0]);
104*0a9764feSAndroid Build Coastguard Worker   if (err != 0) {
105*0a9764feSAndroid Build Coastguard Worker     ALOGE("Failed to get DRM Modifier err=%d", err);
106*0a9764feSAndroid Build Coastguard Worker     return {};
107*0a9764feSAndroid Build Coastguard Worker   }
108*0a9764feSAndroid Build Coastguard Worker 
109*0a9764feSAndroid Build Coastguard Worker   uint64_t width = 0;
110*0a9764feSAndroid Build Coastguard Worker   err = mapper.getWidth(handle, &width);
111*0a9764feSAndroid Build Coastguard Worker   if (err != 0) {
112*0a9764feSAndroid Build Coastguard Worker     ALOGE("Failed to get Width err=%d", err);
113*0a9764feSAndroid Build Coastguard Worker     return {};
114*0a9764feSAndroid Build Coastguard Worker   }
115*0a9764feSAndroid Build Coastguard Worker   bi.width = static_cast<uint32_t>(width);
116*0a9764feSAndroid Build Coastguard Worker 
117*0a9764feSAndroid Build Coastguard Worker   uint64_t height = 0;
118*0a9764feSAndroid Build Coastguard Worker   err = mapper.getHeight(handle, &height);
119*0a9764feSAndroid Build Coastguard Worker   if (err != 0) {
120*0a9764feSAndroid Build Coastguard Worker     ALOGE("Failed to get Height err=%d", err);
121*0a9764feSAndroid Build Coastguard Worker     return {};
122*0a9764feSAndroid Build Coastguard Worker   }
123*0a9764feSAndroid Build Coastguard Worker   bi.height = static_cast<uint32_t>(height);
124*0a9764feSAndroid Build Coastguard Worker 
125*0a9764feSAndroid Build Coastguard Worker   std::vector<ui::PlaneLayout> layouts;
126*0a9764feSAndroid Build Coastguard Worker   err = mapper.getPlaneLayouts(handle, &layouts);
127*0a9764feSAndroid Build Coastguard Worker   if (err != 0) {
128*0a9764feSAndroid Build Coastguard Worker     ALOGE("Failed to get Plane Layouts err=%d", err);
129*0a9764feSAndroid Build Coastguard Worker     return {};
130*0a9764feSAndroid Build Coastguard Worker   }
131*0a9764feSAndroid Build Coastguard Worker 
132*0a9764feSAndroid Build Coastguard Worker   for (uint32_t i = 0; i < layouts.size(); i++) {
133*0a9764feSAndroid Build Coastguard Worker     bi.modifiers[i] = bi.modifiers[0];
134*0a9764feSAndroid Build Coastguard Worker     bi.pitches[i] = layouts[i].strideInBytes;
135*0a9764feSAndroid Build Coastguard Worker     bi.offsets[i] = layouts[i].offsetInBytes;
136*0a9764feSAndroid Build Coastguard Worker     bi.sizes[i] = layouts[i].totalSizeInBytes;
137*0a9764feSAndroid Build Coastguard Worker   }
138*0a9764feSAndroid Build Coastguard Worker 
139*0a9764feSAndroid Build Coastguard Worker   err = GetFds(handle, &bi);
140*0a9764feSAndroid Build Coastguard Worker   if (err != 0) {
141*0a9764feSAndroid Build Coastguard Worker     ALOGE("Failed to get fds (err=%d)", err);
142*0a9764feSAndroid Build Coastguard Worker     return {};
143*0a9764feSAndroid Build Coastguard Worker   }
144*0a9764feSAndroid Build Coastguard Worker 
145*0a9764feSAndroid Build Coastguard Worker   return bi;
146*0a9764feSAndroid Build Coastguard Worker }
147*0a9764feSAndroid Build Coastguard Worker 
148*0a9764feSAndroid Build Coastguard Worker }  // namespace android
149*0a9764feSAndroid Build Coastguard Worker 
150*0a9764feSAndroid Build Coastguard Worker #endif
151