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 "display_layer.h"
17 #include <errno.h>
18 #include <securec.h>
19 #include "hdf_log.h"
20 #include "display_type.h"
21 #include "fb.h"
22
23 #define DEV_ID 0
24 #define LAYER_ID 0
25 #define FB_PATH "/dev/fb0"
26 #define DISP_WIDTH 800
27 #define DISP_HEIGHT 480
28 #define BITS_PER_PIXEL 32
29 #define BITS_TO_BYTE 8
30
31 struct LayerPrivate {
32 int32_t fd;
33 uint32_t width;
34 uint32_t height;
35 int32_t pitch;
36 void *fbAddr;
37 uint32_t fbSize;
38 void *layerAddr;
39 PixelFormat pixFmt;
40 struct fb_mem *fbmem;
41 };
42
GetLayerInstance(void)43 static struct LayerPrivate *GetLayerInstance(void)
44 {
45 static struct LayerPrivate layerPriv = {
46 .fd = -1,
47 .width = DISP_WIDTH,
48 .height = DISP_HEIGHT,
49 .pixFmt = PIXEL_FMT_RGBA_8888,
50 };
51 return &layerPriv;
52 }
53
InitDisplay(uint32_t devId)54 static int32_t InitDisplay(uint32_t devId)
55 {
56 if (devId != DEV_ID) {
57 HDF_LOGE("%s: devId invalid", __func__);
58 return DISPLAY_FAILURE;
59 }
60 return DISPLAY_SUCCESS;
61 }
62
DeinitDisplay(uint32_t devId)63 static int32_t DeinitDisplay(uint32_t devId)
64 {
65 if (devId != DEV_ID) {
66 HDF_LOGE("%s: devId invalid", __func__);
67 return DISPLAY_FAILURE;
68 }
69 return DISPLAY_SUCCESS;
70 }
71
SetBackground(void)72 static void SetBackground(void)
73 {
74 struct LayerPrivate *priv = GetLayerInstance();
75 uint32_t i;
76 uint32_t j;
77 uint32_t *framebuffer = (uint32_t *)priv->fbAddr;
78 for (j = 0; j < priv->height; j++) {
79 for (i = 0; i < priv->width; i++) {
80 framebuffer[i + j * priv->width] = 0xFF0000; // Blue background
81 }
82 }
83 }
84
CreateLayer(uint32_t devId,const LayerInfo * layerInfo,uint32_t * layerId)85 static int32_t CreateLayer(uint32_t devId, const LayerInfo *layerInfo, uint32_t *layerId)
86 {
87 if (layerInfo == NULL || layerId == NULL) {
88 HDF_LOGE("%s: pointer is null", __func__);
89 return DISPLAY_NULL_PTR;
90 }
91 if (devId != DEV_ID) {
92 HDF_LOGE("%s: devId invalid", __func__);
93 return DISPLAY_FAILURE;
94 }
95 struct LayerPrivate *priv = GetLayerInstance();
96
97 priv->fd = fb_open(FB_PATH, &priv->fbmem);
98 if (priv->fd < 0 || priv->fbmem == NULL) {
99 HDF_LOGE("%s: open fb dev failed", __func__);
100 return DISPLAY_FD_ERR;
101 }
102 priv->pitch = layerInfo->width * BITS_PER_PIXEL / BITS_TO_BYTE;
103 priv->fbSize = ((priv->pitch * priv->height) + 0xfff) & (~0xfff);
104
105 if (priv->fbmem != NULL) {
106 fb_ioctl(priv->fbmem, FIOC_MMAP, &priv->fbAddr);
107 }
108
109 if (priv->fbAddr == NULL) {
110 HDF_LOGE("%s: mmap fb address failure, errno: %d", __func__, errno);
111 if (priv->fbmem != NULL) {
112 fb_close(priv->fbmem);
113 priv->fbmem = NULL;
114 }
115 priv->pitch = 0;
116 priv->fbSize = 0;
117 return DISPLAY_FAILURE;
118 }
119
120 SetBackground();
121 *layerId = LAYER_ID;
122 HDF_LOGI("%s: open layer success", __func__);
123 return DISPLAY_SUCCESS;
124 }
125
CloseLayer(uint32_t devId,uint32_t layerId)126 static int32_t CloseLayer(uint32_t devId, uint32_t layerId)
127 {
128 if (devId != DEV_ID) {
129 HDF_LOGE("%s: devId invalid", __func__);
130 return DISPLAY_FAILURE;
131 }
132 if (layerId != LAYER_ID) {
133 HDF_LOGE("%s: layerId invalid", __func__);
134 return DISPLAY_FAILURE;
135 }
136 struct LayerPrivate *priv = GetLayerInstance();
137 if (priv->fbmem != NULL) {
138 fb_close(priv->fbmem);
139 priv->fbmem = NULL;
140 }
141 if (priv->layerAddr != NULL) {
142 free(priv->layerAddr);
143 priv->layerAddr = NULL;
144 }
145 if (priv->fbAddr != NULL) {
146 free(priv->fbAddr);
147 priv->fbAddr = NULL;
148 }
149 priv->fd = -1;
150
151 return DISPLAY_SUCCESS;
152 }
153
GetDisplayInfo(uint32_t devId,DisplayInfo * dispInfo)154 static int32_t GetDisplayInfo(uint32_t devId, DisplayInfo *dispInfo)
155 {
156 if (dispInfo == NULL) {
157 HDF_LOGE("%s: dispInfo is null", __func__);
158 return DISPLAY_NULL_PTR;
159 }
160 if (devId != DEV_ID) {
161 HDF_LOGE("%s: devId invalid", __func__);
162 return DISPLAY_FAILURE;
163 }
164 struct LayerPrivate *priv = GetLayerInstance();
165 dispInfo->width = priv->width;
166 dispInfo->height = priv->height;
167 dispInfo->rotAngle = ROTATE_NONE;
168 HDF_LOGD("%s: width = %u, height = %u, rotAngle = %u", __func__, dispInfo->width,
169 dispInfo->height, dispInfo->rotAngle);
170
171 return DISPLAY_SUCCESS;
172 }
173
Flush(uint32_t devId,uint32_t layerId,LayerBuffer * buffer)174 static int32_t Flush(uint32_t devId, uint32_t layerId, LayerBuffer *buffer)
175 {
176 int32_t ret;
177 if (devId != DEV_ID) {
178 HDF_LOGE("%s: devId invalid", __func__);
179 return DISPLAY_FAILURE;
180 }
181 if (layerId != LAYER_ID) {
182 HDF_LOGE("%s: layerId invalid", __func__);
183 return DISPLAY_FAILURE;
184 }
185 if (buffer == NULL) {
186 HDF_LOGE("%s: buffer is null", __func__);
187 return DISPLAY_FAILURE;
188 }
189
190 struct LayerPrivate *priv = GetLayerInstance();
191
192 ret = memcpy_s(priv->fbAddr, priv->fbSize, buffer->data.virAddr, priv->fbSize);
193 if (ret != EOK) {
194 HDF_LOGE("%s: memcpy_s fail, ret %d", __func__, ret);
195 return ret;
196 }
197 return DISPLAY_SUCCESS;
198 }
199
GetLayerBuffer(uint32_t devId,uint32_t layerId,LayerBuffer * buffer)200 static int32_t GetLayerBuffer(uint32_t devId, uint32_t layerId, LayerBuffer *buffer)
201 {
202 if (buffer == NULL) {
203 HDF_LOGE("%s: buffer is null", __func__);
204 return DISPLAY_NULL_PTR;
205 }
206 if (devId != DEV_ID) {
207 HDF_LOGE("%s: devId invalid", __func__);
208 return DISPLAY_FAILURE;
209 }
210 if (layerId != LAYER_ID) {
211 HDF_LOGE("%s: layerId invalid", __func__);
212 return DISPLAY_FAILURE;
213 }
214 struct LayerPrivate *priv = GetLayerInstance();
215 if (priv->fd < 0 || priv->fbmem == NULL) {
216 HDF_LOGE("%s: fb invalid", __func__);
217 return DISPLAY_FAILURE;
218 }
219 buffer->fenceId = 0;
220 buffer->width = priv->width;
221 buffer->height = priv->height;
222 buffer->pixFormat = priv->pixFmt;
223 buffer->pitch = priv->pitch;
224 buffer->data.virAddr = malloc(priv->fbSize);
225 if (buffer->data.virAddr == NULL) {
226 HDF_LOGE("%s: malloc failure", __func__);
227 return DISPLAY_FAILURE;
228 }
229 priv->layerAddr = buffer->data.virAddr;
230 (void)memset_s(buffer->data.virAddr, priv->fbSize, 0x00, priv->fbSize);
231 HDF_LOGD("%s: fenceId = %d, width = %d, height = %d, pixFormat = %d, pitch = %d", __func__, buffer->fenceId,
232 buffer->width, buffer->height, buffer->pixFormat, buffer->pitch);
233
234 return DISPLAY_SUCCESS;
235 }
236
LayerInitialize(LayerFuncs ** funcs)237 int32_t LayerInitialize(LayerFuncs **funcs)
238 {
239 if (funcs == NULL) {
240 HDF_LOGE("%s: funcs is null", __func__);
241 return DISPLAY_NULL_PTR;
242 }
243 LayerFuncs *lFuncs = (LayerFuncs *)malloc(sizeof(LayerFuncs));
244 if (lFuncs == NULL) {
245 HDF_LOGE("%s: lFuncs is null", __func__);
246 return DISPLAY_NULL_PTR;
247 }
248 (void)memset_s(lFuncs, sizeof(LayerFuncs), 0, sizeof(LayerFuncs));
249 lFuncs->InitDisplay = InitDisplay;
250 lFuncs->DeinitDisplay = DeinitDisplay;
251 lFuncs->GetDisplayInfo = GetDisplayInfo;
252 lFuncs->CreateLayer = CreateLayer;
253 lFuncs->CloseLayer = CloseLayer;
254 lFuncs->Flush = Flush;
255 lFuncs->GetLayerBuffer = GetLayerBuffer;
256 *funcs = lFuncs;
257 HDF_LOGI("%s: success", __func__);
258 return DISPLAY_SUCCESS;
259 }
260
LayerUninitialize(LayerFuncs * funcs)261 int32_t LayerUninitialize(LayerFuncs *funcs)
262 {
263 if (funcs == NULL) {
264 HDF_LOGE("%s: funcs is null", __func__);
265 return DISPLAY_NULL_PTR;
266 }
267 free(funcs);
268 HDF_LOGI("%s: layer uninitialize success", __func__);
269 return DISPLAY_SUCCESS;
270 }
271