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