• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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