• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "drm_allocator.h"
16 #include <cinttypes>
17 #include <cerrno>
18 #include <fcntl.h>
19 #include <securec.h>
20 #include <xf86drm.h>
21 #include <xf86drmMode.h>
22 #include "display_common.h"
23 #include "drm_fourcc.h"
24 #include "hisilicon_drm.h"
25 namespace OHOS {
26 namespace HDI {
27 namespace DISPLAY {
Init()28 int32_t DrmAllocator::Init()
29 {
30     DISPLAY_LOGD();
31     int32_t ret;
32     drmFd_ = open(FILE_PATH, O_RDWR);
33     DISPLAY_CHK_RETURN((drmFd_ < 0), DISPLAY_FAILURE,
34         DISPLAY_LOGE("can not open drm file : %{public}s errno: %{public}d ", FILE_PATH, errno));
35     ret = drmDropMaster(drmFd_);
36     if (ret != 0) {
37         DISPLAY_LOGW("can not drop master");
38     }
39     return DISPLAY_SUCCESS;
40 }
41 
Allocate(const BufferInfo & bufferInfo,BufferHandle & handle)42 int32_t DrmAllocator::Allocate(const BufferInfo &bufferInfo, BufferHandle &handle)
43 {
44     int32_t ret;
45     int32_t fd;
46     struct drm_mode_create_dumb dumb = {0};
47     // create_dumb
48     dumb.width = bufferInfo.widthStride_;
49     dumb.height = bufferInfo.heightStride_;
50     dumb.flags = 0;
51     dumb.bpp = bufferInfo.bitsPerPixel_;
52     DISPLAY_LOGD();
53     ret = drmIoctl(drmFd_, DRM_IOCTL_MODE_CREATE_DUMB, &dumb);
54     DISPLAY_LOGI("fmt 0x%{public}x create dumb width: %{public}d  height: %{public}d bpp: %{public}u pitch %{public}d "
55                  "size %{public}llu",
56         handle.format, dumb.width, dumb.height, dumb.bpp, dumb.pitch, dumb.size);
57     DISPLAY_CHK_RETURN(
58         (ret != 0), DISPLAY_FAILURE, DISPLAY_LOGE("DRM_IOCTL_MODE_CREATE_DUMB failed errno %{public}d", errno));
59 
60     ret = drmPrimeHandleToFD(drmFd_, dumb.handle, DRM_CLOEXEC | DRM_RDWR, &fd);
61     DISPLAY_CHK_RETURN(
62         (ret != 0), DISPLAY_FAILURE, DISPLAY_LOGE("can not get fd from prime handle errno: %{public}d", errno));
63     handle.fd = fd;
64     handle.size = dumb.size;
65     handle.phyAddr = GetPhysicalAddr(handle.fd);
66 
67     if ((handle.usage & HBM_USE_MEM_FB) != 0) {
68         handle.format = PIXEL_FMT_BGRA_8888;
69         DISPLAY_LOGI("drm Allocate set to PIXEL_FMT_BGRA_8888 for FB");
70     }
71 
72     struct drm_mode_destroy_dumb destoryDumb = {0};
73     destoryDumb.handle = dumb.handle;
74     ret = drmIoctl(drmFd_, DRM_IOCTL_MODE_DESTROY_DUMB, &destoryDumb);
75     if (ret != 0) {
76         DISPLAY_LOGW("can not destroy dumb errno: %{public}d", errno);
77     }
78 
79     return DISPLAY_SUCCESS;
80 }
81 
GetPhysicalAddr(int primeFd)82 uint64_t DrmAllocator::GetPhysicalAddr(int primeFd)
83 {
84     struct DrmHisiliconPhyaddr args;
85     int ret;
86     DISPLAY_LOGD();
87     (void)memset_s(&args, sizeof(args), 0, sizeof(args));
88     args.fd = primeFd;
89     ret = ioctl(drmFd_, DRM_IOCTL_HISILICON_GEM_FD_TO_PHYADDR, &args);
90     if (ret != 0) {
91         DISPLAY_LOGE("DRM_IOCTL_HISILICON_GEM_FD_TO_PHYADDR return failed");
92     }
93     return args.phyaddr;
94 }
95 
~DrmAllocator()96 DrmAllocator::~DrmAllocator()
97 {
98     DISPLAY_LOGD();
99     if (drmFd_ >= 0) {
100         close(drmFd_);
101         drmFd_ = -1;
102     }
103 }
104 } // namespace DISPLAY
105 } // namespace HDI
106 } // namespace OHOS