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