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;
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 
GetDisplayBuffer()47 IDisplayBufferSptr 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 
GetOrResetDisplayBuffer()56 IDisplayBufferSptr 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 
73 constexpr int32_t INVALID_ARGUMENT = -1;
74 constexpr uint64_t INVALID_PHYADDR = 0;
75 constexpr uint32_t INVALID_SIZE = 0;
76 constexpr uint64_t INVALID_USAGE = std::numeric_limits<std::uint64_t>::max();
77 }
78 
Create()79 sptr<SurfaceBuffer> SurfaceBuffer::Create()
80 {
81     sptr<SurfaceBuffer> surfaceBufferImpl = new SurfaceBufferImpl();
82     return surfaceBufferImpl;
83 }
84 
SurfaceBufferImpl()85 SurfaceBufferImpl::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 
SurfaceBufferImpl(uint32_t seqNum)104 SurfaceBufferImpl::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 
~SurfaceBufferImpl()112 SurfaceBufferImpl::~SurfaceBufferImpl()
113 {
114     BLOGD("~SurfaceBufferImpl dtor, seq: %{public}u", sequenceNumber_);
115     FreeBufferHandleLocked();
116 }
117 
MetaDataCachedLocked(const uint32_t key, const std::vector<uint8_t>& value)118 bool 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 
Alloc(const BufferRequestConfig& config)127 GSError 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 
Map()167 GSError 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 
Unmap()192 GSError 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 
FlushCache()214 GSError 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 
GetImageLayout(void* layout)233 GSError 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 
InvalidateCache()255 GSError 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 
FreeBufferHandleLocked()274 void 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
GetBufferHandle() const294 BufferHandle* SurfaceBufferImpl::GetBufferHandle() const
295 {
296     std::lock_guard<std::mutex> lock(mutex_);
297     return handle_;
298 }
299 
SetSurfaceBufferColorGamut(const GraphicColorGamut& colorGamut)300 void SurfaceBufferImpl::SetSurfaceBufferColorGamut(const GraphicColorGamut& colorGamut)
301 {
302     std::lock_guard<std::mutex> lock(mutex_);
303     if (surfaceBufferColorGamut_ != colorGamut) {
304         surfaceBufferColorGamut_ = colorGamut;
305     }
306 }
307 
GetSurfaceBufferColorGamut() const308 GraphicColorGamut SurfaceBufferImpl::GetSurfaceBufferColorGamut() const
309 {
310     std::lock_guard<std::mutex> lock(mutex_);
311     return surfaceBufferColorGamut_;
312 }
313 
SetSurfaceBufferTransform(const GraphicTransformType& transform)314 void SurfaceBufferImpl::SetSurfaceBufferTransform(const GraphicTransformType& transform)
315 {
316     std::lock_guard<std::mutex> lock(mutex_);
317     if (transform_ != transform) {
318         transform_ = transform;
319     }
320 }
321 
GetSurfaceBufferTransform() const322 GraphicTransformType SurfaceBufferImpl::GetSurfaceBufferTransform() const
323 {
324     std::lock_guard<std::mutex> lock(mutex_);
325     return transform_;
326 }
327 
GetSurfaceBufferWidth() const328 int32_t SurfaceBufferImpl::GetSurfaceBufferWidth() const
329 {
330     std::lock_guard<std::mutex> lock(mutex_);
331     return surfaceBufferWidth_;
332 }
333 
GetSurfaceBufferHeight() const334 int32_t SurfaceBufferImpl::GetSurfaceBufferHeight() const
335 {
336     std::lock_guard<std::mutex> lock(mutex_);
337     return surfaceBufferHeight_;
338 }
339 
SetSurfaceBufferWidth(int32_t width)340 void SurfaceBufferImpl::SetSurfaceBufferWidth(int32_t width)
341 {
342     std::lock_guard<std::mutex> lock(mutex_);
343     surfaceBufferWidth_ = width;
344 }
345 
SetSurfaceBufferHeight(int32_t height)346 void SurfaceBufferImpl::SetSurfaceBufferHeight(int32_t height)
347 {
348     std::lock_guard<std::mutex> lock(mutex_);
349     surfaceBufferHeight_ = height;
350 }
351 
GetWidth() const352 int32_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 
GetHeight() const361 int32_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 
GetStride() const370 int32_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 
GetFormat() const379 int32_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 
GetUsage() const388 uint64_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 
GetPhyAddr() const397 uint64_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 
GetVirAddr()406 void* 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 
GetFileDescriptor() const419 int32_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 
GetSize() const428 uint32_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 
GetPlanesInfo(void** planesInfo)437 GSError 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 
SetExtraData(sptr<BufferExtraData> bedata)465 void SurfaceBufferImpl::SetExtraData(sptr<BufferExtraData> bedata)
466 {
467     std::lock_guard<std::mutex> lock(mutex_);
468     bedata_ = bedata;
469 }
470 
GetExtraData() const471 sptr<BufferExtraData> SurfaceBufferImpl::GetExtraData() const
472 {
473     std::lock_guard<std::mutex> lock(mutex_);
474     return bedata_;
475 }
476 
SetBufferHandle(BufferHandle* handle)477 void 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 
WriteBufferRequestConfig(MessageParcel& parcel)500 GSError 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 
WriteToMessageParcel(MessageParcel& parcel)514 GSError 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 
ReadBufferRequestConfig(MessageParcel& parcel)528 GSError 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 
ReadFromMessageParcel(MessageParcel& parcel)545 GSError 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
SurfaceBufferToNativeBuffer()553 OH_NativeBuffer* SurfaceBufferImpl::SurfaceBufferToNativeBuffer()
554 {
555     return reinterpret_cast<OH_NativeBuffer *>(this);
556 }
557 
GetSeqNum() const558 uint32_t SurfaceBufferImpl::GetSeqNum() const
559 {
560     return sequenceNumber_;
561 }
562 
CheckBufferConfig(int32_t width, int32_t height, int32_t format, uint64_t usage)563 GSError 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 
GetBufferWrapper()579 BufferWrapper SurfaceBufferImpl::GetBufferWrapper()
580 {
581     return {};
582 }
583 
SetBufferWrapper(BufferWrapper wrapper)584 void SurfaceBufferImpl::SetBufferWrapper(BufferWrapper wrapper) {}
585 
SetMetadata(uint32_t key, const std::vector<uint8_t>& value)586 GSError 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 
GetMetadata(uint32_t key, std::vector<uint8_t>& value)615 GSError 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 
ListMetadataKeys(std::vector<uint32_t>& keys)637 GSError 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 
EraseMetadataKey(uint32_t key)656 GSError 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 
GetBufferRequestConfig() const679 BufferRequestConfig SurfaceBufferImpl::GetBufferRequestConfig() const
680 {
681     std::lock_guard<std::mutex> lock(mutex_);
682     return bufferRequestConfig_;
683 }
684 
SetBufferRequestConfig(const BufferRequestConfig& config)685 void SurfaceBufferImpl::SetBufferRequestConfig(const BufferRequestConfig& config)
686 {
687     std::lock_guard<std::mutex> lock(mutex_);
688     bufferRequestConfig_ = config;
689 }
690 
SetConsumerAttachBufferFlag(bool value)691 void SurfaceBufferImpl::SetConsumerAttachBufferFlag(bool value)
692 {
693     std::lock_guard<std::mutex> lock(mutex_);
694     isConsumerAttachBufferFlag_ = value;
695 }
696 
GetConsumerAttachBufferFlag()697 bool SurfaceBufferImpl::GetConsumerAttachBufferFlag()
698 {
699     std::lock_guard<std::mutex> lock(mutex_);
700     return isConsumerAttachBufferFlag_;
701 }
702 } // namespace OHOS
703