1 /*
2 * Copyright (c) 2023-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 "shared_buffer.h"
17
18 #include <cerrno>
19 #include <unistd.h>
20
21 #include "dp_log.h"
22
23 namespace OHOS {
24 namespace CameraStandard {
25 namespace DeferredProcessing {
26 // LCOV_EXCL_START
SharedBuffer(int64_t capacity)27 SharedBuffer::SharedBuffer(int64_t capacity)
28 : capacity_(capacity)
29 {
30 DP_DEBUG_LOG("entered, capacity = %{public}" PRId64, capacity_);
31 }
32
~SharedBuffer()33 SharedBuffer::~SharedBuffer()
34 {
35 DP_DEBUG_LOG("entered.");
36 DeallocAshmem();
37 }
38
Initialize()39 int32_t SharedBuffer::Initialize()
40 {
41 return AllocateAshmemUnlocked();
42 }
43
GetSize()44 int64_t SharedBuffer::GetSize()
45 {
46 if (ashmem_ != nullptr) {
47 return ashmem_->GetAshmemSize();
48 }
49 return INVALID_FD;
50 }
51
CopyFrom(uint8_t * address,int64_t bytes)52 int32_t SharedBuffer::CopyFrom(uint8_t* address, int64_t bytes)
53 {
54 DP_CHECK_ERROR_RETURN_RET_LOG(bytes > capacity_, DP_INVALID_PARAM,
55 "buffer failed due to invalid size: %{public}" PRId64 ", capacity: %{public}" PRId64, bytes, capacity_);
56 DP_CHECK_ERROR_RETURN_RET_LOG(ashmem_ == nullptr, DP_INIT_FAIL, "ashmem is nullptr.");
57 DP_DEBUG_LOG("capacity: %{public}" PRId64 ", bytes: %{public}" PRId64, capacity_, bytes);
58 auto ret = ashmem_->WriteToAshmem(address, bytes, 0);
59 DP_CHECK_ERROR_RETURN_RET_LOG(!ret, DP_ERR, "copy failed.");
60 return DP_OK;
61 }
62
Reset()63 void SharedBuffer::Reset()
64 {
65 auto offset = lseek(GetFd(), 0, SEEK_SET);
66 DP_CHECK_ERROR_PRINT_LOG(offset != DP_OK, "failed to reset, error = %{public}s.", std::strerror(errno));
67 DP_INFO_LOG("reset success.");
68 }
69
AllocateAshmemUnlocked()70 int32_t SharedBuffer::AllocateAshmemUnlocked()
71 {
72 std::string_view name = "DPS ShareMemory";
73 ashmem_ = Ashmem::CreateAshmem(name.data(), capacity_);
74 DP_CHECK_ERROR_RETURN_RET_LOG(ashmem_ == nullptr, DP_INIT_FAIL,
75 "buffer create ashmem failed. capacity: %{public}" PRId64, capacity_);
76 int fd = ashmem_->GetAshmemFd();
77 DP_DEBUG_LOG("size: %{public}" PRId64 ", fd: %{public}d", capacity_, fd);
78 auto ret = ashmem_->MapReadAndWriteAshmem();
79 DP_CHECK_ERROR_RETURN_RET_LOG(!ret, DP_MEM_MAP_FAILED, "mmap failed.");
80 return DP_OK;
81 }
82
DeallocAshmem()83 void SharedBuffer::DeallocAshmem()
84 {
85 if (ashmem_ != nullptr) {
86 ashmem_->UnmapAshmem();
87 ashmem_->CloseAshmem();
88 ashmem_ = nullptr;
89 DP_DEBUG_LOG("dealloc ashmem capacity(%{public}" PRId64 ") success.", capacity_);
90 }
91 }
92
GetFd() const93 int SharedBuffer::GetFd() const
94 {
95 if (ashmem_ != nullptr) {
96 return ashmem_->GetAshmemFd();
97 }
98 return INVALID_FD;
99 }
100 // LCOV_EXCL_STOP
101 } // namespace DeferredProcessing
102 } // namespace CameraStandard
103 } // namespace OHOS
104