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