153 lines
3.8 KiB
C++
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;
|
|
}
|