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