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 ×tamp, 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 ×tamp)
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