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 };
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 return GSERROR_OK;
160 }
161 BLOGW("Alloc Failed with %{public}d, seq: %{public}u", dRet, sequenceNumber_);
162 return GSERROR_HDI_ERROR;
163 }
164
Map()165 GSError SurfaceBufferImpl::Map()
166 {
167 IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer();
168 if (displayBuffer == nullptr) {
169 return GSERROR_INTERNAL;
170 }
171 std::lock_guard<std::mutex> lock(mutex_);
172 if (handle_ == nullptr) {
173 return GSERROR_INVALID_OPERATING;
174 } else if (handle_->virAddr != nullptr) {
175 return GSERROR_OK;
176 }
177 if (handle_->usage & BUFFER_USAGE_PROTECTED) {
178 return GSERROR_OK;
179 }
180
181 void* virAddr = displayBuffer->Mmap(*handle_);
182 if (virAddr == nullptr || virAddr == MAP_FAILED) {
183 return GSERROR_HDI_ERROR;
184 }
185 return GSERROR_OK;
186 }
187
Unmap()188 GSError SurfaceBufferImpl::Unmap()
189 {
190 IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer();
191 if (displayBuffer == nullptr) {
192 return GSERROR_INTERNAL;
193 }
194 std::lock_guard<std::mutex> lock(mutex_);
195 if (handle_ == nullptr) {
196 return GSERROR_INVALID_OPERATING;
197 } else if (handle_->virAddr == nullptr) {
198 BLOGW("handle has been unmaped, seq: %{public}u", sequenceNumber_);
199 return GSERROR_OK;
200 }
201 auto dRet = displayBuffer->Unmap(*handle_);
202 if (dRet == GRAPHIC_DISPLAY_SUCCESS) {
203 handle_->virAddr = nullptr;
204 return GSERROR_OK;
205 }
206 BLOGW("Unmap Failed with %{public}d, seq: %{public}u", dRet, sequenceNumber_);
207 return GSERROR_HDI_ERROR;
208 }
209
FlushCache()210 GSError SurfaceBufferImpl::FlushCache()
211 {
212 IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer();
213 if (displayBuffer == nullptr) {
214 return GSERROR_INTERNAL;
215 }
216
217 std::lock_guard<std::mutex> lock(mutex_);
218 if (handle_ == nullptr) {
219 return GSERROR_INVALID_OPERATING;
220 }
221 auto dRet = displayBuffer->FlushCache(*handle_);
222 if (dRet == GRAPHIC_DISPLAY_SUCCESS) {
223 return GSERROR_OK;
224 }
225 BLOGW("FlushCache Failed with %{public}d, seq: %{public}u", dRet, sequenceNumber_);
226 return GSERROR_HDI_ERROR;
227 }
228
GetImageLayout(void * layout)229 GSError SurfaceBufferImpl::GetImageLayout(void* layout)
230 {
231 IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer();
232 if (displayBuffer == nullptr) {
233 return GSERROR_INTERNAL;
234 }
235 std::lock_guard<std::mutex> lock(mutex_);
236 if (handle_ == nullptr) {
237 return GSERROR_INVALID_OPERATING;
238 } else if (planesInfo_.planeCount != 0) {
239 return GSERROR_OK;
240 }
241
242 auto dRet = displayBuffer->GetImageLayout(*handle_,
243 *(static_cast<OHOS::HDI::Display::Buffer::V1_2::ImageLayout*>(layout)));
244 if (dRet == GRAPHIC_DISPLAY_SUCCESS) {
245 return GSERROR_OK;
246 }
247 BLOGW("GetImageLayout Failed with %{public}d, seq: %{public}u", dRet, sequenceNumber_);
248 return GSERROR_HDI_ERROR;
249 }
250
InvalidateCache()251 GSError SurfaceBufferImpl::InvalidateCache()
252 {
253 IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer();
254 if (displayBuffer == nullptr) {
255 return GSERROR_INTERNAL;
256 }
257 std::lock_guard<std::mutex> lock(mutex_);
258 if (handle_ == nullptr) {
259 return GSERROR_INVALID_OPERATING;
260 }
261
262 auto dRet = displayBuffer->InvalidateCache(*handle_);
263 if (dRet == GRAPHIC_DISPLAY_SUCCESS) {
264 return GSERROR_OK;
265 }
266 BLOGW("InvalidateCache Failed with %{public}d, seq: %{public}u", dRet, sequenceNumber_);
267 return GSERROR_HDI_ERROR;
268 }
269
FreeBufferHandleLocked()270 void SurfaceBufferImpl::FreeBufferHandleLocked()
271 {
272 metaDataCache_.clear();
273 if (handle_) {
274 IDisplayBufferSptr displayBuffer = GetDisplayBuffer();
275 if (displayBuffer == nullptr) {
276 FreeBufferHandle(handle_);
277 handle_ = nullptr;
278 return;
279 }
280 if (handle_->virAddr != nullptr) {
281 displayBuffer->Unmap(*handle_);
282 handle_->virAddr = nullptr;
283 }
284 displayBuffer->FreeMem(*handle_);
285 handle_ = nullptr;
286 }
287 }
288
289 // return BufferHandle* is dangerous, need to refactor
GetBufferHandle() const290 BufferHandle* SurfaceBufferImpl::GetBufferHandle() const
291 {
292 std::lock_guard<std::mutex> lock(mutex_);
293 return handle_;
294 }
295
SetSurfaceBufferColorGamut(const GraphicColorGamut & colorGamut)296 void SurfaceBufferImpl::SetSurfaceBufferColorGamut(const GraphicColorGamut& colorGamut)
297 {
298 std::lock_guard<std::mutex> lock(mutex_);
299 if (surfaceBufferColorGamut_ != colorGamut) {
300 surfaceBufferColorGamut_ = colorGamut;
301 }
302 }
303
GetSurfaceBufferColorGamut() const304 GraphicColorGamut SurfaceBufferImpl::GetSurfaceBufferColorGamut() const
305 {
306 std::lock_guard<std::mutex> lock(mutex_);
307 return surfaceBufferColorGamut_;
308 }
309
SetSurfaceBufferTransform(const GraphicTransformType & transform)310 void SurfaceBufferImpl::SetSurfaceBufferTransform(const GraphicTransformType& transform)
311 {
312 std::lock_guard<std::mutex> lock(mutex_);
313 if (transform_ != transform) {
314 transform_ = transform;
315 }
316 }
317
GetSurfaceBufferTransform() const318 GraphicTransformType SurfaceBufferImpl::GetSurfaceBufferTransform() const
319 {
320 std::lock_guard<std::mutex> lock(mutex_);
321 return transform_;
322 }
323
GetSurfaceBufferWidth() const324 int32_t SurfaceBufferImpl::GetSurfaceBufferWidth() const
325 {
326 std::lock_guard<std::mutex> lock(mutex_);
327 return surfaceBufferWidth_;
328 }
329
GetSurfaceBufferHeight() const330 int32_t SurfaceBufferImpl::GetSurfaceBufferHeight() const
331 {
332 std::lock_guard<std::mutex> lock(mutex_);
333 return surfaceBufferHeight_;
334 }
335
SetSurfaceBufferWidth(int32_t width)336 void SurfaceBufferImpl::SetSurfaceBufferWidth(int32_t width)
337 {
338 std::lock_guard<std::mutex> lock(mutex_);
339 surfaceBufferWidth_ = width;
340 }
341
SetSurfaceBufferHeight(int32_t height)342 void SurfaceBufferImpl::SetSurfaceBufferHeight(int32_t height)
343 {
344 std::lock_guard<std::mutex> lock(mutex_);
345 surfaceBufferHeight_ = height;
346 }
347
GetWidth() const348 int32_t SurfaceBufferImpl::GetWidth() const
349 {
350 std::lock_guard<std::mutex> lock(mutex_);
351 if (handle_ == nullptr) {
352 return INVALID_ARGUMENT;
353 }
354 return handle_->width;
355 }
356
GetHeight() const357 int32_t SurfaceBufferImpl::GetHeight() const
358 {
359 std::lock_guard<std::mutex> lock(mutex_);
360 if (handle_ == nullptr) {
361 return INVALID_ARGUMENT;
362 }
363 return handle_->height;
364 }
365
GetStride() const366 int32_t SurfaceBufferImpl::GetStride() const
367 {
368 std::lock_guard<std::mutex> lock(mutex_);
369 if (handle_ == nullptr) {
370 return INVALID_ARGUMENT;
371 }
372 return handle_->stride;
373 }
374
GetFormat() const375 int32_t SurfaceBufferImpl::GetFormat() const
376 {
377 std::lock_guard<std::mutex> lock(mutex_);
378 if (handle_ == nullptr) {
379 return INVALID_ARGUMENT;
380 }
381 return handle_->format;
382 }
383
GetUsage() const384 uint64_t SurfaceBufferImpl::GetUsage() const
385 {
386 std::lock_guard<std::mutex> lock(mutex_);
387 if (handle_ == nullptr) {
388 return INVALID_USAGE;
389 }
390 return handle_->usage;
391 }
392
GetPhyAddr() const393 uint64_t SurfaceBufferImpl::GetPhyAddr() const
394 {
395 std::lock_guard<std::mutex> lock(mutex_);
396 if (handle_ == nullptr) {
397 return INVALID_PHYADDR;
398 }
399 return handle_->phyAddr;
400 }
401
GetVirAddr()402 void* SurfaceBufferImpl::GetVirAddr()
403 {
404 GSError ret = this->Map();
405 if (ret != GSERROR_OK) {
406 return nullptr;
407 }
408 std::lock_guard<std::mutex> lock(mutex_);
409 if (handle_ == nullptr) {
410 return nullptr;
411 }
412 return handle_->virAddr;
413 }
414
GetFileDescriptor() const415 int32_t SurfaceBufferImpl::GetFileDescriptor() const
416 {
417 std::lock_guard<std::mutex> lock(mutex_);
418 if (handle_ == nullptr) {
419 return INVALID_ARGUMENT;
420 }
421 return handle_->fd;
422 }
423
GetSize() const424 uint32_t SurfaceBufferImpl::GetSize() const
425 {
426 std::lock_guard<std::mutex> lock(mutex_);
427 if (handle_ == nullptr) {
428 return INVALID_SIZE;
429 }
430 return handle_->size;
431 }
432
GetPlanesInfo(void ** planesInfo)433 GSError SurfaceBufferImpl::GetPlanesInfo(void** planesInfo)
434 {
435 if (planesInfo == nullptr) {
436 return GSERROR_INVALID_ARGUMENTS;
437 }
438 OHOS::HDI::Display::Buffer::V1_2::ImageLayout layout;
439 GSError ret = GetImageLayout(&layout);
440 if (ret != GSERROR_OK) {
441 BLOGW("GetImageLayout failed, ret:%d, seq: %{public}u", ret, sequenceNumber_);
442 return ret;
443 }
444
445 std::lock_guard<std::mutex> lock(mutex_);
446 if (planesInfo_.planeCount != 0) {
447 *planesInfo = static_cast<void*>(&planesInfo_);
448 return GSERROR_OK;
449 }
450 planesInfo_.planeCount = layout.planes.size();
451 for (uint32_t i = 0; i < planesInfo_.planeCount && i < 4; i++) { // 4: max plane count
452 planesInfo_.planes[i].offset = layout.planes[i].offset;
453 planesInfo_.planes[i].rowStride = layout.planes[i].hStride;
454 planesInfo_.planes[i].columnStride = layout.planes[i].vStride;
455 }
456
457 *planesInfo = static_cast<void*>(&planesInfo_);
458 return GSERROR_OK;
459 }
460
SetExtraData(sptr<BufferExtraData> bedata)461 void SurfaceBufferImpl::SetExtraData(sptr<BufferExtraData> bedata)
462 {
463 std::lock_guard<std::mutex> lock(mutex_);
464 bedata_ = bedata;
465 }
466
GetExtraData() const467 sptr<BufferExtraData> SurfaceBufferImpl::GetExtraData() const
468 {
469 std::lock_guard<std::mutex> lock(mutex_);
470 return bedata_;
471 }
472
SetBufferHandle(BufferHandle * handle)473 void SurfaceBufferImpl::SetBufferHandle(BufferHandle* handle)
474 {
475 if (handle == nullptr) {
476 return;
477 }
478 std::lock_guard<std::mutex> lock(mutex_);
479 if (handle_ == handle) {
480 return;
481 }
482 FreeBufferHandleLocked();
483
484 handle_ = handle;
485 IDisplayBufferSptr displayBuffer = GetDisplayBuffer();
486 if (displayBuffer == nullptr) {
487 return;
488 }
489 auto dRet = displayBuffer->RegisterBuffer(*handle_);
490 if (dRet != GRAPHIC_DISPLAY_SUCCESS && dRet != GRAPHIC_DISPLAY_NOT_SUPPORT) {
491 BLOGE("SetBufferHandle RegisterBuffer Failed with %{public}d", dRet);
492 return;
493 }
494 }
495
WriteBufferRequestConfig(MessageParcel & parcel)496 GSError SurfaceBufferImpl::WriteBufferRequestConfig(MessageParcel& parcel)
497 {
498 std::lock_guard<std::mutex> lock(mutex_);
499 if (!parcel.WriteInt32(bufferRequestConfig_.width) || !parcel.WriteInt32(bufferRequestConfig_.height) ||
500 !parcel.WriteInt32(bufferRequestConfig_.strideAlignment) || !parcel.WriteInt32(bufferRequestConfig_.format) ||
501 !parcel.WriteUint64(bufferRequestConfig_.usage) || !parcel.WriteInt32(bufferRequestConfig_.timeout) ||
502 !parcel.WriteUint32(static_cast<uint32_t>(bufferRequestConfig_.colorGamut)) ||
503 !parcel.WriteUint32(static_cast<uint32_t>(bufferRequestConfig_.transform)) ||
504 !parcel.WriteInt32(scalingMode_)) {
505 BLOGE("parcel write fail, seq: %{public}u.", sequenceNumber_);
506 return SURFACE_ERROR_UNKOWN;
507 }
508 return GSERROR_OK;
509 }
510
WriteToMessageParcel(MessageParcel & parcel)511 GSError SurfaceBufferImpl::WriteToMessageParcel(MessageParcel& parcel)
512 {
513 std::lock_guard<std::mutex> lock(mutex_);
514 if (handle_ == nullptr) {
515 return GSERROR_NOT_INIT;
516 }
517 bool ret = WriteBufferHandle(parcel, *handle_);
518 if (ret == false) {
519 return GSERROR_API_FAILED;
520 }
521
522 return GSERROR_OK;
523 }
524
ReadBufferRequestConfig(MessageParcel & parcel)525 GSError SurfaceBufferImpl::ReadBufferRequestConfig(MessageParcel& parcel)
526 {
527 std::lock_guard<std::mutex> lock(mutex_);
528 uint32_t colorGamut = 0;
529 uint32_t transform = 0;
530 int32_t scalingMode = {};
531 if (!parcel.ReadInt32(bufferRequestConfig_.width) || !parcel.ReadInt32(bufferRequestConfig_.height) ||
532 !parcel.ReadInt32(bufferRequestConfig_.strideAlignment) || !parcel.ReadInt32(bufferRequestConfig_.format) ||
533 !parcel.ReadUint64(bufferRequestConfig_.usage) || !parcel.ReadInt32(bufferRequestConfig_.timeout) ||
534 !parcel.ReadUint32(colorGamut) || !parcel.ReadUint32(transform) || !parcel.ReadInt32(scalingMode)) {
535 BLOGE("parcel read fail, seq: %{public}u.", sequenceNumber_);
536 return GSERROR_API_FAILED;
537 }
538 surfaceBufferColorGamut_ = static_cast<GraphicColorGamut>(colorGamut);
539 transform_ = static_cast<GraphicTransformType>(transform);
540 surfaceBufferWidth_ = bufferRequestConfig_.width;
541 surfaceBufferHeight_ = bufferRequestConfig_.height;
542 scalingMode_ = static_cast<ScalingMode>(scalingMode);
543 bufferRequestConfig_.colorGamut = static_cast<GraphicColorGamut>(colorGamut);
544 bufferRequestConfig_.transform = static_cast<GraphicTransformType>(transform);
545 return GSERROR_OK;
546 }
547
ReadFromMessageParcel(MessageParcel & parcel,std::function<int (MessageParcel & parcel,std::function<int (Parcel &)> readFdDefaultFunc)> readSafeFdFunc)548 GSError SurfaceBufferImpl::ReadFromMessageParcel(MessageParcel &parcel,
549 std::function<int(MessageParcel &parcel, std::function<int(Parcel &)>readFdDefaultFunc)>readSafeFdFunc)
550 {
551 auto handle = ReadBufferHandle(parcel, readSafeFdFunc);
552 SetBufferHandle(handle);
553 return handle ? GSERROR_OK : GSERROR_API_FAILED;
554 }
555
556 // return OH_NativeBuffer* is dangerous, need to refactor
SurfaceBufferToNativeBuffer()557 OH_NativeBuffer* SurfaceBufferImpl::SurfaceBufferToNativeBuffer()
558 {
559 return reinterpret_cast<OH_NativeBuffer *>(this);
560 }
561
GetSeqNum() const562 uint32_t SurfaceBufferImpl::GetSeqNum() const
563 {
564 return sequenceNumber_;
565 }
566
CheckBufferConfig(int32_t width,int32_t height,int32_t format,uint64_t usage)567 GSError SurfaceBufferImpl::CheckBufferConfig(int32_t width, int32_t height,
568 int32_t format, uint64_t usage)
569 {
570 if (width <= 0 || height <= 0) {
571 BLOGE("width %{public}d height %{public}d", width, height);
572 return GSERROR_INVALID_ARGUMENTS;
573 }
574
575 if (format < 0 || format > GRAPHIC_PIXEL_FMT_BUTT) {
576 BLOGE("format is %{public}d", format);
577 return GSERROR_INVALID_ARGUMENTS;
578 }
579
580 return GSERROR_OK;
581 }
582
SetMetadata(uint32_t key,const std::vector<uint8_t> & value,bool enableCache)583 GSError SurfaceBufferImpl::SetMetadata(uint32_t key, const std::vector<uint8_t>& value, bool enableCache)
584 {
585 if (key == 0 || key >= HDI::Display::Graphic::Common::V1_1::ATTRKEY_END) {
586 return GSERROR_INVALID_ARGUMENTS;
587 }
588 IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer();
589 if (displayBuffer == nullptr) {
590 return GSERROR_INTERNAL;
591 }
592
593 std::lock_guard<std::mutex> lock(mutex_);
594 if (handle_ == nullptr) {
595 return GSERROR_NOT_INIT;
596 }
597
598 if (enableCache && MetaDataCachedLocked(key, value)) {
599 return GSERROR_OK;
600 }
601
602 auto dRet = displayBuffer->SetMetadata(*handle_, key, value);
603 if (dRet == GRAPHIC_DISPLAY_SUCCESS) {
604 // cache metaData
605 if (enableCache) {
606 metaDataCache_[key] = value;
607 }
608 return GSERROR_OK;
609 }
610 BLOGE("SetMetadata Failed with %{public}d", dRet);
611 return GSERROR_HDI_ERROR;
612 }
613
GetMetadata(uint32_t key,std::vector<uint8_t> & value)614 GSError SurfaceBufferImpl::GetMetadata(uint32_t key, std::vector<uint8_t>& value)
615 {
616 if (key == 0 || key >= HDI::Display::Graphic::Common::V1_1::ATTRKEY_END) {
617 return GSERROR_INVALID_ARGUMENTS;
618 }
619 IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer();
620 if (displayBuffer == nullptr) {
621 return GSERROR_INTERNAL;
622 }
623
624 std::lock_guard<std::mutex> lock(mutex_);
625 if (handle_ == nullptr) {
626 return GSERROR_NOT_INIT;
627 }
628 auto dRet = displayBuffer->GetMetadata(*handle_, key, value);
629 if (dRet == GRAPHIC_DISPLAY_SUCCESS) {
630 return GSERROR_OK;
631 }
632 return GSERROR_HDI_ERROR;
633 }
634
ListMetadataKeys(std::vector<uint32_t> & keys)635 GSError SurfaceBufferImpl::ListMetadataKeys(std::vector<uint32_t>& keys)
636 {
637 IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer();
638 if (displayBuffer == nullptr) {
639 return GSERROR_INTERNAL;
640 }
641 keys.clear();
642 std::lock_guard<std::mutex> lock(mutex_);
643 if (handle_ == nullptr) {
644 return GSERROR_NOT_INIT;
645 }
646 auto dRet = displayBuffer->ListMetadataKeys(*handle_, keys);
647 if (dRet == GRAPHIC_DISPLAY_SUCCESS) {
648 return GSERROR_OK;
649 }
650 BLOGE("ListMetadataKeys Failed with %{public}d", dRet);
651 return GSERROR_HDI_ERROR;
652 }
653
EraseMetadataKey(uint32_t key)654 GSError SurfaceBufferImpl::EraseMetadataKey(uint32_t key)
655 {
656 if (key == 0 || key >= HDI::Display::Graphic::Common::V1_1::ATTRKEY_END) {
657 return GSERROR_INVALID_ARGUMENTS;
658 }
659 IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer();
660 if (displayBuffer == nullptr) {
661 return GSERROR_INTERNAL;
662 }
663
664 std::lock_guard<std::mutex> lock(mutex_);
665 if (handle_ == nullptr) {
666 return GSERROR_NOT_INIT;
667 }
668 auto dRet = displayBuffer->EraseMetadataKey(*handle_, key);
669 if (dRet == GRAPHIC_DISPLAY_SUCCESS) {
670 metaDataCache_.erase(key);
671 return GSERROR_OK;
672 }
673 BLOGE("EraseMetadataKey Failed with %{public}d", dRet);
674 return GSERROR_HDI_ERROR;
675 }
676
SetCropMetadata(const Rect & crop)677 void SurfaceBufferImpl::SetCropMetadata(const Rect& crop)
678 {
679 std::lock_guard<std::mutex> lock(mutex_);
680 crop_ = crop;
681 }
682
GetCropMetadata(Rect & crop)683 bool SurfaceBufferImpl::GetCropMetadata(Rect& crop)
684 {
685 std::lock_guard<std::mutex> lock(mutex_);
686 if (crop_.w <= 0 || crop_.h <= 0) {
687 return false;
688 }
689 crop = crop_;
690 return true;
691 }
692
GetBufferRequestConfig() const693 BufferRequestConfig SurfaceBufferImpl::GetBufferRequestConfig() const
694 {
695 std::lock_guard<std::mutex> lock(mutex_);
696 return bufferRequestConfig_;
697 }
698
SetBufferRequestConfig(const BufferRequestConfig & config)699 void SurfaceBufferImpl::SetBufferRequestConfig(const BufferRequestConfig& config)
700 {
701 std::lock_guard<std::mutex> lock(mutex_);
702 bufferRequestConfig_ = config;
703 }
704
SetConsumerAttachBufferFlag(bool value)705 void SurfaceBufferImpl::SetConsumerAttachBufferFlag(bool value)
706 {
707 std::lock_guard<std::mutex> lock(mutex_);
708 isConsumerAttachBufferFlag_ = value;
709 }
710
GetConsumerAttachBufferFlag()711 bool SurfaceBufferImpl::GetConsumerAttachBufferFlag()
712 {
713 std::lock_guard<std::mutex> lock(mutex_);
714 return isConsumerAttachBufferFlag_;
715 }
716
SetSurfaceBufferScalingMode(const ScalingMode & scalingMode)717 void SurfaceBufferImpl::SetSurfaceBufferScalingMode(const ScalingMode &scalingMode)
718 {
719 std::lock_guard<std::mutex> lock(mutex_);
720 scalingMode_ = scalingMode;
721 }
722
GetSurfaceBufferScalingMode() const723 ScalingMode SurfaceBufferImpl::GetSurfaceBufferScalingMode() const
724 {
725 std::lock_guard<std::mutex> lock(mutex_);
726 return scalingMode_;
727 }
728
SetBufferDeleteFromCacheFlag(const bool & flag)729 void SurfaceBufferImpl::SetBufferDeleteFromCacheFlag(const bool &flag)
730 {
731 isBufferDeleteFromCache = flag;
732 }
733
GetBufferDeleteFromCacheFlag() const734 bool SurfaceBufferImpl::GetBufferDeleteFromCacheFlag() const
735 {
736 return isBufferDeleteFromCache;
737 }
738
739 } // namespace OHOS
740