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