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