Files

153 lines
3.8 KiB
C++

/*
* 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 <cstring>
#include <xf86drm.h>
#include <drm_fourcc.h>
#include <sys/mman.h>
#include <unistd.h>
#include <fcntl.h>
#include <cstdio>
#include <meson_drm.h>
#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<DrmFramebufferBase> 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;
}