1 #include <gralloc3/gralloc_vendor_interface.h>
2 
3 #include <android/hardware/graphics/mapper/2.0/IMapper.h>
4 
5 #include "GrallocBufferDescriptor.h"
6 #include "mali_gralloc_buffer.h"
7 #include "mali_gralloc_bufferallocation.h"
8 #include "mali_gralloc_ion.h"
9 #include "mali_gralloc_formats.h"
10 #include "gralloc_buffer_priv.h"
11 #include "exynos_format.h"
12 #include "format_info.h"
13 
14 namespace android::hardware::graphics::allocator::priv {
15 
16 struct Descriptor {
17     unsigned int size = 0;
18     uint64_t producer_usage = 0;
19     uint64_t consumer_usage = 0;
20 
21     struct PlaneDescriptor {
22         int fd = -1;
23         size_t size = 0;
24         off_t offset = 0;
25         int stride_byte = 0;
26     };
27     std::vector<PlaneDescriptor> planes;
28 
29     int width = 0;
30     int height = 0;
31     int stride_pixel = 0;
32     int format = 0;
33 };
34 
createDescriptor()35 Descriptor *createDescriptor() { return new Descriptor(); }
deleteDescriptor(Descriptor * descriptor)36 void deleteDescriptor(Descriptor *descriptor) { delete descriptor; }
37 
setProducerUsage(Descriptor & descriptor,uint64_t usage)38 void setProducerUsage(Descriptor &descriptor, uint64_t usage) {
39     descriptor.producer_usage = usage;
40 }
41 
setConsumerUsage(Descriptor & descriptor,uint64_t usage)42 void setConsumerUsage(Descriptor &descriptor, uint64_t usage) {
43     descriptor.consumer_usage = usage;
44 }
45 
setPlaneCount(Descriptor & descriptor,int count)46 void setPlaneCount(Descriptor &descriptor, int count) {
47     descriptor.planes.resize(count);
48 }
49 
setPlane(Descriptor & descriptor,int index,int fd,size_t size,off_t offset,int stride_byte)50 void setPlane(Descriptor &descriptor, int index, int fd, size_t size, off_t offset, int stride_byte) {
51     descriptor.planes[index].fd = fd;
52     descriptor.planes[index].size = size;
53     descriptor.planes[index].offset = offset;
54     descriptor.planes[index].stride_byte = stride_byte;
55 }
56 
setWidth(Descriptor & descriptor,int width)57 void setWidth(Descriptor &descriptor, int width) {
58     descriptor.width = width;
59 }
60 
setHeight(Descriptor & descriptor,int height)61 void setHeight(Descriptor &descriptor, int height) {
62     descriptor.height = height;
63 }
64 
setStridePixel(Descriptor & descriptor,int stride_pixel)65 void setStridePixel(Descriptor &descriptor, int stride_pixel) {
66     descriptor.stride_pixel = stride_pixel;
67 }
68 
setFormat(Descriptor & descriptor,int format)69 void setFormat(Descriptor &descriptor, int format) {
70     descriptor.format = format;
71 }
72 
getFormatBitsPerPixel(uint64_t format)73 uint8_t getFormatBitsPerPixel(uint64_t format) {
74     auto idx = get_format_index(format);
75     if (idx == -1) {
76         ALOGE("getFormatBitsPerPixel failed, invalid format %" PRIu64 "", format);
77         return 0;
78     }
79     return formats[idx].bpp[0];
80 }
81 
createNativeHandle(const Descriptor & descriptor)82 buffer_handle_t createNativeHandle(const Descriptor &descriptor) {
83     for (int i = 0; i < descriptor.planes.size(); ++i) {
84         off64_t fd_size = lseek64(descriptor.planes[i].fd, 0, SEEK_END);
85         if (fd_size < descriptor.planes[i].size) {
86             ALOGE("createNativeHandle failed: plane[%d] requested size greater than fd size.",
87                 i);
88             return nullptr;
89         }
90     }
91 
92     buffer_descriptor_t buffer_descriptor;
93 
94     buffer_descriptor.pixel_stride = descriptor.stride_pixel;
95     buffer_descriptor.width = descriptor.width;
96     buffer_descriptor.height = descriptor.height;
97     buffer_descriptor.layer_count = 1;
98     buffer_descriptor.hal_format = descriptor.format;
99     buffer_descriptor.producer_usage = descriptor.producer_usage;
100     buffer_descriptor.consumer_usage = descriptor.consumer_usage;
101     buffer_descriptor.format_type = MALI_GRALLOC_FORMAT_TYPE_USAGE;
102     buffer_descriptor.signature = sizeof(buffer_descriptor_t);
103 
104     buffer_descriptor.alloc_format = buffer_descriptor.internal_format
105         = buffer_descriptor.hal_format;
106 
107     buffer_descriptor.fd_count = buffer_descriptor.plane_count
108         = descriptor.planes.size();
109     for (int i = 0; i < descriptor.planes.size(); ++i) {
110         buffer_descriptor.sizes[i] = descriptor.planes[i].size;
111     }
112 
113     auto format_index = get_format_index(descriptor.format);
114     if (format_index == -1) {
115         ALOGE("get_format_index failed, invalid format %d", descriptor.format);
116         return 0;
117     }
118     for (int i = 0; i < descriptor.planes.size(); ++i) {
119         uint8_t bpp = formats[format_index].bpp[i];
120         if (bpp == 0) {
121             ALOGE("createNativeHandle failed, format %d has bpp[%d]=0",
122                 descriptor.format, i);
123             return nullptr;
124         }
125         buffer_descriptor.plane_info[i] = {
126             .byte_stride = static_cast<uint32_t>((descriptor.planes[i].stride_byte * bpp) / 8),
127             .alloc_width = buffer_descriptor.width,
128             .alloc_height = buffer_descriptor.height,
129         };
130     }
131 
132     mali_gralloc_derive_format_and_size(nullptr, &buffer_descriptor);
133 
134     const gralloc_buffer_descriptor_t gralloc_buffer_descriptor =
135         reinterpret_cast<const gralloc_buffer_descriptor_t>(&buffer_descriptor);
136 
137     buffer_handle_t tmp_buffer;
138     bool shared;
139     // TODO(modan@, make mali_gralloc_ion_allocate accept multiple fds)
140     int allocResult = mali_gralloc_ion_allocate(&gralloc_buffer_descriptor, 1, &tmp_buffer, &shared,
141         descriptor.planes[0].fd);
142     if (allocResult < 0) {
143         return nullptr;
144     }
145 
146     private_handle_t *private_handle = const_cast<private_handle_t *>(
147         static_cast<const private_handle_t *>(tmp_buffer));
148     // TODO(modan@, handle all plane offsets)
149     private_handle->offset = private_handle->plane_info[0].offset = descriptor.planes[0].offset;
150 
151     int err = gralloc_buffer_attr_allocate(private_handle);
152     if (err) {
153         ALOGE("createNativeHandle failed, gralloc_buffer_attr_allocate returned %d.", err);
154         mali_gralloc_ion_free(private_handle);
155         return nullptr;
156     }
157     return tmp_buffer;
158 }
159 
160 }  // namespace android::hardware::graphics::allocator::priv
161