• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include <inttypes.h>
17 #include <android-base/parseint.h>
18 #include <android-base/properties.h>
19 #include <android-base/strings.h>
20 #include <log/log.h>
21 #include <gralloc_cb_bp.h>
22 #include <drm/virtgpu_drm.h>
23 #include <xf86drm.h>
24 
25 #include "cros_gralloc_handle.h"
26 
isMinigbmFromProperty()27 static bool isMinigbmFromProperty() {
28   static constexpr const auto kGrallocProp = "ro.hardware.gralloc";
29 
30   const auto grallocProp = android::base::GetProperty(kGrallocProp, "");
31   ALOGD("%s:codecs: minigbm query prop value is: %s", __FUNCTION__, grallocProp.c_str());
32 
33   if (grallocProp == "minigbm") {
34     ALOGD("%s:codecs: Using minigbm, in minigbm mode.\n", __FUNCTION__);
35     return true;
36   } else {
37     ALOGD("%s:codecs: Is not using minigbm, in goldfish mode.\n", __FUNCTION__);
38     return false;
39   }
40 }
41 
42 class ColorBufferUtilsGlobalState {
43 public:
ColorBufferUtilsGlobalState()44     ColorBufferUtilsGlobalState() {
45         m_isMinigbm = isMinigbmFromProperty();
46 
47         if (m_isMinigbm) {
48             static constexpr int kRendernodeMinor = 128;
49             m_rendernodeFd = drmOpenRender(kRendernodeMinor);
50         }
51     }
52 
getColorBufferHandle(native_handle_t const * handle)53     uint32_t getColorBufferHandle(native_handle_t const* handle) {
54         if (m_isMinigbm) {
55             struct drm_virtgpu_resource_info info;
56             if (!getResInfo(handle, &info)) {
57                 ALOGE("%s: Error gtting color buffer handle (minigbm case)", __func__);
58                 return -1;
59             }
60             return info.res_handle;
61         } else {
62             return cb_handle_t::from(handle)->hostHandle;
63         }
64     }
65 
66 private:
67 
getResInfo(native_handle_t const * handle,struct drm_virtgpu_resource_info * info)68     bool getResInfo(native_handle_t const* handle,
69                     struct drm_virtgpu_resource_info* info) {
70         memset(info, 0x0, sizeof(*info));
71         if (m_rendernodeFd < 0) {
72             ALOGE("%s: Error, rendernode fd missing\n", __func__);
73             return false;
74         }
75 
76         struct drm_gem_close gem_close;
77         memset(&gem_close, 0x0, sizeof(gem_close));
78 
79         cros_gralloc_handle const* cros_handle =
80             reinterpret_cast<cros_gralloc_handle const*>(handle);
81 
82         uint32_t prime_handle;
83         int ret = drmPrimeFDToHandle(m_rendernodeFd, cros_handle->fds[0], &prime_handle);
84         if (ret) {
85             ALOGE("%s: DRM_IOCTL_PRIME_FD_TO_HANDLE failed: %s (errno %d)\n",
86                   __func__, strerror(errno), errno);
87             return false;
88         }
89 
90         info->bo_handle = prime_handle;
91         gem_close.handle = prime_handle;
92 
93         ret = drmIoctl(m_rendernodeFd, DRM_IOCTL_VIRTGPU_RESOURCE_INFO, info);
94         if (ret) {
95             ALOGE("%s: DRM_IOCTL_VIRTGPU_RESOURCE_INFO failed: %s (errno %d)\n",
96                   __func__, strerror(errno), errno);
97             drmIoctl(m_rendernodeFd, DRM_IOCTL_GEM_CLOSE, &gem_close);
98             return false;
99         }
100 
101         drmIoctl(m_rendernodeFd, DRM_IOCTL_GEM_CLOSE, &gem_close);
102         return true;
103     }
104 
105     bool m_isMinigbm;
106     int m_rendernodeFd = -1; // to be closed when this process dies
107 };
108 
getGlobals()109 static ColorBufferUtilsGlobalState* getGlobals() {
110     static ColorBufferUtilsGlobalState* globals = new ColorBufferUtilsGlobalState;
111     return globals;
112 }
113 
getColorBufferHandle(native_handle_t const * handle)114 uint32_t getColorBufferHandle(native_handle_t const* handle) {
115     return getGlobals()->getColorBufferHandle(handle);
116 }
117