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_gralloc.h"
17#include <errno.h>
18#include <inttypes.h>
19#include <stdio.h>
20#include <sys/mman.h>
21#include <sys/shm.h>
22#include <securec.h>
23#include "buffer_handle.h"
24#include "display_type.h"
25#include "disp_common.h"
26#include "hdf_log.h"
27
28#define DEFAULT_READ_WRITE_PERMISSIONS   0666
29#define MAX_MALLOC_SIZE                  0x10000000L
30#define SHM_MAX_KEY                      10000
31#define SHM_START_KEY                    1
32#define INVALID_SHMID -1
33#define BITS_PER_BYTE 8
34
35#define DIV_ROUND_UP(n, d) (((n) + (d)-1) / (d))
36#define ALIGN_UP(x, a) ((((x) + ((a)-1)) / (a)) * (a))
37#define HEIGHT_ALIGN 2U
38#define WIDTH_ALIGN 8U
39#define MAX_PLANES 3
40
41typedef struct {
42    BufferHandle hdl;
43    int32_t shmid;
44} PriBufferHandle;
45
46typedef struct {
47    uint32_t numPlanes;
48    uint32_t radio[MAX_PLANES];
49} PlaneLayoutInfo;
50
51typedef struct {
52    uint32_t format;
53    uint32_t bitsPerPixel; // bits per pixel for first plane
54    const PlaneLayoutInfo *planes;
55} FormatInfo;
56
57static const PlaneLayoutInfo g_yuv420SPLayout = {
58    .numPlanes = 2,
59    .radio = { 4, 2 },
60};
61
62static const PlaneLayoutInfo g_yuv420PLayout = {
63    .numPlanes = 3,
64    .radio = { 4, 1, 1 },
65};
66
67static const FormatInfo *GetFormatInfo(uint32_t format)
68{
69    static const FormatInfo fmtInfos[] = {
70        {PIXEL_FMT_RGBX_8888,  32, NULL},  {PIXEL_FMT_RGBA_8888, 32,  NULL},
71        {PIXEL_FMT_BGRX_8888,  32, NULL},  {PIXEL_FMT_BGRA_8888, 32,  NULL},
72        {PIXEL_FMT_RGB_888,    24, NULL},  {PIXEL_FMT_BGR_565,   16,  NULL},
73        {PIXEL_FMT_RGBA_5551,  16, NULL},  {PIXEL_FMT_RGB_565,   16,  NULL},
74        {PIXEL_FMT_BGRX_4444,  16, NULL},  {PIXEL_FMT_BGRA_4444, 16,  NULL},
75        {PIXEL_FMT_RGBA_4444,  16, NULL},  {PIXEL_FMT_RGBX_4444, 16,  NULL},
76        {PIXEL_FMT_BGRX_5551,  16, NULL},  {PIXEL_FMT_BGRA_5551, 16,  NULL},
77        {PIXEL_FMT_YCBCR_420_SP, 8, &g_yuv420SPLayout}, {PIXEL_FMT_YCRCB_420_SP, 8, &g_yuv420SPLayout},
78        {PIXEL_FMT_YCBCR_420_P, 8, &g_yuv420PLayout}, {PIXEL_FMT_YCRCB_420_P, 8, &g_yuv420PLayout},
79    };
80
81    for (uint32_t i = 0; i < sizeof(fmtInfos) / sizeof(FormatInfo); i++) {
82        if (fmtInfos[i].format == format) {
83            return &fmtInfos[i];
84        }
85    }
86    HDF_LOGE("the format can not support %d %d", format, PIXEL_FMT_RGBA_8888);
87    return NULL;
88}
89
90static uint32_t AdjustStrideFromFormat(uint32_t format, uint32_t width)
91{
92    const FormatInfo *fmtInfo = GetFormatInfo(format);
93    if ((fmtInfo != NULL) && (fmtInfo->planes != NULL)) {
94        uint32_t sum = fmtInfo->planes->radio[0];
95        for (uint32_t i = 1; (i < fmtInfo->planes->numPlanes) && (i < MAX_PLANES); i++) {
96            sum += fmtInfo->planes->radio[i];
97        }
98        if (sum > 0) {
99            width = DIV_ROUND_UP((width * sum), fmtInfo->planes->radio[0]);
100        }
101    }
102    return width;
103}
104
105static int32_t InitBufferHandle(PriBufferHandle* buffer, const AllocInfo* info)
106{
107    int32_t size;
108    int32_t stride;
109    int32_t h = ALIGN_UP(info->height, HEIGHT_ALIGN);
110    const FormatInfo *fmtInfo = GetFormatInfo(info->format);
111    if (fmtInfo == NULL) {
112        HDF_LOGE("can not get format information : %d", buffer->hdl.format);
113        return DISPLAY_FAILURE;
114    }
115
116    stride = ALIGN_UP(AdjustStrideFromFormat(info->format, info->width), WIDTH_ALIGN) *
117        fmtInfo->bitsPerPixel / BITS_PER_BYTE;
118    size = h * stride;
119    buffer->hdl.width = info->width;
120    buffer->hdl.stride = stride;
121    buffer->hdl.height = info->height;
122    buffer->hdl.size = size;
123    buffer->hdl.usage = info->usage;
124    buffer->hdl.fd = -1;
125    buffer->shmid = INVALID_SHMID;
126    buffer->hdl.format = info->format;
127    buffer->hdl.reserveInts = (sizeof(PriBufferHandle) - sizeof(BufferHandle) -
128        buffer->hdl.reserveFds * sizeof(uint32_t)) / sizeof(uint32_t);
129    return DISPLAY_SUCCESS;
130}
131
132static int32_t AllocShm(BufferHandle *buffer)
133{
134    static int32_t key = SHM_START_KEY;
135    int32_t shmid;
136
137    while ((shmid = shmget(key, buffer->size, IPC_CREAT | IPC_EXCL | DEFAULT_READ_WRITE_PERMISSIONS)) < 0) {
138        if (errno != EEXIST) {
139            HDF_LOGE("%s: fail to alloc the shared memory, errno = %d", __func__, errno);
140            return DISPLAY_FAILURE;
141        }
142        key++;
143        if (key >= SHM_MAX_KEY) {
144            key = SHM_START_KEY;
145        }
146    }
147    void *pBase = shmat(shmid, NULL, 0);
148    if (pBase == ((void *)-1)) {
149        HDF_LOGE("%s: Fail to attach the shared memory, errno = %d", __func__, errno);
150        if (shmctl(shmid, IPC_RMID, 0) == -1) {
151            HDF_LOGE("%s: Fail to free shmid, errno = %d", __func__, errno);
152        }
153        return DISPLAY_FAILURE;
154    }
155    buffer->virAddr = pBase;
156    buffer->fd = key;
157    ((PriBufferHandle*)buffer)->shmid = shmid;
158    key++;
159    (void)memset_s(pBase, buffer->size, 0x0, buffer->size);
160    if (key >= SHM_MAX_KEY) {
161        key = SHM_START_KEY;
162    }
163    return DISPLAY_SUCCESS;
164}
165
166typedef enum {
167    MMZ_CACHE = 1,                  /* allocate mmz with cache attribute */
168    MMZ_NOCACHE,                    /* allocate mmz with nocache attribute */
169    MMZ_FREE,                       /* free mmz */
170    MAP_CACHE,
171    MAP_NOCACHE,
172    UNMAP,
173    FLUSH_CACHE,
174    FLUSH_NOCACHE,
175    INVALIDATE,
176    MMZ_MAX
177} MMZ_TYPE;
178
179typedef struct {
180    void *vaddr;
181    uint64_t paddr;
182    int32_t size;
183} MmzMemory;
184
185#define MMZ_IOC_MAGIC               'M'
186#define MMZ_CACHE_TYPE              _IOR(MMZ_IOC_MAGIC, MMZ_CACHE, MmzMemory)
187#define MMZ_NOCACHE_TYPE            _IOR(MMZ_IOC_MAGIC, MMZ_NOCACHE, MmzMemory)
188#define MMZ_FREE_TYPE               _IOR(MMZ_IOC_MAGIC, MMZ_FREE, MmzMemory)
189#define MMZ_MAP_CACHE_TYPE          _IOR(MMZ_IOC_MAGIC, MAP_CACHE, MmzMemory)
190#define MMZ_MAP_NOCACHE_TYPE        _IOR(MMZ_IOC_MAGIC, MAP_NOCACHE, MmzMemory)
191#define MMZ_UNMAP_TYPE              _IOR(MMZ_IOC_MAGIC, UNMAP, MmzMemory)
192#define MMZ_FLUSH_CACHE_TYPE        _IOR(MMZ_IOC_MAGIC, FLUSH_CACHE, MmzMemory)
193#define MMZ_FLUSH_NOCACHE_TYPE      _IOR(MMZ_IOC_MAGIC, FLUSH_NOCACHE, MmzMemory)
194#define MMZ_INVALIDATE_TYPE         _IOR(MMZ_IOC_MAGIC, INVALIDATE, MmzMemory)
195
196#define MMZ_NODE                    "/dev/mmz"
197
198static int SendCmd(int cmd, unsigned long arg)
199{
200    int fd = open(MMZ_NODE, O_RDONLY);
201    if (fd != -1) {
202        int ret = ioctl(fd, cmd, arg);
203        if (ret == -1) {
204            printf("[Init] 1 [ERR] %d!\n", errno);
205        }
206        close(fd);
207        return ret;
208    }
209    return fd;
210}
211
212static int32_t AllocMmz(BufferHandle *buffer)
213{
214    int32_t ret;
215
216    MmzMemory mmz = {0};
217    mmz.size = buffer->size;
218    switch (buffer->usage) {
219        case HBM_USE_MEM_MMZ_CACHE:
220            printf("req size(%#x), ret:%d \n", buffer->size, SendCmd(MMZ_CACHE_TYPE, (uintptr_t)&mmz));
221            printf("vaddr %#x, paddr: %#x\n", mmz.vaddr, mmz.paddr);
222            ret = 0;
223            break;
224        case HBM_USE_MEM_MMZ:
225            printf("req size(%#x), ret:%d \n", buffer->size, SendCmd(MMZ_NOCACHE_TYPE, (uintptr_t)&mmz));
226            printf("vaddr %#x, paddr: %#x\n", mmz.vaddr, mmz.paddr);
227            ret = 0;
228            break;
229        default:
230            HDF_LOGE("%s: not support memory usage: 0x%" PRIx64 "", __func__, buffer->usage);
231            return DISPLAY_NOT_SUPPORT;
232    }
233    if (ret != DISPLAY_SUCCESS) {
234        HDF_LOGE("%s: mmzalloc failure, usage = 0x%" PRIx64 ", ret 0x%x", __func__,
235            buffer->usage, ret);
236        return DISPLAY_FAILURE;
237    }
238    (void)memset_s(mmz.vaddr, buffer->size, 0x0, buffer->size);
239    buffer->phyAddr = mmz.paddr;
240    buffer->virAddr = mmz.vaddr;
241    return DISPLAY_SUCCESS;
242}
243
244static int32_t FreeMmz(uint64_t paddr, void* vaddr)
245{
246    MmzMemory mmz = {0};
247    mmz.vaddr = vaddr;
248    mmz.paddr = paddr;
249    return SendCmd(MMZ_FREE_TYPE, (uintptr_t)&mmz);
250}
251
252static int32_t MmzFlushCache(BufferHandle *buffer)
253{
254    MmzMemory mmz = {0};
255    mmz.paddr = buffer->phyAddr;
256    mmz.size = buffer->size;
257    mmz.vaddr = buffer->virAddr;
258    return SendCmd(MMZ_FLUSH_CACHE_TYPE, (uintptr_t)&mmz);
259}
260
261static int32_t MmzInvalidateCache(BufferHandle *buffer)
262{
263    MmzMemory mmz = {0};
264    mmz.paddr = buffer->phyAddr;
265    mmz.size = buffer->size;
266    mmz.vaddr = buffer->virAddr;
267    return SendCmd(MMZ_INVALIDATE_TYPE, (uintptr_t)&mmz);
268}
269
270static int32_t AllocMem(const AllocInfo* info, BufferHandle **buffer)
271{
272    int32_t ret;
273    DISPLAY_CHK_RETURN((buffer == NULL), DISPLAY_NULL_PTR, HDF_LOGE("%s: in buffer is null", __func__));
274    DISPLAY_CHK_RETURN((info == NULL), DISPLAY_NULL_PTR, HDF_LOGE("%s: in info is null", __func__));
275    PriBufferHandle* priBuffer = calloc(1, sizeof(PriBufferHandle));
276    DISPLAY_CHK_RETURN((priBuffer == NULL), DISPLAY_NULL_PTR, HDF_LOGE("%s: can not calloc errno : %d",
277        __func__, errno));
278    ret = InitBufferHandle(priBuffer, info);
279    DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, HDF_LOGE("%s: can not init buffe handle",
280        __func__); goto OUT);
281
282    BufferHandle *bufferHdl = &priBuffer->hdl;
283    DISPLAY_CHK_RETURN(((bufferHdl->size > MAX_MALLOC_SIZE) || (bufferHdl->size == 0)),
284        DISPLAY_FAILURE, HDF_LOGE("%s: size is invalid %d ", __func__, bufferHdl->size); goto OUT);
285
286    if (bufferHdl->usage == HBM_USE_MEM_SHARE) {
287        ret = AllocShm(bufferHdl);
288    } else if ((bufferHdl->usage == HBM_USE_MEM_DMA ) || (bufferHdl->usage == HBM_USE_MEM_MMZ )) {
289        ret = AllocMmz(bufferHdl);
290    } else {
291        HDF_LOGE("%s: not support memory usage: 0x%" PRIx64 "", __func__, bufferHdl->usage);
292        ret = DISPLAY_NOT_SUPPORT;
293    }
294
295OUT:
296    if ((ret != DISPLAY_SUCCESS) && (bufferHdl != NULL)) {
297        free(bufferHdl);
298        bufferHdl = NULL;
299    }
300    *buffer = bufferHdl;
301    return ret;
302}
303
304static void FreeShm(BufferHandle *buffer)
305{
306    CHECK_NULLPOINTER_RETURN(buffer->virAddr);
307    if (shmdt(buffer->virAddr) == -1) {
308        HDF_LOGE("%s: Fail to free shared memory, errno = %d", __func__, errno);
309    }
310    if (shmctl(((PriBufferHandle*)buffer)->shmid, IPC_RMID, 0) == -1) {
311        HDF_LOGE("%s: Fail to free shmid, errno = %d", __func__, errno);
312    }
313}
314
315static void FreeMem(BufferHandle *buffer)
316{
317    int ret;
318
319    CHECK_NULLPOINTER_RETURN(buffer);
320    if ((buffer->size > MAX_MALLOC_SIZE) || (buffer->size == 0)) {
321        HDF_LOGE("%s: size is invalid, buffer->size = %d", __func__, buffer->size);
322        return;
323    }
324
325    switch (buffer->usage) {
326        case HBM_USE_MEM_MMZ_CACHE:
327        case HBM_USE_MEM_MMZ:
328            ret = FreeMmz(buffer->phyAddr, buffer->virAddr);
329            if (ret != DISPLAY_SUCCESS) {
330                HDF_LOGE("%s: HI_MPI_SYS_MmzFree failure, ret 0x%x", __func__, ret);
331            }
332            break;
333        case HBM_USE_MEM_SHARE:
334            FreeShm(buffer);
335            break;
336        default:
337            HDF_LOGE("%s: not support memory usage: 0x%" PRIx64 "", __func__, buffer->usage);
338    }
339}
340
341static void *MmapShm(BufferHandle *buffer)
342{
343    int32_t shmid;
344
345    shmid = shmget(buffer->fd, buffer->size, IPC_EXCL | DEFAULT_READ_WRITE_PERMISSIONS);
346    if (shmid < 0) {
347        HDF_LOGE("%s: Fail to mmap the shared memory, errno = %d", __func__, errno);
348        return NULL;
349    }
350    void *pBase = shmat(shmid, NULL, 0);
351    if (pBase == ((void *)-1)) {
352        HDF_LOGE("%s: Fail to attach the shared memory, errno = %d", __func__, errno);
353        return NULL;
354    }
355    ((PriBufferHandle*)buffer)->shmid = shmid;
356    HDF_LOGI("%s: Mmap shared memory succeed", __func__);
357    return pBase;
358}
359
360static void *MmapMmzNoCache(uint64_t paddr, int32_t size)
361{
362    MmzMemory mmz = {0};
363    mmz.paddr = paddr;
364    mmz.size = size;
365    SendCmd(MMZ_MAP_NOCACHE_TYPE, (uintptr_t)&mmz);
366    return (void *)mmz.vaddr;
367}
368
369static int32_t UnmapMmz(BufferHandle *buffer)
370{
371    MmzMemory mmz = {0};
372    mmz.paddr = buffer->phyAddr;
373    mmz.size = buffer->size;
374    mmz.vaddr = buffer->virAddr;
375    return SendCmd(MMZ_UNMAP_TYPE, (uintptr_t)&mmz);
376}
377
378static void *MmapMmzCache(uint64_t paddr, int32_t size)
379{
380    MmzMemory mmz = {0};
381    mmz.paddr = paddr;
382    mmz.size = size;
383    SendCmd(MMZ_MAP_CACHE_TYPE, (uintptr_t)&mmz);
384    return (void *)mmz.vaddr;
385}
386
387static void *MmapCache(BufferHandle *buffer)
388{
389    CHECK_NULLPOINTER_RETURN_VALUE(buffer, NULL);
390    if ((buffer->size > MAX_MALLOC_SIZE) || (buffer->size == 0)) {
391        HDF_LOGE("%s: size is invalid, buffer->size = %d", __func__, buffer->size);
392        return NULL;
393    }
394    if (buffer->usage == HBM_USE_MEM_MMZ_CACHE) {
395        return MmapMmzCache(buffer->phyAddr, buffer->size);
396    } else {
397        HDF_LOGE("%s: buffer usage error, buffer->usage = 0x%" PRIx64 "", __func__, buffer->usage);
398        return NULL;
399    }
400}
401
402static void *Mmap(BufferHandle *buffer)
403{
404    CHECK_NULLPOINTER_RETURN_VALUE(buffer, NULL);
405    if ((buffer->size > MAX_MALLOC_SIZE) || (buffer->size == 0)) {
406        HDF_LOGE("%s: size is invalid, buffer->size = %d", __func__, buffer->size);
407        return NULL;
408    }
409
410    switch (buffer->usage) {
411        case HBM_USE_MEM_MMZ_CACHE:
412            return MmapMmzCache(buffer->phyAddr, buffer->size);
413        case HBM_USE_MEM_MMZ:
414            return MmapMmzNoCache(buffer->phyAddr, buffer->size);
415        case HBM_USE_MEM_SHARE:
416            return MmapShm(buffer);
417        default:
418            HDF_LOGE("%s: not support memory usage: 0x%" PRIx64 "", __func__, buffer->usage);
419            break;
420    }
421    return NULL;
422}
423
424static int32_t UnmapShm(BufferHandle *buffer)
425{
426    if (shmdt(buffer->virAddr) == -1) {
427        HDF_LOGE("%s: Fail to unmap shared memory errno =  %d", __func__, errno);
428        return DISPLAY_FAILURE;
429    }
430    int32_t shmid = ((PriBufferHandle*)buffer)->shmid;
431    if ((shmid != INVALID_SHMID) && (shmctl(shmid, IPC_RMID, 0) == -1)) {
432        HDF_LOGE("%s: Fail to free shmid, errno = %d", __func__, errno);
433    }
434    return DISPLAY_SUCCESS;
435}
436
437static int32_t Unmap(BufferHandle *buffer)
438{
439    int32_t ret;
440
441    CHECK_NULLPOINTER_RETURN_VALUE(buffer, DISPLAY_NULL_PTR);
442    CHECK_NULLPOINTER_RETURN_VALUE(buffer->virAddr, DISPLAY_NULL_PTR);
443    if ((buffer->size > MAX_MALLOC_SIZE) || (buffer->size == 0)) {
444        HDF_LOGE("%s: size is invalid, buffer->size = %d", __func__, buffer->size);
445        return DISPLAY_FAILURE;
446    }
447    switch (buffer->usage) {
448        case HBM_USE_MEM_MMZ_CACHE:
449        case HBM_USE_MEM_MMZ:
450            ret = UnmapMmz(buffer);
451            break;
452        case  HBM_USE_MEM_SHARE:
453            ret = UnmapShm(buffer);
454            break;
455        default:
456            HDF_LOGE("%s: not support memory usage: 0x%" PRIx64 "", __func__, buffer->usage);
457            ret = DISPLAY_FAILURE;
458            break;
459    }
460    return ret;
461}
462
463static int32_t FlushCache(BufferHandle *buffer)
464{
465    int32_t ret;
466
467    CHECK_NULLPOINTER_RETURN_VALUE(buffer, DISPLAY_NULL_PTR);
468    CHECK_NULLPOINTER_RETURN_VALUE(buffer->virAddr, DISPLAY_NULL_PTR);
469    if ((buffer->size > MAX_MALLOC_SIZE) || (buffer->size == 0)) {
470        HDF_LOGE("%s: size is invalid, buffer->size = %d", __func__, buffer->size);
471        return DISPLAY_FAILURE;
472    }
473    if (buffer->usage == HBM_USE_MEM_MMZ_CACHE) {
474        ret = MmzFlushCache(buffer);
475        if (ret != DISPLAY_SUCCESS) {
476            HDF_LOGE("%s: MmzFlushCache failure, ret 0x%x", __func__, ret);
477            return DISPLAY_FAILURE;
478        }
479    } else {
480        HDF_LOGE("%s: buffer usage error, usage = 0x%" PRIx64"", __func__, buffer->usage);
481        return DISPLAY_FAILURE;
482    }
483    return DISPLAY_SUCCESS;
484}
485
486static int32_t InvalidateCache(BufferHandle *buffer)
487{
488    int32_t ret;
489
490    CHECK_NULLPOINTER_RETURN_VALUE(buffer, DISPLAY_NULL_PTR);
491    CHECK_NULLPOINTER_RETURN_VALUE(buffer->virAddr, DISPLAY_NULL_PTR);
492    if ((buffer->size > MAX_MALLOC_SIZE) || (buffer->size == 0)) {
493        HDF_LOGE("%s: size is invalid, buffer->size = %d", __func__, buffer->size);
494        return DISPLAY_FAILURE;
495    }
496    if (buffer->usage == HBM_USE_MEM_MMZ_CACHE) {
497        ret = MmzInvalidateCache(buffer);
498        if (ret != DISPLAY_SUCCESS) {
499            HDF_LOGE("%s: MmzFlushCache failure, ret 0x%x", __func__, ret);
500            return DISPLAY_FAILURE;
501        }
502    } else {
503        HDF_LOGE("%s: buffer usage error, usage = 0x%" PRIx64"", __func__, buffer->usage);
504        return DISPLAY_FAILURE;
505    }
506    return DISPLAY_SUCCESS;
507}
508
509int32_t GrallocInitialize(GrallocFuncs **funcs)
510{
511    if (funcs == NULL) {
512        HDF_LOGE("%s: funcs is null", __func__);
513        return DISPLAY_NULL_PTR;
514    }
515    GrallocFuncs *gFuncs = (GrallocFuncs *)malloc(sizeof(GrallocFuncs));
516    if (gFuncs == NULL) {
517        HDF_LOGE("%s: gFuncs is null", __func__);
518        return DISPLAY_NULL_PTR;
519    }
520    (void)memset_s(gFuncs, sizeof(GrallocFuncs), 0, sizeof(GrallocFuncs));
521    gFuncs->AllocMem = AllocMem;
522    gFuncs->FreeMem = FreeMem;
523    gFuncs->Mmap = Mmap;
524    gFuncs->MmapCache = MmapCache;
525    gFuncs->Unmap = Unmap;
526    gFuncs->FlushCache = FlushCache;
527    gFuncs->FlushMCache = FlushCache;
528    gFuncs->InvalidateCache = InvalidateCache;
529    *funcs = gFuncs;
530    HDF_LOGI("%s: gralloc initialize success", __func__);
531    return DISPLAY_SUCCESS;
532}
533
534int32_t GrallocUninitialize(GrallocFuncs *funcs)
535{
536    if (funcs == NULL) {
537        HDF_LOGE("%s: funcs is null", __func__);
538        return DISPLAY_NULL_PTR;
539    }
540    free(funcs);
541    HDF_LOGI("%s: gralloc uninitialize success", __func__);
542    return DISPLAY_SUCCESS;
543}
544