/* * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * 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 FRAMEWORKS_SURFACE_INCLUDE_BUFFER_QUEUE_H #define FRAMEWORKS_SURFACE_INCLUDE_BUFFER_QUEUE_H #include #include #include #include #include #include #include "iconsumer_surface.h" #include "surface_type.h" #include #include "surface_buffer.h" #include "consumer_surface_delegator.h" namespace OHOS { enum BufferState { BUFFER_STATE_RELEASED, BUFFER_STATE_REQUESTED, BUFFER_STATE_FLUSHED, BUFFER_STATE_ACQUIRED, BUFFER_STATE_ATTACHED, }; enum InvokerType { PRODUCER_INVOKER, CONSUMER_INVOKER, }; using BufferElement = struct BufferElement { sptr buffer; BufferState state; bool isDeleting; BufferRequestConfig config; sptr fence; int64_t timestamp; std::vector damages; HDRMetaDataType hdrMetaDataType = HDRMetaDataType::HDR_NOT_USED; std::vector metaData; GraphicHDRMetadataKey key; std::vector metaDataSet; GraphicPresentTimestamp presentTimestamp = {GRAPHIC_DISPLAY_PTS_UNSUPPORTED, 0}; /** * The desired time to present the buffer in nanoseconds. * The buffer should wait until desiredPresentTimestamp is reached before being consumed and displayed. * If multiple buffers reach desiredPresentTimestamp, the earlier buffer should be dropped. */ int64_t desiredPresentTimestamp; /** * The desiredPresentTimestamp is automatically generated by the system, isAutoTimestamp is true. * The desiredPresentTimestamp is manually set by the producer, isAutoTimestamp is false. */ bool isAutoTimestamp; bool isPreAllocBuffer = false; /** * lastAcquireTime is the time when this buffer was acquired last time through AcquireBuffer interface. */ int64_t lastAcquireTime; bool isBufferNeedRealloc = false; /** * dfx for listener ReleaseBufferWithSequenceAndFence. * record the clientpid when the buffer requested from ReleaseBufferWithSequenceAndFence. */ int32_t requestedFromListenerClientPid = 0; }; struct BufferSlot { uint32_t seqId; int64_t timestamp; /** * Lpp Buffer cropping area, processing rpr video * [left, top, width, height] */ int32_t crop[4]; uint32_t isRsUsing = 0; }; struct LppSlotInfo { int32_t readOffset = -1; int32_t writeOffset = -1; /** * The order of using lpp buffer, Similar to dirtyList variable. */ BufferSlot slot[8]; int32_t frameRate = 0; uint32_t isStopShbDraw = 0; }; using BufferAndFence = std::pair, sptr>; class SURFACE_HIDDEN BufferQueue : public RefBase { public: BufferQueue(const std::string &name); virtual ~BufferQueue(); GSError GetProducerInitInfo(ProducerInitInfo &info); GSError RequestBuffer(const BufferRequestConfig &config, sptr &bedata, struct IBufferProducer::RequestBufferReturnValue &retval); GSError ReuseBuffer(const BufferRequestConfig &config, sptr &bedata, struct IBufferProducer::RequestBufferReturnValue &retval, std::unique_lock &lock, bool listenerSeqAndFence = false); GSError CancelBuffer(uint32_t sequence, sptr bedata); GSError FlushBuffer(uint32_t sequence, sptr bedata, sptr fence, const BufferFlushConfigWithDamages &config); GSError DoFlushBuffer(uint32_t sequence, sptr bedata, sptr fence, const BufferFlushConfigWithDamages &config); GSError GetLastFlushedBuffer(sptr& buffer, sptr& fence, float matrix[16], uint32_t matrixSize, bool isUseNewMatrix, bool needRecordSequence = false); GSError AcquireBuffer(sptr& buffer, sptr& fence, int64_t ×tamp, std::vector &damages); GSError AcquireBuffer(IConsumerSurface::AcquireBufferReturnValue &returnValue, int64_t expectPresentTimestamp, bool isUsingAutoTimestamp); GSError ReleaseBuffer(sptr& buffer, const sptr& fence); GSError AttachBuffer(sptr& buffer, int32_t timeOut); GSError DetachBuffer(sptr& buffer); GSError RegisterSurfaceDelegator(sptr client, sptr cSurface); GSError UnregisterSurfaceDelegator(); bool QueryIfBufferAvailable(); uint32_t GetQueueSize(); GSError SetQueueSize(uint32_t queueSize); GSError GetName(std::string &name); GSError RegisterConsumerListener(sptr& listener); GSError RegisterConsumerListener(IBufferConsumerListenerClazz *listener); GSError RegisterReleaseListener(OnReleaseFunc func); GSError RegisterProducerReleaseListener(sptr listener, bool isOnReleaseBufferWithSequenceAndFence); GSError RegisterProducerReleaseListenerBackup(sptr listener); GSError UnRegisterProducerReleaseListener(); GSError UnRegisterProducerReleaseListenerBackup(); GSError RegisterDeleteBufferListener(OnDeleteBufferFunc func, bool isForUniRedraw = false); GSError UnregisterConsumerListener(); GSError RegisterProducerPropertyListener(sptr listener, uint64_t producerId); GSError UnRegisterProducerPropertyListener(uint64_t producerId); GSError NotifyLayerStateChanged(LayerStateChange state); GSError SetDefaultWidthAndHeight(int32_t width, int32_t height); int32_t GetDefaultWidth(); int32_t GetDefaultHeight(); GSError SetDefaultUsage(uint64_t usage); uint64_t GetDefaultUsage(); GSError CleanCache(bool cleanAll, uint32_t *bufSeqNum); GSError GoBackground(); GSError OnConsumerDied(); uint64_t GetUniqueId() const; void Dump(std::string &result); void DumpCurrentFrameLayer(); GSError SetTransform(GraphicTransformType transform); GraphicTransformType GetTransform() const; GSError SetBufferHold(bool hold); GSError SetBufferReallocFlag(bool flag); GSError SetBufferName(const std::string &bufferName); inline bool IsBufferHold() { std::unique_lock lock(mutex_); return isBufferHold_; } GSError SetScalingMode(uint32_t sequence, ScalingMode scalingMode); GSError GetScalingMode(uint32_t sequence, ScalingMode &scalingMode); GSError SetMetaData(uint32_t sequence, const std::vector &metaData); GSError SetMetaDataSet(uint32_t sequence, GraphicHDRMetadataKey key, const std::vector &metaData); GSError QueryMetaDataType(uint32_t sequence, HDRMetaDataType &type); GSError GetMetaData(uint32_t sequence, std::vector &metaData); GSError GetMetaDataSet(uint32_t sequence, GraphicHDRMetadataKey &key, std::vector &metaData); GSError SetTunnelHandle(const sptr &handle); sptr GetTunnelHandle(); GSError SetTunnelLayerInfo(const TunnelLayerInfo& info); GSError GetTunnelLayerInfo(TunnelLayerState& info); GSError SetPresentTimestamp(uint32_t sequence, const GraphicPresentTimestamp ×tamp); GSError GetPresentTimestamp(uint32_t sequence, GraphicPresentTimestampType type, int64_t &time); bool GetStatus() const; void SetStatus(bool status); void SetBatchHandle(bool batch); GSError SetProducerCacheCleanFlag(bool flag); inline void ConsumerRequestCpuAccess(bool on) { isCpuAccessable_ = on; } GSError AttachBufferToQueue(sptr buffer, InvokerType invokerType); GSError DetachBufferFromQueue(sptr buffer, InvokerType invokerType, bool isReserveSlot); GSError SetTransformHint(GraphicTransformType transformHint, uint64_t fromId); GSError SetTransformHint(GraphicTransformType transformHint); GraphicTransformType GetTransformHint() const; GSError SetScalingMode(ScalingMode scalingMode); GSError SetSurfaceSourceType(OHSurfaceSource sourceType); OHSurfaceSource GetSurfaceSourceType() const; GSError SetSurfaceAppFrameworkType(std::string appFrameworkType); std::string GetSurfaceAppFrameworkType() const; GSError SetHdrWhitePointBrightness(float brightness); GSError SetSdrWhitePointBrightness(float brightness); float GetHdrWhitePointBrightness() const; float GetSdrWhitePointBrightness() const; GSError IsSurfaceBufferInCache(uint32_t seqNum, bool &isInCache); GSError AcquireLastFlushedBuffer(sptr &buffer, sptr &fence, float matrix[16], uint32_t matrixSize, bool isUseNewMatrix); GSError ReleaseLastFlushedBuffer(uint32_t sequence); GSError SetGlobalAlpha(int32_t alpha); GSError GetGlobalAlpha(int32_t &alpha); GSError SetRequestBufferNoblockMode(bool noblock); GSError GetRequestBufferNoblockMode(bool &noblock); uint32_t GetAvailableBufferCount(); void SetConnectedPidLocked(int32_t connectedPid); void SetListenerSeqAndFenceCallingPid(int32_t listenerSeqAndFenceCallingPid); GSError RequestAndDetachBuffer(const BufferRequestConfig& config, sptr& bedata, struct IBufferProducer::RequestBufferReturnValue& retval); GSError AttachAndFlushBuffer(sptr& buffer, sptr& bedata, const sptr& fence, BufferFlushConfigWithDamages& config, bool needMap); GSError GetBufferCacheConfig(const sptr& buffer, BufferRequestConfig& config); GSError GetLastFlushedDesiredPresentTimeStamp(int64_t &lastFlushedDesiredPresentTimeStamp); GSError GetFrontDesiredPresentTimeStamp(int64_t &desiredPresentTimeStamp, bool &isAutoTimeStamp); GSError GetBufferSupportFastCompose(bool &bufferSupportFastCompose); GSError GetCycleBuffersNumber(uint32_t& cycleBuffersNumber); GSError SetCycleBuffersNumber(uint32_t cycleBuffersNumber); GSError GetFrameGravity(int32_t &frameGravity); GSError SetFrameGravity(int32_t frameGravity); GSError GetFixedRotation(int32_t &fixedRotation); GSError SetFixedRotation(int32_t fixedRotation); GSError ConnectStrictly(); GSError DisconnectStrictly(); GSError PreAllocBuffers(const BufferRequestConfig &config, uint32_t allocBufferCount); GSError GetLastConsumeTime(int64_t &lastConsumeTime); GSError SetMaxQueueSize(uint32_t queueSize); GSError GetMaxQueueSize(uint32_t &queueSize) const; GSError SetLppShareFd(int fd, bool state); GSError SetLppDrawSource(bool isShbSource, bool isRsSource); GSError AcquireLppBuffer( sptr &buffer, sptr &fence, int64_t ×tamp, std::vector &damages); GSError SetAlphaType(GraphicAlphaType alphaType); GSError GetAlphaType(GraphicAlphaType &alphaType); GSError SetIsPriorityAlloc(bool isPriorityAlloc); bool IsCached(uint32_t bufferSeqNum) const; GSError SyncProducerCache(std::map>& buffers); /** * @brief Set the Drop Frame Level for the buffer queue. * When dirty list size exceeds this level, oldest buffers will be dropped during acquire. * @param level The drop frame level (0 means no drop, >0 means keep latest N frames) * @return {@link GSERROR_OK} 0 - Success. * {@link GSERROR_INVALID_ARGUMENTS} 40001000 - Invalid argument. */ GSError SetDropFrameLevel(int32_t level); GSError SetSingleBufferMode(SingleBufferMode mode); SingleBufferMode GetAndResetSingleBufferMode(); GSError CleanReleasedBuffers(std::vector &cleanedSeqNums); void CleanProducerBySeqNum(const std::vector& seqNums); GSError SetVideoDimensionType(VideoDimType videoDimType); GSError GetVideoDimensionType(VideoDimType &videoDimType); GSError GetVideoDimensionType(uint32_t sequence, VideoDimType &videoDimType); private: GSError AllocBuffer(sptr& buffer, const sptr& previousBuffer, const BufferRequestConfig& config, std::unique_lock& lock); void DeleteBufferInCache(uint32_t sequence, std::unique_lock &lock); uint32_t GetUsedSize(); void DeleteBuffersLocked(int32_t count, std::unique_lock &lock); GSError PopFromFreeListLocked(sptr& buffer, const BufferRequestConfig &config); GSError PopFromDirtyListLocked(sptr& buffer); GSError CheckRequestConfig(const BufferRequestConfig &config); GSError CheckFlushConfig(const BufferFlushConfigWithDamages &config); void DumpCache(std::string &result); void DumpMetadata(std::string &result, BufferElement element); void ClearLocked(std::unique_lock &lock, sptr listener = nullptr); bool CheckProducerCacheListLocked(); GSError SetProducerCacheCleanFlagLocked(bool flag, std::unique_lock &lock); GSError AttachBufferUpdateStatus(std::unique_lock &lock, uint32_t sequence, int32_t timeOut, std::map::iterator &mapIter); void AttachBufferUpdateBufferInfo(sptr& buffer, bool needMap); void ListenerBufferReleasedCb(sptr &buffer, const sptr &fence, bool isOnReleaseBufferWithSequenceAndFence, std::vector>> &requestBuffersAndFences); void OnReleaseBufferWithSequenceAndFence(sptr &listener, std::vector>> &requestBuffersAndFences); void OnBufferDeleteCbForHardwareThreadLocked(const sptr &buffer) const; GSError CheckBufferQueueCache(uint32_t sequence); GSError ReallocBufferLocked(const BufferRequestConfig &config, struct IBufferProducer::RequestBufferReturnValue &retval, std::unique_lock &lock); void SetSurfaceBufferHebcMetaLocked(sptr buffer); GSError RequestBufferCheckStatus(); GSError DelegatorQueueBuffer(uint32_t sequence, sptr fence); bool WaitForCondition(); void RequestBufferDebugInfoLocked(); bool GetStatusLocked() const; void CallConsumerListener(); void SetSurfaceBufferGlobalAlphaUnlocked(sptr buffer); void LogAndTraceAllBufferInBufferQueueCacheLocked(); bool IsPresentTimestampReady(int64_t desiredPresentTimestamp, int64_t expectPresentTimestamp); void SetDesiredPresentTimestampAndUiTimestamp(uint32_t sequence, int64_t desiredPresentTimestamp, uint64_t uiTimestamp); void DropFirstDirtyBuffer(BufferElement &frontBufferElement, BufferElement &secondBufferElement, int64_t &frontDesiredPresentTimestamp, bool &frontIsAutoTimestamp, std::vector &dropBuffers); void ReleaseDropBuffers(std::vector &dropBuffers); void DropBuffersByLevel(std::vector &dropBuffers); void OnBufferDeleteForRS(uint32_t sequence); void DeleteBufferInCacheNoWaitForAllocatingState(uint32_t sequence); void AddDeletingBuffersLocked(std::vector &deletingBuffers); GSError DetachBufferFromQueueLocked(uint32_t sequence, InvokerType invokerType, std::unique_lock &lock, bool isReserveSlot); GSError AttachBufferToQueueLocked(sptr buffer, InvokerType invokerType, bool needMap); GSError FlushBufferImprovedLocked(uint32_t sequence, sptr &bedata, const sptr &fence, const BufferFlushConfigWithDamages &config, std::unique_lock &lock); GSError CheckBufferQueueCacheLocked(uint32_t sequence); GSError DoFlushBufferLocked(uint32_t sequence, sptr bedata, sptr fence, const BufferFlushConfigWithDamages &config, std::unique_lock &lock); GSError RequestBufferLocked(const BufferRequestConfig &config, sptr &bedata, struct IBufferProducer::RequestBufferReturnValue &retval, std::unique_lock &lock, bool listenerSeqAndFence = false); void RequestBuffersForListenerLocked(std::vector>> &requestBuffersAndFences, std::unique_lock &lock); GSError SetupNewBufferLocked(sptr &buffer, sptr &bedata, BufferRequestConfig &updateConfig, const BufferRequestConfig &config, struct IBufferProducer::RequestBufferReturnValue &retval, std::unique_lock &lock); GSError CancelBufferLocked(uint32_t sequence, sptr bedata); void DumpPropertyListener(); void AllocBuffers(const BufferRequestConfig &config, uint32_t allocBufferCount, std::map> &surfaceBufferCache); void DeleteFreeListCacheLocked(uint32_t sequence); void MarkBufferReclaimableByIdLocked(uint32_t sequence); GSError SetQueueSizeLocked(uint32_t queueSize, std::unique_lock &lock); void FlushLppBuffer(); GSError ReuseBufferForNoBlockMode(sptr &buffer, sptr &bedata, BufferRequestConfig &updateConfig, const BufferRequestConfig &config, struct IBufferProducer::RequestBufferReturnValue &retval, std::unique_lock &lock); GSError ReuseBufferForBlockMode(sptr &buffer, sptr &bedata, BufferRequestConfig &updateConfig, const BufferRequestConfig &config, struct IBufferProducer::RequestBufferReturnValue &retval, std::unique_lock &lock); GSError UpdateReuseBufferState(bool needRealloc, sptr &bedata, struct IBufferProducer::RequestBufferReturnValue &retval, std::unique_lock &lock, bool listenerSeqAndFence); void SetLppBufferConfig(sptr &buffer, std::vector &damages, const BufferSlot &slot); bool CheckLppFenceLocked(); GSError ReleaseBufferLocked(sptr &buffer, const sptr& fence, std::unique_lock &lock); void CleanReleasedBuffersLocked(std::unique_lock &lock, std::vector &cleanedSeqNums); void OnCleanCacheForBufferInfoMapLocked(sptr listener); sptr GetDelegator(); int32_t defaultWidth_ = 0; int32_t defaultHeight_ = 0; uint64_t defaultUsage_ = 0; uint32_t bufferQueueSize_ = SURFACE_DEFAULT_QUEUE_SIZE; ScalingMode scalingMode_ = ScalingMode::SCALING_MODE_SCALE_TO_WINDOW; VideoDimType videoDimType_ = VideoDimType::VIDEO_DIM_TYPE_2D; GraphicTransformType transform_ = GraphicTransformType::GRAPHIC_ROTATE_NONE; GraphicTransformType lastFlushedTransform_ = GraphicTransformType::GRAPHIC_ROTATE_NONE; std::string name_; std::list freeList_; std::list dirtyList_; std::list deletingList_; std::list producerCacheList_; std::map bufferQueueCache_; sptr listener_ = nullptr; IBufferConsumerListenerClazz *listenerClazz_ = nullptr; mutable std::mutex mutex_; std::mutex listenerMutex_; std::mutex producerListenerMutex_; std::mutex propertyChangeMutex_; const uint64_t uniqueId_; std::string bufferName_ = ""; OnReleaseFunc onBufferRelease_ = nullptr; std::mutex onBufferReleaseMutex_; sptr producerListener_ = nullptr; sptr producerListenerBackup_ = nullptr; const size_t propertyChangeListenerMaxNum_ = 50; // 50 : limit producer num std::map> propertyChangeListeners_; OnDeleteBufferFunc onBufferDeleteForRSMainThread_; OnDeleteBufferFunc onBufferDeleteForRSHardwareThread_; std::condition_variable waitReqCon_; std::condition_variable waitAttachCon_; sptr tunnelHandle_ = nullptr; TunnelLayerState tunnelLayerState_; bool isValidStatus_ = true; bool producerCacheClean_ = false; const bool isLocalRender_; uint32_t lastFlusedSequence_ = 0; sptr lastFlusedFence_; sptr preBufferReleasedFence_; sptr sptrCSurfaceDelegator_; std::mutex delegatorMutex_; bool isCpuAccessable_ = false; GraphicTransformType transformHint_ = GraphicTransformType::GRAPHIC_ROTATE_NONE; bool isBufferHold_ = false; bool isBatch_ = false; OHSurfaceSource sourceType_ = OHSurfaceSource::OH_SURFACE_SOURCE_DEFAULT; std::string appFrameworkType_ = ""; float hdrWhitePointBrightness_ = 0.0; float sdrWhitePointBrightness_ = 0.0; uint32_t acquireLastFlushedBufSequence_; int32_t globalAlpha_ = -1; // The default is false, where true indicates non blocking mode and false indicates blocking mode. bool requestBufferNoBlockMode_ = false; std::mutex globalAlphaMutex_; std::string requestBufferStateStr_; std::string acquireBufferStateStr_; // << Lpp std::unordered_map lppFenceMap_; LppSlotInfo *lppSlotInfo_ = nullptr; int32_t lastLppWriteOffset_ = -1; int64_t lastLppWriteTimestamp_ = -1; bool isRsDrawLpp_ = false; int32_t lppSkipCount_ = 0; int32_t lastRsToShbWriteOffset_ = -1; // Lpp >> int32_t connectedPid_ = 0; int32_t listenerSeqAndFenceCallingPid_ = 0; bool isAllocatingBuffer_ = false; std::condition_variable isAllocatingBufferCon_; int64_t lastFlushedDesiredPresentTimeStamp_ = 0; bool bufferSupportFastCompose_ = false; uint32_t rotatingBufferNumber_ = 0; int32_t frameGravity_ = -1; int32_t fixedRotation_ = -1; uint32_t detachReserveSlotNum_ = 0; int64_t lastConsumeTime_ = 0; uint32_t maxQueueSize_ = 0; GraphicAlphaType alphaType_ = GraphicAlphaType::GRAPHIC_ALPHATYPE_PREMUL; bool isPriorityAlloc_ = false; bool isOnReleaseBufferWithSequenceAndFence_ = false; int32_t dropFrameLevel_ = 0; // Drop frame level: 0=no drop, >0=keep latest N frames SingleBufferMode singleBufferMode_ = SingleBufferMode::SINGLE_BUFFER_MODE_NONE; std::vector bufferInfoMap_; }; }; // namespace OHOS #endif // FRAMEWORKS_SURFACE_INCLUDE_BUFFER_QUEUE_H