• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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