blob: b4dc0631172d2d7b40d5e74e328ce4700c82d897 [file] [log] [blame]
Roman Stratiienkob2e9fe22020-10-03 10:52:36 +03001/*
2 * Copyright (C) 2020 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
17#define LOG_TAG "hwc-platform-drm-generic"
18
19#include "DrmGenericImporter.h"
20
21#include <cutils/properties.h>
22#include <gralloc_handle.h>
23#include <hardware/gralloc.h>
24#include <log/log.h>
25#include <xf86drm.h>
26#include <xf86drmMode.h>
27
28namespace android {
29
30DrmGenericImporter::DrmGenericImporter(DrmDevice *drm) : drm_(drm) {
31}
32
33DrmGenericImporter::~DrmGenericImporter() {
34}
35
36int DrmGenericImporter::ImportBuffer(hwc_drm_bo_t *bo) {
37 int ret = drmPrimeFDToHandle(drm_->fd(), bo->prime_fds[0],
38 &bo->gem_handles[0]);
39 if (ret) {
40 ALOGE("failed to import prime fd %d ret=%d", bo->prime_fds[0], ret);
41 return ret;
42 }
43
44 for (int i = 1; i < HWC_DRM_BO_MAX_PLANES; i++) {
45 int fd = bo->prime_fds[i];
46 if (fd != 0) {
47 if (fd != bo->prime_fds[0]) {
48 ALOGE("Multiplanar FBs are not supported by this version of composer");
49 return -ENOTSUP;
50 }
51 bo->gem_handles[i] = bo->gem_handles[0];
52 }
53 }
54
55 if (!bo->with_modifiers)
56 ret = drmModeAddFB2(drm_->fd(), bo->width, bo->height, bo->format,
57 bo->gem_handles, bo->pitches, bo->offsets, &bo->fb_id,
58 0);
59 else
60 ret = drmModeAddFB2WithModifiers(drm_->fd(), bo->width, bo->height,
61 bo->format, bo->gem_handles, bo->pitches,
62 bo->offsets, bo->modifiers, &bo->fb_id,
63 bo->modifiers[0] ? DRM_MODE_FB_MODIFIERS
64 : 0);
65
66 if (ret) {
67 ALOGE("could not create drm fb %d", ret);
68 return ret;
69 }
70
71 ImportHandle(bo->gem_handles[0]);
72
73 return ret;
74}
75
76int DrmGenericImporter::ReleaseBuffer(hwc_drm_bo_t *bo) {
77 if (bo->fb_id)
78 if (drmModeRmFB(drm_->fd(), bo->fb_id))
79 ALOGE("Failed to rm fb");
80
81 for (int i = 0; i < HWC_DRM_BO_MAX_PLANES; i++) {
82 if (!bo->gem_handles[i])
83 continue;
84
85 if (ReleaseHandle(bo->gem_handles[i])) {
86 ALOGE("Failed to release gem handle %d", bo->gem_handles[i]);
87 } else {
88 for (int j = i + 1; j < HWC_DRM_BO_MAX_PLANES; j++)
89 if (bo->gem_handles[j] == bo->gem_handles[i])
90 bo->gem_handles[j] = 0;
91 bo->gem_handles[i] = 0;
92 }
93 }
94 return 0;
95}
96
97int DrmGenericImporter::ImportHandle(uint32_t gem_handle) {
98 gem_refcount_[gem_handle]++;
99
100 return 0;
101}
102
103int DrmGenericImporter::ReleaseHandle(uint32_t gem_handle) {
104 if (--gem_refcount_[gem_handle])
105 return 0;
106
107 gem_refcount_.erase(gem_handle);
108
109 return CloseHandle(gem_handle);
110}
111
112int DrmGenericImporter::CloseHandle(uint32_t gem_handle) {
113 struct drm_gem_close gem_close;
114
115 memset(&gem_close, 0, sizeof(gem_close));
116
117 gem_close.handle = gem_handle;
118 int ret = drmIoctl(drm_->fd(), DRM_IOCTL_GEM_CLOSE, &gem_close);
119 if (ret)
120 ALOGE("Failed to close gem handle %d %d", gem_handle, ret);
121
122 return ret;
123}
124} // namespace android