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