Files
BPI-CM9-Linux/aml-comp/vendor/amlogic/meson_videoserver/display/MesonLayer.h
T

309 lines
9.6 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.
*/
#ifndef MESON_LAYER_H
#define MESON_LAYER_H
#include <time.h>
#include <sys/time.h>
#include <utils/threads.h>
#include <pthread.h>
#include <deque>
#include <DrmTypes.h>
#include <BasicTypes.h>
#include <DrmFramebufferBase.h>
#include <UvmDetach.h>
#include <VtConsumer.h>
#include "DrmSync.h"
#include "MesonTypes.h"
#ifdef VSC_ENABLE
#include <linux/v4l2-ext-vsc.h>
#endif
#define VT_VIDEO_STATUS_IMMEDIATELY_OUTPUT 9
class VtDisplayObserver;
#ifdef VSC_ENABLE
typedef enum {
ORBIT_MODE_NULL,
ORBIT_MODE_JUSTCAN,
ORBIT_MODE_OVERSCAN,
} orbit_mode;
#define RECT_WIDTH(x) ((x).right - (x).left)
#define RECT_HEIGHT(x) ((x).bottom - (x).top)
#endif
struct BufferItem {
BufferItem(int bufferFd, int64_t timeStamp)
: mBufferFd(bufferFd),
mTimeStamp(timeStamp) {
mReleaseFence = DrmFence::NO_FENCE;
}
~BufferItem() {
mReleaseFence.reset();
}
void setReleaseFence(std::shared_ptr<DrmFence> & fence) {
if (!fence || fence == DrmFence::NO_FENCE ||
fence->getStatus() == DrmFence::Status::Invalid ||
fence->getStatus() == DrmFence::Status::Signaled) {
return;
}
if (mReleaseFence != DrmFence::NO_FENCE &&
mReleaseFence->getStatus() == DrmFence::Status::Unsignaled) {
mReleaseFence = DrmFence::merge("BufferFd", mReleaseFence, fence);
} else {
mReleaseFence = fence;
}
}
int32_t getReleaseFenceFd() {
if (mReleaseFence.get() && mReleaseFence != DrmFence::NO_FENCE)
return mReleaseFence->dup();
else
return -1;
}
int mBufferFd;
const int64_t mTimeStamp;
std::shared_ptr<DrmFence> mReleaseFence;
};
class MesonLayer : public DrmFramebufferBase {
public:
MesonLayer();
MesonLayer(uint32_t dispId);
~MesonLayer();
int32_t setTunnelId(int tunnelId, std::shared_ptr<VtDisplayObserver> observer);
int32_t setIndex(int index);
int32_t getIndex();
int32_t setCurReleaseFence(int32_t fenceFd);
int32_t getCurReleaseFence();
int32_t onLayerDisplayed(int32_t releaseFence, int32_t processFence);
void setPresentTime(nsecs_t expectedPresentTime);
bool isVtBuffer();
bool isFbUpdated();
bool interruptProcess(bool change = true);
void updateBuffer();
int32_t releaseBuffer();
void setBufferInfo(int fd, int32_t acquireFence);
int32_t getBufferInfo(
uint32_t & width, uint32_t & height, uint32_t & stride, uint32_t & format);
void setBufferInfo(
uint32_t width, uint32_t height, uint32_t stride, uint32_t format);
int32_t getAcquireFenceFd();
int32_t setAcquireFence(int32_t fenceFd);
void setDiProcessorFd(int32_t fd);
int32_t setProcessFence(int32_t fenceFd);
int32_t getProcessFence();
int32_t getBufferFd();
int32_t getBufferFd(source_type_t & sourceType) override;
int32_t releaseResource();
int32_t setDisplayFrame(drm_rect_t dispFrame);
int32_t setSourceCrop(drm_rect_t crop);
drm_rect_t getSourceCrop();
void setVisible(bool visible) { mVisible = visible; }
bool getVisible() { return mVisible; }
uint32_t getVideoPriority() { return mVideoPriority; }
void setVideoPriority(uint32_t priority) { mVideoPriority = priority; }
int32_t setTransform(int32_t transform);
int32_t setZorder(uint32_t z);
int32_t getCurZorder();
void updateZorder();
void registerCallback(void *context, meson_callback_t *cb);
void registerPageFlipCallBack(void *context, adpt_page_flip_callback *cb);
void setPageFlipData(uint64_t id, void *context, adpt_page_flip_callback *cb, int fd);
bool keepFrame();
std::map<uint64_t, meson_page_flip_data> getPageFlipData();
void setFlipDataToUserData(void *userData);
void clearFlipData() { mFlipData.clear(); }
void froceRefresh(bool enable) { mDataUpdate = enable; }
/* videotunnel api */
int32_t registerConsumer();
int32_t onVtFrameAvailable(std::vector<std::shared_ptr<VtBufferItem>> & items) override;
int32_t releaseVtResource();
int32_t onVtFrameDisplayed(std::shared_ptr<VtBufferItem> & item);
void onVtVideoStatus(vt_video_status_t status) override;
void onVtVideoGameMode(int data) override;
bool interruptVtProcess(bool change = true);
void updateVtBuffer();
int32_t releaseVtBuffer();
void setBufferInfo(uint32_t width, uint32_t height, uint32_t stride, uint32_t alignHeight, uint32_t format);
void setVtDisplayFrame(drm_rect_t & frame) override;
bool newGameBuffer();
void vtRefresh();
int32_t unregisterConsumer();
int32_t getBufferInfo(uint32_t & width, uint32_t & height, uint32_t & stride, uint32_t & alignHeight, uint32_t & format);
#ifdef VSC_ENABLE
public:
/* new add function */
drm_rect_t getSourceResolution() { return mSourceRes; }
drm_rect_t getSourcePunch() { return mPunch; }
void setOriginalResolution(drm_rect_t res, drm_rect_t punch) {
mSourceRes = res;
mPunch = punch;
}
int getTunnelId() { return mTunnelId; }
connect_info_t getConnectInfo() { return mConnectInfo; }
void setConnectInfo(connect_info_t info) { mConnectInfo = info; }
win_prop_t getWinProp() { return mWinProp; }
void setWinProp(win_prop_t prop) { mWinProp = prop; }
int getFreeze() { return mFreeze; }
void setFreeze(int freeze) { mFreeze = freeze; }
int getFreezeBuffer() { return mFreezeBuffer; }
void setFreezeBuffer(int freeze) { mFreezeBuffer = freeze; }
meson_error_t setOrbitWindow(drm_rect_t osdIn, drm_rect_t videoIn,
drm_rect_t osdOut, drm_rect_t videoOut, int w, int h);
meson_error_t setOrbitMove(drm_rect_t osdIn, drm_rect_t videoIn,
drm_rect_t osdOut, drm_rect_t videoOut, int w, int h);
void setOrbitPolicy(struct v4l2_ext_vsc_orbit_policy policy) { mOrbitPolicy = policy; }
struct v4l2_ext_vsc_orbit_policy getOrbitPolicy() { return mOrbitPolicy; }
void setSeamlessInfo(struct v4l2_ext_vsc_seamless_info policy) { mSeamless = policy; }
struct v4l2_ext_vsc_seamless_info getSeamlessInfo() { return mSeamless; }
#endif
protected:
bool shouldPresentNow(const std::shared_ptr<BufferItem> item);
bool shouldPresentNow(const std::shared_ptr<VtBufferItem> item);
void dropExpiredFrame(bool drop);
void init();
/* for NR */
int32_t uvmDetachEnable(bool enable);
int32_t attachUvmBuffer(const int bufferFd);
int32_t attachUvmBuffer(const std::shared_ptr<VtBufferItem> item);
int32_t detachUvmBuffer();
int32_t collectUvmBuffer(const int bufferFd, const int fence);
int32_t collectUvmBuffer(const std::shared_ptr<VtBufferItem> item);
int32_t releaseUvmResourceLock();
int32_t releaseResourceLocked();
void onVideoCmd();
/* videotunnel api */
void askVtRefresh(bool flag);
int32_t releaseVtResourceLocked(bool disconnect = true);
void setVtSourceCrop(int32_t l, int32_t t, int32_t r, int32_t b);
int32_t getBufferFdLocked();
int32_t getBufferFdLocked(source_type_t & sourceType);
protected:
uint32_t mDisplayId;
int mTunnelId;
int mIndex = -1;
int mCurrZorder = -1;
uint32_t mVideoPriority = 0;
int mTunnelFd;
int mDifd;
uint32_t mBufferWidth = 0;
uint32_t mBufferHeight = 0;
uint32_t mBufferStride = 0;
uint32_t mBufferFormat = 0;
uint32_t mBufferAlignHeight = 0;
nsecs_t mExpectedPresentTime;
std::deque<std::shared_ptr<VtBufferItem>> mQueueItems;
std::deque<drm_rect_t> mCropItems;
std::shared_ptr<DrmFence> mPrevReleaseFence;
std::shared_ptr<DrmFence> mCurReleaseFence;
std::shared_ptr<DrmFence> mAcquireFence;
std::shared_ptr<DrmFence> mProcessFence;
std::shared_ptr<VtBufferItem> mCurBufferItem;
std::shared_ptr<VtBufferItem> mPrevBufferItem;
std::mutex mMutex;
bool mVisible = true;
/* videotunnel */
std::shared_ptr<VtContentListener> mContentListener;
std::shared_ptr<VtConsumer> mVtConsumer;
std::shared_ptr<VtDisplayObserver> mDisplayObserver;
std::map<uint64_t, meson_page_flip_data> mFlipData;
std::mutex mFlipDataMutex;
int64_t mTimeStamp = 0;
int64_t mVsyncInterval = 0;
bool mDropEnable = false;
meson_callback_t *mCb = NULL;
void *mContext = NULL;
bool mDataUpdate;
bool mVtUpdate;
bool mGameMode;
bool mVtRefreshed;
bool mNeedAskRefresh;
drm_rect_t mVtSourceCrop;
drm_rect_t mVtDisplayFrame;
int32_t mQueuedFrames;
vt_video_status_t mVideoDisplayStatus;
vt_video_status_t mVideoStatus;
std::shared_ptr<UvmDetach> mUvmDetach;
int mPreUvmBufferFd;
bool mNeedReleaseVtResource;
bool mTunnelIdUpdate; /* use to keep last frame when tunnel ID changed */
#ifdef VSC_ENABLE
/* fuse parameter */
drm_rect_t mSourceRes;
drm_rect_t mPunch;
connect_info_t mConnectInfo;
win_prop_t mWinProp;
int mFreeze;
int mFreezeBuffer;
drm_rect_t mOrbitOsdIn;
drm_rect_t mOrbitVideoIn;
drm_rect_t mOrbitOsdOut;
drm_rect_t mOrbitVideoOut;
orbit_mode mOrbitMode;
struct v4l2_ext_vsc_orbit_policy mOrbitPolicy;
struct v4l2_ext_vsc_seamless_info mSeamless;
#endif
};
#endif