1 /*
2 * Copyright (c) 2020-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_client_producer.h"
17 #include "ipc_skeleton.h"
18
19 #include "buffer_common.h"
20 #include "buffer_manager.h"
21 #include "buffer_queue.h"
22 #include "surface_buffer_impl.h"
23
24 namespace OHOS {
25 const int32_t DEFAULT_IPC_SIZE = 200;
BufferClientProducer(const SvcIdentity & sid)26 BufferClientProducer::BufferClientProducer(const SvcIdentity& sid) : sid_(sid)
27 {
28 }
29
~BufferClientProducer()30 BufferClientProducer::~BufferClientProducer()
31 {
32 }
33
RequestBuffer(uint8_t wait)34 SurfaceBufferImpl* BufferClientProducer::RequestBuffer(uint8_t wait)
35 {
36 IpcIo requestIo;
37 uint8_t requestIoData[DEFAULT_IPC_SIZE];
38 IpcIoInit(&requestIo, requestIoData, DEFAULT_IPC_SIZE, 0);
39 WriteUint8(&requestIo, wait);
40 IpcIo reply;
41 uintptr_t ptr;
42 MessageOption option;
43 MessageOptionInit(&option);
44 int32_t ret = SendRequest(sid_, REQUEST_BUFFER, &requestIo, &reply, option, &ptr);
45 if (ret != 0) {
46 GRAPHIC_LOGW("RequestBuffer SendRequest failed");
47 return nullptr;
48 }
49 ReadInt32(&reply, &ret);
50 if (ret != 0) {
51 GRAPHIC_LOGW("RequestBuffer generic failed code=%d", ret);
52 FreeBuffer(reinterpret_cast<void *>(ptr));
53 return nullptr;
54 }
55
56 SurfaceBufferImpl* buffer = new SurfaceBufferImpl();
57 buffer->ReadFromIpcIo(reply);
58 BufferManager* manager = BufferManager::GetInstance();
59 if (manager == nullptr) {
60 GRAPHIC_LOGW("BufferManager is null, usage(%d)", buffer->GetUsage());
61 delete buffer;
62 FreeBuffer(reinterpret_cast<void *>(ptr));
63 return nullptr;
64 }
65
66 if (!manager->MapBuffer(*buffer)) {
67 Cancel(buffer);
68 FreeBuffer(reinterpret_cast<void *>(ptr));
69 return nullptr;
70 }
71 FreeBuffer(reinterpret_cast<void *>(ptr));
72 return buffer;
73 }
74
FlushBuffer(SurfaceBufferImpl * buffer)75 int32_t BufferClientProducer::FlushBuffer(SurfaceBufferImpl* buffer)
76 {
77 RETURN_VAL_IF_FAIL(buffer, -1);
78 BufferManager* manager = BufferManager::GetInstance();
79 RETURN_VAL_IF_FAIL(manager, -1);
80 int32_t ret = SURFACE_ERROR_OK;
81 if (buffer->GetUsage() == BUFFER_CONSUMER_USAGE_HARDWARE_PRODUCER_CACHE) {
82 ret = manager->FlushCache(*buffer);
83 if (ret != SURFACE_ERROR_OK) {
84 GRAPHIC_LOGW("Flush buffer failed, ret=%d", ret);
85 return ret;
86 }
87 }
88 IpcIo requestIo;
89 uint8_t requestIoData[DEFAULT_IPC_SIZE];
90 IpcIoInit(&requestIo, requestIoData, DEFAULT_IPC_SIZE, 0);
91 buffer->WriteToIpcIo(requestIo);
92 IpcIo reply;
93 uintptr_t ptr;
94 MessageOption option;
95 MessageOptionInit(&option);
96 ret = SendRequest(sid_, FLUSH_BUFFER, &requestIo, &reply, option, &ptr);
97 if (ret != SURFACE_ERROR_OK) {
98 GRAPHIC_LOGW("FlushBuffer failed");
99 return ret;
100 }
101 ReadInt32(&reply, &ret);
102 FreeBuffer(reinterpret_cast<void *>(ptr));
103 if (ret != SURFACE_ERROR_OK) {
104 GRAPHIC_LOGW("FlushBuffer failed code=%d", ret);
105 return -1;
106 }
107 manager->UnmapBuffer(*buffer);
108 delete buffer;
109 return ret;
110 }
111
Cancel(SurfaceBufferImpl * buffer)112 void BufferClientProducer::Cancel(SurfaceBufferImpl* buffer)
113 {
114 if (buffer == nullptr) {
115 return;
116 }
117 IpcIo requestIo;
118 uint8_t requestIoData[DEFAULT_IPC_SIZE];
119 IpcIoInit(&requestIo, requestIoData, DEFAULT_IPC_SIZE, 0);
120 buffer->WriteToIpcIo(requestIo);
121 IpcIo reply;
122 uintptr_t ptr;
123 MessageOption option;
124 MessageOptionInit(&option);
125 int32_t ret = SendRequest(sid_, CANCEL_BUFFER, &requestIo, &reply, option, &ptr);
126 if (ret != SURFACE_ERROR_OK) {
127 GRAPHIC_LOGW("Cancel buffer failed");
128 } else {
129 FreeBuffer(reinterpret_cast<void *>(ptr));
130 }
131 BufferManager* manager = BufferManager::GetInstance();
132 RETURN_IF_FAIL(manager);
133 manager->UnmapBuffer(*buffer);
134 delete buffer;
135 }
136
SetQueueSize(uint8_t queueSize)137 void BufferClientProducer::SetQueueSize(uint8_t queueSize)
138 {
139 IpcIo requestIo;
140 uint8_t requestIoData[DEFAULT_IPC_SIZE];
141 IpcIoInit(&requestIo, requestIoData, DEFAULT_IPC_SIZE, 0);
142 WriteUint8(&requestIo, queueSize);
143 IpcIo reply;
144 uintptr_t ptr;
145 MessageOption option;
146 MessageOptionInit(&option);
147 int32_t ret = SendRequest(sid_, SET_QUEUE_SIZE, &requestIo, &reply, option, &ptr);
148 if (ret != SURFACE_ERROR_OK) {
149 GRAPHIC_LOGW("Set Attr(%d:%u) failed", SET_QUEUE_SIZE, queueSize);
150 }
151 FreeBuffer(reinterpret_cast<void *>(ptr));
152 }
153
GetQueueSize()154 uint8_t BufferClientProducer::GetQueueSize()
155 {
156 IpcIo requestIo;
157 uint8_t requestIoData[DEFAULT_IPC_SIZE];
158 IpcIoInit(&requestIo, requestIoData, DEFAULT_IPC_SIZE, 0);
159 IpcIo reply;
160 uintptr_t ptr;
161 MessageOption option;
162 MessageOptionInit(&option);
163 int32_t ret = SendRequest(sid_, GET_QUEUE_SIZE, &requestIo, &reply, option, &ptr);
164 if (ret != SURFACE_ERROR_OK) {
165 GRAPHIC_LOGW("GetAttr SendRequest failed, errno=%d", ret);
166 return 0;
167 }
168 ReadInt32(&reply, &ret);
169 if (ret != SURFACE_ERROR_OK) {
170 GRAPHIC_LOGW("GetAttr failed code=%d", GET_QUEUE_SIZE);
171 FreeBuffer(reinterpret_cast<void *>(ptr));
172 return 0;
173 }
174 uint8_t queueSize;
175 ReadUint8(&reply, &queueSize);
176 FreeBuffer(reinterpret_cast<void *>(ptr));
177 return queueSize;
178 }
179
SetWidthAndHeight(uint32_t width,uint32_t height)180 void BufferClientProducer::SetWidthAndHeight(uint32_t width, uint32_t height)
181 {
182 IpcIo requestIo;
183 uint8_t requestIoData[DEFAULT_IPC_SIZE];
184 IpcIoInit(&requestIo, requestIoData, DEFAULT_IPC_SIZE, 0);
185 WriteUint32(&requestIo, width);
186 WriteUint32(&requestIo, height);
187 IpcIo reply;
188 uintptr_t ptr;
189 MessageOption option;
190 MessageOptionInit(&option);
191 int32_t ret = SendRequest(sid_, SET_WIDTH_AND_HEIGHT, &requestIo, &reply, option, &ptr);
192 if (ret != SURFACE_ERROR_OK) {
193 GRAPHIC_LOGW("SetWidthAndHeight failed");
194 } else {
195 FreeBuffer(reinterpret_cast<void *>(ptr));
196 }
197 return;
198 }
199
GetWidth()200 uint32_t BufferClientProducer::GetWidth()
201 {
202 return GetAttr(GET_WIDTH);
203 }
204
GetHeight()205 uint32_t BufferClientProducer::GetHeight()
206 {
207 return GetAttr(GET_HEIGHT);
208 }
209
SetFormat(uint32_t format)210 void BufferClientProducer::SetFormat(uint32_t format)
211 {
212 SetAttr(SET_FORMAT, format);
213 }
214
GetFormat()215 uint32_t BufferClientProducer::GetFormat()
216 {
217 return GetAttr(GET_FORMAT);
218 }
219
SetStrideAlignment(uint32_t strideAlignment)220 void BufferClientProducer::SetStrideAlignment(uint32_t strideAlignment)
221 {
222 SetAttr(SET_STRIDE_ALIGNMENT, strideAlignment);
223 }
224
GetStrideAlignment()225 uint32_t BufferClientProducer::GetStrideAlignment()
226 {
227 return GetAttr(GET_STRIDE_ALIGNMENT);
228 }
229
GetStride()230 uint32_t BufferClientProducer::GetStride()
231 {
232 return GetAttr(GET_STRIDE);
233 }
234
SetSize(uint32_t size)235 void BufferClientProducer::SetSize(uint32_t size)
236 {
237 SetAttr(SET_SIZE, size);
238 }
239
GetSize()240 uint32_t BufferClientProducer::GetSize()
241 {
242 return GetAttr(GET_SIZE);
243 }
244
SetUsage(uint32_t usage)245 void BufferClientProducer::SetUsage(uint32_t usage)
246 {
247 SetAttr(SET_USAGE, usage);
248 }
249
GetUsage()250 uint32_t BufferClientProducer::GetUsage()
251 {
252 uint32_t usage = GetAttr(GET_USAGE);
253 return usage;
254 }
255
SetUserData(const std::string & key,const std::string & value)256 void BufferClientProducer::SetUserData(const std::string& key, const std::string& value)
257 {
258 IpcIo requestIo;
259 uint8_t requestIoData[DEFAULT_IPC_SIZE];
260 IpcIoInit(&requestIo, requestIoData, DEFAULT_IPC_SIZE, 0);
261 WriteString(&requestIo, key.c_str());
262 WriteString(&requestIo, value.c_str());
263 IpcIo reply;
264 uintptr_t ptr;
265 MessageOption option;
266 MessageOptionInit(&option);
267 int32_t ret = SendRequest(sid_, SET_USER_DATA, &requestIo, &reply, option, &ptr);
268 if (ret != SURFACE_ERROR_OK) {
269 GRAPHIC_LOGW("Get user data(%s) failed", key.c_str());
270 } else {
271 FreeBuffer(reinterpret_cast<void *>(ptr));
272 }
273 }
274
GetUserData(const std::string & key)275 std::string BufferClientProducer::GetUserData(const std::string& key)
276 {
277 std::string sValue = std::string();
278 IpcIo requestIo;
279 uint8_t requestIoData[DEFAULT_IPC_SIZE];
280 IpcIoInit(&requestIo, requestIoData, DEFAULT_IPC_SIZE, 0);
281 WriteString(&requestIo, key.c_str());
282 IpcIo reply;
283 uintptr_t ptr;
284 MessageOption option;
285 MessageOptionInit(&option);
286 int32_t ret = SendRequest(sid_, GET_USER_DATA, &requestIo, &reply, option, &ptr);
287 if (ret != SURFACE_ERROR_OK) {
288 return sValue;
289 } else {
290 size_t len = 0;
291 const char* value = reinterpret_cast<char *>(ReadString(&reply, &len));
292 if (value == nullptr || len == 0) {
293 GRAPHIC_LOGW("Get user data failed");
294 } else {
295 sValue = value;
296 }
297 FreeBuffer(reinterpret_cast<void *>(ptr));
298 return sValue;
299 }
300 }
301
SetAttr(uint32_t code,uint32_t value)302 void BufferClientProducer::SetAttr(uint32_t code, uint32_t value)
303 {
304 IpcIo requestIo;
305 uint8_t requestIoData[DEFAULT_IPC_SIZE];
306 IpcIoInit(&requestIo, requestIoData, DEFAULT_IPC_SIZE, 0);
307 WriteUint32(&requestIo, value);
308 IpcIo reply;
309 uintptr_t ptr;
310 MessageOption option;
311 MessageOptionInit(&option);
312 int32_t ret = SendRequest(sid_, code, &requestIo, &reply, option, &ptr);
313 if (ret != SURFACE_ERROR_OK) {
314 GRAPHIC_LOGW("Set Attr(%u:%u) failed", code, value);
315 } else {
316 FreeBuffer(reinterpret_cast<void *>(ptr));
317 }
318 }
319
GetAttr(uint32_t code)320 uint32_t BufferClientProducer::GetAttr(uint32_t code)
321 {
322 IpcIo requestIo;
323 uint8_t requestIoData[DEFAULT_IPC_SIZE];
324 IpcIoInit(&requestIo, requestIoData, DEFAULT_IPC_SIZE, 0);
325 IpcIo reply;
326 uintptr_t ptr;
327 MessageOption option;
328 MessageOptionInit(&option);
329 int32_t ret = SendRequest(sid_, code, &requestIo, &reply, option, &ptr);
330 if (ret != SURFACE_ERROR_OK) {
331 GRAPHIC_LOGW("GetAttr SendRequest failed, errno=%d", ret);
332 return 0;
333 }
334 ReadInt32(&reply, &ret);
335 if (ret != SURFACE_ERROR_OK) {
336 GRAPHIC_LOGW("GetAttr failed code=%d", code);
337 FreeBuffer(reinterpret_cast<void *>(ptr));
338 return 0;
339 }
340 uint32_t attr;
341 ReadUint32(&reply, &attr);
342 FreeBuffer(reinterpret_cast<void *>(ptr));
343 return attr;
344 }
345 } // end namespace
346