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