Files

291 lines
7.8 KiB
C++

/*
* Copyright (c) 2023 Amlogic, Inc. All rights reserved.
*
* This source code is subject to the terms and conditions defined in the
* file 'LICENSE' which is part of this source code package.
*
* Description:
*/
#define LOG_NDEBUG 1
#include <unistd.h>
#include <cstring>
#include "DrmFramebufferBase.h"
DrmFramebufferBase::DrmFramebufferBase() {
snprintf(mDebugInfo, 32, "DrmFramebufferBase");
mFd = -1;
mDpssTransformFlag = false;
mVtTransform = 0;
reset();
}
DrmFramebufferBase::~DrmFramebufferBase() {
if (mFd >= 0)
close(mFd);
mFd = -1;
}
int32_t DrmFramebufferBase::getAcquireFenceFd() {
return (mAcquireFence.get() ? mAcquireFence->dup() : -1);
}
int32_t DrmFramebufferBase::setAcquireFence(int32_t fenceFd) {
mAcquireFence.reset(new DrmFence(fenceFd));
return 0;
}
void DrmFramebufferBase::setBufferInfo(int fd, int32_t acquireFence) {
if (mFd >= 0)
close(mFd);
mFd = fd;
setAcquireFence(acquireFence);
mUpdated = true;
}
void DrmFramebufferBase::setBufferInfo(
uint32_t width, uint32_t height, uint32_t stride,
uint32_t alignHeight, uint32_t format) {
mBufferWidth = width;
mBufferHeight = height;
mBufferStride = stride;
mBufferFormat = format;
mBufferAlignHeight = alignHeight;
}
int32_t DrmFramebufferBase::getBufferInfo(
uint32_t & width, uint32_t & height, uint32_t & stride,
uint32_t & alignHeight, uint32_t & format) {
width = mBufferWidth;
height = mBufferHeight;
stride = mBufferStride;
format = mBufferFormat;
alignHeight = mBufferAlignHeight;
MESON_LOGV("[%s] [%" PRIu64 "] width:%d height:%d stride:%d format:%d",
__func__, mId, width, height, stride, format);
return 0;
}
void DrmFramebufferBase::reset() {
if (mFd >= 0) close(mFd);
mFd = -1;
mFbType = DRM_FB_UNDEFINED;
mBlendMode = DRM_BLEND_MODE_INVALID;
mCompositionType = MESON_COMPOSITION_UNDETERMINED;
mPlaneAlpha = 1.0;
mTransform = 0;
mZorder = 0xFFFFFFFF; //set to special value for debug.
mDataspace = 0;
mUpdated = false;
mLayerMetaData = 0;
mModifier = 0;
memset(&mDisplayFrame, 0, sizeof(mDisplayFrame));
memset(&mSourceCrop, 0, sizeof(mSourceCrop));
}
drm_fb_type_t DrmFramebufferBase::getFbType() {
std::lock_guard<std::mutex> lock(mMutex);
return mFbType;
}
int32_t DrmFramebufferBase::setFbType(drm_fb_type_t type) {
std::lock_guard<std::mutex> lock(mMutex);
mFbType = type;
mUpdated = true;
return 0;
}
drm_rect_t DrmFramebufferBase::getDisplayFrame() {
std::lock_guard<std::mutex> lock(mMutex);
return mDisplayFrame;
}
int32_t DrmFramebufferBase::setDisplayFrame(drm_rect_t dispFrame) {
std::lock_guard<std::mutex> lock(mMutex);
mDisplayFrame = dispFrame;
return 0;
}
drm_rect_t DrmFramebufferBase::getSourceCrop() {
std::lock_guard<std::mutex> lock(mMutex);
return mSourceCrop;
}
int32_t DrmFramebufferBase::setSourceCrop(drm_rect_t crop) {
std::lock_guard<std::mutex> lock(mMutex);
mSourceCrop = crop;
mUpdated = true;
return 0;
}
int32_t DrmFramebufferBase::setPlaneAlpha(float alpha) {
mPlaneAlpha = alpha;
mUpdated = true;
return 0;
}
int32_t DrmFramebufferBase::setTransform(int32_t transform) {
if (transform < TRANSFORM_NONE || transform > TRANSFORM_ROT_270) {
MESON_LOGD("setTransform layerId(%" PRIu64 ") transform %d not support",
mId, transform);
return 0;
}
mTransform = transform;
mUpdated = true;
return 0;
}
int32_t DrmFramebufferBase::setZorder(uint32_t z) {
mZorder = z;
mUpdated = true;
return 0;
}
int32_t DrmFramebufferBase::setDataspace(int32_t dataSpace) {
mDataspace = dataSpace;
mUpdated = true;
return 0;
}
int32_t DrmFramebufferBase::setSecureFlag(bool flag) {
mSecure = flag;
mUpdated = true;
return 0;
}
int32_t DrmFramebufferBase::setBlendMode (drm_blend_mode_t mode) {
mBlendMode = mode;
mUpdated = true;
return 0;
}
int32_t DrmFramebufferBase::setPrevReleaseFence(int32_t fenceFd) {
mPrevReleaseFence.reset(new DrmFence(fenceFd));
return 0;
}
int32_t DrmFramebufferBase::getPrevReleaseFence() {
return (mPrevReleaseFence.get() ? mPrevReleaseFence->dup() : -1);
}
int32_t DrmFramebufferBase::setCurReleaseFence(int32_t fenceFd) {
mCurReleaseFence.reset(new DrmFence(fenceFd));
return 0;
}
int32_t DrmFramebufferBase::getCurReleaseFence() {
return (mCurReleaseFence.get() ? mCurReleaseFence->dup() : -1);
}
int32_t DrmFramebufferBase::setPresentFence(int32_t fenceFd) {
mPresentFence.reset(new DrmFence(fenceFd));
return 0;
}
int32_t DrmFramebufferBase::getPresentFence(){
return (mPresentFence.get() ? mPresentFence->dup() : -1);
}
int32_t DrmFramebufferBase::setProcessFence(int32_t fenceFd) {
std::lock_guard<std::mutex> lock(mMutex);
mProcessFence.reset(new DrmFence(fenceFd));
return 0;
}
int32_t DrmFramebufferBase::getProcessFence() {
return (mProcessFence.get() ? mProcessFence->dup() : -1);
}
int32_t DrmFramebufferBase::onLayerDisplayed(int32_t releaseFence,
int32_t processFence) {
if (releaseFence < 0 || processFence < 0) {
int32_t fenceFd = (releaseFence < 0) ? processFence : releaseFence;
mCurReleaseFence.reset(new DrmFence(fenceFd));
} else {
mCurReleaseFence = DrmFence::merge(
"FBProcessor",
std::make_shared<DrmFence>(releaseFence),
std::make_shared<DrmFence>(processFence));
}
return 0;
}
int64_t DrmFramebufferBase::getLayerMetaData() {
return mLayerMetaData;
}
int32_t DrmFramebufferBase::setLayerMetaData(int64_t layerMetaData) {
mLayerMetaData = layerMetaData;
return 0;
}
void DrmFramebufferBase::setDpssTransformFlag(bool flag) {
/* call in DPSS PROCESSOR, */
mDpssTransformFlag = flag;
MESON_LOGV("%s, layerId [%" PRIu64 "] rotation %s performed in the DPSS",
__func__, mId, flag ? "was" : "was not");
}
/* ================ content change listener for videotunnel ================ */
int32_t DrmFramebufferBase::VtContentChangeListener::onFrameAvailable(
std::vector<std::shared_ptr<VtBufferItem>> & items) {
int32_t ret = -1;
if (mClient)
ret = mClient->onVtFrameAvailable(items);
else
MESON_LOGE("DrmFramebufferBase::VtContentChangeListener::%s mClient is NULL",
__func__);
return ret;
}
void DrmFramebufferBase::VtContentChangeListener::onVideoStatus(vt_video_status_t status) {
if (mClient)
mClient->onVtVideoStatus(status);
else
MESON_LOGE("DrmFramebufferBase::VtContentChangeListener::%s mClient is NULL",
__func__);
}
void DrmFramebufferBase::VtContentChangeListener::onVideoGameMode(int data) {
if (mClient)
mClient->onVtVideoGameMode(data);
else
MESON_LOGE("DrmFramebufferBase::VtContentChangeListener::%s mClient is NULL",
__func__);
}
void DrmFramebufferBase::VtContentChangeListener::onDisplayFrameChange(vt_rect & frame) {
drm_rect_t rect;
rect.left = frame .left;
rect.top = frame.top;
rect.right = frame.right;
rect.bottom = frame.bottom;
if (mClient)
mClient->setVtDisplayFrame(rect);
else
MESON_LOGE("DrmFramebufferBase::VtContentChangeListener::%s mClient is NULL",
__func__);
}
void DrmFramebufferBase::VtContentChangeListener::onVideoTransform(int transform) {
if (mClient)
mClient->setVtVideoTransform(transform);
else
MESON_LOGE("DrmFramebufferBase::VtContentChangeListener::%s mClient is NULL",
__func__);
}
/* ========================================================================= */