1094332d3Sopenharmony_ci/* 2094332d3Sopenharmony_ci * Copyright (c) 2021-2023 Huawei Device Co., Ltd. 3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License. 5094332d3Sopenharmony_ci * You may obtain a copy of the License at 6094332d3Sopenharmony_ci * 7094332d3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8094332d3Sopenharmony_ci * 9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and 13094332d3Sopenharmony_ci * limitations under the License. 14094332d3Sopenharmony_ci */ 15094332d3Sopenharmony_ci 16094332d3Sopenharmony_ci#include "display_gralloc_gbm.h" 17094332d3Sopenharmony_ci#include <cstdio> 18094332d3Sopenharmony_ci#include <unistd.h> 19094332d3Sopenharmony_ci#include <cerrno> 20094332d3Sopenharmony_ci#include <cinttypes> 21094332d3Sopenharmony_ci#include <climits> 22094332d3Sopenharmony_ci#include <cstring> 23094332d3Sopenharmony_ci#include <fcntl.h> 24094332d3Sopenharmony_ci#include <pthread.h> 25094332d3Sopenharmony_ci#include <sys/mman.h> 26094332d3Sopenharmony_ci#include <sys/ioctl.h> 27094332d3Sopenharmony_ci#include <xf86drm.h> 28094332d3Sopenharmony_ci#include <securec.h> 29094332d3Sopenharmony_ci#include <linux/dma-buf.h> 30094332d3Sopenharmony_ci#include "drm_fourcc.h" 31094332d3Sopenharmony_ci#include "hisilicon_drm.h" 32094332d3Sopenharmony_ci#include "hi_gbm.h" 33094332d3Sopenharmony_ci#include "hdf_dlist.h" 34094332d3Sopenharmony_ci#include "display_gralloc_private.h" 35094332d3Sopenharmony_ci#include "display_log.h" 36094332d3Sopenharmony_ci#include "v1_0/display_composer_type.h" 37094332d3Sopenharmony_ci 38094332d3Sopenharmony_cinamespace OHOS { 39094332d3Sopenharmony_cinamespace HDI { 40094332d3Sopenharmony_cinamespace DISPLAY { 41094332d3Sopenharmony_ciusing namespace OHOS::HDI::Display::Composer::V1_0; 42094332d3Sopenharmony_ciusing namespace OHOS::HDI::Display::Buffer::V1_0; 43094332d3Sopenharmony_ci 44094332d3Sopenharmony_ciconst char *g_drmFileNode = "/dev/dri/renderD128"; 45094332d3Sopenharmony_cistatic GrallocManager *g_grallocManager = nullptr; 46094332d3Sopenharmony_cistatic pthread_mutex_t g_lock; 47094332d3Sopenharmony_ci 48094332d3Sopenharmony_ciusing PixelFormatConvertTbl = struct { 49094332d3Sopenharmony_ci uint32_t drmFormat; 50094332d3Sopenharmony_ci PixelFormat pixFormat; 51094332d3Sopenharmony_ci}; 52094332d3Sopenharmony_ci 53094332d3Sopenharmony_ciusing ValueStrMap = struct { 54094332d3Sopenharmony_ci uint32_t value; 55094332d3Sopenharmony_ci const char *str; 56094332d3Sopenharmony_ci}; 57094332d3Sopenharmony_ci 58094332d3Sopenharmony_cistatic GrallocManager *GetGrallocManager(void) 59094332d3Sopenharmony_ci{ 60094332d3Sopenharmony_ci if (g_grallocManager == nullptr) { 61094332d3Sopenharmony_ci g_grallocManager = (GrallocManager *)malloc(sizeof(GrallocManager)); 62094332d3Sopenharmony_ci errno_t eok = memset_s(g_grallocManager, sizeof(GrallocManager), 0, sizeof(GrallocManager)); 63094332d3Sopenharmony_ci if (eok != EOK) { 64094332d3Sopenharmony_ci DISPLAY_LOGE("memset_s failed"); 65094332d3Sopenharmony_ci } 66094332d3Sopenharmony_ci if (g_grallocManager == nullptr) { 67094332d3Sopenharmony_ci DISPLAY_LOGE("gralloc manager malloc failed"); 68094332d3Sopenharmony_ci } 69094332d3Sopenharmony_ci } 70094332d3Sopenharmony_ci return g_grallocManager; 71094332d3Sopenharmony_ci} 72094332d3Sopenharmony_ci 73094332d3Sopenharmony_ciconst char *GetPixelFmtStr(PixelFormat format) 74094332d3Sopenharmony_ci{ 75094332d3Sopenharmony_ci static const ValueStrMap PIXEL_STR_MAPS[] = { 76094332d3Sopenharmony_ci {PIXEL_FMT_CLUT8, "PIXEL_FMT_CLUT8"}, {PIXEL_FMT_CLUT1, "PIXEL_FMT_CLUT1"}, 77094332d3Sopenharmony_ci {PIXEL_FMT_CLUT4, "PIXEL_FMT_CLUT4"}, {PIXEL_FMT_RGB_565, "PIXEL_FMT_RGB_565"}, 78094332d3Sopenharmony_ci {PIXEL_FMT_RGBA_5658, "IXEL_FMT_RGBA_5658"}, {PIXEL_FMT_RGBX_4444, "PIXEL_FMT_RGBX_4444"}, 79094332d3Sopenharmony_ci {PIXEL_FMT_RGBA_4444, "PIXEL_FMT_RGBA_4444"}, {PIXEL_FMT_RGB_444, "PIXEL_FMT_RGB_444"}, 80094332d3Sopenharmony_ci {PIXEL_FMT_RGBX_5551, "PIXEL_FMT_RGBX_5551"}, {PIXEL_FMT_RGBA_5551, "PIXEL_FMT_RGBA_5551"}, 81094332d3Sopenharmony_ci {PIXEL_FMT_RGB_555, "PIXEL_FMT_RGB_555"}, {PIXEL_FMT_RGBX_8888, "PIXEL_FMT_RGBX_8888"}, 82094332d3Sopenharmony_ci {PIXEL_FMT_RGBA_8888, "PIXEL_FMT_RGBA_8888"}, {PIXEL_FMT_RGB_888, "PIXEL_FMT_RGB_888"}, 83094332d3Sopenharmony_ci {PIXEL_FMT_BGR_565, "PIXEL_FMT_BGR_565"}, {PIXEL_FMT_BGRX_4444, "PIXEL_FMT_BGRX_4444"}, 84094332d3Sopenharmony_ci {PIXEL_FMT_BGRA_4444, "PIXEL_FMT_BGRA_4444"}, {PIXEL_FMT_BGRX_5551, "PIXEL_FMT_BGRX_5551"}, 85094332d3Sopenharmony_ci {PIXEL_FMT_BGRA_5551, "PIXEL_FMT_BGRA_5551"}, {PIXEL_FMT_BGRX_8888, "PIXEL_FMT_BGRX_8888"}, 86094332d3Sopenharmony_ci {PIXEL_FMT_BGRA_8888, "PIXEL_FMT_BGRA_8888"}, {PIXEL_FMT_YUV_422_I, "PIXEL_FMT_YUV_422_I"}, 87094332d3Sopenharmony_ci {PIXEL_FMT_YUV_422_I, "PIXEL_FMT_YUV_422_I"}, {PIXEL_FMT_YCBCR_422_SP, "PIXEL_FMT_YCBCR_422_SP"}, 88094332d3Sopenharmony_ci {PIXEL_FMT_YCRCB_422_SP, "PIXEL_FMT_YCRCB_422_SP"}, {PIXEL_FMT_YCBCR_420_SP, "PIXEL_FMT_YCBCR_420_SP"}, 89094332d3Sopenharmony_ci {PIXEL_FMT_YCRCB_420_SP, "PIXEL_FMT_YCRCB_420_SP"}, {PIXEL_FMT_YCBCR_422_P, "PIXEL_FMT_YCBCR_422_P"}, 90094332d3Sopenharmony_ci {PIXEL_FMT_YCRCB_422_P, "PIXEL_FMT_YCRCB_422_P"}, {PIXEL_FMT_YCBCR_420_P, "PIXEL_FMT_YCBCR_420_P"}, 91094332d3Sopenharmony_ci {PIXEL_FMT_YCRCB_420_P, "PIXEL_FMT_YCRCB_420_P"}, {PIXEL_FMT_YUYV_422_PKG, "PIXEL_FMT_YUYV_422_PKG"}, 92094332d3Sopenharmony_ci {PIXEL_FMT_UYVY_422_PKG, "PIXEL_FMT_UYVY_422_PKG"}, {PIXEL_FMT_YVYU_422_PKG, "PIXEL_FMT_YVYU_422_PKG"}, 93094332d3Sopenharmony_ci {PIXEL_FMT_VYUY_422_PKG, "PIXEL_FMT_VYUY_422_PKG"}, {PIXEL_FMT_BUTT, "PIXEL_FMT_BUTT"}, 94094332d3Sopenharmony_ci }; 95094332d3Sopenharmony_ci static const char *unknown = "unknown format"; 96094332d3Sopenharmony_ci for (uint32_t i = 0; i < sizeof(PIXEL_STR_MAPS) / sizeof(PIXEL_STR_MAPS[0]); i++) { 97094332d3Sopenharmony_ci if (PIXEL_STR_MAPS[i].value == static_cast<uint32_t>(format)) { 98094332d3Sopenharmony_ci return PIXEL_STR_MAPS[i].str; 99094332d3Sopenharmony_ci } 100094332d3Sopenharmony_ci } 101094332d3Sopenharmony_ci DISPLAY_LOGE("GetPixelFmtStr unknown format %{public}d", format); 102094332d3Sopenharmony_ci return unknown; 103094332d3Sopenharmony_ci} 104094332d3Sopenharmony_ci 105094332d3Sopenharmony_ciconst char *GetDrmFmtStr(uint32_t format) 106094332d3Sopenharmony_ci{ 107094332d3Sopenharmony_ci static const ValueStrMap FORMAT_STR_MAPS[] = { 108094332d3Sopenharmony_ci {DRM_FORMAT_C8, "DRM_FORMAT_C8" }, {DRM_FORMAT_R8, "DRM_FORMAT_R8" }, 109094332d3Sopenharmony_ci {DRM_FORMAT_R16, "DRM_FORMAT_R16"}, {DRM_FORMAT_RG88, "DRM_FORMAT_RG88"}, 110094332d3Sopenharmony_ci {DRM_FORMAT_GR88, "DRM_FORMAT_GR88"}, {DRM_FORMAT_RG1616, "DRM_FORMAT_RG1616"}, 111094332d3Sopenharmony_ci {DRM_FORMAT_GR1616, "DRM_FORMAT_GR1616"}, {DRM_FORMAT_RGB332, "DRM_FORMAT_RGB332"}, 112094332d3Sopenharmony_ci {DRM_FORMAT_BGR233, "DRM_FORMAT_BGR233"}, {DRM_FORMAT_XRGB4444, "DRM_FORMAT_XRGB4444"}, 113094332d3Sopenharmony_ci {DRM_FORMAT_XBGR4444, "DRM_FORMAT_XBGR4444"}, {DRM_FORMAT_RGBX4444, "DRM_FORMAT_RGBX4444"}, 114094332d3Sopenharmony_ci {DRM_FORMAT_BGRX4444, "DRM_FORMAT_BGRX4444"}, {DRM_FORMAT_ARGB4444, "DRM_FORMAT_ARGB4444"}, 115094332d3Sopenharmony_ci {DRM_FORMAT_ABGR4444, "DRM_FORMAT_ABGR4444"}, {DRM_FORMAT_RGBA4444, "DRM_FORMAT_RGBA4444"}, 116094332d3Sopenharmony_ci {DRM_FORMAT_BGRA4444, "DRM_FORMAT_BGRA4444"}, {DRM_FORMAT_XRGB1555, "DRM_FORMAT_XRGB1555"}, 117094332d3Sopenharmony_ci {DRM_FORMAT_XBGR1555, "DRM_FORMAT_XBGR1555"}, {DRM_FORMAT_RGBX5551, "DRM_FORMAT_RGBX5551"}, 118094332d3Sopenharmony_ci {DRM_FORMAT_BGRX5551, "DRM_FORMAT_BGRX5551"}, {DRM_FORMAT_ARGB1555, "DRM_FORMAT_ARGB1555"}, 119094332d3Sopenharmony_ci {DRM_FORMAT_ABGR1555, "DRM_FORMAT_ABGR1555"}, {DRM_FORMAT_RGBA5551, "DRM_FORMAT_RGBA5551"}, 120094332d3Sopenharmony_ci {DRM_FORMAT_BGRA5551, "DRM_FORMAT_BGRA5551"}, {DRM_FORMAT_RGB565, "DRM_FORMAT_RGB565"}, 121094332d3Sopenharmony_ci {DRM_FORMAT_BGR565, "DRM_FORMAT_BGR565"}, {DRM_FORMAT_RGB888, "DRM_FORMAT_RGB888"}, 122094332d3Sopenharmony_ci {DRM_FORMAT_BGR888, "DRM_FORMAT_BGR888"}, {DRM_FORMAT_XRGB8888, "DRM_FORMAT_XRGB8888"}, 123094332d3Sopenharmony_ci {DRM_FORMAT_XBGR8888, "DRM_FORMAT_XBGR8888"}, {DRM_FORMAT_RGBX8888, "DRM_FORMAT_RGBX8888"}, 124094332d3Sopenharmony_ci {DRM_FORMAT_BGRX8888, "DRM_FORMAT_BGRX8888"}, {DRM_FORMAT_ARGB8888, "DRM_FORMAT_ARGB8888"}, 125094332d3Sopenharmony_ci {DRM_FORMAT_ABGR8888, "DRM_FORMAT_ABGR8888"}, {DRM_FORMAT_RGBA8888, "DRM_FORMAT_RGBA8888"}, 126094332d3Sopenharmony_ci {DRM_FORMAT_BGRA8888, "DRM_FORMAT_BGRA8888"}, {DRM_FORMAT_XRGB2101010, "DRM_FORMAT_XRGB2101010"}, 127094332d3Sopenharmony_ci {DRM_FORMAT_BGRX1010102, "DRM_FORMAT_BGRX1010102"}, {DRM_FORMAT_ARGB2101010, "DRM_FORMAT_ARGB2101010"}, 128094332d3Sopenharmony_ci {DRM_FORMAT_ABGR2101010, "DRM_FORMAT_ABGR2101010"}, {DRM_FORMAT_RGBA1010102, "DRM_FORMAT_RGBA1010102"}, 129094332d3Sopenharmony_ci {DRM_FORMAT_YVYU, "DRM_FORMAT_YVYU"}, {DRM_FORMAT_UYVY, "DRM_FORMAT_UYVY"}, 130094332d3Sopenharmony_ci {DRM_FORMAT_VYUY, "DRM_FORMAT_VYUY"}, {DRM_FORMAT_AYUV, "DRM_FORMAT_AYUV"}, 131094332d3Sopenharmony_ci {DRM_FORMAT_NV12, "DRM_FORMAT_NV12"}, {DRM_FORMAT_NV21, "DRM_FORMAT_NV21"}, 132094332d3Sopenharmony_ci {DRM_FORMAT_NV16, "DRM_FORMAT_NV16"}, {DRM_FORMAT_NV61, "DRM_FORMAT_NV61"}, 133094332d3Sopenharmony_ci {DRM_FORMAT_NV24, "DRM_FORMAT_NV24"}, {DRM_FORMAT_NV42, "DRM_FORMAT_NV42"}, 134094332d3Sopenharmony_ci {DRM_FORMAT_YUV410, "DRM_FORMAT_YUV410"}, {DRM_FORMAT_YVU410, "DRM_FORMAT_YVU410"}, 135094332d3Sopenharmony_ci {DRM_FORMAT_YUV411, "DRM_FORMAT_YUV411"}, {DRM_FORMAT_YVU411, "DRM_FORMAT_YVU411"}, 136094332d3Sopenharmony_ci {DRM_FORMAT_YUV420, "DRM_FORMAT_YUV420"}, {DRM_FORMAT_YVU420, "DRM_FORMAT_YVU420"}, 137094332d3Sopenharmony_ci {DRM_FORMAT_YUV422, "DRM_FORMAT_YUV422"}, {DRM_FORMAT_YVU422, "DRM_FORMAT_YVU422"}, 138094332d3Sopenharmony_ci {DRM_FORMAT_YUV444, "DRM_FORMAT_YUV444"}, {DRM_FORMAT_YVU444, "DRM_FORMAT_YVU444"}, 139094332d3Sopenharmony_ci }; 140094332d3Sopenharmony_ci 141094332d3Sopenharmony_ci static const char *unknown = "unknown drm format"; 142094332d3Sopenharmony_ci for (uint32_t i = 0; i < sizeof(FORMAT_STR_MAPS) / sizeof(FORMAT_STR_MAPS[0]); i++) { 143094332d3Sopenharmony_ci if (FORMAT_STR_MAPS[i].value == format) { 144094332d3Sopenharmony_ci return FORMAT_STR_MAPS[i].str; 145094332d3Sopenharmony_ci } 146094332d3Sopenharmony_ci } 147094332d3Sopenharmony_ci DISPLAY_LOGE("GetDrmFmtStr unknown format %{public}d", format); 148094332d3Sopenharmony_ci return unknown; 149094332d3Sopenharmony_ci} 150094332d3Sopenharmony_ci 151094332d3Sopenharmony_cistatic uint32_t ConvertFormatToDrm(PixelFormat fmtIn) 152094332d3Sopenharmony_ci{ 153094332d3Sopenharmony_ci static const PixelFormatConvertTbl CONVERT_TABLE[] = { 154094332d3Sopenharmony_ci {DRM_FORMAT_RGBX8888, PIXEL_FMT_RGBX_8888}, {DRM_FORMAT_RGBA8888, PIXEL_FMT_RGBA_8888}, 155094332d3Sopenharmony_ci {DRM_FORMAT_RGB888, PIXEL_FMT_RGB_888}, {DRM_FORMAT_RGB565, PIXEL_FMT_BGR_565}, 156094332d3Sopenharmony_ci {DRM_FORMAT_BGRX4444, PIXEL_FMT_BGRX_4444}, {DRM_FORMAT_BGRA4444, PIXEL_FMT_BGRA_4444}, 157094332d3Sopenharmony_ci {DRM_FORMAT_RGBA4444, PIXEL_FMT_RGBA_4444}, {DRM_FORMAT_RGBX4444, PIXEL_FMT_RGBX_4444}, 158094332d3Sopenharmony_ci {DRM_FORMAT_BGRX5551, PIXEL_FMT_BGRX_5551}, {DRM_FORMAT_BGRA5551, PIXEL_FMT_BGRA_5551}, 159094332d3Sopenharmony_ci {DRM_FORMAT_BGRX8888, PIXEL_FMT_BGRX_8888}, {DRM_FORMAT_BGRA8888, PIXEL_FMT_BGRA_8888}, 160094332d3Sopenharmony_ci {DRM_FORMAT_NV12, PIXEL_FMT_YCBCR_420_SP}, {DRM_FORMAT_NV21, PIXEL_FMT_YCRCB_420_SP}, 161094332d3Sopenharmony_ci {DRM_FORMAT_YUV420, PIXEL_FMT_YCBCR_420_P}, {DRM_FORMAT_YVU420, PIXEL_FMT_YCRCB_420_P}, 162094332d3Sopenharmony_ci {DRM_FORMAT_NV16, PIXEL_FMT_YCBCR_422_SP}, {DRM_FORMAT_NV61, PIXEL_FMT_YCRCB_422_SP}, 163094332d3Sopenharmony_ci {DRM_FORMAT_YUV422, PIXEL_FMT_YCBCR_422_P}, {DRM_FORMAT_YVU422, PIXEL_FMT_YCRCB_422_P}, 164094332d3Sopenharmony_ci }; 165094332d3Sopenharmony_ci uint32_t fmtOut = 0; 166094332d3Sopenharmony_ci for (uint32_t i = 0; i < sizeof(CONVERT_TABLE) / sizeof(CONVERT_TABLE[0]); i++) { 167094332d3Sopenharmony_ci if (CONVERT_TABLE[i].pixFormat == fmtIn) { 168094332d3Sopenharmony_ci fmtOut = CONVERT_TABLE[i].drmFormat; 169094332d3Sopenharmony_ci } 170094332d3Sopenharmony_ci } 171094332d3Sopenharmony_ci DISPLAY_LOGD("fmtIn %{public}d : %{public}s, outFmt %{public}d : %{public}s", fmtIn, 172094332d3Sopenharmony_ci GetPixelFmtStr(fmtIn), fmtOut, GetDrmFmtStr(fmtOut)); 173094332d3Sopenharmony_ci return fmtOut; 174094332d3Sopenharmony_ci} 175094332d3Sopenharmony_ci 176094332d3Sopenharmony_cistatic uint64_t ConvertUsageToGbm(uint64_t inUsage) 177094332d3Sopenharmony_ci{ 178094332d3Sopenharmony_ci uint64_t outUsage = GBM_BO_USE_TEXTURING; 179094332d3Sopenharmony_ci if (inUsage & HBM_USE_CPU_READ) { 180094332d3Sopenharmony_ci outUsage |= GBM_BO_USE_SW_READ_OFTEN; 181094332d3Sopenharmony_ci } 182094332d3Sopenharmony_ci if (inUsage & HBM_USE_CPU_WRITE) { 183094332d3Sopenharmony_ci outUsage |= GBM_BO_USE_SW_WRITE_OFTEN; 184094332d3Sopenharmony_ci } 185094332d3Sopenharmony_ci DISPLAY_LOGD("outUsage 0x%{public}" PRIx64 "", outUsage); 186094332d3Sopenharmony_ci return outUsage; 187094332d3Sopenharmony_ci} 188094332d3Sopenharmony_ci 189094332d3Sopenharmony_cistatic int32_t InitGbmDevice(const char *drmFile, GrallocManager *grallocManager) 190094332d3Sopenharmony_ci{ 191094332d3Sopenharmony_ci DISPLAY_LOGD(); 192094332d3Sopenharmony_ci if (grallocManager->gbmDevice == nullptr) { 193094332d3Sopenharmony_ci char path[PATH_MAX] = {0}; 194094332d3Sopenharmony_ci if (realpath(drmFile, path) == nullptr) { 195094332d3Sopenharmony_ci DISPLAY_LOGE(" drm File : %{public}s is not a realpath, errno: %{public}s", drmFile, strerror(errno)); 196094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 197094332d3Sopenharmony_ci } 198094332d3Sopenharmony_ci int drmFd = open(path, O_RDWR); 199094332d3Sopenharmony_ci if (drmFd < 0) { 200094332d3Sopenharmony_ci DISPLAY_LOGE("drm file:%{public}s open failed %{public}s", drmFile, strerror(errno)); 201094332d3Sopenharmony_ci return HDF_ERR_BAD_FD; 202094332d3Sopenharmony_ci } 203094332d3Sopenharmony_ci drmDropMaster(drmFd); 204094332d3Sopenharmony_ci struct gbm_device *gbmDevice = HdiGbmCreateDevice(drmFd); 205094332d3Sopenharmony_ci grallocManager->drmFd = drmFd; 206094332d3Sopenharmony_ci if (gbmDevice == nullptr) { 207094332d3Sopenharmony_ci close(drmFd); 208094332d3Sopenharmony_ci grallocManager->drmFd = -1; 209094332d3Sopenharmony_ci DISPLAY_LOGE("gbm device create failed"); 210094332d3Sopenharmony_ci return HDF_FAILURE; 211094332d3Sopenharmony_ci } 212094332d3Sopenharmony_ci grallocManager->gbmDevice = gbmDevice; 213094332d3Sopenharmony_ci grallocManager->drmFd = drmFd; 214094332d3Sopenharmony_ci DListHeadInit(&grallocManager->gbmBoHead); 215094332d3Sopenharmony_ci } 216094332d3Sopenharmony_ci return HDF_SUCCESS; 217094332d3Sopenharmony_ci} 218094332d3Sopenharmony_ci 219094332d3Sopenharmony_cistatic void DeInitGbmDevice(GrallocManager *grallocManager) 220094332d3Sopenharmony_ci{ 221094332d3Sopenharmony_ci DISPLAY_LOGD(); 222094332d3Sopenharmony_ci HdiGbmDeviceDestroy(grallocManager->gbmDevice); 223094332d3Sopenharmony_ci if (grallocManager->drmFd > 0) { 224094332d3Sopenharmony_ci close(grallocManager->drmFd); 225094332d3Sopenharmony_ci grallocManager->drmFd = -1; 226094332d3Sopenharmony_ci } 227094332d3Sopenharmony_ci grallocManager->gbmDevice = nullptr; 228094332d3Sopenharmony_ci} 229094332d3Sopenharmony_ci 230094332d3Sopenharmony_cistatic int32_t DmaBufferSync(const BufferHandle *handle, bool start) 231094332d3Sopenharmony_ci{ 232094332d3Sopenharmony_ci DISPLAY_LOGD(); 233094332d3Sopenharmony_ci struct dma_buf_sync syncPrm; 234094332d3Sopenharmony_ci errno_t eok = memset_s(&syncPrm, sizeof(syncPrm), 0, sizeof(syncPrm)); 235094332d3Sopenharmony_ci DISPLAY_CHK_RETURN((eok != EOK), HDF_ERR_INVALID_PARAM, DISPLAY_LOGE("dma buffer sync memset_s failed")); 236094332d3Sopenharmony_ci 237094332d3Sopenharmony_ci if (handle->usage & HBM_USE_CPU_WRITE) { 238094332d3Sopenharmony_ci syncPrm.flags |= DMA_BUF_SYNC_WRITE; 239094332d3Sopenharmony_ci } 240094332d3Sopenharmony_ci 241094332d3Sopenharmony_ci if (handle->usage & HBM_USE_CPU_READ) { 242094332d3Sopenharmony_ci syncPrm.flags |= DMA_BUF_SYNC_READ; 243094332d3Sopenharmony_ci } 244094332d3Sopenharmony_ci 245094332d3Sopenharmony_ci if (start) { 246094332d3Sopenharmony_ci syncPrm.flags |= DMA_BUF_SYNC_START; 247094332d3Sopenharmony_ci } else { 248094332d3Sopenharmony_ci syncPrm.flags |= DMA_BUF_SYNC_END; 249094332d3Sopenharmony_ci } 250094332d3Sopenharmony_ci int retry = 6; 251094332d3Sopenharmony_ci int ret; 252094332d3Sopenharmony_ci do { 253094332d3Sopenharmony_ci ret = ioctl(handle->fd, DMA_BUF_IOCTL_SYNC, &syncPrm); 254094332d3Sopenharmony_ci } while ((retry--) && (ret != -EAGAIN) && (ret != -EINTR)); 255094332d3Sopenharmony_ci 256094332d3Sopenharmony_ci if (ret < 0) { 257094332d3Sopenharmony_ci DISPLAY_LOGE("sync failed"); 258094332d3Sopenharmony_ci return HDF_ERR_DEVICE_BUSY; 259094332d3Sopenharmony_ci } 260094332d3Sopenharmony_ci return HDF_SUCCESS; 261094332d3Sopenharmony_ci} 262094332d3Sopenharmony_ci 263094332d3Sopenharmony_cistatic void InitBufferHandle(struct gbm_bo *bo, int fd, const AllocInfo *info, PriBufferHandle *buffer) 264094332d3Sopenharmony_ci{ 265094332d3Sopenharmony_ci BufferHandle *bufferHandle = &(buffer->hdl); 266094332d3Sopenharmony_ci bufferHandle->fd = fd; 267094332d3Sopenharmony_ci bufferHandle->reserveFds = 0; 268094332d3Sopenharmony_ci bufferHandle->reserveInts = 0; 269094332d3Sopenharmony_ci bufferHandle->stride = HdiGbmBoGetStride(bo); 270094332d3Sopenharmony_ci bufferHandle->width = HdiGbmBoGetWidth(bo); 271094332d3Sopenharmony_ci bufferHandle->height = HdiGbmBoGetHeight(bo); 272094332d3Sopenharmony_ci bufferHandle->usage = info->usage; 273094332d3Sopenharmony_ci bufferHandle->format = info->format; 274094332d3Sopenharmony_ci bufferHandle->virAddr = nullptr; 275094332d3Sopenharmony_ci bufferHandle->size = HdiGbmBoGetSize(bo); 276094332d3Sopenharmony_ci} 277094332d3Sopenharmony_ci 278094332d3Sopenharmony_ciint32_t GbmAllocMem(const AllocInfo *info, BufferHandle **buffer) 279094332d3Sopenharmony_ci{ 280094332d3Sopenharmony_ci DISPLAY_CHK_RETURN((info == nullptr), HDF_FAILURE, DISPLAY_LOGE("info is null")); 281094332d3Sopenharmony_ci DISPLAY_CHK_RETURN((buffer == nullptr), HDF_FAILURE, DISPLAY_LOGE("buffer is null")); 282094332d3Sopenharmony_ci PriBufferHandle *priBuffer = nullptr; 283094332d3Sopenharmony_ci uint32_t drmFmt = ConvertFormatToDrm(static_cast<PixelFormat>(info->format)); 284094332d3Sopenharmony_ci DISPLAY_CHK_RETURN((drmFmt == INVALID_PIXEL_FMT), HDF_ERR_NOT_SUPPORT, 285094332d3Sopenharmony_ci DISPLAY_LOGE("format %{public}d can not support", info->format)); 286094332d3Sopenharmony_ci DISPLAY_LOGD("requeset width %{public}d, heigt %{public}d, format %{public}d", 287094332d3Sopenharmony_ci info->width, info->height, drmFmt); 288094332d3Sopenharmony_ci 289094332d3Sopenharmony_ci GRALLOC_LOCK(); 290094332d3Sopenharmony_ci GrallocManager *grallocManager = GetGrallocManager(); 291094332d3Sopenharmony_ci DISPLAY_CHK_RETURN((grallocManager == nullptr), HDF_ERR_INVALID_PARAM, DISPLAY_LOGE("gralloc manager failed"); 292094332d3Sopenharmony_ci GRALLOC_UNLOCK()); 293094332d3Sopenharmony_ci struct gbm_bo *bo = 294094332d3Sopenharmony_ci HdiGbmBoCreate(grallocManager->gbmDevice, info->width, info->height, drmFmt, ConvertUsageToGbm(info->usage)); 295094332d3Sopenharmony_ci DISPLAY_CHK_RETURN((bo == nullptr), HDF_DEV_ERR_NO_MEMORY, DISPLAY_LOGE("gbm create bo failed"); \ 296094332d3Sopenharmony_ci GRALLOC_UNLOCK()); 297094332d3Sopenharmony_ci 298094332d3Sopenharmony_ci int fd = HdiGbmBoGetFd(bo); 299094332d3Sopenharmony_ci DISPLAY_CHK_RETURN((fd < 0), HDF_ERR_BAD_FD, DISPLAY_LOGE("gbm can not get fd"); \ 300094332d3Sopenharmony_ci HdiGbmBoDestroy(bo); \ 301094332d3Sopenharmony_ci GRALLOC_UNLOCK()); 302094332d3Sopenharmony_ci 303094332d3Sopenharmony_ci errno_t eok = EOK; 304094332d3Sopenharmony_ci priBuffer = (PriBufferHandle *)malloc(sizeof(PriBufferHandle)); 305094332d3Sopenharmony_ci if (priBuffer == nullptr) { 306094332d3Sopenharmony_ci DISPLAY_LOGE("bufferhandle malloc failed"); 307094332d3Sopenharmony_ci goto error; 308094332d3Sopenharmony_ci } 309094332d3Sopenharmony_ci 310094332d3Sopenharmony_ci eok = memset_s(priBuffer, sizeof(PriBufferHandle), 0, sizeof(PriBufferHandle)); 311094332d3Sopenharmony_ci if (eok != EOK) { 312094332d3Sopenharmony_ci DISPLAY_LOGE("memset_s failed"); 313094332d3Sopenharmony_ci goto error; 314094332d3Sopenharmony_ci } 315094332d3Sopenharmony_ci DISPLAY_CHK_RETURN((eok != EOK), DISPLAY_PARAM_ERR, DISPLAY_LOGE("memset_s failed")); 316094332d3Sopenharmony_ci 317094332d3Sopenharmony_ci InitBufferHandle(bo, fd, info, priBuffer); 318094332d3Sopenharmony_ci *buffer = &priBuffer->hdl; 319094332d3Sopenharmony_ci HdiGbmBoDestroy(bo); 320094332d3Sopenharmony_ci GRALLOC_UNLOCK(); 321094332d3Sopenharmony_ci return HDF_SUCCESS; 322094332d3Sopenharmony_cierror: 323094332d3Sopenharmony_ci close(fd); 324094332d3Sopenharmony_ci HdiGbmBoDestroy(bo); 325094332d3Sopenharmony_ci if (priBuffer != nullptr) { 326094332d3Sopenharmony_ci free(priBuffer); 327094332d3Sopenharmony_ci } 328094332d3Sopenharmony_ci GRALLOC_UNLOCK(); 329094332d3Sopenharmony_ci return HDF_FAILURE; 330094332d3Sopenharmony_ci} 331094332d3Sopenharmony_ci 332094332d3Sopenharmony_cistatic void CloseBufferHandle(BufferHandle *handle) 333094332d3Sopenharmony_ci{ 334094332d3Sopenharmony_ci DISPLAY_CHK_RETURN_NOT_VALUE((handle == nullptr), DISPLAY_LOGE("buffer is null")); 335094332d3Sopenharmony_ci if (handle->fd >= 0) { 336094332d3Sopenharmony_ci close(handle->fd); 337094332d3Sopenharmony_ci handle->fd = -1; 338094332d3Sopenharmony_ci } 339094332d3Sopenharmony_ci const uint32_t reserveFds = handle->reserveFds; 340094332d3Sopenharmony_ci for (uint32_t i = 0; i < reserveFds; i++) { 341094332d3Sopenharmony_ci if (handle->reserve[i] >= 0) { 342094332d3Sopenharmony_ci close(handle->reserve[i]); 343094332d3Sopenharmony_ci handle->reserve[i] = -1; 344094332d3Sopenharmony_ci } 345094332d3Sopenharmony_ci } 346094332d3Sopenharmony_ci} 347094332d3Sopenharmony_ci 348094332d3Sopenharmony_civoid GbmFreeMem(BufferHandle *buffer) 349094332d3Sopenharmony_ci{ 350094332d3Sopenharmony_ci DISPLAY_LOGD(); 351094332d3Sopenharmony_ci DISPLAY_CHK_RETURN_NOT_VALUE((buffer == nullptr), DISPLAY_LOGE("buffer is null")); 352094332d3Sopenharmony_ci if ((buffer->virAddr != nullptr) && (GbmUnmap(buffer) != HDF_SUCCESS)) { 353094332d3Sopenharmony_ci DISPLAY_LOGE("freeMem unmap buffer failed"); 354094332d3Sopenharmony_ci } 355094332d3Sopenharmony_ci CloseBufferHandle(buffer); 356094332d3Sopenharmony_ci free(buffer); 357094332d3Sopenharmony_ci} 358094332d3Sopenharmony_ci 359094332d3Sopenharmony_civoid *GbmMmap(BufferHandle *buffer) 360094332d3Sopenharmony_ci{ 361094332d3Sopenharmony_ci void *virAddr = nullptr; 362094332d3Sopenharmony_ci DISPLAY_LOGD(); 363094332d3Sopenharmony_ci if (buffer == nullptr) { 364094332d3Sopenharmony_ci DISPLAY_LOGE("gbmmap the buffer handle is nullptr"); 365094332d3Sopenharmony_ci return nullptr; 366094332d3Sopenharmony_ci } 367094332d3Sopenharmony_ci if (buffer->virAddr != nullptr) { 368094332d3Sopenharmony_ci DISPLAY_LOGD("the buffer has virtual addr"); 369094332d3Sopenharmony_ci return buffer->virAddr; 370094332d3Sopenharmony_ci } 371094332d3Sopenharmony_ci virAddr = mmap(nullptr, buffer->size, PROT_READ | PROT_WRITE, MAP_SHARED, buffer->fd, 0); 372094332d3Sopenharmony_ci if (virAddr == reinterpret_cast<void *>(MAP_FAILED)) { 373094332d3Sopenharmony_ci DISPLAY_LOGE("mmap failed errno %{public}s, fd : %{public}d", strerror(errno), buffer->fd); 374094332d3Sopenharmony_ci } 375094332d3Sopenharmony_ci buffer->virAddr = virAddr; 376094332d3Sopenharmony_ci return virAddr; 377094332d3Sopenharmony_ci} 378094332d3Sopenharmony_ci 379094332d3Sopenharmony_ciint32_t GbmUnmap(BufferHandle *buffer) 380094332d3Sopenharmony_ci{ 381094332d3Sopenharmony_ci DISPLAY_LOGD(); 382094332d3Sopenharmony_ci if (buffer == nullptr) { 383094332d3Sopenharmony_ci DISPLAY_LOGE("gbmumap the buffer handle is null"); 384094332d3Sopenharmony_ci return HDF_FAILURE; 385094332d3Sopenharmony_ci } 386094332d3Sopenharmony_ci 387094332d3Sopenharmony_ci if (buffer->virAddr == nullptr) { 388094332d3Sopenharmony_ci DISPLAY_LOGE("virAddr is nullptr , has not map the buffer"); 389094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 390094332d3Sopenharmony_ci } 391094332d3Sopenharmony_ci int ret = munmap(buffer->virAddr, buffer->size); 392094332d3Sopenharmony_ci if (ret != 0) { 393094332d3Sopenharmony_ci DISPLAY_LOGE("munmap failed err: %{public}s", strerror(errno)); 394094332d3Sopenharmony_ci return HDF_FAILURE; 395094332d3Sopenharmony_ci } 396094332d3Sopenharmony_ci buffer->virAddr = nullptr; 397094332d3Sopenharmony_ci return HDF_SUCCESS; 398094332d3Sopenharmony_ci} 399094332d3Sopenharmony_ci 400094332d3Sopenharmony_ciint32_t GbmInvalidateCache(BufferHandle *buffer) 401094332d3Sopenharmony_ci{ 402094332d3Sopenharmony_ci DISPLAY_LOGD(); 403094332d3Sopenharmony_ci return DmaBufferSync(buffer, true); 404094332d3Sopenharmony_ci} 405094332d3Sopenharmony_ci 406094332d3Sopenharmony_ciint32_t GbmFlushCache(BufferHandle *buffer) 407094332d3Sopenharmony_ci{ 408094332d3Sopenharmony_ci DISPLAY_LOGD(); 409094332d3Sopenharmony_ci return DmaBufferSync(buffer, false); 410094332d3Sopenharmony_ci} 411094332d3Sopenharmony_ci 412094332d3Sopenharmony_ciint32_t GbmGrallocUninitialize(void) 413094332d3Sopenharmony_ci{ 414094332d3Sopenharmony_ci DISPLAY_LOGD(); 415094332d3Sopenharmony_ci GRALLOC_LOCK(); 416094332d3Sopenharmony_ci GrallocManager *grallocManager = GetGrallocManager(); 417094332d3Sopenharmony_ci DISPLAY_CHK_RETURN((grallocManager == nullptr), HDF_ERR_INVALID_PARAM, DISPLAY_LOGE("gralloc manager failed"); \ 418094332d3Sopenharmony_ci GRALLOC_UNLOCK()); 419094332d3Sopenharmony_ci grallocManager->referCount--; 420094332d3Sopenharmony_ci if (grallocManager->referCount < 0) { 421094332d3Sopenharmony_ci DeInitGbmDevice(grallocManager); 422094332d3Sopenharmony_ci free(g_grallocManager); 423094332d3Sopenharmony_ci g_grallocManager = nullptr; 424094332d3Sopenharmony_ci } 425094332d3Sopenharmony_ci GRALLOC_UNLOCK(); 426094332d3Sopenharmony_ci return HDF_SUCCESS; 427094332d3Sopenharmony_ci} 428094332d3Sopenharmony_ci 429094332d3Sopenharmony_ciint32_t GbmGrallocInitialize(void) 430094332d3Sopenharmony_ci{ 431094332d3Sopenharmony_ci DISPLAY_LOGD(); 432094332d3Sopenharmony_ci GRALLOC_LOCK(); 433094332d3Sopenharmony_ci GrallocManager *grallocManager = GetGrallocManager(); 434094332d3Sopenharmony_ci DISPLAY_CHK_RETURN((grallocManager == nullptr), HDF_ERR_INVALID_PARAM, DISPLAY_LOGE("gralloc manager failed"); \ 435094332d3Sopenharmony_ci GRALLOC_UNLOCK()); 436094332d3Sopenharmony_ci int ret = InitGbmDevice(g_drmFileNode, grallocManager); 437094332d3Sopenharmony_ci DISPLAY_CHK_RETURN((ret != HDF_SUCCESS), ret, DISPLAY_LOGE("gralloc manager failed"); \ 438094332d3Sopenharmony_ci GRALLOC_UNLOCK()); 439094332d3Sopenharmony_ci grallocManager->referCount++; 440094332d3Sopenharmony_ci GRALLOC_UNLOCK(); 441094332d3Sopenharmony_ci return HDF_SUCCESS; 442094332d3Sopenharmony_ci} 443094332d3Sopenharmony_ci} // namespace DISPLAY 444094332d3Sopenharmony_ci} // namespace HDI 445094332d3Sopenharmony_ci} // namespace OHOS 446