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