blob: 2fcbe40dd8e53e941f251a7d15a705191de4103f [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
23#include <drm/drm_fourcc.h>
24#include <xf86drm.h>
25#include <xf86drmMode.h>
26
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
Alexandru Gheorghe0f5abd72018-05-01 14:37:10 +010050DrmGenericImporter::DrmGenericImporter(DrmDevice *drm) : drm_(drm) {
Sean Paulda6270d2015-06-01 14:11:52 -040051}
52
53DrmGenericImporter::~DrmGenericImporter() {
54}
55
56int DrmGenericImporter::Init() {
57 int ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID,
58 (const hw_module_t **)&gralloc_);
59 if (ret) {
60 ALOGE("Failed to open gralloc module");
61 return ret;
62 }
Mykhailo Sopihaad438862019-06-06 14:45:27 +030063
64 ALOGI("Using %s gralloc module: %s\n", gralloc_->common.name,
65 gralloc_->common.author);
66
Sean Paulda6270d2015-06-01 14:11:52 -040067 return 0;
68}
69
70uint32_t DrmGenericImporter::ConvertHalFormatToDrm(uint32_t hal_format) {
71 switch (hal_format) {
72 case HAL_PIXEL_FORMAT_RGB_888:
73 return DRM_FORMAT_BGR888;
74 case HAL_PIXEL_FORMAT_BGRA_8888:
75 return DRM_FORMAT_ARGB8888;
76 case HAL_PIXEL_FORMAT_RGBX_8888:
77 return DRM_FORMAT_XBGR8888;
78 case HAL_PIXEL_FORMAT_RGBA_8888:
79 return DRM_FORMAT_ABGR8888;
80 case HAL_PIXEL_FORMAT_RGB_565:
81 return DRM_FORMAT_BGR565;
82 case HAL_PIXEL_FORMAT_YV12:
83 return DRM_FORMAT_YVU420;
84 default:
85 ALOGE("Cannot convert hal format to drm format %u", hal_format);
86 return -EINVAL;
87 }
88}
89
John Stultza4514832018-08-24 16:27:36 -070090uint32_t DrmGenericImporter::DrmFormatToBitsPerPixel(uint32_t drm_format) {
91 switch (drm_format) {
92 case DRM_FORMAT_ARGB8888:
93 case DRM_FORMAT_XBGR8888:
94 case DRM_FORMAT_ABGR8888:
95 return 32;
96 case DRM_FORMAT_BGR888:
97 return 24;
98 case DRM_FORMAT_BGR565:
99 return 16;
100 case DRM_FORMAT_YVU420:
101 return 12;
102 default:
103 ALOGE("Cannot convert hal format %u to bpp (returning 32)", drm_format);
104 return 32;
105 }
106}
107
Sean Paulda6270d2015-06-01 14:11:52 -0400108int DrmGenericImporter::ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) {
John Stultzd12274d2018-04-02 20:57:21 -0700109 gralloc_handle_t *gr_handle = gralloc_handle(handle);
Sean Paulda6270d2015-06-01 14:11:52 -0400110 if (!gr_handle)
111 return -EINVAL;
112
Sean Paulda6270d2015-06-01 14:11:52 -0400113 uint32_t gem_handle;
114 int ret = drmPrimeFDToHandle(drm_->fd(), gr_handle->prime_fd, &gem_handle);
115 if (ret) {
116 ALOGE("failed to import prime fd %d ret=%d", gr_handle->prime_fd, ret);
117 return ret;
118 }
119
120 memset(bo, 0, sizeof(hwc_drm_bo_t));
121 bo->width = gr_handle->width;
122 bo->height = gr_handle->height;
John Stultz616fb222018-08-24 16:08:57 -0700123 bo->hal_format = gr_handle->format;
Sean Paulda6270d2015-06-01 14:11:52 -0400124 bo->format = ConvertHalFormatToDrm(gr_handle->format);
Rob Herringaeccd892017-10-06 17:20:05 -0500125 bo->usage = gr_handle->usage;
John Stultza4514832018-08-24 16:27:36 -0700126 bo->pixel_stride = (gr_handle->stride * 8) /
127 DrmFormatToBitsPerPixel(bo->format);
Sean Paulda6270d2015-06-01 14:11:52 -0400128 bo->pitches[0] = gr_handle->stride;
129 bo->gem_handles[0] = gem_handle;
130 bo->offsets[0] = 0;
131
132 ret = drmModeAddFB2(drm_->fd(), bo->width, bo->height, bo->format,
133 bo->gem_handles, bo->pitches, bo->offsets, &bo->fb_id, 0);
134 if (ret) {
135 ALOGE("could not create drm fb %d", ret);
136 return ret;
137 }
138
139 return ret;
140}
141
142int DrmGenericImporter::ReleaseBuffer(hwc_drm_bo_t *bo) {
143 if (bo->fb_id)
144 if (drmModeRmFB(drm_->fd(), bo->fb_id))
145 ALOGE("Failed to rm fb");
146
147 struct drm_gem_close gem_close;
148 memset(&gem_close, 0, sizeof(gem_close));
John Stultzee18b0e2018-08-27 10:53:07 -0700149
150 for (int i = 0; i < HWC_DRM_BO_MAX_PLANES; i++) {
Sean Paulda6270d2015-06-01 14:11:52 -0400151 if (!bo->gem_handles[i])
152 continue;
153
154 gem_close.handle = bo->gem_handles[i];
155 int ret = drmIoctl(drm_->fd(), DRM_IOCTL_GEM_CLOSE, &gem_close);
John Stultz53cb4ef2018-05-31 17:46:50 -0700156 if (ret) {
Sean Paulda6270d2015-06-01 14:11:52 -0400157 ALOGE("Failed to close gem handle %d %d", i, ret);
John Stultz53cb4ef2018-05-31 17:46:50 -0700158 } else {
John Stultzee18b0e2018-08-27 10:53:07 -0700159 for (int j = i + 1; j < HWC_DRM_BO_MAX_PLANES; j++)
John Stultz53cb4ef2018-05-31 17:46:50 -0700160 if (bo->gem_handles[j] == bo->gem_handles[i])
161 bo->gem_handles[j] = 0;
Sean Paulda6270d2015-06-01 14:11:52 -0400162 bo->gem_handles[i] = 0;
John Stultz53cb4ef2018-05-31 17:46:50 -0700163 }
Sean Paulda6270d2015-06-01 14:11:52 -0400164 }
165 return 0;
166}
Sean Paul4c4646e2016-05-10 04:19:24 -0400167
Alexey Firago18ec6882018-11-21 23:47:05 +0300168bool DrmGenericImporter::CanImportBuffer(buffer_handle_t handle) {
169 if (handle == NULL)
170 return false;
171 return true;
172}
173
Sean Paul4c4646e2016-05-10 04:19:24 -0400174#ifdef USE_DRM_GENERIC_IMPORTER
Alexandru Gheorghe0f5abd72018-05-01 14:37:10 +0100175std::unique_ptr<Planner> Planner::CreateInstance(DrmDevice *) {
Sean Paul4c4646e2016-05-10 04:19:24 -0400176 std::unique_ptr<Planner> planner(new Planner);
177 planner->AddStage<PlanStageGreedy>();
178 return planner;
179}
180#endif
Sean Paulda6270d2015-06-01 14:11:52 -0400181}