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