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