1 // Copyright 2021 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 //#define LOG_NDEBUG 0
6 #define LOG_TAG "DrmGrallocHelper"
7 
8 #include <v4l2_codec2/plugin_store/DrmGrallocHelpers.h>
9 
10 #include <fcntl.h>
11 #include <string.h>
12 
13 #include <drm/drm.h>
14 #include <log/log.h>
15 
16 namespace android {
17 
openRenderFd()18 std::optional<int> openRenderFd() {
19     const char kVirglName[] = "virtio_gpu";
20 
21     for (uint32_t i = 128; i < 192; i++) {
22         char devName[32];
23         snprintf(devName, sizeof(devName), "/dev/dri/renderD%d", i);
24 
25         int fd = open(devName, O_RDWR | O_CLOEXEC);
26         if (fd < 0) {
27             continue;
28         }
29 
30         char name[32];
31         struct drm_version v;
32         memset(&v, 0, sizeof(v));
33         v.name = name;
34         v.name_len = sizeof(name);
35 
36         if (ioctl(fd, static_cast<int>(DRM_IOCTL_VERSION), &v)) {
37             close(fd);
38             continue;
39         }
40         if (v.name_len != sizeof(kVirglName) - 1 || memcmp(name, kVirglName, v.name_len)) {
41             close(fd);
42             continue;
43         }
44         return fd;
45     }
46     return std::nullopt;
47 }
48 
getDrmHandle(int renderFd,int primeFd)49 std::optional<uint32_t> getDrmHandle(int renderFd, int primeFd) {
50     ALOGV("%s(renderFd=%d, primeFd=%u)", __func__, renderFd, primeFd);
51 
52     struct drm_prime_handle prime;
53     memset(&prime, 0, sizeof(prime));
54     prime.fd = primeFd;
55 
56     if (ioctl(renderFd, static_cast<int>(DRM_IOCTL_PRIME_FD_TO_HANDLE), &prime)) {
57         ALOGE("Can't translate prime fd %d to handle", prime.fd);
58         return std::nullopt;
59     }
60     return prime.handle;
61 }
62 
closeDrmHandle(int renderFd,uint32_t handle)63 void closeDrmHandle(int renderFd, uint32_t handle) {
64     ALOGV("%s(renderFd=%d, handle=%u)", __func__, renderFd, handle);
65 
66     struct drm_gem_close gem;
67     memset(&gem, 0, sizeof(gem));
68     gem.handle = handle;
69 
70     ioctl(renderFd, DRM_IOCTL_GEM_CLOSE, &gem);
71 }
72 
73 }  // namespace android
74