Files

247 lines
7.5 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"
#define VT_VIDEO_STATUS_IMMEDIATELY_OUTPUT 9
class VtDisplayObserver;
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);
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 */
};
#endif