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