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