1/*
2 * Copyright (c) 2021-2023 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 "surface_buffer_impl.h"
17
18#include <mutex>
19
20#include <message_parcel.h>
21#include <parameters.h>
22#include <securec.h>
23#include <sys/mman.h>
24#include "buffer_log.h"
25#include "buffer_extra_data_impl.h"
26#include "v1_1/buffer_handle_meta_key_type.h"
27#include "v1_2/display_buffer_type.h"
28#include "v1_2/include/idisplay_buffer.h"
29
30namespace OHOS {
31namespace {
32using IDisplayBufferSptr = std::shared_ptr<OHOS::HDI::Display::Buffer::V1_2::IDisplayBuffer>;
33static IDisplayBufferSptr g_displayBuffer;
34static std::mutex g_displayBufferMutex;
35class DisplayBufferDiedRecipient : public OHOS::IRemoteObject::DeathRecipient {
36public:
37    DisplayBufferDiedRecipient() = default;
38    virtual ~DisplayBufferDiedRecipient() = default;
39    void OnRemoteDied(const OHOS::wptr<OHOS::IRemoteObject>& remote) override
40    {
41        std::lock_guard<std::mutex> bufferLock(g_displayBufferMutex);
42        g_displayBuffer = nullptr;
43        BLOGD("IDisplayBuffer died and g_displayBuffer is nullptr");
44    };
45};
46
47IDisplayBufferSptr GetDisplayBuffer()
48{
49    std::lock_guard<std::mutex> bufferLock(g_displayBufferMutex);
50    if (g_displayBuffer != nullptr) {
51        return g_displayBuffer;
52    }
53    return nullptr;
54}
55
56IDisplayBufferSptr GetOrResetDisplayBuffer()
57{
58    std::lock_guard<std::mutex> bufferLock(g_displayBufferMutex);
59    if (g_displayBuffer != nullptr) {
60        return g_displayBuffer;
61    }
62
63    g_displayBuffer.reset(OHOS::HDI::Display::Buffer::V1_2::IDisplayBuffer::Get());
64    if (g_displayBuffer == nullptr) {
65        BLOGE("IDisplayBuffer::Get return nullptr.");
66        return nullptr;
67    }
68    sptr<IRemoteObject::DeathRecipient> recipient = new DisplayBufferDiedRecipient();
69    g_displayBuffer->AddDeathRecipient(recipient);
70    return g_displayBuffer;
71}
72
73constexpr int32_t INVALID_ARGUMENT = -1;
74constexpr uint64_t INVALID_PHYADDR = 0;
75constexpr uint32_t INVALID_SIZE = 0;
76constexpr uint64_t INVALID_USAGE = std::numeric_limits<std::uint64_t>::max();
77}
78
79sptr<SurfaceBuffer> SurfaceBuffer::Create()
80{
81    sptr<SurfaceBuffer> surfaceBufferImpl = new SurfaceBufferImpl();
82    return surfaceBufferImpl;
83}
84
85SurfaceBufferImpl::SurfaceBufferImpl()
86{
87    {
88        static std::mutex mutex;
89        mutex.lock();
90
91        static uint32_t sequence_number_ = 0;
92        // 0xFFFF is pid mask. 16 is pid offset.
93        sequenceNumber_ = (static_cast<uint32_t>(getpid()) & 0xFFFF) << 16;
94        // 0xFFFF is seqnum mask.
95        sequenceNumber_ |= (sequence_number_++ & 0xFFFF);
96
97        mutex.unlock();
98    }
99    metaDataCache_.clear();
100    bedata_ = new BufferExtraDataImpl;
101    BLOGD("SurfaceBufferImpl ctor, seq: %{public}u", sequenceNumber_);
102}
103
104SurfaceBufferImpl::SurfaceBufferImpl(uint32_t seqNum)
105{
106    metaDataCache_.clear();
107    sequenceNumber_ = seqNum;
108    bedata_ = new BufferExtraDataImpl;
109    BLOGD("SurfaceBufferImpl ctor, seq: %{public}u", sequenceNumber_);
110}
111
112SurfaceBufferImpl::~SurfaceBufferImpl()
113{
114    BLOGD("~SurfaceBufferImpl dtor, seq: %{public}u", sequenceNumber_);
115    FreeBufferHandleLocked();
116}
117
118bool SurfaceBufferImpl::MetaDataCachedLocked(const uint32_t key, const std::vector<uint8_t>& value)
119{
120    auto iter = metaDataCache_.find(key);
121    if (iter != metaDataCache_.end() && (*iter).second == value) {
122        return true;
123    }
124    return false;
125}
126
127GSError SurfaceBufferImpl::Alloc(const BufferRequestConfig& config)
128{
129    IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer();
130    if (displayBuffer == nullptr) {
131        return GSERROR_INTERNAL;
132    }
133    std::lock_guard<std::mutex> lock(mutex_);
134    FreeBufferHandleLocked();
135
136    GSError ret = CheckBufferConfig(config.width, config.height, config.format, config.usage);
137    if (ret != GSERROR_OK) {
138        return GSERROR_INVALID_ARGUMENTS;
139    }
140
141    OHOS::HDI::Display::Buffer::V1_0::AllocInfo info = {config.width, config.height, config.usage, config.format};
142    static bool debugHebcDisabled =
143        std::atoi((system::GetParameter("persist.graphic.debug_hebc.disabled", "0")).c_str()) != 0;
144    if (debugHebcDisabled) {
145        info.usage |= (BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA);
146    }
147    auto dRet = displayBuffer->AllocMem(info, handle_);
148    if (dRet == GRAPHIC_DISPLAY_SUCCESS && handle_ != nullptr) {
149        dRet = displayBuffer->RegisterBuffer(*handle_);
150        if (dRet != GRAPHIC_DISPLAY_SUCCESS && dRet != GRAPHIC_DISPLAY_NOT_SUPPORT) {
151            BLOGE("AllocMem RegisterBuffer Failed with %{public}d", dRet);
152            return GSERROR_HDI_ERROR;
153        }
154        surfaceBufferColorGamut_ = static_cast<GraphicColorGamut>(config.colorGamut);
155        transform_ = static_cast<GraphicTransformType>(config.transform);
156        surfaceBufferWidth_ = config.width;
157        surfaceBufferHeight_ = config.height;
158        bufferRequestConfig_ = config;
159        BLOGD("handle w: %{public}d h: %{public}d t: %{public}d, seq: %{public}u",
160            handle_->width, handle_->height, config.transform, sequenceNumber_);
161        return GSERROR_OK;
162    }
163    BLOGW("Alloc Failed with %{public}d, seq: %{public}u", dRet, sequenceNumber_);
164    return GSERROR_HDI_ERROR;
165}
166
167GSError SurfaceBufferImpl::Map()
168{
169    IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer();
170    if (displayBuffer == nullptr) {
171        return GSERROR_INTERNAL;
172    }
173    std::lock_guard<std::mutex> lock(mutex_);
174    if (handle_ == nullptr) {
175        return GSERROR_INVALID_OPERATING;
176    } else if (handle_->virAddr != nullptr) {
177        BLOGD("handle_->virAddr has been maped, seq: %{public}u", sequenceNumber_);
178        return GSERROR_OK;
179    }
180    if (handle_->usage & BUFFER_USAGE_PROTECTED) {
181        BLOGD("usage is BUFFER_USAGE_PROTECTED, do not Map, seq: %{public}u", sequenceNumber_);
182        return GSERROR_OK;
183    }
184
185    void* virAddr = displayBuffer->Mmap(*handle_);
186    if (virAddr == nullptr || virAddr == MAP_FAILED) {
187        return GSERROR_HDI_ERROR;
188    }
189    return GSERROR_OK;
190}
191
192GSError SurfaceBufferImpl::Unmap()
193{
194    IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer();
195    if (displayBuffer == nullptr) {
196        return GSERROR_INTERNAL;
197    }
198    std::lock_guard<std::mutex> lock(mutex_);
199    if (handle_ == nullptr) {
200        return GSERROR_INVALID_OPERATING;
201    } else if (handle_->virAddr == nullptr) {
202        BLOGW("handle has been unmaped, seq: %{public}u", sequenceNumber_);
203        return GSERROR_OK;
204    }
205    auto dRet = displayBuffer->Unmap(*handle_);
206    if (dRet == GRAPHIC_DISPLAY_SUCCESS) {
207        handle_->virAddr = nullptr;
208        return GSERROR_OK;
209    }
210    BLOGW("Unmap Failed with %{public}d, seq: %{public}u", dRet, sequenceNumber_);
211    return GSERROR_HDI_ERROR;
212}
213
214GSError SurfaceBufferImpl::FlushCache()
215{
216    IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer();
217    if (displayBuffer == nullptr) {
218        return GSERROR_INTERNAL;
219    }
220
221    std::lock_guard<std::mutex> lock(mutex_);
222    if (handle_ == nullptr) {
223        return GSERROR_INVALID_OPERATING;
224    }
225    auto dRet = displayBuffer->FlushCache(*handle_);
226    if (dRet == GRAPHIC_DISPLAY_SUCCESS) {
227        return GSERROR_OK;
228    }
229    BLOGW("FlushCache Failed with %{public}d, seq: %{public}u", dRet, sequenceNumber_);
230    return GSERROR_HDI_ERROR;
231}
232
233GSError SurfaceBufferImpl::GetImageLayout(void* layout)
234{
235    IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer();
236    if (displayBuffer == nullptr) {
237        return GSERROR_INTERNAL;
238    }
239    std::lock_guard<std::mutex> lock(mutex_);
240    if (handle_ == nullptr) {
241        return GSERROR_INVALID_OPERATING;
242    } else if (planesInfo_.planeCount != 0) {
243        return GSERROR_OK;
244    }
245
246    auto dRet = displayBuffer->GetImageLayout(*handle_,
247        *(static_cast<OHOS::HDI::Display::Buffer::V1_2::ImageLayout*>(layout)));
248    if (dRet == GRAPHIC_DISPLAY_SUCCESS) {
249        return GSERROR_OK;
250    }
251    BLOGW("GetImageLayout Failed with %{public}d, seq: %{public}u", dRet, sequenceNumber_);
252    return GSERROR_HDI_ERROR;
253}
254
255GSError SurfaceBufferImpl::InvalidateCache()
256{
257    IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer();
258    if (displayBuffer == nullptr) {
259        return GSERROR_INTERNAL;
260    }
261    std::lock_guard<std::mutex> lock(mutex_);
262    if (handle_ == nullptr) {
263        return GSERROR_INVALID_OPERATING;
264    }
265
266    auto dRet = displayBuffer->InvalidateCache(*handle_);
267    if (dRet == GRAPHIC_DISPLAY_SUCCESS) {
268        return GSERROR_OK;
269    }
270    BLOGW("InvalidateCache Failed with %{public}d, seq: %{public}u", dRet, sequenceNumber_);
271    return GSERROR_HDI_ERROR;
272}
273
274void SurfaceBufferImpl::FreeBufferHandleLocked()
275{
276    metaDataCache_.clear();
277    if (handle_) {
278        IDisplayBufferSptr displayBuffer = GetDisplayBuffer();
279        if (displayBuffer == nullptr) {
280            FreeBufferHandle(handle_);
281            handle_ = nullptr;
282            return;
283        }
284        if (handle_->virAddr != nullptr) {
285            displayBuffer->Unmap(*handle_);
286            handle_->virAddr = nullptr;
287        }
288        displayBuffer->FreeMem(*handle_);
289        handle_ = nullptr;
290    }
291}
292
293// return BufferHandle* is dangerous, need to refactor
294BufferHandle* SurfaceBufferImpl::GetBufferHandle() const
295{
296    std::lock_guard<std::mutex> lock(mutex_);
297    return handle_;
298}
299
300void SurfaceBufferImpl::SetSurfaceBufferColorGamut(const GraphicColorGamut& colorGamut)
301{
302    std::lock_guard<std::mutex> lock(mutex_);
303    if (surfaceBufferColorGamut_ != colorGamut) {
304        surfaceBufferColorGamut_ = colorGamut;
305    }
306}
307
308GraphicColorGamut SurfaceBufferImpl::GetSurfaceBufferColorGamut() const
309{
310    std::lock_guard<std::mutex> lock(mutex_);
311    return surfaceBufferColorGamut_;
312}
313
314void SurfaceBufferImpl::SetSurfaceBufferTransform(const GraphicTransformType& transform)
315{
316    std::lock_guard<std::mutex> lock(mutex_);
317    if (transform_ != transform) {
318        transform_ = transform;
319    }
320}
321
322GraphicTransformType SurfaceBufferImpl::GetSurfaceBufferTransform() const
323{
324    std::lock_guard<std::mutex> lock(mutex_);
325    return transform_;
326}
327
328int32_t SurfaceBufferImpl::GetSurfaceBufferWidth() const
329{
330    std::lock_guard<std::mutex> lock(mutex_);
331    return surfaceBufferWidth_;
332}
333
334int32_t SurfaceBufferImpl::GetSurfaceBufferHeight() const
335{
336    std::lock_guard<std::mutex> lock(mutex_);
337    return surfaceBufferHeight_;
338}
339
340void SurfaceBufferImpl::SetSurfaceBufferWidth(int32_t width)
341{
342    std::lock_guard<std::mutex> lock(mutex_);
343    surfaceBufferWidth_ = width;
344}
345
346void SurfaceBufferImpl::SetSurfaceBufferHeight(int32_t height)
347{
348    std::lock_guard<std::mutex> lock(mutex_);
349    surfaceBufferHeight_ = height;
350}
351
352int32_t SurfaceBufferImpl::GetWidth() const
353{
354    std::lock_guard<std::mutex> lock(mutex_);
355    if (handle_ == nullptr) {
356        return INVALID_ARGUMENT;
357    }
358    return handle_->width;
359}
360
361int32_t SurfaceBufferImpl::GetHeight() const
362{
363    std::lock_guard<std::mutex> lock(mutex_);
364    if (handle_ == nullptr) {
365        return INVALID_ARGUMENT;
366    }
367    return handle_->height;
368}
369
370int32_t SurfaceBufferImpl::GetStride() const
371{
372    std::lock_guard<std::mutex> lock(mutex_);
373    if (handle_ == nullptr) {
374        return INVALID_ARGUMENT;
375    }
376    return handle_->stride;
377}
378
379int32_t SurfaceBufferImpl::GetFormat() const
380{
381    std::lock_guard<std::mutex> lock(mutex_);
382    if (handle_ == nullptr) {
383        return INVALID_ARGUMENT;
384    }
385    return handle_->format;
386}
387
388uint64_t SurfaceBufferImpl::GetUsage() const
389{
390    std::lock_guard<std::mutex> lock(mutex_);
391    if (handle_ == nullptr) {
392        return INVALID_USAGE;
393    }
394    return handle_->usage;
395}
396
397uint64_t SurfaceBufferImpl::GetPhyAddr() const
398{
399    std::lock_guard<std::mutex> lock(mutex_);
400    if (handle_ == nullptr) {
401        return INVALID_PHYADDR;
402    }
403    return handle_->phyAddr;
404}
405
406void* SurfaceBufferImpl::GetVirAddr()
407{
408    GSError ret = this->Map();
409    if (ret != GSERROR_OK) {
410        return nullptr;
411    }
412    std::lock_guard<std::mutex> lock(mutex_);
413    if (handle_ == nullptr) {
414        return nullptr;
415    }
416    return handle_->virAddr;
417}
418
419int32_t SurfaceBufferImpl::GetFileDescriptor() const
420{
421    std::lock_guard<std::mutex> lock(mutex_);
422    if (handle_ == nullptr) {
423        return INVALID_ARGUMENT;
424    }
425    return handle_->fd;
426}
427
428uint32_t SurfaceBufferImpl::GetSize() const
429{
430    std::lock_guard<std::mutex> lock(mutex_);
431    if (handle_ == nullptr) {
432        return INVALID_SIZE;
433    }
434    return handle_->size;
435}
436
437GSError SurfaceBufferImpl::GetPlanesInfo(void** planesInfo)
438{
439    if (planesInfo == nullptr) {
440        return GSERROR_INVALID_ARGUMENTS;
441    }
442    OHOS::HDI::Display::Buffer::V1_2::ImageLayout layout;
443    GSError ret = GetImageLayout(&layout);
444    if (ret != GSERROR_OK) {
445        BLOGW("GetImageLayout failed, ret:%d, seq: %{public}u", ret, sequenceNumber_);
446        return ret;
447    }
448
449    std::lock_guard<std::mutex> lock(mutex_);
450    if (planesInfo_.planeCount != 0) {
451        *planesInfo = static_cast<void*>(&planesInfo_);
452        return GSERROR_OK;
453    }
454    planesInfo_.planeCount = layout.planes.size();
455    for (uint32_t i = 0; i < planesInfo_.planeCount && i < 4; i++) { // 4: max plane count
456        planesInfo_.planes[i].offset = layout.planes[i].offset;
457        planesInfo_.planes[i].rowStride = layout.planes[i].hStride;
458        planesInfo_.planes[i].columnStride = layout.planes[i].vStride;
459    }
460
461    *planesInfo = static_cast<void*>(&planesInfo_);
462    return GSERROR_OK;
463}
464
465void SurfaceBufferImpl::SetExtraData(sptr<BufferExtraData> bedata)
466{
467    std::lock_guard<std::mutex> lock(mutex_);
468    bedata_ = bedata;
469}
470
471sptr<BufferExtraData> SurfaceBufferImpl::GetExtraData() const
472{
473    std::lock_guard<std::mutex> lock(mutex_);
474    return bedata_;
475}
476
477void SurfaceBufferImpl::SetBufferHandle(BufferHandle* handle)
478{
479    if (handle == nullptr) {
480        return;
481    }
482    std::lock_guard<std::mutex> lock(mutex_);
483    if (handle_ == handle) {
484        return;
485    }
486    FreeBufferHandleLocked();
487
488    handle_ = handle;
489    IDisplayBufferSptr displayBuffer = GetDisplayBuffer();
490    if (displayBuffer == nullptr) {
491        return;
492    }
493    auto dRet = displayBuffer->RegisterBuffer(*handle_);
494    if (dRet != GRAPHIC_DISPLAY_SUCCESS && dRet != GRAPHIC_DISPLAY_NOT_SUPPORT) {
495        BLOGE("SetBufferHandle RegisterBuffer Failed with %{public}d", dRet);
496        return;
497    }
498}
499
500GSError SurfaceBufferImpl::WriteBufferRequestConfig(MessageParcel& parcel)
501{
502    std::lock_guard<std::mutex> lock(mutex_);
503    if (!parcel.WriteInt32(bufferRequestConfig_.width) || !parcel.WriteInt32(bufferRequestConfig_.height) ||
504        !parcel.WriteInt32(bufferRequestConfig_.strideAlignment) || !parcel.WriteInt32(bufferRequestConfig_.format) ||
505        !parcel.WriteUint64(bufferRequestConfig_.usage) || !parcel.WriteInt32(bufferRequestConfig_.timeout) ||
506        !parcel.WriteUint32(static_cast<uint32_t>(bufferRequestConfig_.colorGamut)) ||
507        !parcel.WriteUint32(static_cast<uint32_t>(bufferRequestConfig_.transform))) {
508        BLOGE("parcel write fail, seq: %{public}u.", sequenceNumber_);
509        return SURFACE_ERROR_UNKOWN;
510    }
511    return GSERROR_OK;
512}
513
514GSError SurfaceBufferImpl::WriteToMessageParcel(MessageParcel& parcel)
515{
516    std::lock_guard<std::mutex> lock(mutex_);
517    if (handle_ == nullptr) {
518        return GSERROR_NOT_INIT;
519    }
520    bool ret = WriteBufferHandle(parcel, *handle_);
521    if (ret == false) {
522        return GSERROR_API_FAILED;
523    }
524
525    return GSERROR_OK;
526}
527
528GSError SurfaceBufferImpl::ReadBufferRequestConfig(MessageParcel& parcel)
529{
530    std::lock_guard<std::mutex> lock(mutex_);
531    uint32_t colorGamut = 0;
532    uint32_t transform = 0;
533    if (!parcel.ReadInt32(bufferRequestConfig_.width) || !parcel.ReadInt32(bufferRequestConfig_.height) ||
534        !parcel.ReadInt32(bufferRequestConfig_.strideAlignment) || !parcel.ReadInt32(bufferRequestConfig_.format) ||
535        !parcel.ReadUint64(bufferRequestConfig_.usage) || !parcel.ReadInt32(bufferRequestConfig_.timeout) ||
536        !parcel.ReadUint32(colorGamut) || !parcel.ReadUint32(transform)) {
537        BLOGE("parcel read fail, seq: %{public}u.", sequenceNumber_);
538        return GSERROR_API_FAILED;
539    }
540    bufferRequestConfig_.colorGamut = static_cast<GraphicColorGamut>(colorGamut);
541    bufferRequestConfig_.transform = static_cast<GraphicTransformType>(transform);
542    return GSERROR_OK;
543}
544
545GSError SurfaceBufferImpl::ReadFromMessageParcel(MessageParcel& parcel)
546{
547    auto handle = ReadBufferHandle(parcel);
548    SetBufferHandle(handle);
549    return handle ? GSERROR_OK : GSERROR_API_FAILED;
550}
551
552// return OH_NativeBuffer* is dangerous, need to refactor
553OH_NativeBuffer* SurfaceBufferImpl::SurfaceBufferToNativeBuffer()
554{
555    return reinterpret_cast<OH_NativeBuffer *>(this);
556}
557
558uint32_t SurfaceBufferImpl::GetSeqNum() const
559{
560    return sequenceNumber_;
561}
562
563GSError SurfaceBufferImpl::CheckBufferConfig(int32_t width, int32_t height,
564                                             int32_t format, uint64_t usage)
565{
566    if (width <= 0 || height <= 0) {
567        BLOGE("width %{public}d height %{public}d", width, height);
568        return GSERROR_INVALID_ARGUMENTS;
569    }
570
571    if (format < 0 || format > GRAPHIC_PIXEL_FMT_BUTT) {
572        BLOGE("format is %{public}d", format);
573        return GSERROR_INVALID_ARGUMENTS;
574    }
575
576    return GSERROR_OK;
577}
578
579BufferWrapper SurfaceBufferImpl::GetBufferWrapper()
580{
581    return {};
582}
583
584void SurfaceBufferImpl::SetBufferWrapper(BufferWrapper wrapper) {}
585
586GSError SurfaceBufferImpl::SetMetadata(uint32_t key, const std::vector<uint8_t>& value)
587{
588    if (key == 0 || key >= HDI::Display::Graphic::Common::V1_1::ATTRKEY_END) {
589        return GSERROR_INVALID_ARGUMENTS;
590    }
591    IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer();
592    if (displayBuffer == nullptr) {
593        return GSERROR_INTERNAL;
594    }
595
596    std::lock_guard<std::mutex> lock(mutex_);
597    if (handle_ == nullptr) {
598        return GSERROR_NOT_INIT;
599    }
600
601    if (MetaDataCachedLocked(key, value)) {
602        return GSERROR_OK;
603    }
604
605    auto dRet = displayBuffer->SetMetadata(*handle_, key, value);
606    if (dRet == GRAPHIC_DISPLAY_SUCCESS) {
607        // cache metaData
608        metaDataCache_[key] = value;
609        return GSERROR_OK;
610    }
611    BLOGE("SetMetadata Failed with %{public}d", dRet);
612    return GSERROR_HDI_ERROR;
613}
614
615GSError SurfaceBufferImpl::GetMetadata(uint32_t key, std::vector<uint8_t>& value)
616{
617    if (key == 0 || key >= HDI::Display::Graphic::Common::V1_1::ATTRKEY_END) {
618        return GSERROR_INVALID_ARGUMENTS;
619    }
620    IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer();
621    if (displayBuffer == nullptr) {
622        return GSERROR_INTERNAL;
623    }
624
625    std::lock_guard<std::mutex> lock(mutex_);
626    if (handle_ == nullptr) {
627        return GSERROR_NOT_INIT;
628    }
629    auto dRet = displayBuffer->GetMetadata(*handle_, key, value);
630    if (dRet == GRAPHIC_DISPLAY_SUCCESS) {
631        return GSERROR_OK;
632    }
633    BLOGD("GetMetadata Failed with %{public}d", dRet);
634    return GSERROR_HDI_ERROR;
635}
636
637GSError SurfaceBufferImpl::ListMetadataKeys(std::vector<uint32_t>& keys)
638{
639    IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer();
640    if (displayBuffer == nullptr) {
641        return GSERROR_INTERNAL;
642    }
643    keys.clear();
644    std::lock_guard<std::mutex> lock(mutex_);
645    if (handle_ == nullptr) {
646        return GSERROR_NOT_INIT;
647    }
648    auto dRet = displayBuffer->ListMetadataKeys(*handle_, keys);
649    if (dRet == GRAPHIC_DISPLAY_SUCCESS) {
650        return GSERROR_OK;
651    }
652    BLOGE("ListMetadataKeys Failed with %{public}d", dRet);
653    return GSERROR_HDI_ERROR;
654}
655
656GSError SurfaceBufferImpl::EraseMetadataKey(uint32_t key)
657{
658    if (key == 0 || key >= HDI::Display::Graphic::Common::V1_1::ATTRKEY_END) {
659        return GSERROR_INVALID_ARGUMENTS;
660    }
661    IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer();
662    if (displayBuffer == nullptr) {
663        return GSERROR_INTERNAL;
664    }
665
666    std::lock_guard<std::mutex> lock(mutex_);
667    if (handle_ == nullptr) {
668        return GSERROR_NOT_INIT;
669    }
670    auto dRet = displayBuffer->EraseMetadataKey(*handle_, key);
671    if (dRet == GRAPHIC_DISPLAY_SUCCESS) {
672        metaDataCache_.erase(key);
673        return GSERROR_OK;
674    }
675    BLOGE("EraseMetadataKey Failed with %{public}d", dRet);
676    return GSERROR_HDI_ERROR;
677}
678
679BufferRequestConfig SurfaceBufferImpl::GetBufferRequestConfig() const
680{
681    std::lock_guard<std::mutex> lock(mutex_);
682    return bufferRequestConfig_;
683}
684
685void SurfaceBufferImpl::SetBufferRequestConfig(const BufferRequestConfig& config)
686{
687    std::lock_guard<std::mutex> lock(mutex_);
688    bufferRequestConfig_ = config;
689}
690
691void SurfaceBufferImpl::SetConsumerAttachBufferFlag(bool value)
692{
693    std::lock_guard<std::mutex> lock(mutex_);
694    isConsumerAttachBufferFlag_ = value;
695}
696
697bool SurfaceBufferImpl::GetConsumerAttachBufferFlag()
698{
699    std::lock_guard<std::mutex> lock(mutex_);
700    return isConsumerAttachBufferFlag_;
701}
702} // namespace OHOS
703