132a6e48fSopenharmony_ci/* 232a6e48fSopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 332a6e48fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 432a6e48fSopenharmony_ci * you may not use this file except in compliance with the License. 532a6e48fSopenharmony_ci * You may obtain a copy of the License at 632a6e48fSopenharmony_ci * 732a6e48fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 832a6e48fSopenharmony_ci * 932a6e48fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1032a6e48fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1132a6e48fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1232a6e48fSopenharmony_ci * See the License for the specific language governing permissions and 1332a6e48fSopenharmony_ci * limitations under the License. 1432a6e48fSopenharmony_ci */ 1532a6e48fSopenharmony_ci 1632a6e48fSopenharmony_ci#include "buffer_queue.h" 1732a6e48fSopenharmony_ci#include <algorithm> 1832a6e48fSopenharmony_ci#include <fstream> 1932a6e48fSopenharmony_ci#include <sstream> 2032a6e48fSopenharmony_ci#include <sys/time.h> 2132a6e48fSopenharmony_ci#include <cinttypes> 2232a6e48fSopenharmony_ci#include <unistd.h> 2332a6e48fSopenharmony_ci#include <parameters.h> 2432a6e48fSopenharmony_ci 2532a6e48fSopenharmony_ci#include "acquire_fence_manager.h" 2632a6e48fSopenharmony_ci#include "buffer_utils.h" 2732a6e48fSopenharmony_ci#include "buffer_log.h" 2832a6e48fSopenharmony_ci#include "hebc_white_list.h" 2932a6e48fSopenharmony_ci#include "hitrace_meter.h" 3032a6e48fSopenharmony_ci#include "metadata_helper.h" 3132a6e48fSopenharmony_ci#include "sandbox_utils.h" 3232a6e48fSopenharmony_ci#include "surface_buffer_impl.h" 3332a6e48fSopenharmony_ci#include "sync_fence.h" 3432a6e48fSopenharmony_ci#include "sync_fence_tracker.h" 3532a6e48fSopenharmony_ci#include "surface_utils.h" 3632a6e48fSopenharmony_ci#include "surface_trace.h" 3732a6e48fSopenharmony_ci#include "v2_0/buffer_handle_meta_key_type.h" 3832a6e48fSopenharmony_ci 3932a6e48fSopenharmony_cinamespace OHOS { 4032a6e48fSopenharmony_cinamespace { 4132a6e48fSopenharmony_ciconstexpr int32_t FORCE_GLOBAL_ALPHA_MIN = -1; 4232a6e48fSopenharmony_ciconstexpr int32_t FORCE_GLOBAL_ALPHA_MAX = 255; 4332a6e48fSopenharmony_ciconstexpr uint32_t UNIQUE_ID_OFFSET = 32; 4432a6e48fSopenharmony_ciconstexpr uint32_t BUFFER_MEMSIZE_RATE = 1024; 4532a6e48fSopenharmony_ciconstexpr uint32_t BUFFER_MEMSIZE_FORMAT = 2; 4632a6e48fSopenharmony_ciconstexpr uint32_t MAXIMUM_LENGTH_OF_APP_FRAMEWORK = 64; 4732a6e48fSopenharmony_ciconstexpr uint32_t INVALID_SEQUENCE = 0xFFFFFFFF; 4832a6e48fSopenharmony_ciconstexpr uint32_t ONE_SECOND_TIMESTAMP = 1e9; 4932a6e48fSopenharmony_ci} 5032a6e48fSopenharmony_ci 5132a6e48fSopenharmony_cistatic const std::map<BufferState, std::string> BufferStateStrs = { 5232a6e48fSopenharmony_ci {BUFFER_STATE_RELEASED, "0 <released>"}, 5332a6e48fSopenharmony_ci {BUFFER_STATE_REQUESTED, "1 <requested>"}, 5432a6e48fSopenharmony_ci {BUFFER_STATE_FLUSHED, "2 <flushed>"}, 5532a6e48fSopenharmony_ci {BUFFER_STATE_ACQUIRED, "3 <acquired>"}, 5632a6e48fSopenharmony_ci {BUFFER_STATE_ATTACHED, "4 <attached>"}, 5732a6e48fSopenharmony_ci}; 5832a6e48fSopenharmony_ci 5932a6e48fSopenharmony_cistatic uint64_t GetUniqueIdImpl() 6032a6e48fSopenharmony_ci{ 6132a6e48fSopenharmony_ci static std::atomic<uint32_t> counter { 0 }; 6232a6e48fSopenharmony_ci static uint64_t id = static_cast<uint64_t>(GetRealPid()) << UNIQUE_ID_OFFSET; 6332a6e48fSopenharmony_ci return id | counter.fetch_add(1, std::memory_order_relaxed); 6432a6e48fSopenharmony_ci} 6532a6e48fSopenharmony_ci 6632a6e48fSopenharmony_cistatic bool IsLocalRender() 6732a6e48fSopenharmony_ci{ 6832a6e48fSopenharmony_ci std::ifstream procfile("/proc/self/cmdline"); 6932a6e48fSopenharmony_ci if (!procfile.is_open()) { 7032a6e48fSopenharmony_ci BLOGE("Error opening procfile!"); 7132a6e48fSopenharmony_ci return false; 7232a6e48fSopenharmony_ci } 7332a6e48fSopenharmony_ci std::string processName; 7432a6e48fSopenharmony_ci std::getline(procfile, processName); 7532a6e48fSopenharmony_ci procfile.close(); 7632a6e48fSopenharmony_ci std::string target = "/system/bin/render_service"; 7732a6e48fSopenharmony_ci bool result = processName.substr(0, target.size()) == target; 7832a6e48fSopenharmony_ci return result; 7932a6e48fSopenharmony_ci} 8032a6e48fSopenharmony_ci 8132a6e48fSopenharmony_ciBufferQueue::BufferQueue(const std::string &name, bool isShared) 8232a6e48fSopenharmony_ci : name_(name), uniqueId_(GetUniqueIdImpl()), isShared_(isShared), isLocalRender_(IsLocalRender()) 8332a6e48fSopenharmony_ci{ 8432a6e48fSopenharmony_ci BLOGD("BufferQueue ctor, uniqueId: %{public}" PRIu64 ".", uniqueId_); 8532a6e48fSopenharmony_ci if (isShared_ == true) { 8632a6e48fSopenharmony_ci bufferQueueSize_ = 1; 8732a6e48fSopenharmony_ci } 8832a6e48fSopenharmony_ci 8932a6e48fSopenharmony_ci if (isLocalRender_) { 9032a6e48fSopenharmony_ci if (!HebcWhiteList::GetInstance().Init()) { 9132a6e48fSopenharmony_ci BLOGW("HebcWhiteList init failed"); 9232a6e48fSopenharmony_ci } 9332a6e48fSopenharmony_ci } 9432a6e48fSopenharmony_ci acquireLastFlushedBufSequence_ = INVALID_SEQUENCE; 9532a6e48fSopenharmony_ci} 9632a6e48fSopenharmony_ci 9732a6e48fSopenharmony_ciBufferQueue::~BufferQueue() 9832a6e48fSopenharmony_ci{ 9932a6e48fSopenharmony_ci BLOGD("~BufferQueue dtor, uniqueId: %{public}" PRIu64 ".", uniqueId_); 10032a6e48fSopenharmony_ci for (auto &[id, _] : bufferQueueCache_) { 10132a6e48fSopenharmony_ci if (onBufferDeleteForRSMainThread_ != nullptr) { 10232a6e48fSopenharmony_ci onBufferDeleteForRSMainThread_(id); 10332a6e48fSopenharmony_ci } 10432a6e48fSopenharmony_ci if (onBufferDeleteForRSHardwareThread_ != nullptr) { 10532a6e48fSopenharmony_ci onBufferDeleteForRSHardwareThread_(id); 10632a6e48fSopenharmony_ci } 10732a6e48fSopenharmony_ci } 10832a6e48fSopenharmony_ci} 10932a6e48fSopenharmony_ci 11032a6e48fSopenharmony_ciuint32_t BufferQueue::GetUsedSize() 11132a6e48fSopenharmony_ci{ 11232a6e48fSopenharmony_ci return static_cast<uint32_t>(bufferQueueCache_.size()); 11332a6e48fSopenharmony_ci} 11432a6e48fSopenharmony_ci 11532a6e48fSopenharmony_ciGSError BufferQueue::GetProducerInitInfo(ProducerInitInfo &info) 11632a6e48fSopenharmony_ci{ 11732a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 11832a6e48fSopenharmony_ci info.name = name_; 11932a6e48fSopenharmony_ci info.width = defaultWidth_; 12032a6e48fSopenharmony_ci info.height = defaultHeight_; 12132a6e48fSopenharmony_ci info.uniqueId = uniqueId_; 12232a6e48fSopenharmony_ci info.isInHebcList = HebcWhiteList::GetInstance().Check(info.appName); 12332a6e48fSopenharmony_ci return GSERROR_OK; 12432a6e48fSopenharmony_ci} 12532a6e48fSopenharmony_ci 12632a6e48fSopenharmony_ciGSError BufferQueue::PopFromFreeListLocked(sptr<SurfaceBuffer> &buffer, 12732a6e48fSopenharmony_ci const BufferRequestConfig &config) 12832a6e48fSopenharmony_ci{ 12932a6e48fSopenharmony_ci if (isShared_ == true && GetUsedSize() > 0) { 13032a6e48fSopenharmony_ci buffer = bufferQueueCache_.begin()->second.buffer; 13132a6e48fSopenharmony_ci return GSERROR_OK; 13232a6e48fSopenharmony_ci } 13332a6e48fSopenharmony_ci 13432a6e48fSopenharmony_ci for (auto it = freeList_.begin(); it != freeList_.end(); it++) { 13532a6e48fSopenharmony_ci auto mapIter = bufferQueueCache_.find(*it); 13632a6e48fSopenharmony_ci if (mapIter != bufferQueueCache_.end() && mapIter->second.config == config) { 13732a6e48fSopenharmony_ci if (mapIter->first == acquireLastFlushedBufSequence_) { 13832a6e48fSopenharmony_ci continue; 13932a6e48fSopenharmony_ci } 14032a6e48fSopenharmony_ci buffer = mapIter->second.buffer; 14132a6e48fSopenharmony_ci freeList_.erase(it); 14232a6e48fSopenharmony_ci return GSERROR_OK; 14332a6e48fSopenharmony_ci } 14432a6e48fSopenharmony_ci } 14532a6e48fSopenharmony_ci 14632a6e48fSopenharmony_ci if (freeList_.empty() || GetUsedSize() < bufferQueueSize_ || 14732a6e48fSopenharmony_ci (freeList_.size() == 1 && freeList_.front() == acquireLastFlushedBufSequence_)) { 14832a6e48fSopenharmony_ci buffer = nullptr; 14932a6e48fSopenharmony_ci return GSERROR_NO_BUFFER; 15032a6e48fSopenharmony_ci } 15132a6e48fSopenharmony_ci 15232a6e48fSopenharmony_ci if (freeList_.front() == acquireLastFlushedBufSequence_) { 15332a6e48fSopenharmony_ci freeList_.pop_front(); 15432a6e48fSopenharmony_ci freeList_.push_back(acquireLastFlushedBufSequence_); 15532a6e48fSopenharmony_ci } 15632a6e48fSopenharmony_ci 15732a6e48fSopenharmony_ci buffer = bufferQueueCache_[freeList_.front()].buffer; 15832a6e48fSopenharmony_ci buffer->SetSurfaceBufferColorGamut(config.colorGamut); 15932a6e48fSopenharmony_ci buffer->SetSurfaceBufferTransform(config.transform); 16032a6e48fSopenharmony_ci freeList_.pop_front(); 16132a6e48fSopenharmony_ci return GSERROR_OK; 16232a6e48fSopenharmony_ci} 16332a6e48fSopenharmony_ci 16432a6e48fSopenharmony_ciGSError BufferQueue::PopFromDirtyListLocked(sptr<SurfaceBuffer> &buffer) 16532a6e48fSopenharmony_ci{ 16632a6e48fSopenharmony_ci if (isShared_ == true && GetUsedSize() > 0) { 16732a6e48fSopenharmony_ci buffer = bufferQueueCache_.begin()->second.buffer; 16832a6e48fSopenharmony_ci return GSERROR_OK; 16932a6e48fSopenharmony_ci } 17032a6e48fSopenharmony_ci 17132a6e48fSopenharmony_ci if (!dirtyList_.empty()) { 17232a6e48fSopenharmony_ci buffer = bufferQueueCache_[dirtyList_.front()].buffer; 17332a6e48fSopenharmony_ci dirtyList_.pop_front(); 17432a6e48fSopenharmony_ci return GSERROR_OK; 17532a6e48fSopenharmony_ci } else { 17632a6e48fSopenharmony_ci buffer = nullptr; 17732a6e48fSopenharmony_ci return GSERROR_NO_BUFFER; 17832a6e48fSopenharmony_ci } 17932a6e48fSopenharmony_ci} 18032a6e48fSopenharmony_ci 18132a6e48fSopenharmony_ciGSError BufferQueue::CheckRequestConfig(const BufferRequestConfig &config) 18232a6e48fSopenharmony_ci{ 18332a6e48fSopenharmony_ci uint32_t align = config.strideAlignment; 18432a6e48fSopenharmony_ci if (align < SURFACE_MIN_STRIDE_ALIGNMENT || align > SURFACE_MAX_STRIDE_ALIGNMENT) { 18532a6e48fSopenharmony_ci BLOGW("align is %{public}d, uniqueId: %{public}" PRIu64 ".", align, uniqueId_); 18632a6e48fSopenharmony_ci return GSERROR_INVALID_ARGUMENTS; 18732a6e48fSopenharmony_ci } 18832a6e48fSopenharmony_ci 18932a6e48fSopenharmony_ci if (align & (align - 1)) { 19032a6e48fSopenharmony_ci BLOGW("align is %{public}d, uniqueId: %{public}" PRIu64 ".", align, uniqueId_); 19132a6e48fSopenharmony_ci return GSERROR_INVALID_ARGUMENTS; 19232a6e48fSopenharmony_ci } 19332a6e48fSopenharmony_ci 19432a6e48fSopenharmony_ci if (config.colorGamut <= GraphicColorGamut::GRAPHIC_COLOR_GAMUT_INVALID || 19532a6e48fSopenharmony_ci config.colorGamut > GraphicColorGamut::GRAPHIC_COLOR_GAMUT_DISPLAY_BT2020 + 1) { 19632a6e48fSopenharmony_ci BLOGW("colorGamut is %{public}d, uniqueId: %{public}" PRIu64 ".", 19732a6e48fSopenharmony_ci static_cast<uint32_t>(config.colorGamut), uniqueId_); 19832a6e48fSopenharmony_ci return GSERROR_INVALID_ARGUMENTS; 19932a6e48fSopenharmony_ci } 20032a6e48fSopenharmony_ci 20132a6e48fSopenharmony_ci if (config.transform < GraphicTransformType::GRAPHIC_ROTATE_NONE || 20232a6e48fSopenharmony_ci config.transform >= GraphicTransformType::GRAPHIC_ROTATE_BUTT) { 20332a6e48fSopenharmony_ci BLOGW("transform is %{public}d, uniqueId: %{public}" PRIu64 ".", config.transform, uniqueId_); 20432a6e48fSopenharmony_ci return GSERROR_INVALID_ARGUMENTS; 20532a6e48fSopenharmony_ci } 20632a6e48fSopenharmony_ci return GSERROR_OK; 20732a6e48fSopenharmony_ci} 20832a6e48fSopenharmony_ci 20932a6e48fSopenharmony_ciGSError BufferQueue::CheckFlushConfig(const BufferFlushConfigWithDamages &config) 21032a6e48fSopenharmony_ci{ 21132a6e48fSopenharmony_ci for (decltype(config.damages.size()) i = 0; i < config.damages.size(); i++) { 21232a6e48fSopenharmony_ci if (config.damages[i].w < 0 || config.damages[i].h < 0) { 21332a6e48fSopenharmony_ci BLOGW("damages[%{public}zu].w is %{public}d, .h is %{public}d, uniqueId: %{public}" PRIu64 ".", 21432a6e48fSopenharmony_ci i, config.damages[i].w, config.damages[i].h, uniqueId_); 21532a6e48fSopenharmony_ci return GSERROR_INVALID_ARGUMENTS; 21632a6e48fSopenharmony_ci } 21732a6e48fSopenharmony_ci } 21832a6e48fSopenharmony_ci return GSERROR_OK; 21932a6e48fSopenharmony_ci} 22032a6e48fSopenharmony_ci 22132a6e48fSopenharmony_cibool BufferQueue::QueryIfBufferAvailable() 22232a6e48fSopenharmony_ci{ 22332a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 22432a6e48fSopenharmony_ci bool ret = !freeList_.empty() || (GetUsedSize() < bufferQueueSize_); 22532a6e48fSopenharmony_ci return ret; 22632a6e48fSopenharmony_ci} 22732a6e48fSopenharmony_ci 22832a6e48fSopenharmony_cistatic GSError DelegatorDequeueBuffer(wptr<ConsumerSurfaceDelegator>& delegator, 22932a6e48fSopenharmony_ci const BufferRequestConfig& config, 23032a6e48fSopenharmony_ci sptr<BufferExtraData>& bedata, 23132a6e48fSopenharmony_ci struct IBufferProducer::RequestBufferReturnValue& retval) 23232a6e48fSopenharmony_ci{ 23332a6e48fSopenharmony_ci auto consumerDelegator = delegator.promote(); 23432a6e48fSopenharmony_ci if (consumerDelegator == nullptr) { 23532a6e48fSopenharmony_ci BLOGE("Consumer surface delegator has been expired"); 23632a6e48fSopenharmony_ci return GSERROR_INVALID_ARGUMENTS; 23732a6e48fSopenharmony_ci } 23832a6e48fSopenharmony_ci auto ret = consumerDelegator->DequeueBuffer(config, bedata, retval); 23932a6e48fSopenharmony_ci if (ret != GSERROR_OK) { 24032a6e48fSopenharmony_ci BLOGE("Consumer surface delegator failed to dequeuebuffer, err: %{public}d", ret); 24132a6e48fSopenharmony_ci return ret; 24232a6e48fSopenharmony_ci } 24332a6e48fSopenharmony_ci 24432a6e48fSopenharmony_ci ret = retval.buffer->Map(); 24532a6e48fSopenharmony_ci if (ret != GSERROR_OK) { 24632a6e48fSopenharmony_ci BLOGE("Buffer map failed, err: %{public}d", ret); 24732a6e48fSopenharmony_ci return ret; 24832a6e48fSopenharmony_ci } 24932a6e48fSopenharmony_ci retval.buffer->SetSurfaceBufferWidth(retval.buffer->GetWidth()); 25032a6e48fSopenharmony_ci retval.buffer->SetSurfaceBufferHeight(retval.buffer->GetHeight()); 25132a6e48fSopenharmony_ci 25232a6e48fSopenharmony_ci return GSERROR_OK; 25332a6e48fSopenharmony_ci} 25432a6e48fSopenharmony_ci 25532a6e48fSopenharmony_cistatic void SetReturnValue(sptr<SurfaceBuffer>& buffer, sptr<BufferExtraData>& bedata, 25632a6e48fSopenharmony_ci struct IBufferProducer::RequestBufferReturnValue& retval) 25732a6e48fSopenharmony_ci{ 25832a6e48fSopenharmony_ci retval.sequence = buffer->GetSeqNum(); 25932a6e48fSopenharmony_ci bedata = buffer->GetExtraData(); 26032a6e48fSopenharmony_ci retval.fence = SyncFence::InvalidFence(); 26132a6e48fSopenharmony_ci} 26232a6e48fSopenharmony_ci 26332a6e48fSopenharmony_civoid BufferQueue::SetSurfaceBufferHebcMetaLocked(sptr<SurfaceBuffer> buffer) 26432a6e48fSopenharmony_ci{ 26532a6e48fSopenharmony_ci using namespace HDI::Display::Graphic::Common; 26632a6e48fSopenharmony_ci // usage does not contain BUFFER_USAGE_CPU_HW_BOTH, just return 26732a6e48fSopenharmony_ci if (!(buffer->GetUsage() & BUFFER_USAGE_CPU_HW_BOTH)) { 26832a6e48fSopenharmony_ci return; 26932a6e48fSopenharmony_ci } 27032a6e48fSopenharmony_ci 27132a6e48fSopenharmony_ci V2_0::BufferHandleAttrKey key = V2_0::BufferHandleAttrKey::ATTRKEY_REQUEST_ACCESS_TYPE; 27232a6e48fSopenharmony_ci std::vector<uint8_t> values; 27332a6e48fSopenharmony_ci if (isCpuAccessable_) { // hebc is off 27432a6e48fSopenharmony_ci values.emplace_back(static_cast<uint8_t>(V2_0::HebcAccessType::HEBC_ACCESS_CPU_ACCESS)); 27532a6e48fSopenharmony_ci } else { // hebc is on 27632a6e48fSopenharmony_ci values.emplace_back(static_cast<uint8_t>(V2_0::HebcAccessType::HEBC_ACCESS_HW_ONLY)); 27732a6e48fSopenharmony_ci } 27832a6e48fSopenharmony_ci 27932a6e48fSopenharmony_ci buffer->SetMetadata(key, values); 28032a6e48fSopenharmony_ci} 28132a6e48fSopenharmony_ci 28232a6e48fSopenharmony_civoid BufferQueue::SetBatchHandle(bool batch) 28332a6e48fSopenharmony_ci{ 28432a6e48fSopenharmony_ci std::unique_lock<std::mutex> lock(mutex_); 28532a6e48fSopenharmony_ci isBatch_ = batch; 28632a6e48fSopenharmony_ci} 28732a6e48fSopenharmony_ci 28832a6e48fSopenharmony_ciGSError BufferQueue::RequestBufferCheckStatus() 28932a6e48fSopenharmony_ci{ 29032a6e48fSopenharmony_ci { 29132a6e48fSopenharmony_ci std::unique_lock<std::mutex> lock(mutex_); 29232a6e48fSopenharmony_ci if (isBatch_) { 29332a6e48fSopenharmony_ci return GSERROR_OK; 29432a6e48fSopenharmony_ci } 29532a6e48fSopenharmony_ci if (!GetStatusLocked()) { 29632a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("RequestBufferCheckStatus status wrong," 29732a6e48fSopenharmony_ci "surface name: %s queueId: %" PRIu64 " status: %u", name_.c_str(), uniqueId_, GetStatusLocked()); 29832a6e48fSopenharmony_ci BLOGN_FAILURE_RET(GSERROR_NO_CONSUMER); 29932a6e48fSopenharmony_ci } 30032a6e48fSopenharmony_ci } 30132a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(listenerMutex_); 30232a6e48fSopenharmony_ci if (listener_ == nullptr && listenerClazz_ == nullptr) { 30332a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("RequestBufferCheckStatus no listener, surface name: %s queueId: %" PRIu64, 30432a6e48fSopenharmony_ci name_.c_str(), uniqueId_); 30532a6e48fSopenharmony_ci BLOGN_FAILURE_RET(SURFACE_ERROR_CONSUMER_UNREGISTER_LISTENER); 30632a6e48fSopenharmony_ci } 30732a6e48fSopenharmony_ci 30832a6e48fSopenharmony_ci return GSERROR_OK; 30932a6e48fSopenharmony_ci} 31032a6e48fSopenharmony_ci 31132a6e48fSopenharmony_cibool BufferQueue::WaitForCondition() 31232a6e48fSopenharmony_ci{ 31332a6e48fSopenharmony_ci return (!freeList_.empty() && !(freeList_.size() == 1 && freeList_.front() == acquireLastFlushedBufSequence_)) || 31432a6e48fSopenharmony_ci (GetUsedSize() < bufferQueueSize_) || !GetStatusLocked(); 31532a6e48fSopenharmony_ci} 31632a6e48fSopenharmony_ci 31732a6e48fSopenharmony_civoid BufferQueue::RequestBufferDebugInfoLocked() 31832a6e48fSopenharmony_ci{ 31932a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("lockLastFlushedBuffer seq: %u", acquireLastFlushedBufSequence_); 32032a6e48fSopenharmony_ci std::map<BufferState, int32_t> bufferState; 32132a6e48fSopenharmony_ci for (auto &[id, ele] : bufferQueueCache_) { 32232a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("request buffer id: %u state: %u", id, ele.state); 32332a6e48fSopenharmony_ci BLOGD("request no buffer, buffer id:%{public}d state:%{public}d, uniqueId: %{public}" PRIu64 ".", 32432a6e48fSopenharmony_ci id, ele.state, uniqueId_); 32532a6e48fSopenharmony_ci bufferState[ele.state] += 1; 32632a6e48fSopenharmony_ci } 32732a6e48fSopenharmony_ci std::string str = std::to_string(uniqueId_) + 32832a6e48fSopenharmony_ci ", Released: " + std::to_string(bufferState[BUFFER_STATE_RELEASED]) + 32932a6e48fSopenharmony_ci " Requested: " + std::to_string(bufferState[BUFFER_STATE_REQUESTED]) + 33032a6e48fSopenharmony_ci " Flushed: " + std::to_string(bufferState[BUFFER_STATE_FLUSHED]) + 33132a6e48fSopenharmony_ci " Acquired: " + std::to_string(bufferState[BUFFER_STATE_ACQUIRED]); 33232a6e48fSopenharmony_ci if (str.compare(requestBufferStateStr_) != 0) { 33332a6e48fSopenharmony_ci requestBufferStateStr_ = str; 33432a6e48fSopenharmony_ci BLOGE("all buffer are using, uniqueId: %{public}s", str.c_str()); 33532a6e48fSopenharmony_ci } 33632a6e48fSopenharmony_ci} 33732a6e48fSopenharmony_ci 33832a6e48fSopenharmony_ciGSError BufferQueue::RequestBuffer(const BufferRequestConfig &config, sptr<BufferExtraData> &bedata, 33932a6e48fSopenharmony_ci struct IBufferProducer::RequestBufferReturnValue &retval) 34032a6e48fSopenharmony_ci{ 34132a6e48fSopenharmony_ci if (wpCSurfaceDelegator_ != nullptr) { 34232a6e48fSopenharmony_ci return DelegatorDequeueBuffer(wpCSurfaceDelegator_, config, bedata, retval); 34332a6e48fSopenharmony_ci } 34432a6e48fSopenharmony_ci 34532a6e48fSopenharmony_ci GSError ret = RequestBufferCheckStatus(); 34632a6e48fSopenharmony_ci if (ret != GSERROR_OK) { 34732a6e48fSopenharmony_ci return ret; 34832a6e48fSopenharmony_ci } 34932a6e48fSopenharmony_ci 35032a6e48fSopenharmony_ci // check param 35132a6e48fSopenharmony_ci ret = CheckRequestConfig(config); 35232a6e48fSopenharmony_ci if (ret != GSERROR_OK) { 35332a6e48fSopenharmony_ci BLOGE("CheckRequestConfig ret: %{public}d, uniqueId: %{public}" PRIu64 ".", ret, uniqueId_); 35432a6e48fSopenharmony_ci return SURFACE_ERROR_UNKOWN; 35532a6e48fSopenharmony_ci } 35632a6e48fSopenharmony_ci 35732a6e48fSopenharmony_ci std::unique_lock<std::mutex> lock(mutex_); 35832a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("RequestBuffer name: %s queueId: %" PRIu64 " queueSize: %u", 35932a6e48fSopenharmony_ci name_.c_str(), uniqueId_, bufferQueueSize_); 36032a6e48fSopenharmony_ci // dequeue from free list 36132a6e48fSopenharmony_ci sptr<SurfaceBuffer>& buffer = retval.buffer; 36232a6e48fSopenharmony_ci ret = PopFromFreeListLocked(buffer, config); 36332a6e48fSopenharmony_ci if (ret == GSERROR_OK) { 36432a6e48fSopenharmony_ci return ReuseBuffer(config, bedata, retval); 36532a6e48fSopenharmony_ci } 36632a6e48fSopenharmony_ci 36732a6e48fSopenharmony_ci // check queue size 36832a6e48fSopenharmony_ci if (GetUsedSize() >= bufferQueueSize_) { 36932a6e48fSopenharmony_ci waitReqCon_.wait_for(lock, std::chrono::milliseconds(config.timeout), 37032a6e48fSopenharmony_ci [this]() { return WaitForCondition(); }); 37132a6e48fSopenharmony_ci if (!GetStatusLocked() && !isBatch_) { 37232a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("Status wrong, status: %d", GetStatusLocked()); 37332a6e48fSopenharmony_ci BLOGN_FAILURE_RET(GSERROR_NO_CONSUMER); 37432a6e48fSopenharmony_ci } 37532a6e48fSopenharmony_ci // try dequeue from free list again 37632a6e48fSopenharmony_ci ret = PopFromFreeListLocked(buffer, config); 37732a6e48fSopenharmony_ci if (ret == GSERROR_OK) { 37832a6e48fSopenharmony_ci return ReuseBuffer(config, bedata, retval); 37932a6e48fSopenharmony_ci } else if (GetUsedSize() >= bufferQueueSize_) { 38032a6e48fSopenharmony_ci RequestBufferDebugInfoLocked(); 38132a6e48fSopenharmony_ci return GSERROR_NO_BUFFER; 38232a6e48fSopenharmony_ci } 38332a6e48fSopenharmony_ci } 38432a6e48fSopenharmony_ci 38532a6e48fSopenharmony_ci ret = AllocBuffer(buffer, config); 38632a6e48fSopenharmony_ci if (ret == GSERROR_OK) { 38732a6e48fSopenharmony_ci SetSurfaceBufferHebcMetaLocked(buffer); 38832a6e48fSopenharmony_ci SetSurfaceBufferGlobalAlphaUnlocked(buffer); 38932a6e48fSopenharmony_ci SetReturnValue(buffer, bedata, retval); 39032a6e48fSopenharmony_ci BLOGD("Success alloc Buffer[%{public}d %{public}d] seq: %{public}d, uniqueId: %{public}" PRIu64 ".", 39132a6e48fSopenharmony_ci config.width, config.height, retval.sequence, uniqueId_); 39232a6e48fSopenharmony_ci } else { 39332a6e48fSopenharmony_ci BLOGE("Fail to alloc or map Buffer[%{public}d %{public}d] ret: %{public}d, uniqueId: %{public}" PRIu64, 39432a6e48fSopenharmony_ci config.width, config.height, ret, uniqueId_); 39532a6e48fSopenharmony_ci } 39632a6e48fSopenharmony_ci 39732a6e48fSopenharmony_ci return ret; 39832a6e48fSopenharmony_ci} 39932a6e48fSopenharmony_ci 40032a6e48fSopenharmony_ciGSError BufferQueue::SetProducerCacheCleanFlag(bool flag) 40132a6e48fSopenharmony_ci{ 40232a6e48fSopenharmony_ci std::unique_lock<std::mutex> lock(mutex_); 40332a6e48fSopenharmony_ci return SetProducerCacheCleanFlagLocked(flag); 40432a6e48fSopenharmony_ci} 40532a6e48fSopenharmony_ci 40632a6e48fSopenharmony_ciGSError BufferQueue::SetProducerCacheCleanFlagLocked(bool flag) 40732a6e48fSopenharmony_ci{ 40832a6e48fSopenharmony_ci producerCacheClean_ = flag; 40932a6e48fSopenharmony_ci producerCacheList_.clear(); 41032a6e48fSopenharmony_ci return GSERROR_OK; 41132a6e48fSopenharmony_ci} 41232a6e48fSopenharmony_ci 41332a6e48fSopenharmony_cibool BufferQueue::CheckProducerCacheListLocked() 41432a6e48fSopenharmony_ci{ 41532a6e48fSopenharmony_ci for (auto &[id, _] : bufferQueueCache_) { 41632a6e48fSopenharmony_ci if (std::find(producerCacheList_.begin(), producerCacheList_.end(), id) == producerCacheList_.end()) { 41732a6e48fSopenharmony_ci return false; 41832a6e48fSopenharmony_ci } 41932a6e48fSopenharmony_ci } 42032a6e48fSopenharmony_ci return true; 42132a6e48fSopenharmony_ci} 42232a6e48fSopenharmony_ci 42332a6e48fSopenharmony_ciGSError BufferQueue::ReallocBufferLocked(const BufferRequestConfig &config, 42432a6e48fSopenharmony_ci struct IBufferProducer::RequestBufferReturnValue &retval) 42532a6e48fSopenharmony_ci{ 42632a6e48fSopenharmony_ci if (isShared_) { 42732a6e48fSopenharmony_ci BLOGE("shared mode, uniqueId: %{public}" PRIu64, uniqueId_); 42832a6e48fSopenharmony_ci return SURFACE_ERROR_UNKOWN; 42932a6e48fSopenharmony_ci } 43032a6e48fSopenharmony_ci DeleteBufferInCache(retval.sequence); 43132a6e48fSopenharmony_ci 43232a6e48fSopenharmony_ci sptr<SurfaceBuffer> buffer = nullptr; 43332a6e48fSopenharmony_ci auto sret = AllocBuffer(buffer, config); 43432a6e48fSopenharmony_ci if (sret != GSERROR_OK) { 43532a6e48fSopenharmony_ci BLOGE("AllocBuffer failed: %{public}d, uniqueId: %{public}" PRIu64 ".", sret, uniqueId_); 43632a6e48fSopenharmony_ci return sret; 43732a6e48fSopenharmony_ci } 43832a6e48fSopenharmony_ci 43932a6e48fSopenharmony_ci retval.buffer = buffer; 44032a6e48fSopenharmony_ci retval.sequence = buffer->GetSeqNum(); 44132a6e48fSopenharmony_ci bufferQueueCache_[retval.sequence].config = config; 44232a6e48fSopenharmony_ci return GSERROR_OK; 44332a6e48fSopenharmony_ci} 44432a6e48fSopenharmony_ci 44532a6e48fSopenharmony_ciGSError BufferQueue::ReuseBuffer(const BufferRequestConfig &config, sptr<BufferExtraData> &bedata, 44632a6e48fSopenharmony_ci struct IBufferProducer::RequestBufferReturnValue &retval) 44732a6e48fSopenharmony_ci{ 44832a6e48fSopenharmony_ci if (retval.buffer == nullptr) { 44932a6e48fSopenharmony_ci BLOGE("input buffer is null, uniqueId: %{public}" PRIu64 ".", uniqueId_); 45032a6e48fSopenharmony_ci return SURFACE_ERROR_UNKOWN; 45132a6e48fSopenharmony_ci } 45232a6e48fSopenharmony_ci retval.sequence = retval.buffer->GetSeqNum(); 45332a6e48fSopenharmony_ci if (bufferQueueCache_.find(retval.sequence) == bufferQueueCache_.end()) { 45432a6e48fSopenharmony_ci BLOGE("cache not find the buffer(%{public}u), uniqueId: %{public}" PRIu64 ".", retval.sequence, uniqueId_); 45532a6e48fSopenharmony_ci return SURFACE_ERROR_UNKOWN; 45632a6e48fSopenharmony_ci } 45732a6e48fSopenharmony_ci auto &cacheConfig = bufferQueueCache_[retval.sequence].config; 45832a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("ReuseBuffer config width: %d height: %d usage: %llu format: %d id: %u", 45932a6e48fSopenharmony_ci cacheConfig.width, cacheConfig.height, cacheConfig.usage, cacheConfig.format, retval.sequence); 46032a6e48fSopenharmony_ci 46132a6e48fSopenharmony_ci bool needRealloc = (config != bufferQueueCache_[retval.sequence].config); 46232a6e48fSopenharmony_ci // config, realloc 46332a6e48fSopenharmony_ci if (needRealloc) { 46432a6e48fSopenharmony_ci auto sret = ReallocBufferLocked(config, retval); 46532a6e48fSopenharmony_ci if (sret != GSERROR_OK) { 46632a6e48fSopenharmony_ci return sret; 46732a6e48fSopenharmony_ci } 46832a6e48fSopenharmony_ci } 46932a6e48fSopenharmony_ci 47032a6e48fSopenharmony_ci bufferQueueCache_[retval.sequence].state = BUFFER_STATE_REQUESTED; 47132a6e48fSopenharmony_ci retval.fence = bufferQueueCache_[retval.sequence].fence; 47232a6e48fSopenharmony_ci bedata = retval.buffer->GetExtraData(); 47332a6e48fSopenharmony_ci SetSurfaceBufferHebcMetaLocked(retval.buffer); 47432a6e48fSopenharmony_ci SetSurfaceBufferGlobalAlphaUnlocked(retval.buffer); 47532a6e48fSopenharmony_ci 47632a6e48fSopenharmony_ci auto &dbs = retval.deletingBuffers; 47732a6e48fSopenharmony_ci dbs.reserve(dbs.size() + deletingList_.size()); 47832a6e48fSopenharmony_ci dbs.insert(dbs.end(), deletingList_.begin(), deletingList_.end()); 47932a6e48fSopenharmony_ci deletingList_.clear(); 48032a6e48fSopenharmony_ci 48132a6e48fSopenharmony_ci if (needRealloc || isShared_ || producerCacheClean_ || retval.buffer->GetConsumerAttachBufferFlag()) { 48232a6e48fSopenharmony_ci BLOGD("requestBuffer Succ realloc Buffer[%{public}d %{public}d] with new config "\ 48332a6e48fSopenharmony_ci "seq: %{public}u attachFlag: %{public}d, uniqueId: %{public}" PRIu64 ".", 48432a6e48fSopenharmony_ci config.width, config.height, retval.sequence, retval.buffer->GetConsumerAttachBufferFlag(), uniqueId_); 48532a6e48fSopenharmony_ci if (producerCacheClean_) { 48632a6e48fSopenharmony_ci producerCacheList_.push_back(retval.sequence); 48732a6e48fSopenharmony_ci if (CheckProducerCacheListLocked()) { 48832a6e48fSopenharmony_ci SetProducerCacheCleanFlagLocked(false); 48932a6e48fSopenharmony_ci } 49032a6e48fSopenharmony_ci } 49132a6e48fSopenharmony_ci retval.buffer->SetConsumerAttachBufferFlag(false); 49232a6e48fSopenharmony_ci } else { 49332a6e48fSopenharmony_ci BLOGD("RequestBuffer Succ Buffer[%{public}d %{public}d] in seq id: %{public}u "\ 49432a6e48fSopenharmony_ci "releaseFence: %{public}d, uniqueId: %{public}" PRIu64 ".", 49532a6e48fSopenharmony_ci config.width, config.height, retval.sequence, retval.fence->Get(), uniqueId_); 49632a6e48fSopenharmony_ci retval.buffer = nullptr; 49732a6e48fSopenharmony_ci } 49832a6e48fSopenharmony_ci 49932a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("%s:%u", name_.c_str(), retval.sequence); 50032a6e48fSopenharmony_ci if (IsTagEnabled(HITRACE_TAG_GRAPHIC_AGP) && isLocalRender_) { 50132a6e48fSopenharmony_ci static SyncFenceTracker releaseFenceThread("Release Fence"); 50232a6e48fSopenharmony_ci releaseFenceThread.TrackFence(retval.fence); 50332a6e48fSopenharmony_ci } 50432a6e48fSopenharmony_ci return GSERROR_OK; 50532a6e48fSopenharmony_ci} 50632a6e48fSopenharmony_ci 50732a6e48fSopenharmony_ciGSError BufferQueue::CancelBuffer(uint32_t sequence, sptr<BufferExtraData> bedata) 50832a6e48fSopenharmony_ci{ 50932a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("CancelBuffer name: %s queueId: %" PRIu64 " sequence: %u", 51032a6e48fSopenharmony_ci name_.c_str(), uniqueId_, sequence); 51132a6e48fSopenharmony_ci if (isShared_) { 51232a6e48fSopenharmony_ci BLOGN_FAILURE_RET(GSERROR_INVALID_OPERATING); 51332a6e48fSopenharmony_ci } 51432a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 51532a6e48fSopenharmony_ci 51632a6e48fSopenharmony_ci if (bufferQueueCache_.find(sequence) == bufferQueueCache_.end()) { 51732a6e48fSopenharmony_ci return SURFACE_ERROR_BUFFER_NOT_INCACHE; 51832a6e48fSopenharmony_ci } 51932a6e48fSopenharmony_ci 52032a6e48fSopenharmony_ci if (bufferQueueCache_[sequence].state != BUFFER_STATE_REQUESTED && 52132a6e48fSopenharmony_ci bufferQueueCache_[sequence].state != BUFFER_STATE_ATTACHED) { 52232a6e48fSopenharmony_ci return SURFACE_ERROR_BUFFER_STATE_INVALID; 52332a6e48fSopenharmony_ci } 52432a6e48fSopenharmony_ci bufferQueueCache_[sequence].state = BUFFER_STATE_RELEASED; 52532a6e48fSopenharmony_ci freeList_.push_back(sequence); 52632a6e48fSopenharmony_ci if (bufferQueueCache_[sequence].buffer == nullptr) { 52732a6e48fSopenharmony_ci BLOGE("cache buffer is nullptr, sequence:%{public}u, uniqueId: %{public}" PRIu64 ".", sequence, uniqueId_); 52832a6e48fSopenharmony_ci return SURFACE_ERROR_UNKOWN; 52932a6e48fSopenharmony_ci } 53032a6e48fSopenharmony_ci bufferQueueCache_[sequence].buffer->SetExtraData(bedata); 53132a6e48fSopenharmony_ci 53232a6e48fSopenharmony_ci waitReqCon_.notify_all(); 53332a6e48fSopenharmony_ci waitAttachCon_.notify_all(); 53432a6e48fSopenharmony_ci BLOGD("Success Buffer id: %{public}d, uniqueId: %{public}" PRIu64 ".", sequence, uniqueId_); 53532a6e48fSopenharmony_ci 53632a6e48fSopenharmony_ci return GSERROR_OK; 53732a6e48fSopenharmony_ci} 53832a6e48fSopenharmony_ci 53932a6e48fSopenharmony_ciGSError BufferQueue::CheckBufferQueueCache(uint32_t sequence) 54032a6e48fSopenharmony_ci{ 54132a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 54232a6e48fSopenharmony_ci if (bufferQueueCache_.find(sequence) == bufferQueueCache_.end()) { 54332a6e48fSopenharmony_ci BLOGE("no find seq: %{public}u, uniqueId: %{public}" PRIu64 ".", sequence, uniqueId_); 54432a6e48fSopenharmony_ci return SURFACE_ERROR_BUFFER_NOT_INCACHE; 54532a6e48fSopenharmony_ci } 54632a6e48fSopenharmony_ci 54732a6e48fSopenharmony_ci if (isShared_ == false) { 54832a6e48fSopenharmony_ci auto &state = bufferQueueCache_[sequence].state; 54932a6e48fSopenharmony_ci if (state != BUFFER_STATE_REQUESTED && state != BUFFER_STATE_ATTACHED) { 55032a6e48fSopenharmony_ci BLOGE("seq: %{public}u, invalid state %{public}d, uniqueId: %{public}" PRIu64 ".", 55132a6e48fSopenharmony_ci sequence, state, uniqueId_); 55232a6e48fSopenharmony_ci return SURFACE_ERROR_BUFFER_STATE_INVALID; 55332a6e48fSopenharmony_ci } 55432a6e48fSopenharmony_ci } 55532a6e48fSopenharmony_ci return GSERROR_OK; 55632a6e48fSopenharmony_ci} 55732a6e48fSopenharmony_ci 55832a6e48fSopenharmony_ciGSError BufferQueue::DelegatorQueueBuffer(uint32_t sequence, sptr<SyncFence> fence) 55932a6e48fSopenharmony_ci{ 56032a6e48fSopenharmony_ci auto consumerDelegator = wpCSurfaceDelegator_.promote(); 56132a6e48fSopenharmony_ci if (consumerDelegator == nullptr) { 56232a6e48fSopenharmony_ci BLOGE("Consumer surface delegator has been expired"); 56332a6e48fSopenharmony_ci return GSERROR_INVALID_ARGUMENTS; 56432a6e48fSopenharmony_ci } 56532a6e48fSopenharmony_ci sptr<SurfaceBuffer> buffer = nullptr; 56632a6e48fSopenharmony_ci { 56732a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 56832a6e48fSopenharmony_ci if (bufferQueueCache_.find(sequence) == bufferQueueCache_.end()) { 56932a6e48fSopenharmony_ci return GSERROR_NO_ENTRY; 57032a6e48fSopenharmony_ci } 57132a6e48fSopenharmony_ci bufferQueueCache_[sequence].state = BUFFER_STATE_ACQUIRED; 57232a6e48fSopenharmony_ci buffer = bufferQueueCache_[sequence].buffer; 57332a6e48fSopenharmony_ci } 57432a6e48fSopenharmony_ci GSError ret = consumerDelegator->QueueBuffer(buffer, fence->Get()); 57532a6e48fSopenharmony_ci if (ret != GSERROR_OK) { 57632a6e48fSopenharmony_ci BLOGE("Consumer surface delegator failed to queuebuffer"); 57732a6e48fSopenharmony_ci } 57832a6e48fSopenharmony_ci ret = ReleaseBuffer(buffer, SyncFence::InvalidFence()); 57932a6e48fSopenharmony_ci if (ret != GSERROR_OK) { 58032a6e48fSopenharmony_ci BLOGE("Consumer surface delegator failed to releasebuffer"); 58132a6e48fSopenharmony_ci } 58232a6e48fSopenharmony_ci return ret; 58332a6e48fSopenharmony_ci} 58432a6e48fSopenharmony_ci 58532a6e48fSopenharmony_civoid BufferQueue::CallConsumerListener() 58632a6e48fSopenharmony_ci{ 58732a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("CallConsumerListener"); 58832a6e48fSopenharmony_ci sptr<IBufferConsumerListener> listener; 58932a6e48fSopenharmony_ci IBufferConsumerListenerClazz *listenerClazz; 59032a6e48fSopenharmony_ci { 59132a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(listenerMutex_); 59232a6e48fSopenharmony_ci listener = listener_; 59332a6e48fSopenharmony_ci listenerClazz = listenerClazz_; 59432a6e48fSopenharmony_ci } 59532a6e48fSopenharmony_ci if (listener != nullptr) { 59632a6e48fSopenharmony_ci listener->OnBufferAvailable(); 59732a6e48fSopenharmony_ci } else if (listenerClazz != nullptr) { 59832a6e48fSopenharmony_ci listenerClazz->OnBufferAvailable(); 59932a6e48fSopenharmony_ci } 60032a6e48fSopenharmony_ci} 60132a6e48fSopenharmony_ci 60232a6e48fSopenharmony_ciGSError BufferQueue::FlushBuffer(uint32_t sequence, sptr<BufferExtraData> bedata, 60332a6e48fSopenharmony_ci sptr<SyncFence> fence, const BufferFlushConfigWithDamages &config) 60432a6e48fSopenharmony_ci{ 60532a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("FlushBuffer name: %s queueId: %" PRIu64 " sequence: %u", 60632a6e48fSopenharmony_ci name_.c_str(), uniqueId_, sequence); 60732a6e48fSopenharmony_ci { 60832a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 60932a6e48fSopenharmony_ci if (!GetStatusLocked()) { 61032a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("status: %d", GetStatusLocked()); 61132a6e48fSopenharmony_ci BLOGN_FAILURE_RET(GSERROR_NO_CONSUMER); 61232a6e48fSopenharmony_ci } 61332a6e48fSopenharmony_ci } 61432a6e48fSopenharmony_ci // check param 61532a6e48fSopenharmony_ci auto sret = CheckFlushConfig(config); 61632a6e48fSopenharmony_ci if (sret != GSERROR_OK) { 61732a6e48fSopenharmony_ci BLOGE("CheckFlushConfig ret: %{public}d, uniqueId: %{public}" PRIu64 ".", sret, uniqueId_); 61832a6e48fSopenharmony_ci return sret; 61932a6e48fSopenharmony_ci } 62032a6e48fSopenharmony_ci 62132a6e48fSopenharmony_ci sret = CheckBufferQueueCache(sequence); 62232a6e48fSopenharmony_ci if (sret != GSERROR_OK) { 62332a6e48fSopenharmony_ci return sret; 62432a6e48fSopenharmony_ci } 62532a6e48fSopenharmony_ci 62632a6e48fSopenharmony_ci { 62732a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(listenerMutex_); 62832a6e48fSopenharmony_ci if (listener_ == nullptr && listenerClazz_ == nullptr) { 62932a6e48fSopenharmony_ci SURFACE_TRACE_NAME("listener is nullptr"); 63032a6e48fSopenharmony_ci BLOGE("listener is nullptr, uniqueId: %{public}" PRIu64 ".", uniqueId_); 63132a6e48fSopenharmony_ci CancelBuffer(sequence, bedata); 63232a6e48fSopenharmony_ci return SURFACE_ERROR_CONSUMER_UNREGISTER_LISTENER; 63332a6e48fSopenharmony_ci } 63432a6e48fSopenharmony_ci } 63532a6e48fSopenharmony_ci 63632a6e48fSopenharmony_ci sret = DoFlushBuffer(sequence, bedata, fence, config); 63732a6e48fSopenharmony_ci if (sret != GSERROR_OK) { 63832a6e48fSopenharmony_ci return sret; 63932a6e48fSopenharmony_ci } 64032a6e48fSopenharmony_ci CallConsumerListener(); 64132a6e48fSopenharmony_ci BLOGD("Success Buffer seq id: %{public}d AcquireFence:%{public}d, uniqueId: %{public}" PRIu64 ".", 64232a6e48fSopenharmony_ci sequence, fence->Get(), uniqueId_); 64332a6e48fSopenharmony_ci 64432a6e48fSopenharmony_ci if (wpCSurfaceDelegator_ != nullptr) { 64532a6e48fSopenharmony_ci sret = DelegatorQueueBuffer(sequence, fence); 64632a6e48fSopenharmony_ci } 64732a6e48fSopenharmony_ci return sret; 64832a6e48fSopenharmony_ci} 64932a6e48fSopenharmony_ci 65032a6e48fSopenharmony_ciGSError BufferQueue::GetLastFlushedBuffer(sptr<SurfaceBuffer>& buffer, 65132a6e48fSopenharmony_ci sptr<SyncFence>& fence, float matrix[16], uint32_t matrixSize, bool isUseNewMatrix, bool needRecordSequence) 65232a6e48fSopenharmony_ci{ 65332a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 65432a6e48fSopenharmony_ci if (needRecordSequence && acquireLastFlushedBufSequence_ != INVALID_SEQUENCE) { 65532a6e48fSopenharmony_ci BLOGE("last flushed buffer(%{public}d) is using, uniqueId: %{public}" PRIu64 ".", 65632a6e48fSopenharmony_ci acquireLastFlushedBufSequence_, uniqueId_); 65732a6e48fSopenharmony_ci return SURFACE_ERROR_BUFFER_STATE_INVALID; 65832a6e48fSopenharmony_ci } 65932a6e48fSopenharmony_ci if (bufferQueueCache_.find(lastFlusedSequence_) == bufferQueueCache_.end()) { 66032a6e48fSopenharmony_ci BLOGE("cache ont find the buffer(%{public}u), uniqueId: %{public}" PRIu64 ".", lastFlusedSequence_, uniqueId_); 66132a6e48fSopenharmony_ci return SURFACE_ERROR_UNKOWN; 66232a6e48fSopenharmony_ci } 66332a6e48fSopenharmony_ci auto &state = bufferQueueCache_[lastFlusedSequence_].state; 66432a6e48fSopenharmony_ci if (state == BUFFER_STATE_REQUESTED) { 66532a6e48fSopenharmony_ci BLOGE("seq: %{public}u, invalid state %{public}d, uniqueId: %{public}" PRIu64 ".", 66632a6e48fSopenharmony_ci lastFlusedSequence_, state, uniqueId_); 66732a6e48fSopenharmony_ci return SURFACE_ERROR_BUFFER_STATE_INVALID; 66832a6e48fSopenharmony_ci } 66932a6e48fSopenharmony_ci buffer = bufferQueueCache_[lastFlusedSequence_].buffer; 67032a6e48fSopenharmony_ci auto usage = buffer->GetUsage(); 67132a6e48fSopenharmony_ci if (usage & BUFFER_USAGE_PROTECTED) { 67232a6e48fSopenharmony_ci BLOGE("lastFlusedSeq: %{public}u, usage: %{public}" PRIu64 ", uniqueId: %{public}" PRIu64 ".", 67332a6e48fSopenharmony_ci lastFlusedSequence_, usage, uniqueId_); 67432a6e48fSopenharmony_ci return SURFACE_ERROR_NOT_SUPPORT; 67532a6e48fSopenharmony_ci } 67632a6e48fSopenharmony_ci 67732a6e48fSopenharmony_ci fence = lastFlusedFence_; 67832a6e48fSopenharmony_ci Rect damage = {}; 67932a6e48fSopenharmony_ci damage.w = buffer->GetWidth(); 68032a6e48fSopenharmony_ci damage.h = buffer->GetHeight(); 68132a6e48fSopenharmony_ci 68232a6e48fSopenharmony_ci auto utils = SurfaceUtils::GetInstance(); 68332a6e48fSopenharmony_ci if (isUseNewMatrix) { 68432a6e48fSopenharmony_ci utils->ComputeTransformMatrixV2(matrix, matrixSize, buffer, lastFlushedTransform_, damage); 68532a6e48fSopenharmony_ci } else { 68632a6e48fSopenharmony_ci utils->ComputeTransformMatrix(matrix, matrixSize, buffer, lastFlushedTransform_, damage); 68732a6e48fSopenharmony_ci } 68832a6e48fSopenharmony_ci 68932a6e48fSopenharmony_ci if (needRecordSequence) { 69032a6e48fSopenharmony_ci acquireLastFlushedBufSequence_ = lastFlusedSequence_; 69132a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("GetLastFlushedBuffer(needRecordSequence) name: %s queueId: %" PRIu64 " seq: %u", 69232a6e48fSopenharmony_ci name_.c_str(), uniqueId_, acquireLastFlushedBufSequence_); 69332a6e48fSopenharmony_ci } 69432a6e48fSopenharmony_ci return GSERROR_OK; 69532a6e48fSopenharmony_ci} 69632a6e48fSopenharmony_ci 69732a6e48fSopenharmony_ciGSError BufferQueue::AcquireLastFlushedBuffer(sptr<SurfaceBuffer> &buffer, sptr<SyncFence> &fence, 69832a6e48fSopenharmony_ci float matrix[16], uint32_t matrixSize, bool isUseNewMatrix) 69932a6e48fSopenharmony_ci{ 70032a6e48fSopenharmony_ci return GetLastFlushedBuffer(buffer, fence, matrix, matrixSize, isUseNewMatrix, true); 70132a6e48fSopenharmony_ci} 70232a6e48fSopenharmony_ci 70332a6e48fSopenharmony_ciGSError BufferQueue::ReleaseLastFlushedBuffer(uint32_t sequence) 70432a6e48fSopenharmony_ci{ 70532a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("ReleaseLastFlushedBuffer name: %s queueId: %" PRIu64 " seq: %u", 70632a6e48fSopenharmony_ci name_.c_str(), uniqueId_, sequence); 70732a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 70832a6e48fSopenharmony_ci if (acquireLastFlushedBufSequence_ == INVALID_SEQUENCE || acquireLastFlushedBufSequence_ != sequence) { 70932a6e48fSopenharmony_ci BLOGE("ReleaseLastFlushedBuffer lastFlushBuffer:%{public}d sequence:%{public}d, uniqueId: %{public}" PRIu64, 71032a6e48fSopenharmony_ci acquireLastFlushedBufSequence_, sequence, uniqueId_); 71132a6e48fSopenharmony_ci return SURFACE_ERROR_BUFFER_STATE_INVALID; 71232a6e48fSopenharmony_ci } 71332a6e48fSopenharmony_ci acquireLastFlushedBufSequence_ = INVALID_SEQUENCE; 71432a6e48fSopenharmony_ci waitReqCon_.notify_all(); 71532a6e48fSopenharmony_ci return GSERROR_OK; 71632a6e48fSopenharmony_ci} 71732a6e48fSopenharmony_ci 71832a6e48fSopenharmony_ciGSError BufferQueue::DoFlushBuffer(uint32_t sequence, sptr<BufferExtraData> bedata, 71932a6e48fSopenharmony_ci sptr<SyncFence> fence, const BufferFlushConfigWithDamages &config) 72032a6e48fSopenharmony_ci{ 72132a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("DoFlushBuffer name: %s queueId: %" PRIu64 " seq: %u", 72232a6e48fSopenharmony_ci name_.c_str(), uniqueId_, sequence); 72332a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 72432a6e48fSopenharmony_ci if (bufferQueueCache_.find(sequence) == bufferQueueCache_.end()) { 72532a6e48fSopenharmony_ci BLOGE("bufferQueueCache not find sequence:%{public}u, uniqueId: %{public}" PRIu64 ".", sequence, uniqueId_); 72632a6e48fSopenharmony_ci return SURFACE_ERROR_BUFFER_NOT_INCACHE; 72732a6e48fSopenharmony_ci } 72832a6e48fSopenharmony_ci if (bufferQueueCache_[sequence].isDeleting) { 72932a6e48fSopenharmony_ci DeleteBufferInCache(sequence); 73032a6e48fSopenharmony_ci BLOGD("DoFlushBuffer delete seq: %{public}d, uniqueId: %{public}" PRIu64 ".", sequence, uniqueId_); 73132a6e48fSopenharmony_ci CountTrace(HITRACE_TAG_GRAPHIC_AGP, name_, static_cast<int32_t>(dirtyList_.size())); 73232a6e48fSopenharmony_ci return GSERROR_OK; 73332a6e48fSopenharmony_ci } 73432a6e48fSopenharmony_ci 73532a6e48fSopenharmony_ci bufferQueueCache_[sequence].state = BUFFER_STATE_FLUSHED; 73632a6e48fSopenharmony_ci dirtyList_.push_back(sequence); 73732a6e48fSopenharmony_ci bufferQueueCache_[sequence].buffer->SetExtraData(bedata); 73832a6e48fSopenharmony_ci bufferQueueCache_[sequence].fence = fence; 73932a6e48fSopenharmony_ci bufferQueueCache_[sequence].damages = config.damages; 74032a6e48fSopenharmony_ci lastFlusedSequence_ = sequence; 74132a6e48fSopenharmony_ci lastFlusedFence_ = fence; 74232a6e48fSopenharmony_ci lastFlushedTransform_ = transform_; 74332a6e48fSopenharmony_ci bufferQueueCache_[sequence].buffer->SetSurfaceBufferTransform(transform_); 74432a6e48fSopenharmony_ci 74532a6e48fSopenharmony_ci uint64_t usage = static_cast<uint32_t>(bufferQueueCache_[sequence].config.usage); 74632a6e48fSopenharmony_ci if (usage & BUFFER_USAGE_CPU_WRITE) { 74732a6e48fSopenharmony_ci // api flush 74832a6e48fSopenharmony_ci auto sret = bufferQueueCache_[sequence].buffer->FlushCache(); 74932a6e48fSopenharmony_ci if (sret != GSERROR_OK) { 75032a6e48fSopenharmony_ci BLOGE("FlushCache ret: %{public}d, seq: %{public}u, uniqueId: %{public}" PRIu64 ".", 75132a6e48fSopenharmony_ci sret, sequence, uniqueId_); 75232a6e48fSopenharmony_ci return sret; 75332a6e48fSopenharmony_ci } 75432a6e48fSopenharmony_ci } 75532a6e48fSopenharmony_ci SetDesiredPresentTimestampAndUiTimestamp(sequence, config.desiredPresentTimestamp, config.timestamp); 75632a6e48fSopenharmony_ci bool traceTag = IsTagEnabled(HITRACE_TAG_GRAPHIC_AGP); 75732a6e48fSopenharmony_ci if (isLocalRender_) { 75832a6e48fSopenharmony_ci AcquireFenceTracker::TrackFence(fence, traceTag); 75932a6e48fSopenharmony_ci } 76032a6e48fSopenharmony_ci // if you need dump SurfaceBuffer to file, you should execute hdc shell param set persist.dumpbuffer.enabled 1 76132a6e48fSopenharmony_ci // and reboot your device 76232a6e48fSopenharmony_ci static bool dumpBufferEnabled = system::GetParameter("persist.dumpbuffer.enabled", "0") != "0"; 76332a6e48fSopenharmony_ci if (dumpBufferEnabled) { 76432a6e48fSopenharmony_ci // Wait for the status of the fence to change to SIGNALED. 76532a6e48fSopenharmony_ci fence->Wait(-1); 76632a6e48fSopenharmony_ci DumpToFileAsync(GetRealPid(), name_, bufferQueueCache_[sequence].buffer); 76732a6e48fSopenharmony_ci } 76832a6e48fSopenharmony_ci 76932a6e48fSopenharmony_ci CountTrace(HITRACE_TAG_GRAPHIC_AGP, name_, static_cast<int32_t>(dirtyList_.size())); 77032a6e48fSopenharmony_ci return GSERROR_OK; 77132a6e48fSopenharmony_ci} 77232a6e48fSopenharmony_ci 77332a6e48fSopenharmony_civoid BufferQueue::SetDesiredPresentTimestampAndUiTimestamp(uint32_t sequence, int64_t desiredPresentTimestamp, 77432a6e48fSopenharmony_ci uint64_t uiTimestamp) 77532a6e48fSopenharmony_ci{ 77632a6e48fSopenharmony_ci if (desiredPresentTimestamp <= 0) { 77732a6e48fSopenharmony_ci if (desiredPresentTimestamp == 0 && uiTimestamp != 0 77832a6e48fSopenharmony_ci && uiTimestamp <= static_cast<uint64_t>(std::numeric_limits<int64_t>::max())) { 77932a6e48fSopenharmony_ci bufferQueueCache_[sequence].desiredPresentTimestamp = static_cast<int64_t>(uiTimestamp); 78032a6e48fSopenharmony_ci } else { 78132a6e48fSopenharmony_ci bufferQueueCache_[sequence].desiredPresentTimestamp = std::chrono::duration_cast<std::chrono::nanoseconds>( 78232a6e48fSopenharmony_ci std::chrono::steady_clock::now().time_since_epoch()).count(); 78332a6e48fSopenharmony_ci bufferQueueCache_[sequence].isAutoTimestamp = true; 78432a6e48fSopenharmony_ci } 78532a6e48fSopenharmony_ci } else { 78632a6e48fSopenharmony_ci bufferQueueCache_[sequence].desiredPresentTimestamp = desiredPresentTimestamp; 78732a6e48fSopenharmony_ci } 78832a6e48fSopenharmony_ci bufferQueueCache_[sequence].timestamp = static_cast<int64_t>(uiTimestamp); 78932a6e48fSopenharmony_ci} 79032a6e48fSopenharmony_ci 79132a6e48fSopenharmony_civoid BufferQueue::LogAndTraceAllBufferInBufferQueueCache() 79232a6e48fSopenharmony_ci{ 79332a6e48fSopenharmony_ci std::map<BufferState, int32_t> bufferState; 79432a6e48fSopenharmony_ci for (auto &[id, ele] : bufferQueueCache_) { 79532a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("acquire buffer id: %d state: %d desiredPresentTimestamp: %" PRId64 79632a6e48fSopenharmony_ci " isAotuTimestamp: %d", id, ele.state, ele.desiredPresentTimestamp, ele.isAutoTimestamp); 79732a6e48fSopenharmony_ci BLOGD("acquire no buffer, buffer id:%{public}d state:%{public}d, uniqueId: %{public}" PRIu64 79832a6e48fSopenharmony_ci "desiredPresentTimestamp: %{public}" PRId64 " isAotuTimestamp: %{public}d.", 79932a6e48fSopenharmony_ci id, ele.state, uniqueId_, ele.desiredPresentTimestamp, ele.isAutoTimestamp); 80032a6e48fSopenharmony_ci bufferState[ele.state] += 1; 80132a6e48fSopenharmony_ci } 80232a6e48fSopenharmony_ci std::string str = std::to_string(uniqueId_) + 80332a6e48fSopenharmony_ci ", Released: " + std::to_string(bufferState[BUFFER_STATE_RELEASED]) + 80432a6e48fSopenharmony_ci " Requested: " + std::to_string(bufferState[BUFFER_STATE_REQUESTED]) + 80532a6e48fSopenharmony_ci " Flushed: " + std::to_string(bufferState[BUFFER_STATE_FLUSHED]) + 80632a6e48fSopenharmony_ci " Acquired: " + std::to_string(bufferState[BUFFER_STATE_ACQUIRED]); 80732a6e48fSopenharmony_ci if (str.compare(acquireBufferStateStr_) != 0) { 80832a6e48fSopenharmony_ci acquireBufferStateStr_ = str; 80932a6e48fSopenharmony_ci BLOGE("there is no dirty buffer or no dirty buffer ready, uniqueId: %{public}s", str.c_str()); 81032a6e48fSopenharmony_ci } 81132a6e48fSopenharmony_ci} 81232a6e48fSopenharmony_ci 81332a6e48fSopenharmony_ciGSError BufferQueue::AcquireBuffer(sptr<SurfaceBuffer> &buffer, 81432a6e48fSopenharmony_ci sptr<SyncFence> &fence, int64_t ×tamp, std::vector<Rect> &damages) 81532a6e48fSopenharmony_ci{ 81632a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("AcquireBuffer name: %s queueId: %" PRIu64, name_.c_str(), uniqueId_); 81732a6e48fSopenharmony_ci // dequeue from dirty list 81832a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 81932a6e48fSopenharmony_ci GSError ret = PopFromDirtyListLocked(buffer); 82032a6e48fSopenharmony_ci if (ret == GSERROR_OK) { 82132a6e48fSopenharmony_ci uint32_t sequence = buffer->GetSeqNum(); 82232a6e48fSopenharmony_ci bufferQueueCache_[sequence].state = BUFFER_STATE_ACQUIRED; 82332a6e48fSopenharmony_ci 82432a6e48fSopenharmony_ci fence = bufferQueueCache_[sequence].fence; 82532a6e48fSopenharmony_ci timestamp = bufferQueueCache_[sequence].timestamp; 82632a6e48fSopenharmony_ci damages = bufferQueueCache_[sequence].damages; 82732a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("acquire buffer sequence: %u", sequence); 82832a6e48fSopenharmony_ci BLOGD("Success Buffer seq id: %{public}u AcquireFence:%{public}d, uniqueId: %{public}" PRIu64 ".", 82932a6e48fSopenharmony_ci sequence, fence->Get(), uniqueId_); 83032a6e48fSopenharmony_ci } else if (ret == GSERROR_NO_BUFFER) { 83132a6e48fSopenharmony_ci LogAndTraceAllBufferInBufferQueueCache(); 83232a6e48fSopenharmony_ci } 83332a6e48fSopenharmony_ci 83432a6e48fSopenharmony_ci CountTrace(HITRACE_TAG_GRAPHIC_AGP, name_, static_cast<int32_t>(dirtyList_.size())); 83532a6e48fSopenharmony_ci return ret; 83632a6e48fSopenharmony_ci} 83732a6e48fSopenharmony_ci 83832a6e48fSopenharmony_ciGSError BufferQueue::AcquireBuffer(IConsumerSurface::AcquireBufferReturnValue &returnValue, 83932a6e48fSopenharmony_ci int64_t expectPresentTimestamp, bool isUsingAutoTimestamp) 84032a6e48fSopenharmony_ci{ 84132a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("AcquireBuffer with PresentTimestamp name: %s queueId: %" PRIu64 " queueSize: %u" 84232a6e48fSopenharmony_ci "expectPresentTimestamp: %" PRId64, name_.c_str(), uniqueId_, bufferQueueSize_, expectPresentTimestamp); 84332a6e48fSopenharmony_ci if (isShared_ || expectPresentTimestamp <= 0) { 84432a6e48fSopenharmony_ci return AcquireBuffer(returnValue.buffer, returnValue.fence, returnValue.timestamp, returnValue.damages); 84532a6e48fSopenharmony_ci } 84632a6e48fSopenharmony_ci std::vector<BufferElement*> dropBufferElements; 84732a6e48fSopenharmony_ci // traverse dirtyList_ 84832a6e48fSopenharmony_ci { 84932a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 85032a6e48fSopenharmony_ci std::list<uint32_t>::iterator frontSequence = dirtyList_.begin(); 85132a6e48fSopenharmony_ci if (frontSequence == dirtyList_.end()) { 85232a6e48fSopenharmony_ci LogAndTraceAllBufferInBufferQueueCache(); 85332a6e48fSopenharmony_ci return GSERROR_NO_BUFFER; 85432a6e48fSopenharmony_ci } 85532a6e48fSopenharmony_ci BufferElement& frontBufferElement = bufferQueueCache_[*frontSequence]; 85632a6e48fSopenharmony_ci int64_t frontDesiredPresentTimestamp = frontBufferElement.desiredPresentTimestamp; 85732a6e48fSopenharmony_ci bool frontIsAutoTimestamp = frontBufferElement.isAutoTimestamp; 85832a6e48fSopenharmony_ci if (!frontIsAutoTimestamp && frontDesiredPresentTimestamp > expectPresentTimestamp 85932a6e48fSopenharmony_ci && frontDesiredPresentTimestamp - ONE_SECOND_TIMESTAMP <= expectPresentTimestamp) { 86032a6e48fSopenharmony_ci LogAndTraceAllBufferInBufferQueueCache(); 86132a6e48fSopenharmony_ci return GSERROR_NO_BUFFER_READY; 86232a6e48fSopenharmony_ci } 86332a6e48fSopenharmony_ci while (!(frontIsAutoTimestamp && !isUsingAutoTimestamp) 86432a6e48fSopenharmony_ci && frontDesiredPresentTimestamp <= expectPresentTimestamp) { 86532a6e48fSopenharmony_ci BufferElement& frontBufferElement = bufferQueueCache_[*frontSequence]; 86632a6e48fSopenharmony_ci if (++frontSequence == dirtyList_.end()) { 86732a6e48fSopenharmony_ci BLOGD("Buffer seq(%{public}d) is the last buffer, do acquire.", dirtyList_.front()); 86832a6e48fSopenharmony_ci break; 86932a6e48fSopenharmony_ci } 87032a6e48fSopenharmony_ci BufferElement& secondBufferElement = bufferQueueCache_[*frontSequence]; 87132a6e48fSopenharmony_ci 87232a6e48fSopenharmony_ci if ((secondBufferElement.isAutoTimestamp && !isUsingAutoTimestamp) 87332a6e48fSopenharmony_ci || secondBufferElement.desiredPresentTimestamp > expectPresentTimestamp) { 87432a6e48fSopenharmony_ci BLOGD("Next dirty buffer desiredPresentTimestamp: %{public}" PRId64 " not match expectPresentTimestamp" 87532a6e48fSopenharmony_ci ": %{public}" PRId64 ".", secondBufferElement.desiredPresentTimestamp, expectPresentTimestamp); 87632a6e48fSopenharmony_ci break; 87732a6e48fSopenharmony_ci } 87832a6e48fSopenharmony_ci //second buffer match, should drop front buffer 87932a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("DropBuffer name: %s queueId: %" PRIu64 " ,buffer seq: %u , buffer " 88032a6e48fSopenharmony_ci "desiredPresentTimestamp: %" PRId64 " acquire expectPresentTimestamp: %" PRId64, name_.c_str(), 88132a6e48fSopenharmony_ci uniqueId_, frontBufferElement.buffer->GetSeqNum(), frontBufferElement.desiredPresentTimestamp, 88232a6e48fSopenharmony_ci expectPresentTimestamp); 88332a6e48fSopenharmony_ci dirtyList_.pop_front(); 88432a6e48fSopenharmony_ci frontBufferElement.state = BUFFER_STATE_ACQUIRED; 88532a6e48fSopenharmony_ci dropBufferElements.push_back(&frontBufferElement); 88632a6e48fSopenharmony_ci frontDesiredPresentTimestamp = secondBufferElement.desiredPresentTimestamp; 88732a6e48fSopenharmony_ci frontIsAutoTimestamp = secondBufferElement.isAutoTimestamp; 88832a6e48fSopenharmony_ci } 88932a6e48fSopenharmony_ci //Present Later When first buffer not ready 89032a6e48fSopenharmony_ci if (!frontIsAutoTimestamp && !IsPresentTimestampReady(frontDesiredPresentTimestamp, expectPresentTimestamp)) { 89132a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("Acquire no buffer ready"); 89232a6e48fSopenharmony_ci LogAndTraceAllBufferInBufferQueueCache(); 89332a6e48fSopenharmony_ci return GSERROR_NO_BUFFER_READY; 89432a6e48fSopenharmony_ci } 89532a6e48fSopenharmony_ci } 89632a6e48fSopenharmony_ci //drop buffers 89732a6e48fSopenharmony_ci for (const auto& dropBufferElement : dropBufferElements) { 89832a6e48fSopenharmony_ci if (dropBufferElement == nullptr) { 89932a6e48fSopenharmony_ci continue; 90032a6e48fSopenharmony_ci } 90132a6e48fSopenharmony_ci auto ret = ReleaseBuffer(dropBufferElement->buffer, dropBufferElement->fence); 90232a6e48fSopenharmony_ci if (ret != GSERROR_OK) { 90332a6e48fSopenharmony_ci BLOGE("DropBuffer failed, ret: %{public}d, sequence: %{public}u, uniqueId: %{public}" PRIu64 ".", 90432a6e48fSopenharmony_ci ret, dropBufferElement->buffer->GetSeqNum(), uniqueId_); 90532a6e48fSopenharmony_ci } 90632a6e48fSopenharmony_ci } 90732a6e48fSopenharmony_ci //Acquire 90832a6e48fSopenharmony_ci return AcquireBuffer(returnValue.buffer, returnValue.fence, returnValue.timestamp, returnValue.damages); 90932a6e48fSopenharmony_ci} 91032a6e48fSopenharmony_ci 91132a6e48fSopenharmony_cibool BufferQueue::IsPresentTimestampReady(int64_t desiredPresentTimestamp, int64_t expectPresentTimestamp) 91232a6e48fSopenharmony_ci{ 91332a6e48fSopenharmony_ci if (desiredPresentTimestamp <= expectPresentTimestamp) { 91432a6e48fSopenharmony_ci return true; 91532a6e48fSopenharmony_ci } 91632a6e48fSopenharmony_ci if (desiredPresentTimestamp - ONE_SECOND_TIMESTAMP > expectPresentTimestamp) { 91732a6e48fSopenharmony_ci return true; 91832a6e48fSopenharmony_ci } 91932a6e48fSopenharmony_ci return false; 92032a6e48fSopenharmony_ci} 92132a6e48fSopenharmony_ci 92232a6e48fSopenharmony_civoid BufferQueue::ListenerBufferReleasedCb(sptr<SurfaceBuffer> &buffer, const sptr<SyncFence> &fence) 92332a6e48fSopenharmony_ci{ 92432a6e48fSopenharmony_ci { 92532a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(onBufferReleaseMutex_); 92632a6e48fSopenharmony_ci if (onBufferRelease_ != nullptr) { 92732a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("OnBufferRelease_ sequence: %u", buffer->GetSeqNum()); 92832a6e48fSopenharmony_ci sptr<SurfaceBuffer> buf = buffer; 92932a6e48fSopenharmony_ci (void)onBufferRelease_(buf); 93032a6e48fSopenharmony_ci } 93132a6e48fSopenharmony_ci } 93232a6e48fSopenharmony_ci 93332a6e48fSopenharmony_ci sptr<IProducerListener> listener; 93432a6e48fSopenharmony_ci { 93532a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(producerListenerMutex_); 93632a6e48fSopenharmony_ci listener = producerListener_; 93732a6e48fSopenharmony_ci } 93832a6e48fSopenharmony_ci 93932a6e48fSopenharmony_ci if (listener != nullptr) { 94032a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("onBufferReleasedForProducer sequence: %u", buffer->GetSeqNum()); 94132a6e48fSopenharmony_ci if (listener->OnBufferReleased() != GSERROR_OK) { 94232a6e48fSopenharmony_ci BLOGE("seq: %{public}u, OnBufferReleased faile, uniqueId: %{public}" PRIu64 ".", 94332a6e48fSopenharmony_ci buffer->GetSeqNum(), uniqueId_); 94432a6e48fSopenharmony_ci } 94532a6e48fSopenharmony_ci if (listener->OnBufferReleasedWithFence(buffer, fence) != GSERROR_OK) { 94632a6e48fSopenharmony_ci BLOGE("seq: %{public}u, OnBufferReleasedWithFence failed, uniqueId: %{public}" PRIu64 ".", 94732a6e48fSopenharmony_ci buffer->GetSeqNum(), uniqueId_); 94832a6e48fSopenharmony_ci } 94932a6e48fSopenharmony_ci } 95032a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 95132a6e48fSopenharmony_ci OnBufferDeleteCbForHardwareThreadLocked(buffer); 95232a6e48fSopenharmony_ci} 95332a6e48fSopenharmony_ci 95432a6e48fSopenharmony_civoid BufferQueue::OnBufferDeleteCbForHardwareThreadLocked(const sptr<SurfaceBuffer> &buffer) const 95532a6e48fSopenharmony_ci{ 95632a6e48fSopenharmony_ci if (onBufferDeleteForRSHardwareThread_ != nullptr) { 95732a6e48fSopenharmony_ci onBufferDeleteForRSHardwareThread_(buffer->GetSeqNum()); 95832a6e48fSopenharmony_ci } 95932a6e48fSopenharmony_ci} 96032a6e48fSopenharmony_ci 96132a6e48fSopenharmony_ciGSError BufferQueue::ReleaseBuffer(sptr<SurfaceBuffer> &buffer, const sptr<SyncFence>& fence) 96232a6e48fSopenharmony_ci{ 96332a6e48fSopenharmony_ci if (buffer == nullptr) { 96432a6e48fSopenharmony_ci return GSERROR_INVALID_ARGUMENTS; 96532a6e48fSopenharmony_ci } 96632a6e48fSopenharmony_ci 96732a6e48fSopenharmony_ci uint32_t sequence = buffer->GetSeqNum(); 96832a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("ReleaseBuffer name: %s queueId: %" PRIu64 " seq: %u", name_.c_str(), uniqueId_, sequence); 96932a6e48fSopenharmony_ci { 97032a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 97132a6e48fSopenharmony_ci if (bufferQueueCache_.find(sequence) == bufferQueueCache_.end()) { 97232a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("buffer not found in cache"); 97332a6e48fSopenharmony_ci BLOGE("cache not find the buffer(%{public}u), uniqueId: %{public}" PRIu64 ".", sequence, uniqueId_); 97432a6e48fSopenharmony_ci OnBufferDeleteCbForHardwareThreadLocked(buffer); 97532a6e48fSopenharmony_ci return SURFACE_ERROR_BUFFER_NOT_INCACHE; 97632a6e48fSopenharmony_ci } 97732a6e48fSopenharmony_ci 97832a6e48fSopenharmony_ci if (isShared_ == false) { 97932a6e48fSopenharmony_ci const auto &state = bufferQueueCache_[sequence].state; 98032a6e48fSopenharmony_ci if (state != BUFFER_STATE_ACQUIRED && state != BUFFER_STATE_ATTACHED) { 98132a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("invalid state: %u", state); 98232a6e48fSopenharmony_ci BLOGD("invalid state: %{public}d, uniqueId: %{public}" PRIu64 ".", state, uniqueId_); 98332a6e48fSopenharmony_ci return SURFACE_ERROR_BUFFER_STATE_INVALID; 98432a6e48fSopenharmony_ci } 98532a6e48fSopenharmony_ci } 98632a6e48fSopenharmony_ci 98732a6e48fSopenharmony_ci bufferQueueCache_[sequence].state = BUFFER_STATE_RELEASED; 98832a6e48fSopenharmony_ci bufferQueueCache_[sequence].fence = fence; 98932a6e48fSopenharmony_ci 99032a6e48fSopenharmony_ci if (bufferQueueCache_[sequence].isDeleting) { 99132a6e48fSopenharmony_ci DeleteBufferInCache(sequence); 99232a6e48fSopenharmony_ci BLOGD("Succ delete Buffer seq id: %{public}u, uniqueId: %{public}" PRIu64 ".", sequence, uniqueId_); 99332a6e48fSopenharmony_ci } else { 99432a6e48fSopenharmony_ci freeList_.push_back(sequence); 99532a6e48fSopenharmony_ci BLOGD("Succ push Buffer seq id: %{public}u to free list, releaseFence: %{public}d," 99632a6e48fSopenharmony_ci "uniqueId: %{public}" PRIu64 ".", sequence, fence->Get(), uniqueId_); 99732a6e48fSopenharmony_ci } 99832a6e48fSopenharmony_ci waitReqCon_.notify_all(); 99932a6e48fSopenharmony_ci waitAttachCon_.notify_all(); 100032a6e48fSopenharmony_ci } 100132a6e48fSopenharmony_ci ListenerBufferReleasedCb(buffer, fence); 100232a6e48fSopenharmony_ci 100332a6e48fSopenharmony_ci return GSERROR_OK; 100432a6e48fSopenharmony_ci} 100532a6e48fSopenharmony_ci 100632a6e48fSopenharmony_ciGSError BufferQueue::AllocBuffer(sptr<SurfaceBuffer> &buffer, 100732a6e48fSopenharmony_ci const BufferRequestConfig &config) 100832a6e48fSopenharmony_ci{ 100932a6e48fSopenharmony_ci sptr<SurfaceBuffer> bufferImpl = new SurfaceBufferImpl(); 101032a6e48fSopenharmony_ci uint32_t sequence = bufferImpl->GetSeqNum(); 101132a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("AllocBuffer config width: %d height: %d usage: %llu format: %d id: %u", 101232a6e48fSopenharmony_ci config.width, config.height, config.usage, config.format, sequence); 101332a6e48fSopenharmony_ci 101432a6e48fSopenharmony_ci BufferRequestConfig updateConfig = config; 101532a6e48fSopenharmony_ci updateConfig.usage |= defaultUsage_; 101632a6e48fSopenharmony_ci 101732a6e48fSopenharmony_ci GSError ret = bufferImpl->Alloc(updateConfig); 101832a6e48fSopenharmony_ci if (ret != GSERROR_OK) { 101932a6e48fSopenharmony_ci BLOGE("Alloc failed, sequence:%{public}u, ret:%{public}d, uniqueId: %{public}" PRIu64 ".", 102032a6e48fSopenharmony_ci sequence, ret, uniqueId_); 102132a6e48fSopenharmony_ci return SURFACE_ERROR_UNKOWN; 102232a6e48fSopenharmony_ci } 102332a6e48fSopenharmony_ci 102432a6e48fSopenharmony_ci BufferElement ele = { 102532a6e48fSopenharmony_ci .buffer = bufferImpl, 102632a6e48fSopenharmony_ci .state = BUFFER_STATE_REQUESTED, 102732a6e48fSopenharmony_ci .isDeleting = false, 102832a6e48fSopenharmony_ci .config = config, 102932a6e48fSopenharmony_ci .fence = SyncFence::InvalidFence(), 103032a6e48fSopenharmony_ci .scalingMode = scalingMode_, 103132a6e48fSopenharmony_ci }; 103232a6e48fSopenharmony_ci 103332a6e48fSopenharmony_ci if (config.usage & BUFFER_USAGE_PROTECTED) { 103432a6e48fSopenharmony_ci BLOGD("usage is BUFFER_USAGE_PROTECTED, uniqueId: %{public}" PRIu64 ".", uniqueId_); 103532a6e48fSopenharmony_ci bufferQueueCache_[sequence] = ele; 103632a6e48fSopenharmony_ci buffer = bufferImpl; 103732a6e48fSopenharmony_ci return SURFACE_ERROR_OK; 103832a6e48fSopenharmony_ci } 103932a6e48fSopenharmony_ci 104032a6e48fSopenharmony_ci ret = bufferImpl->Map(); 104132a6e48fSopenharmony_ci if (ret == GSERROR_OK) { 104232a6e48fSopenharmony_ci BLOGD("Map Success, seq: %{public}u, uniqueId: %{public}" PRIu64 ".", sequence, uniqueId_); 104332a6e48fSopenharmony_ci bufferQueueCache_[sequence] = ele; 104432a6e48fSopenharmony_ci buffer = bufferImpl; 104532a6e48fSopenharmony_ci } else { 104632a6e48fSopenharmony_ci BLOGE("Map failed, seq:%{public}u, ret:%{public}d, uniqueId: %{public}" PRIu64 ".", 104732a6e48fSopenharmony_ci sequence, ret, uniqueId_); 104832a6e48fSopenharmony_ci return SURFACE_ERROR_UNKOWN; 104932a6e48fSopenharmony_ci } 105032a6e48fSopenharmony_ci return SURFACE_ERROR_OK; 105132a6e48fSopenharmony_ci} 105232a6e48fSopenharmony_ci 105332a6e48fSopenharmony_civoid BufferQueue::DeleteBufferInCache(uint32_t sequence) 105432a6e48fSopenharmony_ci{ 105532a6e48fSopenharmony_ci auto it = bufferQueueCache_.find(sequence); 105632a6e48fSopenharmony_ci if (it != bufferQueueCache_.end()) { 105732a6e48fSopenharmony_ci if (onBufferDeleteForRSMainThread_ != nullptr) { 105832a6e48fSopenharmony_ci onBufferDeleteForRSMainThread_(sequence); 105932a6e48fSopenharmony_ci } 106032a6e48fSopenharmony_ci if (onBufferDeleteForRSHardwareThread_ != nullptr) { 106132a6e48fSopenharmony_ci onBufferDeleteForRSHardwareThread_(sequence); 106232a6e48fSopenharmony_ci } 106332a6e48fSopenharmony_ci BLOGD("DeleteBufferInCache seq: %{public}u, uniqueId: %{public}" PRIu64 ".", sequence, uniqueId_); 106432a6e48fSopenharmony_ci bufferQueueCache_.erase(it); 106532a6e48fSopenharmony_ci deletingList_.push_back(sequence); 106632a6e48fSopenharmony_ci } 106732a6e48fSopenharmony_ci} 106832a6e48fSopenharmony_ci 106932a6e48fSopenharmony_ciuint32_t BufferQueue::GetQueueSize() 107032a6e48fSopenharmony_ci{ 107132a6e48fSopenharmony_ci std::unique_lock<std::mutex> lock(mutex_); 107232a6e48fSopenharmony_ci return bufferQueueSize_; 107332a6e48fSopenharmony_ci} 107432a6e48fSopenharmony_ci 107532a6e48fSopenharmony_civoid BufferQueue::DeleteBuffersLocked(int32_t count) 107632a6e48fSopenharmony_ci{ 107732a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("DeleteBuffersLocked count: %d", count); 107832a6e48fSopenharmony_ci if (count <= 0) { 107932a6e48fSopenharmony_ci return; 108032a6e48fSopenharmony_ci } 108132a6e48fSopenharmony_ci 108232a6e48fSopenharmony_ci while (!freeList_.empty()) { 108332a6e48fSopenharmony_ci DeleteBufferInCache(freeList_.front()); 108432a6e48fSopenharmony_ci freeList_.pop_front(); 108532a6e48fSopenharmony_ci count--; 108632a6e48fSopenharmony_ci if (count <= 0) { 108732a6e48fSopenharmony_ci return; 108832a6e48fSopenharmony_ci } 108932a6e48fSopenharmony_ci } 109032a6e48fSopenharmony_ci 109132a6e48fSopenharmony_ci while (!dirtyList_.empty()) { 109232a6e48fSopenharmony_ci DeleteBufferInCache(dirtyList_.front()); 109332a6e48fSopenharmony_ci dirtyList_.pop_front(); 109432a6e48fSopenharmony_ci count--; 109532a6e48fSopenharmony_ci if (count <= 0) { 109632a6e48fSopenharmony_ci return; 109732a6e48fSopenharmony_ci } 109832a6e48fSopenharmony_ci } 109932a6e48fSopenharmony_ci 110032a6e48fSopenharmony_ci for (auto&& ele : bufferQueueCache_) { 110132a6e48fSopenharmony_ci ele.second.isDeleting = true; 110232a6e48fSopenharmony_ci // we don't have to do anything 110332a6e48fSopenharmony_ci count--; 110432a6e48fSopenharmony_ci if (count <= 0) { 110532a6e48fSopenharmony_ci break; 110632a6e48fSopenharmony_ci } 110732a6e48fSopenharmony_ci } 110832a6e48fSopenharmony_ci} 110932a6e48fSopenharmony_ci 111032a6e48fSopenharmony_ciGSError BufferQueue::AttachBufferUpdateStatus(std::unique_lock<std::mutex> &lock, uint32_t sequence, int32_t timeOut) 111132a6e48fSopenharmony_ci{ 111232a6e48fSopenharmony_ci BufferState state = bufferQueueCache_[sequence].state; 111332a6e48fSopenharmony_ci if (state == BUFFER_STATE_RELEASED) { 111432a6e48fSopenharmony_ci bufferQueueCache_[sequence].state = BUFFER_STATE_ATTACHED; 111532a6e48fSopenharmony_ci } else { 111632a6e48fSopenharmony_ci waitAttachCon_.wait_for(lock, std::chrono::milliseconds(timeOut), 111732a6e48fSopenharmony_ci [this, sequence]() { return (bufferQueueCache_[sequence].state == BUFFER_STATE_RELEASED); }); 111832a6e48fSopenharmony_ci if (bufferQueueCache_[sequence].state == BUFFER_STATE_RELEASED) { 111932a6e48fSopenharmony_ci bufferQueueCache_[sequence].state = BUFFER_STATE_ATTACHED; 112032a6e48fSopenharmony_ci } else { 112132a6e48fSopenharmony_ci BLOGN_FAILURE_RET(SURFACE_ERROR_BUFFER_STATE_INVALID); 112232a6e48fSopenharmony_ci } 112332a6e48fSopenharmony_ci } 112432a6e48fSopenharmony_ci 112532a6e48fSopenharmony_ci for (auto iter = freeList_.begin(); iter != freeList_.end(); iter++) { 112632a6e48fSopenharmony_ci if (sequence == *iter) { 112732a6e48fSopenharmony_ci freeList_.erase(iter); 112832a6e48fSopenharmony_ci break; 112932a6e48fSopenharmony_ci } 113032a6e48fSopenharmony_ci } 113132a6e48fSopenharmony_ci return GSERROR_OK; 113232a6e48fSopenharmony_ci} 113332a6e48fSopenharmony_ci 113432a6e48fSopenharmony_civoid BufferQueue::AttachBufferUpdateBufferInfo(sptr<SurfaceBuffer>& buffer) 113532a6e48fSopenharmony_ci{ 113632a6e48fSopenharmony_ci buffer->Map(); 113732a6e48fSopenharmony_ci buffer->SetSurfaceBufferWidth(buffer->GetWidth()); 113832a6e48fSopenharmony_ci buffer->SetSurfaceBufferHeight(buffer->GetHeight()); 113932a6e48fSopenharmony_ci} 114032a6e48fSopenharmony_ci 114132a6e48fSopenharmony_ciGSError BufferQueue::AttachBufferToQueue(sptr<SurfaceBuffer> buffer, InvokerType invokerType) 114232a6e48fSopenharmony_ci{ 114332a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("AttachBufferToQueue name: %s queueId: %" PRIu64 " sequence: %u invokerType: %u", 114432a6e48fSopenharmony_ci name_.c_str(), uniqueId_, buffer->GetSeqNum(), invokerType); 114532a6e48fSopenharmony_ci { 114632a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 114732a6e48fSopenharmony_ci uint32_t sequence = buffer->GetSeqNum(); 114832a6e48fSopenharmony_ci if (GetUsedSize() >= bufferQueueSize_) { 114932a6e48fSopenharmony_ci BLOGE("seq: %{public}u, buffer queue size:%{public}u, used size:%{public}u," 115032a6e48fSopenharmony_ci "uniqueId: %{public}" PRIu64 ".", sequence, bufferQueueSize_, GetUsedSize(), uniqueId_); 115132a6e48fSopenharmony_ci return SURFACE_ERROR_BUFFER_QUEUE_FULL; 115232a6e48fSopenharmony_ci } 115332a6e48fSopenharmony_ci if (bufferQueueCache_.find(sequence) != bufferQueueCache_.end()) { 115432a6e48fSopenharmony_ci BLOGE("seq: %{public}u, buffer is already in cache, uniqueId: %{public}" PRIu64 ".", 115532a6e48fSopenharmony_ci sequence, uniqueId_); 115632a6e48fSopenharmony_ci return SURFACE_ERROR_BUFFER_IS_INCACHE; 115732a6e48fSopenharmony_ci } 115832a6e48fSopenharmony_ci BufferElement ele; 115932a6e48fSopenharmony_ci ele = { 116032a6e48fSopenharmony_ci .buffer = buffer, 116132a6e48fSopenharmony_ci .isDeleting = false, 116232a6e48fSopenharmony_ci .config = buffer->GetBufferRequestConfig(), 116332a6e48fSopenharmony_ci .fence = SyncFence::InvalidFence(), 116432a6e48fSopenharmony_ci .scalingMode = scalingMode_, 116532a6e48fSopenharmony_ci }; 116632a6e48fSopenharmony_ci if (invokerType == InvokerType::PRODUCER_INVOKER) { 116732a6e48fSopenharmony_ci ele.state = BUFFER_STATE_REQUESTED; 116832a6e48fSopenharmony_ci } else { 116932a6e48fSopenharmony_ci ele.state = BUFFER_STATE_ACQUIRED; 117032a6e48fSopenharmony_ci } 117132a6e48fSopenharmony_ci AttachBufferUpdateBufferInfo(buffer); 117232a6e48fSopenharmony_ci bufferQueueCache_[sequence] = ele; 117332a6e48fSopenharmony_ci } 117432a6e48fSopenharmony_ci return GSERROR_OK; 117532a6e48fSopenharmony_ci} 117632a6e48fSopenharmony_ci 117732a6e48fSopenharmony_ciGSError BufferQueue::DetachBufferFromQueue(sptr<SurfaceBuffer> buffer, InvokerType invokerType) 117832a6e48fSopenharmony_ci{ 117932a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("DetachBufferFromQueue name: %s queueId: %" PRIu64 " sequence: %u invokerType%u", 118032a6e48fSopenharmony_ci name_.c_str(), uniqueId_, buffer->GetSeqNum(), invokerType); 118132a6e48fSopenharmony_ci { 118232a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 118332a6e48fSopenharmony_ci uint32_t sequence = buffer->GetSeqNum(); 118432a6e48fSopenharmony_ci if (bufferQueueCache_.find(sequence) == bufferQueueCache_.end()) { 118532a6e48fSopenharmony_ci BLOGE("seq: %{public}u, not find in cache, uniqueId: %{public}" PRIu64 ".", 118632a6e48fSopenharmony_ci sequence, uniqueId_); 118732a6e48fSopenharmony_ci return SURFACE_ERROR_BUFFER_NOT_INCACHE; 118832a6e48fSopenharmony_ci } 118932a6e48fSopenharmony_ci if (invokerType == InvokerType::PRODUCER_INVOKER) { 119032a6e48fSopenharmony_ci if (bufferQueueCache_[sequence].state != BUFFER_STATE_REQUESTED) { 119132a6e48fSopenharmony_ci BLOGE("seq: %{public}u, state: %{public}d, uniqueId: %{public}" PRIu64 ".", 119232a6e48fSopenharmony_ci sequence, bufferQueueCache_[sequence].state, uniqueId_); 119332a6e48fSopenharmony_ci return SURFACE_ERROR_BUFFER_STATE_INVALID; 119432a6e48fSopenharmony_ci } 119532a6e48fSopenharmony_ci } else { 119632a6e48fSopenharmony_ci if (bufferQueueCache_[sequence].state != BUFFER_STATE_ACQUIRED) { 119732a6e48fSopenharmony_ci BLOGE("seq: %{public}u, state: %{public}d, uniqueId: %{public}" PRIu64 ".", 119832a6e48fSopenharmony_ci sequence, bufferQueueCache_[sequence].state, uniqueId_); 119932a6e48fSopenharmony_ci return SURFACE_ERROR_BUFFER_STATE_INVALID; 120032a6e48fSopenharmony_ci } 120132a6e48fSopenharmony_ci } 120232a6e48fSopenharmony_ci bufferQueueCache_.erase(sequence); 120332a6e48fSopenharmony_ci } 120432a6e48fSopenharmony_ci return GSERROR_OK; 120532a6e48fSopenharmony_ci} 120632a6e48fSopenharmony_ci 120732a6e48fSopenharmony_ciGSError BufferQueue::AttachBuffer(sptr<SurfaceBuffer> &buffer, int32_t timeOut) 120832a6e48fSopenharmony_ci{ 120932a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("%s", __func__); 121032a6e48fSopenharmony_ci { 121132a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 121232a6e48fSopenharmony_ci if (!GetStatusLocked()) { 121332a6e48fSopenharmony_ci BLOGN_FAILURE_RET(GSERROR_NO_CONSUMER); 121432a6e48fSopenharmony_ci } 121532a6e48fSopenharmony_ci } 121632a6e48fSopenharmony_ci { 121732a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(listenerMutex_); 121832a6e48fSopenharmony_ci if (listener_ == nullptr && listenerClazz_ == nullptr) { 121932a6e48fSopenharmony_ci BLOGN_FAILURE_RET(SURFACE_ERROR_CONSUMER_UNREGISTER_LISTENER); 122032a6e48fSopenharmony_ci } 122132a6e48fSopenharmony_ci } 122232a6e48fSopenharmony_ci 122332a6e48fSopenharmony_ci if (isShared_ || buffer == nullptr) { 122432a6e48fSopenharmony_ci BLOGN_FAILURE_RET(GSERROR_INVALID_OPERATING); 122532a6e48fSopenharmony_ci } 122632a6e48fSopenharmony_ci 122732a6e48fSopenharmony_ci uint32_t sequence = buffer->GetSeqNum(); 122832a6e48fSopenharmony_ci std::unique_lock<std::mutex> lock(mutex_); 122932a6e48fSopenharmony_ci if (bufferQueueCache_.find(sequence) != bufferQueueCache_.end()) { 123032a6e48fSopenharmony_ci return AttachBufferUpdateStatus(lock, sequence, timeOut); 123132a6e48fSopenharmony_ci } 123232a6e48fSopenharmony_ci 123332a6e48fSopenharmony_ci BufferElement ele = { 123432a6e48fSopenharmony_ci .buffer = buffer, 123532a6e48fSopenharmony_ci .state = BUFFER_STATE_ATTACHED, 123632a6e48fSopenharmony_ci .config = { 123732a6e48fSopenharmony_ci .width = buffer->GetWidth(), .height = buffer->GetHeight(), .strideAlignment = 0x8, 123832a6e48fSopenharmony_ci .format = buffer->GetFormat(), .usage = buffer->GetUsage(), .timeout = timeOut, 123932a6e48fSopenharmony_ci }, 124032a6e48fSopenharmony_ci .damages = { { .w = buffer->GetWidth(), .h = buffer->GetHeight(), } }, 124132a6e48fSopenharmony_ci }; 124232a6e48fSopenharmony_ci AttachBufferUpdateBufferInfo(buffer); 124332a6e48fSopenharmony_ci int32_t usedSize = static_cast<int32_t>(GetUsedSize()); 124432a6e48fSopenharmony_ci int32_t queueSize = static_cast<int32_t>(bufferQueueSize_); 124532a6e48fSopenharmony_ci if (usedSize >= queueSize) { 124632a6e48fSopenharmony_ci int32_t freeSize = static_cast<int32_t>(dirtyList_.size() + freeList_.size()); 124732a6e48fSopenharmony_ci if (freeSize >= usedSize - queueSize + 1) { 124832a6e48fSopenharmony_ci DeleteBuffersLocked(usedSize - queueSize + 1); 124932a6e48fSopenharmony_ci bufferQueueCache_[sequence] = ele; 125032a6e48fSopenharmony_ci BLOGD("AttachBuffer release seq: %{public}u, uniqueId: %{public}" PRIu64 ".", sequence, uniqueId_); 125132a6e48fSopenharmony_ci return GSERROR_OK; 125232a6e48fSopenharmony_ci } else { 125332a6e48fSopenharmony_ci BLOGN_FAILURE_RET(GSERROR_OUT_OF_RANGE); 125432a6e48fSopenharmony_ci } 125532a6e48fSopenharmony_ci } else { 125632a6e48fSopenharmony_ci bufferQueueCache_[sequence] = ele; 125732a6e48fSopenharmony_ci BLOGD("AttachBuffer no release seq: %{public}d, uniqueId: %{public}" PRIu64 ".", sequence, uniqueId_); 125832a6e48fSopenharmony_ci return GSERROR_OK; 125932a6e48fSopenharmony_ci } 126032a6e48fSopenharmony_ci} 126132a6e48fSopenharmony_ci 126232a6e48fSopenharmony_ciGSError BufferQueue::DetachBuffer(sptr<SurfaceBuffer> &buffer) 126332a6e48fSopenharmony_ci{ 126432a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("%s", __func__); 126532a6e48fSopenharmony_ci if (isShared_) { 126632a6e48fSopenharmony_ci BLOGN_FAILURE_RET(GSERROR_INVALID_OPERATING); 126732a6e48fSopenharmony_ci } 126832a6e48fSopenharmony_ci 126932a6e48fSopenharmony_ci if (buffer == nullptr) { 127032a6e48fSopenharmony_ci BLOGN_FAILURE_RET(GSERROR_INVALID_ARGUMENTS); 127132a6e48fSopenharmony_ci } 127232a6e48fSopenharmony_ci 127332a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 127432a6e48fSopenharmony_ci uint32_t sequence = buffer->GetSeqNum(); 127532a6e48fSopenharmony_ci if (bufferQueueCache_.find(sequence) == bufferQueueCache_.end()) { 127632a6e48fSopenharmony_ci return GSERROR_NO_ENTRY; 127732a6e48fSopenharmony_ci } 127832a6e48fSopenharmony_ci 127932a6e48fSopenharmony_ci if (bufferQueueCache_[sequence].state == BUFFER_STATE_REQUESTED) { 128032a6e48fSopenharmony_ci BLOGD("DetachBuffer requested seq: %{public}u, uniqueId: %{public}" PRIu64 ".", sequence, uniqueId_); 128132a6e48fSopenharmony_ci } else if (bufferQueueCache_[sequence].state == BUFFER_STATE_ACQUIRED) { 128232a6e48fSopenharmony_ci BLOGD("DetachBuffer acquired seq: %{public}u, uniqueId: %{public}" PRIu64 ".", sequence, uniqueId_); 128332a6e48fSopenharmony_ci } else { 128432a6e48fSopenharmony_ci BLOGE("DetachBuffer invalid state: %{public}d, seq: %{public}u, uniqueId: %{public}" PRIu64 ".", 128532a6e48fSopenharmony_ci bufferQueueCache_[sequence].state, sequence, uniqueId_); 128632a6e48fSopenharmony_ci return GSERROR_NO_ENTRY; 128732a6e48fSopenharmony_ci } 128832a6e48fSopenharmony_ci if (onBufferDeleteForRSMainThread_ != nullptr) { 128932a6e48fSopenharmony_ci onBufferDeleteForRSMainThread_(sequence); 129032a6e48fSopenharmony_ci } 129132a6e48fSopenharmony_ci if (onBufferDeleteForRSHardwareThread_ != nullptr) { 129232a6e48fSopenharmony_ci onBufferDeleteForRSHardwareThread_(sequence); 129332a6e48fSopenharmony_ci } 129432a6e48fSopenharmony_ci bufferQueueCache_.erase(sequence); 129532a6e48fSopenharmony_ci return GSERROR_OK; 129632a6e48fSopenharmony_ci} 129732a6e48fSopenharmony_ci 129832a6e48fSopenharmony_ciGSError BufferQueue::RegisterSurfaceDelegator(sptr<IRemoteObject> client, sptr<Surface> cSurface) 129932a6e48fSopenharmony_ci{ 130032a6e48fSopenharmony_ci sptr<ConsumerSurfaceDelegator> surfaceDelegator = ConsumerSurfaceDelegator::Create(); 130132a6e48fSopenharmony_ci if (surfaceDelegator == nullptr) { 130232a6e48fSopenharmony_ci BLOGE("Failed to register consumer delegator because the surface delegator is nullptr"); 130332a6e48fSopenharmony_ci return GSERROR_INVALID_ARGUMENTS; 130432a6e48fSopenharmony_ci } 130532a6e48fSopenharmony_ci if (!surfaceDelegator->SetClient(client)) { 130632a6e48fSopenharmony_ci BLOGE("Failed to set client"); 130732a6e48fSopenharmony_ci return GSERROR_INVALID_ARGUMENTS; 130832a6e48fSopenharmony_ci } 130932a6e48fSopenharmony_ci if (!surfaceDelegator->SetBufferQueue(this)) { 131032a6e48fSopenharmony_ci BLOGE("Failed to set bufferqueue"); 131132a6e48fSopenharmony_ci return GSERROR_INVALID_ARGUMENTS; 131232a6e48fSopenharmony_ci } 131332a6e48fSopenharmony_ci 131432a6e48fSopenharmony_ci surfaceDelegator->SetSurface(cSurface); 131532a6e48fSopenharmony_ci wpCSurfaceDelegator_ = surfaceDelegator; 131632a6e48fSopenharmony_ci return GSERROR_OK; 131732a6e48fSopenharmony_ci} 131832a6e48fSopenharmony_ci 131932a6e48fSopenharmony_ciGSError BufferQueue::SetQueueSize(uint32_t queueSize) 132032a6e48fSopenharmony_ci{ 132132a6e48fSopenharmony_ci if (isShared_ == true && queueSize != 1) { 132232a6e48fSopenharmony_ci BLOGW("shared queue size: %{public}u, uniqueId: %{public}" PRIu64 ".", queueSize, uniqueId_); 132332a6e48fSopenharmony_ci return GSERROR_INVALID_ARGUMENTS; 132432a6e48fSopenharmony_ci } 132532a6e48fSopenharmony_ci 132632a6e48fSopenharmony_ci if (queueSize == 0) { 132732a6e48fSopenharmony_ci BLOGW("queue size: %{public}u, uniqueId: %{public}" PRIu64 ".", queueSize, uniqueId_); 132832a6e48fSopenharmony_ci return GSERROR_INVALID_ARGUMENTS; 132932a6e48fSopenharmony_ci } 133032a6e48fSopenharmony_ci 133132a6e48fSopenharmony_ci if (queueSize > SURFACE_MAX_QUEUE_SIZE) { 133232a6e48fSopenharmony_ci BLOGW("invalid queueSize: %{public}u, uniqueId: %{public}" PRIu64 ".", 133332a6e48fSopenharmony_ci queueSize, uniqueId_); 133432a6e48fSopenharmony_ci return GSERROR_INVALID_ARGUMENTS; 133532a6e48fSopenharmony_ci } 133632a6e48fSopenharmony_ci 133732a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 133832a6e48fSopenharmony_ci if (bufferQueueSize_ > queueSize) { 133932a6e48fSopenharmony_ci DeleteBuffersLocked(bufferQueueSize_ - queueSize); 134032a6e48fSopenharmony_ci } 134132a6e48fSopenharmony_ci // if increase the queue size, try to wakeup the blocked thread 134232a6e48fSopenharmony_ci if (queueSize > bufferQueueSize_) { 134332a6e48fSopenharmony_ci bufferQueueSize_ = queueSize; 134432a6e48fSopenharmony_ci waitReqCon_.notify_all(); 134532a6e48fSopenharmony_ci } else { 134632a6e48fSopenharmony_ci bufferQueueSize_ = queueSize; 134732a6e48fSopenharmony_ci } 134832a6e48fSopenharmony_ci 134932a6e48fSopenharmony_ci BLOGD("queue size: %{public}d, uniqueId: %{public}" PRIu64 ".", bufferQueueSize_, uniqueId_); 135032a6e48fSopenharmony_ci return GSERROR_OK; 135132a6e48fSopenharmony_ci} 135232a6e48fSopenharmony_ci 135332a6e48fSopenharmony_ciGSError BufferQueue::GetName(std::string &name) 135432a6e48fSopenharmony_ci{ 135532a6e48fSopenharmony_ci name = name_; 135632a6e48fSopenharmony_ci return GSERROR_OK; 135732a6e48fSopenharmony_ci} 135832a6e48fSopenharmony_ci 135932a6e48fSopenharmony_ciGSError BufferQueue::RegisterConsumerListener(sptr<IBufferConsumerListener> &listener) 136032a6e48fSopenharmony_ci{ 136132a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(listenerMutex_); 136232a6e48fSopenharmony_ci listener_ = listener; 136332a6e48fSopenharmony_ci return GSERROR_OK; 136432a6e48fSopenharmony_ci} 136532a6e48fSopenharmony_ci 136632a6e48fSopenharmony_ciGSError BufferQueue::RegisterConsumerListener(IBufferConsumerListenerClazz *listener) 136732a6e48fSopenharmony_ci{ 136832a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(listenerMutex_); 136932a6e48fSopenharmony_ci listenerClazz_ = listener; 137032a6e48fSopenharmony_ci return GSERROR_OK; 137132a6e48fSopenharmony_ci} 137232a6e48fSopenharmony_ci 137332a6e48fSopenharmony_ciGSError BufferQueue::UnregisterConsumerListener() 137432a6e48fSopenharmony_ci{ 137532a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(listenerMutex_); 137632a6e48fSopenharmony_ci listener_ = nullptr; 137732a6e48fSopenharmony_ci listenerClazz_ = nullptr; 137832a6e48fSopenharmony_ci return GSERROR_OK; 137932a6e48fSopenharmony_ci} 138032a6e48fSopenharmony_ci 138132a6e48fSopenharmony_ciGSError BufferQueue::RegisterReleaseListener(OnReleaseFunc func) 138232a6e48fSopenharmony_ci{ 138332a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(onBufferReleaseMutex_); 138432a6e48fSopenharmony_ci onBufferRelease_ = func; 138532a6e48fSopenharmony_ci return GSERROR_OK; 138632a6e48fSopenharmony_ci} 138732a6e48fSopenharmony_ci 138832a6e48fSopenharmony_ciGSError BufferQueue::RegisterProducerReleaseListener(sptr<IProducerListener> listener) 138932a6e48fSopenharmony_ci{ 139032a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(producerListenerMutex_); 139132a6e48fSopenharmony_ci producerListener_ = listener; 139232a6e48fSopenharmony_ci return GSERROR_OK; 139332a6e48fSopenharmony_ci} 139432a6e48fSopenharmony_ci 139532a6e48fSopenharmony_ciGSError BufferQueue::UnRegisterProducerReleaseListener() 139632a6e48fSopenharmony_ci{ 139732a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(producerListenerMutex_); 139832a6e48fSopenharmony_ci producerListener_ = nullptr; 139932a6e48fSopenharmony_ci return GSERROR_OK; 140032a6e48fSopenharmony_ci} 140132a6e48fSopenharmony_ci 140232a6e48fSopenharmony_ciGSError BufferQueue::RegisterDeleteBufferListener(OnDeleteBufferFunc func, bool isForUniRedraw) 140332a6e48fSopenharmony_ci{ 140432a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 140532a6e48fSopenharmony_ci if (isForUniRedraw) { 140632a6e48fSopenharmony_ci if (onBufferDeleteForRSHardwareThread_ != nullptr) { 140732a6e48fSopenharmony_ci return GSERROR_OK; 140832a6e48fSopenharmony_ci } 140932a6e48fSopenharmony_ci onBufferDeleteForRSHardwareThread_ = func; 141032a6e48fSopenharmony_ci } else { 141132a6e48fSopenharmony_ci if (onBufferDeleteForRSMainThread_ != nullptr) { 141232a6e48fSopenharmony_ci return GSERROR_OK; 141332a6e48fSopenharmony_ci } 141432a6e48fSopenharmony_ci onBufferDeleteForRSMainThread_ = func; 141532a6e48fSopenharmony_ci } 141632a6e48fSopenharmony_ci return GSERROR_OK; 141732a6e48fSopenharmony_ci} 141832a6e48fSopenharmony_ci 141932a6e48fSopenharmony_ciGSError BufferQueue::SetDefaultWidthAndHeight(int32_t width, int32_t height) 142032a6e48fSopenharmony_ci{ 142132a6e48fSopenharmony_ci if (width <= 0) { 142232a6e48fSopenharmony_ci BLOGW("width is %{public}d, uniqueId: %{public}" PRIu64 ".", width, uniqueId_); 142332a6e48fSopenharmony_ci return GSERROR_INVALID_ARGUMENTS; 142432a6e48fSopenharmony_ci } 142532a6e48fSopenharmony_ci 142632a6e48fSopenharmony_ci if (height <= 0) { 142732a6e48fSopenharmony_ci BLOGW("height is %{public}d, uniqueId: %{public}" PRIu64 ".", height, uniqueId_); 142832a6e48fSopenharmony_ci return GSERROR_INVALID_ARGUMENTS; 142932a6e48fSopenharmony_ci } 143032a6e48fSopenharmony_ci BLOGD("SetDefaultWidthAndHeight(width: %{public}d, height: %{public}d), uniqueId: %{public}" PRIu64 ".", 143132a6e48fSopenharmony_ci width, height, uniqueId_); 143232a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 143332a6e48fSopenharmony_ci defaultWidth_ = width; 143432a6e48fSopenharmony_ci defaultHeight_ = height; 143532a6e48fSopenharmony_ci return GSERROR_OK; 143632a6e48fSopenharmony_ci} 143732a6e48fSopenharmony_ci 143832a6e48fSopenharmony_ciint32_t BufferQueue::GetDefaultWidth() 143932a6e48fSopenharmony_ci{ 144032a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 144132a6e48fSopenharmony_ci return defaultWidth_; 144232a6e48fSopenharmony_ci} 144332a6e48fSopenharmony_ci 144432a6e48fSopenharmony_ciint32_t BufferQueue::GetDefaultHeight() 144532a6e48fSopenharmony_ci{ 144632a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 144732a6e48fSopenharmony_ci return defaultHeight_; 144832a6e48fSopenharmony_ci} 144932a6e48fSopenharmony_ci 145032a6e48fSopenharmony_ciGSError BufferQueue::SetDefaultUsage(uint64_t usage) 145132a6e48fSopenharmony_ci{ 145232a6e48fSopenharmony_ci BLOGD("SetDefaultUsage(usage: %{public}" PRIu64 ") , uniqueId: %{public}" PRIu64 ".", usage, uniqueId_); 145332a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 145432a6e48fSopenharmony_ci defaultUsage_ = usage; 145532a6e48fSopenharmony_ci return GSERROR_OK; 145632a6e48fSopenharmony_ci} 145732a6e48fSopenharmony_ci 145832a6e48fSopenharmony_ciuint64_t BufferQueue::GetDefaultUsage() 145932a6e48fSopenharmony_ci{ 146032a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 146132a6e48fSopenharmony_ci return defaultUsage_; 146232a6e48fSopenharmony_ci} 146332a6e48fSopenharmony_ci 146432a6e48fSopenharmony_civoid BufferQueue::ClearLocked() 146532a6e48fSopenharmony_ci{ 146632a6e48fSopenharmony_ci for (auto &[id, ele] : bufferQueueCache_) { 146732a6e48fSopenharmony_ci if (onBufferDeleteForRSMainThread_ != nullptr) { 146832a6e48fSopenharmony_ci onBufferDeleteForRSMainThread_(id); 146932a6e48fSopenharmony_ci } 147032a6e48fSopenharmony_ci if (onBufferDeleteForRSHardwareThread_ != nullptr) { 147132a6e48fSopenharmony_ci onBufferDeleteForRSHardwareThread_(id); 147232a6e48fSopenharmony_ci } 147332a6e48fSopenharmony_ci 147432a6e48fSopenharmony_ci if (name_ == "RosenWeb") { 147532a6e48fSopenharmony_ci BLOGD("ClearLocked, bufferFd: %{public}d, refCount: %{public}d.", 147632a6e48fSopenharmony_ci ele.buffer->GetBufferHandle()->fd, ele.buffer->GetSptrRefCount()); 147732a6e48fSopenharmony_ci } 147832a6e48fSopenharmony_ci } 147932a6e48fSopenharmony_ci bufferQueueCache_.clear(); 148032a6e48fSopenharmony_ci freeList_.clear(); 148132a6e48fSopenharmony_ci dirtyList_.clear(); 148232a6e48fSopenharmony_ci deletingList_.clear(); 148332a6e48fSopenharmony_ci} 148432a6e48fSopenharmony_ci 148532a6e48fSopenharmony_ciGSError BufferQueue::GoBackground() 148632a6e48fSopenharmony_ci{ 148732a6e48fSopenharmony_ci BLOGD("GoBackground, uniqueId: %{public}" PRIu64 ".", uniqueId_); 148832a6e48fSopenharmony_ci sptr<IBufferConsumerListener> listener; 148932a6e48fSopenharmony_ci IBufferConsumerListenerClazz *listenerClazz; 149032a6e48fSopenharmony_ci { 149132a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(listenerMutex_); 149232a6e48fSopenharmony_ci listener = listener_; 149332a6e48fSopenharmony_ci listenerClazz = listenerClazz_; 149432a6e48fSopenharmony_ci } 149532a6e48fSopenharmony_ci if (listener != nullptr) { 149632a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("OnGoBackground name: %s queueId: %" PRIu64, name_.c_str(), uniqueId_); 149732a6e48fSopenharmony_ci listener->OnGoBackground(); 149832a6e48fSopenharmony_ci } else if (listenerClazz != nullptr) { 149932a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("OnGoBackground name: %s queueId: %" PRIu64, name_.c_str(), uniqueId_); 150032a6e48fSopenharmony_ci listenerClazz->OnGoBackground(); 150132a6e48fSopenharmony_ci } 150232a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 150332a6e48fSopenharmony_ci ClearLocked(); 150432a6e48fSopenharmony_ci waitReqCon_.notify_all(); 150532a6e48fSopenharmony_ci SetProducerCacheCleanFlagLocked(false); 150632a6e48fSopenharmony_ci return GSERROR_OK; 150732a6e48fSopenharmony_ci} 150832a6e48fSopenharmony_ci 150932a6e48fSopenharmony_ciGSError BufferQueue::CleanCache(bool cleanAll) 151032a6e48fSopenharmony_ci{ 151132a6e48fSopenharmony_ci BLOGD("CleanCache, uniqueId: %{public}" PRIu64 ". cleanAll: %{public}d.", uniqueId_, cleanAll); 151232a6e48fSopenharmony_ci sptr<IBufferConsumerListener> listener; 151332a6e48fSopenharmony_ci IBufferConsumerListenerClazz *listenerClazz; 151432a6e48fSopenharmony_ci { 151532a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(listenerMutex_); 151632a6e48fSopenharmony_ci listener = listener_; 151732a6e48fSopenharmony_ci listenerClazz = listenerClazz_; 151832a6e48fSopenharmony_ci } 151932a6e48fSopenharmony_ci if (cleanAll) { 152032a6e48fSopenharmony_ci if (listener != nullptr) { 152132a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("OnGoBackground name: %s queueId: %" PRIu64, name_.c_str(), uniqueId_); 152232a6e48fSopenharmony_ci listener->OnGoBackground(); 152332a6e48fSopenharmony_ci } else if (listenerClazz != nullptr) { 152432a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("OnGoBackground name: %s queueId: %" PRIu64, name_.c_str(), uniqueId_); 152532a6e48fSopenharmony_ci listenerClazz->OnGoBackground(); 152632a6e48fSopenharmony_ci } 152732a6e48fSopenharmony_ci } else { 152832a6e48fSopenharmony_ci if (listener != nullptr) { 152932a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("OnCleanCache name: %s queueId: %" PRIu64, name_.c_str(), uniqueId_); 153032a6e48fSopenharmony_ci listener->OnCleanCache(); 153132a6e48fSopenharmony_ci } else if (listenerClazz != nullptr) { 153232a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("OnCleanCache name: %s queueId: %" PRIu64, name_.c_str(), uniqueId_); 153332a6e48fSopenharmony_ci listenerClazz->OnCleanCache(); 153432a6e48fSopenharmony_ci } 153532a6e48fSopenharmony_ci } 153632a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 153732a6e48fSopenharmony_ci ClearLocked(); 153832a6e48fSopenharmony_ci waitReqCon_.notify_all(); 153932a6e48fSopenharmony_ci return GSERROR_OK; 154032a6e48fSopenharmony_ci} 154132a6e48fSopenharmony_ci 154232a6e48fSopenharmony_ciGSError BufferQueue::OnConsumerDied() 154332a6e48fSopenharmony_ci{ 154432a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 154532a6e48fSopenharmony_ci ClearLocked(); 154632a6e48fSopenharmony_ci waitReqCon_.notify_all(); 154732a6e48fSopenharmony_ci return GSERROR_OK; 154832a6e48fSopenharmony_ci} 154932a6e48fSopenharmony_ci 155032a6e48fSopenharmony_ciGSError BufferQueue::IsSurfaceBufferInCache(uint32_t seqNum, bool &isInCache) 155132a6e48fSopenharmony_ci{ 155232a6e48fSopenharmony_ci std::unique_lock<std::mutex> lock(mutex_); 155332a6e48fSopenharmony_ci if (bufferQueueCache_.find(seqNum) != bufferQueueCache_.end()) { 155432a6e48fSopenharmony_ci isInCache = true; 155532a6e48fSopenharmony_ci } else { 155632a6e48fSopenharmony_ci isInCache = false; 155732a6e48fSopenharmony_ci } 155832a6e48fSopenharmony_ci return GSERROR_OK; 155932a6e48fSopenharmony_ci} 156032a6e48fSopenharmony_ci 156132a6e48fSopenharmony_ciuint64_t BufferQueue::GetUniqueId() const 156232a6e48fSopenharmony_ci{ 156332a6e48fSopenharmony_ci std::unique_lock<std::mutex> lock(mutex_); 156432a6e48fSopenharmony_ci return uniqueId_; 156532a6e48fSopenharmony_ci} 156632a6e48fSopenharmony_ci 156732a6e48fSopenharmony_ciGSError BufferQueue::SetTransform(GraphicTransformType transform) 156832a6e48fSopenharmony_ci{ 156932a6e48fSopenharmony_ci { 157032a6e48fSopenharmony_ci std::unique_lock<std::mutex> lock(mutex_); 157132a6e48fSopenharmony_ci if (transform_ == transform) { 157232a6e48fSopenharmony_ci return GSERROR_OK; 157332a6e48fSopenharmony_ci } 157432a6e48fSopenharmony_ci 157532a6e48fSopenharmony_ci transform_ = transform; 157632a6e48fSopenharmony_ci } 157732a6e48fSopenharmony_ci sptr<IBufferConsumerListener> listener; 157832a6e48fSopenharmony_ci IBufferConsumerListenerClazz *listenerClazz; 157932a6e48fSopenharmony_ci { 158032a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(listenerMutex_); 158132a6e48fSopenharmony_ci listener = listener_; 158232a6e48fSopenharmony_ci listenerClazz = listenerClazz_; 158332a6e48fSopenharmony_ci } 158432a6e48fSopenharmony_ci if (listener != nullptr) { 158532a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("OnTransformChange transform: %u", transform); 158632a6e48fSopenharmony_ci listener->OnTransformChange(); 158732a6e48fSopenharmony_ci } else if (listenerClazz != nullptr) { 158832a6e48fSopenharmony_ci SURFACE_TRACE_NAME_FMT("OnTransformChange transform: %u", transform); 158932a6e48fSopenharmony_ci listenerClazz->OnTransformChange(); 159032a6e48fSopenharmony_ci } 159132a6e48fSopenharmony_ci return GSERROR_OK; 159232a6e48fSopenharmony_ci} 159332a6e48fSopenharmony_ci 159432a6e48fSopenharmony_ciGraphicTransformType BufferQueue::GetTransform() const 159532a6e48fSopenharmony_ci{ 159632a6e48fSopenharmony_ci std::unique_lock<std::mutex> lock(mutex_); 159732a6e48fSopenharmony_ci return transform_; 159832a6e48fSopenharmony_ci} 159932a6e48fSopenharmony_ci 160032a6e48fSopenharmony_ciGSError BufferQueue::SetTransformHint(GraphicTransformType transformHint) 160132a6e48fSopenharmony_ci{ 160232a6e48fSopenharmony_ci std::unique_lock<std::mutex> lock(mutex_); 160332a6e48fSopenharmony_ci transformHint_ = transformHint; 160432a6e48fSopenharmony_ci return GSERROR_OK; 160532a6e48fSopenharmony_ci} 160632a6e48fSopenharmony_ci 160732a6e48fSopenharmony_ciGraphicTransformType BufferQueue::GetTransformHint() const 160832a6e48fSopenharmony_ci{ 160932a6e48fSopenharmony_ci std::unique_lock<std::mutex> lock(mutex_); 161032a6e48fSopenharmony_ci return transformHint_; 161132a6e48fSopenharmony_ci} 161232a6e48fSopenharmony_ci 161332a6e48fSopenharmony_ciGSError BufferQueue::SetSurfaceSourceType(OHSurfaceSource sourceType) 161432a6e48fSopenharmony_ci{ 161532a6e48fSopenharmony_ci std::unique_lock<std::mutex> lock(mutex_); 161632a6e48fSopenharmony_ci sourceType_ = sourceType; 161732a6e48fSopenharmony_ci return GSERROR_OK; 161832a6e48fSopenharmony_ci} 161932a6e48fSopenharmony_ci 162032a6e48fSopenharmony_ciOHSurfaceSource BufferQueue::GetSurfaceSourceType() const 162132a6e48fSopenharmony_ci{ 162232a6e48fSopenharmony_ci std::unique_lock<std::mutex> lock(mutex_); 162332a6e48fSopenharmony_ci return sourceType_; 162432a6e48fSopenharmony_ci} 162532a6e48fSopenharmony_ci 162632a6e48fSopenharmony_ciGSError BufferQueue::SetHdrWhitePointBrightness(float brightness) 162732a6e48fSopenharmony_ci{ 162832a6e48fSopenharmony_ci std::unique_lock<std::mutex> lock(mutex_); 162932a6e48fSopenharmony_ci hdrWhitePointBrightness_ = brightness; 163032a6e48fSopenharmony_ci return GSERROR_OK; 163132a6e48fSopenharmony_ci} 163232a6e48fSopenharmony_ci 163332a6e48fSopenharmony_ciGSError BufferQueue::SetSdrWhitePointBrightness(float brightness) 163432a6e48fSopenharmony_ci{ 163532a6e48fSopenharmony_ci std::unique_lock<std::mutex> lock(mutex_); 163632a6e48fSopenharmony_ci sdrWhitePointBrightness_ = brightness; 163732a6e48fSopenharmony_ci return GSERROR_OK; 163832a6e48fSopenharmony_ci} 163932a6e48fSopenharmony_ci 164032a6e48fSopenharmony_cifloat BufferQueue::GetHdrWhitePointBrightness() const 164132a6e48fSopenharmony_ci{ 164232a6e48fSopenharmony_ci std::unique_lock<std::mutex> lock(mutex_); 164332a6e48fSopenharmony_ci return hdrWhitePointBrightness_; 164432a6e48fSopenharmony_ci} 164532a6e48fSopenharmony_ci 164632a6e48fSopenharmony_cifloat BufferQueue::GetSdrWhitePointBrightness() const 164732a6e48fSopenharmony_ci{ 164832a6e48fSopenharmony_ci std::unique_lock<std::mutex> lock(mutex_); 164932a6e48fSopenharmony_ci return sdrWhitePointBrightness_; 165032a6e48fSopenharmony_ci} 165132a6e48fSopenharmony_ci 165232a6e48fSopenharmony_ciGSError BufferQueue::SetSurfaceAppFrameworkType(std::string appFrameworkType) 165332a6e48fSopenharmony_ci{ 165432a6e48fSopenharmony_ci if (appFrameworkType.empty()) { 165532a6e48fSopenharmony_ci return GSERROR_NO_ENTRY; 165632a6e48fSopenharmony_ci } 165732a6e48fSopenharmony_ci if (appFrameworkType.size() > MAXIMUM_LENGTH_OF_APP_FRAMEWORK) { 165832a6e48fSopenharmony_ci return GSERROR_OUT_OF_RANGE; 165932a6e48fSopenharmony_ci } 166032a6e48fSopenharmony_ci std::unique_lock<std::mutex> lock(mutex_); 166132a6e48fSopenharmony_ci appFrameworkType_ = appFrameworkType; 166232a6e48fSopenharmony_ci return GSERROR_OK; 166332a6e48fSopenharmony_ci} 166432a6e48fSopenharmony_ci 166532a6e48fSopenharmony_cistd::string BufferQueue::GetSurfaceAppFrameworkType() const 166632a6e48fSopenharmony_ci{ 166732a6e48fSopenharmony_ci std::unique_lock<std::mutex> lock(mutex_); 166832a6e48fSopenharmony_ci return appFrameworkType_; 166932a6e48fSopenharmony_ci} 167032a6e48fSopenharmony_ci 167132a6e48fSopenharmony_ciGSError BufferQueue::IsSupportedAlloc(const std::vector<BufferVerifyAllocInfo> &infos, 167232a6e48fSopenharmony_ci std::vector<bool> &supporteds) const 167332a6e48fSopenharmony_ci{ 167432a6e48fSopenharmony_ci supporteds.clear(); 167532a6e48fSopenharmony_ci for (uint32_t index = 0; index < infos.size(); index++) { 167632a6e48fSopenharmony_ci if (infos[index].format == GRAPHIC_PIXEL_FMT_RGBA_8888 || 167732a6e48fSopenharmony_ci infos[index].format == GRAPHIC_PIXEL_FMT_YCRCB_420_SP) { 167832a6e48fSopenharmony_ci supporteds.push_back(true); 167932a6e48fSopenharmony_ci } else { 168032a6e48fSopenharmony_ci supporteds.push_back(false); 168132a6e48fSopenharmony_ci } 168232a6e48fSopenharmony_ci } 168332a6e48fSopenharmony_ci return GSERROR_OK; 168432a6e48fSopenharmony_ci} 168532a6e48fSopenharmony_ci 168632a6e48fSopenharmony_ciGSError BufferQueue::SetBufferHold(bool hold) 168732a6e48fSopenharmony_ci{ 168832a6e48fSopenharmony_ci std::unique_lock<std::mutex> lock(mutex_); 168932a6e48fSopenharmony_ci isBufferHold_ = hold; 169032a6e48fSopenharmony_ci return GSERROR_OK; 169132a6e48fSopenharmony_ci} 169232a6e48fSopenharmony_ci 169332a6e48fSopenharmony_ciGSError BufferQueue::SetScalingMode(uint32_t sequence, ScalingMode scalingMode) 169432a6e48fSopenharmony_ci{ 169532a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 169632a6e48fSopenharmony_ci if (bufferQueueCache_.find(sequence) == bufferQueueCache_.end()) { 169732a6e48fSopenharmony_ci return GSERROR_NO_ENTRY; 169832a6e48fSopenharmony_ci } 169932a6e48fSopenharmony_ci bufferQueueCache_[sequence].scalingMode = scalingMode; 170032a6e48fSopenharmony_ci return GSERROR_OK; 170132a6e48fSopenharmony_ci} 170232a6e48fSopenharmony_ci 170332a6e48fSopenharmony_ciGSError BufferQueue::SetScalingMode(ScalingMode scalingMode) 170432a6e48fSopenharmony_ci{ 170532a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 170632a6e48fSopenharmony_ci for (auto it = bufferQueueCache_.begin(); it != bufferQueueCache_.end(); it++) { 170732a6e48fSopenharmony_ci it->second.scalingMode = scalingMode; 170832a6e48fSopenharmony_ci } 170932a6e48fSopenharmony_ci scalingMode_ = scalingMode; 171032a6e48fSopenharmony_ci return GSERROR_OK; 171132a6e48fSopenharmony_ci} 171232a6e48fSopenharmony_ci 171332a6e48fSopenharmony_ciGSError BufferQueue::GetScalingMode(uint32_t sequence, ScalingMode &scalingMode) 171432a6e48fSopenharmony_ci{ 171532a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 171632a6e48fSopenharmony_ci if (bufferQueueCache_.find(sequence) == bufferQueueCache_.end()) { 171732a6e48fSopenharmony_ci return GSERROR_NO_ENTRY; 171832a6e48fSopenharmony_ci } 171932a6e48fSopenharmony_ci scalingMode = bufferQueueCache_.at(sequence).scalingMode; 172032a6e48fSopenharmony_ci return GSERROR_OK; 172132a6e48fSopenharmony_ci} 172232a6e48fSopenharmony_ci 172332a6e48fSopenharmony_ciGSError BufferQueue::SetMetaData(uint32_t sequence, const std::vector<GraphicHDRMetaData> &metaData) 172432a6e48fSopenharmony_ci{ 172532a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 172632a6e48fSopenharmony_ci if (metaData.size() == 0) { 172732a6e48fSopenharmony_ci BLOGW("metaData size is 0, uniqueId: %{public}" PRIu64 ".", uniqueId_); 172832a6e48fSopenharmony_ci return GSERROR_INVALID_ARGUMENTS; 172932a6e48fSopenharmony_ci } 173032a6e48fSopenharmony_ci if (bufferQueueCache_.find(sequence) == bufferQueueCache_.end()) { 173132a6e48fSopenharmony_ci return GSERROR_NO_ENTRY; 173232a6e48fSopenharmony_ci } 173332a6e48fSopenharmony_ci bufferQueueCache_[sequence].metaData.clear(); 173432a6e48fSopenharmony_ci bufferQueueCache_[sequence].metaData = metaData; 173532a6e48fSopenharmony_ci bufferQueueCache_[sequence].hdrMetaDataType = HDRMetaDataType::HDR_META_DATA; 173632a6e48fSopenharmony_ci return GSERROR_OK; 173732a6e48fSopenharmony_ci} 173832a6e48fSopenharmony_ci 173932a6e48fSopenharmony_ciGSError BufferQueue::SetMetaDataSet(uint32_t sequence, GraphicHDRMetadataKey key, 174032a6e48fSopenharmony_ci const std::vector<uint8_t> &metaData) 174132a6e48fSopenharmony_ci{ 174232a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 174332a6e48fSopenharmony_ci if (key < GraphicHDRMetadataKey::GRAPHIC_MATAKEY_RED_PRIMARY_X || 174432a6e48fSopenharmony_ci key > GraphicHDRMetadataKey::GRAPHIC_MATAKEY_HDR_VIVID) { 174532a6e48fSopenharmony_ci BLOGW("key is %{public}d, uniqueId: %{public}" PRIu64 ".", key, uniqueId_); 174632a6e48fSopenharmony_ci return GSERROR_INVALID_ARGUMENTS; 174732a6e48fSopenharmony_ci } 174832a6e48fSopenharmony_ci if (metaData.size() == 0) { 174932a6e48fSopenharmony_ci BLOGW("metaData size is 0, uniqueId: %{public}" PRIu64 ".", uniqueId_); 175032a6e48fSopenharmony_ci return GSERROR_INVALID_ARGUMENTS; 175132a6e48fSopenharmony_ci } 175232a6e48fSopenharmony_ci if (bufferQueueCache_.find(sequence) == bufferQueueCache_.end()) { 175332a6e48fSopenharmony_ci return GSERROR_NO_ENTRY; 175432a6e48fSopenharmony_ci } 175532a6e48fSopenharmony_ci bufferQueueCache_[sequence].metaDataSet.clear(); 175632a6e48fSopenharmony_ci bufferQueueCache_[sequence].key = key; 175732a6e48fSopenharmony_ci bufferQueueCache_[sequence].metaDataSet = metaData; 175832a6e48fSopenharmony_ci bufferQueueCache_[sequence].hdrMetaDataType = HDRMetaDataType::HDR_META_DATA_SET; 175932a6e48fSopenharmony_ci return GSERROR_OK; 176032a6e48fSopenharmony_ci} 176132a6e48fSopenharmony_ci 176232a6e48fSopenharmony_ciGSError BufferQueue::QueryMetaDataType(uint32_t sequence, HDRMetaDataType &type) 176332a6e48fSopenharmony_ci{ 176432a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 176532a6e48fSopenharmony_ci if (bufferQueueCache_.find(sequence) == bufferQueueCache_.end()) { 176632a6e48fSopenharmony_ci return GSERROR_NO_ENTRY; 176732a6e48fSopenharmony_ci } 176832a6e48fSopenharmony_ci type = bufferQueueCache_.at(sequence).hdrMetaDataType; 176932a6e48fSopenharmony_ci return GSERROR_OK; 177032a6e48fSopenharmony_ci} 177132a6e48fSopenharmony_ci 177232a6e48fSopenharmony_ciGSError BufferQueue::GetMetaData(uint32_t sequence, std::vector<GraphicHDRMetaData> &metaData) 177332a6e48fSopenharmony_ci{ 177432a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 177532a6e48fSopenharmony_ci if (bufferQueueCache_.find(sequence) == bufferQueueCache_.end()) { 177632a6e48fSopenharmony_ci return GSERROR_NO_ENTRY; 177732a6e48fSopenharmony_ci } 177832a6e48fSopenharmony_ci metaData.clear(); 177932a6e48fSopenharmony_ci metaData = bufferQueueCache_.at(sequence).metaData; 178032a6e48fSopenharmony_ci return GSERROR_OK; 178132a6e48fSopenharmony_ci} 178232a6e48fSopenharmony_ci 178332a6e48fSopenharmony_ciGSError BufferQueue::GetMetaDataSet(uint32_t sequence, GraphicHDRMetadataKey &key, 178432a6e48fSopenharmony_ci std::vector<uint8_t> &metaData) 178532a6e48fSopenharmony_ci{ 178632a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 178732a6e48fSopenharmony_ci if (bufferQueueCache_.find(sequence) == bufferQueueCache_.end()) { 178832a6e48fSopenharmony_ci return GSERROR_NO_ENTRY; 178932a6e48fSopenharmony_ci } 179032a6e48fSopenharmony_ci metaData.clear(); 179132a6e48fSopenharmony_ci key = bufferQueueCache_.at(sequence).key; 179232a6e48fSopenharmony_ci metaData = bufferQueueCache_.at(sequence).metaDataSet; 179332a6e48fSopenharmony_ci return GSERROR_OK; 179432a6e48fSopenharmony_ci} 179532a6e48fSopenharmony_ci 179632a6e48fSopenharmony_ciGSError BufferQueue::SetTunnelHandle(const sptr<SurfaceTunnelHandle> &handle) 179732a6e48fSopenharmony_ci{ 179832a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 179932a6e48fSopenharmony_ci bool tunnelHandleChange = false; 180032a6e48fSopenharmony_ci if (tunnelHandle_ == nullptr) { 180132a6e48fSopenharmony_ci if (handle == nullptr) { 180232a6e48fSopenharmony_ci BLOGW("tunnel handle is nullptr, uniqueId: %{public}" PRIu64 ".", uniqueId_); 180332a6e48fSopenharmony_ci return GSERROR_INVALID_ARGUMENTS; 180432a6e48fSopenharmony_ci } 180532a6e48fSopenharmony_ci tunnelHandleChange = true; 180632a6e48fSopenharmony_ci } else { 180732a6e48fSopenharmony_ci tunnelHandleChange = tunnelHandle_->Different(handle); 180832a6e48fSopenharmony_ci } 180932a6e48fSopenharmony_ci if (!tunnelHandleChange) { 181032a6e48fSopenharmony_ci BLOGW("same tunnel handle, uniqueId: %{public}" PRIu64 ".", uniqueId_); 181132a6e48fSopenharmony_ci return GSERROR_NO_ENTRY; 181232a6e48fSopenharmony_ci } 181332a6e48fSopenharmony_ci tunnelHandle_ = handle; 181432a6e48fSopenharmony_ci sptr<IBufferConsumerListener> listener; 181532a6e48fSopenharmony_ci IBufferConsumerListenerClazz *listenerClazz; 181632a6e48fSopenharmony_ci { 181732a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(listenerMutex_); 181832a6e48fSopenharmony_ci listener = listener_; 181932a6e48fSopenharmony_ci listenerClazz = listenerClazz_; 182032a6e48fSopenharmony_ci } 182132a6e48fSopenharmony_ci if (listener != nullptr) { 182232a6e48fSopenharmony_ci SURFACE_TRACE_NAME("OnTunnelHandleChange"); 182332a6e48fSopenharmony_ci listener->OnTunnelHandleChange(); 182432a6e48fSopenharmony_ci } else if (listenerClazz != nullptr) { 182532a6e48fSopenharmony_ci SURFACE_TRACE_NAME("OnTunnelHandleChange"); 182632a6e48fSopenharmony_ci listenerClazz->OnTunnelHandleChange(); 182732a6e48fSopenharmony_ci } else { 182832a6e48fSopenharmony_ci return SURFACE_ERROR_CONSUMER_UNREGISTER_LISTENER; 182932a6e48fSopenharmony_ci } 183032a6e48fSopenharmony_ci return GSERROR_OK; 183132a6e48fSopenharmony_ci} 183232a6e48fSopenharmony_ci 183332a6e48fSopenharmony_cisptr<SurfaceTunnelHandle> BufferQueue::GetTunnelHandle() 183432a6e48fSopenharmony_ci{ 183532a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 183632a6e48fSopenharmony_ci return tunnelHandle_; 183732a6e48fSopenharmony_ci} 183832a6e48fSopenharmony_ci 183932a6e48fSopenharmony_ciGSError BufferQueue::SetPresentTimestamp(uint32_t sequence, const GraphicPresentTimestamp ×tamp) 184032a6e48fSopenharmony_ci{ 184132a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 184232a6e48fSopenharmony_ci if (bufferQueueCache_.find(sequence) == bufferQueueCache_.end()) { 184332a6e48fSopenharmony_ci return GSERROR_NO_ENTRY; 184432a6e48fSopenharmony_ci } 184532a6e48fSopenharmony_ci bufferQueueCache_[sequence].presentTimestamp = timestamp; 184632a6e48fSopenharmony_ci return GSERROR_OK; 184732a6e48fSopenharmony_ci} 184832a6e48fSopenharmony_ci 184932a6e48fSopenharmony_ciGSError BufferQueue::GetPresentTimestamp(uint32_t sequence, GraphicPresentTimestampType type, int64_t &time) 185032a6e48fSopenharmony_ci{ 185132a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 185232a6e48fSopenharmony_ci if (bufferQueueCache_.find(sequence) == bufferQueueCache_.end()) { 185332a6e48fSopenharmony_ci return GSERROR_NO_ENTRY; 185432a6e48fSopenharmony_ci } 185532a6e48fSopenharmony_ci if (type != bufferQueueCache_.at(sequence).presentTimestamp.type) { 185632a6e48fSopenharmony_ci BLOGE("seq: %{public}u, PresentTimestampType [%{public}d] is not supported, the supported type is [%{public}d]," 185732a6e48fSopenharmony_ci "uniqueId: %{public}" PRIu64 ".", sequence, type, 185832a6e48fSopenharmony_ci bufferQueueCache_.at(sequence).presentTimestamp.type, uniqueId_); 185932a6e48fSopenharmony_ci return GSERROR_NO_ENTRY; 186032a6e48fSopenharmony_ci } 186132a6e48fSopenharmony_ci switch (type) { 186232a6e48fSopenharmony_ci case GraphicPresentTimestampType::GRAPHIC_DISPLAY_PTS_DELAY: { 186332a6e48fSopenharmony_ci time = bufferQueueCache_.at(sequence).presentTimestamp.time; 186432a6e48fSopenharmony_ci return GSERROR_OK; 186532a6e48fSopenharmony_ci } 186632a6e48fSopenharmony_ci case GraphicPresentTimestampType::GRAPHIC_DISPLAY_PTS_TIMESTAMP: { 186732a6e48fSopenharmony_ci time = bufferQueueCache_.at(sequence).presentTimestamp.time - bufferQueueCache_.at(sequence).timestamp; 186832a6e48fSopenharmony_ci return GSERROR_OK; 186932a6e48fSopenharmony_ci } 187032a6e48fSopenharmony_ci default: { 187132a6e48fSopenharmony_ci BLOGE("seq: %{public}u, unsupported type: %{public}d, uniqueId: %{public}" PRIu64 ".", 187232a6e48fSopenharmony_ci sequence, type, uniqueId_); 187332a6e48fSopenharmony_ci return GSERROR_TYPE_ERROR; 187432a6e48fSopenharmony_ci } 187532a6e48fSopenharmony_ci } 187632a6e48fSopenharmony_ci} 187732a6e48fSopenharmony_ci 187832a6e48fSopenharmony_civoid BufferQueue::SetSurfaceBufferGlobalAlphaUnlocked(sptr<SurfaceBuffer> buffer) 187932a6e48fSopenharmony_ci{ 188032a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(globalAlphaMutex_); 188132a6e48fSopenharmony_ci if (globalAlpha_ < FORCE_GLOBAL_ALPHA_MIN || globalAlpha_ > FORCE_GLOBAL_ALPHA_MAX) { 188232a6e48fSopenharmony_ci BLOGE("Invalid global alpha value: %{public}d, uniqueId: %{public}" PRIu64 ".", globalAlpha_, uniqueId_); 188332a6e48fSopenharmony_ci return; 188432a6e48fSopenharmony_ci } 188532a6e48fSopenharmony_ci using namespace HDI::Display::Graphic::Common; 188632a6e48fSopenharmony_ci V2_0::BufferHandleAttrKey key = V2_0::BufferHandleAttrKey::ATTRKEY_FORCE_GLOBAL_ALPHA; 188732a6e48fSopenharmony_ci std::vector<uint8_t> values; 188832a6e48fSopenharmony_ci auto ret = MetadataHelper::ConvertMetadataToVec(globalAlpha_, values); 188932a6e48fSopenharmony_ci if (ret != GSERROR_OK) { 189032a6e48fSopenharmony_ci BLOGE("Convert global alpha value failed, ret: %{public}d, value: %{public}d, uniqueId: %{public}" PRIu64 ".", 189132a6e48fSopenharmony_ci ret, globalAlpha_, uniqueId_); 189232a6e48fSopenharmony_ci return; 189332a6e48fSopenharmony_ci } 189432a6e48fSopenharmony_ci buffer->SetMetadata(key, values); 189532a6e48fSopenharmony_ci} 189632a6e48fSopenharmony_ci 189732a6e48fSopenharmony_ciGSError BufferQueue::SetGlobalAlpha(int32_t alpha) 189832a6e48fSopenharmony_ci{ 189932a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(globalAlphaMutex_); 190032a6e48fSopenharmony_ci globalAlpha_ = alpha; 190132a6e48fSopenharmony_ci return GSERROR_OK; 190232a6e48fSopenharmony_ci} 190332a6e48fSopenharmony_ci 190432a6e48fSopenharmony_ciGSError BufferQueue::GetGlobalAlpha(int32_t &alpha) 190532a6e48fSopenharmony_ci{ 190632a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(globalAlphaMutex_); 190732a6e48fSopenharmony_ci alpha = globalAlpha_; 190832a6e48fSopenharmony_ci return GSERROR_OK; 190932a6e48fSopenharmony_ci} 191032a6e48fSopenharmony_ci 191132a6e48fSopenharmony_civoid BufferQueue::DumpMetadata(std::string &result, BufferElement element) 191232a6e48fSopenharmony_ci{ 191332a6e48fSopenharmony_ci HDI::Display::Graphic::Common::V1_0::CM_ColorSpaceType colorSpaceType; 191432a6e48fSopenharmony_ci MetadataHelper::GetColorSpaceType(element.buffer, colorSpaceType); 191532a6e48fSopenharmony_ci HDI::Display::Graphic::Common::V1_0::CM_HDR_Metadata_Type hdrMetadataType = 191632a6e48fSopenharmony_ci HDI::Display::Graphic::Common::V1_0::CM_METADATA_NONE; 191732a6e48fSopenharmony_ci std::vector<uint8_t> dataStatic; 191832a6e48fSopenharmony_ci std::vector<uint8_t> dataDynamic; 191932a6e48fSopenharmony_ci MetadataHelper::GetHDRDynamicMetadata(element.buffer, dataDynamic); 192032a6e48fSopenharmony_ci MetadataHelper::GetHDRStaticMetadata(element.buffer, dataStatic); 192132a6e48fSopenharmony_ci MetadataHelper::GetHDRMetadataType(element.buffer, hdrMetadataType); 192232a6e48fSopenharmony_ci result += std::to_string(colorSpaceType) + ", "; 192332a6e48fSopenharmony_ci result += " [staticMetadata: "; 192432a6e48fSopenharmony_ci for (auto x : dataStatic) { 192532a6e48fSopenharmony_ci result += std::to_string(x); 192632a6e48fSopenharmony_ci result += " "; 192732a6e48fSopenharmony_ci } 192832a6e48fSopenharmony_ci result += " ],[dynamicMetadata: "; 192932a6e48fSopenharmony_ci for (auto x : dataDynamic) { 193032a6e48fSopenharmony_ci result += std::to_string(x); 193132a6e48fSopenharmony_ci result += " "; 193232a6e48fSopenharmony_ci } 193332a6e48fSopenharmony_ci result += " ],[metadataType: "; 193432a6e48fSopenharmony_ci result += std::to_string(hdrMetadataType) + "],"; 193532a6e48fSopenharmony_ci} 193632a6e48fSopenharmony_ci 193732a6e48fSopenharmony_civoid BufferQueue::DumpCache(std::string &result) 193832a6e48fSopenharmony_ci{ 193932a6e48fSopenharmony_ci for (auto it = bufferQueueCache_.begin(); it != bufferQueueCache_.end(); it++) { 194032a6e48fSopenharmony_ci BufferElement element = it->second; 194132a6e48fSopenharmony_ci if (BufferStateStrs.find(element.state) != BufferStateStrs.end()) { 194232a6e48fSopenharmony_ci result += " sequence = " + std::to_string(it->first) + 194332a6e48fSopenharmony_ci ", state = " + std::to_string(element.state) + 194432a6e48fSopenharmony_ci ", timestamp = " + std::to_string(element.timestamp); 194532a6e48fSopenharmony_ci } 194632a6e48fSopenharmony_ci for (decltype(element.damages.size()) i = 0; i < element.damages.size(); i++) { 194732a6e48fSopenharmony_ci result += ", damagesRect = [" + std::to_string(i) + "] = [" + 194832a6e48fSopenharmony_ci std::to_string(element.damages[i].x) + ", " + 194932a6e48fSopenharmony_ci std::to_string(element.damages[i].y) + ", " + 195032a6e48fSopenharmony_ci std::to_string(element.damages[i].w) + ", " + 195132a6e48fSopenharmony_ci std::to_string(element.damages[i].h) + "],"; 195232a6e48fSopenharmony_ci } 195332a6e48fSopenharmony_ci result += " config = [" + std::to_string(element.config.width) + "x" + 195432a6e48fSopenharmony_ci std::to_string(element.config.height) + ", " + 195532a6e48fSopenharmony_ci std::to_string(element.config.strideAlignment) + ", " + 195632a6e48fSopenharmony_ci std::to_string(element.config.format) +", " + 195732a6e48fSopenharmony_ci std::to_string(element.config.usage) + ", " + 195832a6e48fSopenharmony_ci std::to_string(element.config.timeout) + ", " + 195932a6e48fSopenharmony_ci std::to_string(element.config.colorGamut) + ", " + 196032a6e48fSopenharmony_ci std::to_string(element.config.transform) + "],"; 196132a6e48fSopenharmony_ci DumpMetadata(result, element); 196232a6e48fSopenharmony_ci result += " scalingMode = " + std::to_string(element.scalingMode) + ","; 196332a6e48fSopenharmony_ci result += " HDR = " + std::to_string(element.hdrMetaDataType) + ", "; 196432a6e48fSopenharmony_ci 196532a6e48fSopenharmony_ci double bufferMemSize = 0; 196632a6e48fSopenharmony_ci if (element.buffer != nullptr) { 196732a6e48fSopenharmony_ci result += " bufferWith = " + std::to_string(element.buffer->GetWidth()) + 196832a6e48fSopenharmony_ci ", bufferHeight = " + std::to_string(element.buffer->GetHeight()); 196932a6e48fSopenharmony_ci bufferMemSize = static_cast<double>(element.buffer->GetSize()) / BUFFER_MEMSIZE_RATE; 197032a6e48fSopenharmony_ci } 197132a6e48fSopenharmony_ci 197232a6e48fSopenharmony_ci std::ostringstream ss; 197332a6e48fSopenharmony_ci ss.precision(BUFFER_MEMSIZE_FORMAT); 197432a6e48fSopenharmony_ci ss.setf(std::ios::fixed); 197532a6e48fSopenharmony_ci ss << bufferMemSize; 197632a6e48fSopenharmony_ci std::string str = ss.str(); 197732a6e48fSopenharmony_ci result += ", bufferMemSize = " + str + "(KiB).\n"; 197832a6e48fSopenharmony_ci } 197932a6e48fSopenharmony_ci} 198032a6e48fSopenharmony_ci 198132a6e48fSopenharmony_civoid BufferQueue::Dump(std::string &result) 198232a6e48fSopenharmony_ci{ 198332a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 198432a6e48fSopenharmony_ci std::ostringstream ss; 198532a6e48fSopenharmony_ci ss.precision(BUFFER_MEMSIZE_FORMAT); 198632a6e48fSopenharmony_ci ss.setf(std::ios::fixed); 198732a6e48fSopenharmony_ci static double allSurfacesMemSize = 0; 198832a6e48fSopenharmony_ci uint64_t totalBufferListSize = 0; 198932a6e48fSopenharmony_ci double memSizeInKB = 0; 199032a6e48fSopenharmony_ci 199132a6e48fSopenharmony_ci for (auto it = bufferQueueCache_.begin(); it != bufferQueueCache_.end(); it++) { 199232a6e48fSopenharmony_ci BufferElement element = it->second; 199332a6e48fSopenharmony_ci if (element.buffer != nullptr) { 199432a6e48fSopenharmony_ci totalBufferListSize += element.buffer->GetSize(); 199532a6e48fSopenharmony_ci } 199632a6e48fSopenharmony_ci } 199732a6e48fSopenharmony_ci memSizeInKB = static_cast<double>(totalBufferListSize) / BUFFER_MEMSIZE_RATE; 199832a6e48fSopenharmony_ci 199932a6e48fSopenharmony_ci allSurfacesMemSize += memSizeInKB; 200032a6e48fSopenharmony_ci uint32_t resultLen = result.size(); 200132a6e48fSopenharmony_ci std::string dumpEndFlag = "dumpend"; 200232a6e48fSopenharmony_ci if (resultLen > dumpEndFlag.size() && resultLen > 1) { 200332a6e48fSopenharmony_ci std::string dumpEndIn(result, resultLen - dumpEndFlag.size(), resultLen - 1); 200432a6e48fSopenharmony_ci if (dumpEndIn == dumpEndFlag) { 200532a6e48fSopenharmony_ci ss << allSurfacesMemSize; 200632a6e48fSopenharmony_ci std::string dumpEndStr = ss.str(); 200732a6e48fSopenharmony_ci result.erase(resultLen - dumpEndFlag.size(), resultLen - 1); 200832a6e48fSopenharmony_ci result += dumpEndStr + " KiB.\n"; 200932a6e48fSopenharmony_ci allSurfacesMemSize = 0; 201032a6e48fSopenharmony_ci return; 201132a6e48fSopenharmony_ci } 201232a6e48fSopenharmony_ci } 201332a6e48fSopenharmony_ci 201432a6e48fSopenharmony_ci ss.str(""); 201532a6e48fSopenharmony_ci ss << memSizeInKB; 201632a6e48fSopenharmony_ci std::string str = ss.str(); 201732a6e48fSopenharmony_ci result.append("\nBufferQueue:\n"); 201832a6e48fSopenharmony_ci result += " default-size = [" + std::to_string(defaultWidth_) + "x" + std::to_string(defaultHeight_) + "]" + 201932a6e48fSopenharmony_ci ", FIFO = " + std::to_string(bufferQueueSize_) + 202032a6e48fSopenharmony_ci ", name = " + name_ + 202132a6e48fSopenharmony_ci ", uniqueId = " + std::to_string(uniqueId_) + 202232a6e48fSopenharmony_ci ", usedBufferListLen = " + std::to_string(GetUsedSize()) + 202332a6e48fSopenharmony_ci ", freeBufferListLen = " + std::to_string(freeList_.size()) + 202432a6e48fSopenharmony_ci ", dirtyBufferListLen = " + std::to_string(dirtyList_.size()) + 202532a6e48fSopenharmony_ci ", totalBuffersMemSize = " + str + "(KiB)" + 202632a6e48fSopenharmony_ci ", hdrWhitePointBrightness = " + std::to_string(hdrWhitePointBrightness_) + 202732a6e48fSopenharmony_ci ", sdrWhitePointBrightness = " + std::to_string(sdrWhitePointBrightness_) + 202832a6e48fSopenharmony_ci ", lockLastFlushedBuffer seq = " + std::to_string(acquireLastFlushedBufSequence_) + "\n"; 202932a6e48fSopenharmony_ci 203032a6e48fSopenharmony_ci result.append(" bufferQueueCache:\n"); 203132a6e48fSopenharmony_ci DumpCache(result); 203232a6e48fSopenharmony_ci} 203332a6e48fSopenharmony_ci 203432a6e48fSopenharmony_cibool BufferQueue::GetStatusLocked() const 203532a6e48fSopenharmony_ci{ 203632a6e48fSopenharmony_ci return isValidStatus_; 203732a6e48fSopenharmony_ci} 203832a6e48fSopenharmony_ci 203932a6e48fSopenharmony_cibool BufferQueue::GetStatus() const 204032a6e48fSopenharmony_ci{ 204132a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 204232a6e48fSopenharmony_ci return GetStatusLocked(); 204332a6e48fSopenharmony_ci} 204432a6e48fSopenharmony_ci 204532a6e48fSopenharmony_civoid BufferQueue::SetStatus(bool status) 204632a6e48fSopenharmony_ci{ 204732a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 204832a6e48fSopenharmony_ci isValidStatus_ = status; 204932a6e48fSopenharmony_ci waitReqCon_.notify_all(); 205032a6e48fSopenharmony_ci} 205132a6e48fSopenharmony_ci 205232a6e48fSopenharmony_ciuint32_t BufferQueue::GetAvailableBufferCount() 205332a6e48fSopenharmony_ci{ 205432a6e48fSopenharmony_ci std::lock_guard<std::mutex> lockGuard(mutex_); 205532a6e48fSopenharmony_ci return static_cast<uint32_t>(dirtyList_.size()); 205632a6e48fSopenharmony_ci} 205732a6e48fSopenharmony_ci}; // namespace OHOS 2058