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