• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "buffer_queue_producer.h"
17 
18 #include <mutex>
19 #include <set>
20 
21 #include "buffer_extra_data_impl.h"
22 #include "buffer_log.h"
23 #include "buffer_manager.h"
24 #include "buffer_utils.h"
25 
26 namespace OHOS {
BufferQueueProducer(sptr<BufferQueue> & bufferQueue)27 BufferQueueProducer::BufferQueueProducer(sptr<BufferQueue>& bufferQueue)
28 {
29     bufferQueue_ = bufferQueue;
30     if (bufferQueue_ != nullptr) {
31         bufferQueue_->GetName(name_);
32     }
33     BLOGNI("ctor");
34 
35     memberFuncMap_[BUFFER_PRODUCER_REQUEST_BUFFER] = &BufferQueueProducer::RequestBufferRemote;
36     memberFuncMap_[BUFFER_PRODUCER_CANCEL_BUFFER] = &BufferQueueProducer::CancelBufferRemote;
37     memberFuncMap_[BUFFER_PRODUCER_FLUSH_BUFFER] = &BufferQueueProducer::FlushBufferRemote;
38     memberFuncMap_[BUFFER_PRODUCER_ATTACH_BUFFER] = &BufferQueueProducer::AttachBufferRemote;
39     memberFuncMap_[BUFFER_PRODUCER_DETACH_BUFFER] = &BufferQueueProducer::DetachBufferRemote;
40     memberFuncMap_[BUFFER_PRODUCER_GET_QUEUE_SIZE] = &BufferQueueProducer::GetQueueSizeRemote;
41     memberFuncMap_[BUFFER_PRODUCER_SET_QUEUE_SIZE] = &BufferQueueProducer::SetQueueSizeRemote;
42     memberFuncMap_[BUFFER_PRODUCER_GET_NAME] = &BufferQueueProducer::GetNameRemote;
43     memberFuncMap_[BUFFER_PRODUCER_GET_DEFAULT_WIDTH] = &BufferQueueProducer::GetDefaultWidthRemote;
44     memberFuncMap_[BUFFER_PRODUCER_GET_DEFAULT_HEIGHT] = &BufferQueueProducer::GetDefaultHeightRemote;
45     memberFuncMap_[BUFFER_PRODUCER_GET_DEFAULT_USAGE] = &BufferQueueProducer::GetDefaultUsageRemote;
46     memberFuncMap_[BUFFER_PRODUCER_GET_UNIQUE_ID] = &BufferQueueProducer::GetUniqueIdRemote;
47     memberFuncMap_[BUFFER_PRODUCER_CLEAN_CACHE] = &BufferQueueProducer::CleanCacheRemote;
48     memberFuncMap_[BUFFER_PRODUCER_REGISTER_RELEASE_LISTENER] = &BufferQueueProducer::RegisterReleaseListenerRemote;
49 }
50 
~BufferQueueProducer()51 BufferQueueProducer::~BufferQueueProducer()
52 {
53     BLOGNI("dtor");
54 }
55 
OnRemoteRequest(uint32_t code,MessageParcel & arguments,MessageParcel & reply,MessageOption & option)56 int BufferQueueProducer::OnRemoteRequest(uint32_t code, MessageParcel &arguments,
57                                          MessageParcel &reply, MessageOption &option)
58 {
59     auto it = memberFuncMap_.find(code);
60     if (it == memberFuncMap_.end()) {
61         BLOGN_FAILURE("cannot process %{public}u", code);
62         return 0;
63     }
64 
65     if (it->second == nullptr) {
66         BLOGN_FAILURE("memberFuncMap_[%{public}u] is nullptr", code);
67         return 0;
68     }
69 
70     auto remoteDescriptor = arguments.ReadInterfaceToken();
71     if (GetDescriptor() != remoteDescriptor) {
72         return ERR_INVALID_STATE;
73     }
74 
75     auto ret = (this->*(it->second))(arguments, reply, option);
76     return ret;
77 }
78 
RequestBufferRemote(MessageParcel & arguments,MessageParcel & reply,MessageOption & option)79 int32_t BufferQueueProducer::RequestBufferRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option)
80 {
81     RequestBufferReturnValue retval;
82     BufferExtraDataImpl bedataimpl;
83     BufferRequestConfig config = {};
84 
85     ReadRequestConfig(arguments, config);
86 
87     GSError sret = RequestBuffer(config, bedataimpl, retval);
88 
89     reply.WriteInt32(sret);
90     if (sret == GSERROR_OK) {
91         WriteSurfaceBufferImpl(reply, retval.sequence, retval.buffer);
92         bedataimpl.WriteToParcel(reply);
93         WriteFence(reply, retval.fence);
94         reply.WriteInt32Vector(retval.deletingBuffers);
95     }
96     return 0;
97 }
98 
CancelBufferRemote(MessageParcel & arguments,MessageParcel & reply,MessageOption & option)99 int BufferQueueProducer::CancelBufferRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option)
100 {
101     int32_t sequence;
102     BufferExtraDataImpl bedataimpl;
103 
104     sequence = arguments.ReadInt32();
105     bedataimpl.ReadFromParcel(arguments);
106 
107     GSError sret = CancelBuffer(sequence, bedataimpl);
108     reply.WriteInt32(sret);
109     return 0;
110 }
111 
FlushBufferRemote(MessageParcel & arguments,MessageParcel & reply,MessageOption & option)112 int BufferQueueProducer::FlushBufferRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option)
113 {
114     int32_t fence;
115     int32_t sequence;
116     BufferFlushConfig config;
117     BufferExtraDataImpl bedataimpl;
118 
119     sequence = arguments.ReadInt32();
120     bedataimpl.ReadFromParcel(arguments);
121     ReadFence(arguments, fence);
122     ReadFlushConfig(arguments, config);
123 
124     GSError sret = FlushBuffer(sequence, bedataimpl, fence, config);
125 
126     reply.WriteInt32(sret);
127     return 0;
128 }
129 
AttachBufferRemote(MessageParcel & arguments,MessageParcel & reply,MessageOption & option)130 int32_t BufferQueueProducer::AttachBufferRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option)
131 {
132     BLOGNE("BufferQueueProducer::AttachBufferRemote not support remote");
133     return 0;
134 }
135 
DetachBufferRemote(MessageParcel & arguments,MessageParcel & reply,MessageOption & option)136 int32_t BufferQueueProducer::DetachBufferRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option)
137 {
138     BLOGNE("BufferQueueProducer::DetachBufferRemote not support remote");
139     return 0;
140 }
141 
GetQueueSizeRemote(MessageParcel & arguments,MessageParcel & reply,MessageOption & option)142 int BufferQueueProducer::GetQueueSizeRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option)
143 {
144     reply.WriteInt32(GetQueueSize());
145     return 0;
146 }
147 
SetQueueSizeRemote(MessageParcel & arguments,MessageParcel & reply,MessageOption & option)148 int BufferQueueProducer::SetQueueSizeRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option)
149 {
150     int32_t queueSize = arguments.ReadInt32();
151     GSError sret = SetQueueSize(queueSize);
152     reply.WriteInt32(sret);
153     return 0;
154 }
155 
GetNameRemote(MessageParcel & arguments,MessageParcel & reply,MessageOption & option)156 int BufferQueueProducer::GetNameRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option)
157 {
158     std::string name;
159     auto sret = bufferQueue_->GetName(name);
160     reply.WriteInt32(sret);
161     if (sret == GSERROR_OK) {
162         reply.WriteString(name);
163     }
164     return 0;
165 }
166 
GetDefaultWidthRemote(MessageParcel & arguments,MessageParcel & reply,MessageOption & option)167 int BufferQueueProducer::GetDefaultWidthRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option)
168 {
169     reply.WriteInt32(GetDefaultWidth());
170     return 0;
171 }
172 
GetDefaultHeightRemote(MessageParcel & arguments,MessageParcel & reply,MessageOption & option)173 int BufferQueueProducer::GetDefaultHeightRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option)
174 {
175     reply.WriteInt32(GetDefaultHeight());
176     return 0;
177 }
178 
GetDefaultUsageRemote(MessageParcel & arguments,MessageParcel & reply,MessageOption & option)179 int BufferQueueProducer::GetDefaultUsageRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option)
180 {
181     reply.WriteUint32(GetDefaultUsage());
182     return 0;
183 }
184 
GetUniqueIdRemote(MessageParcel & arguments,MessageParcel & reply,MessageOption & option)185 int BufferQueueProducer::GetUniqueIdRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option)
186 {
187     reply.WriteUint64(GetUniqueId());
188     return 0;
189 }
190 
CleanCacheRemote(MessageParcel & arguments,MessageParcel & reply,MessageOption & option)191 int BufferQueueProducer::CleanCacheRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option)
192 {
193     reply.WriteInt32(CleanCache());
194     return 0;
195 }
196 
RegisterReleaseListenerRemote(MessageParcel & arguments,MessageParcel & reply,MessageOption & option)197 int32_t BufferQueueProducer::RegisterReleaseListenerRemote(MessageParcel &arguments,
198     MessageParcel &reply, MessageOption &option)
199 {
200     BLOGNE("BufferQueueProducer::RegisterReleaseListenerRemote not support remote");
201     return 0;
202 }
203 
RequestBuffer(const BufferRequestConfig & config,BufferExtraData & bedata,RequestBufferReturnValue & retval)204 GSError BufferQueueProducer::RequestBuffer(const BufferRequestConfig &config, BufferExtraData &bedata,
205                                            RequestBufferReturnValue &retval)
206 {
207     static std::map<int32_t, wptr<SurfaceBuffer>> cache;
208     static std::map<pid_t, std::set<int32_t>> sendeds;
209     static std::mutex mutex;
210     if (bufferQueue_ == nullptr) {
211         return GSERROR_INVALID_ARGUMENTS;
212     }
213 
214     auto sret = bufferQueue_->RequestBuffer(config, bedata, retval);
215 
216     std::lock_guard<std::mutex> lock(mutex);
217     auto callingPid = GetCallingPid();
218     auto &sended = sendeds[callingPid];
219     if (sret == GSERROR_OK) {
220         if (retval.buffer != nullptr) {
221             cache[retval.sequence] = retval.buffer;
222             sended.insert(retval.sequence);
223         } else if (callingPid == getpid()) {
224             // for BufferQueue not first
225             // A local call always returns a non-null pointer
226             retval.buffer = cache[retval.sequence].promote();
227         } else if (sended.find(retval.sequence) == sended.end()) {
228             // The first remote call from a different process returns a non-null pointer
229             retval.buffer = cache[retval.sequence].promote();
230             sended.insert(retval.sequence);
231         }
232     } else {
233         BLOGNI("BufferQueue::RequestBuffer failed with %{public}s", GSErrorStr(sret).c_str());
234     }
235 
236     for (const auto &buffer : retval.deletingBuffers) {
237         cache.erase(buffer);
238         sended.erase(buffer);
239     }
240     return sret;
241 }
242 
CancelBuffer(int32_t sequence,BufferExtraData & bedata)243 GSError BufferQueueProducer::CancelBuffer(int32_t sequence, BufferExtraData &bedata)
244 {
245     if (bufferQueue_ == nullptr) {
246         return GSERROR_INVALID_ARGUMENTS;
247     }
248     return bufferQueue_->CancelBuffer(sequence, bedata);
249 }
250 
FlushBuffer(int32_t sequence,BufferExtraData & bedata,int32_t fence,BufferFlushConfig & config)251 GSError BufferQueueProducer::FlushBuffer(int32_t sequence, BufferExtraData &bedata,
252                                          int32_t fence, BufferFlushConfig &config)
253 {
254     if (bufferQueue_ == nullptr) {
255         return GSERROR_INVALID_ARGUMENTS;
256     }
257     return bufferQueue_->FlushBuffer(sequence, bedata, fence, config);
258 }
259 
AttachBuffer(sptr<SurfaceBuffer> & buffer)260 GSError BufferQueueProducer::AttachBuffer(sptr<SurfaceBuffer>& buffer)
261 {
262     if (bufferQueue_ == nullptr) {
263         return GSERROR_INVALID_ARGUMENTS;
264     }
265     sptr<SurfaceBufferImpl> bufferImpl = SurfaceBufferImpl::FromBase(buffer);
266     return bufferQueue_->AttachBuffer(bufferImpl);
267 }
268 
DetachBuffer(sptr<SurfaceBuffer> & buffer)269 GSError BufferQueueProducer::DetachBuffer(sptr<SurfaceBuffer>& buffer)
270 {
271     if (bufferQueue_ == nullptr) {
272         return GSERROR_INVALID_ARGUMENTS;
273     }
274     sptr<SurfaceBufferImpl> bufferImpl = SurfaceBufferImpl::FromBase(buffer);
275     return bufferQueue_->DetachBuffer(bufferImpl);
276 }
277 
GetQueueSize()278 uint32_t BufferQueueProducer::GetQueueSize()
279 {
280     if (bufferQueue_ == nullptr) {
281         return 0;
282     }
283     return bufferQueue_->GetQueueSize();
284 }
285 
SetQueueSize(uint32_t queueSize)286 GSError BufferQueueProducer::SetQueueSize(uint32_t queueSize)
287 {
288     if (bufferQueue_ == nullptr) {
289         return GSERROR_INVALID_ARGUMENTS;
290     }
291     return bufferQueue_->SetQueueSize(queueSize);
292 }
293 
GetName(std::string & name)294 GSError BufferQueueProducer::GetName(std::string &name)
295 {
296     if (bufferQueue_ == nullptr) {
297         return GSERROR_INVALID_ARGUMENTS;
298     }
299     return bufferQueue_->GetName(name);
300 }
301 
GetDefaultWidth()302 int32_t BufferQueueProducer::GetDefaultWidth()
303 {
304     if (bufferQueue_ == nullptr) {
305         return 0;
306     }
307     return bufferQueue_->GetDefaultWidth();
308 }
309 
GetDefaultHeight()310 int32_t BufferQueueProducer::GetDefaultHeight()
311 {
312     if (bufferQueue_ == nullptr) {
313         return 0;
314     }
315     return bufferQueue_->GetDefaultHeight();
316 }
317 
GetDefaultUsage()318 uint32_t BufferQueueProducer::GetDefaultUsage()
319 {
320     if (bufferQueue_ == nullptr) {
321         return 0;
322     }
323     return bufferQueue_->GetDefaultUsage();
324 }
325 
GetUniqueId()326 uint64_t BufferQueueProducer::GetUniqueId()
327 {
328     if (bufferQueue_ == nullptr) {
329         return 0;
330     }
331     return bufferQueue_->GetUniqueId();
332 }
333 
CleanCache()334 GSError BufferQueueProducer::CleanCache()
335 {
336     if (bufferQueue_ == nullptr) {
337         return GSERROR_INVALID_ARGUMENTS;
338     }
339     return bufferQueue_->CleanCache();
340 }
341 
RegisterReleaseListener(OnReleaseFunc func)342 GSError BufferQueueProducer::RegisterReleaseListener(OnReleaseFunc func)
343 {
344     if (bufferQueue_ == nullptr) {
345         return GSERROR_INVALID_ARGUMENTS;
346     }
347     return bufferQueue_->RegisterReleaseListener(func);
348 }
349 }; // namespace OHOS
350