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