247 lines
7.5 KiB
C++
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
|