1094332d3Sopenharmony_ci/*
2094332d3Sopenharmony_ci * Copyright (c) 2021 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.h"
17094332d3Sopenharmony_ci#include <cerrno>
18094332d3Sopenharmony_ci#include <inttypes.h>
19094332d3Sopenharmony_ci#include <pthread.h>
20094332d3Sopenharmony_ci#include <stdio.h>
21094332d3Sopenharmony_ci#include <sys/mman.h>
22094332d3Sopenharmony_ci#include <sys/shm.h>
23094332d3Sopenharmony_ci#include <securec.h>
24094332d3Sopenharmony_ci#include "buffer_handle.h"
25094332d3Sopenharmony_ci#include "display_type.h"
26094332d3Sopenharmony_ci#include "disp_common.h"
27094332d3Sopenharmony_ci#include "hdf_log.h"
28094332d3Sopenharmony_ci#include "osal_mem.h"
29094332d3Sopenharmony_ci
30094332d3Sopenharmony_ci#define DEFAULT_READ_WRITE_PERMISSIONS   0666
31094332d3Sopenharmony_ci#define MAX_MALLOC_SIZE                  0x10000000L
32094332d3Sopenharmony_ci#define SHM_MAX_KEY                      10000
33094332d3Sopenharmony_ci#define SHM_START_KEY                    1
34094332d3Sopenharmony_ci#define INVALID_SHMID -1
35094332d3Sopenharmony_ci#define BITS_PER_BYTE 8
36094332d3Sopenharmony_ci
37094332d3Sopenharmony_ci#define DIV_ROUND_UP(n, d)   (((n) + (d) - 1) / (d))
38094332d3Sopenharmony_ci#define ALIGN_UP(x, a)       ((((x) + ((a) - 1)) / (a)) * (a))
39094332d3Sopenharmony_ci#define HEIGHT_ALIGN         2U
40094332d3Sopenharmony_ci#define WIDTH_ALIGN          8U
41094332d3Sopenharmony_ci#define MAX_PLANES           3
42094332d3Sopenharmony_ci
43094332d3Sopenharmony_ci#undef  HDF_LOG_TAG
44094332d3Sopenharmony_ci#define HDF_LOG_TAG          display_gralloc_c
45094332d3Sopenharmony_ci
46094332d3Sopenharmony_citypedef struct {
47094332d3Sopenharmony_ci    BufferHandle hdl;
48094332d3Sopenharmony_ci    int32_t shmid;
49094332d3Sopenharmony_ci} PriBufferHandle;
50094332d3Sopenharmony_ci
51094332d3Sopenharmony_citypedef struct {
52094332d3Sopenharmony_ci    uint32_t numPlanes;
53094332d3Sopenharmony_ci    uint32_t radio[MAX_PLANES];
54094332d3Sopenharmony_ci} PlaneLayoutInfo;
55094332d3Sopenharmony_ci
56094332d3Sopenharmony_citypedef struct {
57094332d3Sopenharmony_ci    uint32_t format;
58094332d3Sopenharmony_ci    uint32_t bitsPerPixel; // bits per pixel for first plane
59094332d3Sopenharmony_ci    const PlaneLayoutInfo *planes;
60094332d3Sopenharmony_ci} FormatInfo;
61094332d3Sopenharmony_ci
62094332d3Sopenharmony_cistruct GrallocManager {
63094332d3Sopenharmony_ci    pthread_mutex_t mutex;
64094332d3Sopenharmony_ci    pthread_mutexattr_t mutexattr;
65094332d3Sopenharmony_ci    int32_t count;
66094332d3Sopenharmony_ci};
67094332d3Sopenharmony_ci
68094332d3Sopenharmony_cistatic struct GrallocManager g_grallocManager;
69094332d3Sopenharmony_ci
70094332d3Sopenharmony_cistatic const PlaneLayoutInfo g_yuv420SPLayout = {
71094332d3Sopenharmony_ci    .numPlanes = 2,
72094332d3Sopenharmony_ci    .radio = { 4, 2 },
73094332d3Sopenharmony_ci};
74094332d3Sopenharmony_ci
75094332d3Sopenharmony_cistatic const PlaneLayoutInfo g_yuv420PLayout = {
76094332d3Sopenharmony_ci    .numPlanes = 3,
77094332d3Sopenharmony_ci    .radio = { 4, 1, 1 },
78094332d3Sopenharmony_ci};
79094332d3Sopenharmony_ci
80094332d3Sopenharmony_cistatic void GetGrallocMgr(void)
81094332d3Sopenharmony_ci{
82094332d3Sopenharmony_ci    g_grallocManager.count++;
83094332d3Sopenharmony_ci}
84094332d3Sopenharmony_ci
85094332d3Sopenharmony_cistatic int32_t PutGrallocMgr(void)
86094332d3Sopenharmony_ci{
87094332d3Sopenharmony_ci    g_grallocManager.count--;
88094332d3Sopenharmony_ci    return g_grallocManager.count;
89094332d3Sopenharmony_ci}
90094332d3Sopenharmony_ci
91094332d3Sopenharmony_cistatic void LockGrallocMgr(void)
92094332d3Sopenharmony_ci{
93094332d3Sopenharmony_ci    pthread_mutex_lock(&g_grallocManager.mutex);
94094332d3Sopenharmony_ci}
95094332d3Sopenharmony_ci
96094332d3Sopenharmony_cistatic void UnlockGrallocMgr(void)
97094332d3Sopenharmony_ci{
98094332d3Sopenharmony_ci    pthread_mutex_unlock(&g_grallocManager.mutex);
99094332d3Sopenharmony_ci}
100094332d3Sopenharmony_ci
101094332d3Sopenharmony_cistatic const FormatInfo *GetFormatInfo(uint32_t format)
102094332d3Sopenharmony_ci{
103094332d3Sopenharmony_ci    static const FormatInfo fmtInfos[] = {
104094332d3Sopenharmony_ci        {PIXEL_FMT_RGBX_8888,  32, NULL},  {PIXEL_FMT_RGBA_8888, 32,  NULL},
105094332d3Sopenharmony_ci        {PIXEL_FMT_BGRX_8888,  32, NULL},  {PIXEL_FMT_BGRA_8888, 32,  NULL},
106094332d3Sopenharmony_ci        {PIXEL_FMT_RGB_888,    24, NULL},  {PIXEL_FMT_BGR_565,   16,  NULL},
107094332d3Sopenharmony_ci        {PIXEL_FMT_RGBA_5551,  16, NULL},  {PIXEL_FMT_RGB_565,   16,  NULL},
108094332d3Sopenharmony_ci        {PIXEL_FMT_BGRX_4444,  16, NULL},  {PIXEL_FMT_BGRA_4444, 16,  NULL},
109094332d3Sopenharmony_ci        {PIXEL_FMT_RGBA_4444,  16, NULL},  {PIXEL_FMT_RGBX_4444, 16,  NULL},
110094332d3Sopenharmony_ci        {PIXEL_FMT_BGRX_5551,  16, NULL},  {PIXEL_FMT_BGRA_5551, 16,  NULL},
111094332d3Sopenharmony_ci        {PIXEL_FMT_YCBCR_420_SP, 8, &g_yuv420SPLayout}, {PIXEL_FMT_YCRCB_420_SP, 8, &g_yuv420SPLayout},
112094332d3Sopenharmony_ci        {PIXEL_FMT_YCBCR_420_P, 8, &g_yuv420PLayout}, {PIXEL_FMT_YCRCB_420_P, 8, &g_yuv420PLayout},
113094332d3Sopenharmony_ci    };
114094332d3Sopenharmony_ci
115094332d3Sopenharmony_ci    for (uint32_t i = 0; i < sizeof(fmtInfos) / sizeof(FormatInfo); i++) {
116094332d3Sopenharmony_ci        if (fmtInfos[i].format == format) {
117094332d3Sopenharmony_ci            return &fmtInfos[i];
118094332d3Sopenharmony_ci        }
119094332d3Sopenharmony_ci    }
120094332d3Sopenharmony_ci    HDF_LOGE("the format can not support %d %d", format, PIXEL_FMT_RGBA_8888);
121094332d3Sopenharmony_ci    return NULL;
122094332d3Sopenharmony_ci}
123094332d3Sopenharmony_ci
124094332d3Sopenharmony_cistatic uint32_t AdjustStrideFromFormat(uint32_t format, uint32_t width)
125094332d3Sopenharmony_ci{
126094332d3Sopenharmony_ci    const FormatInfo *fmtInfo = GetFormatInfo(format);
127094332d3Sopenharmony_ci    if ((fmtInfo != NULL) && (fmtInfo->planes != NULL)) {
128094332d3Sopenharmony_ci        uint32_t sum = fmtInfo->planes->radio[0];
129094332d3Sopenharmony_ci        for (uint32_t i = 1; (i < fmtInfo->planes->numPlanes) && (i < MAX_PLANES); i++) {
130094332d3Sopenharmony_ci            sum += fmtInfo->planes->radio[i];
131094332d3Sopenharmony_ci        }
132094332d3Sopenharmony_ci        if (sum > 0) {
133094332d3Sopenharmony_ci            width = DIV_ROUND_UP((width * sum), fmtInfo->planes->radio[0]);
134094332d3Sopenharmony_ci        }
135094332d3Sopenharmony_ci    }
136094332d3Sopenharmony_ci    return width;
137094332d3Sopenharmony_ci}
138094332d3Sopenharmony_ci
139094332d3Sopenharmony_cistatic int32_t InitBufferHandle(PriBufferHandle* buffer, const AllocInfo* info)
140094332d3Sopenharmony_ci{
141094332d3Sopenharmony_ci    int32_t size;
142094332d3Sopenharmony_ci    int32_t stride;
143094332d3Sopenharmony_ci    int32_t h = ALIGN_UP(info->height, HEIGHT_ALIGN);
144094332d3Sopenharmony_ci    const FormatInfo *fmtInfo = GetFormatInfo(info->format);
145094332d3Sopenharmony_ci    if (fmtInfo == NULL) {
146094332d3Sopenharmony_ci        HDF_LOGE("can not get format information : %d", buffer->hdl.format);
147094332d3Sopenharmony_ci        return DISPLAY_FAILURE;
148094332d3Sopenharmony_ci    }
149094332d3Sopenharmony_ci
150094332d3Sopenharmony_ci    stride = ALIGN_UP(AdjustStrideFromFormat(info->format, info->width), WIDTH_ALIGN) *
151094332d3Sopenharmony_ci        fmtInfo->bitsPerPixel / BITS_PER_BYTE;
152094332d3Sopenharmony_ci    size = h * stride;
153094332d3Sopenharmony_ci    buffer->hdl.width = info->width;
154094332d3Sopenharmony_ci    buffer->hdl.stride = stride;
155094332d3Sopenharmony_ci    buffer->hdl.height = info->height;
156094332d3Sopenharmony_ci    buffer->hdl.size = size;
157094332d3Sopenharmony_ci    buffer->hdl.usage = info->usage;
158094332d3Sopenharmony_ci    buffer->hdl.fd = -1;
159094332d3Sopenharmony_ci    buffer->shmid = INVALID_SHMID;
160094332d3Sopenharmony_ci    buffer->hdl.format = info->format;
161094332d3Sopenharmony_ci    buffer->hdl.reserveInts = (sizeof(PriBufferHandle) - sizeof(BufferHandle) -
162094332d3Sopenharmony_ci        buffer->hdl.reserveFds * sizeof(uint32_t)) / sizeof(uint32_t);
163094332d3Sopenharmony_ci    return DISPLAY_SUCCESS;
164094332d3Sopenharmony_ci}
165094332d3Sopenharmony_ci
166094332d3Sopenharmony_cistatic int32_t AllocShm(BufferHandle *buffer)
167094332d3Sopenharmony_ci{
168094332d3Sopenharmony_ci    static int32_t key = SHM_START_KEY;
169094332d3Sopenharmony_ci    int32_t shmid;
170094332d3Sopenharmony_ci
171094332d3Sopenharmony_ci    while ((shmid = shmget(key, buffer->size, IPC_CREAT | IPC_EXCL | DEFAULT_READ_WRITE_PERMISSIONS)) < 0) {
172094332d3Sopenharmony_ci        if (errno != EEXIST) {
173094332d3Sopenharmony_ci            HDF_LOGE("%s: fail to alloc the shared memory, errno = %d", __func__, errno);
174094332d3Sopenharmony_ci            return DISPLAY_FAILURE;
175094332d3Sopenharmony_ci        }
176094332d3Sopenharmony_ci        key++;
177094332d3Sopenharmony_ci        if (key >= SHM_MAX_KEY) {
178094332d3Sopenharmony_ci            key = SHM_START_KEY;
179094332d3Sopenharmony_ci        }
180094332d3Sopenharmony_ci    }
181094332d3Sopenharmony_ci    void *pBase = shmat(shmid, NULL, 0);
182094332d3Sopenharmony_ci    if (pBase == ((void *)-1)) {
183094332d3Sopenharmony_ci        HDF_LOGE("%s: Fail to attach the shared memory, errno = %d", __func__, errno);
184094332d3Sopenharmony_ci        if (shmctl(shmid, IPC_RMID, 0) == -1) {
185094332d3Sopenharmony_ci            HDF_LOGE("%s: Fail to free shmid, errno = %d", __func__, errno);
186094332d3Sopenharmony_ci        }
187094332d3Sopenharmony_ci        return DISPLAY_FAILURE;
188094332d3Sopenharmony_ci    }
189094332d3Sopenharmony_ci    buffer->virAddr = pBase;
190094332d3Sopenharmony_ci    buffer->fd = key;
191094332d3Sopenharmony_ci    ((PriBufferHandle*)buffer)->shmid = shmid;
192094332d3Sopenharmony_ci    key++;
193094332d3Sopenharmony_ci    if (memset_s(pBase, buffer->size, 0x0, buffer->size) != EOK) {
194094332d3Sopenharmony_ci        HDF_LOGE("memset_s failure");
195094332d3Sopenharmony_ci        if (shmctl(shmid, IPC_RMID, 0) == -1) {
196094332d3Sopenharmony_ci            HDF_LOGE("%s: Fail to free shmid, errno = %d", __func__, errno);
197094332d3Sopenharmony_ci        }
198094332d3Sopenharmony_ci        return DISPLAY_FAILURE;
199094332d3Sopenharmony_ci    }
200094332d3Sopenharmony_ci    if (key >= SHM_MAX_KEY) {
201094332d3Sopenharmony_ci        key = SHM_START_KEY;
202094332d3Sopenharmony_ci    }
203094332d3Sopenharmony_ci    return DISPLAY_SUCCESS;
204094332d3Sopenharmony_ci}
205094332d3Sopenharmony_ci
206094332d3Sopenharmony_cistatic int32_t AllocMem(const AllocInfo* info, BufferHandle **buffer)
207094332d3Sopenharmony_ci{
208094332d3Sopenharmony_ci    int32_t ret;
209094332d3Sopenharmony_ci    DISPLAY_CHK_RETURN((buffer == NULL), DISPLAY_NULL_PTR, HDF_LOGE("%s: in buffer is null", __func__));
210094332d3Sopenharmony_ci    DISPLAY_CHK_RETURN((info == NULL), DISPLAY_NULL_PTR, HDF_LOGE("%s: in info is null", __func__));
211094332d3Sopenharmony_ci    PriBufferHandle* priBuffer = (PriBufferHandle*)calloc(1, sizeof(PriBufferHandle));
212094332d3Sopenharmony_ci    DISPLAY_CHK_RETURN((priBuffer == NULL), DISPLAY_NULL_PTR, HDF_LOGE("%s: can not calloc errno : %d",
213094332d3Sopenharmony_ci        __func__, errno));
214094332d3Sopenharmony_ci    ret = InitBufferHandle(priBuffer, info);
215094332d3Sopenharmony_ci    DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, HDF_LOGE("%s: can not init buffe handle",
216094332d3Sopenharmony_ci        __func__); goto OUT);
217094332d3Sopenharmony_ci
218094332d3Sopenharmony_ci    BufferHandle *bufferHdl = &priBuffer->hdl;
219094332d3Sopenharmony_ci    DISPLAY_CHK_RETURN(((bufferHdl->size > MAX_MALLOC_SIZE) || (bufferHdl->size == 0)),
220094332d3Sopenharmony_ci        DISPLAY_FAILURE, HDF_LOGE("%s: size is invalid %d ", __func__, bufferHdl->size); goto OUT);
221094332d3Sopenharmony_ci    LockGrallocMgr();
222094332d3Sopenharmony_ci    if (bufferHdl->usage == HBM_USE_MEM_SHARE) {
223094332d3Sopenharmony_ci        ret = AllocShm(bufferHdl);
224094332d3Sopenharmony_ci    } else {
225094332d3Sopenharmony_ci        HDF_LOGE("%s: not support memory usage: 0x%" PRIx64 "", __func__, bufferHdl->usage);
226094332d3Sopenharmony_ci        ret = DISPLAY_NOT_SUPPORT;
227094332d3Sopenharmony_ci    }
228094332d3Sopenharmony_ci
229094332d3Sopenharmony_ciOUT:
230094332d3Sopenharmony_ci    if ((ret != DISPLAY_SUCCESS) && (bufferHdl != NULL)) {
231094332d3Sopenharmony_ci        free(bufferHdl);
232094332d3Sopenharmony_ci        bufferHdl = NULL;
233094332d3Sopenharmony_ci    }
234094332d3Sopenharmony_ci    *buffer = bufferHdl;
235094332d3Sopenharmony_ci    UnlockGrallocMgr();
236094332d3Sopenharmony_ci    return ret;
237094332d3Sopenharmony_ci}
238094332d3Sopenharmony_ci
239094332d3Sopenharmony_cistatic void FreeShm(BufferHandle *buffer)
240094332d3Sopenharmony_ci{
241094332d3Sopenharmony_ci    CHECK_NULLPOINTER_RETURN(buffer->virAddr);
242094332d3Sopenharmony_ci    if (shmdt(buffer->virAddr) == -1) {
243094332d3Sopenharmony_ci        HDF_LOGE("%s: Fail to free shared memory, errno = %d", __func__, errno);
244094332d3Sopenharmony_ci    }
245094332d3Sopenharmony_ci    if (shmctl(((PriBufferHandle*)buffer)->shmid, IPC_RMID, 0) == -1) {
246094332d3Sopenharmony_ci        HDF_LOGE("%s: Fail to free shmid, errno = %d", __func__, errno);
247094332d3Sopenharmony_ci    }
248094332d3Sopenharmony_ci}
249094332d3Sopenharmony_ci
250094332d3Sopenharmony_cistatic void FreeMem(BufferHandle *buffer)
251094332d3Sopenharmony_ci{
252094332d3Sopenharmony_ci    CHECK_NULLPOINTER_RETURN(buffer);
253094332d3Sopenharmony_ci    if ((buffer->size > MAX_MALLOC_SIZE) || (buffer->size == 0)) {
254094332d3Sopenharmony_ci        HDF_LOGE("%s: size is invalid, buffer->size = %d", __func__, buffer->size);
255094332d3Sopenharmony_ci        return;
256094332d3Sopenharmony_ci    }
257094332d3Sopenharmony_ci
258094332d3Sopenharmony_ci    LockGrallocMgr();
259094332d3Sopenharmony_ci    if (buffer->usage == HBM_USE_MEM_SHARE) {
260094332d3Sopenharmony_ci        FreeShm(buffer);
261094332d3Sopenharmony_ci    } else {
262094332d3Sopenharmony_ci        HDF_LOGE("%s: not support memory usage: 0x%" PRIx64 "", __func__, buffer->usage);
263094332d3Sopenharmony_ci    }
264094332d3Sopenharmony_ci    UnlockGrallocMgr();
265094332d3Sopenharmony_ci}
266094332d3Sopenharmony_ci
267094332d3Sopenharmony_cistatic void *MmapShm(BufferHandle *buffer)
268094332d3Sopenharmony_ci{
269094332d3Sopenharmony_ci    int32_t shmid;
270094332d3Sopenharmony_ci
271094332d3Sopenharmony_ci    shmid = shmget(buffer->fd, buffer->size, IPC_EXCL | DEFAULT_READ_WRITE_PERMISSIONS);
272094332d3Sopenharmony_ci    if (shmid < 0) {
273094332d3Sopenharmony_ci        HDF_LOGE("%s: Fail to mmap the shared memory, errno = %d", __func__, errno);
274094332d3Sopenharmony_ci        return NULL;
275094332d3Sopenharmony_ci    }
276094332d3Sopenharmony_ci    void *pBase = shmat(shmid, NULL, 0);
277094332d3Sopenharmony_ci    if (pBase == ((void *)-1)) {
278094332d3Sopenharmony_ci        HDF_LOGE("%s: Fail to attach the shared memory, errno = %d", __func__, errno);
279094332d3Sopenharmony_ci        return NULL;
280094332d3Sopenharmony_ci    }
281094332d3Sopenharmony_ci    ((PriBufferHandle*)buffer)->shmid = shmid;
282094332d3Sopenharmony_ci    HDF_LOGI("%s: Mmap shared memory succeed", __func__);
283094332d3Sopenharmony_ci    return pBase;
284094332d3Sopenharmony_ci}
285094332d3Sopenharmony_ci
286094332d3Sopenharmony_cistatic void *Mmap(BufferHandle *buffer)
287094332d3Sopenharmony_ci{
288094332d3Sopenharmony_ci    void *temp = NULL;
289094332d3Sopenharmony_ci
290094332d3Sopenharmony_ci    CHECK_NULLPOINTER_RETURN_VALUE(buffer, NULL);
291094332d3Sopenharmony_ci    if ((buffer->size > MAX_MALLOC_SIZE) || (buffer->size == 0)) {
292094332d3Sopenharmony_ci        HDF_LOGE("%s: size is invalid, buffer->size = %d", __func__, buffer->size);
293094332d3Sopenharmony_ci        return NULL;
294094332d3Sopenharmony_ci    }
295094332d3Sopenharmony_ci
296094332d3Sopenharmony_ci    LockGrallocMgr();
297094332d3Sopenharmony_ci    if (buffer->usage == HBM_USE_MEM_SHARE) {
298094332d3Sopenharmony_ci        temp = MmapShm(buffer);
299094332d3Sopenharmony_ci    } else {
300094332d3Sopenharmony_ci        HDF_LOGE("%s: not support memory usage: 0x%" PRIx64 "", __func__, buffer->usage);
301094332d3Sopenharmony_ci    }
302094332d3Sopenharmony_ci    UnlockGrallocMgr();
303094332d3Sopenharmony_ci    return temp;
304094332d3Sopenharmony_ci}
305094332d3Sopenharmony_ci
306094332d3Sopenharmony_cistatic int32_t UnmapShm(BufferHandle *buffer)
307094332d3Sopenharmony_ci{
308094332d3Sopenharmony_ci    if (shmdt(buffer->virAddr) == -1) {
309094332d3Sopenharmony_ci        HDF_LOGE("%s: Fail to unmap shared memory errno =  %d", __func__, errno);
310094332d3Sopenharmony_ci        return DISPLAY_FAILURE;
311094332d3Sopenharmony_ci    }
312094332d3Sopenharmony_ci    int32_t shmid = ((PriBufferHandle*)buffer)->shmid;
313094332d3Sopenharmony_ci    if ((shmid != INVALID_SHMID) && (shmctl(shmid, IPC_RMID, 0) == -1)) {
314094332d3Sopenharmony_ci        HDF_LOGE("%s: Fail to free shmid, errno = %d", __func__, errno);
315094332d3Sopenharmony_ci    }
316094332d3Sopenharmony_ci    return DISPLAY_SUCCESS;
317094332d3Sopenharmony_ci}
318094332d3Sopenharmony_ci
319094332d3Sopenharmony_cistatic int32_t Unmap(BufferHandle *buffer)
320094332d3Sopenharmony_ci{
321094332d3Sopenharmony_ci    int32_t ret;
322094332d3Sopenharmony_ci
323094332d3Sopenharmony_ci    CHECK_NULLPOINTER_RETURN_VALUE(buffer, DISPLAY_NULL_PTR);
324094332d3Sopenharmony_ci    CHECK_NULLPOINTER_RETURN_VALUE(buffer->virAddr, DISPLAY_NULL_PTR);
325094332d3Sopenharmony_ci    if ((buffer->size > MAX_MALLOC_SIZE) || (buffer->size == 0)) {
326094332d3Sopenharmony_ci        HDF_LOGE("%s: size is invalid, buffer->size = %d", __func__, buffer->size);
327094332d3Sopenharmony_ci        return DISPLAY_FAILURE;
328094332d3Sopenharmony_ci    }
329094332d3Sopenharmony_ci    LockGrallocMgr();
330094332d3Sopenharmony_ci    if (buffer->usage == HBM_USE_MEM_SHARE) {
331094332d3Sopenharmony_ci        ret = UnmapShm(buffer);
332094332d3Sopenharmony_ci    } else {
333094332d3Sopenharmony_ci        HDF_LOGE("%s: not support memory usage: 0x%" PRIx64 "", __func__, buffer->usage);
334094332d3Sopenharmony_ci        ret = DISPLAY_FAILURE;
335094332d3Sopenharmony_ci    }
336094332d3Sopenharmony_ci    UnlockGrallocMgr();
337094332d3Sopenharmony_ci    return ret;
338094332d3Sopenharmony_ci}
339094332d3Sopenharmony_ci
340094332d3Sopenharmony_ciint32_t GrallocInitialize(GrallocFuncs **funcs)
341094332d3Sopenharmony_ci{
342094332d3Sopenharmony_ci    static GrallocFuncs *gFuncs = NULL;
343094332d3Sopenharmony_ci
344094332d3Sopenharmony_ci    if (funcs == NULL) {
345094332d3Sopenharmony_ci        HDF_LOGE("%s: funcs is null", __func__);
346094332d3Sopenharmony_ci        return DISPLAY_NULL_PTR;
347094332d3Sopenharmony_ci    }
348094332d3Sopenharmony_ci    if (gFuncs == NULL) {
349094332d3Sopenharmony_ci        gFuncs = (GrallocFuncs *)OsalMemCalloc(sizeof(GrallocFuncs));
350094332d3Sopenharmony_ci        if (gFuncs == NULL) {
351094332d3Sopenharmony_ci            HDF_LOGE("%s: gFuncs is null", __func__);
352094332d3Sopenharmony_ci            return DISPLAY_NULL_PTR;
353094332d3Sopenharmony_ci        }
354094332d3Sopenharmony_ci        pthread_mutexattr_init(&g_grallocManager.mutexattr);
355094332d3Sopenharmony_ci        pthread_mutexattr_setpshared(&g_grallocManager.mutexattr, PTHREAD_PROCESS_SHARED);
356094332d3Sopenharmony_ci        pthread_mutex_init(&g_grallocManager.mutex, &g_grallocManager.mutexattr);
357094332d3Sopenharmony_ci        gFuncs->AllocMem = AllocMem;
358094332d3Sopenharmony_ci        gFuncs->FreeMem = FreeMem;
359094332d3Sopenharmony_ci        gFuncs->Mmap = Mmap;
360094332d3Sopenharmony_ci        gFuncs->Unmap = Unmap;
361094332d3Sopenharmony_ci    }
362094332d3Sopenharmony_ci    *funcs = gFuncs;
363094332d3Sopenharmony_ci    GetGrallocMgr();
364094332d3Sopenharmony_ci    HDF_LOGI("%s: gralloc initialize success", __func__);
365094332d3Sopenharmony_ci    return DISPLAY_SUCCESS;
366094332d3Sopenharmony_ci}
367094332d3Sopenharmony_ci
368094332d3Sopenharmony_ciint32_t GrallocUninitialize(GrallocFuncs *funcs)
369094332d3Sopenharmony_ci{
370094332d3Sopenharmony_ci    if (funcs == NULL) {
371094332d3Sopenharmony_ci        HDF_LOGE("%s: funcs is null", __func__);
372094332d3Sopenharmony_ci        return DISPLAY_NULL_PTR;
373094332d3Sopenharmony_ci    }
374094332d3Sopenharmony_ci    if (PutGrallocMgr() == 0) {
375094332d3Sopenharmony_ci        pthread_mutexattr_destroy(&g_grallocManager.mutexattr);
376094332d3Sopenharmony_ci        pthread_mutex_destroy(&g_grallocManager.mutex);
377094332d3Sopenharmony_ci        OsalMemFree(funcs);
378094332d3Sopenharmony_ci    }
379094332d3Sopenharmony_ci    HDF_LOGI("%s: gralloc uninitialize success", __func__);
380094332d3Sopenharmony_ci    return DISPLAY_SUCCESS;
381094332d3Sopenharmony_ci}
382