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