• 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 <dlfcn.h>
19 #include <mutex>
20 
21 #include <message_parcel.h>
22 #include <parameters.h>
23 #include <securec.h>
24 #include <sys/mman.h>
25 #include "buffer_log.h"
26 #include "buffer_extra_data_impl.h"
27 #include "surface_trace.h"
28 #include "v1_1/buffer_handle_meta_key_type.h"
29 #include "v1_2/display_buffer_type.h"
30 #include "v1_3/include/idisplay_buffer.h"
31 
32 namespace OHOS {
33 namespace {
34 using IDisplayBufferSptr = std::shared_ptr<OHOS::HDI::Display::Buffer::V1_3::IDisplayBuffer>;
35 static IDisplayBufferSptr g_displayBuffer;
36 static std::mutex g_displayBufferMutex;
37 static std::mutex g_seqNumMutex;
38 static constexpr uint32_t MAX_SEQUENCE_NUM = 0xFFFF;
39 static std::bitset<MAX_SEQUENCE_NUM> g_seqBitset(0);
40 class DisplayBufferDiedRecipient : public OHOS::IRemoteObject::DeathRecipient {
41 public:
42     DisplayBufferDiedRecipient() = default;
43     virtual ~DisplayBufferDiedRecipient() = default;
OnRemoteDied(const OHOS::wptr<OHOS::IRemoteObject> & remote)44     void OnRemoteDied(const OHOS::wptr<OHOS::IRemoteObject>& remote) override
45     {
46         std::lock_guard<std::mutex> bufferLock(g_displayBufferMutex);
47         g_displayBuffer = nullptr;
48         BLOGD("IDisplayBuffer died and g_displayBuffer is nullptr");
49     };
50 };
51 
GetDisplayBuffer()52 IDisplayBufferSptr GetDisplayBuffer()
53 {
54     std::lock_guard<std::mutex> bufferLock(g_displayBufferMutex);
55     if (g_displayBuffer != nullptr) {
56         return g_displayBuffer;
57     }
58     return nullptr;
59 }
60 
GetOrResetDisplayBuffer()61 IDisplayBufferSptr GetOrResetDisplayBuffer()
62 {
63     std::lock_guard<std::mutex> bufferLock(g_displayBufferMutex);
64     if (g_displayBuffer != nullptr) {
65         return g_displayBuffer;
66     }
67 
68     g_displayBuffer.reset(OHOS::HDI::Display::Buffer::V1_3::IDisplayBuffer::Get());
69     if (g_displayBuffer == nullptr) {
70         BLOGE("IDisplayBuffer::Get return nullptr.");
71         return nullptr;
72     }
73     sptr<IRemoteObject::DeathRecipient> recipient = new DisplayBufferDiedRecipient();
74     g_displayBuffer->AddDeathRecipient(recipient);
75     return g_displayBuffer;
76 }
77 
78 constexpr int32_t INVALID_ARGUMENT = -1;
79 constexpr uint64_t INVALID_PHYADDR = 0;
80 constexpr uint32_t INVALID_SIZE = 0;
81 constexpr uint64_t INVALID_USAGE = std::numeric_limits<std::uint64_t>::max();
82 const std::string MEMMGR_SO = "libmemmgrclient.z.so";
83 }
84 
Create()85 sptr<SurfaceBuffer> SurfaceBuffer::Create()
86 {
87     sptr<SurfaceBuffer> surfaceBufferImpl = new SurfaceBufferImpl();
88     return surfaceBufferImpl;
89 }
90 
SurfaceBufferImpl()91 SurfaceBufferImpl::SurfaceBufferImpl()
92 {
93     {
94         std::lock_guard<std::mutex> lock(g_seqNumMutex);
95 
96         static uint32_t sequence_number_ = 0;
97         // 0xFFFF is pid mask. 16 is pid offset.
98         sequenceNumber_ = (static_cast<uint32_t>(getpid()) & 0xFFFF) << 16;
99         // 0xFFFF is seqnum mask.
100         sequence_number_++;
101         sequenceNumber_ |= (GenerateSequenceNumber(sequence_number_) & MAX_SEQUENCE_NUM);
102 
103         InitMemMgrMembers();
104     }
105     metaDataCache_.clear();
106     bedata_ = new BufferExtraDataImpl;
107 
108     BLOGD("SurfaceBufferImpl ctor, seq: %{public}u", sequenceNumber_);
109 }
110 
GenerateSequenceNumber(uint32_t & seqNum)111 uint32_t SurfaceBufferImpl::GenerateSequenceNumber(uint32_t& seqNum)
112 {
113     uint32_t startSeqNum = seqNum;
114     seqNum %= MAX_SEQUENCE_NUM;
115     for (; seqNum <= MAX_SEQUENCE_NUM; ++seqNum) {
116         if (seqNum == MAX_SEQUENCE_NUM) {
117             seqNum = 0;
118         }
119 
120         if (!g_seqBitset.test(seqNum)) {
121             g_seqBitset.set(seqNum);
122             break;
123         }
124 
125         if (seqNum == (startSeqNum - 1) % MAX_SEQUENCE_NUM) {
126             BLOGE("SurfaceBufferImpl GenerateSequenceNumber failed, no idle seq");
127             seqNum = startSeqNum;
128             break;
129         }
130     }
131 
132     return seqNum;
133 }
134 
InitMemMgrMembers()135 void SurfaceBufferImpl::InitMemMgrMembers()
136 {
137     if (initMemMgrSucceed_.load()) {
138         return;
139     }
140     libMemMgrClientHandle_ = dlopen(MEMMGR_SO.c_str(), RTLD_NOW);
141     if (!libMemMgrClientHandle_) {
142         BLOGE("dlopen libmemmgrclient failed, error:%{public}s", dlerror());
143         return;
144     }
145     void *reclaim = dlsym(libMemMgrClientHandle_, "reclaim");
146     if (!reclaim) {
147         BLOGE("dlsym reclaim failed, error:%{public}s", dlerror());
148         dlclose(libMemMgrClientHandle_);
149         libMemMgrClientHandle_ = nullptr;
150         return;
151     }
152     reclaimFunc_ = reinterpret_cast<MemMgrFunctionPtr>(reclaim);
153     void *resume = dlsym(libMemMgrClientHandle_, "resume");
154     if (!resume) {
155         BLOGE("dlsym resume failed, error:%{public}s", dlerror());
156         dlclose(libMemMgrClientHandle_);
157         libMemMgrClientHandle_ = nullptr;
158         return;
159     }
160     resumeFunc_ = reinterpret_cast<MemMgrFunctionPtr>(resume);
161     ownPid_ = getpid();
162     if (ownPid_ < 0) {
163         BLOGE("ownPid_(%{public}d) is invaid", ownPid_);
164         dlclose(libMemMgrClientHandle_);
165         libMemMgrClientHandle_ = nullptr;
166         return;
167     }
168     initMemMgrSucceed_ = true;
169     BLOGI("InitMemMgrMembers %{public}s", initMemMgrSucceed_.load() ? "succeed" : "failed");
170 }
171 
SurfaceBufferImpl(uint32_t seqNum)172 SurfaceBufferImpl::SurfaceBufferImpl(uint32_t seqNum)
173 {
174     metaDataCache_.clear();
175     {
176         std::lock_guard<std::mutex> lock(g_seqNumMutex);
177         sequenceNumber_ = seqNum;
178         if ((sequenceNumber_ & MAX_SEQUENCE_NUM) < MAX_SEQUENCE_NUM) {
179             g_seqBitset.set(sequenceNumber_ & MAX_SEQUENCE_NUM);
180         }
181     }
182     bedata_ = new BufferExtraDataImpl;
183     BLOGD("SurfaceBufferImpl ctor, seq: %{public}u", sequenceNumber_);
184 }
185 
~SurfaceBufferImpl()186 SurfaceBufferImpl::~SurfaceBufferImpl()
187 {
188     BLOGD("~SurfaceBufferImpl dtor, seq: %{public}u", sequenceNumber_);
189     {
190         std::lock_guard<std::mutex> lock(g_seqNumMutex);
191         if ((sequenceNumber_ & MAX_SEQUENCE_NUM) < MAX_SEQUENCE_NUM) {
192             g_seqBitset.reset(sequenceNumber_ & MAX_SEQUENCE_NUM);
193         }
194     }
195     FreeBufferHandleLocked();
196 }
197 
MetaDataCachedLocked(const uint32_t key,const std::vector<uint8_t> & value)198 bool SurfaceBufferImpl::MetaDataCachedLocked(const uint32_t key, const std::vector<uint8_t>& value)
199 {
200     auto iter = metaDataCache_.find(key);
201     if (iter != metaDataCache_.end() && (*iter).second == value) {
202         return true;
203     }
204     return false;
205 }
206 
Alloc(const BufferRequestConfig & config,const sptr<SurfaceBuffer> & previousBuffer)207 GSError SurfaceBufferImpl::Alloc(const BufferRequestConfig& config, const sptr<SurfaceBuffer>& previousBuffer)
208 {
209     IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer();
210     if (displayBuffer == nullptr) {
211         return GSERROR_INTERNAL;
212     }
213     std::lock_guard<std::mutex> lock(mutex_);
214     FreeBufferHandleLocked();
215 
216     GSError ret = CheckBufferConfig(config.width, config.height, config.format, config.usage);
217     if (ret != GSERROR_OK) {
218         return GSERROR_INVALID_ARGUMENTS;
219     }
220 
221     OHOS::HDI::Display::Buffer::V1_0::AllocInfo info = {config.width, config.height, config.usage, config.format};
222     static bool debugHebcDisabled =
223         std::atoi((system::GetParameter("persist.graphic.debug_hebc.disabled", "0")).c_str()) != 0;
224     if (debugHebcDisabled) {
225         info.usage |= (BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA);
226     }
227     int32_t dRet = 0;
228     if (previousBuffer != nullptr && previousBuffer->GetBufferHandle() != nullptr) {
229         SURFACE_TRACE_NAME_FMT("Realloc buffer");
230         dRet = displayBuffer->ReAllocMem(info, *(previousBuffer->GetBufferHandle()), handle_);
231         BLOGI("Realloc buffer, %{public}d", dRet);
232     } else {
233         SURFACE_TRACE_NAME_FMT("Alloc buffer");
234         dRet = displayBuffer->AllocMem(info, handle_);
235     }
236     if (dRet == GRAPHIC_DISPLAY_SUCCESS && handle_ != nullptr) {
237         dRet = displayBuffer->RegisterBuffer(*handle_);
238         if (dRet != GRAPHIC_DISPLAY_SUCCESS && dRet != GRAPHIC_DISPLAY_NOT_SUPPORT) {
239             BLOGE("AllocMem RegisterBuffer Failed with %{public}d", dRet);
240             return GSERROR_HDI_ERROR;
241         }
242         surfaceBufferColorGamut_ = static_cast<GraphicColorGamut>(config.colorGamut);
243         transform_ = static_cast<GraphicTransformType>(config.transform);
244         surfaceBufferWidth_ = config.width;
245         surfaceBufferHeight_ = config.height;
246         bufferRequestConfig_ = config;
247         return GSERROR_OK;
248     }
249     BLOGW("Alloc Failed with %{public}d, seq: %{public}u", dRet, sequenceNumber_);
250     return GSERROR_HDI_ERROR;
251 }
252 
Map()253 GSError SurfaceBufferImpl::Map()
254 {
255     IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer();
256     if (displayBuffer == nullptr) {
257         return GSERROR_INTERNAL;
258     }
259     std::lock_guard<std::mutex> lock(mutex_);
260     if (handle_ == nullptr) {
261         return GSERROR_INVALID_OPERATING;
262     } else if (handle_->virAddr != nullptr) {
263         return GSERROR_OK;
264     }
265     if (handle_->usage & BUFFER_USAGE_PROTECTED) {
266         return GSERROR_OK;
267     }
268 
269     void* virAddr = displayBuffer->Mmap(*handle_);
270     if (virAddr == nullptr || virAddr == MAP_FAILED) {
271         return GSERROR_HDI_ERROR;
272     }
273     return GSERROR_OK;
274 }
275 
Unmap()276 GSError SurfaceBufferImpl::Unmap()
277 {
278     IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer();
279     if (displayBuffer == nullptr) {
280         return GSERROR_INTERNAL;
281     }
282     std::lock_guard<std::mutex> lock(mutex_);
283     if (handle_ == nullptr) {
284         return GSERROR_INVALID_OPERATING;
285     } else if (handle_->virAddr == nullptr) {
286         BLOGW("handle has been unmaped, seq: %{public}u", sequenceNumber_);
287         return GSERROR_OK;
288     }
289     auto dRet = displayBuffer->Unmap(*handle_);
290     if (dRet == GRAPHIC_DISPLAY_SUCCESS) {
291         handle_->virAddr = nullptr;
292         return GSERROR_OK;
293     }
294     BLOGW("Unmap Failed with %{public}d, seq: %{public}u", dRet, sequenceNumber_);
295     return GSERROR_HDI_ERROR;
296 }
297 
FlushCache()298 GSError SurfaceBufferImpl::FlushCache()
299 {
300     IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer();
301     if (displayBuffer == nullptr) {
302         return GSERROR_INTERNAL;
303     }
304 
305     std::lock_guard<std::mutex> lock(mutex_);
306     if (handle_ == nullptr) {
307         return GSERROR_INVALID_OPERATING;
308     }
309     auto dRet = displayBuffer->FlushCache(*handle_);
310     if (dRet == GRAPHIC_DISPLAY_SUCCESS) {
311         return GSERROR_OK;
312     }
313     BLOGW("FlushCache Failed with %{public}d, seq: %{public}u", dRet, sequenceNumber_);
314     return GSERROR_HDI_ERROR;
315 }
316 
GetImageLayout(void * layout)317 GSError SurfaceBufferImpl::GetImageLayout(void* layout)
318 {
319     IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer();
320     if (displayBuffer == nullptr) {
321         return GSERROR_INTERNAL;
322     }
323     std::lock_guard<std::mutex> lock(mutex_);
324     if (handle_ == nullptr) {
325         return GSERROR_INVALID_OPERATING;
326     } else if (planesInfo_.planeCount != 0) {
327         return GSERROR_OK;
328     }
329 
330     auto dRet = displayBuffer->GetImageLayout(*handle_,
331         *(static_cast<OHOS::HDI::Display::Buffer::V1_2::ImageLayout*>(layout)));
332     if (dRet == GRAPHIC_DISPLAY_SUCCESS) {
333         return GSERROR_OK;
334     }
335     BLOGW("GetImageLayout Failed with %{public}d, seq: %{public}u", dRet, sequenceNumber_);
336     return GSERROR_HDI_ERROR;
337 }
338 
InvalidateCache()339 GSError SurfaceBufferImpl::InvalidateCache()
340 {
341     IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer();
342     if (displayBuffer == nullptr) {
343         return GSERROR_INTERNAL;
344     }
345     std::lock_guard<std::mutex> lock(mutex_);
346     if (handle_ == nullptr) {
347         return GSERROR_INVALID_OPERATING;
348     }
349 
350     auto dRet = displayBuffer->InvalidateCache(*handle_);
351     if (dRet == GRAPHIC_DISPLAY_SUCCESS) {
352         return GSERROR_OK;
353     }
354     BLOGW("InvalidateCache Failed with %{public}d, seq: %{public}u", dRet, sequenceNumber_);
355     return GSERROR_HDI_ERROR;
356 }
357 
FreeBufferHandleLocked()358 void SurfaceBufferImpl::FreeBufferHandleLocked()
359 {
360     metaDataCache_.clear();
361     if (handle_) {
362         IDisplayBufferSptr displayBuffer = GetDisplayBuffer();
363         if (displayBuffer == nullptr) {
364             FreeBufferHandle(handle_);
365             handle_ = nullptr;
366             return;
367         }
368         if (handle_->virAddr != nullptr) {
369             displayBuffer->Unmap(*handle_);
370             handle_->virAddr = nullptr;
371         }
372         displayBuffer->FreeMem(*handle_);
373         handle_ = nullptr;
374     }
375 }
376 
377 // return BufferHandle* is dangerous, need to refactor
GetBufferHandle() const378 BufferHandle* SurfaceBufferImpl::GetBufferHandle() const
379 {
380     std::lock_guard<std::mutex> lock(mutex_);
381     return handle_;
382 }
383 
SetSurfaceBufferColorGamut(const GraphicColorGamut & colorGamut)384 void SurfaceBufferImpl::SetSurfaceBufferColorGamut(const GraphicColorGamut& colorGamut)
385 {
386     std::lock_guard<std::mutex> lock(mutex_);
387     if (surfaceBufferColorGamut_ != colorGamut) {
388         surfaceBufferColorGamut_ = colorGamut;
389     }
390 }
391 
GetSurfaceBufferColorGamut() const392 GraphicColorGamut SurfaceBufferImpl::GetSurfaceBufferColorGamut() const
393 {
394     std::lock_guard<std::mutex> lock(mutex_);
395     return surfaceBufferColorGamut_;
396 }
397 
SetSurfaceBufferTransform(const GraphicTransformType & transform)398 void SurfaceBufferImpl::SetSurfaceBufferTransform(const GraphicTransformType& transform)
399 {
400     std::lock_guard<std::mutex> lock(mutex_);
401     if (transform_ != transform) {
402         transform_ = transform;
403     }
404 }
405 
GetSurfaceBufferTransform() const406 GraphicTransformType SurfaceBufferImpl::GetSurfaceBufferTransform() const
407 {
408     std::lock_guard<std::mutex> lock(mutex_);
409     return transform_;
410 }
411 
GetSurfaceBufferWidth() const412 int32_t SurfaceBufferImpl::GetSurfaceBufferWidth() const
413 {
414     std::lock_guard<std::mutex> lock(mutex_);
415     return surfaceBufferWidth_;
416 }
417 
GetSurfaceBufferHeight() const418 int32_t SurfaceBufferImpl::GetSurfaceBufferHeight() const
419 {
420     std::lock_guard<std::mutex> lock(mutex_);
421     return surfaceBufferHeight_;
422 }
423 
SetSurfaceBufferWidth(int32_t width)424 void SurfaceBufferImpl::SetSurfaceBufferWidth(int32_t width)
425 {
426     std::lock_guard<std::mutex> lock(mutex_);
427     surfaceBufferWidth_ = width;
428 }
429 
SetSurfaceBufferHeight(int32_t height)430 void SurfaceBufferImpl::SetSurfaceBufferHeight(int32_t height)
431 {
432     std::lock_guard<std::mutex> lock(mutex_);
433     surfaceBufferHeight_ = height;
434 }
435 
GetWidth() const436 int32_t SurfaceBufferImpl::GetWidth() const
437 {
438     std::lock_guard<std::mutex> lock(mutex_);
439     if (handle_ == nullptr) {
440         return INVALID_ARGUMENT;
441     }
442     return handle_->width;
443 }
444 
GetHeight() const445 int32_t SurfaceBufferImpl::GetHeight() const
446 {
447     std::lock_guard<std::mutex> lock(mutex_);
448     if (handle_ == nullptr) {
449         return INVALID_ARGUMENT;
450     }
451     return handle_->height;
452 }
453 
GetStride() const454 int32_t SurfaceBufferImpl::GetStride() const
455 {
456     std::lock_guard<std::mutex> lock(mutex_);
457     if (handle_ == nullptr) {
458         return INVALID_ARGUMENT;
459     }
460     return handle_->stride;
461 }
462 
GetFormat() const463 int32_t SurfaceBufferImpl::GetFormat() const
464 {
465     std::lock_guard<std::mutex> lock(mutex_);
466     if (handle_ == nullptr) {
467         return INVALID_ARGUMENT;
468     }
469     return handle_->format;
470 }
471 
GetUsage() const472 uint64_t SurfaceBufferImpl::GetUsage() const
473 {
474     std::lock_guard<std::mutex> lock(mutex_);
475     if (handle_ == nullptr) {
476         return INVALID_USAGE;
477     }
478     return handle_->usage;
479 }
480 
GetPhyAddr() const481 uint64_t SurfaceBufferImpl::GetPhyAddr() const
482 {
483     std::lock_guard<std::mutex> lock(mutex_);
484     if (handle_ == nullptr) {
485         return INVALID_PHYADDR;
486     }
487     return handle_->phyAddr;
488 }
489 
GetVirAddr()490 void* SurfaceBufferImpl::GetVirAddr()
491 {
492     GSError ret = this->Map();
493     if (ret != GSERROR_OK) {
494         return nullptr;
495     }
496     std::lock_guard<std::mutex> lock(mutex_);
497     if (handle_ == nullptr) {
498         return nullptr;
499     }
500     return handle_->virAddr;
501 }
502 
GetFileDescriptor() const503 int32_t SurfaceBufferImpl::GetFileDescriptor() const
504 {
505     std::lock_guard<std::mutex> lock(mutex_);
506     if (handle_ == nullptr) {
507         return INVALID_ARGUMENT;
508     }
509     return handle_->fd;
510 }
511 
GetSize() const512 uint32_t SurfaceBufferImpl::GetSize() const
513 {
514     std::lock_guard<std::mutex> lock(mutex_);
515     if (handle_ == nullptr) {
516         return INVALID_SIZE;
517     }
518     return handle_->size;
519 }
520 
GetPlanesInfo(void ** planesInfo)521 GSError SurfaceBufferImpl::GetPlanesInfo(void** planesInfo)
522 {
523     if (planesInfo == nullptr) {
524         return GSERROR_INVALID_ARGUMENTS;
525     }
526     OHOS::HDI::Display::Buffer::V1_2::ImageLayout layout;
527     GSError ret = GetImageLayout(&layout);
528     if (ret != GSERROR_OK) {
529         BLOGW("GetImageLayout failed, ret:%d, seq: %{public}u", ret, sequenceNumber_);
530         return ret;
531     }
532 
533     std::lock_guard<std::mutex> lock(mutex_);
534     if (planesInfo_.planeCount != 0) {
535         *planesInfo = static_cast<void*>(&planesInfo_);
536         return GSERROR_OK;
537     }
538     planesInfo_.planeCount = layout.planes.size();
539     for (uint32_t i = 0; i < planesInfo_.planeCount && i < 4; i++) { // 4: max plane count
540         planesInfo_.planes[i].offset = layout.planes[i].offset;
541         planesInfo_.planes[i].rowStride = layout.planes[i].hStride;
542         planesInfo_.planes[i].columnStride = layout.planes[i].vStride;
543     }
544 
545     *planesInfo = static_cast<void*>(&planesInfo_);
546     return GSERROR_OK;
547 }
548 
SetExtraData(sptr<BufferExtraData> bedata)549 void SurfaceBufferImpl::SetExtraData(sptr<BufferExtraData> bedata)
550 {
551     std::lock_guard<std::mutex> lock(mutex_);
552     bedata_ = bedata;
553 }
554 
GetExtraData() const555 sptr<BufferExtraData> SurfaceBufferImpl::GetExtraData() const
556 {
557     std::lock_guard<std::mutex> lock(mutex_);
558     return bedata_;
559 }
560 
SetBufferHandle(BufferHandle * handle)561 void SurfaceBufferImpl::SetBufferHandle(BufferHandle* handle)
562 {
563     if (handle == nullptr) {
564         return;
565     }
566     std::lock_guard<std::mutex> lock(mutex_);
567     if (handle_ == handle) {
568         return;
569     }
570     FreeBufferHandleLocked();
571 
572     handle_ = handle;
573     IDisplayBufferSptr displayBuffer = GetDisplayBuffer();
574     if (displayBuffer == nullptr) {
575         return;
576     }
577     auto dRet = displayBuffer->RegisterBuffer(*handle_);
578     if (dRet != GRAPHIC_DISPLAY_SUCCESS && dRet != GRAPHIC_DISPLAY_NOT_SUPPORT) {
579         BLOGE("SetBufferHandle RegisterBuffer Failed with %{public}d", dRet);
580         return;
581     }
582 }
583 
WriteBufferRequestConfig(MessageParcel & parcel)584 GSError SurfaceBufferImpl::WriteBufferRequestConfig(MessageParcel& parcel)
585 {
586     std::lock_guard<std::mutex> lock(mutex_);
587     if (!parcel.WriteInt32(bufferRequestConfig_.width) || !parcel.WriteInt32(bufferRequestConfig_.height) ||
588         !parcel.WriteInt32(bufferRequestConfig_.strideAlignment) || !parcel.WriteInt32(bufferRequestConfig_.format) ||
589         !parcel.WriteUint64(bufferRequestConfig_.usage) || !parcel.WriteInt32(bufferRequestConfig_.timeout) ||
590         !parcel.WriteUint32(static_cast<uint32_t>(bufferRequestConfig_.colorGamut)) ||
591         !parcel.WriteUint32(static_cast<uint32_t>(bufferRequestConfig_.transform)) ||
592         !parcel.WriteInt32(scalingMode_)) {
593         BLOGE("parcel write fail, seq: %{public}u.", sequenceNumber_);
594         return SURFACE_ERROR_UNKOWN;
595     }
596     return GSERROR_OK;
597 }
598 
WriteBufferProperty(MessageParcel & parcel)599 GSError SurfaceBufferImpl::WriteBufferProperty(MessageParcel& parcel)
600 {
601     std::lock_guard<std::mutex> lock(mutex_);
602     if (!parcel.WriteInt32(bufferRequestConfig_.width) || !parcel.WriteInt32(bufferRequestConfig_.height) ||
603         !parcel.WriteInt32(bufferRequestConfig_.strideAlignment) || !parcel.WriteInt32(bufferRequestConfig_.format) ||
604         !parcel.WriteUint64(bufferRequestConfig_.usage) || !parcel.WriteInt32(bufferRequestConfig_.timeout) ||
605         !parcel.WriteUint32(static_cast<uint32_t>(bufferRequestConfig_.colorGamut)) ||
606         !parcel.WriteUint32(static_cast<uint32_t>(bufferRequestConfig_.transform)) ||
607         !parcel.WriteInt32(scalingMode_) || !parcel.WriteInt32(transform_)) {
608         BLOGE("parcel write fail, seq: %{public}u.", sequenceNumber_);
609         return SURFACE_ERROR_UNKOWN;
610     }
611     return GSERROR_OK;
612 }
613 
WriteToMessageParcel(MessageParcel & parcel)614 GSError SurfaceBufferImpl::WriteToMessageParcel(MessageParcel& parcel)
615 {
616     std::lock_guard<std::mutex> lock(mutex_);
617     if (handle_ == nullptr) {
618         return GSERROR_NOT_INIT;
619     }
620     bool ret = WriteBufferHandle(parcel, *handle_);
621     if (ret == false) {
622         return GSERROR_API_FAILED;
623     }
624 
625     return GSERROR_OK;
626 }
627 
ReadBufferRequestConfig(MessageParcel & parcel)628 GSError SurfaceBufferImpl::ReadBufferRequestConfig(MessageParcel& parcel)
629 {
630     std::lock_guard<std::mutex> lock(mutex_);
631     uint32_t colorGamut = 0;
632     uint32_t transform = 0;
633     int32_t scalingMode = {};
634     if (!parcel.ReadInt32(bufferRequestConfig_.width) || !parcel.ReadInt32(bufferRequestConfig_.height) ||
635         !parcel.ReadInt32(bufferRequestConfig_.strideAlignment) || !parcel.ReadInt32(bufferRequestConfig_.format) ||
636         !parcel.ReadUint64(bufferRequestConfig_.usage) || !parcel.ReadInt32(bufferRequestConfig_.timeout) ||
637         !parcel.ReadUint32(colorGamut) || !parcel.ReadUint32(transform) || !parcel.ReadInt32(scalingMode)) {
638         BLOGE("parcel read fail, seq: %{public}u.", sequenceNumber_);
639         return GSERROR_API_FAILED;
640     }
641     surfaceBufferColorGamut_ = static_cast<GraphicColorGamut>(colorGamut);
642     transform_ = static_cast<GraphicTransformType>(transform);
643     surfaceBufferWidth_ = bufferRequestConfig_.width;
644     surfaceBufferHeight_ = bufferRequestConfig_.height;
645     scalingMode_ = static_cast<ScalingMode>(scalingMode);
646     bufferRequestConfig_.colorGamut = static_cast<GraphicColorGamut>(colorGamut);
647     bufferRequestConfig_.transform = static_cast<GraphicTransformType>(transform);
648     return GSERROR_OK;
649 }
650 
ReadBufferProperty(MessageParcel & parcel)651 GSError SurfaceBufferImpl::ReadBufferProperty(MessageParcel& parcel)
652 {
653     std::lock_guard<std::mutex> lock(mutex_);
654     uint32_t colorGamut = 0;
655     uint32_t transform = 0;
656     int32_t scalingMode = {};
657     uint32_t configTransform = 0;
658     if (!parcel.ReadInt32(bufferRequestConfig_.width) || !parcel.ReadInt32(bufferRequestConfig_.height) ||
659         !parcel.ReadInt32(bufferRequestConfig_.strideAlignment) || !parcel.ReadInt32(bufferRequestConfig_.format) ||
660         !parcel.ReadUint64(bufferRequestConfig_.usage) || !parcel.ReadInt32(bufferRequestConfig_.timeout) ||
661         !parcel.ReadUint32(colorGamut) || !parcel.ReadUint32(configTransform) || !parcel.ReadInt32(scalingMode) ||
662         !parcel.ReadUint32(transform)) {
663         BLOGE("parcel read fail, seq: %{public}u.", sequenceNumber_);
664         return GSERROR_API_FAILED;
665     }
666     surfaceBufferColorGamut_ = static_cast<GraphicColorGamut>(colorGamut);
667     transform_ = static_cast<GraphicTransformType>(transform);
668     surfaceBufferWidth_ = bufferRequestConfig_.width;
669     surfaceBufferHeight_ = bufferRequestConfig_.height;
670     scalingMode_ = static_cast<ScalingMode>(scalingMode);
671     bufferRequestConfig_.colorGamut = static_cast<GraphicColorGamut>(colorGamut);
672     bufferRequestConfig_.transform = static_cast<GraphicTransformType>(configTransform);
673     return GSERROR_OK;
674 }
675 
ReadFromBufferInfo(const RSBufferInfo & bufferInfo)676 GSError SurfaceBufferImpl::ReadFromBufferInfo(const RSBufferInfo &bufferInfo)
677 {
678     std::lock_guard<std::mutex> lock(mutex_);
679     bufferRequestConfig_ = bufferInfo.bufferRequestConfig;
680     surfaceBufferWidth_ = bufferInfo.surfaceBufferWidth;
681     surfaceBufferHeight_ = bufferInfo.surfaceBufferHeight;
682     scalingMode_ = bufferInfo.scalingMode;
683     transform_ = bufferInfo.transform;
684     surfaceBufferColorGamut_ = bufferInfo.surfaceBufferColorGamut;
685     return GSERROR_OK;
686 }
687 
ReadFromMessageParcel(MessageParcel & parcel,std::function<int (MessageParcel & parcel,std::function<int (Parcel &)> readFdDefaultFunc)> readSafeFdFunc)688 GSError SurfaceBufferImpl::ReadFromMessageParcel(MessageParcel &parcel,
689     std::function<int(MessageParcel &parcel, std::function<int(Parcel &)>readFdDefaultFunc)>readSafeFdFunc)
690 {
691     auto handle = ReadBufferHandle(parcel, readSafeFdFunc);
692     SetBufferHandle(handle);
693     return handle ? GSERROR_OK : GSERROR_API_FAILED;
694 }
695 
696 // return OH_NativeBuffer* is dangerous, need to refactor
SurfaceBufferToNativeBuffer()697 OH_NativeBuffer* SurfaceBufferImpl::SurfaceBufferToNativeBuffer()
698 {
699     return reinterpret_cast<OH_NativeBuffer *>(this);
700 }
701 
GetSeqNum() const702 uint32_t SurfaceBufferImpl::GetSeqNum() const
703 {
704     return sequenceNumber_;
705 }
706 
CheckBufferConfig(int32_t width,int32_t height,int32_t format,uint64_t usage)707 GSError SurfaceBufferImpl::CheckBufferConfig(int32_t width, int32_t height,
708                                              int32_t format, uint64_t usage)
709 {
710     if (width <= 0 || height <= 0) {
711         BLOGE("width %{public}d height %{public}d", width, height);
712         return GSERROR_INVALID_ARGUMENTS;
713     }
714 
715     if (format < 0 || format > GRAPHIC_PIXEL_FMT_BUTT) {
716         BLOGE("format is %{public}d", format);
717         return GSERROR_INVALID_ARGUMENTS;
718     }
719 
720     return GSERROR_OK;
721 }
722 
SetMetadata(uint32_t key,const std::vector<uint8_t> & value,bool enableCache)723 GSError SurfaceBufferImpl::SetMetadata(uint32_t key, const std::vector<uint8_t>& value, bool enableCache)
724 {
725     if (key == 0 || key >= HDI::Display::Graphic::Common::V1_1::ATTRKEY_END) {
726         return GSERROR_INVALID_ARGUMENTS;
727     }
728     IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer();
729     if (displayBuffer == nullptr) {
730         return GSERROR_INTERNAL;
731     }
732 
733     std::lock_guard<std::mutex> lock(mutex_);
734     if (handle_ == nullptr) {
735         return GSERROR_NOT_INIT;
736     }
737 
738     if (enableCache && MetaDataCachedLocked(key, value)) {
739         return GSERROR_OK;
740     }
741 
742     auto dRet = displayBuffer->SetMetadata(*handle_, key, value);
743     if (dRet == GRAPHIC_DISPLAY_SUCCESS) {
744         // cache metaData
745         if (enableCache) {
746             metaDataCache_[key] = value;
747         }
748         return GSERROR_OK;
749     }
750     BLOGE("SetMetadata Failed with %{public}d", dRet);
751     return GSERROR_HDI_ERROR;
752 }
753 
GetMetadata(uint32_t key,std::vector<uint8_t> & value)754 GSError SurfaceBufferImpl::GetMetadata(uint32_t key, std::vector<uint8_t>& value)
755 {
756     if (key == 0 || key >= HDI::Display::Graphic::Common::V1_1::ATTRKEY_END) {
757         return GSERROR_INVALID_ARGUMENTS;
758     }
759     IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer();
760     if (displayBuffer == nullptr) {
761         return GSERROR_INTERNAL;
762     }
763 
764     std::lock_guard<std::mutex> lock(mutex_);
765     if (handle_ == nullptr) {
766         return GSERROR_NOT_INIT;
767     }
768     auto dRet = displayBuffer->GetMetadata(*handle_, key, value);
769     if (dRet == GRAPHIC_DISPLAY_SUCCESS) {
770         return GSERROR_OK;
771     }
772     return GSERROR_HDI_ERROR;
773 }
774 
ListMetadataKeys(std::vector<uint32_t> & keys)775 GSError SurfaceBufferImpl::ListMetadataKeys(std::vector<uint32_t>& keys)
776 {
777     IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer();
778     if (displayBuffer == nullptr) {
779         return GSERROR_INTERNAL;
780     }
781     keys.clear();
782     std::lock_guard<std::mutex> lock(mutex_);
783     if (handle_ == nullptr) {
784         return GSERROR_NOT_INIT;
785     }
786     auto dRet = displayBuffer->ListMetadataKeys(*handle_, keys);
787     if (dRet == GRAPHIC_DISPLAY_SUCCESS) {
788         return GSERROR_OK;
789     }
790     BLOGE("ListMetadataKeys Failed with %{public}d", dRet);
791     return GSERROR_HDI_ERROR;
792 }
793 
EraseMetadataKey(uint32_t key)794 GSError SurfaceBufferImpl::EraseMetadataKey(uint32_t key)
795 {
796     if (key == 0 || key >= HDI::Display::Graphic::Common::V1_1::ATTRKEY_END) {
797         return GSERROR_INVALID_ARGUMENTS;
798     }
799     IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer();
800     if (displayBuffer == nullptr) {
801         return GSERROR_INTERNAL;
802     }
803 
804     std::lock_guard<std::mutex> lock(mutex_);
805     if (handle_ == nullptr) {
806         return GSERROR_NOT_INIT;
807     }
808     auto dRet = displayBuffer->EraseMetadataKey(*handle_, key);
809     if (dRet == GRAPHIC_DISPLAY_SUCCESS) {
810         metaDataCache_.erase(key);
811         return GSERROR_OK;
812     }
813     BLOGE("EraseMetadataKey Failed with %{public}d", dRet);
814     return GSERROR_HDI_ERROR;
815 }
816 
SetCropMetadata(const Rect & crop)817 void SurfaceBufferImpl::SetCropMetadata(const Rect& crop)
818 {
819     std::lock_guard<std::mutex> lock(mutex_);
820     crop_ = crop;
821 }
822 
GetCropMetadata(Rect & crop)823 bool SurfaceBufferImpl::GetCropMetadata(Rect& crop)
824 {
825     std::lock_guard<std::mutex> lock(mutex_);
826     if (crop_.w <= 0 || crop_.h <= 0) {
827         return false;
828     }
829     crop = crop_;
830     return true;
831 }
832 
GetBufferRequestConfig() const833 BufferRequestConfig SurfaceBufferImpl::GetBufferRequestConfig() const
834 {
835     std::lock_guard<std::mutex> lock(mutex_);
836     return bufferRequestConfig_;
837 }
838 
SetBufferRequestConfig(const BufferRequestConfig & config)839 void SurfaceBufferImpl::SetBufferRequestConfig(const BufferRequestConfig& config)
840 {
841     std::lock_guard<std::mutex> lock(mutex_);
842     bufferRequestConfig_ = config;
843 }
844 
SetConsumerAttachBufferFlag(bool value)845 void SurfaceBufferImpl::SetConsumerAttachBufferFlag(bool value)
846 {
847     std::lock_guard<std::mutex> lock(mutex_);
848     isConsumerAttachBufferFlag_ = value;
849 }
850 
GetConsumerAttachBufferFlag()851 bool SurfaceBufferImpl::GetConsumerAttachBufferFlag()
852 {
853     std::lock_guard<std::mutex> lock(mutex_);
854     return isConsumerAttachBufferFlag_;
855 }
856 
SetSurfaceBufferScalingMode(const ScalingMode & scalingMode)857 void SurfaceBufferImpl::SetSurfaceBufferScalingMode(const ScalingMode &scalingMode)
858 {
859     std::lock_guard<std::mutex> lock(mutex_);
860     scalingMode_ = scalingMode;
861 }
862 
GetSurfaceBufferScalingMode() const863 ScalingMode SurfaceBufferImpl::GetSurfaceBufferScalingMode() const
864 {
865     std::lock_guard<std::mutex> lock(mutex_);
866     return scalingMode_;
867 }
868 
SetBufferDeleteFromCacheFlag(const bool & flag)869 void SurfaceBufferImpl::SetBufferDeleteFromCacheFlag(const bool &flag)
870 {
871     isBufferDeleteFromCache = flag;
872 }
873 
GetBufferDeleteFromCacheFlag() const874 bool SurfaceBufferImpl::GetBufferDeleteFromCacheFlag() const
875 {
876     return isBufferDeleteFromCache;
877 }
878 
TryReclaim()879 GSError SurfaceBufferImpl::TryReclaim()
880 {
881     if (!initMemMgrSucceed_.load()) {
882         BLOGE("init memmgr members failed");
883         return GSERROR_INVALID_ARGUMENTS;
884     }
885     if (isReclaimed_.load()) {
886         return GSERROR_INVALID_OPERATING;
887     }
888 
889     int32_t fd = -1;
890     {
891         std::lock_guard<std::mutex> lock(mutex_);
892         if (handle_ == nullptr) {
893             return GSERROR_INVALID_ARGUMENTS;
894         }
895         fd = handle_->fd;
896     }
897     if (fd < 0) {
898         return GSERROR_INVALID_ARGUMENTS;
899     }
900 
901     int32_t ret = reclaimFunc_(ownPid_, fd);
902     isReclaimed_ = (ret == 0 ? true : false);
903     return (ret == 0 ? GSERROR_OK : GSERROR_API_FAILED);
904 }
905 
TryResumeIfNeeded()906 GSError SurfaceBufferImpl::TryResumeIfNeeded()
907 {
908     if (!initMemMgrSucceed_.load()) {
909         BLOGE("init memmgr members failed");
910         return GSERROR_INVALID_ARGUMENTS;
911     }
912     if (!isReclaimed_.load()) {
913         return GSERROR_INVALID_OPERATING;
914     }
915 
916     int32_t fd = -1;
917     {
918         std::lock_guard<std::mutex> lock(mutex_);
919         if (handle_ == nullptr) {
920             return GSERROR_INVALID_ARGUMENTS;
921         }
922         fd = handle_->fd;
923     }
924     if (fd < 0) {
925         return GSERROR_INVALID_ARGUMENTS;
926     }
927 
928     int32_t ret = resumeFunc_(ownPid_, fd);
929     isReclaimed_ = (ret == 0 ? false : true);
930     return (ret == 0 ? GSERROR_OK : GSERROR_API_FAILED);
931 }
932 
IsReclaimed()933 bool SurfaceBufferImpl::IsReclaimed()
934 {
935     return isReclaimed_.load();
936 }
937 
SetAndMergeSyncFence(const sptr<SyncFence> & syncFence)938 void SurfaceBufferImpl::SetAndMergeSyncFence(const sptr<SyncFence>& syncFence)
939 {
940     std::lock_guard<std::mutex> lock(mutex_);
941     if (syncFence == nullptr) {
942         return;
943     }
944     if (syncFence_ != nullptr && syncFence_->IsValid()) {
945         syncFence_ = SyncFence::MergeFence("SurfaceBufferSyncFence", syncFence_, syncFence);
946     } else {
947         syncFence_ = syncFence;
948     }
949 }
950 
GetSyncFence() const951 sptr<SyncFence> SurfaceBufferImpl::GetSyncFence() const
952 {
953     std::lock_guard<std::mutex> lock(mutex_);
954     return syncFence_;
955 }
956 } // namespace OHOS
957