• 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 "seed_gbm.h"
17 #include <errno.h>
18 #include <fcntl.h>
19 #include <string.h>
20 #include <stdlib.h>
21 #include <xf86drm.h>
22 #include <xf86drmMode.h>
23 #include <drm_fourcc.h>
24 #include <securec.h>
25 #include "display_common.h"
26 #include "seed_gbm_internal.h"
27 
28 typedef struct {
29     uint32_t wPixelAlign;
30     uint32_t hPixelAlign;
31 } PlaneLayoutInfo;
32 
33 typedef struct {
34     uint32_t format;
35     uint32_t bitsPerPixel;
36     uint32_t numPlanes;
37     const PlaneLayoutInfo *planes;
38 } FormatInfo;
39 
40 static const PlaneLayoutInfo g_defaultLayout = {
41     32, 1
42 };
43 
44 static const PlaneLayoutInfo g_yuvLayout = {
45     16, 1
46 };
47 
GetFormatInfo(uint32_t format)48 static const FormatInfo *GetFormatInfo(uint32_t format)
49 {
50     static const FormatInfo fmtInfos[] = {
51         {DRM_FORMAT_RGBX8888,  32, 1, &g_defaultLayout},  {DRM_FORMAT_RGBA8888, 32,  1, &g_defaultLayout},
52         {DRM_FORMAT_BGRX8888,  32, 1, &g_defaultLayout},  {DRM_FORMAT_BGRA8888, 32,  1, &g_defaultLayout},
53         {DRM_FORMAT_RGB888,    24, 1, &g_defaultLayout},  {DRM_FORMAT_RGB565,  16, 1, &g_defaultLayout},
54         {DRM_FORMAT_BGRX4444,  16, 1, &g_defaultLayout},  {DRM_FORMAT_BGRA4444, 16,  1, &g_defaultLayout},
55         {DRM_FORMAT_RGBA4444,  16, 1, &g_defaultLayout},  {DRM_FORMAT_RGBX4444, 16,  1, &g_defaultLayout},
56         {DRM_FORMAT_BGRX5551,  16, 1, &g_defaultLayout},  {DRM_FORMAT_BGRA5551, 16,  1, &g_defaultLayout},
57         {DRM_FORMAT_NV12, 12, 2, &g_yuvLayout}, {DRM_FORMAT_NV21, 12, 2, &g_yuvLayout},
58         {DRM_FORMAT_NV16, 16, 2, &g_yuvLayout},  {DRM_FORMAT_NV61, 16, 2, &g_yuvLayout},
59         {DRM_FORMAT_YUV420, 12, 3, &g_yuvLayout}, {DRM_FORMAT_YVU420, 12, 3, &g_yuvLayout},
60         {DRM_FORMAT_YUV422, 16, 3, &g_yuvLayout}, {DRM_FORMAT_YVU422, 16, 3, &g_yuvLayout},
61     };
62 
63     for (uint32_t i = 0; i < sizeof(fmtInfos) / sizeof(FormatInfo); i++) {
64         if (fmtInfos[i].format == format) {
65             return &fmtInfos[i];
66         }
67     }
68     DISPLAY_LOGE("the format can not support");
69     return NULL;
70 }
71 
InitGbmBo(struct gbm_bo * bo,const struct drm_mode_create_dumb * dumb)72 void InitGbmBo(struct gbm_bo *bo, const struct drm_mode_create_dumb *dumb)
73 {
74     DISPLAY_CHK_RETURN_NOT_VALUE((dumb == NULL), DISPLAY_LOGE("dumb is null"));
75     DISPLAY_CHK_RETURN_NOT_VALUE((bo == NULL), DISPLAY_LOGE("bo is null"));
76     bo->stride = dumb->pitch;
77     bo->size = dumb->size;
78     bo->handle = dumb->handle;
79 }
80 
AdjustStrideFromFormat(const FormatInfo * fmtInfo,uint32_t * heightStride,uint32_t * widthStride)81 static bool AdjustStrideFromFormat(const FormatInfo *fmtInfo, uint32_t *heightStride, uint32_t *widthStride)
82 {
83     if (fmtInfo != NULL) {
84         *heightStride = ALIGN_UP((*heightStride), fmtInfo->planes->hPixelAlign);
85         *widthStride = ALIGN_UP((*widthStride), fmtInfo->planes->wPixelAlign);
86         return true;
87     }
88     return false;
89 }
90 
hdi_gbm_bo_create(struct gbm_device * gbm,uint32_t width,uint32_t height,uint32_t format,uint32_t usage)91 struct gbm_bo *hdi_gbm_bo_create(struct gbm_device *gbm, uint32_t width, uint32_t height, uint32_t format,
92     uint32_t usage)
93 {
94     DISPLAY_UNUSED(usage);
95     int ret;
96     struct drm_mode_create_dumb dumb = { 0 };
97     const FormatInfo *fmtInfo = GetFormatInfo(format);
98     DISPLAY_CHK_RETURN((fmtInfo == NULL), NULL, DISPLAY_LOGE("formt: 0x%{public}x can not get layout info", format));
99     struct gbm_bo *bo  = (struct gbm_bo *)calloc(1, sizeof(struct gbm_bo));
100     DISPLAY_CHK_RETURN((bo == NULL), NULL, DISPLAY_LOGE("gbm bo create fialed no memery"));
101     (void)memset_s(bo, sizeof(struct gbm_bo), 0, sizeof(struct gbm_bo));
102     AdjustStrideFromFormat(fmtInfo, &height, &width);
103     bo->width = width;
104     bo->height = height;
105     bo->gbm = gbm;
106     bo->format = format;
107     dumb.height = height;
108     dumb.width = width;
109     dumb.flags = 0;
110     dumb.bpp = fmtInfo->bitsPerPixel;
111     ret = drmIoctl(gbm->fd, DRM_IOCTL_MODE_CREATE_DUMB, &dumb);
112     DISPLAY_LOGI("fmt 0x%{public}x create dumb width: %{public}d  height: %{public}d bpp: %{public}u pitch %{public}d "
113         "size %{public}llu",
114         format, dumb.width, dumb.height, dumb.bpp, dumb.pitch, dumb.size);
115     DISPLAY_CHK_RETURN((ret != 0), NULL, DISPLAY_LOGE("DRM_IOCTL_MODE_CREATE_DUMB failed errno %{public}d", errno));
116     InitGbmBo(bo, &dumb);
117     DISPLAY_LOGI(
118         "fmt 0x%{public}x create dumb width: %{public}d  height: %{public}d  stride %{public}d size %{public}u", format,
119         bo->width, bo->height, bo->stride, bo->size);
120     return bo;
121 }
122 
hdi_gbm_create_device(int fd)123 struct gbm_device *hdi_gbm_create_device(int fd)
124 {
125     struct gbm_device *gbm;
126     gbm = (struct gbm_device *)calloc(1, sizeof(struct gbm_device));
127     DISPLAY_CHK_RETURN((gbm == NULL), NULL, DISPLAY_LOGE("memory calloc failed"));
128     gbm->fd = fd;
129     return gbm;
130 }
131 
hdi_gbm_device_destroy(struct gbm_device * gbm)132 void hdi_gbm_device_destroy(struct gbm_device *gbm)
133 {
134     free(gbm);
135 }
136 
hdi_gbm_bo_get_stride(struct gbm_bo * bo)137 uint32_t hdi_gbm_bo_get_stride(struct gbm_bo *bo)
138 {
139     DISPLAY_CHK_RETURN((bo == NULL), 0, DISPLAY_LOGE("the bo is null"));
140     return bo->stride;
141 }
142 
hdi_gbm_bo_get_width(struct gbm_bo * bo)143 uint32_t hdi_gbm_bo_get_width(struct gbm_bo *bo)
144 {
145     DISPLAY_CHK_RETURN((bo == NULL), 0, DISPLAY_LOGE("the bo is null"));
146     return bo->width;
147 }
148 
hdi_gbm_bo_get_height(struct gbm_bo * bo)149 uint32_t hdi_gbm_bo_get_height(struct gbm_bo *bo)
150 {
151     DISPLAY_CHK_RETURN((bo == NULL), 0, DISPLAY_LOGE("the bo is null"));
152     return bo->height;
153 }
154 
hdi_gbm_bo_destroy(struct gbm_bo * bo)155 void hdi_gbm_bo_destroy(struct gbm_bo *bo)
156 {
157     int ret;
158     DISPLAY_CHK_RETURN_NOT_VALUE((bo == NULL), DISPLAY_LOGE("the bo is null"));
159     struct drm_mode_destroy_dumb dumb = { 0 };
160     dumb.handle = bo->handle;
161     ret = drmIoctl(bo->gbm->fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dumb);
162     DISPLAY_CHK_RETURN_NOT_VALUE((ret), DISPLAY_LOGE("dumb buffer destroy failed errno %{public}d", errno));
163     free(bo);
164 }
165 
hdi_gbm_bo_get_fd(struct gbm_bo * bo)166 int hdi_gbm_bo_get_fd(struct gbm_bo *bo)
167 {
168     int fd, ret;
169     ret = drmPrimeHandleToFD(bo->gbm->fd, bo->handle, DRM_CLOEXEC | DRM_RDWR, &fd);
170     DISPLAY_CHK_RETURN((ret), -1,
171         DISPLAY_LOGE("drmPrimeHandleToFD  failed ret: %{public}d  errno: %{public}d", ret, errno));
172     return fd;
173 }
174