• 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 
24 #include "buffer_log.h"
25 #include "buffer_manager.h"
26 #include "buffer_extra_data_impl.h"
27 #include "native_buffer.h"
28 
29 namespace OHOS {
30 namespace {
GenerateError(GSError err,DispErrCode code)31 GSError GenerateError(GSError err, DispErrCode code)
32 {
33     switch (code) {
34         case DISPLAY_SUCCESS: return static_cast<GSError>(err + 0);
35         case DISPLAY_FAILURE: return static_cast<GSError>(err + LOWERROR_FAILURE);
36         case DISPLAY_FD_ERR: return static_cast<GSError>(err + EBADF);
37         case DISPLAY_PARAM_ERR: return static_cast<GSError>(err + EINVAL);
38         case DISPLAY_NULL_PTR: return static_cast<GSError>(err + EINVAL);
39         case DISPLAY_NOT_SUPPORT: return static_cast<GSError>(err + EOPNOTSUPP);
40         case DISPLAY_NOMEM: return static_cast<GSError>(err + ENOMEM);
41         case DISPLAY_SYS_BUSY: return static_cast<GSError>(err + EBUSY);
42         case 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<DispErrCode>(code));
51 }
52 }
53 
54 static const std::map<uint64_t, uint64_t> bufferUsageConvertMap = {
55     {BUFFER_USAGE_CPU_READ,                    HBM_USE_CPU_READ},
56     {BUFFER_USAGE_CPU_WRITE,                   HBM_USE_CPU_WRITE},
57     {BUFFER_USAGE_MEM_MMZ,                     HBM_USE_MEM_MMZ},
58     {BUFFER_USAGE_MEM_DMA,                     HBM_USE_MEM_DMA},
59     {BUFFER_USAGE_MEM_SHARE,                   HBM_USE_MEM_SHARE},
60     {BUFFER_USAGE_MEM_MMZ_CACHE,               HBM_USE_MEM_MMZ_CACHE},
61     {BUFFER_USAGE_MEM_FB,                      HBM_USE_MEM_FB},
62     {BUFFER_USAGE_ASSIGN_SIZE,                 HBM_USE_ASSIGN_SIZE},
63     {BUFFER_USAGE_HW_RENDER,                   HBM_USE_HW_RENDER},
64     {BUFFER_USAGE_HW_TEXTURE,                  HBM_USE_HW_TEXTURE},
65     {BUFFER_USAGE_HW_COMPOSER,                 HBM_USE_HW_COMPOSER},
66     {BUFFER_USAGE_PROTECTED,                   HBM_USE_PROTECTED},
67     {BUFFER_USAGE_CAMERA_READ,                 HBM_USE_CAMERA_READ},
68     {BUFFER_USAGE_CAMERA_WRITE,                HBM_USE_CAMERA_WRITE},
69     {BUFFER_USAGE_VIDEO_ENCODER,               HBM_USE_VIDEO_ENCODER},
70     {BUFFER_USAGE_VIDEO_DECODER,               HBM_USE_VIDEO_DECODER},
71     {BUFFER_USAGE_VENDOR_PRI0,                 HBM_USE_VENDOR_PRI0},
72     {BUFFER_USAGE_VENDOR_PRI1,                 HBM_USE_VENDOR_PRI1},
73     {BUFFER_USAGE_VENDOR_PRI2,                 HBM_USE_VENDOR_PRI2},
74     {BUFFER_USAGE_VENDOR_PRI3,                 HBM_USE_VENDOR_PRI3},
75     {BUFFER_USAGE_VENDOR_PRI4,                 HBM_USE_VENDOR_PRI4},
76     {BUFFER_USAGE_VENDOR_PRI5,                 HBM_USE_VENDOR_PRI5},
77     {BUFFER_USAGE_VENDOR_PRI6,                 HBM_USE_VENDOR_PRI6},
78     {BUFFER_USAGE_VENDOR_PRI7,                 HBM_USE_VENDOR_PRI7},
79     {BUFFER_USAGE_VENDOR_PRI8,                 HBM_USE_VENDOR_PRI8},
80     {BUFFER_USAGE_VENDOR_PRI9,                 HBM_USE_VENDOR_PRI9},
81     {BUFFER_USAGE_VENDOR_PRI10,                HBM_USE_VENDOR_PRI10},
82     {BUFFER_USAGE_VENDOR_PRI11,                HBM_USE_VENDOR_PRI11},
83     {BUFFER_USAGE_VENDOR_PRI12,                HBM_USE_VENDOR_PRI12},
84     {BUFFER_USAGE_VENDOR_PRI13,                HBM_USE_VENDOR_PRI13},
85     {BUFFER_USAGE_VENDOR_PRI14,                HBM_USE_VENDOR_PRI14},
86     {BUFFER_USAGE_VENDOR_PRI15,                HBM_USE_VENDOR_PRI15},
87     {BUFFER_USAGE_VENDOR_PRI16,                HBM_USE_VENDOR_PRI16},
88     {BUFFER_USAGE_VENDOR_PRI17,                HBM_USE_VENDOR_PRI17},
89     {BUFFER_USAGE_VENDOR_PRI18,                HBM_USE_VENDOR_PRI18},
90     {BUFFER_USAGE_VENDOR_PRI19,                HBM_USE_VENDOR_PRI19},
91 };
92 
93 SurfaceBufferImpl::IDisplayGrallocSptr SurfaceBufferImpl::displayGralloc_ = nullptr;
94 std::mutex SurfaceBufferImpl::displayGrallocMutex_;
95 
DisplayGrallocDeathCallback(void * data)96 void SurfaceBufferImpl::DisplayGrallocDeathCallback(void* data)
97 {
98     std::lock_guard<std::mutex> lock(displayGrallocMutex_);
99     displayGralloc_ = nullptr;
100     BLOGD("gralloc_host died and displayGralloc_ is nullptr.");
101 }
102 
GetDisplayGralloc()103 SurfaceBufferImpl::IDisplayGrallocSptr SurfaceBufferImpl::GetDisplayGralloc()
104 {
105     std::lock_guard<std::mutex> lock(displayGrallocMutex_);
106     if (displayGralloc_ != nullptr) {
107         return displayGralloc_;
108     }
109 
110     displayGralloc_.reset(::OHOS::HDI::Display::V1_0::IDisplayGralloc::Get());
111     if (displayGralloc_ == nullptr) {
112         BLOGE("IDisplayGralloc::Get return nullptr.");
113         return nullptr;
114     }
115     displayGralloc_->RegAllocatorDeathCallback(&SurfaceBufferImpl::DisplayGrallocDeathCallback, nullptr);
116     return displayGralloc_;
117 }
118 
SurfaceBufferImpl()119 SurfaceBufferImpl::SurfaceBufferImpl()
120 {
121     {
122         static std::mutex mutex;
123         mutex.lock();
124 
125         static uint32_t sequence_number_ = 0;
126         sequenceNumber_ = sequence_number_++;
127 
128         mutex.unlock();
129     }
130     bedata_ = new BufferExtraDataImpl;
131     BLOGD("ctor +[%{public}u]", sequenceNumber_);
132 }
133 
SurfaceBufferImpl(uint32_t seqNum)134 SurfaceBufferImpl::SurfaceBufferImpl(uint32_t seqNum)
135 {
136     sequenceNumber_ = seqNum;
137     bedata_ = new BufferExtraDataImpl;
138     BLOGD("ctor =[%{public}u]", sequenceNumber_);
139 }
140 
~SurfaceBufferImpl()141 SurfaceBufferImpl::~SurfaceBufferImpl()
142 {
143     BLOGD("dtor ~[%{public}u] handle_ %{public}p", sequenceNumber_, handle_);
144     FreeBufferHandleLocked();
145 }
146 
FromBase(const sptr<SurfaceBuffer> & buffer)147 SurfaceBufferImpl *SurfaceBufferImpl::FromBase(const sptr<SurfaceBuffer>& buffer)
148 {
149     return static_cast<SurfaceBufferImpl*>(buffer.GetRefPtr());
150 }
151 
Alloc(const BufferRequestConfig & config)152 GSError SurfaceBufferImpl::Alloc(const BufferRequestConfig &config)
153 {
154     if (GetDisplayGralloc() == nullptr) {
155         BLOGE("GetDisplayGralloc failed!");
156         return GSERROR_INTERNAL;
157     }
158 
159     {
160         std::lock_guard<std::mutex> lock(mutex_);
161         if (handle_ != nullptr) {
162             FreeBufferHandleLocked();
163         }
164     }
165 
166     GSError ret = CheckBufferConfig(config.width, config.height, config.format, config.usage);
167     if (ret != GSERROR_OK) {
168         return GSERROR_INVALID_ARGUMENTS;
169     }
170 
171     BufferHandle *handle = nullptr;
172     uint64_t usage = BufferUsageToGrallocUsage(config.usage);
173     AllocInfo info = {config.width, config.height, usage, (PixelFormat)config.format};
174     auto dret = displayGralloc_->AllocMem(info, handle);
175     if (dret == DISPLAY_SUCCESS) {
176         std::lock_guard<std::mutex> lock(mutex_);
177         surfaceBufferColorGamut_ = config.colorGamut;
178         transform_ = config.transform;
179         surfaceBufferWidth_ = config.width;
180         surfaceBufferHeight_ = config.height;
181         handle_ = handle;
182         BLOGD("buffer handle %{public}p w: %{public}d h: %{public}d t: %{public}d", handle_,
183             handle_->width, handle_->height, config.transform);
184         return GSERROR_OK;
185     }
186     BLOGW("Failed with %{public}d", dret);
187     return GenerateError(GSERROR_API_FAILED, dret);
188 }
Map()189 GSError SurfaceBufferImpl::Map()
190 {
191     if (GetDisplayGralloc() == nullptr) {
192         BLOGE("GetDisplayGralloc failed!");
193         return GSERROR_INTERNAL;
194     }
195 
196     BufferHandle *handle = nullptr;
197     {
198         std::lock_guard<std::mutex> lock(mutex_);
199         if (handle_ == nullptr) {
200             BLOGE("handle is nullptr");
201             return GSERROR_INVALID_OPERATING;
202         } else if (handle_->virAddr != nullptr) {
203             BLOGD("handle_->virAddr has been maped");
204             return GSERROR_OK;
205         }
206         handle = handle_;
207     }
208 #ifdef RS_ENABLE_AFBC
209     handle->usage |= (BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA);
210 #endif
211     void *virAddr = displayGralloc_->Mmap(*handle);
212     if (virAddr == nullptr || virAddr == MAP_FAILED) {
213         return GSERROR_API_FAILED;
214     }
215     return GSERROR_OK;
216 }
Unmap()217 GSError SurfaceBufferImpl::Unmap()
218 {
219     if (GetDisplayGralloc() == nullptr) {
220         BLOGE("GetDisplayGralloc failed!");
221         return GSERROR_INTERNAL;
222     }
223     BufferHandle *handle = nullptr;
224     {
225         std::lock_guard<std::mutex> lock(mutex_);
226         if (handle_ == nullptr) {
227             BLOGE("handle is nullptr");
228             return GSERROR_INVALID_OPERATING;
229         } else if (handle_->virAddr == nullptr) {
230             BLOGW("handle has been unmaped");
231             return GSERROR_OK;
232         }
233         handle = handle_;
234     }
235 
236     auto dret = displayGralloc_->Unmap(*handle);
237     if (dret == DISPLAY_SUCCESS) {
238         handle_->virAddr = nullptr;
239         return GSERROR_OK;
240     }
241     BLOGW("Failed with %{public}d", dret);
242     return GenerateError(GSERROR_API_FAILED, dret);
243 }
FlushCache()244 GSError SurfaceBufferImpl::FlushCache()
245 {
246     if (GetDisplayGralloc() == nullptr) {
247         BLOGE("GetDisplayGralloc failed!");
248         return GSERROR_INTERNAL;
249     }
250     BufferHandle *handle = nullptr;
251     {
252         std::lock_guard<std::mutex> lock(mutex_);
253         if (handle_ == nullptr) {
254             BLOGE("handle is nullptr");
255             return GSERROR_INVALID_OPERATING;
256         }
257         handle = handle_;
258     }
259 
260     if (handle->virAddr == nullptr) {
261         return GSERROR_API_FAILED;
262     }
263 
264     auto dret = displayGralloc_->FlushCache(*handle);
265     if (dret == DISPLAY_SUCCESS) {
266         return GSERROR_OK;
267     }
268     BLOGW("Failed with %{public}d", dret);
269     return GenerateError(GSERROR_API_FAILED, dret);
270 }
271 
InvalidateCache()272 GSError SurfaceBufferImpl::InvalidateCache()
273 {
274     if (GetDisplayGralloc() == nullptr) {
275         BLOGE("GetDisplayGralloc failed!");
276         return GSERROR_INTERNAL;
277     }
278     BufferHandle *handle = nullptr;
279     {
280         std::lock_guard<std::mutex> lock(mutex_);
281         if (handle_ == nullptr) {
282             BLOGE("handle is nullptr");
283             return GSERROR_INVALID_OPERATING;
284         }
285         handle = handle_;
286     }
287 
288     auto dret = displayGralloc_->InvalidateCache(*handle);
289     if (dret == DISPLAY_SUCCESS) {
290         return GSERROR_OK;
291     }
292     BLOGW("Failed with %{public}d", dret);
293     return GenerateError(GSERROR_API_FAILED, dret);
294 }
295 
FreeBufferHandleLocked()296 void SurfaceBufferImpl::FreeBufferHandleLocked()
297 {
298     if (handle_) {
299         if (handle_->virAddr != nullptr && displayGralloc_ != nullptr) {
300             displayGralloc_->Unmap(*handle_);
301             handle_->virAddr = nullptr;
302         }
303         FreeBufferHandle(handle_);
304     }
305     handle_ = nullptr;
306 }
307 
GetBufferHandle() const308 BufferHandle *SurfaceBufferImpl::GetBufferHandle() const
309 {
310     std::lock_guard<std::mutex> lock(mutex_);
311     return handle_;
312 }
313 
SetSurfaceBufferColorGamut(const GraphicColorGamut & colorGamut)314 void SurfaceBufferImpl::SetSurfaceBufferColorGamut(const GraphicColorGamut& colorGamut)
315 {
316     std::lock_guard<std::mutex> lock(mutex_);
317     surfaceBufferColorGamut_ = colorGamut;
318 }
319 
GetSurfaceBufferColorGamut() const320 const GraphicColorGamut& SurfaceBufferImpl::GetSurfaceBufferColorGamut() const
321 {
322     std::lock_guard<std::mutex> lock(mutex_);
323     return surfaceBufferColorGamut_;
324 }
325 
SetSurfaceBufferTransform(const GraphicTransformType & transform)326 void SurfaceBufferImpl::SetSurfaceBufferTransform(const GraphicTransformType& transform)
327 {
328     std::lock_guard<std::mutex> lock(mutex_);
329     transform_ = transform;
330 }
331 
GetSurfaceBufferTransform() const332 const GraphicTransformType& SurfaceBufferImpl::GetSurfaceBufferTransform() const
333 {
334     std::lock_guard<std::mutex> lock(mutex_);
335     return transform_;
336 }
337 
GetSurfaceBufferWidth() const338 int32_t SurfaceBufferImpl::GetSurfaceBufferWidth() const
339 {
340     std::lock_guard<std::mutex> lock(mutex_);
341     return surfaceBufferWidth_;
342 }
343 
GetSurfaceBufferHeight() const344 int32_t SurfaceBufferImpl::GetSurfaceBufferHeight() const
345 {
346     std::lock_guard<std::mutex> lock(mutex_);
347     return surfaceBufferHeight_;
348 }
349 
SetSurfaceBufferWidth(int32_t width)350 void SurfaceBufferImpl::SetSurfaceBufferWidth(int32_t width)
351 {
352     std::lock_guard<std::mutex> lock(mutex_);
353     surfaceBufferWidth_ = width;
354 }
355 
SetSurfaceBufferHeight(int32_t height)356 void SurfaceBufferImpl::SetSurfaceBufferHeight(int32_t height)
357 {
358     std::lock_guard<std::mutex> lock(mutex_);
359     surfaceBufferHeight_ = height;
360 }
361 
GetWidth() const362 int32_t SurfaceBufferImpl::GetWidth() 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_->width;
370 }
371 
GetHeight() const372 int32_t SurfaceBufferImpl::GetHeight() 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_->height;
380 }
381 
GetStride() const382 int32_t SurfaceBufferImpl::GetStride() 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_->stride;
390 }
391 
GetFormat() const392 int32_t SurfaceBufferImpl::GetFormat() const
393 {
394     std::lock_guard<std::mutex> lock(mutex_);
395     if (handle_ == nullptr) {
396         BLOGE("handle is nullptr");
397         return -1;
398     }
399     return handle_->format;
400 }
401 
GetUsage() const402 uint64_t SurfaceBufferImpl::GetUsage() const
403 {
404     std::lock_guard<std::mutex> lock(mutex_);
405     if (handle_ == nullptr) {
406         BLOGE("handle is nullptr");
407         return -1;
408     }
409     return handle_->usage;
410 }
411 
GetPhyAddr() const412 uint64_t SurfaceBufferImpl::GetPhyAddr() const
413 {
414     std::lock_guard<std::mutex> lock(mutex_);
415     if (handle_ == nullptr) {
416         BLOGE("handle is nullptr");
417         return 0;
418     }
419     return handle_->phyAddr;
420 }
421 
GetKey() const422 int32_t SurfaceBufferImpl::GetKey() const
423 {
424     std::lock_guard<std::mutex> lock(mutex_);
425     if (handle_ == nullptr) {
426         BLOGE("handle is nullptr");
427         return -1;
428     }
429     return handle_->key;
430 }
431 
GetVirAddr()432 void *SurfaceBufferImpl::GetVirAddr()
433 {
434     GSError ret = this->Map();
435     if (ret != GSERROR_OK) {
436         BLOGW("Map failed");
437         return nullptr;
438     }
439     return handle_->virAddr;
440 }
441 
GetFileDescriptor() const442 int32_t SurfaceBufferImpl::GetFileDescriptor() const
443 {
444     std::lock_guard<std::mutex> lock(mutex_);
445     if (handle_ == nullptr) {
446         BLOGE("handle is nullptr");
447         return -1;
448     }
449     return handle_->fd;
450 }
451 
GetSize() const452 uint32_t SurfaceBufferImpl::GetSize() const
453 {
454     std::lock_guard<std::mutex> lock(mutex_);
455     if (handle_ == nullptr) {
456         BLOGW("handle is nullptr");
457         return 0;
458     }
459     return handle_->size;
460 }
461 
SetExtraData(const sptr<BufferExtraData> & bedata)462 void SurfaceBufferImpl::SetExtraData(const sptr<BufferExtraData> &bedata)
463 {
464     std::lock_guard<std::mutex> lock(mutex_);
465     bedata_ = bedata;
466 }
467 
GetExtraData() const468 const sptr<BufferExtraData>& SurfaceBufferImpl::GetExtraData() const
469 {
470     std::lock_guard<std::mutex> lock(mutex_);
471     return bedata_;
472 }
473 
SetBufferHandle(BufferHandle * handle)474 void SurfaceBufferImpl::SetBufferHandle(BufferHandle *handle)
475 {
476     std::lock_guard<std::mutex> lock(mutex_);
477     handle_ = handle;
478 }
479 
WriteToMessageParcel(MessageParcel & parcel)480 GSError SurfaceBufferImpl::WriteToMessageParcel(MessageParcel &parcel)
481 {
482     BufferHandle *handle = nullptr;
483     {
484         std::lock_guard<std::mutex> lock(mutex_);
485         if (handle_ == nullptr) {
486             BLOGE("Failure, Reason: handle_ is nullptr");
487             return GSERROR_NOT_INIT;
488         }
489         handle = handle_;
490     }
491 
492     bool ret = WriteBufferHandle(parcel, *handle);
493     if (ret == false) {
494         BLOGE("Failure, Reason: WriteBufferHandle return false");
495         return GSERROR_API_FAILED;
496     }
497 
498     return GSERROR_OK;
499 }
500 
ReadFromMessageParcel(MessageParcel & parcel)501 GSError SurfaceBufferImpl::ReadFromMessageParcel(MessageParcel &parcel)
502 {
503     std::lock_guard<std::mutex> lock(mutex_);
504     FreeBufferHandleLocked();
505     handle_ = ReadBufferHandle(parcel);
506     if (handle_ == nullptr) {
507         return GSERROR_API_FAILED;
508     }
509 
510     return GSERROR_OK;
511 }
512 
SurfaceBufferToNativeBuffer()513 OH_NativeBuffer* SurfaceBufferImpl::SurfaceBufferToNativeBuffer()
514 {
515     return reinterpret_cast<OH_NativeBuffer *>(this);
516 }
517 
GetSeqNum() const518 uint32_t SurfaceBufferImpl::GetSeqNum() const
519 {
520     return sequenceNumber_;
521 }
522 
GetEglData() const523 sptr<EglData> SurfaceBufferImpl::GetEglData() const
524 {
525     return eglData_;
526 }
527 
SetEglData(const sptr<EglData> & data)528 void SurfaceBufferImpl::SetEglData(const sptr<EglData>& data)
529 {
530     eglData_ = data;
531 }
532 
CheckBufferConfig(int32_t width,int32_t height,int32_t format,uint64_t usage)533 GSError SurfaceBufferImpl::CheckBufferConfig(int32_t width, int32_t height,
534                                              int32_t format, uint64_t usage)
535 {
536     if (width <= 0 || height <= 0) {
537         BLOGE("width or height is greater than 0, now is w %{public}d h %{public}d", width, height);
538         return GSERROR_INVALID_ARGUMENTS;
539     }
540 
541     if (format < 0 || format > GRAPHIC_PIXEL_FMT_BUTT) {
542         BLOGE("format [0, %{public}d], now is %{public}d", GRAPHIC_PIXEL_FMT_BUTT, format);
543         return GSERROR_INVALID_ARGUMENTS;
544     }
545 
546     return GSERROR_OK;
547 }
548 
BufferUsageToGrallocUsage(uint64_t bufferUsage)549 uint64_t SurfaceBufferImpl::BufferUsageToGrallocUsage(uint64_t bufferUsage)
550 {
551     uint64_t grallocUsage = 0;
552     for (auto iter = bufferUsageConvertMap.begin(); iter != bufferUsageConvertMap.end(); iter++) {
553         if (bufferUsage & iter->first) {
554             grallocUsage |= iter->second;
555         }
556     }
557     return grallocUsage;
558 }
559 
GetBufferWrapper()560 BufferWrapper SurfaceBufferImpl::GetBufferWrapper()
561 {
562     BufferWrapper wrapper;
563     return wrapper;
564 }
565 
SetBufferWrapper(BufferWrapper wrapper)566 void SurfaceBufferImpl::SetBufferWrapper(BufferWrapper wrapper) {}
567 } // namespace OHOS
568