1d6aed566Sopenharmony_ci/*
2d6aed566Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
3d6aed566Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4d6aed566Sopenharmony_ci * you may not use this file except in compliance with the License.
5d6aed566Sopenharmony_ci * You may obtain a copy of the License at
6d6aed566Sopenharmony_ci *
7d6aed566Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8d6aed566Sopenharmony_ci *
9d6aed566Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10d6aed566Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11d6aed566Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12d6aed566Sopenharmony_ci * See the License for the specific language governing permissions and
13d6aed566Sopenharmony_ci * limitations under the License.
14d6aed566Sopenharmony_ci */
15d6aed566Sopenharmony_ci
16d6aed566Sopenharmony_ci#include "display_layer.h"
17d6aed566Sopenharmony_ci#include <errno.h>
18d6aed566Sopenharmony_ci#include <stdio.h>
19d6aed566Sopenharmony_ci#include <unistd.h>
20d6aed566Sopenharmony_ci#include <sys/mman.h>
21d6aed566Sopenharmony_ci#include <securec.h>
22d6aed566Sopenharmony_ci#include "hdf_log.h"
23d6aed566Sopenharmony_ci#include "display_type.h"
24d6aed566Sopenharmony_ci
25d6aed566Sopenharmony_ci#define DEV_ID             0
26d6aed566Sopenharmony_ci#define LAYER_ID           0
27d6aed566Sopenharmony_ci#define FB_PATH            "/dev/fb0"
28d6aed566Sopenharmony_ci#define DISP_WIDTH         960
29d6aed566Sopenharmony_ci#define DISP_HEIGHT        480
30d6aed566Sopenharmony_ci#define BITS_PER_PIXEL     32
31d6aed566Sopenharmony_ci#define BITS_TO_BYTE       8
32d6aed566Sopenharmony_ci
33d6aed566Sopenharmony_cistruct LayerPrivate {
34d6aed566Sopenharmony_ci    int32_t  fd;
35d6aed566Sopenharmony_ci    uint32_t width;
36d6aed566Sopenharmony_ci    uint32_t height;
37d6aed566Sopenharmony_ci    int32_t  pitch;
38d6aed566Sopenharmony_ci    void     *fbAddr;
39d6aed566Sopenharmony_ci    uint32_t fbSize;
40d6aed566Sopenharmony_ci    void     *layerAddr;
41d6aed566Sopenharmony_ci    PixelFormat pixFmt;
42d6aed566Sopenharmony_ci};
43d6aed566Sopenharmony_ci
44d6aed566Sopenharmony_cistatic struct LayerPrivate *GetLayerInstance(void)
45d6aed566Sopenharmony_ci{
46d6aed566Sopenharmony_ci    static struct LayerPrivate layerPriv = {
47d6aed566Sopenharmony_ci        .fd = -1,
48d6aed566Sopenharmony_ci        .width = DISP_WIDTH,
49d6aed566Sopenharmony_ci        .height = DISP_HEIGHT,
50d6aed566Sopenharmony_ci        .pixFmt = PIXEL_FMT_RGBA_8888,
51d6aed566Sopenharmony_ci    };
52d6aed566Sopenharmony_ci    return &layerPriv;
53d6aed566Sopenharmony_ci}
54d6aed566Sopenharmony_ci
55d6aed566Sopenharmony_cistatic int32_t InitDisplay(uint32_t devId)
56d6aed566Sopenharmony_ci{
57d6aed566Sopenharmony_ci    if (devId != DEV_ID) {
58d6aed566Sopenharmony_ci        HDF_LOGE("%s: devId invalid", __func__);
59d6aed566Sopenharmony_ci        return DISPLAY_FAILURE;
60d6aed566Sopenharmony_ci    }
61d6aed566Sopenharmony_ci    return DISPLAY_SUCCESS;
62d6aed566Sopenharmony_ci}
63d6aed566Sopenharmony_ci
64d6aed566Sopenharmony_cistatic int32_t DeinitDisplay(uint32_t devId)
65d6aed566Sopenharmony_ci{
66d6aed566Sopenharmony_ci    if (devId != DEV_ID) {
67d6aed566Sopenharmony_ci        HDF_LOGE("%s: devId invalid", __func__);
68d6aed566Sopenharmony_ci        return DISPLAY_FAILURE;
69d6aed566Sopenharmony_ci    }
70d6aed566Sopenharmony_ci    return DISPLAY_SUCCESS;
71d6aed566Sopenharmony_ci}
72d6aed566Sopenharmony_ci
73d6aed566Sopenharmony_cistatic void SetBackground(void)
74d6aed566Sopenharmony_ci{
75d6aed566Sopenharmony_ci    struct LayerPrivate *priv = GetLayerInstance();
76d6aed566Sopenharmony_ci    uint32_t i;
77d6aed566Sopenharmony_ci    uint32_t j;
78d6aed566Sopenharmony_ci    uint32_t *framebuffer = (uint32_t *)priv->fbAddr;
79d6aed566Sopenharmony_ci    for (j = 0; j < priv->height; j++) {
80d6aed566Sopenharmony_ci        for (i = 0; i < priv->width; i++) {
81d6aed566Sopenharmony_ci            framebuffer[i + j * priv->width] = 0xFF; // Blue background
82d6aed566Sopenharmony_ci        }
83d6aed566Sopenharmony_ci    }
84d6aed566Sopenharmony_ci}
85d6aed566Sopenharmony_ci
86d6aed566Sopenharmony_cistatic int32_t CreateLayer(uint32_t devId, const LayerInfo *layerInfo, uint32_t *layerId)
87d6aed566Sopenharmony_ci{
88d6aed566Sopenharmony_ci    if (layerInfo == NULL || layerId == NULL) {
89d6aed566Sopenharmony_ci        HDF_LOGE("%s: pointer is null", __func__);
90d6aed566Sopenharmony_ci        return DISPLAY_NULL_PTR;
91d6aed566Sopenharmony_ci    }
92d6aed566Sopenharmony_ci    if (devId != DEV_ID) {
93d6aed566Sopenharmony_ci        HDF_LOGE("%s: devId invalid", __func__);
94d6aed566Sopenharmony_ci        return DISPLAY_FAILURE;
95d6aed566Sopenharmony_ci    }
96d6aed566Sopenharmony_ci    struct LayerPrivate *priv = GetLayerInstance();
97d6aed566Sopenharmony_ci    priv->fd = open(FB_PATH, O_RDWR, 0);
98d6aed566Sopenharmony_ci    if (priv->fd < 0) {
99d6aed566Sopenharmony_ci        HDF_LOGE("%s: open fb dev failed", __func__);
100d6aed566Sopenharmony_ci        return DISPLAY_FD_ERR;
101d6aed566Sopenharmony_ci    }
102d6aed566Sopenharmony_ci    priv->pitch = layerInfo->width * BITS_PER_PIXEL / BITS_TO_BYTE;
103d6aed566Sopenharmony_ci    priv->fbSize = ((priv->pitch * priv->height) + 0xfff) & (~0xfff);
104d6aed566Sopenharmony_ci    priv->fbAddr = (void *)mmap(NULL, priv->fbSize, PROT_READ | PROT_WRITE, MAP_SHARED, priv->fd, 0);
105d6aed566Sopenharmony_ci    if (priv->fbAddr == NULL) {
106d6aed566Sopenharmony_ci        HDF_LOGE("%s: mmap fb address failure, errno: %d", __func__, errno);
107d6aed566Sopenharmony_ci        close(priv->fd);
108d6aed566Sopenharmony_ci        priv->fd = -1;
109d6aed566Sopenharmony_ci        priv->pitch = 0;
110d6aed566Sopenharmony_ci        priv->fbSize = 0;
111d6aed566Sopenharmony_ci        return DISPLAY_FAILURE;
112d6aed566Sopenharmony_ci    }
113d6aed566Sopenharmony_ci    SetBackground();
114d6aed566Sopenharmony_ci    *layerId = LAYER_ID;
115d6aed566Sopenharmony_ci    HDF_LOGI("%s: open layer success", __func__);
116d6aed566Sopenharmony_ci    return DISPLAY_SUCCESS;
117d6aed566Sopenharmony_ci}
118d6aed566Sopenharmony_ci
119d6aed566Sopenharmony_cistatic int32_t CloseLayer(uint32_t devId, uint32_t layerId)
120d6aed566Sopenharmony_ci{
121d6aed566Sopenharmony_ci    if (devId != DEV_ID) {
122d6aed566Sopenharmony_ci        HDF_LOGE("%s: devId invalid", __func__);
123d6aed566Sopenharmony_ci        return DISPLAY_FAILURE;
124d6aed566Sopenharmony_ci    }
125d6aed566Sopenharmony_ci    if (layerId != LAYER_ID) {
126d6aed566Sopenharmony_ci        HDF_LOGE("%s: layerId invalid", __func__);
127d6aed566Sopenharmony_ci        return DISPLAY_FAILURE;
128d6aed566Sopenharmony_ci    }
129d6aed566Sopenharmony_ci    struct LayerPrivate *priv = GetLayerInstance();
130d6aed566Sopenharmony_ci    if (priv->fd >= 0) {
131d6aed566Sopenharmony_ci        close(priv->fd);
132d6aed566Sopenharmony_ci    }
133d6aed566Sopenharmony_ci    if (priv->layerAddr != NULL) {
134d6aed566Sopenharmony_ci        free(priv->layerAddr);
135d6aed566Sopenharmony_ci        priv->layerAddr = NULL;
136d6aed566Sopenharmony_ci    }
137d6aed566Sopenharmony_ci    if (priv->fbAddr != NULL) {
138d6aed566Sopenharmony_ci        munmap(priv->fbAddr, priv->fbSize);
139d6aed566Sopenharmony_ci    }
140d6aed566Sopenharmony_ci    priv->fd = -1;
141d6aed566Sopenharmony_ci    return DISPLAY_SUCCESS;
142d6aed566Sopenharmony_ci}
143d6aed566Sopenharmony_ci
144d6aed566Sopenharmony_cistatic int32_t GetDisplayInfo(uint32_t devId, DisplayInfo *dispInfo)
145d6aed566Sopenharmony_ci{
146d6aed566Sopenharmony_ci    if (dispInfo == NULL) {
147d6aed566Sopenharmony_ci        HDF_LOGE("%s: dispInfo is null", __func__);
148d6aed566Sopenharmony_ci        return DISPLAY_NULL_PTR;
149d6aed566Sopenharmony_ci    }
150d6aed566Sopenharmony_ci    if (devId != DEV_ID) {
151d6aed566Sopenharmony_ci        HDF_LOGE("%s: devId invalid", __func__);
152d6aed566Sopenharmony_ci        return DISPLAY_FAILURE;
153d6aed566Sopenharmony_ci    }
154d6aed566Sopenharmony_ci    struct LayerPrivate *priv = GetLayerInstance();
155d6aed566Sopenharmony_ci    dispInfo->width = priv->width;
156d6aed566Sopenharmony_ci    dispInfo->height = priv->height;
157d6aed566Sopenharmony_ci    dispInfo->rotAngle = ROTATE_NONE;
158d6aed566Sopenharmony_ci    HDF_LOGD("%s: width = %u, height = %u, rotAngle = %u", __func__, dispInfo->width,
159d6aed566Sopenharmony_ci        dispInfo->height, dispInfo->rotAngle);
160d6aed566Sopenharmony_ci    return DISPLAY_SUCCESS;
161d6aed566Sopenharmony_ci}
162d6aed566Sopenharmony_ci
163d6aed566Sopenharmony_cistatic int32_t Flush(uint32_t devId, uint32_t layerId, LayerBuffer *buffer)
164d6aed566Sopenharmony_ci{
165d6aed566Sopenharmony_ci    int32_t ret;
166d6aed566Sopenharmony_ci    if (devId != DEV_ID) {
167d6aed566Sopenharmony_ci        HDF_LOGE("%s: devId invalid", __func__);
168d6aed566Sopenharmony_ci        return DISPLAY_FAILURE;
169d6aed566Sopenharmony_ci    }
170d6aed566Sopenharmony_ci    if (layerId != LAYER_ID) {
171d6aed566Sopenharmony_ci        HDF_LOGE("%s: layerId invalid", __func__);
172d6aed566Sopenharmony_ci        return DISPLAY_FAILURE;
173d6aed566Sopenharmony_ci    }
174d6aed566Sopenharmony_ci    if (buffer == NULL) {
175d6aed566Sopenharmony_ci        HDF_LOGE("%s: buffer is null", __func__);
176d6aed566Sopenharmony_ci        return DISPLAY_FAILURE;
177d6aed566Sopenharmony_ci    }
178d6aed566Sopenharmony_ci
179d6aed566Sopenharmony_ci    struct LayerPrivate *priv = GetLayerInstance();
180d6aed566Sopenharmony_ci    ret = memcpy_s(priv->fbAddr, priv->fbSize, buffer->data.virAddr, priv->fbSize);
181d6aed566Sopenharmony_ci    if (ret != EOK) {
182d6aed566Sopenharmony_ci        HDF_LOGE("%s: memcpy_s fail, ret %d", __func__, ret);
183d6aed566Sopenharmony_ci        return ret;
184d6aed566Sopenharmony_ci    }
185d6aed566Sopenharmony_ci    return DISPLAY_SUCCESS;
186d6aed566Sopenharmony_ci}
187d6aed566Sopenharmony_ci
188d6aed566Sopenharmony_cistatic int32_t GetLayerBuffer(uint32_t devId, uint32_t layerId, LayerBuffer *buffer)
189d6aed566Sopenharmony_ci{
190d6aed566Sopenharmony_ci    if (buffer == NULL) {
191d6aed566Sopenharmony_ci        HDF_LOGE("%s: buffer is null", __func__);
192d6aed566Sopenharmony_ci        return DISPLAY_NULL_PTR;
193d6aed566Sopenharmony_ci    }
194d6aed566Sopenharmony_ci    if (devId != DEV_ID) {
195d6aed566Sopenharmony_ci        HDF_LOGE("%s: devId invalid", __func__);
196d6aed566Sopenharmony_ci        return DISPLAY_FAILURE;
197d6aed566Sopenharmony_ci    }
198d6aed566Sopenharmony_ci    if (layerId != LAYER_ID) {
199d6aed566Sopenharmony_ci        HDF_LOGE("%s: layerId invalid", __func__);
200d6aed566Sopenharmony_ci        return DISPLAY_FAILURE;
201d6aed566Sopenharmony_ci    }
202d6aed566Sopenharmony_ci    struct LayerPrivate *priv = GetLayerInstance();
203d6aed566Sopenharmony_ci    if (priv->fd < 0) {
204d6aed566Sopenharmony_ci        HDF_LOGE("%s: fd invalid", __func__);
205d6aed566Sopenharmony_ci        return DISPLAY_FAILURE;
206d6aed566Sopenharmony_ci    }
207d6aed566Sopenharmony_ci    buffer->fenceId = 0;
208d6aed566Sopenharmony_ci    buffer->width = priv->width;
209d6aed566Sopenharmony_ci    buffer->height = priv->height;
210d6aed566Sopenharmony_ci    buffer->pixFormat = priv->pixFmt;
211d6aed566Sopenharmony_ci    buffer->pitch = priv->pitch;
212d6aed566Sopenharmony_ci    buffer->data.virAddr = malloc(priv->fbSize);
213d6aed566Sopenharmony_ci    if (buffer->data.virAddr == NULL) {
214d6aed566Sopenharmony_ci        HDF_LOGE("%s: malloc failure", __func__);
215d6aed566Sopenharmony_ci        return DISPLAY_FAILURE;
216d6aed566Sopenharmony_ci    }
217d6aed566Sopenharmony_ci    priv->layerAddr = buffer->data.virAddr;
218d6aed566Sopenharmony_ci    (void)memset_s(buffer->data.virAddr, priv->fbSize, 0x00, priv->fbSize);
219d6aed566Sopenharmony_ci    HDF_LOGD("%s: fenceId = %d, width = %d, height = %d, pixFormat = %d, pitch = %d", __func__, buffer->fenceId,
220d6aed566Sopenharmony_ci        buffer->width, buffer->height, buffer->pixFormat, buffer->pitch);
221d6aed566Sopenharmony_ci    return DISPLAY_SUCCESS;
222d6aed566Sopenharmony_ci}
223d6aed566Sopenharmony_ci
224d6aed566Sopenharmony_ciint32_t LayerInitialize(LayerFuncs **funcs)
225d6aed566Sopenharmony_ci{
226d6aed566Sopenharmony_ci    if (funcs == NULL) {
227d6aed566Sopenharmony_ci        HDF_LOGE("%s: funcs is null", __func__);
228d6aed566Sopenharmony_ci        return DISPLAY_NULL_PTR;
229d6aed566Sopenharmony_ci    }
230d6aed566Sopenharmony_ci    LayerFuncs *lFuncs = (LayerFuncs *)malloc(sizeof(LayerFuncs));
231d6aed566Sopenharmony_ci    if (lFuncs == NULL) {
232d6aed566Sopenharmony_ci        HDF_LOGE("%s: lFuncs is null", __func__);
233d6aed566Sopenharmony_ci        return DISPLAY_NULL_PTR;
234d6aed566Sopenharmony_ci    }
235d6aed566Sopenharmony_ci    (void)memset_s(lFuncs, sizeof(LayerFuncs), 0, sizeof(LayerFuncs));
236d6aed566Sopenharmony_ci    lFuncs->InitDisplay = InitDisplay;
237d6aed566Sopenharmony_ci    lFuncs->DeinitDisplay = DeinitDisplay;
238d6aed566Sopenharmony_ci    lFuncs->GetDisplayInfo = GetDisplayInfo;
239d6aed566Sopenharmony_ci    lFuncs->CreateLayer = CreateLayer;
240d6aed566Sopenharmony_ci    lFuncs->CloseLayer = CloseLayer;
241d6aed566Sopenharmony_ci    lFuncs->Flush = Flush;
242d6aed566Sopenharmony_ci    lFuncs->GetLayerBuffer = GetLayerBuffer;
243d6aed566Sopenharmony_ci    *funcs = lFuncs;
244d6aed566Sopenharmony_ci    HDF_LOGI("%s: success", __func__);
245d6aed566Sopenharmony_ci    return DISPLAY_SUCCESS;
246d6aed566Sopenharmony_ci}
247d6aed566Sopenharmony_ci
248d6aed566Sopenharmony_ciint32_t LayerUninitialize(LayerFuncs *funcs)
249d6aed566Sopenharmony_ci{
250d6aed566Sopenharmony_ci    if (funcs == NULL) {
251d6aed566Sopenharmony_ci        HDF_LOGE("%s: funcs is null", __func__);
252d6aed566Sopenharmony_ci        return DISPLAY_NULL_PTR;
253d6aed566Sopenharmony_ci    }
254d6aed566Sopenharmony_ci    free(funcs);
255d6aed566Sopenharmony_ci    HDF_LOGI("%s: layer uninitialize success", __func__);
256d6aed566Sopenharmony_ci    return DISPLAY_SUCCESS;
257d6aed566Sopenharmony_ci}
258