1 /*
2 * Copyright 2023 Google LLC
3 * SPDX-License-Identifier: MIT
4 */
5
6 #include "GrallocMinigbm.h"
7
8 #include <cros_gralloc/cros_gralloc_handle.h>
9 #include <stdlib.h>
10 #include <sys/user.h>
11 #include <unistd.h>
12 #include <vndk/hardware_buffer.h>
13
14 #include <cinttypes>
15 #include <cstring>
16
17 #include "VirtGpu.h"
18 #include "util/log.h"
19
20 namespace gfxstream {
21
MinigbmGralloc(int32_t descriptor)22 MinigbmGralloc::MinigbmGralloc(int32_t descriptor) {
23 mDevice.reset(createPlatformVirtGpuDevice(kCapsetNone, descriptor));
24 }
25
getGrallocType()26 GrallocType MinigbmGralloc::getGrallocType() { return GRALLOC_TYPE_MINIGBM; }
27
createColorBuffer(int width,int height,uint32_t glformat)28 uint32_t MinigbmGralloc::createColorBuffer(int width, int height, uint32_t glformat) {
29 // Only supported format for pbuffers in gfxstream should be RGBA8
30 const uint32_t kVirglFormatRGBA = 67; // VIRGL_FORMAT_R8G8B8A8_UNORM;
31 uint32_t virtgpu_format = 0;
32 uint32_t bpp = 0;
33 switch (glformat) {
34 case kGlRGB:
35 mesa_logi("Note: egl wanted GL_RGB, still using RGBA");
36 virtgpu_format = kVirglFormatRGBA;
37 bpp = 4;
38 break;
39 case kGlRGBA:
40 virtgpu_format = kVirglFormatRGBA;
41 bpp = 4;
42 break;
43 default:
44 mesa_logi("Note: egl wanted 0x%x, still using RGBA", glformat);
45 virtgpu_format = kVirglFormatRGBA;
46 bpp = 4;
47 break;
48 }
49
50 uint32_t stride = bpp * width;
51 auto resource = mDevice->createResource(width, height, stride, stride * height, virtgpu_format,
52 PIPE_TEXTURE_2D, VIRGL_BIND_RENDER_TARGET);
53
54 uint32_t handle = resource->getResourceHandle();
55 resource->intoRaw();
56 return handle;
57 }
58
allocate(uint32_t width,uint32_t height,uint32_t format,uint64_t usage,AHardwareBuffer ** outputAhb)59 int MinigbmGralloc::allocate(uint32_t width, uint32_t height, uint32_t format, uint64_t usage,
60 AHardwareBuffer** outputAhb) {
61 struct AHardwareBuffer_Desc desc = {
62 .width = width,
63 .height = height,
64 .layers = 1,
65 .format = format,
66 .usage = usage,
67 };
68
69 return AHardwareBuffer_allocate(&desc, outputAhb);
70 }
71
acquire(AHardwareBuffer * ahb)72 void MinigbmGralloc::acquire(AHardwareBuffer* ahb) { AHardwareBuffer_acquire(ahb); }
73
release(AHardwareBuffer * ahb)74 void MinigbmGralloc::release(AHardwareBuffer* ahb) { AHardwareBuffer_release(ahb); }
75
lock(AHardwareBuffer * ahb,uint8_t ** ptr)76 int MinigbmGralloc::lock(AHardwareBuffer* ahb, uint8_t** ptr) {
77 return AHardwareBuffer_lock(ahb, AHARDWAREBUFFER_USAGE_CPU_READ_RARELY, -1, nullptr,
78 reinterpret_cast<void**>(ptr));
79 }
80
lockPlanes(AHardwareBuffer * ahb,std::vector<LockedPlane> * ahbPlanes)81 int MinigbmGralloc::lockPlanes(AHardwareBuffer* ahb, std::vector<LockedPlane>* ahbPlanes) {
82 mesa_loge("%s: unimplemented", __func__);
83 return -1;
84 }
85
unlock(AHardwareBuffer * ahb)86 int MinigbmGralloc::unlock(AHardwareBuffer* ahb) { return AHardwareBuffer_unlock(ahb, nullptr); }
87
getHostHandle(const native_handle_t * handle)88 uint32_t MinigbmGralloc::getHostHandle(const native_handle_t* handle) {
89 cros_gralloc_handle const* cros_handle = reinterpret_cast<cros_gralloc_handle const*>(handle);
90 struct VirtGpuExternalHandle hnd = {
91 .osHandle = dup(cros_handle->fds[0]),
92 .type = kMemHandleDmabuf,
93 };
94
95 auto resource = mDevice->importBlob(hnd);
96 if (!resource) {
97 return 0;
98 }
99
100 if (resource->wait()) {
101 return 0;
102 }
103
104 return resource->getResourceHandle();
105 }
106
getHostHandle(const AHardwareBuffer * ahb)107 uint32_t MinigbmGralloc::getHostHandle(const AHardwareBuffer* ahb) {
108 const native_handle_t* handle = AHardwareBuffer_getNativeHandle(ahb);
109 return getHostHandle(handle);
110 }
111
getNativeHandle(const AHardwareBuffer * ahb)112 const native_handle_t* MinigbmGralloc::getNativeHandle(const AHardwareBuffer* ahb) {
113 return AHardwareBuffer_getNativeHandle(ahb);
114 }
115
getFormat(const native_handle_t * handle)116 int MinigbmGralloc::getFormat(const native_handle_t* handle) {
117 return ((cros_gralloc_handle*)handle)->droid_format;
118 }
119
getFormat(const AHardwareBuffer * ahb)120 int MinigbmGralloc::getFormat(const AHardwareBuffer* ahb) {
121 const native_handle_t* handle = AHardwareBuffer_getNativeHandle(ahb);
122
123 return ((cros_gralloc_handle*)handle)->droid_format;
124 }
125
getFormatDrmFourcc(const native_handle_t * handle)126 uint32_t MinigbmGralloc::getFormatDrmFourcc(const native_handle_t* handle) {
127 return ((cros_gralloc_handle*)handle)->format;
128 }
129
getFormatDrmFourcc(const AHardwareBuffer * ahb)130 uint32_t MinigbmGralloc::getFormatDrmFourcc(const AHardwareBuffer* ahb) {
131 const native_handle_t* handle = AHardwareBuffer_getNativeHandle(ahb);
132 return getFormatDrmFourcc(handle);
133 }
134
getWidth(const AHardwareBuffer * ahb)135 uint32_t MinigbmGralloc::getWidth(const AHardwareBuffer* ahb) {
136 AHardwareBuffer_Desc desc = {};
137 AHardwareBuffer_describe(ahb, &desc);
138 return desc.width;
139 }
140
getHeight(const AHardwareBuffer * ahb)141 uint32_t MinigbmGralloc::getHeight(const AHardwareBuffer* ahb) {
142 AHardwareBuffer_Desc desc = {};
143 AHardwareBuffer_describe(ahb, &desc);
144 return desc.height;
145 }
146
getAllocatedSize(const native_handle_t * handle)147 size_t MinigbmGralloc::getAllocatedSize(const native_handle_t* handle) {
148 cros_gralloc_handle const* cros_handle = reinterpret_cast<cros_gralloc_handle const*>(handle);
149 struct VirtGpuExternalHandle hnd = {
150 .osHandle = dup(cros_handle->fds[0]),
151 .type = kMemHandleDmabuf,
152 };
153
154 auto resource = mDevice->importBlob(hnd);
155 if (!resource) {
156 return 0;
157 }
158
159 if (resource->wait()) {
160 return 0;
161 }
162
163 return resource->getSize();
164 }
165
getAllocatedSize(const AHardwareBuffer * ahb)166 size_t MinigbmGralloc::getAllocatedSize(const AHardwareBuffer* ahb) {
167 const native_handle_t* handle = AHardwareBuffer_getNativeHandle(ahb);
168 return getAllocatedSize(handle);
169 }
170
getId(const AHardwareBuffer * ahb,uint64_t * id)171 int MinigbmGralloc::getId(const AHardwareBuffer* ahb, uint64_t* id) {
172 #if ANDROID_API_LEVEL >= 31
173 return AHardwareBuffer_getId(ahb, id);
174 #else
175 (void)ahb;
176 *id = 0;
177 return 0;
178 #endif
179 }
180
getDataspace(const AHardwareBuffer * ahb)181 int32_t MinigbmGralloc::getDataspace(const AHardwareBuffer* ahb) {
182 #if ANDROID_API_LEVEL >= 34
183 return AHardwareBuffer_getDataSpace(ahb);
184 #else
185 (void)ahb;
186 return GFXSTREAM_AHB_DATASPACE_UNKNOWN;
187 #endif
188 }
189
190 } // namespace gfxstream
191