1094332d3Sopenharmony_ci/*
2094332d3Sopenharmony_ci * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License.
5094332d3Sopenharmony_ci * You may obtain a copy of the License at
6094332d3Sopenharmony_ci *
7094332d3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8094332d3Sopenharmony_ci *
9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and
13094332d3Sopenharmony_ci * limitations under the License.
14094332d3Sopenharmony_ci */
15094332d3Sopenharmony_ci
16094332d3Sopenharmony_ci#include "display_gralloc_gbm.h"
17094332d3Sopenharmony_ci#include <cstdio>
18094332d3Sopenharmony_ci#include <unistd.h>
19094332d3Sopenharmony_ci#include <cerrno>
20094332d3Sopenharmony_ci#include <cinttypes>
21094332d3Sopenharmony_ci#include <climits>
22094332d3Sopenharmony_ci#include <cstring>
23094332d3Sopenharmony_ci#include <fcntl.h>
24094332d3Sopenharmony_ci#include <pthread.h>
25094332d3Sopenharmony_ci#include <sys/mman.h>
26094332d3Sopenharmony_ci#include <sys/ioctl.h>
27094332d3Sopenharmony_ci#include <xf86drm.h>
28094332d3Sopenharmony_ci#include <securec.h>
29094332d3Sopenharmony_ci#include <linux/dma-buf.h>
30094332d3Sopenharmony_ci#include "drm_fourcc.h"
31094332d3Sopenharmony_ci#include "hisilicon_drm.h"
32094332d3Sopenharmony_ci#include "hi_gbm.h"
33094332d3Sopenharmony_ci#include "hdf_dlist.h"
34094332d3Sopenharmony_ci#include "display_gralloc_private.h"
35094332d3Sopenharmony_ci#include "display_log.h"
36094332d3Sopenharmony_ci#include "v1_0/display_composer_type.h"
37094332d3Sopenharmony_ci
38094332d3Sopenharmony_cinamespace OHOS {
39094332d3Sopenharmony_cinamespace HDI {
40094332d3Sopenharmony_cinamespace DISPLAY {
41094332d3Sopenharmony_ciusing namespace OHOS::HDI::Display::Composer::V1_0;
42094332d3Sopenharmony_ciusing namespace OHOS::HDI::Display::Buffer::V1_0;
43094332d3Sopenharmony_ci
44094332d3Sopenharmony_ciconst char *g_drmFileNode = "/dev/dri/renderD128";
45094332d3Sopenharmony_cistatic GrallocManager *g_grallocManager = nullptr;
46094332d3Sopenharmony_cistatic pthread_mutex_t g_lock;
47094332d3Sopenharmony_ci
48094332d3Sopenharmony_ciusing PixelFormatConvertTbl = struct {
49094332d3Sopenharmony_ci    uint32_t drmFormat;
50094332d3Sopenharmony_ci    PixelFormat pixFormat;
51094332d3Sopenharmony_ci};
52094332d3Sopenharmony_ci
53094332d3Sopenharmony_ciusing ValueStrMap = struct {
54094332d3Sopenharmony_ci    uint32_t value;
55094332d3Sopenharmony_ci    const char *str;
56094332d3Sopenharmony_ci};
57094332d3Sopenharmony_ci
58094332d3Sopenharmony_cistatic GrallocManager *GetGrallocManager(void)
59094332d3Sopenharmony_ci{
60094332d3Sopenharmony_ci    if (g_grallocManager == nullptr) {
61094332d3Sopenharmony_ci        g_grallocManager = (GrallocManager *)malloc(sizeof(GrallocManager));
62094332d3Sopenharmony_ci        errno_t eok = memset_s(g_grallocManager, sizeof(GrallocManager), 0, sizeof(GrallocManager));
63094332d3Sopenharmony_ci        if (eok != EOK) {
64094332d3Sopenharmony_ci            DISPLAY_LOGE("memset_s failed");
65094332d3Sopenharmony_ci        }
66094332d3Sopenharmony_ci        if (g_grallocManager == nullptr) {
67094332d3Sopenharmony_ci            DISPLAY_LOGE("gralloc manager malloc failed");
68094332d3Sopenharmony_ci        }
69094332d3Sopenharmony_ci    }
70094332d3Sopenharmony_ci    return g_grallocManager;
71094332d3Sopenharmony_ci}
72094332d3Sopenharmony_ci
73094332d3Sopenharmony_ciconst char *GetPixelFmtStr(PixelFormat format)
74094332d3Sopenharmony_ci{
75094332d3Sopenharmony_ci    static const ValueStrMap PIXEL_STR_MAPS[] = {
76094332d3Sopenharmony_ci        {PIXEL_FMT_CLUT8, "PIXEL_FMT_CLUT8"}, {PIXEL_FMT_CLUT1, "PIXEL_FMT_CLUT1"},
77094332d3Sopenharmony_ci        {PIXEL_FMT_CLUT4, "PIXEL_FMT_CLUT4"}, {PIXEL_FMT_RGB_565, "PIXEL_FMT_RGB_565"},
78094332d3Sopenharmony_ci        {PIXEL_FMT_RGBA_5658, "IXEL_FMT_RGBA_5658"}, {PIXEL_FMT_RGBX_4444, "PIXEL_FMT_RGBX_4444"},
79094332d3Sopenharmony_ci        {PIXEL_FMT_RGBA_4444, "PIXEL_FMT_RGBA_4444"}, {PIXEL_FMT_RGB_444, "PIXEL_FMT_RGB_444"},
80094332d3Sopenharmony_ci        {PIXEL_FMT_RGBX_5551, "PIXEL_FMT_RGBX_5551"}, {PIXEL_FMT_RGBA_5551, "PIXEL_FMT_RGBA_5551"},
81094332d3Sopenharmony_ci        {PIXEL_FMT_RGB_555, "PIXEL_FMT_RGB_555"}, {PIXEL_FMT_RGBX_8888, "PIXEL_FMT_RGBX_8888"},
82094332d3Sopenharmony_ci        {PIXEL_FMT_RGBA_8888, "PIXEL_FMT_RGBA_8888"}, {PIXEL_FMT_RGB_888, "PIXEL_FMT_RGB_888"},
83094332d3Sopenharmony_ci        {PIXEL_FMT_BGR_565, "PIXEL_FMT_BGR_565"}, {PIXEL_FMT_BGRX_4444, "PIXEL_FMT_BGRX_4444"},
84094332d3Sopenharmony_ci        {PIXEL_FMT_BGRA_4444, "PIXEL_FMT_BGRA_4444"}, {PIXEL_FMT_BGRX_5551, "PIXEL_FMT_BGRX_5551"},
85094332d3Sopenharmony_ci        {PIXEL_FMT_BGRA_5551, "PIXEL_FMT_BGRA_5551"}, {PIXEL_FMT_BGRX_8888, "PIXEL_FMT_BGRX_8888"},
86094332d3Sopenharmony_ci        {PIXEL_FMT_BGRA_8888, "PIXEL_FMT_BGRA_8888"}, {PIXEL_FMT_YUV_422_I, "PIXEL_FMT_YUV_422_I"},
87094332d3Sopenharmony_ci        {PIXEL_FMT_YUV_422_I, "PIXEL_FMT_YUV_422_I"}, {PIXEL_FMT_YCBCR_422_SP, "PIXEL_FMT_YCBCR_422_SP"},
88094332d3Sopenharmony_ci        {PIXEL_FMT_YCRCB_422_SP, "PIXEL_FMT_YCRCB_422_SP"}, {PIXEL_FMT_YCBCR_420_SP, "PIXEL_FMT_YCBCR_420_SP"},
89094332d3Sopenharmony_ci        {PIXEL_FMT_YCRCB_420_SP, "PIXEL_FMT_YCRCB_420_SP"}, {PIXEL_FMT_YCBCR_422_P, "PIXEL_FMT_YCBCR_422_P"},
90094332d3Sopenharmony_ci        {PIXEL_FMT_YCRCB_422_P, "PIXEL_FMT_YCRCB_422_P"}, {PIXEL_FMT_YCBCR_420_P, "PIXEL_FMT_YCBCR_420_P"},
91094332d3Sopenharmony_ci        {PIXEL_FMT_YCRCB_420_P, "PIXEL_FMT_YCRCB_420_P"}, {PIXEL_FMT_YUYV_422_PKG, "PIXEL_FMT_YUYV_422_PKG"},
92094332d3Sopenharmony_ci        {PIXEL_FMT_UYVY_422_PKG, "PIXEL_FMT_UYVY_422_PKG"}, {PIXEL_FMT_YVYU_422_PKG, "PIXEL_FMT_YVYU_422_PKG"},
93094332d3Sopenharmony_ci        {PIXEL_FMT_VYUY_422_PKG, "PIXEL_FMT_VYUY_422_PKG"}, {PIXEL_FMT_BUTT, "PIXEL_FMT_BUTT"},
94094332d3Sopenharmony_ci    };
95094332d3Sopenharmony_ci    static const char *unknown = "unknown format";
96094332d3Sopenharmony_ci    for (uint32_t i = 0; i < sizeof(PIXEL_STR_MAPS) / sizeof(PIXEL_STR_MAPS[0]); i++) {
97094332d3Sopenharmony_ci        if (PIXEL_STR_MAPS[i].value == static_cast<uint32_t>(format)) {
98094332d3Sopenharmony_ci            return PIXEL_STR_MAPS[i].str;
99094332d3Sopenharmony_ci        }
100094332d3Sopenharmony_ci    }
101094332d3Sopenharmony_ci    DISPLAY_LOGE("GetPixelFmtStr unknown format %{public}d", format);
102094332d3Sopenharmony_ci    return unknown;
103094332d3Sopenharmony_ci}
104094332d3Sopenharmony_ci
105094332d3Sopenharmony_ciconst char *GetDrmFmtStr(uint32_t format)
106094332d3Sopenharmony_ci{
107094332d3Sopenharmony_ci    static const ValueStrMap FORMAT_STR_MAPS[] = {
108094332d3Sopenharmony_ci        {DRM_FORMAT_C8, "DRM_FORMAT_C8" }, {DRM_FORMAT_R8, "DRM_FORMAT_R8" },
109094332d3Sopenharmony_ci        {DRM_FORMAT_R16, "DRM_FORMAT_R16"}, {DRM_FORMAT_RG88, "DRM_FORMAT_RG88"},
110094332d3Sopenharmony_ci        {DRM_FORMAT_GR88, "DRM_FORMAT_GR88"}, {DRM_FORMAT_RG1616, "DRM_FORMAT_RG1616"},
111094332d3Sopenharmony_ci        {DRM_FORMAT_GR1616, "DRM_FORMAT_GR1616"}, {DRM_FORMAT_RGB332, "DRM_FORMAT_RGB332"},
112094332d3Sopenharmony_ci        {DRM_FORMAT_BGR233, "DRM_FORMAT_BGR233"}, {DRM_FORMAT_XRGB4444, "DRM_FORMAT_XRGB4444"},
113094332d3Sopenharmony_ci        {DRM_FORMAT_XBGR4444, "DRM_FORMAT_XBGR4444"}, {DRM_FORMAT_RGBX4444, "DRM_FORMAT_RGBX4444"},
114094332d3Sopenharmony_ci        {DRM_FORMAT_BGRX4444, "DRM_FORMAT_BGRX4444"}, {DRM_FORMAT_ARGB4444, "DRM_FORMAT_ARGB4444"},
115094332d3Sopenharmony_ci        {DRM_FORMAT_ABGR4444, "DRM_FORMAT_ABGR4444"}, {DRM_FORMAT_RGBA4444, "DRM_FORMAT_RGBA4444"},
116094332d3Sopenharmony_ci        {DRM_FORMAT_BGRA4444, "DRM_FORMAT_BGRA4444"}, {DRM_FORMAT_XRGB1555, "DRM_FORMAT_XRGB1555"},
117094332d3Sopenharmony_ci        {DRM_FORMAT_XBGR1555, "DRM_FORMAT_XBGR1555"}, {DRM_FORMAT_RGBX5551, "DRM_FORMAT_RGBX5551"},
118094332d3Sopenharmony_ci        {DRM_FORMAT_BGRX5551, "DRM_FORMAT_BGRX5551"}, {DRM_FORMAT_ARGB1555, "DRM_FORMAT_ARGB1555"},
119094332d3Sopenharmony_ci        {DRM_FORMAT_ABGR1555, "DRM_FORMAT_ABGR1555"}, {DRM_FORMAT_RGBA5551, "DRM_FORMAT_RGBA5551"},
120094332d3Sopenharmony_ci        {DRM_FORMAT_BGRA5551, "DRM_FORMAT_BGRA5551"}, {DRM_FORMAT_RGB565, "DRM_FORMAT_RGB565"},
121094332d3Sopenharmony_ci        {DRM_FORMAT_BGR565, "DRM_FORMAT_BGR565"}, {DRM_FORMAT_RGB888, "DRM_FORMAT_RGB888"},
122094332d3Sopenharmony_ci        {DRM_FORMAT_BGR888, "DRM_FORMAT_BGR888"}, {DRM_FORMAT_XRGB8888, "DRM_FORMAT_XRGB8888"},
123094332d3Sopenharmony_ci        {DRM_FORMAT_XBGR8888, "DRM_FORMAT_XBGR8888"}, {DRM_FORMAT_RGBX8888, "DRM_FORMAT_RGBX8888"},
124094332d3Sopenharmony_ci        {DRM_FORMAT_BGRX8888, "DRM_FORMAT_BGRX8888"}, {DRM_FORMAT_ARGB8888, "DRM_FORMAT_ARGB8888"},
125094332d3Sopenharmony_ci        {DRM_FORMAT_ABGR8888, "DRM_FORMAT_ABGR8888"}, {DRM_FORMAT_RGBA8888, "DRM_FORMAT_RGBA8888"},
126094332d3Sopenharmony_ci        {DRM_FORMAT_BGRA8888, "DRM_FORMAT_BGRA8888"}, {DRM_FORMAT_XRGB2101010, "DRM_FORMAT_XRGB2101010"},
127094332d3Sopenharmony_ci        {DRM_FORMAT_BGRX1010102, "DRM_FORMAT_BGRX1010102"}, {DRM_FORMAT_ARGB2101010, "DRM_FORMAT_ARGB2101010"},
128094332d3Sopenharmony_ci        {DRM_FORMAT_ABGR2101010, "DRM_FORMAT_ABGR2101010"}, {DRM_FORMAT_RGBA1010102, "DRM_FORMAT_RGBA1010102"},
129094332d3Sopenharmony_ci        {DRM_FORMAT_YVYU, "DRM_FORMAT_YVYU"}, {DRM_FORMAT_UYVY, "DRM_FORMAT_UYVY"},
130094332d3Sopenharmony_ci        {DRM_FORMAT_VYUY, "DRM_FORMAT_VYUY"}, {DRM_FORMAT_AYUV, "DRM_FORMAT_AYUV"},
131094332d3Sopenharmony_ci        {DRM_FORMAT_NV12, "DRM_FORMAT_NV12"}, {DRM_FORMAT_NV21, "DRM_FORMAT_NV21"},
132094332d3Sopenharmony_ci        {DRM_FORMAT_NV16, "DRM_FORMAT_NV16"}, {DRM_FORMAT_NV61, "DRM_FORMAT_NV61"},
133094332d3Sopenharmony_ci        {DRM_FORMAT_NV24, "DRM_FORMAT_NV24"}, {DRM_FORMAT_NV42, "DRM_FORMAT_NV42"},
134094332d3Sopenharmony_ci        {DRM_FORMAT_YUV410, "DRM_FORMAT_YUV410"}, {DRM_FORMAT_YVU410, "DRM_FORMAT_YVU410"},
135094332d3Sopenharmony_ci        {DRM_FORMAT_YUV411, "DRM_FORMAT_YUV411"}, {DRM_FORMAT_YVU411, "DRM_FORMAT_YVU411"},
136094332d3Sopenharmony_ci        {DRM_FORMAT_YUV420, "DRM_FORMAT_YUV420"}, {DRM_FORMAT_YVU420, "DRM_FORMAT_YVU420"},
137094332d3Sopenharmony_ci        {DRM_FORMAT_YUV422, "DRM_FORMAT_YUV422"}, {DRM_FORMAT_YVU422, "DRM_FORMAT_YVU422"},
138094332d3Sopenharmony_ci        {DRM_FORMAT_YUV444, "DRM_FORMAT_YUV444"}, {DRM_FORMAT_YVU444, "DRM_FORMAT_YVU444"},
139094332d3Sopenharmony_ci    };
140094332d3Sopenharmony_ci
141094332d3Sopenharmony_ci    static const char *unknown = "unknown drm format";
142094332d3Sopenharmony_ci    for (uint32_t i = 0; i < sizeof(FORMAT_STR_MAPS) / sizeof(FORMAT_STR_MAPS[0]); i++) {
143094332d3Sopenharmony_ci        if (FORMAT_STR_MAPS[i].value == format) {
144094332d3Sopenharmony_ci            return FORMAT_STR_MAPS[i].str;
145094332d3Sopenharmony_ci        }
146094332d3Sopenharmony_ci    }
147094332d3Sopenharmony_ci    DISPLAY_LOGE("GetDrmFmtStr unknown format %{public}d", format);
148094332d3Sopenharmony_ci    return unknown;
149094332d3Sopenharmony_ci}
150094332d3Sopenharmony_ci
151094332d3Sopenharmony_cistatic uint32_t ConvertFormatToDrm(PixelFormat fmtIn)
152094332d3Sopenharmony_ci{
153094332d3Sopenharmony_ci    static const PixelFormatConvertTbl CONVERT_TABLE[] = {
154094332d3Sopenharmony_ci        {DRM_FORMAT_RGBX8888, PIXEL_FMT_RGBX_8888}, {DRM_FORMAT_RGBA8888, PIXEL_FMT_RGBA_8888},
155094332d3Sopenharmony_ci        {DRM_FORMAT_RGB888, PIXEL_FMT_RGB_888}, {DRM_FORMAT_RGB565, PIXEL_FMT_BGR_565},
156094332d3Sopenharmony_ci        {DRM_FORMAT_BGRX4444, PIXEL_FMT_BGRX_4444}, {DRM_FORMAT_BGRA4444, PIXEL_FMT_BGRA_4444},
157094332d3Sopenharmony_ci        {DRM_FORMAT_RGBA4444, PIXEL_FMT_RGBA_4444}, {DRM_FORMAT_RGBX4444, PIXEL_FMT_RGBX_4444},
158094332d3Sopenharmony_ci        {DRM_FORMAT_BGRX5551, PIXEL_FMT_BGRX_5551}, {DRM_FORMAT_BGRA5551, PIXEL_FMT_BGRA_5551},
159094332d3Sopenharmony_ci        {DRM_FORMAT_BGRX8888, PIXEL_FMT_BGRX_8888}, {DRM_FORMAT_BGRA8888, PIXEL_FMT_BGRA_8888},
160094332d3Sopenharmony_ci        {DRM_FORMAT_NV12, PIXEL_FMT_YCBCR_420_SP}, {DRM_FORMAT_NV21, PIXEL_FMT_YCRCB_420_SP},
161094332d3Sopenharmony_ci        {DRM_FORMAT_YUV420, PIXEL_FMT_YCBCR_420_P}, {DRM_FORMAT_YVU420, PIXEL_FMT_YCRCB_420_P},
162094332d3Sopenharmony_ci        {DRM_FORMAT_NV16, PIXEL_FMT_YCBCR_422_SP}, {DRM_FORMAT_NV61, PIXEL_FMT_YCRCB_422_SP},
163094332d3Sopenharmony_ci        {DRM_FORMAT_YUV422, PIXEL_FMT_YCBCR_422_P}, {DRM_FORMAT_YVU422, PIXEL_FMT_YCRCB_422_P},
164094332d3Sopenharmony_ci    };
165094332d3Sopenharmony_ci    uint32_t fmtOut = 0;
166094332d3Sopenharmony_ci    for (uint32_t i = 0; i < sizeof(CONVERT_TABLE) / sizeof(CONVERT_TABLE[0]); i++) {
167094332d3Sopenharmony_ci        if (CONVERT_TABLE[i].pixFormat == fmtIn) {
168094332d3Sopenharmony_ci            fmtOut = CONVERT_TABLE[i].drmFormat;
169094332d3Sopenharmony_ci        }
170094332d3Sopenharmony_ci    }
171094332d3Sopenharmony_ci    DISPLAY_LOGD("fmtIn %{public}d : %{public}s, outFmt %{public}d : %{public}s", fmtIn,
172094332d3Sopenharmony_ci        GetPixelFmtStr(fmtIn), fmtOut, GetDrmFmtStr(fmtOut));
173094332d3Sopenharmony_ci    return fmtOut;
174094332d3Sopenharmony_ci}
175094332d3Sopenharmony_ci
176094332d3Sopenharmony_cistatic uint64_t ConvertUsageToGbm(uint64_t inUsage)
177094332d3Sopenharmony_ci{
178094332d3Sopenharmony_ci    uint64_t outUsage = GBM_BO_USE_TEXTURING;
179094332d3Sopenharmony_ci    if (inUsage & HBM_USE_CPU_READ) {
180094332d3Sopenharmony_ci        outUsage |= GBM_BO_USE_SW_READ_OFTEN;
181094332d3Sopenharmony_ci    }
182094332d3Sopenharmony_ci    if (inUsage & HBM_USE_CPU_WRITE) {
183094332d3Sopenharmony_ci        outUsage |= GBM_BO_USE_SW_WRITE_OFTEN;
184094332d3Sopenharmony_ci    }
185094332d3Sopenharmony_ci    DISPLAY_LOGD("outUsage 0x%{public}" PRIx64 "", outUsage);
186094332d3Sopenharmony_ci    return outUsage;
187094332d3Sopenharmony_ci}
188094332d3Sopenharmony_ci
189094332d3Sopenharmony_cistatic int32_t InitGbmDevice(const char *drmFile, GrallocManager *grallocManager)
190094332d3Sopenharmony_ci{
191094332d3Sopenharmony_ci    DISPLAY_LOGD();
192094332d3Sopenharmony_ci    if (grallocManager->gbmDevice == nullptr) {
193094332d3Sopenharmony_ci	    char path[PATH_MAX] = {0};
194094332d3Sopenharmony_ci        if (realpath(drmFile, path) == nullptr) {
195094332d3Sopenharmony_ci            DISPLAY_LOGE(" drm File : %{public}s is not a realpath, errno: %{public}s", drmFile, strerror(errno));
196094332d3Sopenharmony_ci            return HDF_ERR_INVALID_PARAM;
197094332d3Sopenharmony_ci        }
198094332d3Sopenharmony_ci        int drmFd = open(path, O_RDWR);
199094332d3Sopenharmony_ci        if (drmFd < 0) {
200094332d3Sopenharmony_ci            DISPLAY_LOGE("drm file:%{public}s open failed %{public}s", drmFile, strerror(errno));
201094332d3Sopenharmony_ci            return HDF_ERR_BAD_FD;
202094332d3Sopenharmony_ci        }
203094332d3Sopenharmony_ci        drmDropMaster(drmFd);
204094332d3Sopenharmony_ci        struct gbm_device *gbmDevice = HdiGbmCreateDevice(drmFd);
205094332d3Sopenharmony_ci        grallocManager->drmFd = drmFd;
206094332d3Sopenharmony_ci        if (gbmDevice == nullptr) {
207094332d3Sopenharmony_ci            close(drmFd);
208094332d3Sopenharmony_ci            grallocManager->drmFd = -1;
209094332d3Sopenharmony_ci            DISPLAY_LOGE("gbm device create failed");
210094332d3Sopenharmony_ci            return HDF_FAILURE;
211094332d3Sopenharmony_ci        }
212094332d3Sopenharmony_ci        grallocManager->gbmDevice = gbmDevice;
213094332d3Sopenharmony_ci        grallocManager->drmFd = drmFd;
214094332d3Sopenharmony_ci        DListHeadInit(&grallocManager->gbmBoHead);
215094332d3Sopenharmony_ci    }
216094332d3Sopenharmony_ci    return HDF_SUCCESS;
217094332d3Sopenharmony_ci}
218094332d3Sopenharmony_ci
219094332d3Sopenharmony_cistatic void DeInitGbmDevice(GrallocManager *grallocManager)
220094332d3Sopenharmony_ci{
221094332d3Sopenharmony_ci    DISPLAY_LOGD();
222094332d3Sopenharmony_ci    HdiGbmDeviceDestroy(grallocManager->gbmDevice);
223094332d3Sopenharmony_ci    if (grallocManager->drmFd > 0) {
224094332d3Sopenharmony_ci        close(grallocManager->drmFd);
225094332d3Sopenharmony_ci        grallocManager->drmFd = -1;
226094332d3Sopenharmony_ci    }
227094332d3Sopenharmony_ci    grallocManager->gbmDevice = nullptr;
228094332d3Sopenharmony_ci}
229094332d3Sopenharmony_ci
230094332d3Sopenharmony_cistatic int32_t DmaBufferSync(const BufferHandle *handle, bool start)
231094332d3Sopenharmony_ci{
232094332d3Sopenharmony_ci    DISPLAY_LOGD();
233094332d3Sopenharmony_ci    struct dma_buf_sync syncPrm;
234094332d3Sopenharmony_ci    errno_t eok = memset_s(&syncPrm, sizeof(syncPrm), 0, sizeof(syncPrm));
235094332d3Sopenharmony_ci    DISPLAY_CHK_RETURN((eok != EOK), HDF_ERR_INVALID_PARAM, DISPLAY_LOGE("dma buffer sync memset_s failed"));
236094332d3Sopenharmony_ci
237094332d3Sopenharmony_ci    if (handle->usage & HBM_USE_CPU_WRITE) {
238094332d3Sopenharmony_ci        syncPrm.flags |= DMA_BUF_SYNC_WRITE;
239094332d3Sopenharmony_ci    }
240094332d3Sopenharmony_ci
241094332d3Sopenharmony_ci    if (handle->usage & HBM_USE_CPU_READ) {
242094332d3Sopenharmony_ci        syncPrm.flags |= DMA_BUF_SYNC_READ;
243094332d3Sopenharmony_ci    }
244094332d3Sopenharmony_ci
245094332d3Sopenharmony_ci    if (start) {
246094332d3Sopenharmony_ci        syncPrm.flags |= DMA_BUF_SYNC_START;
247094332d3Sopenharmony_ci    } else {
248094332d3Sopenharmony_ci        syncPrm.flags |= DMA_BUF_SYNC_END;
249094332d3Sopenharmony_ci    }
250094332d3Sopenharmony_ci    int retry = 6;
251094332d3Sopenharmony_ci    int ret;
252094332d3Sopenharmony_ci    do {
253094332d3Sopenharmony_ci        ret = ioctl(handle->fd, DMA_BUF_IOCTL_SYNC, &syncPrm);
254094332d3Sopenharmony_ci    } while ((retry--) && (ret != -EAGAIN) && (ret != -EINTR));
255094332d3Sopenharmony_ci
256094332d3Sopenharmony_ci    if (ret < 0) {
257094332d3Sopenharmony_ci        DISPLAY_LOGE("sync failed");
258094332d3Sopenharmony_ci        return HDF_ERR_DEVICE_BUSY;
259094332d3Sopenharmony_ci    }
260094332d3Sopenharmony_ci    return HDF_SUCCESS;
261094332d3Sopenharmony_ci}
262094332d3Sopenharmony_ci
263094332d3Sopenharmony_cistatic void InitBufferHandle(struct gbm_bo *bo, int fd, const AllocInfo *info, PriBufferHandle *buffer)
264094332d3Sopenharmony_ci{
265094332d3Sopenharmony_ci    BufferHandle *bufferHandle = &(buffer->hdl);
266094332d3Sopenharmony_ci    bufferHandle->fd = fd;
267094332d3Sopenharmony_ci    bufferHandle->reserveFds = 0;
268094332d3Sopenharmony_ci    bufferHandle->reserveInts = 0;
269094332d3Sopenharmony_ci    bufferHandle->stride = HdiGbmBoGetStride(bo);
270094332d3Sopenharmony_ci    bufferHandle->width = HdiGbmBoGetWidth(bo);
271094332d3Sopenharmony_ci    bufferHandle->height = HdiGbmBoGetHeight(bo);
272094332d3Sopenharmony_ci    bufferHandle->usage = info->usage;
273094332d3Sopenharmony_ci    bufferHandle->format = info->format;
274094332d3Sopenharmony_ci    bufferHandle->virAddr = nullptr;
275094332d3Sopenharmony_ci    bufferHandle->size = HdiGbmBoGetSize(bo);
276094332d3Sopenharmony_ci}
277094332d3Sopenharmony_ci
278094332d3Sopenharmony_ciint32_t GbmAllocMem(const AllocInfo *info, BufferHandle **buffer)
279094332d3Sopenharmony_ci{
280094332d3Sopenharmony_ci    DISPLAY_CHK_RETURN((info == nullptr), HDF_FAILURE, DISPLAY_LOGE("info is null"));
281094332d3Sopenharmony_ci    DISPLAY_CHK_RETURN((buffer == nullptr), HDF_FAILURE, DISPLAY_LOGE("buffer is null"));
282094332d3Sopenharmony_ci    PriBufferHandle *priBuffer = nullptr;
283094332d3Sopenharmony_ci    uint32_t drmFmt = ConvertFormatToDrm(static_cast<PixelFormat>(info->format));
284094332d3Sopenharmony_ci    DISPLAY_CHK_RETURN((drmFmt == INVALID_PIXEL_FMT), HDF_ERR_NOT_SUPPORT,
285094332d3Sopenharmony_ci        DISPLAY_LOGE("format %{public}d can not support", info->format));
286094332d3Sopenharmony_ci    DISPLAY_LOGD("requeset width %{public}d, heigt %{public}d, format %{public}d",
287094332d3Sopenharmony_ci        info->width, info->height, drmFmt);
288094332d3Sopenharmony_ci
289094332d3Sopenharmony_ci        GRALLOC_LOCK();
290094332d3Sopenharmony_ci    GrallocManager *grallocManager = GetGrallocManager();
291094332d3Sopenharmony_ci    DISPLAY_CHK_RETURN((grallocManager == nullptr), HDF_ERR_INVALID_PARAM, DISPLAY_LOGE("gralloc manager failed");
292094332d3Sopenharmony_ci        GRALLOC_UNLOCK());
293094332d3Sopenharmony_ci    struct gbm_bo *bo =
294094332d3Sopenharmony_ci        HdiGbmBoCreate(grallocManager->gbmDevice, info->width, info->height, drmFmt, ConvertUsageToGbm(info->usage));
295094332d3Sopenharmony_ci    DISPLAY_CHK_RETURN((bo == nullptr), HDF_DEV_ERR_NO_MEMORY, DISPLAY_LOGE("gbm create bo failed"); \
296094332d3Sopenharmony_ci        GRALLOC_UNLOCK());
297094332d3Sopenharmony_ci
298094332d3Sopenharmony_ci    int fd = HdiGbmBoGetFd(bo);
299094332d3Sopenharmony_ci    DISPLAY_CHK_RETURN((fd < 0), HDF_ERR_BAD_FD, DISPLAY_LOGE("gbm can not get fd"); \
300094332d3Sopenharmony_ci        HdiGbmBoDestroy(bo); \
301094332d3Sopenharmony_ci        GRALLOC_UNLOCK());
302094332d3Sopenharmony_ci
303094332d3Sopenharmony_ci    errno_t eok = EOK;
304094332d3Sopenharmony_ci    priBuffer = (PriBufferHandle *)malloc(sizeof(PriBufferHandle));
305094332d3Sopenharmony_ci    if (priBuffer == nullptr) {
306094332d3Sopenharmony_ci        DISPLAY_LOGE("bufferhandle malloc failed");
307094332d3Sopenharmony_ci        goto error;
308094332d3Sopenharmony_ci    }
309094332d3Sopenharmony_ci
310094332d3Sopenharmony_ci    eok = memset_s(priBuffer, sizeof(PriBufferHandle), 0, sizeof(PriBufferHandle));
311094332d3Sopenharmony_ci    if (eok != EOK) {
312094332d3Sopenharmony_ci        DISPLAY_LOGE("memset_s failed");
313094332d3Sopenharmony_ci        goto error;
314094332d3Sopenharmony_ci    }
315094332d3Sopenharmony_ci    DISPLAY_CHK_RETURN((eok != EOK), DISPLAY_PARAM_ERR, DISPLAY_LOGE("memset_s failed"));
316094332d3Sopenharmony_ci
317094332d3Sopenharmony_ci    InitBufferHandle(bo, fd, info, priBuffer);
318094332d3Sopenharmony_ci    *buffer = &priBuffer->hdl;
319094332d3Sopenharmony_ci    HdiGbmBoDestroy(bo);
320094332d3Sopenharmony_ci    GRALLOC_UNLOCK();
321094332d3Sopenharmony_ci    return HDF_SUCCESS;
322094332d3Sopenharmony_cierror:
323094332d3Sopenharmony_ci    close(fd);
324094332d3Sopenharmony_ci    HdiGbmBoDestroy(bo);
325094332d3Sopenharmony_ci    if (priBuffer != nullptr) {
326094332d3Sopenharmony_ci        free(priBuffer);
327094332d3Sopenharmony_ci    }
328094332d3Sopenharmony_ci    GRALLOC_UNLOCK();
329094332d3Sopenharmony_ci    return HDF_FAILURE;
330094332d3Sopenharmony_ci}
331094332d3Sopenharmony_ci
332094332d3Sopenharmony_cistatic void CloseBufferHandle(BufferHandle *handle)
333094332d3Sopenharmony_ci{
334094332d3Sopenharmony_ci    DISPLAY_CHK_RETURN_NOT_VALUE((handle == nullptr), DISPLAY_LOGE("buffer is null"));
335094332d3Sopenharmony_ci    if (handle->fd >= 0) {
336094332d3Sopenharmony_ci        close(handle->fd);
337094332d3Sopenharmony_ci        handle->fd = -1;
338094332d3Sopenharmony_ci    }
339094332d3Sopenharmony_ci    const uint32_t reserveFds = handle->reserveFds;
340094332d3Sopenharmony_ci    for (uint32_t i = 0; i < reserveFds; i++) {
341094332d3Sopenharmony_ci        if (handle->reserve[i] >= 0) {
342094332d3Sopenharmony_ci            close(handle->reserve[i]);
343094332d3Sopenharmony_ci            handle->reserve[i] = -1;
344094332d3Sopenharmony_ci        }
345094332d3Sopenharmony_ci    }
346094332d3Sopenharmony_ci}
347094332d3Sopenharmony_ci
348094332d3Sopenharmony_civoid GbmFreeMem(BufferHandle *buffer)
349094332d3Sopenharmony_ci{
350094332d3Sopenharmony_ci    DISPLAY_LOGD();
351094332d3Sopenharmony_ci    DISPLAY_CHK_RETURN_NOT_VALUE((buffer == nullptr), DISPLAY_LOGE("buffer is null"));
352094332d3Sopenharmony_ci    if ((buffer->virAddr != nullptr) && (GbmUnmap(buffer) != HDF_SUCCESS)) {
353094332d3Sopenharmony_ci        DISPLAY_LOGE("freeMem unmap buffer failed");
354094332d3Sopenharmony_ci    }
355094332d3Sopenharmony_ci    CloseBufferHandle(buffer);
356094332d3Sopenharmony_ci    free(buffer);
357094332d3Sopenharmony_ci}
358094332d3Sopenharmony_ci
359094332d3Sopenharmony_civoid *GbmMmap(BufferHandle *buffer)
360094332d3Sopenharmony_ci{
361094332d3Sopenharmony_ci    void *virAddr = nullptr;
362094332d3Sopenharmony_ci    DISPLAY_LOGD();
363094332d3Sopenharmony_ci    if (buffer == nullptr) {
364094332d3Sopenharmony_ci        DISPLAY_LOGE("gbmmap the buffer handle is nullptr");
365094332d3Sopenharmony_ci        return nullptr;
366094332d3Sopenharmony_ci    }
367094332d3Sopenharmony_ci    if (buffer->virAddr != nullptr) {
368094332d3Sopenharmony_ci        DISPLAY_LOGD("the buffer has virtual addr");
369094332d3Sopenharmony_ci        return buffer->virAddr;
370094332d3Sopenharmony_ci    }
371094332d3Sopenharmony_ci    virAddr = mmap(nullptr, buffer->size, PROT_READ | PROT_WRITE, MAP_SHARED, buffer->fd, 0);
372094332d3Sopenharmony_ci    if (virAddr == reinterpret_cast<void *>(MAP_FAILED)) {
373094332d3Sopenharmony_ci        DISPLAY_LOGE("mmap failed errno %{public}s, fd : %{public}d", strerror(errno), buffer->fd);
374094332d3Sopenharmony_ci    }
375094332d3Sopenharmony_ci    buffer->virAddr = virAddr;
376094332d3Sopenharmony_ci    return virAddr;
377094332d3Sopenharmony_ci}
378094332d3Sopenharmony_ci
379094332d3Sopenharmony_ciint32_t GbmUnmap(BufferHandle *buffer)
380094332d3Sopenharmony_ci{
381094332d3Sopenharmony_ci    DISPLAY_LOGD();
382094332d3Sopenharmony_ci    if (buffer == nullptr) {
383094332d3Sopenharmony_ci        DISPLAY_LOGE("gbmumap the buffer handle is null");
384094332d3Sopenharmony_ci        return HDF_FAILURE;
385094332d3Sopenharmony_ci    }
386094332d3Sopenharmony_ci
387094332d3Sopenharmony_ci    if (buffer->virAddr == nullptr) {
388094332d3Sopenharmony_ci        DISPLAY_LOGE("virAddr is nullptr , has not map the buffer");
389094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
390094332d3Sopenharmony_ci    }
391094332d3Sopenharmony_ci    int ret = munmap(buffer->virAddr, buffer->size);
392094332d3Sopenharmony_ci    if (ret != 0) {
393094332d3Sopenharmony_ci        DISPLAY_LOGE("munmap failed err: %{public}s", strerror(errno));
394094332d3Sopenharmony_ci        return HDF_FAILURE;
395094332d3Sopenharmony_ci    }
396094332d3Sopenharmony_ci    buffer->virAddr = nullptr;
397094332d3Sopenharmony_ci    return HDF_SUCCESS;
398094332d3Sopenharmony_ci}
399094332d3Sopenharmony_ci
400094332d3Sopenharmony_ciint32_t GbmInvalidateCache(BufferHandle *buffer)
401094332d3Sopenharmony_ci{
402094332d3Sopenharmony_ci    DISPLAY_LOGD();
403094332d3Sopenharmony_ci    return DmaBufferSync(buffer, true);
404094332d3Sopenharmony_ci}
405094332d3Sopenharmony_ci
406094332d3Sopenharmony_ciint32_t GbmFlushCache(BufferHandle *buffer)
407094332d3Sopenharmony_ci{
408094332d3Sopenharmony_ci    DISPLAY_LOGD();
409094332d3Sopenharmony_ci    return DmaBufferSync(buffer, false);
410094332d3Sopenharmony_ci}
411094332d3Sopenharmony_ci
412094332d3Sopenharmony_ciint32_t GbmGrallocUninitialize(void)
413094332d3Sopenharmony_ci{
414094332d3Sopenharmony_ci    DISPLAY_LOGD();
415094332d3Sopenharmony_ci    GRALLOC_LOCK();
416094332d3Sopenharmony_ci    GrallocManager *grallocManager = GetGrallocManager();
417094332d3Sopenharmony_ci    DISPLAY_CHK_RETURN((grallocManager == nullptr), HDF_ERR_INVALID_PARAM, DISPLAY_LOGE("gralloc manager failed"); \
418094332d3Sopenharmony_ci        GRALLOC_UNLOCK());
419094332d3Sopenharmony_ci    grallocManager->referCount--;
420094332d3Sopenharmony_ci    if (grallocManager->referCount < 0) {
421094332d3Sopenharmony_ci        DeInitGbmDevice(grallocManager);
422094332d3Sopenharmony_ci        free(g_grallocManager);
423094332d3Sopenharmony_ci        g_grallocManager = nullptr;
424094332d3Sopenharmony_ci    }
425094332d3Sopenharmony_ci    GRALLOC_UNLOCK();
426094332d3Sopenharmony_ci    return HDF_SUCCESS;
427094332d3Sopenharmony_ci}
428094332d3Sopenharmony_ci
429094332d3Sopenharmony_ciint32_t GbmGrallocInitialize(void)
430094332d3Sopenharmony_ci{
431094332d3Sopenharmony_ci    DISPLAY_LOGD();
432094332d3Sopenharmony_ci    GRALLOC_LOCK();
433094332d3Sopenharmony_ci    GrallocManager *grallocManager = GetGrallocManager();
434094332d3Sopenharmony_ci    DISPLAY_CHK_RETURN((grallocManager == nullptr), HDF_ERR_INVALID_PARAM, DISPLAY_LOGE("gralloc manager failed"); \
435094332d3Sopenharmony_ci        GRALLOC_UNLOCK());
436094332d3Sopenharmony_ci    int ret = InitGbmDevice(g_drmFileNode, grallocManager);
437094332d3Sopenharmony_ci    DISPLAY_CHK_RETURN((ret != HDF_SUCCESS), ret, DISPLAY_LOGE("gralloc manager failed"); \
438094332d3Sopenharmony_ci        GRALLOC_UNLOCK());
439094332d3Sopenharmony_ci    grallocManager->referCount++;
440094332d3Sopenharmony_ci    GRALLOC_UNLOCK();
441094332d3Sopenharmony_ci    return HDF_SUCCESS;
442094332d3Sopenharmony_ci}
443094332d3Sopenharmony_ci} // namespace DISPLAY
444094332d3Sopenharmony_ci} // namespace HDI
445094332d3Sopenharmony_ci} // namespace OHOS
446