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