blob: 8c1adba5553efae6048c8350b283767a08ad0b54 [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"
Sean Paulda6270d2015-06-01 14:11:52 -040020
Sean Paulda6270d2015-06-01 14:11:52 -040021#include <xf86drm.h>
22#include <xf86drmMode.h>
23
Mykhailo Sopiha1693bc32019-07-08 18:28:56 +030024#include <cutils/properties.h>
John Stultzd12274d2018-04-02 20:57:21 -070025#include <gralloc_handle.h>
Sean Paulda6270d2015-06-01 14:11:52 -040026#include <hardware/gralloc.h>
Sean Paulf72cccd2018-08-27 13:59:08 -040027#include <log/log.h>
Sean Paulda6270d2015-06-01 14:11:52 -040028
29namespace android {
30
Roman Stratiienko42c7f0c2020-08-29 22:28:07 +030031DrmGenericImporter::DrmGenericImporter(DrmDevice *drm) : drm_(drm) {
Sean Paulda6270d2015-06-01 14:11:52 -040032}
33
34DrmGenericImporter::~DrmGenericImporter() {
35}
36
37int DrmGenericImporter::Init() {
38 int ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID,
39 (const hw_module_t **)&gralloc_);
40 if (ret) {
41 ALOGE("Failed to open gralloc module");
42 return ret;
43 }
Mykhailo Sopihaad438862019-06-06 14:45:27 +030044
45 ALOGI("Using %s gralloc module: %s\n", gralloc_->common.name,
46 gralloc_->common.author);
47
Sean Paulda6270d2015-06-01 14:11:52 -040048 return 0;
49}
50
51uint32_t DrmGenericImporter::ConvertHalFormatToDrm(uint32_t hal_format) {
52 switch (hal_format) {
53 case HAL_PIXEL_FORMAT_RGB_888:
54 return DRM_FORMAT_BGR888;
55 case HAL_PIXEL_FORMAT_BGRA_8888:
56 return DRM_FORMAT_ARGB8888;
57 case HAL_PIXEL_FORMAT_RGBX_8888:
58 return DRM_FORMAT_XBGR8888;
59 case HAL_PIXEL_FORMAT_RGBA_8888:
60 return DRM_FORMAT_ABGR8888;
61 case HAL_PIXEL_FORMAT_RGB_565:
62 return DRM_FORMAT_BGR565;
63 case HAL_PIXEL_FORMAT_YV12:
64 return DRM_FORMAT_YVU420;
65 default:
66 ALOGE("Cannot convert hal format to drm format %u", hal_format);
Roman Stratiienkof63726c2019-11-06 15:03:12 +020067 return DRM_FORMAT_INVALID;
Sean Paulda6270d2015-06-01 14:11:52 -040068 }
69}
70
John Stultza4514832018-08-24 16:27:36 -070071uint32_t DrmGenericImporter::DrmFormatToBitsPerPixel(uint32_t drm_format) {
72 switch (drm_format) {
73 case DRM_FORMAT_ARGB8888:
74 case DRM_FORMAT_XBGR8888:
75 case DRM_FORMAT_ABGR8888:
76 return 32;
77 case DRM_FORMAT_BGR888:
78 return 24;
79 case DRM_FORMAT_BGR565:
80 return 16;
81 case DRM_FORMAT_YVU420:
82 return 12;
83 default:
84 ALOGE("Cannot convert hal format %u to bpp (returning 32)", drm_format);
85 return 32;
86 }
87}
88
Roman Stratiienko4163efc2019-12-06 12:30:28 +020089int DrmGenericImporter::ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) {
90 memset(bo, 0, sizeof(hwc_drm_bo_t));
91
92 int ret = ConvertBoInfo(handle, bo);
93 if (ret)
94 return ret;
95
96 ret = drmPrimeFDToHandle(drm_->fd(), bo->prime_fds[0], &bo->gem_handles[0]);
97 if (ret) {
98 ALOGE("failed to import prime fd %d ret=%d", bo->prime_fds[0], ret);
99 return ret;
100 }
101
102 for (int i = 1; i < HWC_DRM_BO_MAX_PLANES; i++) {
103 int fd = bo->prime_fds[i];
104 if (fd != 0) {
105 if (fd != bo->prime_fds[0]) {
106 ALOGE("Multiplanar FBs are not supported by this version of composer");
107 return -ENOTSUP;
108 }
109 bo->gem_handles[i] = bo->gem_handles[0];
110 }
111 }
112
113 if (!bo->with_modifiers)
114 ret = drmModeAddFB2(drm_->fd(), bo->width, bo->height, bo->format,
115 bo->gem_handles, bo->pitches, bo->offsets, &bo->fb_id,
116 0);
117 else
118 ret = drmModeAddFB2WithModifiers(drm_->fd(), bo->width, bo->height,
119 bo->format, bo->gem_handles, bo->pitches,
120 bo->offsets, bo->modifiers, &bo->fb_id,
121 bo->modifiers[0] ? DRM_MODE_FB_MODIFIERS
122 : 0);
123
Sean Paulda6270d2015-06-01 14:11:52 -0400124 if (ret) {
125 ALOGE("could not create drm fb %d", ret);
126 return ret;
127 }
128
Roman Stratiienko4163efc2019-12-06 12:30:28 +0200129 ImportHandle(bo->gem_handles[0]);
Vincent Donnefortf67c3652019-08-02 11:18:35 +0100130
Sean Paulda6270d2015-06-01 14:11:52 -0400131 return ret;
132}
133
134int DrmGenericImporter::ReleaseBuffer(hwc_drm_bo_t *bo) {
135 if (bo->fb_id)
136 if (drmModeRmFB(drm_->fd(), bo->fb_id))
137 ALOGE("Failed to rm fb");
138
John Stultzee18b0e2018-08-27 10:53:07 -0700139 for (int i = 0; i < HWC_DRM_BO_MAX_PLANES; i++) {
Sean Paulda6270d2015-06-01 14:11:52 -0400140 if (!bo->gem_handles[i])
141 continue;
142
Vincent Donnefortf67c3652019-08-02 11:18:35 +0100143 if (ReleaseHandle(bo->gem_handles[i])) {
144 ALOGE("Failed to release gem handle %d", bo->gem_handles[i]);
John Stultz53cb4ef2018-05-31 17:46:50 -0700145 } else {
John Stultzee18b0e2018-08-27 10:53:07 -0700146 for (int j = i + 1; j < HWC_DRM_BO_MAX_PLANES; j++)
John Stultz53cb4ef2018-05-31 17:46:50 -0700147 if (bo->gem_handles[j] == bo->gem_handles[i])
148 bo->gem_handles[j] = 0;
Sean Paulda6270d2015-06-01 14:11:52 -0400149 bo->gem_handles[i] = 0;
John Stultz53cb4ef2018-05-31 17:46:50 -0700150 }
Sean Paulda6270d2015-06-01 14:11:52 -0400151 }
152 return 0;
153}
Sean Paul4c4646e2016-05-10 04:19:24 -0400154
Alexey Firago18ec6882018-11-21 23:47:05 +0300155bool DrmGenericImporter::CanImportBuffer(buffer_handle_t handle) {
Roman Stratiienko4163efc2019-12-06 12:30:28 +0200156 hwc_drm_bo_t bo;
157
158 int ret = ConvertBoInfo(handle, &bo);
159 if (ret)
Alexey Firago18ec6882018-11-21 23:47:05 +0300160 return false;
Mykhailo Sopiha1693bc32019-07-08 18:28:56 +0300161
Roman Stratiienko4163efc2019-12-06 12:30:28 +0200162 if (bo.prime_fds[0] == 0)
163 return false;
164
Alexey Firago18ec6882018-11-21 23:47:05 +0300165 return true;
166}
167
Alexandru Gheorghe0f5abd72018-05-01 14:37:10 +0100168std::unique_ptr<Planner> Planner::CreateInstance(DrmDevice *) {
Sean Paul4c4646e2016-05-10 04:19:24 -0400169 std::unique_ptr<Planner> planner(new Planner);
170 planner->AddStage<PlanStageGreedy>();
171 return planner;
172}
Vincent Donnefortf67c3652019-08-02 11:18:35 +0100173
174int DrmGenericImporter::ImportHandle(uint32_t gem_handle) {
175 gem_refcount_[gem_handle]++;
176
177 return 0;
178}
179
180int DrmGenericImporter::ReleaseHandle(uint32_t gem_handle) {
181 if (--gem_refcount_[gem_handle])
182 return 0;
183
184 gem_refcount_.erase(gem_handle);
185
186 return CloseHandle(gem_handle);
187}
188
189int DrmGenericImporter::CloseHandle(uint32_t gem_handle) {
190 struct drm_gem_close gem_close;
191
192 memset(&gem_close, 0, sizeof(gem_close));
193
194 gem_close.handle = gem_handle;
195 int ret = drmIoctl(drm_->fd(), DRM_IOCTL_GEM_CLOSE, &gem_close);
196 if (ret)
197 ALOGE("Failed to close gem handle %d %d", gem_handle, ret);
198
199 return ret;
200}
Sean Paulda6270d2015-06-01 14:11:52 -0400201}