• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 <securec.h>
22 #include <sys/mman.h>
23 #include "buffer_log.h"
24 #include "buffer_manager.h"
25 #include "buffer_extra_data_impl.h"
26 #include "native_buffer.h"
27 #include "v1_0/include/idisplay_buffer.h"
28 
29 namespace OHOS {
30 namespace {
GenerateError(GSError err,GraphicDispErrCode code)31 GSError GenerateError(GSError err, GraphicDispErrCode code)
32 {
33     switch (code) {
34         case GRAPHIC_DISPLAY_SUCCESS: return static_cast<GSError>(err + 0);
35         case GRAPHIC_DISPLAY_FAILURE: return static_cast<GSError>(err + LOWERROR_FAILURE);
36         case GRAPHIC_DISPLAY_FD_ERR: return static_cast<GSError>(err + EBADF);
37         case GRAPHIC_DISPLAY_PARAM_ERR: return static_cast<GSError>(err + EINVAL);
38         case GRAPHIC_DISPLAY_NULL_PTR: return static_cast<GSError>(err + EINVAL);
39         case GRAPHIC_DISPLAY_NOT_SUPPORT: return static_cast<GSError>(err + EOPNOTSUPP);
40         case GRAPHIC_DISPLAY_NOMEM: return static_cast<GSError>(err + ENOMEM);
41         case GRAPHIC_DISPLAY_SYS_BUSY: return static_cast<GSError>(err + EBUSY);
42         case GRAPHIC_DISPLAY_NOT_PERM: return static_cast<GSError>(err + EPERM);
43         default: break;
44     }
45     return static_cast<GSError>(err + LOWERROR_INVALID);
46 }
47 
GenerateError(GSError err,int32_t code)48 inline GSError GenerateError(GSError err, int32_t code)
49 {
50     return GenerateError(err, static_cast<GraphicDispErrCode>(code));
51 }
52 
53 using namespace OHOS::HDI::Display::Buffer::V1_0;
54 using IDisplayBufferSptr = std::shared_ptr<IDisplayBuffer>;
55 static IDisplayBufferSptr g_displayBuffer;
56 static std::mutex g_DisplayBufferMutex;
57 class DisplayBufferDiedRecipient : public OHOS::IRemoteObject::DeathRecipient {
58 public:
59     DisplayBufferDiedRecipient() = default;
60     virtual ~DisplayBufferDiedRecipient() = default;
OnRemoteDied(const OHOS::wptr<OHOS::IRemoteObject> & remote)61     void OnRemoteDied(const OHOS::wptr<OHOS::IRemoteObject>& remote) override
62     {
63         std::lock_guard<std::mutex> lock(g_DisplayBufferMutex);
64         g_displayBuffer = nullptr;
65         BLOGD("IDisplayBuffer died and g_displayBuffer is nullptr");
66     };
67 };
GetDisplayBuffer()68 IDisplayBufferSptr GetDisplayBuffer()
69 {
70     std::lock_guard<std::mutex> lock(g_DisplayBufferMutex);
71     if (g_displayBuffer != nullptr) {
72         return g_displayBuffer;
73     }
74 
75     g_displayBuffer.reset(IDisplayBuffer::Get());
76     if (g_displayBuffer == nullptr) {
77         BLOGE("IDisplayBuffer::Get return nullptr.");
78         return nullptr;
79     }
80     sptr<IRemoteObject::DeathRecipient> recipient = new DisplayBufferDiedRecipient();
81     g_displayBuffer->AddDeathRecipient(recipient);
82     return g_displayBuffer;
83 }
84 
85 }
86 
Create()87 sptr<SurfaceBuffer> SurfaceBuffer::Create()
88 {
89     sptr<SurfaceBuffer> surfaceBufferImpl = new SurfaceBufferImpl();
90     return surfaceBufferImpl;
91 }
92 
DisplayBufferDeathCallback(void * data)93 void SurfaceBufferImpl::DisplayBufferDeathCallback(void* data)
94 {
95     std::lock_guard<std::mutex> lock(g_DisplayBufferMutex);
96     g_displayBuffer = nullptr;
97     BLOGD("gralloc_host died and g_displayBuffer is nullptr.");
98 }
99 
SurfaceBufferImpl()100 SurfaceBufferImpl::SurfaceBufferImpl()
101 {
102     {
103         static std::mutex mutex;
104         mutex.lock();
105 
106         static uint32_t sequence_number_ = 0;
107         sequenceNumber_ = sequence_number_++;
108 
109         mutex.unlock();
110     }
111     bedata_ = new BufferExtraDataImpl;
112     BLOGD("ctor +[%{public}u]", sequenceNumber_);
113 }
114 
SurfaceBufferImpl(uint32_t seqNum)115 SurfaceBufferImpl::SurfaceBufferImpl(uint32_t seqNum)
116 {
117     sequenceNumber_ = seqNum;
118     bedata_ = new BufferExtraDataImpl;
119     BLOGD("ctor =[%{public}u]", sequenceNumber_);
120 }
121 
~SurfaceBufferImpl()122 SurfaceBufferImpl::~SurfaceBufferImpl()
123 {
124     BLOGD("dtor ~[%{public}u]", sequenceNumber_);
125     FreeBufferHandleLocked();
126 }
127 
FromBase(const sptr<SurfaceBuffer> & buffer)128 SurfaceBufferImpl *SurfaceBufferImpl::FromBase(const sptr<SurfaceBuffer>& buffer)
129 {
130     return static_cast<SurfaceBufferImpl*>(buffer.GetRefPtr());
131 }
132 
Alloc(const BufferRequestConfig & config)133 GSError SurfaceBufferImpl::Alloc(const BufferRequestConfig &config)
134 {
135     if (GetDisplayBuffer() == nullptr) {
136         BLOGE("GetDisplayBuffer failed!");
137         return GSERROR_INTERNAL;
138     }
139 
140     {
141         std::lock_guard<std::mutex> lock(mutex_);
142         if (handle_ != nullptr) {
143             FreeBufferHandleLocked();
144         }
145     }
146 
147     GSError ret = CheckBufferConfig(config.width, config.height, config.format, config.usage);
148     if (ret != GSERROR_OK) {
149         return GSERROR_INVALID_ARGUMENTS;
150     }
151 
152     BufferHandle *handle = nullptr;
153     AllocInfo info = {config.width, config.height, config.usage, config.format};
154     auto dret = g_displayBuffer->AllocMem(info, handle);
155     if (dret == GRAPHIC_DISPLAY_SUCCESS) {
156         std::lock_guard<std::mutex> lock(mutex_);
157         surfaceBufferColorGamut_ = static_cast<GraphicColorGamut>(config.colorGamut);
158         transform_ = static_cast<GraphicTransformType>(config.transform);
159         surfaceBufferWidth_ = config.width;
160         surfaceBufferHeight_ = config.height;
161         handle_ = handle;
162         BLOGD("buffer handle w: %{public}d h: %{public}d t: %{public}d",
163             handle_->width, handle_->height, config.transform);
164         return GSERROR_OK;
165     }
166     BLOGW("Failed with %{public}d", dret);
167     return GenerateError(GSERROR_API_FAILED, dret);
168 }
Map()169 GSError SurfaceBufferImpl::Map()
170 {
171     if (GetDisplayBuffer() == nullptr) {
172         BLOGE("GetDisplayBuffer failed!");
173         return GSERROR_INTERNAL;
174     }
175 
176     BufferHandle *handle = nullptr;
177     {
178         std::lock_guard<std::mutex> lock(mutex_);
179         if (handle_ == nullptr) {
180             BLOGE("handle is nullptr");
181             return GSERROR_INVALID_OPERATING;
182         } else if (handle_->virAddr != nullptr) {
183             BLOGD("handle_->virAddr has been maped");
184             return GSERROR_OK;
185         }
186         handle = handle_;
187     }
188 #ifdef RS_ENABLE_AFBC
189     handle->usage |= (BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA);
190 #endif
191     void *virAddr = g_displayBuffer->Mmap(*handle);
192     if (virAddr == nullptr || virAddr == MAP_FAILED) {
193         return GSERROR_API_FAILED;
194     }
195     return GSERROR_OK;
196 }
Unmap()197 GSError SurfaceBufferImpl::Unmap()
198 {
199     if (GetDisplayBuffer() == nullptr) {
200         BLOGE("GetDisplayBuffer failed!");
201         return GSERROR_INTERNAL;
202     }
203     BufferHandle *handle = nullptr;
204     {
205         std::lock_guard<std::mutex> lock(mutex_);
206         if (handle_ == nullptr) {
207             BLOGE("handle is nullptr");
208             return GSERROR_INVALID_OPERATING;
209         } else if (handle_->virAddr == nullptr) {
210             BLOGW("handle has been unmaped");
211             return GSERROR_OK;
212         }
213         handle = handle_;
214     }
215 
216     auto dret = g_displayBuffer->Unmap(*handle);
217     if (dret == GRAPHIC_DISPLAY_SUCCESS) {
218         handle_->virAddr = nullptr;
219         return GSERROR_OK;
220     }
221     BLOGW("Failed with %{public}d", dret);
222     return GenerateError(GSERROR_API_FAILED, dret);
223 }
FlushCache()224 GSError SurfaceBufferImpl::FlushCache()
225 {
226     if (GetDisplayBuffer() == nullptr) {
227         BLOGE("GetDisplayBuffer failed!");
228         return GSERROR_INTERNAL;
229     }
230     BufferHandle *handle = nullptr;
231     {
232         std::lock_guard<std::mutex> lock(mutex_);
233         if (handle_ == nullptr) {
234             BLOGE("handle is nullptr");
235             return GSERROR_INVALID_OPERATING;
236         }
237         handle = handle_;
238     }
239 
240     if (handle->virAddr == nullptr) {
241         return GSERROR_API_FAILED;
242     }
243 
244     auto dret = g_displayBuffer->FlushCache(*handle);
245     if (dret == GRAPHIC_DISPLAY_SUCCESS) {
246         return GSERROR_OK;
247     }
248     BLOGW("Failed with %{public}d", dret);
249     return GenerateError(GSERROR_API_FAILED, dret);
250 }
251 
InvalidateCache()252 GSError SurfaceBufferImpl::InvalidateCache()
253 {
254     if (GetDisplayBuffer() == nullptr) {
255         BLOGE("GetDisplayBuffer failed!");
256         return GSERROR_INTERNAL;
257     }
258     BufferHandle *handle = nullptr;
259     {
260         std::lock_guard<std::mutex> lock(mutex_);
261         if (handle_ == nullptr) {
262             BLOGE("handle is nullptr");
263             return GSERROR_INVALID_OPERATING;
264         }
265         handle = handle_;
266     }
267 
268     auto dret = g_displayBuffer->InvalidateCache(*handle);
269     if (dret == GRAPHIC_DISPLAY_SUCCESS) {
270         return GSERROR_OK;
271     }
272     BLOGW("Failed with %{public}d", dret);
273     return GenerateError(GSERROR_API_FAILED, dret);
274 }
275 
FreeBufferHandleLocked()276 void SurfaceBufferImpl::FreeBufferHandleLocked()
277 {
278     if (handle_) {
279         if (handle_->virAddr != nullptr && g_displayBuffer != nullptr) {
280             g_displayBuffer->Unmap(*handle_);
281             handle_->virAddr = nullptr;
282         }
283         FreeBufferHandle(handle_);
284     }
285     handle_ = nullptr;
286 }
287 
GetBufferHandle() const288 BufferHandle *SurfaceBufferImpl::GetBufferHandle() const
289 {
290     std::lock_guard<std::mutex> lock(mutex_);
291     return handle_;
292 }
293 
SetSurfaceBufferColorGamut(const GraphicColorGamut & colorGamut)294 void SurfaceBufferImpl::SetSurfaceBufferColorGamut(const GraphicColorGamut& colorGamut)
295 {
296     std::lock_guard<std::mutex> lock(mutex_);
297     surfaceBufferColorGamut_ = colorGamut;
298 }
299 
GetSurfaceBufferColorGamut() const300 const GraphicColorGamut& SurfaceBufferImpl::GetSurfaceBufferColorGamut() const
301 {
302     std::lock_guard<std::mutex> lock(mutex_);
303     return surfaceBufferColorGamut_;
304 }
305 
SetSurfaceBufferTransform(const GraphicTransformType & transform)306 void SurfaceBufferImpl::SetSurfaceBufferTransform(const GraphicTransformType& transform)
307 {
308     std::lock_guard<std::mutex> lock(mutex_);
309     transform_ = transform;
310 }
311 
GetSurfaceBufferTransform() const312 const GraphicTransformType& SurfaceBufferImpl::GetSurfaceBufferTransform() const
313 {
314     std::lock_guard<std::mutex> lock(mutex_);
315     return transform_;
316 }
317 
GetSurfaceBufferWidth() const318 int32_t SurfaceBufferImpl::GetSurfaceBufferWidth() const
319 {
320     std::lock_guard<std::mutex> lock(mutex_);
321     return surfaceBufferWidth_;
322 }
323 
GetSurfaceBufferHeight() const324 int32_t SurfaceBufferImpl::GetSurfaceBufferHeight() const
325 {
326     std::lock_guard<std::mutex> lock(mutex_);
327     return surfaceBufferHeight_;
328 }
329 
SetSurfaceBufferWidth(int32_t width)330 void SurfaceBufferImpl::SetSurfaceBufferWidth(int32_t width)
331 {
332     std::lock_guard<std::mutex> lock(mutex_);
333     surfaceBufferWidth_ = width;
334 }
335 
SetSurfaceBufferHeight(int32_t height)336 void SurfaceBufferImpl::SetSurfaceBufferHeight(int32_t height)
337 {
338     std::lock_guard<std::mutex> lock(mutex_);
339     surfaceBufferHeight_ = height;
340 }
341 
GetWidth() const342 int32_t SurfaceBufferImpl::GetWidth() const
343 {
344     std::lock_guard<std::mutex> lock(mutex_);
345     if (handle_ == nullptr) {
346         BLOGE("handle is nullptr");
347         return -1;
348     }
349     return handle_->width;
350 }
351 
GetHeight() const352 int32_t SurfaceBufferImpl::GetHeight() const
353 {
354     std::lock_guard<std::mutex> lock(mutex_);
355     if (handle_ == nullptr) {
356         BLOGE("handle is nullptr");
357         return -1;
358     }
359     return handle_->height;
360 }
361 
GetStride() const362 int32_t SurfaceBufferImpl::GetStride() const
363 {
364     std::lock_guard<std::mutex> lock(mutex_);
365     if (handle_ == nullptr) {
366         BLOGE("handle is nullptr");
367         return -1;
368     }
369     return handle_->stride;
370 }
371 
GetFormat() const372 int32_t SurfaceBufferImpl::GetFormat() const
373 {
374     std::lock_guard<std::mutex> lock(mutex_);
375     if (handle_ == nullptr) {
376         BLOGE("handle is nullptr");
377         return -1;
378     }
379     return handle_->format;
380 }
381 
GetUsage() const382 uint64_t SurfaceBufferImpl::GetUsage() const
383 {
384     std::lock_guard<std::mutex> lock(mutex_);
385     if (handle_ == nullptr) {
386         BLOGE("handle is nullptr");
387         return -1;
388     }
389     return handle_->usage;
390 }
391 
GetPhyAddr() const392 uint64_t SurfaceBufferImpl::GetPhyAddr() const
393 {
394     std::lock_guard<std::mutex> lock(mutex_);
395     if (handle_ == nullptr) {
396         BLOGE("handle is nullptr");
397         return 0;
398     }
399     return handle_->phyAddr;
400 }
401 
GetVirAddr()402 void *SurfaceBufferImpl::GetVirAddr()
403 {
404     GSError ret = this->Map();
405     if (ret != GSERROR_OK) {
406         BLOGW("Map failed");
407         return nullptr;
408     }
409     return handle_->virAddr;
410 }
411 
GetFileDescriptor() const412 int32_t SurfaceBufferImpl::GetFileDescriptor() const
413 {
414     std::lock_guard<std::mutex> lock(mutex_);
415     if (handle_ == nullptr) {
416         BLOGE("handle is nullptr");
417         return -1;
418     }
419     return handle_->fd;
420 }
421 
GetSize() const422 uint32_t SurfaceBufferImpl::GetSize() const
423 {
424     std::lock_guard<std::mutex> lock(mutex_);
425     if (handle_ == nullptr) {
426         BLOGW("handle is nullptr");
427         return 0;
428     }
429     return handle_->size;
430 }
431 
SetExtraData(const sptr<BufferExtraData> & bedata)432 void SurfaceBufferImpl::SetExtraData(const sptr<BufferExtraData> &bedata)
433 {
434     std::lock_guard<std::mutex> lock(mutex_);
435     bedata_ = bedata;
436 }
437 
GetExtraData() const438 const sptr<BufferExtraData>& SurfaceBufferImpl::GetExtraData() const
439 {
440     std::lock_guard<std::mutex> lock(mutex_);
441     return bedata_;
442 }
443 
SetBufferHandle(BufferHandle * handle)444 void SurfaceBufferImpl::SetBufferHandle(BufferHandle *handle)
445 {
446     std::lock_guard<std::mutex> lock(mutex_);
447     handle_ = handle;
448 }
449 
WriteToMessageParcel(MessageParcel & parcel)450 GSError SurfaceBufferImpl::WriteToMessageParcel(MessageParcel &parcel)
451 {
452     BufferHandle *handle = nullptr;
453     {
454         std::lock_guard<std::mutex> lock(mutex_);
455         if (handle_ == nullptr) {
456             BLOGE("Failure, Reason: handle_ is nullptr");
457             return GSERROR_NOT_INIT;
458         }
459         handle = handle_;
460     }
461 
462     bool ret = WriteBufferHandle(parcel, *handle);
463     if (ret == false) {
464         BLOGE("Failure, Reason: WriteBufferHandle return false");
465         return GSERROR_API_FAILED;
466     }
467 
468     return GSERROR_OK;
469 }
470 
ReadFromMessageParcel(MessageParcel & parcel)471 GSError SurfaceBufferImpl::ReadFromMessageParcel(MessageParcel &parcel)
472 {
473     std::lock_guard<std::mutex> lock(mutex_);
474     FreeBufferHandleLocked();
475     handle_ = ReadBufferHandle(parcel);
476     if (handle_ == nullptr) {
477         return GSERROR_API_FAILED;
478     }
479 
480     return GSERROR_OK;
481 }
482 
SurfaceBufferToNativeBuffer()483 OH_NativeBuffer* SurfaceBufferImpl::SurfaceBufferToNativeBuffer()
484 {
485     return reinterpret_cast<OH_NativeBuffer *>(this);
486 }
487 
GetSeqNum() const488 uint32_t SurfaceBufferImpl::GetSeqNum() const
489 {
490     return sequenceNumber_;
491 }
492 
GetEglData() const493 sptr<EglData> SurfaceBufferImpl::GetEglData() const
494 {
495     return eglData_;
496 }
497 
SetEglData(const sptr<EglData> & data)498 void SurfaceBufferImpl::SetEglData(const sptr<EglData>& data)
499 {
500     eglData_ = data;
501 }
502 
CheckBufferConfig(int32_t width,int32_t height,int32_t format,uint64_t usage)503 GSError SurfaceBufferImpl::CheckBufferConfig(int32_t width, int32_t height,
504                                              int32_t format, uint64_t usage)
505 {
506     if (width <= 0 || height <= 0) {
507         BLOGE("width or height is greater than 0, now is w %{public}d h %{public}d", width, height);
508         return GSERROR_INVALID_ARGUMENTS;
509     }
510 
511     if (format < 0 || format > GRAPHIC_PIXEL_FMT_BUTT) {
512         BLOGE("format [0, %{public}d], now is %{public}d", GRAPHIC_PIXEL_FMT_BUTT, format);
513         return GSERROR_INVALID_ARGUMENTS;
514     }
515 
516     return GSERROR_OK;
517 }
518 
GetBufferWrapper()519 BufferWrapper SurfaceBufferImpl::GetBufferWrapper()
520 {
521     BufferWrapper wrapper;
522     return wrapper;
523 }
524 
SetBufferWrapper(BufferWrapper wrapper)525 void SurfaceBufferImpl::SetBufferWrapper(BufferWrapper wrapper) {}
526 } // namespace OHOS
527