• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef FRAMEWORKS_SURFACE_INCLUDE_BUFFER_QUEUE_H
17 #define FRAMEWORKS_SURFACE_INCLUDE_BUFFER_QUEUE_H
18 
19 #include <map>
20 #include <list>
21 #include <vector>
22 #include <mutex>
23 
24 #include <ibuffer_consumer_listener.h>
25 #include <ibuffer_producer.h>
26 #include "iconsumer_surface.h"
27 #include "surface_type.h"
28 #include <surface_tunnel_handle.h>
29 #include "surface_buffer.h"
30 #include "consumer_surface_delegator.h"
31 
32 namespace OHOS {
33 enum BufferState {
34     BUFFER_STATE_RELEASED,
35     BUFFER_STATE_REQUESTED,
36     BUFFER_STATE_FLUSHED,
37     BUFFER_STATE_ACQUIRED,
38     BUFFER_STATE_ATTACHED,
39 };
40 
41 enum InvokerType {
42     PRODUCER_INVOKER,
43     CONSUMER_INVOKER,
44 };
45 
46 using BufferElement = struct BufferElement {
47     sptr<SurfaceBuffer> buffer;
48     BufferState state;
49     bool isDeleting;
50 
51     BufferRequestConfig config;
52     sptr<SyncFence> fence;
53     int64_t timestamp;
54     std::vector<Rect> damages;
55     HDRMetaDataType hdrMetaDataType = HDRMetaDataType::HDR_NOT_USED;
56     std::vector<GraphicHDRMetaData> metaData;
57     GraphicHDRMetadataKey key;
58     std::vector<uint8_t> metaDataSet;
59     GraphicPresentTimestamp presentTimestamp = {GRAPHIC_DISPLAY_PTS_UNSUPPORTED, 0};
60     /**
61      * The desired time to present the buffer in nanoseconds.
62      * The buffer should wait until desiredPresentTimestamp is reached before being consumed and displayed.
63      * If multiple buffers reach desiredPresentTimestamp, the earlier buffer should be dropped.
64      */
65     int64_t desiredPresentTimestamp;
66     /**
67      * The desiredPresentTimestamp is automatically generated by the system, isAutoTimestamp is true.
68      * The desiredPresentTimestamp is manually set by the producer, isAutoTimestamp is false.
69      */
70     bool isAutoTimestamp;
71     bool isPreAllocBuffer = false;
72     /**
73      * lastAcquireTime is the time when this buffer was acquired last time through AcquireBuffer interface.
74      */
75     int64_t lastAcquireTime;
76     int64_t requestTimeNs;
77     int64_t flushTimeNs;
78     bool isBufferNeedRealloc = false;
79 };
80 
81 struct BufferSlot {
82     uint32_t seqId;
83     int64_t timestamp;
84     int32_t damage[4];
85 };
86 
87 struct LppSlotInfo {
88     int32_t readOffset = -1;
89     int32_t writeOffset = -1;
90     BufferSlot slot[8];
91     int32_t frameRate = 0;
92     bool isStopShbDraw = false;
93 };
94 
95 using BufferAndFence = std::pair<sptr<SurfaceBuffer>, sptr<SyncFence>>;
96 
97 class SURFACE_HIDDEN BufferQueue : public RefBase {
98 public:
99     BufferQueue(const std::string &name);
100     virtual ~BufferQueue();
101 
102     GSError GetProducerInitInfo(ProducerInitInfo &info);
103 
104     GSError RequestBuffer(const BufferRequestConfig &config, sptr<BufferExtraData> &bedata,
105                           struct IBufferProducer::RequestBufferReturnValue &retval);
106 
107     GSError ReuseBuffer(const BufferRequestConfig &config, sptr<BufferExtraData> &bedata,
108                         struct IBufferProducer::RequestBufferReturnValue &retval, std::unique_lock<std::mutex> &lock);
109 
110     GSError CancelBuffer(uint32_t sequence, sptr<BufferExtraData> bedata);
111 
112     GSError FlushBuffer(uint32_t sequence, sptr<BufferExtraData> bedata,
113                         sptr<SyncFence> fence, const BufferFlushConfigWithDamages &config);
114 
115     GSError DoFlushBuffer(uint32_t sequence, sptr<BufferExtraData> bedata,
116         sptr<SyncFence> fence, const BufferFlushConfigWithDamages &config);
117 
118     GSError GetLastFlushedBuffer(sptr<SurfaceBuffer>& buffer, sptr<SyncFence>& fence,
119         float matrix[16], uint32_t matrixSize, bool isUseNewMatrix, bool needRecordSequence = false);
120 
121     GSError AcquireBuffer(sptr<SurfaceBuffer>& buffer, sptr<SyncFence>& fence,
122                           int64_t &timestamp, std::vector<Rect> &damages);
123     GSError AcquireBuffer(IConsumerSurface::AcquireBufferReturnValue &returnValue, int64_t expectPresentTimestamp,
124                           bool isUsingAutoTimestamp);
125     GSError AcquireBuffer(IConsumerSurface::AcquireBufferReturnValue &returnValue);
126     GSError ReleaseBuffer(sptr<SurfaceBuffer>& buffer, const sptr<SyncFence>& fence);
127 
128     GSError AttachBuffer(sptr<SurfaceBuffer>& buffer, int32_t timeOut);
129 
130     GSError DetachBuffer(sptr<SurfaceBuffer>& buffer);
131 
132     GSError RegisterSurfaceDelegator(sptr<IRemoteObject> client, sptr<Surface> cSurface);
133 
134     bool QueryIfBufferAvailable();
135 
136     uint32_t GetQueueSize();
137     GSError SetQueueSize(uint32_t queueSize);
138 
139     GSError GetName(std::string &name);
140 
141     GSError RegisterConsumerListener(sptr<IBufferConsumerListener>& listener);
142     GSError RegisterConsumerListener(IBufferConsumerListenerClazz *listener);
143     GSError RegisterReleaseListener(OnReleaseFunc func);
144     GSError RegisterProducerReleaseListener(sptr<IProducerListener> listener);
145     GSError RegisterProducerReleaseListenerBackup(sptr<IProducerListener> listener);
146     GSError UnRegisterProducerReleaseListener();
147     GSError UnRegisterProducerReleaseListenerBackup();
148     GSError RegisterDeleteBufferListener(OnDeleteBufferFunc func, bool isForUniRedraw = false);
149     GSError UnregisterConsumerListener();
150     GSError RegisterProducerPropertyListener(sptr<IProducerListener> listener, uint64_t producerId);
151     GSError UnRegisterProducerPropertyListener(uint64_t producerId);
152 
153     GSError SetDefaultWidthAndHeight(int32_t width, int32_t height);
154     int32_t GetDefaultWidth();
155     int32_t GetDefaultHeight();
156     GSError SetDefaultUsage(uint64_t usage);
157     uint64_t GetDefaultUsage();
158 
159     GSError CleanCache(bool cleanAll, uint32_t *bufSeqNum);
160     GSError GoBackground();
161     GSError OnConsumerDied();
162 
163     uint64_t GetUniqueId() const;
164 
165     void Dump(std::string &result);
166     void DumpCurrentFrameLayer();
167 
168     GSError SetTransform(GraphicTransformType transform);
169     GraphicTransformType GetTransform() const;
170 
171     GSError SetBufferHold(bool hold);
172     GSError SetBufferReallocFlag(bool flag);
173     GSError SetBufferName(const std::string &bufferName);
IsBufferHold()174     inline bool IsBufferHold()
175     {
176         return isBufferHold_;
177     }
178     GSError SetScalingMode(uint32_t sequence, ScalingMode scalingMode);
179     GSError GetScalingMode(uint32_t sequence, ScalingMode &scalingMode);
180     GSError SetMetaData(uint32_t sequence, const std::vector<GraphicHDRMetaData> &metaData);
181     GSError SetMetaDataSet(uint32_t sequence, GraphicHDRMetadataKey key,
182                            const std::vector<uint8_t> &metaData);
183     GSError QueryMetaDataType(uint32_t sequence, HDRMetaDataType &type);
184     GSError GetMetaData(uint32_t sequence, std::vector<GraphicHDRMetaData> &metaData);
185     GSError GetMetaDataSet(uint32_t sequence, GraphicHDRMetadataKey &key,
186                            std::vector<uint8_t> &metaData);
187     GSError SetTunnelHandle(const sptr<SurfaceTunnelHandle> &handle);
188     sptr<SurfaceTunnelHandle> GetTunnelHandle();
189     GSError SetPresentTimestamp(uint32_t sequence, const GraphicPresentTimestamp &timestamp);
190     GSError GetPresentTimestamp(uint32_t sequence, GraphicPresentTimestampType type, int64_t &time);
191 
192     bool GetStatus() const;
193     void SetStatus(bool status);
194 
195     void SetBatchHandle(bool batch);
196 
197     GSError SetProducerCacheCleanFlag(bool flag);
ConsumerRequestCpuAccess(bool on)198     inline void ConsumerRequestCpuAccess(bool on)
199     {
200         isCpuAccessable_ = on;
201     }
202 
203     GSError AttachBufferToQueue(sptr<SurfaceBuffer> buffer, InvokerType invokerType);
204     GSError DetachBufferFromQueue(sptr<SurfaceBuffer> buffer, InvokerType invokerType, bool isReserveSlot);
205 
206     GSError SetTransformHint(GraphicTransformType transformHint, uint64_t fromId);
207     GSError SetTransformHint(GraphicTransformType transformHint);
208     GraphicTransformType GetTransformHint() const;
209     GSError SetScalingMode(ScalingMode scalingMode);
210 
211     GSError SetSurfaceSourceType(OHSurfaceSource sourceType);
212     OHSurfaceSource GetSurfaceSourceType() const;
213 
214     GSError SetSurfaceAppFrameworkType(std::string appFrameworkType);
215     std::string GetSurfaceAppFrameworkType() const;
216 
217     GSError SetHdrWhitePointBrightness(float brightness);
218     GSError SetSdrWhitePointBrightness(float brightness);
219     float GetHdrWhitePointBrightness() const;
220     float GetSdrWhitePointBrightness() const;
221 
222     GSError IsSurfaceBufferInCache(uint32_t seqNum, bool &isInCache);
223 
224     GSError AcquireLastFlushedBuffer(sptr<SurfaceBuffer> &buffer, sptr<SyncFence> &fence,
225         float matrix[16], uint32_t matrixSize, bool isUseNewMatrix);
226     GSError ReleaseLastFlushedBuffer(uint32_t sequence);
227     GSError SetGlobalAlpha(int32_t alpha);
228     GSError GetGlobalAlpha(int32_t &alpha);
229     GSError SetRequestBufferNoblockMode(bool noblock);
230     GSError GetRequestBufferNoblockMode(bool &noblock);
231     uint32_t GetAvailableBufferCount();
232 
233     void SetConnectedPidLocked(int32_t connectedPid);
234     GSError RequestAndDetachBuffer(const BufferRequestConfig& config, sptr<BufferExtraData>& bedata,
235         struct IBufferProducer::RequestBufferReturnValue& retval);
236     GSError AttachAndFlushBuffer(sptr<SurfaceBuffer>& buffer, sptr<BufferExtraData>& bedata,
237         const sptr<SyncFence>& fence, BufferFlushConfigWithDamages& config, bool needMap);
238     GSError GetLastFlushedDesiredPresentTimeStamp(int64_t &lastFlushedDesiredPresentTimeStamp);
239     GSError GetFrontDesiredPresentTimeStamp(int64_t &desiredPresentTimeStamp, bool &isAutoTimeStamp);
240     GSError GetBufferSupportFastCompose(bool &bufferSupportFastCompose);
241     GSError GetBufferCacheConfig(const sptr<SurfaceBuffer>& buffer, BufferRequestConfig& config);
242     GSError GetCycleBuffersNumber(uint32_t& cycleBuffersNumber);
243     GSError SetCycleBuffersNumber(uint32_t cycleBuffersNumber);
244     GSError GetFrameGravity(int32_t &frameGravity);
245     GSError SetFrameGravity(int32_t frameGravity);
246     GSError GetFixedRotation(int32_t &fixedRotation);
247     GSError SetFixedRotation(int32_t fixedRotation);
248     GSError ConnectStrictly();
249     GSError DisconnectStrictly();
250     GSError PreAllocBuffers(const BufferRequestConfig &config, uint32_t allocBufferCount);
251     GSError GetLastConsumeTime(int64_t &lastConsumeTime);
252     GSError SetMaxQueueSize(uint32_t queueSize);
253     GSError GetMaxQueueSize(uint32_t &queueSize) const;
254     GSError ReleaseBuffer(uint32_t sequence, const sptr<SyncFence> &fence);
255     GSError ReleaseBufferLocked(BufferElement &ele, const sptr<SyncFence> &fence, std::unique_lock<std::mutex> &lock);
256     GSError SetIsActiveGame(bool isActiveGame);
257     GSError SetLppShareFd(int fd, bool state);
258     GSError SetLppDrawSource(bool isShbSource, bool isRsSource);
259     GSError AcquireLppBuffer(
260         sptr<SurfaceBuffer> &buffer, sptr<SyncFence> &fence, int64_t &timestamp, std::vector<Rect> &damages);
261     GSError SetAlphaType(GraphicAlphaType alphaType);
262     GSError GetAlphaType(GraphicAlphaType &alphaType);
263     GSError SetIsPriorityAlloc(bool isPriorityAlloc);
264 private:
265     GSError AllocBuffer(sptr<SurfaceBuffer>& buffer, const sptr<SurfaceBuffer>& previousBuffer,
266         const BufferRequestConfig& config, std::unique_lock<std::mutex>& lock);
267     void DeleteBufferInCache(uint32_t sequence, std::unique_lock<std::mutex> &lock);
268 
269     uint32_t GetUsedSize();
270     void DeleteBuffersLocked(int32_t count, std::unique_lock<std::mutex> &lock);
271 
272     GSError PopFromFreeListLocked(sptr<SurfaceBuffer>& buffer, const BufferRequestConfig &config);
273     GSError PopFromDirtyListLocked(sptr<SurfaceBuffer>& buffer);
274 
275     GSError CheckRequestConfig(const BufferRequestConfig &config);
276     GSError CheckFlushConfig(const BufferFlushConfigWithDamages &config);
277     void DumpCache(std::string &result);
278     void DumpMetadata(std::string &result, BufferElement element);
279     void ClearLocked(std::unique_lock<std::mutex> &lock);
280     bool CheckProducerCacheListLocked();
281     GSError SetProducerCacheCleanFlagLocked(bool flag, std::unique_lock<std::mutex> &lock);
282     GSError AttachBufferUpdateStatus(std::unique_lock<std::mutex> &lock, uint32_t sequence,
283         int32_t timeOut, std::map<uint32_t, BufferElement>::iterator &mapIter);
284     void AttachBufferUpdateBufferInfo(sptr<SurfaceBuffer>& buffer, bool needMap);
285     void ListenerBufferReleasedCb(sptr<SurfaceBuffer> &buffer, const sptr<SyncFence> &fence);
286     void OnBufferDeleteCbForHardwareThreadLocked(const sptr<SurfaceBuffer> &buffer) const;
287     GSError CheckBufferQueueCache(uint32_t sequence);
288     GSError ReallocBufferLocked(const BufferRequestConfig &config,
289         struct IBufferProducer::RequestBufferReturnValue &retval, std::unique_lock<std::mutex> &lock);
290     void SetSurfaceBufferHebcMetaLocked(sptr<SurfaceBuffer> buffer);
291     GSError RequestBufferCheckStatus();
292     GSError DelegatorQueueBuffer(uint32_t sequence, sptr<SyncFence> fence);
293     bool WaitForCondition();
294     void RequestBufferDebugInfoLocked();
295     bool GetStatusLocked() const;
296     void CallConsumerListener();
297     void SetSurfaceBufferGlobalAlphaUnlocked(sptr<SurfaceBuffer> buffer);
298     void LogAndTraceAllBufferInBufferQueueCacheLocked();
299     bool IsPresentTimestampReady(int64_t desiredPresentTimestamp, int64_t expectPresentTimestamp);
300     void SetDesiredPresentTimestampAndUiTimestamp(uint32_t sequence, int64_t desiredPresentTimestamp,
301                                                   uint64_t uiTimestamp);
302     void DropFirstDirtyBuffer(BufferElement &frontBufferElement, BufferElement &secondBufferElement,
303                               int64_t &frontDesiredPresentTimestamp, bool &frontIsAutoTimestamp,
304                               std::vector<BufferAndFence> &dropBuffers);
305     void ReleaseDropBuffers(std::vector<BufferAndFence> &dropBuffers);
306     void OnBufferDeleteForRS(uint32_t sequence);
307     void DeleteBufferInCacheNoWaitForAllocatingState(uint32_t sequence);
308     void AddDeletingBuffersLocked(std::vector<uint32_t> &deletingBuffers);
309     GSError DetachBufferFromQueueLocked(uint32_t sequence, InvokerType invokerType,
310         std::unique_lock<std::mutex> &lock, bool isReserveSlot);
311     GSError AttachBufferToQueueLocked(sptr<SurfaceBuffer> buffer, InvokerType invokerType, bool needMap);
312     GSError FlushBufferImprovedLocked(uint32_t sequence, sptr<BufferExtraData> &bedata,
313         const sptr<SyncFence> &fence, const BufferFlushConfigWithDamages &config, std::unique_lock<std::mutex> &lock);
314     GSError CheckBufferQueueCacheLocked(uint32_t sequence);
315     GSError DoFlushBufferLocked(uint32_t sequence, sptr<BufferExtraData> bedata,
316         sptr<SyncFence> fence, const BufferFlushConfigWithDamages &config, std::unique_lock<std::mutex> &lock);
317     GSError RequestBufferLocked(const BufferRequestConfig &config, sptr<BufferExtraData> &bedata,
318         struct IBufferProducer::RequestBufferReturnValue &retval, std::unique_lock<std::mutex> &lock);
319     GSError SetupNewBufferLocked(sptr<SurfaceBuffer> &buffer, sptr<BufferExtraData> &bedata,
320         BufferRequestConfig &updateConfig, const BufferRequestConfig &config,
321         struct IBufferProducer::RequestBufferReturnValue &retval, std::unique_lock<std::mutex> &lock);
322     GSError CancelBufferLocked(uint32_t sequence, sptr<BufferExtraData> bedata);
323     void DumpPropertyListener();
324     void AllocBuffers(const BufferRequestConfig &config, uint32_t allocBufferCount,
325         std::map<uint32_t, sptr<SurfaceBuffer>> &surfaceBufferCache);
326     void DeleteFreeListCacheLocked(uint32_t sequence);
327 
328     void MarkBufferReclaimableByIdLocked(uint32_t sequence);
329     GSError SetQueueSizeLocked(uint32_t queueSize, std::unique_lock<std::mutex> &lock);
330     GSError AcquireBufferLocked(sptr<SurfaceBuffer>& buffer, sptr<SyncFence>& fence,
331                                 int64_t &timestamp, std::vector<Rect> &damages);
332     void FlushLppBuffer();
333     GSError ReuseBufferForNoBlockMode(sptr<SurfaceBuffer> &buffer, sptr<BufferExtraData> &bedata,
334         BufferRequestConfig &updateConfig, const BufferRequestConfig &config,
335         struct IBufferProducer::RequestBufferReturnValue &retval, std::unique_lock<std::mutex> &lock);
336     GSError ReuseBufferForBlockMode(sptr<SurfaceBuffer> &buffer, sptr<BufferExtraData> &bedata,
337         BufferRequestConfig &updateConfig, const BufferRequestConfig &config,
338         struct IBufferProducer::RequestBufferReturnValue &retval, std::unique_lock<std::mutex> &lock);
339     int32_t defaultWidth_ = 0;
340     int32_t defaultHeight_ = 0;
341     uint64_t defaultUsage_ = 0;
342     uint32_t bufferQueueSize_ = SURFACE_DEFAULT_QUEUE_SIZE;
343     ScalingMode scalingMode_ = ScalingMode::SCALING_MODE_SCALE_TO_WINDOW;
344     GraphicTransformType transform_ = GraphicTransformType::GRAPHIC_ROTATE_NONE;
345     GraphicTransformType lastFlushedTransform_ = GraphicTransformType::GRAPHIC_ROTATE_NONE;
346     std::string name_;
347     std::list<uint32_t> freeList_;
348     std::list<uint32_t> dirtyList_;
349     std::list<uint32_t> deletingList_;
350     std::list<uint32_t> producerCacheList_;
351     std::map<uint32_t, BufferElement> bufferQueueCache_;
352     sptr<IBufferConsumerListener> listener_ = nullptr;
353     IBufferConsumerListenerClazz *listenerClazz_ = nullptr;
354     mutable std::mutex mutex_;
355     std::mutex listenerMutex_;
356     std::mutex producerListenerMutex_;
357     std::mutex propertyChangeMutex_;
358     const uint64_t uniqueId_;
359     std::string bufferName_ = "";
360     OnReleaseFunc onBufferRelease_ = nullptr;
361     std::mutex onBufferReleaseMutex_;
362     sptr<IProducerListener> producerListener_ = nullptr;
363     sptr<IProducerListener> producerListenerBackup_ = nullptr;
364     const size_t propertyChangeListenerMaxNum_ = 50; // 50 : limit producer num
365     std::map<uint64_t, sptr<IProducerListener>> propertyChangeListeners_;
366     OnDeleteBufferFunc onBufferDeleteForRSMainThread_;
367     OnDeleteBufferFunc onBufferDeleteForRSHardwareThread_;
368     std::condition_variable waitReqCon_;
369     std::condition_variable waitAttachCon_;
370     sptr<SurfaceTunnelHandle> tunnelHandle_ = nullptr;
371     bool isValidStatus_ = true;
372     bool producerCacheClean_ = false;
373     const bool isLocalRender_;
374     uint32_t lastFlusedSequence_ = 0;
375     sptr<SyncFence> lastFlusedFence_;
376     wptr<ConsumerSurfaceDelegator> wpCSurfaceDelegator_;
377     bool isCpuAccessable_ = false;
378     GraphicTransformType transformHint_ = GraphicTransformType::GRAPHIC_ROTATE_NONE;
379     bool isBufferHold_ = false;
380     bool isBatch_ = false;
381     OHSurfaceSource sourceType_ = OHSurfaceSource::OH_SURFACE_SOURCE_DEFAULT;
382     std::string appFrameworkType_ = "";
383     float hdrWhitePointBrightness_ = 0.0;
384     float sdrWhitePointBrightness_ = 0.0;
385     uint32_t acquireLastFlushedBufSequence_;
386     int32_t globalAlpha_ = -1;
387     // The default is false, where true indicates non blocking mode and false indicates blocking mode.
388     bool requestBufferNoBlockMode_ = false;
389     std::mutex globalAlphaMutex_;
390     std::string requestBufferStateStr_;
391     std::string acquireBufferStateStr_;
392     // << Lpp
393     std::map<uint32_t, sptr<SurfaceBuffer>> lppBufferCache_;
394     LppSlotInfo *lppSlotInfo_ = nullptr;
395     int32_t lastLppWriteOffset_ = -1;
396     bool isRsDrawLpp_ = false;
397     int32_t lppSkipCount_ = 0;
398     // Lpp >>
399     int32_t connectedPid_ = 0;
400     bool isAllocatingBuffer_ = false;
401     std::condition_variable isAllocatingBufferCon_;
402     int64_t lastFlushedDesiredPresentTimeStamp_ = 0;
403     bool bufferSupportFastCompose_ = false;
404     uint32_t rotatingBufferNumber_ = 0;
405     int32_t frameGravity_ = -1;
406     int32_t fixedRotation_ = -1;
407     uint32_t detachReserveSlotNum_ = 0;
408     int64_t lastConsumeTime_ = 0;
409     uint32_t maxQueueSize_ = 0;
410     bool isActiveGame_ = false;
411     bool isFirstSetDropModeOpen_ = false;
412     GraphicAlphaType alphaType_ = GraphicAlphaType::GRAPHIC_ALPHATYPE_PREMUL;
413     bool isPriorityAlloc_ = false;
414 };
415 }; // namespace OHOS
416 
417 #endif // FRAMEWORKS_SURFACE_INCLUDE_BUFFER_QUEUE_H
418