/* * Copyright (C) 2024 Amlogic Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include #include #ifndef DRM_IOCTL_MESON_RMFB #define DRM_IOCTL_MESON_RMFB DRM_IOWR(DRM_COMMAND_BASE + 0x01, unsigned int) #endif #include "DrmVideoBo.h" #include "DispAdptLog.h" DrmVideoBo::DrmVideoBo(int drmFd) { mDrmFd = drmFd; fbId = 0; width = 0; height = 0; format = 0; stride = 0; alpha = 0; z = 0; inFence = -1; nbo = 0; dmaBufFd = -1; repeatedBuf = false; rotate = 0; memset(&srcRect, 0, sizeof(srcRect)); memset(&crtcRect, 0, sizeof(crtcRect)); } DrmVideoBo::~DrmVideoBo() { release(); } int32_t DrmVideoBo::import(std::shared_ptr fb) { int ret = 0; uint32_t handle = 0; int drmFd = mDrmFd; uint32_t alignHeight = 0; if (fbId > 0) release(); fb->getBufferInfo(width, height, stride, alignHeight, format); nbo = (format == DRM_FORMAT_YUV444 ? 3 :2); if (width == 0 || height == 0) { DISPLAY_LOGE("import fail, width(%d) or height(%d) error", width, height); return -1; } dmaBufFd = fb->getBufferFd(); ret = drmPrimeFDToHandle(drmFd, dmaBufFd, &handle); if (ret != 0) { DISPLAY_LOGE("FdToHandle failed fd(%d) ret(%d), \n", dmaBufFd, ret); return ret; } for (uint32_t i = 0; i < nbo; i++) { handles[i] = handle; pitches[i] = stride; offsets[i] = i * stride * height; modifiers[i] = 0; } /*set other elements to invalid.*/ for (int i = nbo; i < BUF_PLANE_NUM; i++) { handles[i] = 0; pitches[i] = 0; offsets[i] = 0; modifiers[i] = 0; } ret = drmModeAddFB2WithModifiers(drmFd, width, height, format, handles, pitches, offsets, modifiers, &fbId, modifiers[0] ? DRM_MODE_FB_MODIFIERS : 0); DISPLAY_ASSERT(!ret, "drmModeAddFB2 failed(%d)", ret); srcRect = fb->getSourceCrop(); crtcRect = fb->getDisplayFrame(); alpha = fb->mPlaneAlpha; z = fb->mZorder; inFence = fb->getAcquireFenceFd(); rotate = fb->getTransform(); return ret; } int32_t DrmVideoBo::release() { if (fbId == 0) return 0; int ret = 0; int drmFd = mDrmFd; if (inFence >=0) close(inFence); inFence = -1; ret = drmIoctl(drmFd, DRM_IOCTL_MESON_RMFB, &fbId); if (ret !=0) { DISPLAY_LOGE("drmModeRmFB failed fbId[%d] ret[%d] handle[%d]", fbId, ret, handles[0]); return ret; } if (handles[0] != 0 && !repeatedBuf) { struct drm_gem_close closeArg; memset(&closeArg, 0, sizeof(drm_gem_close)); closeArg.handle = handles[0]; int ret = drmIoctl(drmFd, DRM_IOCTL_GEM_CLOSE, &closeArg); if (ret != 0) DISPLAY_LOGD("DRM_IOCTL_GEM_CLOSE failed fbId[%d] ret[%d] handle[%d]", fbId, ret, handles[0]); } for (int i = 0; i < BUF_PLANE_NUM; i++) handles[i] = 0; return ret; } uint32_t DrmVideoBo::getHandle() { return handles[0]; } void DrmVideoBo::setRepeatBuffer(bool repeat) { repeatedBuf = repeat; }