• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <securec.h>
20 #include "buffer_handle.h"
21 #include "display_type.h"
22 #include "disp_common.h"
23 #include "hdf_log.h"
24 
25 #define DEFAULT_READ_WRITE_PERMISSIONS   0666
26 #define MAX_MALLOC_SIZE                  0x10000000L
27 #define SHM_MAX_KEY                      10000
28 #define SHM_START_KEY                    1
29 #define INVALID_SHMID -1
30 #define BITS_PER_BYTE 8
31 
32 #define DIV_ROUND_UP(n, d) (((n) + (d)-1) / (d))
33 #define ALIGN_UP(x, a) ((((x) + ((a)-1)) / (a)) * (a))
34 #define HEIGHT_ALIGN 2U
35 #define WIDTH_ALIGN 8U
36 #define MAX_PLANES 3
37 
38 typedef struct {
39     BufferHandle hdl;
40     int32_t shmid;
41 } PriBufferHandle;
42 
43 typedef struct {
44     uint32_t numPlanes;
45     uint32_t radio[MAX_PLANES];
46 } PlaneLayoutInfo;
47 
48 typedef struct {
49     uint32_t format;
50     uint32_t bitsPerPixel; // bits per pixel for first plane
51     const PlaneLayoutInfo *planes;
52 } FormatInfo;
53 
54 static const PlaneLayoutInfo g_yuv420SPLayout = {
55     .numPlanes = 2,
56     .radio = { 4, 2 },
57 };
58 
59 static const PlaneLayoutInfo g_yuv420PLayout = {
60     .numPlanes = 3,
61     .radio = { 4, 1, 1 },
62 };
63 
GetFormatInfo(uint32_t format)64 static const FormatInfo *GetFormatInfo(uint32_t format)
65 {
66     static const FormatInfo fmtInfos[] = {
67         {PIXEL_FMT_RGBX_8888,  32, NULL},  {PIXEL_FMT_RGBA_8888, 32,  NULL},
68         {PIXEL_FMT_BGRX_8888,  32, NULL},  {PIXEL_FMT_BGRA_8888, 32,  NULL},
69         {PIXEL_FMT_RGB_888,    24, NULL},  {PIXEL_FMT_BGR_565,   16,  NULL},
70         {PIXEL_FMT_RGBA_5551,  16, NULL},  {PIXEL_FMT_RGB_565,   16,  NULL},
71         {PIXEL_FMT_BGRX_4444,  16, NULL},  {PIXEL_FMT_BGRA_4444, 16,  NULL},
72         {PIXEL_FMT_RGBA_4444,  16, NULL},  {PIXEL_FMT_RGBX_4444, 16,  NULL},
73         {PIXEL_FMT_BGRX_5551,  16, NULL},  {PIXEL_FMT_BGRA_5551, 16,  NULL},
74         {PIXEL_FMT_YCBCR_420_SP, 8, &g_yuv420SPLayout}, {PIXEL_FMT_YCRCB_420_SP, 8, &g_yuv420SPLayout},
75         {PIXEL_FMT_YCBCR_420_P, 8, &g_yuv420PLayout}, {PIXEL_FMT_YCRCB_420_P, 8, &g_yuv420PLayout},
76     };
77 
78     for (uint32_t i = 0; i < sizeof(fmtInfos) / sizeof(FormatInfo); i++) {
79         if (fmtInfos[i].format == format) {
80             return &fmtInfos[i];
81         }
82     }
83     HDF_LOGE("the format can not support %d %d", format, PIXEL_FMT_RGBA_8888);
84     return NULL;
85 }
86 
AdjustStrideFromFormat(uint32_t format,uint32_t width)87 static uint32_t AdjustStrideFromFormat(uint32_t format, uint32_t width)
88 {
89     const FormatInfo *fmtInfo = GetFormatInfo(format);
90     if ((fmtInfo != NULL) && (fmtInfo->planes != NULL)) {
91         uint32_t sum = fmtInfo->planes->radio[0];
92         for (uint32_t i = 1; (i < fmtInfo->planes->numPlanes) && (i < MAX_PLANES); i++) {
93             sum += fmtInfo->planes->radio[i];
94         }
95         if (sum > 0) {
96             width = DIV_ROUND_UP((width * sum), fmtInfo->planes->radio[0]);
97         }
98     }
99     return width;
100 }
101 
InitBufferHandle(PriBufferHandle * buffer,const AllocInfo * info)102 static int32_t InitBufferHandle(PriBufferHandle* buffer, const AllocInfo* info)
103 {
104     int32_t size;
105     int32_t stride;
106     int32_t h = ALIGN_UP(info->height, HEIGHT_ALIGN);
107     const FormatInfo *fmtInfo = GetFormatInfo(info->format);
108     if (fmtInfo == NULL) {
109         HDF_LOGE("can not get format information : %d", buffer->hdl.format);
110         return DISPLAY_FAILURE;
111     }
112 
113     stride = ALIGN_UP(AdjustStrideFromFormat(info->format, info->width), WIDTH_ALIGN) *
114         fmtInfo->bitsPerPixel / BITS_PER_BYTE;
115     size = h * stride;
116     buffer->hdl.width = info->width;
117     buffer->hdl.stride = stride;
118     buffer->hdl.height = info->height;
119     buffer->hdl.size = size;
120     buffer->hdl.usage = info->usage;
121     buffer->hdl.fd = -1;
122     buffer->shmid = INVALID_SHMID;
123     buffer->hdl.format = info->format;
124     buffer->hdl.reserveInts = (sizeof(PriBufferHandle) - sizeof(BufferHandle) -
125         buffer->hdl.reserveFds * sizeof(uint32_t)) / sizeof(uint32_t);
126     return DISPLAY_SUCCESS;
127 }
128 
129 
AllocMem(const AllocInfo * info,BufferHandle ** buffer)130 static int32_t AllocMem(const AllocInfo* info, BufferHandle **buffer)
131 {
132     int32_t ret;
133     DISPLAY_CHK_RETURN((buffer == NULL), DISPLAY_NULL_PTR, HDF_LOGE("%s: in buffer is null", __func__));
134     DISPLAY_CHK_RETURN((info == NULL), DISPLAY_NULL_PTR, HDF_LOGE("%s: in info is null", __func__));
135     PriBufferHandle* priBuffer = calloc(1, sizeof(PriBufferHandle));
136     DISPLAY_CHK_RETURN((priBuffer == NULL), DISPLAY_NULL_PTR, HDF_LOGE("%s: can not calloc errno : %d",
137         __func__, errno));
138     ret = InitBufferHandle(priBuffer, info);
139     DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, HDF_LOGE("%s: can not init buffe handle",
140         __func__); goto OUT);
141 
142     BufferHandle *bufferHdl = &priBuffer->hdl;
143     DISPLAY_CHK_RETURN(((bufferHdl->size > MAX_MALLOC_SIZE) || (bufferHdl->size == 0)),
144         DISPLAY_FAILURE, HDF_LOGE("%s: size is invalid %d ", __func__, bufferHdl->size); goto OUT);
145 
146     void *pBase = malloc(bufferHdl->size);
147     if (pBase == NULL) {
148         HDF_LOGE("%s: Fail to alloc memory, errno = %d", __func__, errno);
149         ret = DISPLAY_FAILURE;
150     } else {
151         bufferHdl->virAddr = pBase;
152         (void)memset_s(pBase, bufferHdl->size, 0x0, bufferHdl->size);
153         ret = DISPLAY_SUCCESS;
154     }
155 
156 OUT:
157     if ((ret != DISPLAY_SUCCESS) && (bufferHdl != NULL)) {
158         free(bufferHdl);
159         bufferHdl = NULL;
160     }
161     *buffer = bufferHdl;
162     return ret;
163 }
164 
FreeMem(BufferHandle * buffer)165 static void FreeMem(BufferHandle *buffer)
166 {
167     CHECK_NULLPOINTER_RETURN(buffer);
168     if ((buffer->size > MAX_MALLOC_SIZE) || (buffer->size == 0)) {
169         HDF_LOGE("%s: size is invalid, buffer->size = %d", __func__, buffer->size);
170         return;
171     }
172 
173     CHECK_NULLPOINTER_RETURN(buffer->virAddr);
174     free(buffer->virAddr);
175 }
176 
177 
GrallocInitialize(GrallocFuncs ** funcs)178 int32_t GrallocInitialize(GrallocFuncs **funcs)
179 {
180     if (funcs == NULL) {
181         HDF_LOGE("%s: funcs is null", __func__);
182         return DISPLAY_NULL_PTR;
183     }
184     GrallocFuncs *gFuncs = (GrallocFuncs *)malloc(sizeof(GrallocFuncs));
185     if (gFuncs == NULL) {
186         HDF_LOGE("%s: gFuncs is null", __func__);
187         return DISPLAY_NULL_PTR;
188     }
189     (void)memset_s(gFuncs, sizeof(GrallocFuncs), 0, sizeof(GrallocFuncs));
190     gFuncs->AllocMem = AllocMem;
191     gFuncs->FreeMem = FreeMem;
192     *funcs = gFuncs;
193     HDF_LOGI("%s: gralloc initialize success", __func__);
194     return DISPLAY_SUCCESS;
195 }
196 
GrallocUninitialize(GrallocFuncs * funcs)197 int32_t GrallocUninitialize(GrallocFuncs *funcs)
198 {
199     if (funcs == NULL) {
200         HDF_LOGE("%s: funcs is null", __func__);
201         return DISPLAY_NULL_PTR;
202     }
203     free(funcs);
204     HDF_LOGI("%s: gralloc uninitialize success", __func__);
205     return DISPLAY_SUCCESS;
206 }
207