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