1 /*
2 * Copyright (c) 2020-2022 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 "buffer_common.h"
19 #include "buffer_manager.h"
20 #include "buffer_queue.h"
21 #include "surface_buffer_impl.h"
22
23 namespace OHOS {
24 const int32_t DEFAULT_IPC_SIZE = 100;
25
26 extern "C" {
27 typedef int32_t (*IpcMsgHandle)(BufferQueueProducer* product, IpcIo *io, IpcIo *reply);
28 };
29
OnRequestBuffer(BufferQueueProducer * product,IpcIo * io,IpcIo * reply)30 static int32_t OnRequestBuffer(BufferQueueProducer* product, IpcIo *io, IpcIo *reply)
31 {
32 uint8_t isWaiting;
33 ReadUint8(io, &isWaiting);
34 SurfaceBufferImpl* buffer = product->RequestBuffer(isWaiting);
35 uint32_t ret = -1;
36 if (buffer == nullptr) {
37 GRAPHIC_LOGW("get buffer failed");
38 WriteInt32(reply, -1);
39 ret = -1;
40 } else {
41 WriteInt32(reply, 0);
42 buffer->WriteToIpcIo(*reply);
43 ret = 0;
44 }
45 return ret;
46 }
47
OnFlushBuffer(BufferQueueProducer * product,IpcIo * io,IpcIo * reply)48 static int32_t OnFlushBuffer(BufferQueueProducer* product, IpcIo *io, IpcIo *reply)
49 {
50 SurfaceBufferImpl buffer;
51 buffer.ReadFromIpcIo(*io);
52 WriteInt32(reply, product->EnqueueBuffer(buffer));
53 return 0;
54 }
55
OnCancelBuffer(BufferQueueProducer * product,IpcIo * io,IpcIo * reply)56 static int32_t OnCancelBuffer(BufferQueueProducer* product, IpcIo *io, IpcIo *reply)
57 {
58 SurfaceBufferImpl buffer;
59 buffer.ReadFromIpcIo(*io);
60 product->Cancel(&buffer);
61 WriteInt32(reply, 0);
62 return 0;
63 }
64
OnGetAttr(uint32_t attr,IpcIo * io,IpcIo * reply)65 static int32_t OnGetAttr(uint32_t attr, IpcIo *io, IpcIo *reply)
66 {
67 WriteInt32(reply, 0);
68 WriteUint32(reply, attr);
69 return 0;
70 }
71
OnSendReply(IpcIo * io,IpcIo * reply)72 static int32_t OnSendReply(IpcIo *io, IpcIo *reply)
73 {
74 WriteInt32(reply, 0);
75 return 0;
76 }
77
OnSetQueueSize(BufferQueueProducer * product,IpcIo * io,IpcIo * reply)78 static int32_t OnSetQueueSize(BufferQueueProducer* product, IpcIo *io, IpcIo *reply)
79 {
80 uint32_t queueSize;
81 ReadUint32(io, &queueSize);
82 product->SetQueueSize(queueSize);
83 return OnSendReply(io, reply);
84 }
85
OnGetQueueSize(BufferQueueProducer * product,IpcIo * io,IpcIo * reply)86 static int32_t OnGetQueueSize(BufferQueueProducer* product, IpcIo *io, IpcIo *reply)
87 {
88 return OnGetAttr(product->GetQueueSize(), io, reply);
89 }
90
OnSetWidthAndHeight(BufferQueueProducer * product,IpcIo * io,IpcIo * reply)91 static int32_t OnSetWidthAndHeight(BufferQueueProducer* product, IpcIo *io, IpcIo *reply)
92 {
93 uint32_t width;
94 ReadUint32(io, &width);
95 uint32_t height;
96 ReadUint32(io, &height);
97 product->SetWidthAndHeight(width, height);
98 return OnSendReply(io, reply);
99 }
100
OnGetWidth(BufferQueueProducer * product,IpcIo * io,IpcIo * reply)101 static int32_t OnGetWidth(BufferQueueProducer* product, IpcIo *io, IpcIo *reply)
102 {
103 return OnGetAttr(product->GetWidth(), io, reply);
104 }
105
OnGetHeight(BufferQueueProducer * product,IpcIo * io,IpcIo * reply)106 static int32_t OnGetHeight(BufferQueueProducer* product, IpcIo *io, IpcIo *reply)
107 {
108 return OnGetAttr(product->GetHeight(), io, reply);
109 }
110
OnSetFormat(BufferQueueProducer * product,IpcIo * io,IpcIo * reply)111 static int32_t OnSetFormat(BufferQueueProducer* product, IpcIo *io, IpcIo *reply)
112 {
113 uint32_t format;
114 ReadUint32(io, &format);
115 product->SetFormat(format);
116 return OnSendReply(io, reply);
117 }
118
OnGetFormat(BufferQueueProducer * product,IpcIo * io,IpcIo * reply)119 static int32_t OnGetFormat(BufferQueueProducer* product, IpcIo *io, IpcIo *reply)
120 {
121 return OnGetAttr(product->GetFormat(), io, reply);
122 }
123
OnSetStrideAlignment(BufferQueueProducer * product,IpcIo * io,IpcIo * reply)124 static int32_t OnSetStrideAlignment(BufferQueueProducer* product, IpcIo *io, IpcIo *reply)
125 {
126 uint32_t strideAlignment;
127 ReadUint32(io, &strideAlignment);
128 product->SetStrideAlignment(strideAlignment);
129 return OnSendReply(io, reply);
130 }
131
GetStrideAlignment(BufferQueueProducer * product,IpcIo * io,IpcIo * reply)132 static int32_t GetStrideAlignment(BufferQueueProducer* product, IpcIo *io, IpcIo *reply)
133 {
134 return OnGetAttr(product->GetStrideAlignment(), io, reply);
135 }
136
OnGetStride(BufferQueueProducer * product,IpcIo * io,IpcIo * reply)137 static int32_t OnGetStride(BufferQueueProducer* product, IpcIo *io, IpcIo *reply)
138 {
139 return OnGetAttr(product->GetStride(), io, reply);
140 }
141
OnSetSize(BufferQueueProducer * product,IpcIo * io,IpcIo * reply)142 static int32_t OnSetSize(BufferQueueProducer* product, IpcIo *io, IpcIo *reply)
143 {
144 uint32_t size;
145 ReadUint32(io, &size);
146 product->SetSize(size);
147 return OnSendReply(io, reply);
148 }
149
OnGetSize(BufferQueueProducer * product,IpcIo * io,IpcIo * reply)150 static int32_t OnGetSize(BufferQueueProducer* product, IpcIo *io, IpcIo *reply)
151 {
152 return OnGetAttr(product->GetSize(), io, reply);
153 }
154
OnSetUsage(BufferQueueProducer * product,IpcIo * io,IpcIo * reply)155 static int32_t OnSetUsage(BufferQueueProducer* product, IpcIo *io, IpcIo *reply)
156 {
157 uint32_t usage;
158 ReadUint32(io, &usage);
159 product->SetUsage(usage);
160 return OnSendReply(io, reply);
161 }
162
OnGetUsage(BufferQueueProducer * product,IpcIo * io,IpcIo * reply)163 static int32_t OnGetUsage(BufferQueueProducer* product, IpcIo *io, IpcIo *reply)
164 {
165 return OnGetAttr(product->GetUsage(), io, reply);
166 }
167
OnSetUserData(BufferQueueProducer * product,IpcIo * io,IpcIo * reply)168 static int32_t OnSetUserData(BufferQueueProducer* product, IpcIo *io, IpcIo *reply)
169 {
170 size_t len = 0;
171 const char* key = reinterpret_cast<char *>(ReadString(io, &len));
172 if (key == nullptr || len == 0) {
173 GRAPHIC_LOGW("Get user data key failed");
174 return -1;
175 }
176 const char* value = reinterpret_cast<char *>(ReadString(io, &len));
177 if (value == nullptr || len == 0) {
178 GRAPHIC_LOGW("Get user data value failed");
179 return -1;
180 }
181 std::string sKey = key;
182 std::string sValue = value;
183 product->SetUserData(sKey, sValue);
184 OnSendReply(io, reply);
185 return 0;
186 }
187
OnGetUserData(BufferQueueProducer * product,IpcIo * io,IpcIo * reply)188 static int32_t OnGetUserData(BufferQueueProducer* product, IpcIo *io, IpcIo *reply)
189 {
190 size_t len = 0;
191 const char* key = reinterpret_cast<char *>(ReadString(io, &len));
192 if (key == nullptr || len == 0) {
193 GRAPHIC_LOGW("Get user data key failed");
194 return -1;
195 }
196 std::string sKey = key;
197 std::string value = product->GetUserData(sKey);
198 WriteString(reply, value.c_str());
199 return 0;
200 }
201
202 static IpcMsgHandle g_ipcMsgHandleList[] = {
203 OnRequestBuffer, // REQUEST_BUFFER
204 OnFlushBuffer, // FLUSH_BUFFER
205 OnCancelBuffer, // CANCEL_BUFFER
206 OnSetQueueSize, // SET_QUEUE_SIZE
207 OnGetQueueSize, // GET_QUEUE_SIZE
208 OnSetWidthAndHeight, // SET_WIDTH_AND_HEIGHT
209 OnGetWidth, // GET_WIDTH
210 OnGetHeight, // GET_HEIGHT
211 OnSetFormat, // SET_FORMAT
212 OnGetFormat, // GET_FORMAT
213 OnSetStrideAlignment, // SET_STRIDE_ALIGNMENT
214 GetStrideAlignment, // GET_STRIDE_ALIGNMENT
215 OnGetStride, // GET_STRIDE
216 OnSetSize, // SET_SIZE
217 OnGetSize, // GET_SIZE
218 OnSetUsage, // SET_USAGE
219 OnGetUsage, // GET_USAGE
220 OnSetUserData, // SET_USER_DATA
221 OnGetUserData, // GET_USER_DATA
222 };
223
BufferQueueProducer(BufferQueue * bufferQueue)224 BufferQueueProducer::BufferQueueProducer(BufferQueue* bufferQueue)
225 : bufferQueue_(bufferQueue),
226 consumerListener_(nullptr)
227 {
228 }
~BufferQueueProducer()229 BufferQueueProducer::~BufferQueueProducer()
230 {
231 consumerListener_ = nullptr;
232 if (bufferQueue_ != nullptr) {
233 delete bufferQueue_;
234 bufferQueue_ = nullptr;
235 }
236 }
237
RequestBuffer(uint8_t wait)238 SurfaceBufferImpl* BufferQueueProducer::RequestBuffer(uint8_t wait)
239 {
240 RETURN_VAL_IF_FAIL(bufferQueue_, nullptr);
241 SurfaceBufferImpl* buffer = bufferQueue_->RequestBuffer(wait);
242 return buffer;
243 }
244
EnqueueBuffer(SurfaceBufferImpl & buffer)245 int32_t BufferQueueProducer::EnqueueBuffer(SurfaceBufferImpl& buffer)
246 {
247 RETURN_VAL_IF_FAIL(bufferQueue_, SURFACE_ERROR_INVALID_PARAM);
248 int32_t ret = bufferQueue_->FlushBuffer(buffer);
249 if (ret == 0) {
250 if (consumerListener_ != nullptr) {
251 consumerListener_->OnBufferAvailable();
252 }
253 }
254 return ret;
255 }
256
FlushBuffer(SurfaceBufferImpl * buffer)257 int32_t BufferQueueProducer::FlushBuffer(SurfaceBufferImpl* buffer)
258 {
259 RETURN_VAL_IF_FAIL(buffer, SURFACE_ERROR_INVALID_PARAM);
260 RETURN_VAL_IF_FAIL(bufferQueue_, SURFACE_ERROR_INVALID_PARAM);
261 BufferManager* manager = BufferManager::GetInstance();
262 RETURN_VAL_IF_FAIL(manager, SURFACE_ERROR_NOT_READY);
263 if (buffer->GetUsage() == BUFFER_CONSUMER_USAGE_HARDWARE_CONSUMER_CACHE) {
264 int32_t ret = manager->FlushCache(*buffer);
265 if (ret != 0) {
266 GRAPHIC_LOGW("Flush buffer failed, ret=%d", ret);
267 return ret;
268 }
269 }
270 return EnqueueBuffer(*buffer);
271 }
272
Cancel(SurfaceBufferImpl * buffer)273 void BufferQueueProducer::Cancel(SurfaceBufferImpl* buffer)
274 {
275 RETURN_IF_FAIL(bufferQueue_);
276 bufferQueue_->CancelBuffer(*buffer);
277 }
278
SetQueueSize(uint8_t queueSize)279 void BufferQueueProducer::SetQueueSize(uint8_t queueSize)
280 {
281 RETURN_IF_FAIL(bufferQueue_);
282 bufferQueue_->SetQueueSize(queueSize);
283 }
284
GetQueueSize()285 uint8_t BufferQueueProducer::GetQueueSize()
286 {
287 RETURN_VAL_IF_FAIL(bufferQueue_, 0);
288 return bufferQueue_->GetQueueSize();
289 }
290
SetWidthAndHeight(uint32_t width,uint32_t height)291 void BufferQueueProducer::SetWidthAndHeight(uint32_t width, uint32_t height)
292 {
293 RETURN_IF_FAIL(bufferQueue_);
294 bufferQueue_->SetWidthAndHeight(width, height);
295 }
296
GetWidth()297 uint32_t BufferQueueProducer::GetWidth()
298 {
299 RETURN_VAL_IF_FAIL(bufferQueue_, 0);
300 return bufferQueue_->GetWidth();
301 }
302
GetHeight()303 uint32_t BufferQueueProducer::GetHeight()
304 {
305 RETURN_VAL_IF_FAIL(bufferQueue_, 0);
306 return bufferQueue_->GetHeight();
307 }
308
SetFormat(uint32_t format)309 void BufferQueueProducer::SetFormat(uint32_t format)
310 {
311 RETURN_IF_FAIL(bufferQueue_);
312 bufferQueue_->SetFormat(format);
313 }
314
GetFormat()315 uint32_t BufferQueueProducer::GetFormat()
316 {
317 RETURN_VAL_IF_FAIL(bufferQueue_, 0);
318 return bufferQueue_->GetFormat();
319 }
320
SetStrideAlignment(uint32_t strideAlignment)321 void BufferQueueProducer::SetStrideAlignment(uint32_t strideAlignment)
322 {
323 RETURN_IF_FAIL(bufferQueue_);
324 bufferQueue_->SetStrideAlignment(strideAlignment);
325 }
326
GetStrideAlignment()327 uint32_t BufferQueueProducer::GetStrideAlignment()
328 {
329 RETURN_VAL_IF_FAIL(bufferQueue_, 0);
330 return bufferQueue_->GetStrideAlignment();
331 }
332
GetStride()333 uint32_t BufferQueueProducer::GetStride()
334 {
335 RETURN_VAL_IF_FAIL(bufferQueue_, 0);
336 return bufferQueue_->GetStride();
337 }
338
SetSize(uint32_t size)339 void BufferQueueProducer::SetSize(uint32_t size)
340 {
341 RETURN_IF_FAIL(bufferQueue_);
342 bufferQueue_->SetSize(size);
343 }
344
GetSize()345 uint32_t BufferQueueProducer::GetSize()
346 {
347 RETURN_VAL_IF_FAIL(bufferQueue_, 0);
348 return bufferQueue_->GetSize();
349 }
350
SetUsage(uint32_t usage)351 void BufferQueueProducer::SetUsage(uint32_t usage)
352 {
353 RETURN_IF_FAIL(bufferQueue_);
354 bufferQueue_->SetUsage(usage);
355 }
356
GetUsage()357 uint32_t BufferQueueProducer::GetUsage()
358 {
359 RETURN_VAL_IF_FAIL(bufferQueue_, 0);
360 return bufferQueue_->GetUsage();
361 }
362
RegisterConsumerListener(IBufferConsumerListener & listener)363 void BufferQueueProducer::RegisterConsumerListener(IBufferConsumerListener& listener)
364 {
365 consumerListener_ = &listener;
366 }
367
UnregisterConsumerListener()368 void BufferQueueProducer::UnregisterConsumerListener()
369 {
370 consumerListener_ = nullptr;
371 }
372
OnIpcMsg(uint32_t code,IpcIo * data,IpcIo * reply,MessageOption option)373 int32_t BufferQueueProducer::OnIpcMsg(uint32_t code, IpcIo *data, IpcIo *reply, MessageOption option)
374 {
375 if (data == NULL) {
376 GRAPHIC_LOGW("Invalid parameter, null pointer");
377 return SURFACE_ERROR_INVALID_PARAM;
378 }
379
380 if (code >= MAX_REQUEST_CODE) {
381 GRAPHIC_LOGW("Resquest code(%u) does not support.", code);
382 return SURFACE_ERROR_INVALID_REQUEST;
383 }
384 return g_ipcMsgHandleList[code](this, data, reply);
385 }
386
SetUserData(const std::string & key,const std::string & value)387 void BufferQueueProducer::SetUserData(const std::string& key, const std::string& value)
388 {
389 bufferQueue_->SetUserData(key, value);
390 }
391
GetUserData(const std::string & key)392 std::string BufferQueueProducer::GetUserData(const std::string& key)
393 {
394 return bufferQueue_->GetUserData(key);
395 }
396 } // end namespace
397