1  /*
2   * Copyright (c) 2021 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  #include "buffer_queue.h"
17  #include <algorithm>
18  #include <fstream>
19  #include <sstream>
20  #include <sys/time.h>
21  #include <cinttypes>
22  #include <unistd.h>
23  #include <parameters.h>
24  
25  #include "acquire_fence_manager.h"
26  #include "buffer_utils.h"
27  #include "buffer_log.h"
28  #include "hitrace_meter.h"
29  #include "metadata_helper.h"
30  #include "sandbox_utils.h"
31  #include "surface_buffer_impl.h"
32  #include "sync_fence.h"
33  #include "sync_fence_tracker.h"
34  #include "surface_utils.h"
35  #include "surface_trace.h"
36  #include "v1_1/buffer_handle_meta_key_type.h"
37  
38  namespace OHOS {
39  namespace {
40  constexpr uint32_t UNIQUE_ID_OFFSET = 32;
41  constexpr uint32_t BUFFER_MEMSIZE_RATE = 1024;
42  constexpr uint32_t BUFFER_MEMSIZE_FORMAT = 2;
43  constexpr uint32_t MAXIMUM_LENGTH_OF_APP_FRAMEWORK = 64;
44  constexpr uint32_t INVALID_SEQUENCE = 0xFFFFFFFF;
45  constexpr uint32_t ONE_SECOND_TIMESTAMP = 1e9;
46  }
47  
48  static const std::map<BufferState, std::string> BufferStateStrs = {
49      {BUFFER_STATE_RELEASED,                    "0 <released>"},
50      {BUFFER_STATE_REQUESTED,                   "1 <requested>"},
51      {BUFFER_STATE_FLUSHED,                     "2 <flushed>"},
52      {BUFFER_STATE_ACQUIRED,                    "3 <acquired>"},
53      {BUFFER_STATE_ATTACHED,                    "4 <attached>"},
54  };
55  
GetUniqueIdImpl()56  static uint64_t GetUniqueIdImpl()
57  {
58      static std::atomic<uint32_t> counter { 0 };
59      static uint64_t id = static_cast<uint64_t>(GetRealPid()) << UNIQUE_ID_OFFSET;
60      return id | counter++;
61  }
62  
IsLocalRender()63  static bool IsLocalRender()
64  {
65      std::ifstream procfile("/proc/self/cmdline");
66      if (!procfile.is_open()) {
67          BLOGE("Error opening procfile!");
68          return false;
69      }
70      std::string processName;
71      std::getline(procfile, processName);
72      procfile.close();
73      std::string target = "/system/bin/render_service";
74      bool result = processName.substr(0, target.size()) == target;
75      return result;
76  }
77  
BufferQueue(const std::string & name,bool isShared)78  BufferQueue::BufferQueue(const std::string &name, bool isShared)
79      : name_(name), uniqueId_(GetUniqueIdImpl()), isShared_(isShared), isLocalRender_(IsLocalRender())
80  {
81      BLOGD("BufferQueue ctor, uniqueId: %{public}" PRIu64 ".", uniqueId_);
82      if (isShared_ == true) {
83          queueSize_ = 1;
84      }
85      acquireLastFlushedBufSequence_ = INVALID_SEQUENCE;
86  }
87  
~BufferQueue()88  BufferQueue::~BufferQueue()
89  {
90      BLOGD("~BufferQueue dtor, uniqueId: %{public}" PRIu64 ".", uniqueId_);
91      for (auto &[id, _] : bufferQueueCache_) {
92          OnBufferDeleteForRS(id);
93      }
94  }
95  
GetUsedSize()96  uint32_t BufferQueue::GetUsedSize()
97  {
98      return static_cast<uint32_t>(bufferQueueCache_.size());
99  }
100  
GetProducerInitInfo(ProducerInitInfo & info)101  GSError BufferQueue::GetProducerInitInfo(ProducerInitInfo &info)
102  {
103      std::lock_guard<std::mutex> lockGuard(mutex_);
104      info.name = name_;
105      info.width = defaultWidth_;
106      info.height = defaultHeight_;
107      info.uniqueId = uniqueId_;
108      return GSERROR_OK;
109  }
110  
PopFromFreeList(sptr<SurfaceBuffer> & buffer,const BufferRequestConfig & config)111  GSError BufferQueue::PopFromFreeList(sptr<SurfaceBuffer> &buffer,
112      const BufferRequestConfig &config)
113  {
114      if (isShared_ == true && GetUsedSize() > 0) {
115          buffer = bufferQueueCache_.begin()->second.buffer;
116          return GSERROR_OK;
117      }
118  
119      for (auto it = freeList_.begin(); it != freeList_.end(); it++) {
120          auto mapIter = bufferQueueCache_.find(*it);
121          if (mapIter != bufferQueueCache_.end() && mapIter->second.config == config) {
122              if (mapIter->first == acquireLastFlushedBufSequence_) {
123                  continue;
124              }
125              buffer = mapIter->second.buffer;
126              freeList_.erase(it);
127              return GSERROR_OK;
128          }
129      }
130  
131      if (freeList_.empty() || GetUsedSize() < GetQueueSize() ||
132          (freeList_.size() == 1 && freeList_.front() == acquireLastFlushedBufSequence_)) {
133          buffer = nullptr;
134          return GSERROR_NO_BUFFER;
135      }
136  
137      if (freeList_.front() == acquireLastFlushedBufSequence_) {
138          freeList_.pop_front();
139          freeList_.push_back(acquireLastFlushedBufSequence_);
140      }
141  
142      buffer = bufferQueueCache_[freeList_.front()].buffer;
143      buffer->SetSurfaceBufferColorGamut(config.colorGamut);
144      buffer->SetSurfaceBufferTransform(config.transform);
145      freeList_.pop_front();
146      return GSERROR_OK;
147  }
148  
PopFromDirtyList(sptr<SurfaceBuffer> & buffer)149  GSError BufferQueue::PopFromDirtyList(sptr<SurfaceBuffer> &buffer)
150  {
151      if (isShared_ == true && GetUsedSize() > 0) {
152          buffer = bufferQueueCache_.begin()->second.buffer;
153          return GSERROR_OK;
154      }
155  
156      if (!dirtyList_.empty()) {
157          buffer = bufferQueueCache_[dirtyList_.front()].buffer;
158          dirtyList_.pop_front();
159          return GSERROR_OK;
160      } else {
161          buffer = nullptr;
162          return GSERROR_NO_BUFFER;
163      }
164  }
165  
CheckRequestConfig(const BufferRequestConfig & config)166  GSError BufferQueue::CheckRequestConfig(const BufferRequestConfig &config)
167  {
168      uint32_t align = config.strideAlignment;
169      if (align < SURFACE_MIN_STRIDE_ALIGNMENT || align > SURFACE_MAX_STRIDE_ALIGNMENT) {
170          BLOGW("align is %{public}d, uniqueId: %{public}" PRIu64 ".", align, uniqueId_);
171          return GSERROR_INVALID_ARGUMENTS;
172      }
173  
174      if (align & (align - 1)) {
175          BLOGW("align is %{public}d, uniqueId: %{public}" PRIu64 ".", align, uniqueId_);
176          return GSERROR_INVALID_ARGUMENTS;
177      }
178  
179      if (config.colorGamut <= GraphicColorGamut::GRAPHIC_COLOR_GAMUT_INVALID ||
180          config.colorGamut > GraphicColorGamut::GRAPHIC_COLOR_GAMUT_DISPLAY_BT2020 + 1) {
181          BLOGW("colorGamut is %{public}d, uniqueId: %{public}" PRIu64 ".",
182              static_cast<uint32_t>(config.colorGamut), uniqueId_);
183          return GSERROR_INVALID_ARGUMENTS;
184      }
185  
186      if (config.transform < GraphicTransformType::GRAPHIC_ROTATE_NONE ||
187          config.transform >= GraphicTransformType::GRAPHIC_ROTATE_BUTT) {
188          BLOGW("transform is %{public}d, uniqueId: %{public}" PRIu64 ".", config.transform, uniqueId_);
189          return GSERROR_INVALID_ARGUMENTS;
190      }
191      return GSERROR_OK;
192  }
193  
CheckFlushConfig(const BufferFlushConfigWithDamages & config)194  GSError BufferQueue::CheckFlushConfig(const BufferFlushConfigWithDamages &config)
195  {
196      for (decltype(config.damages.size()) i = 0; i < config.damages.size(); i++) {
197          if (config.damages[i].w < 0 || config.damages[i].h < 0) {
198              BLOGW("damages[%{public}zu].w is %{public}d, .h is %{public}d, uniqueId: %{public}" PRIu64 ".",
199                  i, config.damages[i].w, config.damages[i].h, uniqueId_);
200              return GSERROR_INVALID_ARGUMENTS;
201          }
202      }
203      return GSERROR_OK;
204  }
205  
QueryIfBufferAvailable()206  bool BufferQueue::QueryIfBufferAvailable()
207  {
208      std::lock_guard<std::mutex> lockGuard(mutex_);
209      bool ret = !freeList_.empty() || (GetUsedSize() < GetQueueSize());
210      return ret;
211  }
212  
DelegatorDequeueBuffer(wptr<ConsumerSurfaceDelegator> & delegator,const BufferRequestConfig & config,sptr<BufferExtraData> & bedata,struct IBufferProducer::RequestBufferReturnValue & retval)213  static GSError DelegatorDequeueBuffer(wptr<ConsumerSurfaceDelegator>& delegator,
214                                        const BufferRequestConfig& config,
215                                        sptr<BufferExtraData>& bedata,
216                                        struct IBufferProducer::RequestBufferReturnValue& retval)
217  {
218      auto consumerDelegator = delegator.promote();
219      if (consumerDelegator == nullptr) {
220          BLOGE("Consumer surface delegator has been expired");
221          return GSERROR_INVALID_ARGUMENTS;
222      }
223      auto ret = consumerDelegator->DequeueBuffer(config, bedata, retval);
224      if (ret != GSERROR_OK) {
225          BLOGE("Consumer surface delegator failed to dequeuebuffer, err: %{public}d", ret);
226          return ret;
227      }
228  
229      ret = retval.buffer->Map();
230      if (ret != GSERROR_OK) {
231          BLOGE("Buffer map failed, err: %{public}d", ret);
232          return ret;
233      }
234      retval.buffer->SetSurfaceBufferWidth(retval.buffer->GetWidth());
235      retval.buffer->SetSurfaceBufferHeight(retval.buffer->GetHeight());
236  
237      return GSERROR_OK;
238  }
239  
SetReturnValue(sptr<SurfaceBuffer> & buffer,sptr<BufferExtraData> & bedata,struct IBufferProducer::RequestBufferReturnValue & retval)240  static void SetReturnValue(sptr<SurfaceBuffer>& buffer, sptr<BufferExtraData>& bedata,
241                             struct IBufferProducer::RequestBufferReturnValue& retval)
242  {
243      retval.sequence = buffer->GetSeqNum();
244      bedata = buffer->GetExtraData();
245      retval.fence = SyncFence::InvalidFence();
246  }
247  
SetSurfaceBufferHebcMetaLocked(sptr<SurfaceBuffer> buffer)248  void BufferQueue::SetSurfaceBufferHebcMetaLocked(sptr<SurfaceBuffer> buffer)
249  {
250      using namespace HDI::Display::Graphic::Common;
251      // usage does not contain BUFFER_USAGE_CPU_HW_BOTH, just return
252      if (!(buffer->GetUsage() & BUFFER_USAGE_CPU_HW_BOTH)) {
253          return;
254      }
255  
256      V1_1::BufferHandleAttrKey key = V1_1::BufferHandleAttrKey::ATTRKEY_REQUEST_ACCESS_TYPE;
257      std::vector<uint8_t> values;
258      if (isCpuAccessable_) { // hebc is off
259          values.push_back(static_cast<uint8_t>(V1_1::HebcAccessType::HEBC_ACCESS_CPU_ACCESS));
260      } else { // hebc is on
261          values.push_back(static_cast<uint8_t>(V1_1::HebcAccessType::HEBC_ACCESS_HW_ONLY));
262      }
263  
264      buffer->SetMetadata(key, values);
265  }
266  
SetBatchHandle(bool batch)267  void BufferQueue::SetBatchHandle(bool batch)
268  {
269      std::unique_lock<std::mutex> lock(mutex_);
270      isBatch_ = batch;
271  }
272  
RequestBufferCheckStatus()273  GSError BufferQueue::RequestBufferCheckStatus()
274  {
275      if (isBatch_) {
276          return GSERROR_OK;
277      }
278      if (!GetStatusLocked()) {
279          SURFACE_TRACE_NAME_FMT("RequestBufferCheckStatus status wrong,"
280              "surface name: %s queueId: %" PRIu64 " status: %u", name_.c_str(), uniqueId_, GetStatusLocked());
281          BLOGN_FAILURE_RET(GSERROR_NO_CONSUMER);
282      }
283      std::lock_guard<std::mutex> lockGuard(listenerMutex_);
284      if (listener_ == nullptr && listenerClazz_ == nullptr) {
285          SURFACE_TRACE_NAME_FMT("RequestBufferCheckStatus no listener, surface name: %s queueId: %" PRIu64,
286              name_.c_str(), uniqueId_);
287          BLOGN_FAILURE_RET(SURFACE_ERROR_CONSUMER_UNREGISTER_LISTENER);
288      }
289  
290      return GSERROR_OK;
291  }
292  
WaitForCondition()293  bool BufferQueue::WaitForCondition()
294  {
295      return (!freeList_.empty() && !(freeList_.size() == 1 && freeList_.front() == acquireLastFlushedBufSequence_)) ||
296          (GetUsedSize() < GetQueueSize()) || !GetStatusLocked();
297  }
298  
RequestBufferDebugInfo()299  void BufferQueue::RequestBufferDebugInfo()
300  {
301      SURFACE_TRACE_NAME_FMT("lockLastFlushedBuffer seq: %u", acquireLastFlushedBufSequence_);
302      std::map<BufferState, int32_t> bufferState;
303      for (auto &[id, ele] : bufferQueueCache_) {
304          SURFACE_TRACE_NAME_FMT("request buffer id: %d state: %u", id, ele.state);
305          BLOGD("request no buffer, buffer id:%{public}d state:%{public}d, uniqueId: %{public}" PRIu64 ".",
306              id, ele.state, uniqueId_);
307          bufferState[ele.state] += 1;
308      }
309      std::string str = std::to_string(uniqueId_) +
310          ", Released: " + std::to_string(bufferState[BUFFER_STATE_RELEASED]) +
311          " Requested: " + std::to_string(bufferState[BUFFER_STATE_REQUESTED]) +
312          " Flushed: " + std::to_string(bufferState[BUFFER_STATE_FLUSHED]) +
313          " Acquired: " + std::to_string(bufferState[BUFFER_STATE_ACQUIRED]);
314      if (str.compare(requestBufferStateStr_) != 0) {
315          requestBufferStateStr_ = str;
316          BLOGE("all buffer are using, uniqueId: %{public}s", str.c_str());
317      }
318  }
319  
RequestBufferLocked(const BufferRequestConfig & config,sptr<BufferExtraData> & bedata,struct IBufferProducer::RequestBufferReturnValue & retval,std::unique_lock<std::mutex> & lock)320  GSError BufferQueue::RequestBufferLocked(const BufferRequestConfig &config, sptr<BufferExtraData> &bedata,
321      struct IBufferProducer::RequestBufferReturnValue &retval, std::unique_lock<std::mutex> &lock)
322  {
323      GSError ret = RequestBufferCheckStatus();
324      if (ret != GSERROR_OK) {
325          return ret;
326      }
327  
328      SURFACE_TRACE_NAME_FMT("RequestBuffer name: %s queueId: %" PRIu64 " queueSize: %u",
329          name_.c_str(), uniqueId_, GetQueueSize());
330      // check param
331      ret = CheckRequestConfig(config);
332      if (ret != GSERROR_OK) {
333          BLOGE("CheckRequestConfig ret: %{public}d, uniqueId: %{public}" PRIu64 ".", ret, uniqueId_);
334          return SURFACE_ERROR_UNKOWN;
335      }
336      // dequeue from free list
337      sptr<SurfaceBuffer>& buffer = retval.buffer;
338      ret = PopFromFreeList(buffer, config);
339      if (ret == GSERROR_OK) {
340          return ReuseBuffer(config, bedata, retval);
341      }
342  
343      // check queue size
344      if (GetUsedSize() >= GetQueueSize()) {
345          waitReqCon_.wait_for(lock, std::chrono::milliseconds(config.timeout),
346              [this]() { return WaitForCondition(); });
347          if (!GetStatusLocked() && !isBatch_) {
348              SURFACE_TRACE_NAME_FMT("Status wrong, status: %d", GetStatusLocked());
349              BLOGN_FAILURE_RET(GSERROR_NO_CONSUMER);
350          }
351          // try dequeue from free list again
352          ret = PopFromFreeList(buffer, config);
353          if (ret == GSERROR_OK) {
354              return ReuseBuffer(config, bedata, retval);
355          } else if (GetUsedSize() >= GetQueueSize()) {
356              RequestBufferDebugInfo();
357              return GSERROR_NO_BUFFER;
358          }
359      }
360  
361      ret = AllocBuffer(buffer, config);
362      if (ret == GSERROR_OK) {
363          AddDeletingBuffersLocked(retval.deletingBuffers);
364          SetSurfaceBufferHebcMetaLocked(buffer);
365          SetReturnValue(buffer, bedata, retval);
366          BLOGD("Success alloc Buffer[%{public}d %{public}d] seq: %{public}d, uniqueId: %{public}" PRIu64 ".",
367              config.width, config.height, retval.sequence, uniqueId_);
368      } else {
369          BLOGE("Fail to alloc or map Buffer[%{public}d %{public}d] ret: %{public}d, uniqueId: %{public}" PRIu64,
370              config.width, config.height, ret, uniqueId_);
371      }
372      return ret;
373  }
374  
RequestBuffer(const BufferRequestConfig & config,sptr<BufferExtraData> & bedata,struct IBufferProducer::RequestBufferReturnValue & retval)375  GSError BufferQueue::RequestBuffer(const BufferRequestConfig &config, sptr<BufferExtraData> &bedata,
376      struct IBufferProducer::RequestBufferReturnValue &retval)
377  {
378      if (wpCSurfaceDelegator_ != nullptr) {
379          return DelegatorDequeueBuffer(wpCSurfaceDelegator_, config, bedata, retval);
380      }
381      std::unique_lock<std::mutex> lock(mutex_);
382      return RequestBufferLocked(config, bedata, retval, lock);
383  }
384  
SetProducerCacheCleanFlag(bool flag)385  GSError BufferQueue::SetProducerCacheCleanFlag(bool flag)
386  {
387      std::unique_lock<std::mutex> lock(mutex_);
388      return SetProducerCacheCleanFlagLocked(flag);
389  }
390  
SetProducerCacheCleanFlagLocked(bool flag)391  GSError BufferQueue::SetProducerCacheCleanFlagLocked(bool flag)
392  {
393      producerCacheClean_ = flag;
394      producerCacheList_.clear();
395      return GSERROR_OK;
396  }
397  
CheckProducerCacheList()398  bool BufferQueue::CheckProducerCacheList()
399  {
400      for (auto &[id, _] : bufferQueueCache_) {
401          if (std::find(producerCacheList_.begin(), producerCacheList_.end(), id) == producerCacheList_.end()) {
402              return false;
403          }
404      }
405      return true;
406  }
407  
ReallocBuffer(const BufferRequestConfig & config,struct IBufferProducer::RequestBufferReturnValue & retval)408  GSError BufferQueue::ReallocBuffer(const BufferRequestConfig &config,
409      struct IBufferProducer::RequestBufferReturnValue &retval)
410  {
411      if (isShared_) {
412          BLOGE("shared mode, uniqueId: %{public}" PRIu64, uniqueId_);
413          return SURFACE_ERROR_UNKOWN;
414      }
415      DeleteBufferInCache(retval.sequence);
416  
417      sptr<SurfaceBuffer> buffer = nullptr;
418      auto sret = AllocBuffer(buffer, config);
419      if (sret != GSERROR_OK) {
420          BLOGE("AllocBuffer failed: %{public}d, uniqueId: %{public}" PRIu64 ".", sret, uniqueId_);
421          return sret;
422      }
423  
424      retval.buffer = buffer;
425      retval.sequence = buffer->GetSeqNum();
426      bufferQueueCache_[retval.sequence].config = config;
427      return GSERROR_OK;
428  }
429  
AddDeletingBuffersLocked(std::vector<uint32_t> & deletingBuffers)430  void BufferQueue::AddDeletingBuffersLocked(std::vector<uint32_t> &deletingBuffers)
431  {
432      deletingBuffers.reserve(deletingBuffers.size() + deletingList_.size());
433      deletingBuffers.insert(deletingBuffers.end(), deletingList_.begin(), deletingList_.end());
434      deletingList_.clear();
435  }
436  
ReuseBuffer(const BufferRequestConfig & config,sptr<BufferExtraData> & bedata,struct IBufferProducer::RequestBufferReturnValue & retval)437  GSError BufferQueue::ReuseBuffer(const BufferRequestConfig &config, sptr<BufferExtraData> &bedata,
438      struct IBufferProducer::RequestBufferReturnValue &retval)
439  {
440      if (retval.buffer == nullptr) {
441          BLOGE("input buffer is null, uniqueId: %{public}" PRIu64 ".", uniqueId_);
442          return SURFACE_ERROR_UNKOWN;
443      }
444      retval.sequence = retval.buffer->GetSeqNum();
445      if (bufferQueueCache_.find(retval.sequence) == bufferQueueCache_.end()) {
446          BLOGE("cache not find the buffer(%{public}u), uniqueId: %{public}" PRIu64 ".", retval.sequence, uniqueId_);
447          return SURFACE_ERROR_UNKOWN;
448      }
449      auto &cacheConfig = bufferQueueCache_[retval.sequence].config;
450      SURFACE_TRACE_NAME_FMT("ReuseBuffer config width: %d height: %d usage: %llu format: %d id: %u",
451          cacheConfig.width, cacheConfig.height, cacheConfig.usage, cacheConfig.format, retval.sequence);
452  
453      bool needRealloc = (config != bufferQueueCache_[retval.sequence].config);
454      // config, realloc
455      if (needRealloc) {
456          auto sret = ReallocBuffer(config, retval);
457          if (sret != GSERROR_OK) {
458              return sret;
459          }
460      }
461  
462      bufferQueueCache_[retval.sequence].state = BUFFER_STATE_REQUESTED;
463      retval.fence = bufferQueueCache_[retval.sequence].fence;
464      bedata = retval.buffer->GetExtraData();
465      SetSurfaceBufferHebcMetaLocked(retval.buffer);
466  
467      auto &dbs = retval.deletingBuffers;
468      AddDeletingBuffersLocked(dbs);
469  
470      if (needRealloc || isShared_ || producerCacheClean_ || retval.buffer->GetConsumerAttachBufferFlag()) {
471          BLOGD("requestBuffer Succ realloc Buffer[%{public}d %{public}d] with new config "\
472              "seq: %{public}d attachFlag: %{public}d, uniqueId: %{public}" PRIu64 ".",
473              config.width, config.height, retval.sequence, retval.buffer->GetConsumerAttachBufferFlag(), uniqueId_);
474          if (producerCacheClean_) {
475              producerCacheList_.push_back(retval.sequence);
476              if (CheckProducerCacheList()) {
477                  SetProducerCacheCleanFlagLocked(false);
478              }
479          }
480          retval.buffer->SetConsumerAttachBufferFlag(false);
481      } else {
482          BLOGD("RequestBuffer Succ Buffer[%{public}d %{public}d] in seq id: %{public}d "\
483              "seq: %{public}" PRIu64 " releaseFence: %{public}d, uniqueId: %{public}" PRIu64 ".",
484              config.width, config.height, retval.sequence, uniqueId_, retval.fence->Get(), uniqueId_);
485          retval.buffer = nullptr;
486      }
487  
488      SURFACE_TRACE_NAME_FMT("%s:%u", name_.c_str(), retval.sequence);
489      if (IsTagEnabled(HITRACE_TAG_GRAPHIC_AGP) && isLocalRender_) {
490          static SyncFenceTracker releaseFenceThread("Release Fence");
491          releaseFenceThread.TrackFence(retval.fence);
492      }
493      return GSERROR_OK;
494  }
495  
CancelBuffer(uint32_t sequence,sptr<BufferExtraData> bedata)496  GSError BufferQueue::CancelBuffer(uint32_t sequence, sptr<BufferExtraData> bedata)
497  {
498      SURFACE_TRACE_NAME_FMT("CancelBuffer name: %s queueId: %" PRIu64 " sequence: %u",
499          name_.c_str(), uniqueId_, sequence);
500      if (isShared_) {
501          BLOGN_FAILURE_RET(GSERROR_INVALID_OPERATING);
502      }
503      std::lock_guard<std::mutex> lockGuard(mutex_);
504  
505      if (bufferQueueCache_.find(sequence) == bufferQueueCache_.end()) {
506          return GSERROR_NO_ENTRY;
507      }
508  
509      if (bufferQueueCache_[sequence].state != BUFFER_STATE_REQUESTED &&
510          bufferQueueCache_[sequence].state != BUFFER_STATE_ATTACHED) {
511          return GSERROR_INVALID_OPERATING;
512      }
513      bufferQueueCache_[sequence].state = BUFFER_STATE_RELEASED;
514      freeList_.push_back(sequence);
515      if (bufferQueueCache_[sequence].buffer == nullptr) {
516          BLOGE("cache buffer is nullptr, sequence:%{public}u, uniqueId: %{public}" PRIu64 ".", sequence, uniqueId_);
517          return GSERROR_INVALID_OPERATING;
518      }
519      bufferQueueCache_[sequence].buffer->SetExtraData(bedata);
520  
521      waitReqCon_.notify_all();
522      waitAttachCon_.notify_all();
523      BLOGD("Success Buffer id: %{public}d, uniqueId: %{public}" PRIu64 ".", sequence, uniqueId_);
524  
525      return GSERROR_OK;
526  }
527  
CheckBufferQueueCacheLocked(uint32_t sequence)528  GSError BufferQueue::CheckBufferQueueCacheLocked(uint32_t sequence)
529  {
530      if (bufferQueueCache_.find(sequence) == bufferQueueCache_.end()) {
531          BLOGE("no find seq: %{public}u, uniqueId: %{public}" PRIu64 ".", sequence, uniqueId_);
532          return SURFACE_ERROR_BUFFER_NOT_INCACHE;
533      }
534  
535      if (isShared_ == false) {
536          auto &state = bufferQueueCache_[sequence].state;
537          if (state != BUFFER_STATE_REQUESTED && state != BUFFER_STATE_ATTACHED) {
538              BLOGE("seq: %{public}u, invalid state %{public}d, uniqueId: %{public}" PRIu64 ".",
539                  sequence, state, uniqueId_);
540              return SURFACE_ERROR_BUFFER_STATE_INVALID;
541          }
542      }
543      return GSERROR_OK;
544  }
545  
CheckBufferQueueCache(uint32_t sequence)546  GSError BufferQueue::CheckBufferQueueCache(uint32_t sequence)
547  {
548      std::lock_guard<std::mutex> lockGuard(mutex_);
549      return CheckBufferQueueCacheLocked(sequence);
550  }
551  
DelegatorQueueBuffer(uint32_t sequence,sptr<SyncFence> fence)552  GSError BufferQueue::DelegatorQueueBuffer(uint32_t sequence, sptr<SyncFence> fence)
553  {
554      auto consumerDelegator = wpCSurfaceDelegator_.promote();
555      if (consumerDelegator == nullptr) {
556          BLOGE("Consumer surface delegator has been expired");
557          return GSERROR_INVALID_ARGUMENTS;
558      }
559      sptr<SurfaceBuffer> buffer = nullptr;
560      {
561          std::lock_guard<std::mutex> lockGuard(mutex_);
562          if (bufferQueueCache_.find(sequence) == bufferQueueCache_.end()) {
563              return GSERROR_NO_ENTRY;
564          }
565          bufferQueueCache_[sequence].state = BUFFER_STATE_ACQUIRED;
566          buffer = bufferQueueCache_[sequence].buffer;
567      }
568      GSError ret = consumerDelegator->QueueBuffer(buffer, fence->Get());
569      if (ret != GSERROR_OK) {
570          BLOGE("Consumer surface delegator failed to queuebuffer");
571      }
572      ret = ReleaseBuffer(buffer, SyncFence::InvalidFence());
573      if (ret != GSERROR_OK) {
574          BLOGE("Consumer surface delegator failed to releasebuffer");
575      }
576      return ret;
577  }
578  
CallConsumerListener()579  void BufferQueue::CallConsumerListener()
580  {
581      SURFACE_TRACE_NAME_FMT("CallConsumerListener");
582      sptr<IBufferConsumerListener> listener;
583      IBufferConsumerListenerClazz *listenerClazz;
584      {
585          std::lock_guard<std::mutex> lockGuard(listenerMutex_);
586          listener = listener_;
587          listenerClazz = listenerClazz_;
588      }
589      if (listener != nullptr) {
590          listener->OnBufferAvailable();
591      } else if (listenerClazz != nullptr) {
592          listenerClazz->OnBufferAvailable();
593      }
594  }
595  
FlushBuffer(uint32_t sequence,sptr<BufferExtraData> bedata,sptr<SyncFence> fence,const BufferFlushConfigWithDamages & config)596  GSError BufferQueue::FlushBuffer(uint32_t sequence, sptr<BufferExtraData> bedata,
597      sptr<SyncFence> fence, const BufferFlushConfigWithDamages &config)
598  {
599      SURFACE_TRACE_NAME_FMT("FlushBuffer name: %s queueId: %" PRIu64 " sequence: %u",
600          name_.c_str(), uniqueId_, sequence);
601      {
602          std::lock_guard<std::mutex> lockGuard(mutex_);
603          if (!GetStatusLocked()) {
604              SURFACE_TRACE_NAME_FMT("status: %d", GetStatusLocked());
605              BLOGN_FAILURE_RET(GSERROR_NO_CONSUMER);
606          }
607      }
608      // check param
609      auto sret = CheckFlushConfig(config);
610      if (sret != GSERROR_OK) {
611          BLOGE("CheckFlushConfig ret: %{public}d, uniqueId: %{public}" PRIu64 ".", sret, uniqueId_);
612          return sret;
613      }
614  
615      sret = CheckBufferQueueCache(sequence);
616      if (sret != GSERROR_OK) {
617          return sret;
618      }
619  
620      bool listenerNullCheck = false;
621      {
622          std::lock_guard<std::mutex> lockGuard(listenerMutex_);
623          if (listener_ == nullptr && listenerClazz_ == nullptr) {
624              listenerNullCheck = true;
625          }
626      }
627      if (listenerNullCheck) {
628          SURFACE_TRACE_NAME("listener is nullptr");
629          BLOGE("listener is nullptr, uniqueId: %{public}" PRIu64 ".", uniqueId_);
630          CancelBuffer(sequence, bedata);
631          return SURFACE_ERROR_CONSUMER_UNREGISTER_LISTENER;
632      }
633  
634      sret = DoFlushBuffer(sequence, bedata, fence, config);
635      if (sret != GSERROR_OK) {
636          return sret;
637      }
638      if (sret == GSERROR_OK) {
639          CallConsumerListener();
640      }
641      BLOGD("Success Buffer seq id: %{public}d AcquireFence:%{public}d, uniqueId: %{public}" PRIu64 ".",
642          sequence, fence->Get(), uniqueId_);
643  
644      if (wpCSurfaceDelegator_ != nullptr) {
645          sret = DelegatorQueueBuffer(sequence, fence);
646      }
647      return sret;
648  }
649  
GetLastFlushedBuffer(sptr<SurfaceBuffer> & buffer,sptr<SyncFence> & fence,float matrix[16],uint32_t matrixSize,bool isUseNewMatrix,bool needRecordSequence)650  GSError BufferQueue::GetLastFlushedBuffer(sptr<SurfaceBuffer>& buffer,
651      sptr<SyncFence>& fence, float matrix[16], uint32_t matrixSize, bool isUseNewMatrix, bool needRecordSequence)
652  {
653      std::lock_guard<std::mutex> lockGuard(mutex_);
654      if (needRecordSequence && acquireLastFlushedBufSequence_ != INVALID_SEQUENCE) {
655          BLOGE("last flushed buffer(%{public}d) is using, uniqueId: %{public}" PRIu64 ".",
656              acquireLastFlushedBufSequence_, uniqueId_);
657          return SURFACE_ERROR_BUFFER_STATE_INVALID;
658      }
659      if (bufferQueueCache_.find(lastFlusedSequence_) == bufferQueueCache_.end()) {
660          BLOGE("cache ont find the buffer(%{public}u), uniqueId: %{public}" PRIu64 ".", lastFlusedSequence_, uniqueId_);
661          return SURFACE_ERROR_UNKOWN;
662      }
663      auto &state = bufferQueueCache_[lastFlusedSequence_].state;
664      if (state == BUFFER_STATE_REQUESTED) {
665          BLOGE("seq: %{public}u, invalid state %{public}d, uniqueId: %{public}" PRIu64 ".",
666              lastFlusedSequence_, state, uniqueId_);
667          return SURFACE_ERROR_BUFFER_STATE_INVALID;
668      }
669      auto usage = bufferQueueCache_[lastFlusedSequence_].buffer->GetUsage();
670      if (usage & BUFFER_USAGE_PROTECTED) {
671          BLOGE("lastFlusedSeq: %{public}u, usage: %{public}" PRIu64 ", uniqueId: %{public}" PRIu64 ".",
672              lastFlusedSequence_, usage, uniqueId_);
673          return SURFACE_ERROR_NOT_SUPPORT;
674      }
675      buffer = bufferQueueCache_[lastFlusedSequence_].buffer;
676      fence = lastFlusedFence_;
677      Rect damage = {};
678      if (buffer != nullptr) {
679          damage.w = buffer->GetWidth();
680          damage.h = buffer->GetHeight();
681      }
682      auto utils = SurfaceUtils::GetInstance();
683      if (isUseNewMatrix) {
684          utils->ComputeTransformMatrixV2(matrix, matrixSize, buffer, lastFlushedTransform_, damage);
685      } else {
686          utils->ComputeTransformMatrix(matrix, matrixSize, buffer, lastFlushedTransform_, damage);
687      }
688  
689      if (needRecordSequence) {
690          acquireLastFlushedBufSequence_ = lastFlusedSequence_;
691          SURFACE_TRACE_NAME_FMT("GetLastFlushedBuffer(needRecordSequence) name: %s queueId: %" PRIu64 " seq: %u",
692              name_.c_str(), uniqueId_, acquireLastFlushedBufSequence_);
693      }
694      return GSERROR_OK;
695  }
696  
AcquireLastFlushedBuffer(sptr<SurfaceBuffer> & buffer,sptr<SyncFence> & fence,float matrix[16],uint32_t matrixSize,bool isUseNewMatrix)697  GSError BufferQueue::AcquireLastFlushedBuffer(sptr<SurfaceBuffer> &buffer, sptr<SyncFence> &fence,
698      float matrix[16], uint32_t matrixSize, bool isUseNewMatrix)
699  {
700      return GetLastFlushedBuffer(buffer, fence, matrix, matrixSize, isUseNewMatrix, true);
701  }
702  
ReleaseLastFlushedBuffer(uint32_t sequence)703  GSError BufferQueue::ReleaseLastFlushedBuffer(uint32_t sequence)
704  {
705      SURFACE_TRACE_NAME_FMT("ReleaseLastFlushedBuffer name: %s queueId: %" PRIu64 " seq: %u",
706          name_.c_str(), uniqueId_, sequence);
707      std::lock_guard<std::mutex> lockGuard(mutex_);
708      if (acquireLastFlushedBufSequence_ == INVALID_SEQUENCE || acquireLastFlushedBufSequence_ != sequence) {
709          BLOGE("ReleaseLastFlushedBuffer lastFlushBuffer:%{public}d sequence:%{public}d, uniqueId: %{public}" PRIu64,
710              acquireLastFlushedBufSequence_, sequence, uniqueId_);
711          return SURFACE_ERROR_BUFFER_STATE_INVALID;
712      }
713      acquireLastFlushedBufSequence_ = INVALID_SEQUENCE;
714      waitReqCon_.notify_all();
715      return GSERROR_OK;
716  }
717  
DoFlushBufferLocked(uint32_t sequence,sptr<BufferExtraData> bedata,sptr<SyncFence> fence,const BufferFlushConfigWithDamages & config)718  GSError BufferQueue::DoFlushBufferLocked(uint32_t sequence, sptr<BufferExtraData> bedata,
719      sptr<SyncFence> fence, const BufferFlushConfigWithDamages &config)
720  {
721      if (bufferQueueCache_.find(sequence) == bufferQueueCache_.end()) {
722          BLOGE("bufferQueueCache not find sequence:%{public}u, uniqueId: %{public}" PRIu64 ".", sequence, uniqueId_);
723          return SURFACE_ERROR_BUFFER_NOT_INCACHE;
724      }
725      if (bufferQueueCache_[sequence].isDeleting) {
726          DeleteBufferInCache(sequence);
727          BLOGD("DoFlushBuffer delete seq: %{public}d, uniqueId: %{public}" PRIu64 ".", sequence, uniqueId_);
728          CountTrace(HITRACE_TAG_GRAPHIC_AGP, name_, static_cast<int32_t>(dirtyList_.size()));
729          return GSERROR_OK;
730      }
731  
732      bufferQueueCache_[sequence].state = BUFFER_STATE_FLUSHED;
733      dirtyList_.push_back(sequence);
734      bufferQueueCache_[sequence].buffer->SetExtraData(bedata);
735      bufferQueueCache_[sequence].fence = fence;
736      bufferQueueCache_[sequence].damages = config.damages;
737      lastFlusedSequence_ = sequence;
738      lastFlusedFence_ = fence;
739      lastFlushedTransform_ = transform_;
740      bufferQueueCache_[sequence].buffer->SetSurfaceBufferTransform(transform_);
741  
742      uint64_t usage = static_cast<uint32_t>(bufferQueueCache_[sequence].config.usage);
743      if (usage & BUFFER_USAGE_CPU_WRITE) {
744          // api flush
745          auto sret = bufferQueueCache_[sequence].buffer->FlushCache();
746          if (sret != GSERROR_OK) {
747              BLOGE("FlushCache ret: %{public}d, seq: %{public}u, uniqueId: %{public}" PRIu64 ".",
748                  sret, sequence, uniqueId_);
749              return sret;
750          }
751      }
752      SetDesiredPresentTimestampAndUiTimestamp(sequence, config.desiredPresentTimestamp, config.timestamp);
753      bool traceTag = IsTagEnabled(HITRACE_TAG_GRAPHIC_AGP);
754      if (isLocalRender_) {
755          AcquireFenceTracker::TrackFence(fence, traceTag);
756      }
757      // if you need dump SurfaceBuffer to file, you should execute hdc shell param set persist.dumpbuffer.enabled 1
758      // and reboot your device
759      static bool dumpBufferEnabled = system::GetParameter("persist.dumpbuffer.enabled", "0") != "0";
760      if (dumpBufferEnabled) {
761          // Wait for the status of the fence to change to SIGNALED.
762          fence->Wait(-1);
763          DumpToFileAsync(GetRealPid(), name_, bufferQueueCache_[sequence].buffer);
764      }
765  
766      CountTrace(HITRACE_TAG_GRAPHIC_AGP, name_, static_cast<int32_t>(dirtyList_.size()));
767      return GSERROR_OK;
768  }
769  
DoFlushBuffer(uint32_t sequence,sptr<BufferExtraData> bedata,sptr<SyncFence> fence,const BufferFlushConfigWithDamages & config)770  GSError BufferQueue::DoFlushBuffer(uint32_t sequence, sptr<BufferExtraData> bedata,
771      sptr<SyncFence> fence, const BufferFlushConfigWithDamages &config)
772  {
773      SURFACE_TRACE_NAME_FMT("DoFlushBuffer name: %s queueId: %" PRIu64 " seq: %u",
774          name_.c_str(), uniqueId_, sequence);
775      std::unique_lock<std::mutex> lock(mutex_);
776      return DoFlushBufferLocked(sequence, bedata, fence, config);
777  }
778  
SetDesiredPresentTimestampAndUiTimestamp(uint32_t sequence,int64_t desiredPresentTimestamp,uint64_t uiTimestamp)779  void BufferQueue::SetDesiredPresentTimestampAndUiTimestamp(uint32_t sequence, int64_t desiredPresentTimestamp,
780                                                             uint64_t uiTimestamp)
781  {
782      bufferQueueCache_[sequence].isAutoTimestamp = false;
783      if (desiredPresentTimestamp <= 0) {
784          if (desiredPresentTimestamp == 0 && uiTimestamp != 0
785              && uiTimestamp <= static_cast<uint64_t>(std::numeric_limits<int64_t>::max())) {
786              bufferQueueCache_[sequence].desiredPresentTimestamp = static_cast<int64_t>(uiTimestamp);
787          } else {
788              bufferQueueCache_[sequence].desiredPresentTimestamp = std::chrono::duration_cast<std::chrono::nanoseconds>(
789                  std::chrono::steady_clock::now().time_since_epoch()).count();
790              bufferQueueCache_[sequence].isAutoTimestamp = true;
791          }
792      } else {
793          bufferQueueCache_[sequence].desiredPresentTimestamp = desiredPresentTimestamp;
794      }
795      bufferQueueCache_[sequence].timestamp = static_cast<int64_t>(uiTimestamp);
796  }
797  
LogAndTraceAllBufferInBufferQueueCache()798  void BufferQueue::LogAndTraceAllBufferInBufferQueueCache()
799  {
800      std::map<BufferState, int32_t> bufferState;
801      for (auto &[id, ele] : bufferQueueCache_) {
802          SURFACE_TRACE_NAME_FMT("acquire buffer id: %d state: %d desiredPresentTimestamp: %" PRId64
803              " isAotuTimestamp: %d", id, ele.state, ele.desiredPresentTimestamp, ele.isAutoTimestamp);
804          BLOGD("acquire no buffer, buffer id:%{public}d state:%{public}d, uniqueId: %{public}" PRIu64
805              "desiredPresentTimestamp: %{public}" PRId64 " isAotuTimestamp: %{public}d.",
806              id, ele.state, uniqueId_, ele.desiredPresentTimestamp, ele.isAutoTimestamp);
807          bufferState[ele.state] += 1;
808      }
809      std::string str = std::to_string(uniqueId_) +
810          ", Released: " + std::to_string(bufferState[BUFFER_STATE_RELEASED]) +
811          " Requested: " + std::to_string(bufferState[BUFFER_STATE_REQUESTED]) +
812          " Flushed: " + std::to_string(bufferState[BUFFER_STATE_FLUSHED]) +
813          " Acquired: " + std::to_string(bufferState[BUFFER_STATE_ACQUIRED]);
814      if (str.compare(acquireBufferStateStr_) != 0) {
815          acquireBufferStateStr_ = str;
816          BLOGE("there is no dirty buffer or no dirty buffer ready, uniqueId: %{public}s", str.c_str());
817      }
818  }
819  
AcquireBuffer(sptr<SurfaceBuffer> & buffer,sptr<SyncFence> & fence,int64_t & timestamp,std::vector<Rect> & damages)820  GSError BufferQueue::AcquireBuffer(sptr<SurfaceBuffer> &buffer,
821      sptr<SyncFence> &fence, int64_t &timestamp, std::vector<Rect> &damages)
822  {
823      SURFACE_TRACE_NAME_FMT("AcquireBuffer name: %s queueId: %" PRIu64, name_.c_str(), uniqueId_);
824      // dequeue from dirty list
825      std::lock_guard<std::mutex> lockGuard(mutex_);
826      GSError ret = PopFromDirtyList(buffer);
827      if (ret == GSERROR_OK) {
828          uint32_t sequence = buffer->GetSeqNum();
829          bufferQueueCache_[sequence].state = BUFFER_STATE_ACQUIRED;
830  
831          fence = bufferQueueCache_[sequence].fence;
832          timestamp = bufferQueueCache_[sequence].timestamp;
833          damages = bufferQueueCache_[sequence].damages;
834          SURFACE_TRACE_NAME_FMT("acquire buffer sequence: %u desiredPresentTimestamp: %" PRId64 " isAotuTimestamp: %d",
835              sequence, bufferQueueCache_[sequence].desiredPresentTimestamp,
836              bufferQueueCache_[sequence].isAutoTimestamp);
837          BLOGD("Success Buffer seq id: %{public}d AcquireFence:%{public}d, uniqueId: %{public}" PRIu64 ".",
838              sequence, fence->Get(), uniqueId_);
839      } else if (ret == GSERROR_NO_BUFFER) {
840          LogAndTraceAllBufferInBufferQueueCache();
841      }
842  
843      CountTrace(HITRACE_TAG_GRAPHIC_AGP, name_, static_cast<int32_t>(dirtyList_.size()));
844      return ret;
845  }
846  
AcquireBuffer(IConsumerSurface::AcquireBufferReturnValue & returnValue,int64_t expectPresentTimestamp,bool isUsingAutoTimestamp)847  GSError BufferQueue::AcquireBuffer(IConsumerSurface::AcquireBufferReturnValue &returnValue,
848                                     int64_t expectPresentTimestamp, bool isUsingAutoTimestamp)
849  {
850      SURFACE_TRACE_NAME_FMT("AcquireBuffer with PresentTimestamp name: %s queueId: %" PRIu64 " queueSize: %u"
851          "expectPresentTimestamp: %" PRId64, name_.c_str(), uniqueId_, queueSize_, expectPresentTimestamp);
852      if (isShared_ || expectPresentTimestamp <= 0) {
853          return AcquireBuffer(returnValue.buffer, returnValue.fence, returnValue.timestamp, returnValue.damages);
854      }
855      std::vector<BufferAndFence> dropBuffers;
856      {
857          std::lock_guard<std::mutex> lockGuard(mutex_);
858          std::list<uint32_t>::iterator frontSequence = dirtyList_.begin();
859          if (frontSequence == dirtyList_.end()) {
860              LogAndTraceAllBufferInBufferQueueCache();
861              return GSERROR_NO_BUFFER;
862          }
863          int64_t frontDesiredPresentTimestamp = bufferQueueCache_[*frontSequence].desiredPresentTimestamp;
864          bool frontIsAutoTimestamp = bufferQueueCache_[*frontSequence].isAutoTimestamp;
865          if (!frontIsAutoTimestamp && frontDesiredPresentTimestamp > expectPresentTimestamp
866              && frontDesiredPresentTimestamp - ONE_SECOND_TIMESTAMP <= expectPresentTimestamp) {
867              SURFACE_TRACE_NAME_FMT("Acquire no buffer ready");
868              LogAndTraceAllBufferInBufferQueueCache();
869              return GSERROR_NO_BUFFER_READY;
870          }
871          while (!(frontIsAutoTimestamp && !isUsingAutoTimestamp)
872              && frontDesiredPresentTimestamp <= expectPresentTimestamp) {
873              BufferElement& frontBufferElement = bufferQueueCache_[*frontSequence];
874              if (++frontSequence == dirtyList_.end()) {
875                  BLOGD("Buffer seq(%{public}d) is the last buffer, do acquire.", dirtyList_.front());
876                  break;
877              }
878              BufferElement& secondBufferElement = bufferQueueCache_[*frontSequence];
879              if ((secondBufferElement.isAutoTimestamp && !isUsingAutoTimestamp)
880                  || secondBufferElement.desiredPresentTimestamp > expectPresentTimestamp) {
881                  BLOGD("Next dirty buffer desiredPresentTimestamp: %{public}" PRId64 " not match expectPresentTimestamp"
882                      ": %{public}" PRId64 ".", secondBufferElement.desiredPresentTimestamp, expectPresentTimestamp);
883                  break;
884              }
885              SURFACE_TRACE_NAME_FMT("DropBuffer name: %s queueId: %" PRIu64 " ,buffer seq: %u , buffer "
886                  "desiredPresentTimestamp: %" PRId64 " acquire expectPresentTimestamp: %" PRId64, name_.c_str(),
887                  uniqueId_, frontBufferElement.buffer->GetSeqNum(), frontBufferElement.desiredPresentTimestamp,
888                  expectPresentTimestamp);
889              DropFirstDirtyBuffer(frontBufferElement, secondBufferElement, frontDesiredPresentTimestamp,
890                                   frontIsAutoTimestamp, dropBuffers);
891          }
892          if (!frontIsAutoTimestamp && !IsPresentTimestampReady(frontDesiredPresentTimestamp, expectPresentTimestamp)) {
893              SURFACE_TRACE_NAME_FMT("Acquire no buffer ready");
894              LogAndTraceAllBufferInBufferQueueCache();
895              return GSERROR_NO_BUFFER_READY;
896          }
897      }
898      ReleaseDropBuffers(dropBuffers);
899      return AcquireBuffer(returnValue.buffer, returnValue.fence, returnValue.timestamp, returnValue.damages);
900  }
901  
DropFirstDirtyBuffer(BufferElement & frontBufferElement,BufferElement & secondBufferElement,int64_t & frontDesiredPresentTimestamp,bool & frontIsAutoTimestamp,std::vector<BufferAndFence> & dropBuffers)902  void BufferQueue::DropFirstDirtyBuffer(BufferElement &frontBufferElement, BufferElement &secondBufferElement,
903                                         int64_t &frontDesiredPresentTimestamp, bool &frontIsAutoTimestamp,
904                                         std::vector<BufferAndFence> &dropBuffers)
905  {
906      dirtyList_.pop_front();
907      frontBufferElement.state = BUFFER_STATE_ACQUIRED;
908      dropBuffers.emplace_back(frontBufferElement.buffer, frontBufferElement.fence);
909      frontDesiredPresentTimestamp = secondBufferElement.desiredPresentTimestamp;
910      frontIsAutoTimestamp = secondBufferElement.isAutoTimestamp;
911  }
912  
ReleaseDropBuffers(std::vector<BufferAndFence> & dropBuffers)913  void BufferQueue::ReleaseDropBuffers(std::vector<BufferAndFence> &dropBuffers)
914  {
915      for (auto& dropBuffer : dropBuffers) {
916          auto ret = ReleaseBuffer(dropBuffer.first, dropBuffer.second);
917          if (ret != GSERROR_OK) {
918              BLOGE("DropBuffer failed, ret: %{public}d, sequeue: %{public}u, uniqueId: %{public}" PRIu64 ".",
919                  ret, dropBuffer.first->GetSeqNum(), uniqueId_);
920          }
921      }
922  }
923  
IsPresentTimestampReady(int64_t desiredPresentTimestamp,int64_t expectPresentTimestamp)924  bool BufferQueue::IsPresentTimestampReady(int64_t desiredPresentTimestamp, int64_t expectPresentTimestamp)
925  {
926      if (desiredPresentTimestamp <= expectPresentTimestamp) {
927          return true;
928      }
929      if (desiredPresentTimestamp - ONE_SECOND_TIMESTAMP > expectPresentTimestamp) {
930          return true;
931      }
932      return false;
933  }
934  
ListenerBufferReleasedCb(sptr<SurfaceBuffer> & buffer,const sptr<SyncFence> & fence)935  void BufferQueue::ListenerBufferReleasedCb(sptr<SurfaceBuffer> &buffer, const sptr<SyncFence> &fence)
936  {
937      {
938          std::lock_guard<std::mutex> lockGuard(onBufferReleaseMutex_);
939          if (onBufferRelease_ != nullptr) {
940              SURFACE_TRACE_NAME_FMT("OnBufferRelease_ sequence: %u", buffer->GetSeqNum());
941              sptr<SurfaceBuffer> buf = buffer;
942              (void)onBufferRelease_(buf);
943          }
944      }
945  
946      sptr<IProducerListener> listener;
947      {
948          std::lock_guard<std::mutex> lockGuard(producerListenerMutex_);
949          listener = producerListener_;
950      }
951  
952      if (listener != nullptr) {
953          SURFACE_TRACE_NAME_FMT("onBufferReleasedForProducer sequence: %u", buffer->GetSeqNum());
954          if (listener->OnBufferReleased() != GSERROR_OK) {
955              BLOGE("seq: %{public}u, OnBufferReleased faile, uniqueId: %{public}" PRIu64 ".",
956                  buffer->GetSeqNum(), uniqueId_);
957          }
958          if (listener->OnBufferReleasedWithFence(buffer, fence) != GSERROR_OK) {
959              BLOGE("seq: %{public}u, OnBufferReleasedWithFence failed, uniqueId: %{public}" PRIu64 ".",
960                  buffer->GetSeqNum(), uniqueId_);
961          }
962      }
963      std::lock_guard<std::mutex> lockGuard(mutex_);
964      OnBufferDeleteCbForHardwareThreadLocked(buffer);
965  }
966  
OnBufferDeleteCbForHardwareThreadLocked(const sptr<SurfaceBuffer> & buffer) const967  void BufferQueue::OnBufferDeleteCbForHardwareThreadLocked(const sptr<SurfaceBuffer> &buffer) const
968  {
969      if (onBufferDeleteForRSHardwareThread_ != nullptr) {
970          onBufferDeleteForRSHardwareThread_(buffer->GetSeqNum());
971      }
972  }
973  
ReleaseBuffer(sptr<SurfaceBuffer> & buffer,const sptr<SyncFence> & fence)974  GSError BufferQueue::ReleaseBuffer(sptr<SurfaceBuffer> &buffer, const sptr<SyncFence>& fence)
975  {
976      if (buffer == nullptr) {
977          return GSERROR_INVALID_ARGUMENTS;
978      }
979  
980      uint32_t sequence = buffer->GetSeqNum();
981      SURFACE_TRACE_NAME_FMT("ReleaseBuffer name: %s queueId: %" PRIu64 " seq: %u", name_.c_str(), uniqueId_, sequence);
982      {
983          std::lock_guard<std::mutex> lockGuard(mutex_);
984          if (bufferQueueCache_.find(sequence) == bufferQueueCache_.end()) {
985              SURFACE_TRACE_NAME_FMT("buffer not found in cache");
986              BLOGE("cache not find the buffer(%{public}u), uniqueId: %{public}" PRIu64 ".", sequence, uniqueId_);
987              OnBufferDeleteCbForHardwareThreadLocked(buffer);
988              return SURFACE_ERROR_BUFFER_NOT_INCACHE;
989          }
990  
991          if (isShared_ == false) {
992              const auto &state = bufferQueueCache_[sequence].state;
993              if (state != BUFFER_STATE_ACQUIRED && state != BUFFER_STATE_ATTACHED) {
994                  SURFACE_TRACE_NAME_FMT("invalid state: %u", state);
995                  BLOGD("invalid state: %{public}d, uniqueId: %{public}" PRIu64 ".", state, uniqueId_);
996                  return SURFACE_ERROR_BUFFER_STATE_INVALID;
997              }
998          }
999  
1000          bufferQueueCache_[sequence].state = BUFFER_STATE_RELEASED;
1001          bufferQueueCache_[sequence].fence = fence;
1002  
1003          if (bufferQueueCache_[sequence].isDeleting) {
1004              DeleteBufferInCache(sequence);
1005              BLOGD("Succ delete Buffer seq id: %{public}d, uniqueId: %{public}" PRIu64 ".", sequence, uniqueId_);
1006          } else {
1007              freeList_.push_back(sequence);
1008              BLOGD("Succ push Buffer seq id: %{public}d to free list, releaseFence: %{public}d,"
1009                  "uniqueId: %{public}" PRIu64 ".", sequence, fence->Get(), uniqueId_);
1010          }
1011          waitReqCon_.notify_all();
1012          waitAttachCon_.notify_all();
1013      }
1014      ListenerBufferReleasedCb(buffer, fence);
1015  
1016      return GSERROR_OK;
1017  }
1018  
AllocBuffer(sptr<SurfaceBuffer> & buffer,const BufferRequestConfig & config)1019  GSError BufferQueue::AllocBuffer(sptr<SurfaceBuffer> &buffer,
1020      const BufferRequestConfig &config)
1021  {
1022      sptr<SurfaceBuffer> bufferImpl = new SurfaceBufferImpl();
1023      uint32_t sequence = bufferImpl->GetSeqNum();
1024      SURFACE_TRACE_NAME_FMT("AllocBuffer config width: %d height: %d usage: %llu format: %d id: %u",
1025          config.width, config.height, config.usage, config.format, sequence);
1026  
1027      BufferRequestConfig updateConfig = config;
1028      updateConfig.usage |= defaultUsage_;
1029  
1030      GSError ret = bufferImpl->Alloc(updateConfig);
1031      if (ret != GSERROR_OK) {
1032          BLOGE("Alloc failed, sequence:%{public}u, ret:%{public}d, uniqueId: %{public}" PRIu64 ".",
1033              sequence, ret, uniqueId_);
1034          return SURFACE_ERROR_UNKOWN;
1035      }
1036  
1037      bufferImpl->SetSurfaceBufferScalingMode(scalingMode_);
1038      BufferElement ele = {
1039          .buffer = bufferImpl,
1040          .state = BUFFER_STATE_REQUESTED,
1041          .isDeleting = false,
1042          .config = config,
1043          .fence = SyncFence::InvalidFence(),
1044      };
1045  
1046      if (config.usage & BUFFER_USAGE_PROTECTED) {
1047          BLOGD("usage is BUFFER_USAGE_PROTECTED, uniqueId: %{public}" PRIu64 ".", uniqueId_);
1048          bufferQueueCache_[sequence] = ele;
1049          buffer = bufferImpl;
1050          return SURFACE_ERROR_OK;
1051      }
1052  
1053      ret = bufferImpl->Map();
1054      if (ret == GSERROR_OK) {
1055          BLOGD("Map Success, seq: %{public}d, uniqueId: %{public}" PRIu64 ".", sequence, uniqueId_);
1056          bufferQueueCache_[sequence] = ele;
1057          buffer = bufferImpl;
1058      } else {
1059          BLOGE("Map failed, seq:%{public}u, ret:%{public}d, uniqueId: %{public}" PRIu64 ".",
1060              sequence, ret, uniqueId_);
1061          return SURFACE_ERROR_UNKOWN;
1062      }
1063      return SURFACE_ERROR_OK;
1064  }
1065  
OnBufferDeleteForRS(uint32_t sequence)1066  void BufferQueue::OnBufferDeleteForRS(uint32_t sequence)
1067  {
1068      if (onBufferDeleteForRSMainThread_ != nullptr) {
1069          onBufferDeleteForRSMainThread_(sequence);
1070      }
1071      if (onBufferDeleteForRSHardwareThread_ != nullptr) {
1072          onBufferDeleteForRSHardwareThread_(sequence);
1073      }
1074  }
1075  
DeleteBufferInCache(uint32_t sequence)1076  void BufferQueue::DeleteBufferInCache(uint32_t sequence)
1077  {
1078      auto it = bufferQueueCache_.find(sequence);
1079      if (it != bufferQueueCache_.end()) {
1080          OnBufferDeleteForRS(sequence);
1081          BLOGD("DeleteBufferInCache seq: %{public}u, uniqueId: %{public}" PRIu64 ".", sequence, uniqueId_);
1082          bufferQueueCache_.erase(it);
1083          deletingList_.push_back(sequence);
1084      }
1085  }
1086  
GetQueueSize()1087  uint32_t BufferQueue::GetQueueSize()
1088  {
1089      return queueSize_;
1090  }
1091  
DeleteBuffersLocked(int32_t count)1092  void BufferQueue::DeleteBuffersLocked(int32_t count)
1093  {
1094      SURFACE_TRACE_NAME_FMT("DeleteBuffersLocked count: %d", count);
1095      if (count <= 0) {
1096          return;
1097      }
1098  
1099      while (!freeList_.empty()) {
1100          DeleteBufferInCache(freeList_.front());
1101          freeList_.pop_front();
1102          count--;
1103          if (count <= 0) {
1104              return;
1105          }
1106      }
1107  
1108      while (!dirtyList_.empty()) {
1109          DeleteBufferInCache(dirtyList_.front());
1110          dirtyList_.pop_front();
1111          count--;
1112          if (count <= 0) {
1113              return;
1114          }
1115      }
1116  
1117      for (auto&& ele : bufferQueueCache_) {
1118          ele.second.isDeleting = true;
1119          // we don't have to do anything
1120          count--;
1121          if (count <= 0) {
1122              break;
1123          }
1124      }
1125  }
1126  
AttachBufferUpdateStatus(std::unique_lock<std::mutex> & lock,uint32_t sequence,int32_t timeOut)1127  GSError BufferQueue::AttachBufferUpdateStatus(std::unique_lock<std::mutex> &lock, uint32_t sequence, int32_t timeOut)
1128  {
1129      BufferState state = bufferQueueCache_[sequence].state;
1130      if (state == BUFFER_STATE_RELEASED) {
1131          bufferQueueCache_[sequence].state = BUFFER_STATE_ATTACHED;
1132      } else {
1133          waitAttachCon_.wait_for(lock, std::chrono::milliseconds(timeOut),
1134              [this, sequence]() { return (bufferQueueCache_[sequence].state == BUFFER_STATE_RELEASED); });
1135          if (bufferQueueCache_[sequence].state == BUFFER_STATE_RELEASED) {
1136              bufferQueueCache_[sequence].state = BUFFER_STATE_ATTACHED;
1137          } else {
1138              BLOGN_FAILURE_RET(SURFACE_ERROR_BUFFER_STATE_INVALID);
1139          }
1140      }
1141  
1142      for (auto iter = freeList_.begin(); iter != freeList_.end(); iter++) {
1143          if (sequence == *iter) {
1144              freeList_.erase(iter);
1145              break;
1146          }
1147      }
1148      return GSERROR_OK;
1149  }
1150  
AttachBufferUpdateBufferInfo(sptr<SurfaceBuffer> & buffer,bool needMap)1151  void BufferQueue::AttachBufferUpdateBufferInfo(sptr<SurfaceBuffer>& buffer, bool needMap)
1152  {
1153      if (needMap) {
1154          buffer->Map();
1155      }
1156      buffer->SetSurfaceBufferWidth(buffer->GetWidth());
1157      buffer->SetSurfaceBufferHeight(buffer->GetHeight());
1158  }
1159  
AttachBufferToQueueLocked(sptr<SurfaceBuffer> buffer,InvokerType invokerType,bool needMap)1160  GSError BufferQueue::AttachBufferToQueueLocked(sptr<SurfaceBuffer> buffer, InvokerType invokerType, bool needMap)
1161  {
1162      uint32_t sequence = buffer->GetSeqNum();
1163      if (GetUsedSize() >= queueSize_) {
1164          BLOGE("seq: %{public}u, buffer queue size:%{public}u, used size:%{public}u,"
1165              "uniqueId: %{public}" PRIu64 ".", sequence, queueSize_, GetUsedSize(), uniqueId_);
1166          return SURFACE_ERROR_BUFFER_QUEUE_FULL;
1167      }
1168      if (bufferQueueCache_.find(sequence) != bufferQueueCache_.end()) {
1169          BLOGE("seq: %{public}u, buffer is already in cache, uniqueId: %{public}" PRIu64 ".",
1170              sequence, uniqueId_);
1171          return SURFACE_ERROR_BUFFER_IS_INCACHE;
1172      }
1173      buffer->SetSurfaceBufferScalingMode(scalingMode_);
1174      BufferElement ele;
1175      ele = {
1176          .buffer = buffer,
1177          .isDeleting = false,
1178          .config = buffer->GetBufferRequestConfig(),
1179          .fence = SyncFence::InvalidFence(),
1180      };
1181      if (invokerType == InvokerType::PRODUCER_INVOKER) {
1182          ele.state = BUFFER_STATE_REQUESTED;
1183      } else {
1184          ele.state = BUFFER_STATE_ACQUIRED;
1185      }
1186      AttachBufferUpdateBufferInfo(buffer, needMap);
1187      bufferQueueCache_[sequence] = ele;
1188      return GSERROR_OK;
1189  }
1190  
AttachBufferToQueue(sptr<SurfaceBuffer> buffer,InvokerType invokerType)1191  GSError BufferQueue::AttachBufferToQueue(sptr<SurfaceBuffer> buffer, InvokerType invokerType)
1192  {
1193      SURFACE_TRACE_NAME_FMT("AttachBufferToQueue name: %s queueId: %" PRIu64 " sequence: %u invokerType%u",
1194          name_.c_str(), uniqueId_, buffer->GetSeqNum(), invokerType);
1195      std::lock_guard<std::mutex> lockGuard(mutex_);
1196      return AttachBufferToQueueLocked(buffer, invokerType, true);
1197  }
1198  
DetachBufferFromQueueLocked(uint32_t sequence,InvokerType invokerType)1199  GSError BufferQueue::DetachBufferFromQueueLocked(uint32_t sequence, InvokerType invokerType)
1200  {
1201      if (bufferQueueCache_.find(sequence) == bufferQueueCache_.end()) {
1202          BLOGE("seq: %{public}u, not find in cache, uniqueId: %{public}" PRIu64 ".",
1203              sequence, uniqueId_);
1204          return SURFACE_ERROR_BUFFER_NOT_INCACHE;
1205      }
1206      if (invokerType == InvokerType::PRODUCER_INVOKER) {
1207          if (bufferQueueCache_[sequence].state != BUFFER_STATE_REQUESTED) {
1208              BLOGE("seq: %{public}u, state: %{public}d, uniqueId: %{public}" PRIu64 ".",
1209                  sequence, bufferQueueCache_[sequence].state, uniqueId_);
1210              return SURFACE_ERROR_BUFFER_STATE_INVALID;
1211          }
1212          OnBufferDeleteForRS(sequence);
1213          bufferQueueCache_.erase(sequence);
1214      } else {
1215          if (bufferQueueCache_[sequence].state != BUFFER_STATE_ACQUIRED) {
1216              BLOGE("seq: %{public}u, state: %{public}d, uniqueId: %{public}" PRIu64 ".",
1217                  sequence, bufferQueueCache_[sequence].state, uniqueId_);
1218              return SURFACE_ERROR_BUFFER_STATE_INVALID;
1219          }
1220          DeleteBufferInCache(sequence);
1221      }
1222      return GSERROR_OK;
1223  }
1224  
DetachBufferFromQueue(sptr<SurfaceBuffer> buffer,InvokerType invokerType)1225  GSError BufferQueue::DetachBufferFromQueue(sptr<SurfaceBuffer> buffer, InvokerType invokerType)
1226  {
1227      SURFACE_TRACE_NAME_FMT("DetachBufferFromQueue name: %s queueId: %" PRIu64 " sequence: %u invokerType%u",
1228          name_.c_str(), uniqueId_, buffer->GetSeqNum(), invokerType);
1229      std::unique_lock<std::mutex> lock(mutex_);
1230      uint32_t sequence = buffer->GetSeqNum();
1231      auto ret = DetachBufferFromQueueLocked(sequence, invokerType);
1232      if (ret != GSERROR_OK) {
1233          return ret;
1234      }
1235      return GSERROR_OK;
1236  }
1237  
AttachBuffer(sptr<SurfaceBuffer> & buffer,int32_t timeOut)1238  GSError BufferQueue::AttachBuffer(sptr<SurfaceBuffer> &buffer, int32_t timeOut)
1239  {
1240      SURFACE_TRACE_NAME_FMT("%s", __func__);
1241      {
1242          std::lock_guard<std::mutex> lockGuard(mutex_);
1243          if (!GetStatusLocked()) {
1244              BLOGN_FAILURE_RET(GSERROR_NO_CONSUMER);
1245          }
1246      }
1247      {
1248          std::lock_guard<std::mutex> lockGuard(listenerMutex_);
1249          if (listener_ == nullptr && listenerClazz_ == nullptr) {
1250              BLOGN_FAILURE_RET(SURFACE_ERROR_CONSUMER_UNREGISTER_LISTENER);
1251          }
1252      }
1253  
1254      if (isShared_ || buffer == nullptr) {
1255          BLOGN_FAILURE_RET(GSERROR_INVALID_OPERATING);
1256      }
1257  
1258      uint32_t sequence = buffer->GetSeqNum();
1259      std::unique_lock<std::mutex> lock(mutex_);
1260      if (bufferQueueCache_.find(sequence) != bufferQueueCache_.end()) {
1261          return AttachBufferUpdateStatus(lock, sequence, timeOut);
1262      }
1263  
1264      buffer->SetSurfaceBufferScalingMode(scalingMode_);
1265      BufferElement ele = {
1266          .buffer = buffer,
1267          .state = BUFFER_STATE_ATTACHED,
1268          .config = {
1269              .width = buffer->GetWidth(), .height = buffer->GetHeight(), .strideAlignment = 0x8,
1270              .format = buffer->GetFormat(), .usage = buffer->GetUsage(), .timeout = timeOut,
1271          },
1272          .damages = { { .w = buffer->GetWidth(), .h = buffer->GetHeight(), } },
1273      };
1274      AttachBufferUpdateBufferInfo(buffer, true);
1275      int32_t usedSize = static_cast<int32_t>(GetUsedSize());
1276      int32_t queueSize = static_cast<int32_t>(GetQueueSize());
1277      if (usedSize >= queueSize) {
1278          int32_t freeSize = static_cast<int32_t>(dirtyList_.size() + freeList_.size());
1279          if (freeSize >= usedSize - queueSize + 1) {
1280              DeleteBuffersLocked(usedSize - queueSize + 1);
1281              bufferQueueCache_[sequence] = ele;
1282              BLOGD("AttachBuffer release seq: %{public}d, uniqueId: %{public}" PRIu64 ".", sequence, uniqueId_);
1283              return GSERROR_OK;
1284          } else {
1285              BLOGN_FAILURE_RET(GSERROR_OUT_OF_RANGE);
1286          }
1287      } else {
1288          bufferQueueCache_[sequence] = ele;
1289          BLOGD("AttachBuffer no release seq: %{public}d, uniqueId: %{public}" PRIu64 ".", sequence, uniqueId_);
1290          return GSERROR_OK;
1291      }
1292  }
1293  
DetachBuffer(sptr<SurfaceBuffer> & buffer)1294  GSError BufferQueue::DetachBuffer(sptr<SurfaceBuffer> &buffer)
1295  {
1296      SURFACE_TRACE_NAME_FMT("%s", __func__);
1297      if (isShared_) {
1298          BLOGN_FAILURE_RET(GSERROR_INVALID_OPERATING);
1299      }
1300  
1301      if (buffer == nullptr) {
1302          BLOGN_FAILURE_RET(GSERROR_INVALID_ARGUMENTS);
1303      }
1304  
1305      std::lock_guard<std::mutex> lockGuard(mutex_);
1306      uint32_t sequence = buffer->GetSeqNum();
1307      if (bufferQueueCache_.find(sequence) == bufferQueueCache_.end()) {
1308          return GSERROR_NO_ENTRY;
1309      }
1310  
1311      if (bufferQueueCache_[sequence].state == BUFFER_STATE_REQUESTED) {
1312          BLOGD("DetachBuffer requested seq: %{public}d, uniqueId: %{public}" PRIu64 ".", sequence, uniqueId_);
1313      } else if (bufferQueueCache_[sequence].state == BUFFER_STATE_ACQUIRED) {
1314          BLOGD("DetachBuffer acquired seq: %{public}d, uniqueId: %{public}" PRIu64 ".", sequence, uniqueId_);
1315      } else {
1316          BLOGE("DetachBuffer invalid state: %{public}d, seq: %{public}u, uniqueId: %{public}" PRIu64 ".",
1317              bufferQueueCache_[sequence].state, sequence, uniqueId_);
1318          return GSERROR_NO_ENTRY;
1319      }
1320      OnBufferDeleteForRS(sequence);
1321      bufferQueueCache_.erase(sequence);
1322      return GSERROR_OK;
1323  }
1324  
RegisterSurfaceDelegator(sptr<IRemoteObject> client,sptr<Surface> cSurface)1325  GSError BufferQueue::RegisterSurfaceDelegator(sptr<IRemoteObject> client, sptr<Surface> cSurface)
1326  {
1327      sptr<ConsumerSurfaceDelegator> surfaceDelegator = ConsumerSurfaceDelegator::Create();
1328      if (surfaceDelegator == nullptr) {
1329          BLOGE("Failed to register consumer delegator because the surface delegator is nullptr");
1330          return GSERROR_INVALID_ARGUMENTS;
1331      }
1332      if (!surfaceDelegator->SetClient(client)) {
1333          BLOGE("Failed to set client");
1334          return GSERROR_INVALID_ARGUMENTS;
1335      }
1336      if (!surfaceDelegator->SetBufferQueue(this)) {
1337          BLOGE("Failed to set bufferqueue");
1338          return GSERROR_INVALID_ARGUMENTS;
1339      }
1340  
1341      surfaceDelegator->SetSurface(cSurface);
1342      wpCSurfaceDelegator_ = surfaceDelegator;
1343      return GSERROR_OK;
1344  }
1345  
SetQueueSize(uint32_t queueSize)1346  GSError BufferQueue::SetQueueSize(uint32_t queueSize)
1347  {
1348      if (isShared_ == true && queueSize != 1) {
1349          BLOGW("shared queue size: %{public}u, uniqueId: %{public}" PRIu64 ".", queueSize, uniqueId_);
1350          return GSERROR_INVALID_ARGUMENTS;
1351      }
1352  
1353      if (queueSize == 0) {
1354          BLOGW("queue size: %{public}u, uniqueId: %{public}" PRIu64 ".", queueSize, uniqueId_);
1355          return GSERROR_INVALID_ARGUMENTS;
1356      }
1357  
1358      if (queueSize > SURFACE_MAX_QUEUE_SIZE) {
1359          BLOGW("invalid queueSize: %{public}u, uniqueId: %{public}" PRIu64 ".",
1360              queueSize, uniqueId_);
1361          return GSERROR_INVALID_ARGUMENTS;
1362      }
1363  
1364      std::lock_guard<std::mutex> lockGuard(mutex_);
1365      if (queueSize_ > queueSize) {
1366          DeleteBuffersLocked(queueSize_ - queueSize);
1367      }
1368      // if increase the queue size, try to wakeup the blocked thread
1369      if (queueSize > queueSize_) {
1370          queueSize_ = queueSize;
1371          waitReqCon_.notify_all();
1372      } else {
1373          queueSize_ = queueSize;
1374      }
1375  
1376      BLOGD("queue size: %{public}d, uniqueId: %{public}" PRIu64 ".", queueSize_, uniqueId_);
1377      return GSERROR_OK;
1378  }
1379  
GetName(std::string & name)1380  GSError BufferQueue::GetName(std::string &name)
1381  {
1382      name = name_;
1383      return GSERROR_OK;
1384  }
1385  
RegisterConsumerListener(sptr<IBufferConsumerListener> & listener)1386  GSError BufferQueue::RegisterConsumerListener(sptr<IBufferConsumerListener> &listener)
1387  {
1388      std::lock_guard<std::mutex> lockGuard(listenerMutex_);
1389      listener_ = listener;
1390      return GSERROR_OK;
1391  }
1392  
RegisterConsumerListener(IBufferConsumerListenerClazz * listener)1393  GSError BufferQueue::RegisterConsumerListener(IBufferConsumerListenerClazz *listener)
1394  {
1395      std::lock_guard<std::mutex> lockGuard(listenerMutex_);
1396      listenerClazz_ = listener;
1397      return GSERROR_OK;
1398  }
1399  
UnregisterConsumerListener()1400  GSError BufferQueue::UnregisterConsumerListener()
1401  {
1402      std::lock_guard<std::mutex> lockGuard(listenerMutex_);
1403      listener_ = nullptr;
1404      listenerClazz_ = nullptr;
1405      return GSERROR_OK;
1406  }
1407  
RegisterReleaseListener(OnReleaseFunc func)1408  GSError BufferQueue::RegisterReleaseListener(OnReleaseFunc func)
1409  {
1410      std::lock_guard<std::mutex> lockGuard(onBufferReleaseMutex_);
1411      onBufferRelease_ = func;
1412      return GSERROR_OK;
1413  }
1414  
RegisterProducerReleaseListener(sptr<IProducerListener> listener)1415  GSError BufferQueue::RegisterProducerReleaseListener(sptr<IProducerListener> listener)
1416  {
1417      std::lock_guard<std::mutex> lockGuard(producerListenerMutex_);
1418      producerListener_ = listener;
1419      return GSERROR_OK;
1420  }
1421  
UnRegisterProducerReleaseListener()1422  GSError BufferQueue::UnRegisterProducerReleaseListener()
1423  {
1424      std::lock_guard<std::mutex> lockGuard(producerListenerMutex_);
1425      producerListener_ = nullptr;
1426      return GSERROR_OK;
1427  }
1428  
RegisterDeleteBufferListener(OnDeleteBufferFunc func,bool isForUniRedraw)1429  GSError BufferQueue::RegisterDeleteBufferListener(OnDeleteBufferFunc func, bool isForUniRedraw)
1430  {
1431      std::lock_guard<std::mutex> lockGuard(mutex_);
1432      if (isForUniRedraw) {
1433          if (onBufferDeleteForRSHardwareThread_ != nullptr) {
1434              return GSERROR_OK;
1435          }
1436          onBufferDeleteForRSHardwareThread_ = func;
1437      } else {
1438          if (onBufferDeleteForRSMainThread_ != nullptr) {
1439              return GSERROR_OK;
1440          }
1441          onBufferDeleteForRSMainThread_ = func;
1442      }
1443      return GSERROR_OK;
1444  }
1445  
SetDefaultWidthAndHeight(int32_t width,int32_t height)1446  GSError BufferQueue::SetDefaultWidthAndHeight(int32_t width, int32_t height)
1447  {
1448      if (width <= 0) {
1449          BLOGW("width is %{public}d, uniqueId: %{public}" PRIu64 ".", width, uniqueId_);
1450          return GSERROR_INVALID_ARGUMENTS;
1451      }
1452  
1453      if (height <= 0) {
1454          BLOGW("height is %{public}d, uniqueId: %{public}" PRIu64 ".", height, uniqueId_);
1455          return GSERROR_INVALID_ARGUMENTS;
1456      }
1457      BLOGD("SetDefaultWidthAndHeight(width: %{public}d, height: %{public}d), uniqueId: %{public}" PRIu64 ".",
1458          width, height, uniqueId_);
1459      std::lock_guard<std::mutex> lockGuard(mutex_);
1460      defaultWidth_ = width;
1461      defaultHeight_ = height;
1462      return GSERROR_OK;
1463  }
1464  
GetDefaultWidth()1465  int32_t BufferQueue::GetDefaultWidth()
1466  {
1467      std::lock_guard<std::mutex> lockGuard(mutex_);
1468      return defaultWidth_;
1469  }
1470  
GetDefaultHeight()1471  int32_t BufferQueue::GetDefaultHeight()
1472  {
1473      std::lock_guard<std::mutex> lockGuard(mutex_);
1474      return defaultHeight_;
1475  }
1476  
SetDefaultUsage(uint64_t usage)1477  GSError BufferQueue::SetDefaultUsage(uint64_t usage)
1478  {
1479      BLOGD("SetDefaultUsage(usage: %{public}" PRIu64 ") , uniqueId: %{public}" PRIu64 ".", usage, uniqueId_);
1480      std::lock_guard<std::mutex> lockGuard(mutex_);
1481      defaultUsage_ = usage;
1482      return GSERROR_OK;
1483  }
1484  
GetDefaultUsage()1485  uint64_t BufferQueue::GetDefaultUsage()
1486  {
1487      std::lock_guard<std::mutex> lockGuard(mutex_);
1488      return defaultUsage_;
1489  }
1490  
ClearLocked()1491  void BufferQueue::ClearLocked()
1492  {
1493      for (auto &[id, _] : bufferQueueCache_) {
1494          OnBufferDeleteForRS(id);
1495      }
1496      bufferQueueCache_.clear();
1497      freeList_.clear();
1498      dirtyList_.clear();
1499      deletingList_.clear();
1500  }
1501  
GoBackground()1502  GSError BufferQueue::GoBackground()
1503  {
1504      BLOGD("GoBackground, uniqueId: %{public}" PRIu64 ".", uniqueId_);
1505      sptr<IBufferConsumerListener> listener;
1506      IBufferConsumerListenerClazz *listenerClazz;
1507      {
1508          std::lock_guard<std::mutex> lockGuard(listenerMutex_);
1509          listener = listener_;
1510          listenerClazz = listenerClazz_;
1511      }
1512      if (listener != nullptr) {
1513          SURFACE_TRACE_NAME_FMT("OnGoBackground name: %s queueId: %" PRIu64, name_.c_str(), uniqueId_);
1514          listener->OnGoBackground();
1515      } else if (listenerClazz != nullptr) {
1516          SURFACE_TRACE_NAME_FMT("OnGoBackground name: %s queueId: %" PRIu64, name_.c_str(), uniqueId_);
1517          listenerClazz->OnGoBackground();
1518      }
1519      std::lock_guard<std::mutex> lockGuard(mutex_);
1520      ClearLocked();
1521      waitReqCon_.notify_all();
1522      SetProducerCacheCleanFlagLocked(false);
1523      return GSERROR_OK;
1524  }
1525  
CleanCache(bool cleanAll)1526  GSError BufferQueue::CleanCache(bool cleanAll)
1527  {
1528      sptr<IBufferConsumerListener> listener;
1529      IBufferConsumerListenerClazz *listenerClazz;
1530      {
1531          std::lock_guard<std::mutex> lockGuard(listenerMutex_);
1532          listener = listener_;
1533          listenerClazz = listenerClazz_;
1534      }
1535      if (cleanAll) {
1536          if (listener != nullptr) {
1537              SURFACE_TRACE_NAME_FMT("OnGoBackground name: %s queueId: %" PRIu64, name_.c_str(), uniqueId_);
1538              listener->OnGoBackground();
1539          } else if (listenerClazz != nullptr) {
1540              SURFACE_TRACE_NAME_FMT("OnGoBackground name: %s queueId: %" PRIu64, name_.c_str(), uniqueId_);
1541              listenerClazz->OnGoBackground();
1542          }
1543      } else {
1544          if (listener != nullptr) {
1545              SURFACE_TRACE_NAME_FMT("OnCleanCache name: %s queueId: %" PRIu64, name_.c_str(), uniqueId_);
1546              listener->OnCleanCache();
1547          } else if (listenerClazz != nullptr) {
1548              SURFACE_TRACE_NAME_FMT("OnCleanCache name: %s queueId: %" PRIu64, name_.c_str(), uniqueId_);
1549              listenerClazz->OnCleanCache();
1550          }
1551      }
1552      std::lock_guard<std::mutex> lockGuard(mutex_);
1553      ClearLocked();
1554      waitReqCon_.notify_all();
1555      return GSERROR_OK;
1556  }
1557  
OnConsumerDied()1558  GSError BufferQueue::OnConsumerDied()
1559  {
1560      std::lock_guard<std::mutex> lockGuard(mutex_);
1561      ClearLocked();
1562      waitReqCon_.notify_all();
1563      return GSERROR_OK;
1564  }
1565  
IsSurfaceBufferInCache(uint32_t seqNum,bool & isInCache)1566  GSError BufferQueue::IsSurfaceBufferInCache(uint32_t seqNum, bool &isInCache)
1567  {
1568      std::unique_lock<std::mutex> lock(mutex_);
1569      if (bufferQueueCache_.find(seqNum) != bufferQueueCache_.end()) {
1570          isInCache = true;
1571      } else {
1572          isInCache = false;
1573      }
1574      return GSERROR_OK;
1575  }
1576  
GetUniqueId() const1577  uint64_t BufferQueue::GetUniqueId() const
1578  {
1579      std::unique_lock<std::mutex> lock(mutex_);
1580      return uniqueId_;
1581  }
1582  
SetTransform(GraphicTransformType transform)1583  GSError BufferQueue::SetTransform(GraphicTransformType transform)
1584  {
1585      {
1586          std::unique_lock<std::mutex> lock(mutex_);
1587          if (transform_ == transform) {
1588              return GSERROR_OK;
1589          }
1590  
1591          transform_ = transform;
1592      }
1593      sptr<IBufferConsumerListener> listener;
1594      IBufferConsumerListenerClazz *listenerClazz;
1595      {
1596          std::lock_guard<std::mutex> lockGuard(listenerMutex_);
1597          listener = listener_;
1598          listenerClazz = listenerClazz_;
1599      }
1600      if (listener != nullptr) {
1601          SURFACE_TRACE_NAME_FMT("OnTransformChange transform: %u", transform);
1602          listener->OnTransformChange();
1603      } else if (listenerClazz != nullptr) {
1604          SURFACE_TRACE_NAME_FMT("OnTransformChange transform: %u", transform);
1605          listenerClazz->OnTransformChange();
1606      }
1607      return GSERROR_OK;
1608  }
1609  
GetTransform() const1610  GraphicTransformType BufferQueue::GetTransform() const
1611  {
1612      std::unique_lock<std::mutex> lock(mutex_);
1613      return transform_;
1614  }
1615  
SetTransformHint(GraphicTransformType transformHint)1616  GSError BufferQueue::SetTransformHint(GraphicTransformType transformHint)
1617  {
1618      std::unique_lock<std::mutex> lock(mutex_);
1619      transformHint_ = transformHint;
1620      return GSERROR_OK;
1621  }
1622  
GetTransformHint() const1623  GraphicTransformType BufferQueue::GetTransformHint() const
1624  {
1625      std::unique_lock<std::mutex> lock(mutex_);
1626      return transformHint_;
1627  }
1628  
SetSurfaceSourceType(OHSurfaceSource sourceType)1629  GSError BufferQueue::SetSurfaceSourceType(OHSurfaceSource sourceType)
1630  {
1631      std::unique_lock<std::mutex> lock(mutex_);
1632      sourceType_ = sourceType;
1633      return GSERROR_OK;
1634  }
1635  
GetSurfaceSourceType() const1636  OHSurfaceSource BufferQueue::GetSurfaceSourceType() const
1637  {
1638      std::unique_lock<std::mutex> lock(mutex_);
1639      return sourceType_;
1640  }
1641  
SetHdrWhitePointBrightness(float brightness)1642  GSError BufferQueue::SetHdrWhitePointBrightness(float brightness)
1643  {
1644      std::unique_lock<std::mutex> lock(mutex_);
1645      hdrWhitePointBrightness_ = brightness;
1646      return GSERROR_OK;
1647  }
1648  
SetSdrWhitePointBrightness(float brightness)1649  GSError BufferQueue::SetSdrWhitePointBrightness(float brightness)
1650  {
1651      std::unique_lock<std::mutex> lock(mutex_);
1652      sdrWhitePointBrightness_ = brightness;
1653      return GSERROR_OK;
1654  }
1655  
GetHdrWhitePointBrightness() const1656  float BufferQueue::GetHdrWhitePointBrightness() const
1657  {
1658      std::unique_lock<std::mutex> lock(mutex_);
1659      return hdrWhitePointBrightness_;
1660  }
1661  
GetSdrWhitePointBrightness() const1662  float BufferQueue::GetSdrWhitePointBrightness() const
1663  {
1664      std::unique_lock<std::mutex> lock(mutex_);
1665      return sdrWhitePointBrightness_;
1666  }
1667  
SetSurfaceAppFrameworkType(std::string appFrameworkType)1668  GSError BufferQueue::SetSurfaceAppFrameworkType(std::string appFrameworkType)
1669  {
1670      if (appFrameworkType.empty()) {
1671          return GSERROR_NO_ENTRY;
1672      }
1673      if (appFrameworkType.size() > MAXIMUM_LENGTH_OF_APP_FRAMEWORK) {
1674          return GSERROR_OUT_OF_RANGE;
1675      }
1676      std::unique_lock<std::mutex> lock(mutex_);
1677      appFrameworkType_ = appFrameworkType;
1678      return GSERROR_OK;
1679  }
1680  
GetSurfaceAppFrameworkType() const1681  std::string BufferQueue::GetSurfaceAppFrameworkType() const
1682  {
1683      std::unique_lock<std::mutex> lock(mutex_);
1684      return appFrameworkType_;
1685  }
1686  
IsSupportedAlloc(const std::vector<BufferVerifyAllocInfo> & infos,std::vector<bool> & supporteds) const1687  GSError BufferQueue::IsSupportedAlloc(const std::vector<BufferVerifyAllocInfo> &infos,
1688                                        std::vector<bool> &supporteds) const
1689  {
1690      supporteds.clear();
1691      for (uint32_t index = 0; index < infos.size(); index++) {
1692          if (infos[index].format == GRAPHIC_PIXEL_FMT_RGBA_8888 ||
1693              infos[index].format == GRAPHIC_PIXEL_FMT_YCRCB_420_SP) {
1694              supporteds.push_back(true);
1695          } else {
1696              supporteds.push_back(false);
1697          }
1698      }
1699      return GSERROR_OK;
1700  }
1701  
SetBufferHold(bool hold)1702  GSError BufferQueue::SetBufferHold(bool hold)
1703  {
1704      std::unique_lock<std::mutex> lock(mutex_);
1705      isBufferHold_ = hold;
1706      return GSERROR_OK;
1707  }
1708  
SetScalingMode(uint32_t sequence,ScalingMode scalingMode)1709  GSError BufferQueue::SetScalingMode(uint32_t sequence, ScalingMode scalingMode)
1710  {
1711      std::lock_guard<std::mutex> lockGuard(mutex_);
1712      if (bufferQueueCache_.find(sequence) == bufferQueueCache_.end()) {
1713          return GSERROR_NO_ENTRY;
1714      }
1715      bufferQueueCache_[sequence].buffer->SetSurfaceBufferScalingMode(scalingMode);
1716      return GSERROR_OK;
1717  }
1718  
SetScalingMode(ScalingMode scalingMode)1719  GSError BufferQueue::SetScalingMode(ScalingMode scalingMode)
1720  {
1721      std::lock_guard<std::mutex> lockGuard(mutex_);
1722      for (auto it = bufferQueueCache_.begin(); it != bufferQueueCache_.end(); it++) {
1723          it->second.buffer->SetSurfaceBufferScalingMode(scalingMode);
1724      }
1725      scalingMode_ = scalingMode;
1726      return GSERROR_OK;
1727  }
1728  
GetScalingMode(uint32_t sequence,ScalingMode & scalingMode)1729  GSError BufferQueue::GetScalingMode(uint32_t sequence, ScalingMode &scalingMode)
1730  {
1731      std::lock_guard<std::mutex> lockGuard(mutex_);
1732      if (bufferQueueCache_.find(sequence) == bufferQueueCache_.end()) {
1733          return GSERROR_NO_ENTRY;
1734      }
1735      scalingMode = bufferQueueCache_.at(sequence).buffer->GetSurfaceBufferScalingMode();
1736      return GSERROR_OK;
1737  }
1738  
SetMetaData(uint32_t sequence,const std::vector<GraphicHDRMetaData> & metaData)1739  GSError BufferQueue::SetMetaData(uint32_t sequence, const std::vector<GraphicHDRMetaData> &metaData)
1740  {
1741      std::lock_guard<std::mutex> lockGuard(mutex_);
1742      if (metaData.size() == 0) {
1743          BLOGW("metaData size is 0, uniqueId: %{public}" PRIu64 ".", uniqueId_);
1744          return GSERROR_INVALID_ARGUMENTS;
1745      }
1746      if (bufferQueueCache_.find(sequence) == bufferQueueCache_.end()) {
1747          return GSERROR_NO_ENTRY;
1748      }
1749      bufferQueueCache_[sequence].metaData.clear();
1750      bufferQueueCache_[sequence].metaData = metaData;
1751      bufferQueueCache_[sequence].hdrMetaDataType = HDRMetaDataType::HDR_META_DATA;
1752      return GSERROR_OK;
1753  }
1754  
SetMetaDataSet(uint32_t sequence,GraphicHDRMetadataKey key,const std::vector<uint8_t> & metaData)1755  GSError BufferQueue::SetMetaDataSet(uint32_t sequence, GraphicHDRMetadataKey key,
1756                                      const std::vector<uint8_t> &metaData)
1757  {
1758      std::lock_guard<std::mutex> lockGuard(mutex_);
1759      if (key < GraphicHDRMetadataKey::GRAPHIC_MATAKEY_RED_PRIMARY_X ||
1760          key > GraphicHDRMetadataKey::GRAPHIC_MATAKEY_HDR_VIVID) {
1761          BLOGW("key is %{public}d, uniqueId: %{public}" PRIu64 ".", key, uniqueId_);
1762          return GSERROR_INVALID_ARGUMENTS;
1763      }
1764      if (metaData.size() == 0) {
1765          BLOGW("metaData size is 0, uniqueId: %{public}" PRIu64 ".", uniqueId_);
1766          return GSERROR_INVALID_ARGUMENTS;
1767      }
1768      if (bufferQueueCache_.find(sequence) == bufferQueueCache_.end()) {
1769          return GSERROR_NO_ENTRY;
1770      }
1771      bufferQueueCache_[sequence].metaDataSet.clear();
1772      bufferQueueCache_[sequence].key = key;
1773      bufferQueueCache_[sequence].metaDataSet = metaData;
1774      bufferQueueCache_[sequence].hdrMetaDataType = HDRMetaDataType::HDR_META_DATA_SET;
1775      return GSERROR_OK;
1776  }
1777  
QueryMetaDataType(uint32_t sequence,HDRMetaDataType & type)1778  GSError BufferQueue::QueryMetaDataType(uint32_t sequence, HDRMetaDataType &type)
1779  {
1780      std::lock_guard<std::mutex> lockGuard(mutex_);
1781      if (bufferQueueCache_.find(sequence) == bufferQueueCache_.end()) {
1782          return GSERROR_NO_ENTRY;
1783      }
1784      type = bufferQueueCache_.at(sequence).hdrMetaDataType;
1785      return GSERROR_OK;
1786  }
1787  
GetMetaData(uint32_t sequence,std::vector<GraphicHDRMetaData> & metaData)1788  GSError BufferQueue::GetMetaData(uint32_t sequence, std::vector<GraphicHDRMetaData> &metaData)
1789  {
1790      std::lock_guard<std::mutex> lockGuard(mutex_);
1791      if (bufferQueueCache_.find(sequence) == bufferQueueCache_.end()) {
1792          return GSERROR_NO_ENTRY;
1793      }
1794      metaData.clear();
1795      metaData = bufferQueueCache_.at(sequence).metaData;
1796      return GSERROR_OK;
1797  }
1798  
GetMetaDataSet(uint32_t sequence,GraphicHDRMetadataKey & key,std::vector<uint8_t> & metaData)1799  GSError BufferQueue::GetMetaDataSet(uint32_t sequence, GraphicHDRMetadataKey &key,
1800                                      std::vector<uint8_t> &metaData)
1801  {
1802      std::lock_guard<std::mutex> lockGuard(mutex_);
1803      if (bufferQueueCache_.find(sequence) == bufferQueueCache_.end()) {
1804          return GSERROR_NO_ENTRY;
1805      }
1806      metaData.clear();
1807      key = bufferQueueCache_.at(sequence).key;
1808      metaData = bufferQueueCache_.at(sequence).metaDataSet;
1809      return GSERROR_OK;
1810  }
1811  
SetTunnelHandle(const sptr<SurfaceTunnelHandle> & handle)1812  GSError BufferQueue::SetTunnelHandle(const sptr<SurfaceTunnelHandle> &handle)
1813  {
1814      std::lock_guard<std::mutex> lockGuard(mutex_);
1815      bool tunnelHandleChange = false;
1816      if (tunnelHandle_ == nullptr) {
1817          if (handle == nullptr) {
1818              BLOGW("tunnel handle is nullptr, uniqueId: %{public}" PRIu64 ".", uniqueId_);
1819              return GSERROR_INVALID_ARGUMENTS;
1820          }
1821          tunnelHandleChange = true;
1822      } else {
1823          tunnelHandleChange = tunnelHandle_->Different(handle);
1824      }
1825      if (!tunnelHandleChange) {
1826          BLOGW("same tunnel handle, uniqueId: %{public}" PRIu64 ".", uniqueId_);
1827          return GSERROR_NO_ENTRY;
1828      }
1829      tunnelHandle_ = handle;
1830      sptr<IBufferConsumerListener> listener;
1831      IBufferConsumerListenerClazz *listenerClazz;
1832      {
1833          std::lock_guard<std::mutex> lockGuard(listenerMutex_);
1834          listener = listener_;
1835          listenerClazz = listenerClazz_;
1836      }
1837      if (listener != nullptr) {
1838          SURFACE_TRACE_NAME("OnTunnelHandleChange");
1839          listener->OnTunnelHandleChange();
1840      } else if (listenerClazz != nullptr) {
1841          SURFACE_TRACE_NAME("OnTunnelHandleChange");
1842          listenerClazz->OnTunnelHandleChange();
1843      } else {
1844          return SURFACE_ERROR_CONSUMER_UNREGISTER_LISTENER;
1845      }
1846      return GSERROR_OK;
1847  }
1848  
GetTunnelHandle()1849  sptr<SurfaceTunnelHandle> BufferQueue::GetTunnelHandle()
1850  {
1851      std::lock_guard<std::mutex> lockGuard(mutex_);
1852      return tunnelHandle_;
1853  }
1854  
SetPresentTimestamp(uint32_t sequence,const GraphicPresentTimestamp & timestamp)1855  GSError BufferQueue::SetPresentTimestamp(uint32_t sequence, const GraphicPresentTimestamp &timestamp)
1856  {
1857      std::lock_guard<std::mutex> lockGuard(mutex_);
1858      if (bufferQueueCache_.find(sequence) == bufferQueueCache_.end()) {
1859          return GSERROR_NO_ENTRY;
1860      }
1861      bufferQueueCache_[sequence].presentTimestamp = timestamp;
1862      return GSERROR_OK;
1863  }
1864  
GetPresentTimestamp(uint32_t sequence,GraphicPresentTimestampType type,int64_t & time)1865  GSError BufferQueue::GetPresentTimestamp(uint32_t sequence, GraphicPresentTimestampType type, int64_t &time)
1866  {
1867      std::lock_guard<std::mutex> lockGuard(mutex_);
1868      if (bufferQueueCache_.find(sequence) == bufferQueueCache_.end()) {
1869          return GSERROR_NO_ENTRY;
1870      }
1871      if (type != bufferQueueCache_.at(sequence).presentTimestamp.type) {
1872          BLOGE("seq: %{public}u, PresentTimestampType [%{public}d] is not supported, the supported type is [%{public}d],"
1873              "uniqueId: %{public}" PRIu64 ".", sequence, type,
1874              bufferQueueCache_.at(sequence).presentTimestamp.type, uniqueId_);
1875          return GSERROR_NO_ENTRY;
1876      }
1877      switch (type) {
1878          case GraphicPresentTimestampType::GRAPHIC_DISPLAY_PTS_DELAY: {
1879              time = bufferQueueCache_.at(sequence).presentTimestamp.time;
1880              return GSERROR_OK;
1881          }
1882          case GraphicPresentTimestampType::GRAPHIC_DISPLAY_PTS_TIMESTAMP: {
1883              time = bufferQueueCache_.at(sequence).presentTimestamp.time - bufferQueueCache_.at(sequence).timestamp;
1884              return GSERROR_OK;
1885          }
1886          default: {
1887              BLOGE("seq: %{public}u, unsupported type: %{public}d, uniqueId: %{public}" PRIu64 ".",
1888                  sequence, type, uniqueId_);
1889              return GSERROR_TYPE_ERROR;
1890          }
1891      }
1892  }
DumpMetadata(std::string & result,BufferElement element)1893  void BufferQueue::DumpMetadata(std::string &result, BufferElement element)
1894  {
1895      HDI::Display::Graphic::Common::V1_0::CM_ColorSpaceType colorSpaceType;
1896      MetadataHelper::GetColorSpaceType(element.buffer, colorSpaceType);
1897      HDI::Display::Graphic::Common::V1_0::CM_HDR_Metadata_Type hdrMetadataType =
1898          HDI::Display::Graphic::Common::V1_0::CM_METADATA_NONE;
1899      std::vector<uint8_t> dataStatic;
1900      std::vector<uint8_t> dataDynamic;
1901      MetadataHelper::GetHDRDynamicMetadata(element.buffer, dataDynamic);
1902      MetadataHelper::GetHDRStaticMetadata(element.buffer, dataStatic);
1903      MetadataHelper::GetHDRMetadataType(element.buffer, hdrMetadataType);
1904      result += std::to_string(colorSpaceType) + ", ";
1905      result += " [staticMetadata: ";
1906      for (auto x : dataStatic) {
1907          result += std::to_string(x);
1908          result += " ";
1909      }
1910      result += " ],[dynamicMetadata: ";
1911      for (auto x : dataDynamic) {
1912          result += std::to_string(x);
1913          result += " ";
1914      }
1915      result += " ],[metadataType: ";
1916      result += std::to_string(hdrMetadataType) + "],";
1917  }
1918  
DumpCache(std::string & result)1919  void BufferQueue::DumpCache(std::string &result)
1920  {
1921      for (auto it = bufferQueueCache_.begin(); it != bufferQueueCache_.end(); it++) {
1922          BufferElement element = it->second;
1923          if (BufferStateStrs.find(element.state) != BufferStateStrs.end()) {
1924              result += "        sequence = " + std::to_string(it->first) +
1925                  ", state = " + std::to_string(element.state) +
1926                  ", timestamp = " + std::to_string(element.timestamp);
1927          }
1928          for (decltype(element.damages.size()) i = 0; i < element.damages.size(); i++) {
1929              result += ", damagesRect = [" + std::to_string(i) + "] = [" +
1930              std::to_string(element.damages[i].x) + ", " +
1931              std::to_string(element.damages[i].y) + ", " +
1932              std::to_string(element.damages[i].w) + ", " +
1933              std::to_string(element.damages[i].h) + "],";
1934          }
1935          result += " config = [" + std::to_string(element.config.width) + "x" +
1936              std::to_string(element.config.height) + ", " +
1937              std::to_string(element.config.strideAlignment) + ", " +
1938              std::to_string(element.config.format) +", " +
1939              std::to_string(element.config.usage) + ", " +
1940              std::to_string(element.config.timeout) + ", " +
1941              std::to_string(element.config.colorGamut) + ", " +
1942              std::to_string(element.config.transform) + "],";
1943          DumpMetadata(result, element);
1944          result += " scalingMode = " + std::to_string(element.buffer->GetSurfaceBufferScalingMode()) + ",";
1945          result += " HDR = " + std::to_string(element.hdrMetaDataType) + ", ";
1946  
1947          double bufferMemSize = 0;
1948          if (element.buffer != nullptr) {
1949              result += " bufferWith = " + std::to_string(element.buffer->GetWidth()) +
1950                      ", bufferHeight = " + std::to_string(element.buffer->GetHeight());
1951              bufferMemSize = static_cast<double>(element.buffer->GetSize()) / BUFFER_MEMSIZE_RATE;
1952          }
1953  
1954          std::ostringstream ss;
1955          ss.precision(BUFFER_MEMSIZE_FORMAT);
1956          ss.setf(std::ios::fixed);
1957          ss << bufferMemSize;
1958          std::string str = ss.str();
1959          result += ", bufferMemSize = " + str + "(KiB).\n";
1960      }
1961  }
1962  
Dump(std::string & result)1963  void BufferQueue::Dump(std::string &result)
1964  {
1965      std::lock_guard<std::mutex> lockGuard(mutex_);
1966      std::ostringstream ss;
1967      ss.precision(BUFFER_MEMSIZE_FORMAT);
1968      ss.setf(std::ios::fixed);
1969      static double allSurfacesMemSize = 0;
1970      uint64_t totalBufferListSize = 0;
1971      double memSizeInKB = 0;
1972  
1973      for (auto it = bufferQueueCache_.begin(); it != bufferQueueCache_.end(); it++) {
1974          BufferElement element = it->second;
1975          if (element.buffer != nullptr) {
1976              totalBufferListSize += element.buffer->GetSize();
1977          }
1978      }
1979      memSizeInKB = static_cast<double>(totalBufferListSize) / BUFFER_MEMSIZE_RATE;
1980  
1981      allSurfacesMemSize += memSizeInKB;
1982      uint32_t resultLen = result.size();
1983      std::string dumpEndFlag = "dumpend";
1984      if (resultLen > dumpEndFlag.size() && resultLen > 1) {
1985          std::string dumpEndIn(result, resultLen - dumpEndFlag.size(), resultLen - 1);
1986          if (dumpEndIn == dumpEndFlag) {
1987              ss << allSurfacesMemSize;
1988              std::string dumpEndStr = ss.str();
1989              result.erase(resultLen - dumpEndFlag.size(), resultLen - 1);
1990              result += dumpEndStr + " KiB.\n";
1991              allSurfacesMemSize = 0;
1992              return;
1993          }
1994      }
1995  
1996      ss.str("");
1997      ss << memSizeInKB;
1998      std::string str = ss.str();
1999      result.append("\nBufferQueue:\n");
2000      result += "      default-size = [" + std::to_string(defaultWidth_) + "x" + std::to_string(defaultHeight_) + "]" +
2001          ", FIFO = " + std::to_string(queueSize_) +
2002          ", name = " + name_ +
2003          ", uniqueId = " + std::to_string(uniqueId_) +
2004          ", usedBufferListLen = " + std::to_string(GetUsedSize()) +
2005          ", freeBufferListLen = " + std::to_string(freeList_.size()) +
2006          ", dirtyBufferListLen = " + std::to_string(dirtyList_.size()) +
2007          ", totalBuffersMemSize = " + str + "(KiB)" +
2008          ", hdrWhitePointBrightness = " + std::to_string(hdrWhitePointBrightness_) +
2009          ", sdrWhitePointBrightness = " + std::to_string(sdrWhitePointBrightness_) +
2010          ", lockLastFlushedBuffer seq = " + std::to_string(acquireLastFlushedBufSequence_) + "\n";
2011  
2012      result.append("      bufferQueueCache:\n");
2013      DumpCache(result);
2014  }
2015  
GetStatusLocked() const2016  bool BufferQueue::GetStatusLocked() const
2017  {
2018      return isValidStatus_;
2019  }
2020  
GetStatus() const2021  bool BufferQueue::GetStatus() const
2022  {
2023      std::lock_guard<std::mutex> lockGuard(mutex_);
2024      return GetStatusLocked();
2025  }
2026  
SetStatus(bool status)2027  void BufferQueue::SetStatus(bool status)
2028  {
2029      std::lock_guard<std::mutex> lockGuard(mutex_);
2030      isValidStatus_ = status;
2031      waitReqCon_.notify_all();
2032  }
2033  
GetAvailableBufferCount()2034  uint32_t BufferQueue::GetAvailableBufferCount()
2035  {
2036      std::lock_guard<std::mutex> lockGuard(mutex_);
2037      return static_cast<uint32_t>(dirtyList_.size());
2038  }
2039  
2040  /**
2041   * @brief Optimize the original FlushBuffer to reduce segmentation locking.
2042   */
FlushBufferImprovedLocked(uint32_t sequence,sptr<BufferExtraData> & bedata,const sptr<SyncFence> & fence,const BufferFlushConfigWithDamages & config)2043  GSError BufferQueue::FlushBufferImprovedLocked(uint32_t sequence, sptr<BufferExtraData> &bedata,
2044      const sptr<SyncFence> &fence, const BufferFlushConfigWithDamages &config)
2045  {
2046      if (!GetStatusLocked()) {
2047          SURFACE_TRACE_NAME_FMT("status: %d", GetStatusLocked());
2048          BLOGN_FAILURE_RET(GSERROR_NO_CONSUMER);
2049      }
2050      // check param
2051      auto sret = CheckFlushConfig(config);
2052      if (sret != GSERROR_OK) {
2053          BLOGE("CheckFlushConfig ret: %{public}d, uniqueId: %{public}" PRIu64 ".", sret, uniqueId_);
2054          return sret;
2055      }
2056  
2057      sret = CheckBufferQueueCacheLocked(sequence);
2058      if (sret != GSERROR_OK) {
2059          return sret;
2060      }
2061  
2062      {
2063          std::lock_guard<std::mutex> lockGuard(listenerMutex_);
2064          if (listener_ == nullptr && listenerClazz_ == nullptr) {
2065              BLOGE("listener is nullptr, uniqueId: %{public}" PRIu64 ".", uniqueId_);
2066              return SURFACE_ERROR_CONSUMER_UNREGISTER_LISTENER;
2067          }
2068      }
2069  
2070      sret = DoFlushBufferLocked(sequence, bedata, fence, config);
2071      if (sret != GSERROR_OK) {
2072          return sret;
2073      }
2074      return sret;
2075  }
2076  
RequestAndDetachBuffer(const BufferRequestConfig & config,sptr<BufferExtraData> & bedata,struct IBufferProducer::RequestBufferReturnValue & retval)2077  GSError BufferQueue::RequestAndDetachBuffer(const BufferRequestConfig& config, sptr<BufferExtraData>& bedata,
2078      struct IBufferProducer::RequestBufferReturnValue& retval)
2079  {
2080      SURFACE_TRACE_NAME_FMT("RequestAndDetachBuffer queueId: %" PRIu64, uniqueId_);
2081      std::unique_lock<std::mutex> lock(mutex_);
2082      auto ret = RequestBufferLocked(config, bedata, retval, lock);
2083      if (ret != GSERROR_OK) {
2084          return ret;
2085      }
2086      return DetachBufferFromQueueLocked(retval.sequence, InvokerType::PRODUCER_INVOKER);
2087  }
2088  
AttachAndFlushBuffer(sptr<SurfaceBuffer> & buffer,sptr<BufferExtraData> & bedata,const sptr<SyncFence> & fence,BufferFlushConfigWithDamages & config,bool needMap)2089  GSError BufferQueue::AttachAndFlushBuffer(sptr<SurfaceBuffer>& buffer, sptr<BufferExtraData>& bedata,
2090      const sptr<SyncFence>& fence, BufferFlushConfigWithDamages& config, bool needMap)
2091  {
2092      SURFACE_TRACE_NAME_FMT("AttachAndFlushBuffer queueId: %" PRIu64 " sequence: %u", uniqueId_, buffer->GetSeqNum());
2093      GSError ret;
2094      {
2095          std::unique_lock<std::mutex> lock(mutex_);
2096          ret = AttachBufferToQueueLocked(buffer, InvokerType::PRODUCER_INVOKER, needMap);
2097          if (ret != GSERROR_OK) {
2098              return ret;
2099          }
2100          uint32_t sequence = buffer->GetSeqNum();
2101          ret = FlushBufferImprovedLocked(sequence, bedata, fence, config);
2102          if (ret != GSERROR_OK) {
2103              bufferQueueCache_.erase(sequence);
2104              return ret;
2105          }
2106      }
2107      CallConsumerListener();
2108      return ret;
2109  }
2110  }; // namespace OHOS
2111