• 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 "display_layer.h"
17 #include <cerrno>
18 #include <pthread.h>
19 #include <stdio.h>
20 #include <unistd.h>
21 #include <sys/mman.h>
22 #include <securec.h>
23 #include "display_type.h"
24 #include "hdf_log.h"
25 #include "hdf_io_service_if.h"
26 #include "hdf_sbuf.h"
27 #include "osal_mem.h"
28 
29 #define DEV_ID                   0
30 #define LAYER_ID                 0
31 #define FB_PATH                  "/dev/fb0"
32 #define DISP_WIDTH               800
33 #define DISP_HEIGHT              480
34 #define BITS_PER_PIXEL           32
35 #define BITS_TO_BYTE             8
36 #define DISP_SERVICE_NAME        "hdf_disp"
37 #define DISP_CMD_GET_PANELINFO   1
38 
39 #undef  HDF_LOG_TAG
40 #define HDF_LOG_TAG              display_layer_c
41 
42 /* output timing */
43 enum IntfSync {
44     OUTPUT_USER = 0,          /* User timing */
45     OUTPUT_PAL,               /* PAL standard */
46     OUTPUT_NTSC,              /* NTSC standard */
47     OUTPUT_1080P24,           /* 1920 x 1080 at 24 Hz. */
48     OUTPUT_1080P25,           /* 1920 x 1080 at 25 Hz. */
49     OUTPUT_1080P30,           /* 1920 x 1080 at 30 Hz. */
50     OUTPUT_720P50,            /* 1280 x  720 at 50 Hz. */
51     OUTPUT_720P60,            /* 1280 x  720 at 60 Hz. */
52     OUTPUT_1080I50,           /* 1920 x 1080 at 50 Hz, interlace. */
53     OUTPUT_1080I60,           /* 1920 x 1080 at 60 Hz, interlace. */
54     OUTPUT_1080P50,           /* 1920 x 1080 at 50 Hz. */
55     OUTPUT_1080P60,           /* 1920 x 1080 at 60 Hz. */
56     OUTPUT_576P50,            /* 720  x  576 at 50 Hz. */
57     OUTPUT_480P60,            /* 720  x  480 at 60 Hz. */
58     OUTPUT_800X600_60,        /* VESA 800 x 600 at 60 Hz (non-interlaced) */
59     OUTPUT_1024X768_60,       /* VESA 1024 x 768 at 60 Hz (non-interlaced) */
60     OUTPUT_1280X1024_60,      /* VESA 1280 x 1024 at 60 Hz (non-interlaced) */
61     OUTPUT_1366X768_60,       /* VESA 1366 x 768 at 60 Hz (non-interlaced) */
62     OUTPUT_1440X900_60,       /* VESA 1440 x 900 at 60 Hz (non-interlaced) CVT Compliant */
63     OUTPUT_1280X800_60,       /* 1280*800@60Hz VGA@60Hz */
64     OUTPUT_1600X1200_60,      /* VESA 1600 x 1200 at 60 Hz (non-interlaced) */
65     OUTPUT_1680X1050_60,      /* VESA 1680 x 1050 at 60 Hz (non-interlaced) */
66     OUTPUT_1920X1200_60,      /* VESA 1920 x 1600 at 60 Hz (non-interlaced) CVT (Reduced Blanking) */
67     OUTPUT_640X480_60,        /* VESA 640 x 480 at 60 Hz (non-interlaced) CVT */
68     OUTPUT_960H_PAL,          /* ITU-R BT.1302 960 x 576 at 50 Hz (interlaced) */
69     OUTPUT_960H_NTSC,         /* ITU-R BT.1302 960 x 480 at 60 Hz (interlaced) */
70     OUTPUT_1920X2160_30,      /* 1920x2160_30 */
71     OUTPUT_2560X1440_30,      /* 2560x1440_30 */
72     OUTPUT_2560X1440_60,      /* 2560x1440_60 */
73     OUTPUT_2560X1600_60,      /* 2560x1600_60 */
74     OUTPUT_3840X2160_24,      /* 3840x2160_24 */
75     OUTPUT_3840X2160_25,      /* 3840x2160_25 */
76     OUTPUT_3840X2160_30,      /* 3840x2160_30 */
77     OUTPUT_3840X2160_50,      /* 3840x2160_50 */
78     OUTPUT_3840X2160_60,      /* 3840x2160_60 */
79     OUTPUT_4096X2160_24,      /* 4096x2160_24 */
80     OUTPUT_4096X2160_25,      /* 4096x2160_25 */
81     OUTPUT_4096X2160_30,      /* 4096x2160_30 */
82     OUTPUT_4096X2160_50,      /* 4096x2160_50 */
83     OUTPUT_4096X2160_60,      /* 4096x2160_60 */
84     OUTPUT_320X240_60,        /* For ota5182 at 60 Hz (8bit) */
85     OUTPUT_320X240_50,        /* For ili9342 at 50 Hz (6bit) */
86     OUTPUT_240X320_50,        /* Hi3559AV100: For ili9341 at 50 Hz (6bit) */
87     OUTPUT_240X320_60,        /* For ili9341 at 60 Hz (16bit) */
88     OUTPUT_800X600_50,        /* For LCD     at 50 Hz (24bit) */
89     OUTPUT_720X1280_60,       /* For MIPI DSI Tx 720 x1280 at 60 Hz */
90     OUTPUT_1080X1920_60,      /* For MIPI DSI Tx 1080x1920 at 60 Hz */
91     OUTPUT_7680X4320_30,      /* For HDMI2.1 at 30 Hz */
92 };
93 
94 struct DispInfo {
95     uint32_t width;
96     uint32_t hbp;
97     uint32_t hfp;
98     uint32_t hsw;
99     uint32_t height;
100     uint32_t vbp;
101     uint32_t vfp;
102     uint32_t vsw;
103     uint32_t frameRate;
104     uint32_t intfType;
105     enum IntfSync intfSync;
106     uint32_t minLevel;
107     uint32_t maxLevel;
108     uint32_t defLevel;
109 };
110 
111 struct LayerPrivate {
112     int32_t  fd;
113     uint32_t width;
114     uint32_t height;
115     int32_t  pitch;
116     void     *fbAddr;
117     uint32_t fbSize;
118     void     *layerAddr;
119     PixelFormat pixFmt;
120 };
121 
122 struct LayerManager {
123     pthread_mutex_t mutex;
124     pthread_mutexattr_t mutexattr;
125     int32_t count;
126 };
127 
128 static struct LayerManager g_layerManager;
129 
GetLayerMgr(void)130 static void GetLayerMgr(void)
131 {
132     g_layerManager.count++;
133 }
134 
PutLayerMgr(void)135 static int32_t PutLayerMgr(void)
136 {
137     g_layerManager.count--;
138     return g_layerManager.count;
139 }
140 
LockLayerMgr(void)141 static void LockLayerMgr(void)
142 {
143     pthread_mutex_lock(&g_layerManager.mutex);
144 }
145 
UnlockLayerMgr(void)146 static void UnlockLayerMgr(void)
147 {
148     pthread_mutex_unlock(&g_layerManager.mutex);
149 }
150 
DispCmdSend(const uint32_t cmd,struct HdfSBuf * reqData,struct HdfSBuf * respData)151 static int32_t DispCmdSend(const uint32_t cmd, struct HdfSBuf *reqData, struct HdfSBuf *respData)
152 {
153     struct HdfIoService *dispService = NULL;
154 
155     dispService = HdfIoServiceBind(DISP_SERVICE_NAME);
156     if ((dispService == NULL) || (dispService->dispatcher == NULL) || (dispService->dispatcher->Dispatch == NULL)) {
157         HDF_LOGE("%s:bad remote service found", __func__);
158         return DISPLAY_FAILURE;
159     }
160     int32_t ret = dispService->dispatcher->Dispatch(&dispService->object, cmd, reqData, respData);
161     if (ret != DISPLAY_SUCCESS) {
162         HDF_LOGE("%s: cmd=%u, ret=%d", __func__, cmd, ret);
163         HdfIoServiceRecycle(dispService);
164         return DISPLAY_FAILURE;
165     }
166     HdfIoServiceRecycle(dispService);
167     return DISPLAY_SUCCESS;
168 }
169 
GetInfo(uint32_t devId,struct DispInfo * info)170 static int32_t GetInfo(uint32_t devId, struct DispInfo *info)
171 {
172     struct DispInfo *tmpInfo = NULL;
173     struct HdfSBuf *data = NULL;
174     struct HdfSBuf *reply = NULL;
175 
176     if (info == NULL) {
177         HDF_LOGE("%s: invalid param", __func__);
178         return DISPLAY_FAILURE;
179     }
180     data = HdfSbufObtainDefaultSize();
181     if (data == NULL) {
182         HDF_LOGE("%s: obtain data sbuf fail", __func__);
183         return DISPLAY_FAILURE;
184     }
185     reply = HdfSbufObtainDefaultSize();
186     if (reply == NULL) {
187         HDF_LOGE("%s: obtain reply sbuf fail", __func__);
188         HdfSbufRecycle(data);
189         return DISPLAY_FAILURE;
190     }
191     if (!HdfSbufWriteUint32(data, devId)) {
192         HDF_LOGE("HdfSbufWriteUint32 failure");
193         goto ERR;
194     }
195     if (DispCmdSend(DISP_CMD_GET_PANELINFO, data, reply) != DISPLAY_SUCCESS) {
196         HDF_LOGE("cmd:DISP_CMD_GET_PANEL_INFO failure");
197         goto ERR;
198     }
199     uint32_t dataSize = 0;
200     if (!HdfSbufReadBuffer(reply, (const void **)(&tmpInfo), &dataSize) || dataSize != sizeof(struct DispInfo)) {
201         HDF_LOGE("HdfSbufReadBuffer failure");
202         goto ERR;
203     }
204     if (memcpy_s(info, sizeof(struct DispInfo), tmpInfo, dataSize) != EOK) {
205         HDF_LOGE("memcpy_s failure");
206         goto ERR;
207     }
208     HdfSbufRecycle(data);
209     HdfSbufRecycle(reply);
210     return DISPLAY_SUCCESS;
211 
212 ERR:
213     HdfSbufRecycle(data);
214     HdfSbufRecycle(reply);
215     return DISPLAY_FAILURE;
216 }
217 
GetLayerInstance(void)218 static struct LayerPrivate *GetLayerInstance(void)
219 {
220     static int32_t count;
221     static struct DispInfo info;
222     static struct LayerPrivate layerPriv = {
223         .fd = -1,
224         .width = DISP_WIDTH,
225         .height = DISP_HEIGHT,
226         .pixFmt = PIXEL_FMT_RGBA_8888,
227     };
228 
229     if (count == 0) {
230         count = 1;
231         if (GetInfo(DEV_ID, &info) == DISPLAY_SUCCESS) {
232             layerPriv.width = info.width;
233             layerPriv.height = info.height;
234         } else {
235             HDF_LOGI("%s: GetInfo failed, use default setting", __func__);
236         }
237     }
238     return &layerPriv;
239 }
240 
InitDisplay(uint32_t devId)241 static int32_t InitDisplay(uint32_t devId)
242 {
243     if (devId != DEV_ID) {
244         HDF_LOGE("%s: devId invalid", __func__);
245         return DISPLAY_FAILURE;
246     }
247     return DISPLAY_SUCCESS;
248 }
249 
DeinitDisplay(uint32_t devId)250 static int32_t DeinitDisplay(uint32_t devId)
251 {
252     if (devId != DEV_ID) {
253         HDF_LOGE("%s: devId invalid", __func__);
254         return DISPLAY_FAILURE;
255     }
256     return DISPLAY_SUCCESS;
257 }
258 
SetBackground(void)259 static void SetBackground(void)
260 {
261     struct LayerPrivate *priv = GetLayerInstance();
262     uint32_t i;
263     uint32_t j;
264     uint32_t *framebuffer = (uint32_t *)priv->fbAddr;
265     for (j = 0; j < priv->height; j++) {
266         for (i = 0; i < priv->width; i++) {
267             framebuffer[i + j * priv->width] = 0xFF; // Blue background
268         }
269     }
270 }
271 
CreateLayer(uint32_t devId,const LayerInfo * layerInfo,uint32_t * layerId)272 static int32_t CreateLayer(uint32_t devId, const LayerInfo *layerInfo, uint32_t *layerId)
273 {
274     if (layerInfo == NULL || layerId == NULL) {
275         HDF_LOGE("%s: pointer is null", __func__);
276         return DISPLAY_NULL_PTR;
277     }
278     if (devId != DEV_ID) {
279         HDF_LOGE("%s: devId invalid", __func__);
280         return DISPLAY_FAILURE;
281     }
282     LockLayerMgr();
283     struct LayerPrivate *priv = GetLayerInstance();
284     priv->fd = open(FB_PATH, O_RDWR, 0);
285     if (priv->fd < 0) {
286         HDF_LOGE("%s: open fb dev failed", __func__);
287         UnlockLayerMgr();
288         return DISPLAY_FD_ERR;
289     }
290     priv->pitch = layerInfo->width * BITS_PER_PIXEL / BITS_TO_BYTE;
291     priv->fbSize = ((priv->pitch * priv->height) + 0xfff) & (~0xfff);
292     priv->fbAddr = (void *)mmap(NULL, priv->fbSize, PROT_READ | PROT_WRITE, MAP_SHARED, priv->fd, 0);
293     if (priv->fbAddr == NULL) {
294         HDF_LOGE("%s: mmap fb address failure, errno: %d", __func__, errno);
295         close(priv->fd);
296         priv->fd = -1;
297         priv->pitch = 0;
298         priv->fbSize = 0;
299         UnlockLayerMgr();
300         return DISPLAY_FAILURE;
301     }
302     SetBackground();
303     *layerId = LAYER_ID;
304     HDF_LOGI("%s: open layer success", __func__);
305     UnlockLayerMgr();
306     return DISPLAY_SUCCESS;
307 }
308 
CloseLayer(uint32_t devId,uint32_t layerId)309 static int32_t CloseLayer(uint32_t devId, uint32_t layerId)
310 {
311     if (devId != DEV_ID) {
312         HDF_LOGE("%s: devId invalid", __func__);
313         return DISPLAY_FAILURE;
314     }
315     if (layerId != LAYER_ID) {
316         HDF_LOGE("%s: layerId invalid", __func__);
317         return DISPLAY_FAILURE;
318     }
319     LockLayerMgr();
320     struct LayerPrivate *priv = GetLayerInstance();
321     if (priv->fd >= 0) {
322         close(priv->fd);
323     }
324     if (priv->layerAddr != NULL) {
325         free(priv->layerAddr);
326         priv->layerAddr = NULL;
327     }
328     if (priv->fbAddr != NULL) {
329         munmap(priv->fbAddr, priv->fbSize);
330     }
331     priv->fd = -1;
332     UnlockLayerMgr();
333     return DISPLAY_SUCCESS;
334 }
335 
GetDisplayInfo(uint32_t devId,DisplayInfo * dispInfo)336 static int32_t GetDisplayInfo(uint32_t devId, DisplayInfo *dispInfo)
337 {
338     if (dispInfo == NULL) {
339         HDF_LOGE("%s: dispInfo is null", __func__);
340         return DISPLAY_NULL_PTR;
341     }
342     if (devId != DEV_ID) {
343         HDF_LOGE("%s: devId invalid", __func__);
344         return DISPLAY_FAILURE;
345     }
346     LockLayerMgr();
347     struct LayerPrivate *priv = GetLayerInstance();
348     dispInfo->width = priv->width;
349     dispInfo->height = priv->height;
350     dispInfo->rotAngle = ROTATE_NONE;
351     HDF_LOGD("%s: width = %u, height = %u, rotAngle = %u", __func__, dispInfo->width,
352         dispInfo->height, dispInfo->rotAngle);
353     UnlockLayerMgr();
354     return DISPLAY_SUCCESS;
355 }
356 
Flush(uint32_t devId,uint32_t layerId,LayerBuffer * buffer)357 static int32_t Flush(uint32_t devId, uint32_t layerId, LayerBuffer *buffer)
358 {
359     int32_t ret;
360 
361     if (devId != DEV_ID) {
362         HDF_LOGE("%s: devId invalid", __func__);
363         return DISPLAY_FAILURE;
364     }
365     if (layerId != LAYER_ID) {
366         HDF_LOGE("%s: layerId invalid", __func__);
367         return DISPLAY_FAILURE;
368     }
369     if (buffer == NULL) {
370         HDF_LOGE("%s: buffer is null", __func__);
371         return DISPLAY_FAILURE;
372     }
373 
374     HDF_LOGD("%s: width = %d, height = %d, pixFormat = %d, pitch = %d", __func__, buffer->width,
375         buffer->height, buffer->pixFormat, buffer->pitch);
376     LockLayerMgr();
377     struct LayerPrivate *priv = GetLayerInstance();
378     ret = memcpy_s(priv->fbAddr, priv->fbSize, buffer->data.virAddr, priv->fbSize);
379     if (ret != EOK) {
380         HDF_LOGE("%s: memcpy_s fail, ret %d", __func__, ret);
381         UnlockLayerMgr();
382         return ret;
383     }
384     UnlockLayerMgr();
385     return DISPLAY_SUCCESS;
386 }
387 
GetLayerBuffer(uint32_t devId,uint32_t layerId,LayerBuffer * buffer)388 static int32_t GetLayerBuffer(uint32_t devId, uint32_t layerId, LayerBuffer *buffer)
389 {
390     if (buffer == NULL) {
391         HDF_LOGE("%s: buffer is null", __func__);
392         return DISPLAY_NULL_PTR;
393     }
394     if (devId != DEV_ID) {
395         HDF_LOGE("%s: devId invalid", __func__);
396         return DISPLAY_FAILURE;
397     }
398     if (layerId != LAYER_ID) {
399         HDF_LOGE("%s: layerId invalid", __func__);
400         return DISPLAY_FAILURE;
401     }
402     LockLayerMgr();
403     struct LayerPrivate *priv = GetLayerInstance();
404     if (priv->fd < 0) {
405         HDF_LOGE("%s: fd invalid", __func__);
406         UnlockLayerMgr();
407         return DISPLAY_FAILURE;
408     }
409     buffer->fenceId = 0;
410     buffer->width = priv->width;
411     buffer->height = priv->height;
412     buffer->pixFormat = priv->pixFmt;
413     buffer->pitch = priv->pitch;
414     buffer->data.virAddr = malloc(priv->fbSize);
415     if (buffer->data.virAddr == NULL) {
416         HDF_LOGE("%s: malloc failure", __func__);
417         UnlockLayerMgr();
418         return DISPLAY_FAILURE;
419     }
420     priv->layerAddr = buffer->data.virAddr;
421     (void)memset_s(buffer->data.virAddr, priv->fbSize, 0x00, priv->fbSize);
422     HDF_LOGD("%s: fenceId = %d, width = %d, height = %d, pixFormat = %d, pitch = %d", __func__, buffer->fenceId,
423         buffer->width, buffer->height, buffer->pixFormat, buffer->pitch);
424     UnlockLayerMgr();
425     return DISPLAY_SUCCESS;
426 }
427 
LayerInitialize(LayerFuncs ** funcs)428 int32_t LayerInitialize(LayerFuncs **funcs)
429 {
430     static LayerFuncs *lFuncs = NULL;
431 
432     if (funcs == NULL) {
433         HDF_LOGE("%s: funcs is null", __func__);
434         return DISPLAY_NULL_PTR;
435     }
436     if (lFuncs == NULL) {
437         lFuncs = (LayerFuncs *)OsalMemCalloc(sizeof(LayerFuncs));
438         if (lFuncs == NULL) {
439             HDF_LOGE("%s: lFuncs is null", __func__);
440             return DISPLAY_NULL_PTR;
441         }
442         pthread_mutexattr_init(&g_layerManager.mutexattr);
443         pthread_mutexattr_setpshared(&g_layerManager.mutexattr, PTHREAD_PROCESS_SHARED);
444         pthread_mutex_init(&g_layerManager.mutex, &g_layerManager.mutexattr);
445         lFuncs->InitDisplay = InitDisplay;
446         lFuncs->DeinitDisplay = DeinitDisplay;
447         lFuncs->GetDisplayInfo = GetDisplayInfo;
448         lFuncs->CreateLayer = CreateLayer;
449         lFuncs->CloseLayer = CloseLayer;
450         lFuncs->Flush = Flush;
451         lFuncs->GetLayerBuffer = GetLayerBuffer;
452     }
453     *funcs = lFuncs;
454     GetLayerMgr();
455     HDF_LOGI("%s: success", __func__);
456     return DISPLAY_SUCCESS;
457 }
458 
LayerUninitialize(LayerFuncs * funcs)459 int32_t LayerUninitialize(LayerFuncs *funcs)
460 {
461     if (funcs == NULL) {
462         HDF_LOGE("%s: funcs is null", __func__);
463         return DISPLAY_NULL_PTR;
464     }
465     if (PutLayerMgr() == 0) {
466         pthread_mutexattr_destroy(&g_layerManager.mutexattr);
467         pthread_mutex_destroy(&g_layerManager.mutex);
468         OsalMemFree(funcs);
469     }
470     HDF_LOGI("%s: layer uninitialize success", __func__);
471     return DISPLAY_SUCCESS;
472 }
473