1 /*
2 * Copyright (c) 2022 Unionman 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 <stdio.h>
17 #include <string.h>
18 #include <sys/mman.h>
19 #include "display_log.h"
20 #include "display_gralloc.h"
21 #include "securec.h"
22 #include "aml_ge2d.h"
23 #include "ge2d_dmabuf.h"
24 #include "display_gfx_private.h"
25 #include "display_gfx.h"
26
27 static aml_ge2d_t g_ge2d;
28
blendTypeChange(BlendType blendType)29 static enum GE2DBlendMode blendTypeChange(BlendType blendType)
30 {
31 enum GE2DBlendMode ge2dBlendMode;
32
33 switch (blendType) {
34 case BLEND_SRC:
35 ge2dBlendMode = GE2D_BLEND_MODE_PREMULTIPLIED;
36 break;
37 case BLEND_SRCOVER:
38 ge2dBlendMode = GE2D_BLEND_MODE_NONE;
39 break;
40 case BLEND_SRCATOP:
41 ge2dBlendMode = GE2D_BLEND_MODE_COVERAGE;
42 break;
43 default:
44 ge2dBlendMode = GE2D_BLEND_MODE_INVALID;
45 break;
46 }
47
48 return ge2dBlendMode;
49 }
50
pixelFormatChange(PixelFormat fmt)51 static enum GE2DPixelFormat pixelFormatChange(PixelFormat fmt)
52 {
53 enum GE2DPixelFormat ge2dPixelFmt;
54
55 switch (fmt) {
56 case PIXEL_FMT_RGBA_8888:
57 ge2dPixelFmt = GE2D_PIXEL_FORMAT_RGBA_8888;
58 break;
59 case PIXEL_FMT_RGBX_8888:
60 ge2dPixelFmt = GE2D_PIXEL_FORMAT_RGBX_8888;
61 break;
62 case PIXEL_FMT_RGB_888:
63 ge2dPixelFmt = GE2D_PIXEL_FORMAT_RGB_888;
64 break;
65 case PIXEL_FMT_BGRA_8888:
66 ge2dPixelFmt = GE2D_PIXEL_FORMAT_BGRA_8888;
67 break;
68 case PIXEL_FMT_YCRCB_420_P:
69 ge2dPixelFmt = GE2D_PIXEL_FORMAT_YV12;
70 break;
71 case PIXEL_FMT_YCBCR_422_SP:
72 ge2dPixelFmt = GE2D_PIXEL_FORMAT_YCbCr_422_SP;
73 break;
74 case PIXEL_FMT_YCRCB_420_SP:
75 ge2dPixelFmt = GE2D_PIXEL_FORMAT_YCrCb_420_SP;
76 break;
77 case PIXEL_FMT_UYVY_422_PKG:
78 ge2dPixelFmt = GE2D_PIXEL_FORMAT_YCbCr_422_UYVY;
79 break;
80 default:
81 ge2dPixelFmt = GE2D_PIXEL_FORMAT_RGBA_8888;
82 break;
83 }
84
85 return ge2dPixelFmt;
86 }
87
transformTypeChange(TransformType type)88 static enum GE2DRotation transformTypeChange(TransformType type)
89 {
90 enum GE2DRotation ge2dRotation;
91
92 switch (type) {
93 case ROTATE_NONE:
94 ge2dRotation = GE2D_ROTATION_0;
95 break;
96 case ROTATE_90:
97 ge2dRotation = GE2D_ROTATION_90;
98 break;
99 case ROTATE_180:
100 ge2dRotation = GE2D_ROTATION_180;
101 break;
102 case ROTATE_270:
103 ge2dRotation = GE2D_ROTATION_270;
104 break;
105 default:
106 ge2dRotation = GE2D_ROTATION_0;
107 break;
108 }
109
110 return ge2dRotation;
111 }
112
InitGfx()113 static int32_t InitGfx()
114 {
115 int32_t ret = DISPLAY_SUCCESS;
116
117 DISPLAY_LOGI("Init Gfx\n");
118
119 ret = aml_ge2d_init(&g_ge2d);
120 if (ret < 0) {
121 DISPLAY_LOGE("aml_ge2d_init failed. ret=%{public}d", ret);
122 return DISPLAY_FAILURE;
123 }
124
125 return DISPLAY_SUCCESS;
126 }
127
DeinitGfx()128 static int32_t DeinitGfx()
129 {
130 DISPLAY_LOGI("Deinit Gfx\n");
131 aml_ge2d_exit(&g_ge2d);
132 return DISPLAY_SUCCESS;
133 }
134
FillGe2d(ISurface * surface,IRect dstRect,uint32_t color,GfxOpt * opt)135 static void FillGe2d(ISurface *surface, IRect dstRect, uint32_t color, GfxOpt *opt)
136 {
137 g_ge2d.ge2dinfo.offset = 0;
138 g_ge2d.ge2dinfo.ge2d_op = GE2D_OP_FILLRECTANGLE;
139 g_ge2d.ge2dinfo.blend_mode = GE2D_BLEND_MODE_NONE;
140
141 g_ge2d.ge2dinfo.src_info[0].memtype = GE2D_CANVAS_TYPE_INVALID;
142 g_ge2d.ge2dinfo.src_info[1].memtype = GE2D_CANVAS_TYPE_INVALID;
143
144 g_ge2d.ge2dinfo.dst_info.plane_number = 1;
145 g_ge2d.ge2dinfo.dst_info.rotation = GE2D_ROTATION_0;
146 g_ge2d.ge2dinfo.dst_info.mem_alloc_type = GE2D_MEM_DMABUF;
147 g_ge2d.ge2dinfo.dst_info.memtype = GE2D_CANVAS_ALLOC;
148
149 g_ge2d.ge2dinfo.dst_info.shared_fd[0] = (int32_t)surface->phyAddr;
150 g_ge2d.ge2dinfo.color = color;
151 g_ge2d.ge2dinfo.dst_info.plane_alpha = surface->alpha0;
152 g_ge2d.ge2dinfo.dst_info.format = pixelFormatChange(surface->enColorFmt);
153 g_ge2d.ge2dinfo.dst_info.canvas_w = surface->width;
154 g_ge2d.ge2dinfo.dst_info.canvas_h = surface->height;
155 g_ge2d.ge2dinfo.dst_info.rect.x = dstRect.x;
156 g_ge2d.ge2dinfo.dst_info.rect.y = dstRect.y;
157 g_ge2d.ge2dinfo.dst_info.rect.w = dstRect.w;
158 g_ge2d.ge2dinfo.dst_info.rect.h = dstRect.h;
159
160 if ((opt != NULL) && (opt->enGlobalAlpha)) {
161 g_ge2d.ge2dinfo.gl_alpha = opt->globalAlpha;
162 g_ge2d.ge2dinfo.src_info[0].plane_alpha = surface->alpha0;
163 }
164
165 return ;
166 }
167
FillRect(ISurface * surface,IRect * rect,uint32_t color,GfxOpt * opt)168 static int32_t FillRect(ISurface *surface, IRect *rect, uint32_t color, GfxOpt *opt)
169 {
170 int32_t ret = DISPLAY_SUCCESS;
171 errno_t eok = EOK;
172 IRect dstRect;
173
174 if (surface == NULL) {
175 DISPLAY_LOGE("surface is null and return\n");
176 return DISPLAY_NULL_PTR;
177 }
178
179 eok = memset_s(&dstRect, sizeof(dstRect), 0, sizeof(dstRect));
180 if (ret != EOK) {
181 DISPLAY_LOGE("memset_s failed");
182 return DISPLAY_FAILURE;
183 }
184
185 if (rect != NULL) {
186 dstRect.x = rect->x;
187 dstRect.y = rect->y;
188 dstRect.w = rect->w;
189 dstRect.h = rect->h;
190 } else {
191 dstRect.x = 0;
192 dstRect.y = 0;
193 dstRect.w = surface->width;
194 dstRect.h = surface->height;
195 }
196
197 DISPLAY_LOGD("fd %{public}d, rect [%{public}d %{public}d %{public}d %{public}d]", \
198 (int32_t)surface->phyAddr, dstRect.x, dstRect.y, dstRect.w, dstRect.h);
199
200 eok = memset_s(&g_ge2d.ge2dinfo.src_info, sizeof(g_ge2d.ge2dinfo.src_info), \
201 0, sizeof(g_ge2d.ge2dinfo.src_info));
202 if (eok != EOK) {
203 DISPLAY_LOGE("memset_s failed");
204 return DISPLAY_FAILURE;
205 }
206
207 eok = memset_s(&g_ge2d.ge2dinfo.dst_info, sizeof(g_ge2d.ge2dinfo.dst_info), \
208 0, sizeof(g_ge2d.ge2dinfo.dst_info));
209 if (eok != EOK) {
210 DISPLAY_LOGE("memset_s failed");
211 return DISPLAY_FAILURE;
212 }
213
214 FillGe2d(surface, dstRect, color, opt);
215
216 ret = aml_ge2d_process(&g_ge2d.ge2dinfo);
217 if (ret < 0) {
218 DISPLAY_LOGE("aml_ge2d_process failed. ret=%{public}d", ret);
219 return DISPLAY_FAILURE;
220 }
221
222 return DISPLAY_SUCCESS;
223 }
224
BlitGe2dOpt(enum GE2DOP opMode,GfxOpt * opt)225 static void BlitGe2dOpt(enum GE2DOP opMode, GfxOpt *opt)
226 {
227 enum GE2DBlendMode blendMode = GE2D_BLEND_MODE_NONE;
228 enum GE2DRotation rotation = GE2D_ROTATION_0;
229 int32_t globalAlpha = 0;
230 errno_t eok = EOK;
231
232 eok = memset_s(&g_ge2d.ge2dinfo.src_info, sizeof(g_ge2d.ge2dinfo.src_info), \
233 0, sizeof(g_ge2d.ge2dinfo.src_info));
234 if (eok != EOK) {
235 DISPLAY_LOGW("memset_s failed");
236 }
237
238 eok = memset_s(&g_ge2d.ge2dinfo.dst_info, sizeof(g_ge2d.ge2dinfo.dst_info), \
239 0, sizeof(g_ge2d.ge2dinfo.dst_info));
240 if (eok != EOK) {
241 DISPLAY_LOGW("memset_s failed");
242 }
243
244 if (opt != NULL) {
245 globalAlpha = opt->globalAlpha;
246 rotation = transformTypeChange(opt->rotateType);
247
248 if (BLEND_NONE != opt->blendType) {
249 blendMode = blendTypeChange(opt->blendType);
250 if (GE2D_BLEND_MODE_INVALID == blendMode) {
251 DISPLAY_LOGW("No support blend type %{public}d", opt->blendType);
252 }
253 }
254 }
255
256 DISPLAY_LOGD("opMode: %{public}d", opMode);
257 if (blendMode != GE2D_BLEND_MODE_INVALID) {
258 opMode = GE2D_OP_BLEND;
259 }
260
261 g_ge2d.ge2dinfo.ge2d_op = opMode;
262 if (GE2D_OP_BLEND != opMode) {
263 blendMode = GE2D_BLEND_MODE_NONE;
264 }
265
266 g_ge2d.ge2dinfo.ge2d_op = opMode;
267 g_ge2d.ge2dinfo.blend_mode = blendMode;
268 g_ge2d.ge2dinfo.dst_info.rotation = rotation;
269 g_ge2d.ge2dinfo.gl_alpha = globalAlpha;
270
271 return ;
272 }
273
BlitGe2dNoAlpha(ISurface * srcSurface,IRect sRect,ISurface * dstSurface,IRect dRect)274 static int32_t BlitGe2dNoAlpha(ISurface *srcSurface, IRect sRect, ISurface *dstSurface, IRect dRect)
275 {
276 int32_t ret = DISPLAY_SUCCESS;
277
278 g_ge2d.ge2dinfo.src_info[0].plane_number = 1;
279 g_ge2d.ge2dinfo.src_info[0].plane_alpha = srcSurface->alpha0;
280 g_ge2d.ge2dinfo.src_info[0].memtype = GE2D_CANVAS_ALLOC;
281 g_ge2d.ge2dinfo.src_info[0].mem_alloc_type = GE2D_MEM_DMABUF;
282 g_ge2d.ge2dinfo.src_info[0].layer_mode = GE2D_LAYER_MODE_NON;
283 g_ge2d.ge2dinfo.src_info[0].shared_fd[0] = (int32_t)srcSurface->phyAddr;
284 g_ge2d.ge2dinfo.src_info[0].canvas_w = srcSurface->width;
285 g_ge2d.ge2dinfo.src_info[0].canvas_h = srcSurface->height;
286 g_ge2d.ge2dinfo.src_info[0].format = pixelFormatChange(srcSurface->enColorFmt);
287 g_ge2d.ge2dinfo.src_info[0].rect.x = sRect.x;
288 g_ge2d.ge2dinfo.src_info[0].rect.y = sRect.y;
289 g_ge2d.ge2dinfo.src_info[0].rect.w = sRect.w;
290 g_ge2d.ge2dinfo.src_info[0].rect.h = sRect.h;
291
292 g_ge2d.ge2dinfo.src_info[1].plane_number = 1;
293 g_ge2d.ge2dinfo.src_info[1].plane_alpha = dstSurface->alpha0;
294 g_ge2d.ge2dinfo.src_info[1].memtype = GE2D_CANVAS_ALLOC;
295 g_ge2d.ge2dinfo.src_info[1].mem_alloc_type = GE2D_MEM_DMABUF;
296 g_ge2d.ge2dinfo.src_info[1].layer_mode = GE2D_LAYER_MODE_NON;
297 g_ge2d.ge2dinfo.src_info[1].shared_fd[0] = (int32_t)dstSurface->phyAddr;
298 g_ge2d.ge2dinfo.src_info[1].canvas_w = dstSurface->width;
299 g_ge2d.ge2dinfo.src_info[1].canvas_h = dstSurface->height;
300 g_ge2d.ge2dinfo.src_info[1].format = pixelFormatChange(dstSurface->enColorFmt);
301 g_ge2d.ge2dinfo.src_info[1].rect.x = dRect.x;
302 g_ge2d.ge2dinfo.src_info[1].rect.y = dRect.y;
303 g_ge2d.ge2dinfo.src_info[1].rect.w = dRect.w;
304 g_ge2d.ge2dinfo.src_info[1].rect.h = dRect.h;
305
306 ret = aml_ge2d_process(&g_ge2d.ge2dinfo);
307 if (ret < 0) {
308 DISPLAY_LOGE("aml_ge2d_process failed. ret=%{public}d", ret);
309 return DISPLAY_FAILURE;
310 }
311
312 return DISPLAY_SUCCESS;
313 }
314
BlitGe2dAlpha(ISurface * dstSurface,IRect dRect)315 static int32_t BlitGe2dAlpha(ISurface *dstSurface, IRect dRect)
316 {
317 int32_t ret = DISPLAY_SUCCESS;
318
319 g_ge2d.ge2dinfo.src_info[0].layer_mode = GE2D_LAYER_MODE_PREMULTIPLIED;
320 g_ge2d.ge2dinfo.dst_info.mem_alloc_type = GE2D_MEM_DMABUF;
321 g_ge2d.ge2dinfo.dst_info.memtype = GE2D_CANVAS_ALLOC;
322 g_ge2d.ge2dinfo.dst_info.shared_fd[0] = (int32_t)dstSurface->phyAddr;
323 g_ge2d.ge2dinfo.dst_info.plane_number = 1;
324 g_ge2d.ge2dinfo.dst_info.plane_alpha = dstSurface->alpha0;
325 g_ge2d.ge2dinfo.dst_info.canvas_w = dstSurface->width;
326 g_ge2d.ge2dinfo.dst_info.canvas_h = dstSurface->height;
327 g_ge2d.ge2dinfo.dst_info.format = pixelFormatChange(dstSurface->enColorFmt);
328 g_ge2d.ge2dinfo.dst_info.rect.x = dRect.x;
329 g_ge2d.ge2dinfo.dst_info.rect.y = dRect.y;
330 g_ge2d.ge2dinfo.dst_info.rect.w = dRect.w;
331 g_ge2d.ge2dinfo.dst_info.rect.h = dRect.h;
332
333 ret = aml_ge2d_process(&g_ge2d.ge2dinfo);
334 if (ret < 0) {
335 DISPLAY_LOGE("aml_ge2d_process failed. ret=%{public}d", ret);
336 return DISPLAY_FAILURE;
337 }
338
339 return DISPLAY_SUCCESS;
340 }
341
Blit(ISurface * srcSurface,IRect * srcRect,ISurface * dstSurface,IRect * dstRect,GfxOpt * opt)342 static int32_t Blit(ISurface *srcSurface, IRect *srcRect, ISurface *dstSurface, IRect *dstRect, GfxOpt *opt)
343 {
344 int32_t ret = DISPLAY_SUCCESS;
345 IRect sRect, dRect;
346 enum GE2DOP opMode = GE2D_OP_NONE;
347
348 if ((srcSurface == NULL) || (dstSurface == NULL)) {
349 DISPLAY_LOGE("srcSurface or dstSurface is null and return\n");
350 return DISPLAY_NULL_PTR;
351 }
352
353 if (srcRect != NULL) {
354 sRect.x = srcRect->x;
355 sRect.y = srcRect->y;
356 sRect.w = srcRect->w;
357 sRect.h = srcRect->h;
358 } else {
359 sRect.x = 0;
360 sRect.y = 0;
361 sRect.w = srcSurface->width;
362 sRect.h = srcSurface->height;
363 }
364
365 if (dstRect != NULL) {
366 dRect.x = dstRect->x;
367 dRect.y = dstRect->y;
368 dRect.w = dstRect->w;
369 dRect.h = dstRect->h;
370 } else {
371 dRect.x = 0;
372 dRect.y = 0;
373 dRect.w = dstSurface->width;
374 dRect.h = dstSurface->height;
375 }
376
377 DISPLAY_LOGD("src: w %{public}d, h %{publuc}d, dst:w %{public}d, h %{publuc}d", \
378 srcSurface->width, srcSurface->height, dstSurface->width, dstSurface->height);
379
380 if ((sRect.w != dRect.w) || (sRect.h != dRect.h)) {
381 opMode = GE2D_OP_STRETCHBLIT;
382 } else {
383 opMode = GE2D_OP_BLIT;
384 }
385
386 BlitGe2dOpt(opMode, opt);
387
388 ret = BlitGe2dNoAlpha(srcSurface, sRect, dstSurface, dRect);
389 if (ret < 0) {
390 DISPLAY_LOGE("BlitGe2dNoAlpha failed. ret=%{public}d", ret);
391 return DISPLAY_FAILURE;
392 }
393
394 ret = BlitGe2dAlpha(dstSurface, dRect);
395 if (ret < 0) {
396 DISPLAY_LOGE("BlitGe2dAlpha failed. ret=%{public}d", ret);
397 return DISPLAY_FAILURE;
398 }
399
400 return DISPLAY_SUCCESS;
401 }
402
Sync(int32_t timeOut)403 static int32_t Sync(int32_t timeOut)
404 {
405 return DISPLAY_SUCCESS;
406 }
407
GfxInitialize(GfxFuncs ** funcs)408 int32_t GfxInitialize(GfxFuncs **funcs)
409 {
410 DISPLAY_CHK_RETURN((funcs == NULL), DISPLAY_PARAM_ERR, DISPLAY_LOGE("info is null"));
411 GfxFuncs *gfxFuncs = (GfxFuncs *)malloc(sizeof(GfxFuncs));
412 if (!gfxFuncs) {
413 DISPLAY_LOGE("malloc GfxFuncs failed");
414 return DISPLAY_FAILURE;
415 }
416
417 errno_t eok = memset_s((void *)gfxFuncs, sizeof(GfxFuncs), 0, sizeof(GfxFuncs));
418 if (eok != EOK) {
419 DISPLAY_LOGE("memset_s failed");
420 free(gfxFuncs);
421 return DISPLAY_FAILURE;
422 }
423
424 gfxFuncs->InitGfx = InitGfx;
425 gfxFuncs->DeinitGfx = DeinitGfx;
426 gfxFuncs->FillRect = FillRect;
427 gfxFuncs->Blit = Blit;
428 gfxFuncs->Sync = Sync;
429 *funcs = gfxFuncs;
430
431 return DISPLAY_SUCCESS;
432 }
433
GfxUninitialize(GfxFuncs * funcs)434 int32_t GfxUninitialize(GfxFuncs *funcs)
435 {
436 if (funcs == NULL) {
437 DISPLAY_LOGE("funcs is null and return\n");
438 return DISPLAY_NULL_PTR;
439 }
440 free(funcs);
441 DISPLAY_LOGI("%s: gfx uninitialize success", __func__);
442 return DISPLAY_SUCCESS;
443 }
444