blob: bc28dd5a062ebe3c0135efdc55cc612d45b2187f [file] [log] [blame]
Sean Paulda6270d2015-06-01 14:11:52 -04001/*
2 * Copyright (C) 2015 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
Sean Paul0aee6b22016-05-10 04:08:10 -040017#define LOG_TAG "hwc-platform-drm-generic"
Sean Paulda6270d2015-06-01 14:11:52 -040018
Sean Paulf72cccd2018-08-27 13:59:08 -040019#include "platformdrmgeneric.h"
Alexandru Gheorghe0f5abd72018-05-01 14:37:10 +010020#include "drmdevice.h"
Sean Paul63769962016-04-21 16:25:06 -040021#include "platform.h"
Sean Paulda6270d2015-06-01 14:11:52 -040022
Sean Paulda6270d2015-06-01 14:11:52 -040023#include <xf86drm.h>
24#include <xf86drmMode.h>
25
Mykhailo Sopiha1693bc32019-07-08 18:28:56 +030026#include <cutils/properties.h>
John Stultzd12274d2018-04-02 20:57:21 -070027#include <gralloc_handle.h>
Sean Paulda6270d2015-06-01 14:11:52 -040028#include <hardware/gralloc.h>
Sean Paulf72cccd2018-08-27 13:59:08 -040029#include <log/log.h>
Sean Paulda6270d2015-06-01 14:11:52 -040030
31namespace android {
32
33#ifdef USE_DRM_GENERIC_IMPORTER
34// static
Alexandru Gheorghe0f5abd72018-05-01 14:37:10 +010035Importer *Importer::CreateInstance(DrmDevice *drm) {
Sean Paulda6270d2015-06-01 14:11:52 -040036 DrmGenericImporter *importer = new DrmGenericImporter(drm);
37 if (!importer)
38 return NULL;
39
40 int ret = importer->Init();
41 if (ret) {
42 ALOGE("Failed to initialize the nv importer %d", ret);
43 delete importer;
44 return NULL;
45 }
46 return importer;
47}
48#endif
49
Mykhailo Sopiha1693bc32019-07-08 18:28:56 +030050DrmGenericImporter::DrmGenericImporter(DrmDevice *drm)
51 : drm_(drm), exclude_non_hwfb_(false) {
Sean Paulda6270d2015-06-01 14:11:52 -040052}
53
54DrmGenericImporter::~DrmGenericImporter() {
55}
56
57int DrmGenericImporter::Init() {
58 int ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID,
59 (const hw_module_t **)&gralloc_);
60 if (ret) {
61 ALOGE("Failed to open gralloc module");
62 return ret;
63 }
Mykhailo Sopihaad438862019-06-06 14:45:27 +030064
65 ALOGI("Using %s gralloc module: %s\n", gralloc_->common.name,
66 gralloc_->common.author);
67
Mykhailo Sopiha1693bc32019-07-08 18:28:56 +030068 char exclude_non_hwfb_prop[PROPERTY_VALUE_MAX];
Jason Macnakf1af9572020-08-20 11:49:51 -070069 property_get("vendor.hwc.drm.exclude_non_hwfb_imports", exclude_non_hwfb_prop,
70 "0");
Mykhailo Sopiha1693bc32019-07-08 18:28:56 +030071 exclude_non_hwfb_ = static_cast<bool>(strncmp(exclude_non_hwfb_prop, "0", 1));
72
Sean Paulda6270d2015-06-01 14:11:52 -040073 return 0;
74}
75
76uint32_t DrmGenericImporter::ConvertHalFormatToDrm(uint32_t hal_format) {
77 switch (hal_format) {
78 case HAL_PIXEL_FORMAT_RGB_888:
79 return DRM_FORMAT_BGR888;
80 case HAL_PIXEL_FORMAT_BGRA_8888:
81 return DRM_FORMAT_ARGB8888;
82 case HAL_PIXEL_FORMAT_RGBX_8888:
83 return DRM_FORMAT_XBGR8888;
84 case HAL_PIXEL_FORMAT_RGBA_8888:
85 return DRM_FORMAT_ABGR8888;
86 case HAL_PIXEL_FORMAT_RGB_565:
87 return DRM_FORMAT_BGR565;
88 case HAL_PIXEL_FORMAT_YV12:
89 return DRM_FORMAT_YVU420;
90 default:
91 ALOGE("Cannot convert hal format to drm format %u", hal_format);
Roman Stratiienkof63726c2019-11-06 15:03:12 +020092 return DRM_FORMAT_INVALID;
Sean Paulda6270d2015-06-01 14:11:52 -040093 }
94}
95
John Stultza4514832018-08-24 16:27:36 -070096uint32_t DrmGenericImporter::DrmFormatToBitsPerPixel(uint32_t drm_format) {
97 switch (drm_format) {
98 case DRM_FORMAT_ARGB8888:
99 case DRM_FORMAT_XBGR8888:
100 case DRM_FORMAT_ABGR8888:
101 return 32;
102 case DRM_FORMAT_BGR888:
103 return 24;
104 case DRM_FORMAT_BGR565:
105 return 16;
106 case DRM_FORMAT_YVU420:
107 return 12;
108 default:
109 ALOGE("Cannot convert hal format %u to bpp (returning 32)", drm_format);
110 return 32;
111 }
112}
113
Roman Stratiienko4163efc2019-12-06 12:30:28 +0200114int DrmGenericImporter::ConvertBoInfo(buffer_handle_t handle,
115 hwc_drm_bo_t *bo) {
John Stultzd12274d2018-04-02 20:57:21 -0700116 gralloc_handle_t *gr_handle = gralloc_handle(handle);
Sean Paulda6270d2015-06-01 14:11:52 -0400117 if (!gr_handle)
118 return -EINVAL;
119
Sean Paulda6270d2015-06-01 14:11:52 -0400120 bo->width = gr_handle->width;
121 bo->height = gr_handle->height;
John Stultz616fb222018-08-24 16:08:57 -0700122 bo->hal_format = gr_handle->format;
Sean Paulda6270d2015-06-01 14:11:52 -0400123 bo->format = ConvertHalFormatToDrm(gr_handle->format);
Roman Stratiienkof63726c2019-11-06 15:03:12 +0200124 if (bo->format == DRM_FORMAT_INVALID)
125 return -EINVAL;
Rob Herringaeccd892017-10-06 17:20:05 -0500126 bo->usage = gr_handle->usage;
John Stultza4514832018-08-24 16:27:36 -0700127 bo->pixel_stride = (gr_handle->stride * 8) /
128 DrmFormatToBitsPerPixel(bo->format);
Roman Stratiienko4163efc2019-12-06 12:30:28 +0200129 bo->prime_fds[0] = gr_handle->prime_fd;
Sean Paulda6270d2015-06-01 14:11:52 -0400130 bo->pitches[0] = gr_handle->stride;
Sean Paulda6270d2015-06-01 14:11:52 -0400131 bo->offsets[0] = 0;
132
Roman Stratiienko4163efc2019-12-06 12:30:28 +0200133 return 0;
134}
135
136int DrmGenericImporter::ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) {
137 memset(bo, 0, sizeof(hwc_drm_bo_t));
138
139 int ret = ConvertBoInfo(handle, bo);
140 if (ret)
141 return ret;
142
143 ret = drmPrimeFDToHandle(drm_->fd(), bo->prime_fds[0], &bo->gem_handles[0]);
144 if (ret) {
145 ALOGE("failed to import prime fd %d ret=%d", bo->prime_fds[0], ret);
146 return ret;
147 }
148
149 for (int i = 1; i < HWC_DRM_BO_MAX_PLANES; i++) {
150 int fd = bo->prime_fds[i];
151 if (fd != 0) {
152 if (fd != bo->prime_fds[0]) {
153 ALOGE("Multiplanar FBs are not supported by this version of composer");
154 return -ENOTSUP;
155 }
156 bo->gem_handles[i] = bo->gem_handles[0];
157 }
158 }
159
160 if (!bo->with_modifiers)
161 ret = drmModeAddFB2(drm_->fd(), bo->width, bo->height, bo->format,
162 bo->gem_handles, bo->pitches, bo->offsets, &bo->fb_id,
163 0);
164 else
165 ret = drmModeAddFB2WithModifiers(drm_->fd(), bo->width, bo->height,
166 bo->format, bo->gem_handles, bo->pitches,
167 bo->offsets, bo->modifiers, &bo->fb_id,
168 bo->modifiers[0] ? DRM_MODE_FB_MODIFIERS
169 : 0);
170
Sean Paulda6270d2015-06-01 14:11:52 -0400171 if (ret) {
172 ALOGE("could not create drm fb %d", ret);
173 return ret;
174 }
175
Roman Stratiienko4163efc2019-12-06 12:30:28 +0200176 ImportHandle(bo->gem_handles[0]);
Vincent Donnefortf67c3652019-08-02 11:18:35 +0100177
Sean Paulda6270d2015-06-01 14:11:52 -0400178 return ret;
179}
180
181int DrmGenericImporter::ReleaseBuffer(hwc_drm_bo_t *bo) {
182 if (bo->fb_id)
183 if (drmModeRmFB(drm_->fd(), bo->fb_id))
184 ALOGE("Failed to rm fb");
185
John Stultzee18b0e2018-08-27 10:53:07 -0700186 for (int i = 0; i < HWC_DRM_BO_MAX_PLANES; i++) {
Sean Paulda6270d2015-06-01 14:11:52 -0400187 if (!bo->gem_handles[i])
188 continue;
189
Vincent Donnefortf67c3652019-08-02 11:18:35 +0100190 if (ReleaseHandle(bo->gem_handles[i])) {
191 ALOGE("Failed to release gem handle %d", bo->gem_handles[i]);
John Stultz53cb4ef2018-05-31 17:46:50 -0700192 } else {
John Stultzee18b0e2018-08-27 10:53:07 -0700193 for (int j = i + 1; j < HWC_DRM_BO_MAX_PLANES; j++)
John Stultz53cb4ef2018-05-31 17:46:50 -0700194 if (bo->gem_handles[j] == bo->gem_handles[i])
195 bo->gem_handles[j] = 0;
Sean Paulda6270d2015-06-01 14:11:52 -0400196 bo->gem_handles[i] = 0;
John Stultz53cb4ef2018-05-31 17:46:50 -0700197 }
Sean Paulda6270d2015-06-01 14:11:52 -0400198 }
199 return 0;
200}
Sean Paul4c4646e2016-05-10 04:19:24 -0400201
Alexey Firago18ec6882018-11-21 23:47:05 +0300202bool DrmGenericImporter::CanImportBuffer(buffer_handle_t handle) {
Roman Stratiienko4163efc2019-12-06 12:30:28 +0200203 hwc_drm_bo_t bo;
204
205 int ret = ConvertBoInfo(handle, &bo);
206 if (ret)
Alexey Firago18ec6882018-11-21 23:47:05 +0300207 return false;
Mykhailo Sopiha1693bc32019-07-08 18:28:56 +0300208
Roman Stratiienko4163efc2019-12-06 12:30:28 +0200209 if (bo.prime_fds[0] == 0)
210 return false;
211
212 if (exclude_non_hwfb_ && !(bo.usage & GRALLOC_USAGE_HW_FB))
213 return false;
Mykhailo Sopiha1693bc32019-07-08 18:28:56 +0300214
Alexey Firago18ec6882018-11-21 23:47:05 +0300215 return true;
216}
217
Sean Paul4c4646e2016-05-10 04:19:24 -0400218#ifdef USE_DRM_GENERIC_IMPORTER
Alexandru Gheorghe0f5abd72018-05-01 14:37:10 +0100219std::unique_ptr<Planner> Planner::CreateInstance(DrmDevice *) {
Sean Paul4c4646e2016-05-10 04:19:24 -0400220 std::unique_ptr<Planner> planner(new Planner);
221 planner->AddStage<PlanStageGreedy>();
222 return planner;
223}
224#endif
Vincent Donnefortf67c3652019-08-02 11:18:35 +0100225
226int DrmGenericImporter::ImportHandle(uint32_t gem_handle) {
227 gem_refcount_[gem_handle]++;
228
229 return 0;
230}
231
232int DrmGenericImporter::ReleaseHandle(uint32_t gem_handle) {
233 if (--gem_refcount_[gem_handle])
234 return 0;
235
236 gem_refcount_.erase(gem_handle);
237
238 return CloseHandle(gem_handle);
239}
240
241int DrmGenericImporter::CloseHandle(uint32_t gem_handle) {
242 struct drm_gem_close gem_close;
243
244 memset(&gem_close, 0, sizeof(gem_close));
245
246 gem_close.handle = gem_handle;
247 int ret = drmIoctl(drm_->fd(), DRM_IOCTL_GEM_CLOSE, &gem_close);
248 if (ret)
249 ALOGE("Failed to close gem handle %d %d", gem_handle, ret);
250
251 return ret;
252}
Sean Paulda6270d2015-06-01 14:11:52 -0400253}