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 return ashmem_ != nullptr ? ashmem_->GetAshmemSize() : INVALID_FD;
47 }
48
CopyFrom(uint8_t * address,int64_t bytes)49 int32_t SharedBuffer::CopyFrom(uint8_t* address, int64_t bytes)
50 {
51 DP_CHECK_ERROR_RETURN_RET_LOG(bytes > capacity_, DP_INVALID_PARAM,
52 "buffer failed due to invalid size: %{public}" PRId64 ", capacity: %{public}" PRId64, bytes, capacity_);
53 DP_CHECK_ERROR_RETURN_RET_LOG(ashmem_ == nullptr, DP_INIT_FAIL, "ashmem is nullptr.");
54 DP_DEBUG_LOG("capacity: %{public}" PRId64 ", bytes: %{public}" PRId64, capacity_, bytes);
55 auto ret = ashmem_->WriteToAshmem(address, bytes, 0);
56 DP_CHECK_ERROR_RETURN_RET_LOG(!ret, DP_ERR, "copy failed.");
57 return DP_OK;
58 }
59
Reset()60 void SharedBuffer::Reset()
61 {
62 auto offset = lseek(GetFd(), 0, SEEK_SET);
63 DP_CHECK_ERROR_PRINT_LOG(offset != DP_OK, "failed to reset, error = %{public}s.", std::strerror(errno));
64 DP_INFO_LOG("reset success.");
65 }
66
AllocateAshmemUnlocked()67 int32_t SharedBuffer::AllocateAshmemUnlocked()
68 {
69 std::string_view name = "DPS ShareMemory";
70 ashmem_ = Ashmem::CreateAshmem(name.data(), capacity_);
71 DP_CHECK_ERROR_RETURN_RET_LOG(ashmem_ == nullptr, DP_INIT_FAIL,
72 "buffer create ashmem failed. capacity: %{public}" PRId64, capacity_);
73 int fd = ashmem_->GetAshmemFd();
74 DP_DEBUG_LOG("size: %{public}" PRId64 ", fd: %{public}d", capacity_, fd);
75 auto ret = ashmem_->MapReadAndWriteAshmem();
76 DP_CHECK_ERROR_RETURN_RET_LOG(!ret, DP_MEM_MAP_FAILED, "mmap failed.");
77 return DP_OK;
78 }
79
DeallocAshmem()80 void SharedBuffer::DeallocAshmem()
81 {
82 DP_CHECK_RETURN(ashmem_ == nullptr);
83 ashmem_->UnmapAshmem();
84 ashmem_->CloseAshmem();
85 ashmem_ = nullptr;
86 DP_DEBUG_LOG("dealloc ashmem capacity(%{public}" PRId64 ") success.", capacity_);
87 }
88
GetFd() const89 int SharedBuffer::GetFd() const
90 {
91 return ashmem_ != nullptr ? ashmem_->GetAshmemFd() : INVALID_FD;
92 }
93 // LCOV_EXCL_STOP
94 } // namespace DeferredProcessing
95 } // namespace CameraStandard
96 } // namespace OHOS
97