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 BLOGE("parcel write fail, seq: %{public}u.", sequenceNumber_);
487 return SURFACE_ERROR_UNKOWN;
488 }
489 return GSERROR_OK;
490 }
491
WriteToMessageParcel(MessageParcel & parcel)492 GSError SurfaceBufferImpl::WriteToMessageParcel(MessageParcel &parcel)
493 {
494 std::lock_guard<std::mutex> lock(mutex_);
495 if (handle_ == nullptr) {
496 return GSERROR_NOT_INIT;
497 }
498 bool ret = WriteBufferHandle(parcel, *handle_);
499 if (ret == false) {
500 return GSERROR_API_FAILED;
501 }
502
503 return GSERROR_OK;
504 }
505
ReadBufferRequestConfig(MessageParcel & parcel)506 GSError SurfaceBufferImpl::ReadBufferRequestConfig(MessageParcel &parcel)
507 {
508 std::lock_guard<std::mutex> lock(mutex_);
509 uint32_t colorGamut = 0;
510 uint32_t transform = 0;
511 if (!parcel.ReadInt32(bufferRequestConfig_.width) || !parcel.ReadInt32(bufferRequestConfig_.height) ||
512 !parcel.ReadInt32(bufferRequestConfig_.strideAlignment) || !parcel.ReadInt32(bufferRequestConfig_.format) ||
513 !parcel.ReadUint64(bufferRequestConfig_.usage) || !parcel.ReadInt32(bufferRequestConfig_.timeout) ||
514 !parcel.ReadUint32(colorGamut) || !parcel.ReadUint32(transform)) {
515 BLOGE("parcel read fail, seq: %{public}u.", sequenceNumber_);
516 return GSERROR_API_FAILED;
517 }
518 bufferRequestConfig_.colorGamut = static_cast<GraphicColorGamut>(colorGamut);
519 bufferRequestConfig_.transform = static_cast<GraphicTransformType>(transform);
520 return GSERROR_OK;
521 }
522
ReadFromMessageParcel(MessageParcel & parcel)523 GSError SurfaceBufferImpl::ReadFromMessageParcel(MessageParcel &parcel)
524 {
525 auto handle = ReadBufferHandle(parcel);
526 SetBufferHandle(handle);
527 return handle ? GSERROR_OK : GSERROR_API_FAILED;
528 }
529
530 // return OH_NativeBuffer* is dangerous, need to refactor
SurfaceBufferToNativeBuffer()531 OH_NativeBuffer* SurfaceBufferImpl::SurfaceBufferToNativeBuffer()
532 {
533 return reinterpret_cast<OH_NativeBuffer *>(this);
534 }
535
GetSeqNum() const536 uint32_t SurfaceBufferImpl::GetSeqNum() const
537 {
538 return sequenceNumber_;
539 }
540
GetEglData() const541 sptr<EglData> SurfaceBufferImpl::GetEglData() const
542 {
543 return eglData_;
544 }
545
SetEglData(const sptr<EglData> & data)546 void SurfaceBufferImpl::SetEglData(const sptr<EglData>& data)
547 {
548 eglData_ = data;
549 }
550
CheckBufferConfig(int32_t width,int32_t height,int32_t format,uint64_t usage)551 GSError SurfaceBufferImpl::CheckBufferConfig(int32_t width, int32_t height,
552 int32_t format, uint64_t usage)
553 {
554 if (width <= 0 || height <= 0) {
555 BLOGE("width %{public}d height %{public}d", width, height);
556 return GSERROR_INVALID_ARGUMENTS;
557 }
558
559 if (format < 0 || format > GRAPHIC_PIXEL_FMT_BUTT) {
560 BLOGE("format is %{public}d", format);
561 return GSERROR_INVALID_ARGUMENTS;
562 }
563
564 return GSERROR_OK;
565 }
566
GetBufferWrapper()567 BufferWrapper SurfaceBufferImpl::GetBufferWrapper()
568 {
569 return {};
570 }
571
SetBufferWrapper(BufferWrapper wrapper)572 void SurfaceBufferImpl::SetBufferWrapper(BufferWrapper wrapper) {}
573
SetMetadata(uint32_t key,const std::vector<uint8_t> & value)574 GSError SurfaceBufferImpl::SetMetadata(uint32_t key, const std::vector<uint8_t>& value)
575 {
576 if (key == 0 || key >= HDI::Display::Graphic::Common::V1_1::ATTRKEY_END) {
577 return GSERROR_INVALID_ARGUMENTS;
578 }
579 IDisplayBufferSptr displayBuffer = GetDisplayBuffer();
580 if (displayBuffer == nullptr) {
581 return GSERROR_INTERNAL;
582 }
583
584 std::lock_guard<std::mutex> lock(mutex_);
585 if (handle_ == nullptr) {
586 return GSERROR_NOT_INIT;
587 }
588
589 if (MetaDataCachedLocked(key, value)) {
590 return GSERROR_OK;
591 }
592
593 auto dret = displayBuffer->SetMetadata(*handle_, key, value);
594 if (dret == GRAPHIC_DISPLAY_SUCCESS) {
595 // cache metaData
596 metaDataCache_[key] = value;
597 return GSERROR_OK;
598 }
599 BLOGE("SetMetadata Failed with %{public}d", dret);
600 return GSERROR_HDI_ERROR;
601 }
602
GetMetadata(uint32_t key,std::vector<uint8_t> & value)603 GSError SurfaceBufferImpl::GetMetadata(uint32_t key, std::vector<uint8_t>& value)
604 {
605 if (key == 0 || key >= HDI::Display::Graphic::Common::V1_1::ATTRKEY_END) {
606 return GSERROR_INVALID_ARGUMENTS;
607 }
608 IDisplayBufferSptr displayBuffer = GetDisplayBuffer();
609 if (displayBuffer == nullptr) {
610 return GSERROR_INTERNAL;
611 }
612
613 std::lock_guard<std::mutex> lock(mutex_);
614 if (handle_ == nullptr) {
615 return GSERROR_NOT_INIT;
616 }
617 auto dret = displayBuffer->GetMetadata(*handle_, key, value);
618 if (dret == GRAPHIC_DISPLAY_SUCCESS) {
619 return GSERROR_OK;
620 }
621 BLOGD("GetMetadata Failed with %{public}d", dret);
622 return GSERROR_HDI_ERROR;
623 }
624
ListMetadataKeys(std::vector<uint32_t> & keys)625 GSError SurfaceBufferImpl::ListMetadataKeys(std::vector<uint32_t>& keys)
626 {
627 IDisplayBufferSptr displayBuffer = GetDisplayBuffer();
628 if (displayBuffer == nullptr) {
629 return GSERROR_INTERNAL;
630 }
631
632 keys.clear();
633 std::lock_guard<std::mutex> lock(mutex_);
634 if (handle_ == nullptr) {
635 return GSERROR_NOT_INIT;
636 }
637 auto dret = displayBuffer->ListMetadataKeys(*handle_, keys);
638 if (dret == GRAPHIC_DISPLAY_SUCCESS) {
639 return GSERROR_OK;
640 }
641 BLOGE("ListMetadataKeys Failed with %{public}d", dret);
642 return GSERROR_HDI_ERROR;
643 }
644
EraseMetadataKey(uint32_t key)645 GSError SurfaceBufferImpl::EraseMetadataKey(uint32_t key)
646 {
647 if (key == 0 || key >= HDI::Display::Graphic::Common::V1_1::ATTRKEY_END) {
648 return GSERROR_INVALID_ARGUMENTS;
649 }
650 IDisplayBufferSptr displayBuffer = GetDisplayBuffer();
651 if (displayBuffer == nullptr) {
652 return GSERROR_INTERNAL;
653 }
654
655 std::lock_guard<std::mutex> lock(mutex_);
656 if (handle_ == nullptr) {
657 return GSERROR_NOT_INIT;
658 }
659 auto dret = displayBuffer->EraseMetadataKey(*handle_, key);
660 if (dret == GRAPHIC_DISPLAY_SUCCESS) {
661 metaDataCache_.erase(key);
662 return GSERROR_OK;
663 }
664 BLOGE("EraseMetadataKey Failed with %{public}d", dret);
665 return GSERROR_HDI_ERROR;
666 }
667
GetBufferRequestConfig() const668 BufferRequestConfig SurfaceBufferImpl::GetBufferRequestConfig() const
669 {
670 std::lock_guard<std::mutex> lock(mutex_);
671 return bufferRequestConfig_;
672 }
673
SetBufferRequestConfig(const BufferRequestConfig & config)674 void SurfaceBufferImpl::SetBufferRequestConfig(const BufferRequestConfig &config)
675 {
676 std::lock_guard<std::mutex> lock(mutex_);
677 bufferRequestConfig_ = config;
678 }
679
SetConsumerAttachBufferFlag(bool value)680 void SurfaceBufferImpl::SetConsumerAttachBufferFlag(bool value)
681 {
682 std::lock_guard<std::mutex> lock(mutex_);
683 isConsumerAttachBufferFlag_ = value;
684 }
685
GetConsumerAttachBufferFlag()686 bool SurfaceBufferImpl::GetConsumerAttachBufferFlag()
687 {
688 std::lock_guard<std::mutex> lock(mutex_);
689 return isConsumerAttachBufferFlag_;
690 }
691 } // namespace OHOS
692