1/*
2 * Copyright (c) 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 "fbdev.h"
17
18#include "display_layer.h"
19#include "display_type.h"
20#include "gfx_utils/color.h"
21#include "gfx_utils/graphic_log.h"
22#include "graphic_config.h"
23
24namespace OHOS {
25struct DisplayDesc {
26    LayerFuncs* layerFuncs;
27    uint32_t devId;
28    uint32_t layerId;
29    LayerBuffer buffer;
30    LayerRotateType rotateType;
31};
32
33static LayerInfo g_layerInfo = {};
34static DisplayDesc g_display = {};
35constexpr const uint8_t DISPLAY_DEV_ID = 0;
36#ifdef LAYER_PF_ARGB1555
37constexpr const uint8_t LAYER_BPP = 16;
38constexpr const PixelFormat HDI_LAYER_PIXEL_FORMAT = PIXEL_FMT_RGBA_5551;
39constexpr const ImagePixelFormat LAYER_PIXEL_FORMAT = IMAGE_PIXEL_FORMAT_ARGB1555;
40#elif defined LAYER_PF_ARGB8888
41constexpr const uint8_t LAYER_BPP = 32;
42constexpr const PixelFormat HDI_LAYER_PIXEL_FORMAT = PIXEL_FMT_RGBA_8888;
43constexpr const ImagePixelFormat LAYER_PIXEL_FORMAT = IMAGE_PIXEL_FORMAT_ARGB8888;
44#endif
45constexpr const uint8_t BITS_PER_BYTE = 8;
46static LiteSurfaceData g_devSurfaceData = {};
47
48void FbdevFlush(void)
49{
50    if (g_display.layerFuncs->Flush != nullptr) {
51        int32_t ret =
52            g_display.layerFuncs->Flush(g_display.devId, g_display.layerId, &g_display.buffer);
53        if (ret != DISPLAY_SUCCESS) {
54            GRAPHIC_LOGE("flush fail");
55            return;
56        }
57    }
58}
59
60LayerRotateType GetLayerRotateType(void)
61{
62    return g_display.rotateType;
63}
64
65LiteSurfaceData* GetDevSurfaceData(void)
66{
67    return &g_devSurfaceData;
68}
69
70static void DisplayInit(void)
71{
72    int32_t ret = LayerInitialize(&g_display.layerFuncs);
73    if (ret != DISPLAY_SUCCESS || g_display.layerFuncs == nullptr) {
74        GRAPHIC_LOGE("layer initialize failed");
75        return;
76    }
77    if (g_display.layerFuncs->InitDisplay != nullptr) {
78        ret = g_display.layerFuncs->InitDisplay(DISPLAY_DEV_ID);
79        if (ret != DISPLAY_SUCCESS) {
80            GRAPHIC_LOGE("InitDisplay fail");
81            return;
82        }
83    }
84}
85
86static void OpenLayer(void)
87{
88    if (g_display.layerFuncs->GetDisplayInfo == nullptr) {
89        return;
90    }
91    g_display.devId = DISPLAY_DEV_ID;
92    DisplayInfo displayInfo = {};
93    int32_t ret = g_display.layerFuncs->GetDisplayInfo(g_display.devId, &displayInfo);
94    if (ret != DISPLAY_SUCCESS) {
95        GRAPHIC_LOGE("GetDisplayInfo fail");
96        return;
97    }
98    g_display.rotateType = static_cast<LayerRotateType>(displayInfo.rotAngle);
99    g_layerInfo.width = displayInfo.width;
100    g_layerInfo.height = displayInfo.height;
101    g_layerInfo.bpp = LAYER_BPP;
102    g_layerInfo.pixFormat = HDI_LAYER_PIXEL_FORMAT;
103    g_layerInfo.type = LAYER_TYPE_GRAPHIC;
104    if (g_display.layerFuncs->CreateLayer != nullptr) {
105        ret = g_display.layerFuncs->CreateLayer(g_display.devId, &g_layerInfo, &g_display.layerId);
106        if (ret != DISPLAY_SUCCESS) {
107            GRAPHIC_LOGE("CreateLayer fail");
108            return;
109        }
110    }
111}
112
113static void SetLayerVisible(bool visibled)
114{
115    if (g_display.layerFuncs->SetLayerVisible != nullptr) {
116        int32_t ret = g_display.layerFuncs->SetLayerVisible(g_display.devId, g_display.layerId, visibled);
117        if (ret != DISPLAY_SUCCESS) {
118            GRAPHIC_LOGE("setLayerVisible fail");
119            return;
120        }
121    }
122}
123
124static void SetLayerDirtyRegion(void)
125{
126    IRect rect = {0, 0, g_layerInfo.width, g_layerInfo.height};
127    if (g_display.layerFuncs->SetLayerDirtyRegion != nullptr) {
128        int32_t ret = g_display.layerFuncs->SetLayerDirtyRegion(g_display.devId, g_display.layerId, &rect);
129        if (ret != DISPLAY_SUCCESS) {
130            GRAPHIC_LOGE("setLayerDirtyRegion fail");
131            return;
132        }
133    }
134}
135
136static void AllocDisplayBuffer(void)
137{
138    if (g_display.layerFuncs->GetLayerBuffer != nullptr) {
139        int32_t ret =
140            g_display.layerFuncs->GetLayerBuffer(g_display.devId, g_display.layerId, &g_display.buffer);
141        if (ret != DISPLAY_SUCCESS) {
142            GRAPHIC_LOGE("getLayerBuffer fail");
143            return;
144        }
145    }
146}
147
148void FbdevInit(void)
149{
150    DisplayInit();
151    OpenLayer();
152    SetLayerVisible(true);
153    SetLayerDirtyRegion();
154    AllocDisplayBuffer();
155    uintptr_t phyAddr = g_display.buffer.data.phyAddr;
156    g_devSurfaceData.phyAddr = reinterpret_cast<uint8_t*>(phyAddr);
157    g_devSurfaceData.pixelFormat = LAYER_PIXEL_FORMAT;
158    g_devSurfaceData.width = g_layerInfo.width;
159    g_devSurfaceData.height = g_layerInfo.height;
160    g_devSurfaceData.stride = g_display.buffer.pitch;
161    g_devSurfaceData.virAddr = static_cast<uint8_t*>(g_display.buffer.data.virAddr);
162    g_devSurfaceData.bytePerPixel = g_layerInfo.bpp / BITS_PER_BYTE;
163}
164
165void FbdevClose(void)
166{
167    if (g_display.layerFuncs->CloseLayer == nullptr) {
168        return;
169    }
170    if (g_display.layerFuncs->DeinitDisplay == nullptr) {
171        return;
172    }
173    int32_t ret = g_display.layerFuncs->CloseLayer(g_display.devId, g_display.layerId);
174    if (ret != DISPLAY_SUCCESS) {
175        GRAPHIC_LOGE("CloseLayer fail");
176        return;
177    }
178    ret = g_display.layerFuncs->DeinitDisplay(g_display.devId);
179    if (ret != DISPLAY_SUCCESS) {
180        GRAPHIC_LOGE("DeinitDisplay fail");
181        return;
182    }
183    ret = LayerUninitialize(g_display.layerFuncs);
184    if (ret != DISPLAY_SUCCESS) {
185        GRAPHIC_LOGE("LayerUninitialize fail");
186    }
187}
188} // namespace OHOS
189