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 &timestamp, 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 &timestamp)
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