1 /*
2 * Copyright (c) 2021 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
16 #include "surface_dev.h"
17 #include <cerrno>
18 #include <cstring>
19 #include <drm_fourcc.h>
20 #include <fcntl.h>
21 #include <poll.h>
22 #include <sys/mman.h>
23 #include <xf86drm.h>
24 #include <xf86drmMode.h>
25 #include <linux/fb.h>
26 #include "log.h"
27 #include "securec.h"
28 #include "utils/hdf_log.h"
29
30 namespace OHOS {
31 namespace HDI {
32 namespace Battery {
33 namespace V1_0 {
34 struct BufferObject {
35 uint32_t width;
36 uint32_t height;
37 uint32_t pitch;
38 uint32_t handle;
39 uint32_t size;
40 uint8_t* vaddr;
41 uint32_t fbId;
42 };
43
44 struct BufferObject g_buff;
45
Flip(char * buf)46 void SurfaceDev::Flip(char* buf)
47 {
48 HDF_LOGD("%{public}s enter", __func__);
49 if (!buf) {
50 HDF_LOGE("%{public}s, buf is null.", __func__);
51 return;
52 }
53 if (memcpy_s(g_buff.vaddr, g_buff.size, static_cast<void*>(buf), g_buff.size) != EOK) {
54 HDF_LOGE("%{public}s, memcpy_s fail.", __func__);
55 return;
56 }
57 }
58
ModesetCreateFb(int fd,struct BufferObject * bo)59 static int ModesetCreateFb(int fd, struct BufferObject* bo)
60 {
61 HDF_LOGD("%{public}s enter", __func__);
62 struct drm_mode_create_dumb create = {};
63 struct drm_mode_map_dumb map = {};
64 const int offsetNumber = 4;
65 uint32_t handles[offsetNumber] = {0};
66 uint32_t pitches[offsetNumber] = {0};
67 uint32_t offsets[offsetNumber] = {0};
68 int ret;
69
70 /* create a dumb-buffer, the pixel format is XRGB888 */
71 const int pixelDepth = 32;
72 create.width = bo->width;
73 create.height = bo->height;
74 create.bpp = pixelDepth;
75 drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &create);
76
77 /* bind the dumb-buffer to an FB object */
78 bo->pitch = create.pitch;
79 bo->size = create.size;
80 bo->handle = create.handle;
81
82 handles[0] = bo->handle;
83 pitches[0] = bo->pitch;
84 offsets[0] = 0;
85 ret = drmModeAddFB2(fd, bo->width, bo->height, DRM_FORMAT_ARGB8888, handles, pitches, offsets, &bo->fbId, 0);
86 if (ret) {
87 HDF_LOGD("%{public}s, [fbtest]failed to add fb %{public}d x %{public}d: errno %{public}s", __func__, \
88 bo->width, bo->height, strerror(errno));
89 return -1;
90 }
91
92 /* map the dumb-buffer to userspace */
93 map.handle = create.handle;
94 drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &map);
95 bo->vaddr = static_cast<uint8_t*>(mmap(0, create.size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, map.offset));
96 const int newColor = 0xff00ff00;
97 uint32_t i = 0;
98 uint32_t color = newColor;
99 while (i < bo->size) {
100 if (memcpy_s(&bo->vaddr[i], bo->size, &color, sizeof(color)) != EOK) {
101 HDF_LOGE("%{public}s, memcpy_s fail.", __func__);
102 return -1;
103 }
104 i += sizeof(color);
105 }
106 return 0;
107 }
108
DrmInit(void)109 int DrmInit(void)
110 {
111 HDF_LOGD("%{public}s enter", __func__);
112 int fd = -1;
113 drmModeConnector* conn;
114 uint32_t connId;
115 uint32_t crtcId;
116 fd = open("/dev/dri/card0", O_RDWR | O_CLOEXEC);
117 if (fd < 0) {
118 HDF_LOGE("%{public}s, open failed.", __func__);
119 return -1;
120 }
121
122 drmModeRes* res = drmModeGetResources(fd);
123 if (res == nullptr) {
124 HDF_LOGE("%{public}s, drmModeGetResources.", __func__);
125 return -1;
126 }
127
128 crtcId = res->crtcs[0];
129 connId = res->connectors[1];
130 conn = drmModeGetConnector(fd, connId);
131 if (conn == nullptr) {
132 HDF_LOGE("%{public}s, drmModeGetConnector.", __func__);
133 return -1;
134 }
135 g_buff.width = conn->modes[0].hdisplay;
136 g_buff.height = conn->modes[0].vdisplay;
137
138 ModesetCreateFb(fd, &g_buff);
139 drmModeSetCrtc(fd, crtcId, g_buff.fbId, 0, 0, &connId, 1, &conn->modes[0]);
140 HDF_LOGD("%{public}s, drm init succcess.", __func__);
141 return 0;
142 }
143
SurfaceDev(SurfaceDev::DevType devType)144 SurfaceDev::SurfaceDev(SurfaceDev::DevType devType)
145 {
146 HDF_LOGD("%{public}s enter", __func__);
147 if (devType == SurfaceDev::DevType::DRM_DEVICE) {
148 DrmInit();
149 } else {
150 HDF_LOGE("%{public}s, Only Support drm driver.", __func__);
151 }
152 }
153
GetScreenSize(int & w,int & h)154 void SurfaceDev::GetScreenSize(int& w, int& h)
155 {
156 HDF_LOGD("%{public}s enter", __func__);
157 const int screenSizeW = 480;
158 const int screenSizeH = 960;
159 w = screenSizeW;
160 h = screenSizeH;
161 }
162 } // namespace V1_0
163 } // namespace Battery
164 } // namespace HDI
165 } // namespace OHOS
166