1 /*
2  * Copyright (c) 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 #ifndef OHOS_HDI_DISPLAY_V1_0_DISPLAY_BUFFER_HDI_IMPL_H
17 #define OHOS_HDI_DISPLAY_V1_0_DISPLAY_BUFFER_HDI_IMPL_H
18 
19 #include <iremote_object.h>
20 #include <iproxy_broker.h>
21 #include <unistd.h>
22 #include "hdf_log.h"
23 #include "hilog/log.h"
24 #include "buffer_handle.h"
25 #include "v1_0/display_buffer_type.h"
26 #include "v1_0/iallocator.h"
27 #include "v1_0/imapper.h"
28 #include "v1_0/include/idisplay_buffer.h"
29 
30 #undef LOG_TAG
31 #define LOG_TAG "DISP_HDI_BUFF"
32 #undef LOG_DOMAIN
33 #define LOG_DOMAIN 0xD002515
34 
35 #ifndef BUFFER_HDI_IMPL_LOGE
36 #define BUFFER_HDI_IMPL_LOGE(format, ...)              \
37     do {                                               \
38         HDF_LOGE(                                      \
39             "\033[0;32;31m"                            \
40             "[%{public}s:%{public}d] " format "\033[m" \
41             "\n",                                      \
42             __FUNCTION__, __LINE__, ##__VA_ARGS__);    \
43     } while (0)
44 #endif
45 
46 #ifndef CHECK_NULLPOINTER_RETURN_VALUE
47 #define CHECK_NULLPOINTER_RETURN_VALUE(pointer, ret)                  \
48     do {                                                              \
49         if ((pointer) == NULL) {                                      \
50             BUFFER_HDI_IMPL_LOGE("pointer is null and return ret\n"); \
51             return (ret);                                             \
52         }                                                             \
53     } while (0)
54 #endif
55 
56 #ifndef CHECK_NULLPOINTER_RETURN
57 #define CHECK_NULLPOINTER_RETURN(pointer)                             \
58     do {                                                              \
59         if ((pointer) == NULL) {                                      \
60             BUFFER_HDI_IMPL_LOGE("pointer is null and return\n");     \
61             return;                                                   \
62         }                                                             \
63     } while (0)
64 #endif
65 
66 namespace OHOS {
67 namespace HDI {
68 namespace Display {
69 namespace Buffer {
70 namespace V1_0 {
71 
72 template<typename Interface>
73 class DisplayBufferHdiImpl : public Interface {
74 public:
75     explicit DisplayBufferHdiImpl(bool isAllocLocal = false) : allocator_(nullptr),
76         mapper_(nullptr), recipient_(nullptr)
77     {
78         while ((allocator_ = IAllocator::Get(isAllocLocal)) == nullptr) {
79             // Waiting for allocator service ready
80             usleep(WAIT_TIME_INTERVAL);
81         }
82         while ((mapper_ = IMapper::Get(true)) == nullptr) {
83             // Waiting for mapper IF ready
84             usleep(WAIT_TIME_INTERVAL);
85         }
86     }
~DisplayBufferHdiImpl()87     virtual ~DisplayBufferHdiImpl()
88     {
89         if (recipient_ != nullptr) {
90             sptr<IRemoteObject> remoteObj = OHOS::HDI::hdi_objcast<IAllocator>(allocator_);
91             remoteObj->RemoveDeathRecipient(recipient_);
92             recipient_ = nullptr;
93         }
94     }
95 
AddDeathRecipient(const sptr<IRemoteObject::DeathRecipient> & recipient)96     bool AddDeathRecipient(const sptr<IRemoteObject::DeathRecipient>& recipient) override
97     {
98         sptr<IRemoteObject> remoteObj = OHOS::HDI::hdi_objcast<IAllocator>(allocator_);
99         if (recipient_ != nullptr) {
100             HDF_LOGE("%{public}s: the existing recipient is removed, and add the new. %{public}d",
101                 __func__, __LINE__);
102             remoteObj->RemoveDeathRecipient(recipient_);
103         }
104         bool ret = remoteObj->AddDeathRecipient(recipient);
105         if (ret) {
106             recipient_ = recipient;
107         } else {
108             recipient_ = nullptr;
109             HDF_LOGE("%{public}s: AddDeathRecipient failed %{public}d", __func__, __LINE__);
110         }
111         return ret;
112     }
113 
RemoveDeathRecipient()114     bool RemoveDeathRecipient() override
115     {
116         if (recipient_ != nullptr) {
117             sptr<IRemoteObject> remoteObj = OHOS::HDI::hdi_objcast<IAllocator>(allocator_);
118             remoteObj->RemoveDeathRecipient(recipient_);
119             recipient_ = nullptr;
120         }
121         return true;
122     }
123 
AllocMem(const AllocInfo & info,BufferHandle * & handle)124     int32_t AllocMem(const AllocInfo& info, BufferHandle*& handle) const override
125     {
126         CHECK_NULLPOINTER_RETURN_VALUE(allocator_, HDF_FAILURE);
127         sptr<NativeBuffer> hdiBuffer;
128         int32_t ret = allocator_->AllocMem(info, hdiBuffer);
129         if ((ret == HDF_SUCCESS) && (hdiBuffer != nullptr)) {
130             handle = hdiBuffer->Move();
131         } else {
132             handle = nullptr;
133             if (ret == HDF_SUCCESS) {
134                 ret = HDF_FAILURE;
135             }
136             HDF_LOGE("%{public}s: AllocMem error", __func__);
137         }
138         return ret;
139     }
140 
FreeMem(const BufferHandle & handle)141     void FreeMem(const BufferHandle& handle) const override
142     {
143         CHECK_NULLPOINTER_RETURN(mapper_);
144         sptr<NativeBuffer> hdiBuffer = new NativeBuffer();
145         CHECK_NULLPOINTER_RETURN(hdiBuffer);
146         hdiBuffer->SetBufferHandle(const_cast<BufferHandle*>(&handle), true);
147         mapper_->FreeMem(hdiBuffer);
148     }
149 
Mmap(const BufferHandle & handle)150     void *Mmap(const BufferHandle& handle) const override
151     {
152         CHECK_NULLPOINTER_RETURN_VALUE(mapper_, nullptr);
153         sptr<NativeBuffer> hdiBuffer = new NativeBuffer();
154         CHECK_NULLPOINTER_RETURN_VALUE(hdiBuffer, nullptr);
155         hdiBuffer->SetBufferHandle(const_cast<BufferHandle*>(&handle));
156         int32_t ret = mapper_->Mmap(hdiBuffer);
157         void *virAddr = (ret == HDF_SUCCESS ? handle.virAddr : nullptr);
158         return virAddr;
159     }
160 
Unmap(const BufferHandle & handle)161     int32_t Unmap(const BufferHandle& handle) const override
162     {
163         CHECK_NULLPOINTER_RETURN_VALUE(mapper_, HDF_FAILURE);
164         sptr<NativeBuffer> hdiBuffer = new NativeBuffer();
165         CHECK_NULLPOINTER_RETURN_VALUE(hdiBuffer, HDF_FAILURE);
166         hdiBuffer->SetBufferHandle(const_cast<BufferHandle*>(&handle));
167         int32_t ret = mapper_->Unmap(hdiBuffer);
168         return ret;
169     }
170 
FlushCache(const BufferHandle & handle)171     int32_t FlushCache(const BufferHandle& handle) const override
172     {
173         CHECK_NULLPOINTER_RETURN_VALUE(mapper_, HDF_FAILURE);
174         sptr<NativeBuffer> hdiBuffer = new NativeBuffer();
175         CHECK_NULLPOINTER_RETURN_VALUE(hdiBuffer, HDF_FAILURE);
176         hdiBuffer->SetBufferHandle(const_cast<BufferHandle*>(&handle));
177         int32_t ret = mapper_->FlushCache(hdiBuffer);
178         return ret;
179     }
180 
InvalidateCache(const BufferHandle & handle)181     int32_t InvalidateCache(const BufferHandle& handle) const override
182     {
183         CHECK_NULLPOINTER_RETURN_VALUE(mapper_, HDF_FAILURE);
184         sptr<NativeBuffer> hdiBuffer = new NativeBuffer();
185         CHECK_NULLPOINTER_RETURN_VALUE(hdiBuffer, HDF_FAILURE);
186         hdiBuffer->SetBufferHandle(const_cast<BufferHandle*>(&handle));
187         int32_t ret = mapper_->InvalidateCache(hdiBuffer);
188         return ret;
189     }
190 
IsSupportedAlloc(const std::vector<VerifyAllocInfo> & infos,std::vector<bool> & supporteds)191     int32_t IsSupportedAlloc(const std::vector<VerifyAllocInfo>& infos,
192         std::vector<bool>& supporteds) const override
193     {
194         (void)infos;
195         (void)supporteds;
196         return HDF_ERR_NOT_SUPPORT;
197     }
198 
199 protected:
200     static constexpr uint32_t WAIT_TIME_INTERVAL = 10000;
201     sptr<IAllocator> allocator_;
202     sptr<IMapper> mapper_;
203     sptr<IRemoteObject::DeathRecipient> recipient_;
204 };
205 using HdiDisplayBufferImpl = DisplayBufferHdiImpl<V1_0::IDisplayBuffer>;
206 } // namespace V1_0
207 } // namespace Buffer
208 } // namespace Display
209 } // namespace HDI
210 } // namespace OHOS
211 
212 #endif // OHOS_HDI_DISPLAY_V1_0_DISPLAY_BUFFER_HDI_IMPL_H
213