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