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