1 /*
2  * Copyright (c) 2023 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 #ifndef OHOS_HDI_DISPLAY_V1_0_DISPLAY_CMD_REQUESTER_H
17 #define OHOS_HDI_DISPLAY_V1_0_DISPLAY_CMD_REQUESTER_H
18 
19 #include <unordered_map>
20 #include "base/hdi_smq.h"
21 #include "command_pack/command_data_packer.h"
22 #include "command_pack/command_data_unpacker.h"
23 #include "common/include/display_interface_utils.h"
24 #include "display_cmd_utils.h"
25 #include "hdifd_parcelable.h"
26 #include "hdf_log.h"
27 #include "v1_0/display_composer_type.h"
28 #include "v1_0/idisplay_composer.h"
29 
30 namespace OHOS {
31 namespace HDI {
32 namespace Display {
33 namespace Composer {
34 namespace V1_0 {
35 using namespace OHOS::HDI::Base;
36 using namespace OHOS::HDI::Display::Composer::V1_0;
37 
38 template <typename Transfer, typename CompHdi>
39 class DisplayCmdRequester {
40 public:
DisplayCmdRequester(sptr<CompHdi> hdi)41     DisplayCmdRequester(sptr<CompHdi> hdi)
42         : initFlag_(false),
43         hdi_(hdi),
44         request_(nullptr),
45         reply_(nullptr)
46     {
47     }
48 
Create(sptr<CompHdi> hdi)49     static std::unique_ptr<DisplayCmdRequester> Create(sptr<CompHdi> hdi)
50     {
51         DISPLAY_CHK_RETURN(hdi == nullptr, nullptr, HDF_LOGE("%{public}s: hdi is nullptr", __func__));
52         auto requester = std::make_unique<DisplayCmdRequester>(hdi);
53         DISPLAY_CHK_RETURN(requester == nullptr, nullptr,
54             HDF_LOGE("%{public}s: CmdRequester is nullptr", __func__));
55         auto ret = requester->Init(CmdUtils::INIT_ELEMENT_COUNT);
56         if (ret != HDF_SUCCESS) {
57             HDF_LOGE("DisplayCmdRequester init failed");
58             return nullptr;
59         }
60         return requester;
61     }
62 
Init(uint32_t eleCnt)63     int32_t Init(uint32_t eleCnt)
64     {
65         request_ = std::make_shared<Transfer>(eleCnt, SmqType::SYNCED_SMQ);
66         DISPLAY_CHK_RETURN(request_ == nullptr, HDF_FAILURE,
67             HDF_LOGE("%{public}s: request_ is nullptr", __func__));
68 
69         DISPLAY_CHK_RETURN(hdi_ == nullptr, HDF_FAILURE,
70             HDF_LOGE("%{public}s: hdi_ is nullptr", __func__));
71 
72         int32_t ret = hdi_->InitCmdRequest(request_);
73         DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret,
74             HDF_LOGE("%{public}s: InitCmdRequest failure, ret=%{public}d", __func__, ret));
75 
76         if (requestPacker_.Init(request_->GetSize() << CmdUtils::MOVE_SIZE) == false) {
77             HDF_LOGE("%{public}s: requestPacker init failed", __func__);
78             return HDF_FAILURE;
79         }
80 
81         ret = hdi_->GetCmdReply(reply_);
82         DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret,
83             HDF_LOGE("%{public}s: GetCmdReply failure, ret=%{public}d", __func__, ret));
84         initFlag_ = true;
85 
86         ret = CmdUtils::StartPack(CONTROL_CMD_REQUEST_BEGIN, requestPacker_);
87         DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret,
88             HDF_LOGE("%{public}s: StartPack failed", __func__));
89 
90         return HDF_SUCCESS;
91     }
92 
PrepareDisplayLayers(uint32_t devId,bool & needFlushFb)93     int32_t PrepareDisplayLayers(uint32_t devId, bool &needFlushFb)
94     {
95         uint32_t replyEleCnt;
96         std::vector<HdifdInfo> outFds;
97         std::shared_ptr<char> replyData;
98 
99         int32_t ret = CmdUtils::StartSection(REQUEST_CMD_PREPARE_DISPLAY_LAYERS, requestPacker_);
100         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
101 
102         ret = requestPacker_.WriteUint32(devId) ? HDF_SUCCESS : HDF_FAILURE;
103         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
104 
105         ret = CmdUtils::EndSection(requestPacker_);
106         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
107 
108         ret = CmdUtils::EndPack(requestPacker_);
109         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
110 
111         ret = DoRequest(replyEleCnt, outFds, replyData);
112         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
113 
114         ret = DoReplyResults(replyEleCnt, outFds, replyData, [&](void *data) -> int32_t {
115             needFlushFb = *(reinterpret_cast<bool *>(data));
116             return HDF_SUCCESS;
117         });
118         if (ret != HDF_SUCCESS) {
119             HDF_LOGE("DoReplyResults failure, ret=%{public}d", ret);
120         }
121 
122 EXIT:
123         return PeriodDataReset() == HDF_SUCCESS ? ret : HDF_FAILURE;
124     }
125 
SetDisplayClientBuffer(uint32_t devId,const BufferHandle * buffer,uint32_t seqNo,int32_t fence)126     int32_t SetDisplayClientBuffer(uint32_t devId, const BufferHandle* buffer, uint32_t seqNo,
127         int32_t fence)
128     {
129         int32_t ret = 0;
130         bool retBool = false;
131         int32_t writePos = requestPacker_.ValidSize();
132 
133         do {
134             ret = CmdUtils::StartSection(REQUEST_CMD_SET_DISPLAY_CLIENT_BUFFER, requestPacker_);
135             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
136                 HDF_LOGE("%{public}s: StartSection failed", __func__));
137 
138             retBool = requestPacker_.WriteUint32(devId);
139             DISPLAY_CHK_BREAK(retBool == false,
140                 HDF_LOGE("%{public}s: write devId failed", __func__));
141 
142             ret = CmdUtils::BufferHandlePack(buffer, requestPacker_, requestHdiFds_);
143             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
144                 HDF_LOGE("%{public}s: BufferHandlePack failed", __func__));
145 
146             retBool = requestPacker_.WriteUint32(seqNo);
147             DISPLAY_CHK_BREAK(retBool == false,
148                 HDF_LOGE("%{public}s: write seqNo failed", __func__));
149 
150             ret = CmdUtils::FileDescriptorPack(fence, requestPacker_, requestHdiFds_);
151             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
152                 HDF_LOGE("%{public}s: FileDescriptorPack failed", __func__));
153 
154             ret = CmdUtils::EndSection(requestPacker_);
155             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
156                 HDF_LOGE("%{public}s: EndSection failed", __func__));
157         } while (0);
158 
159         if (retBool == false || ret != HDF_SUCCESS) {
160             requestPacker_.RollBack(writePos);
161             HDF_LOGE("%{public}s: writePos_ rollback", __func__);
162             return HDF_FAILURE;
163         }
164         return HDF_SUCCESS;
165     }
166 
SetDisplayClientDamage(uint32_t devId,std::vector<IRect> & rects)167     int32_t SetDisplayClientDamage(uint32_t devId, std::vector<IRect> &rects)
168     {
169         int32_t ret = 0;
170         bool retBool = false;
171         int32_t writePos = requestPacker_.ValidSize();
172 
173         do {
174             ret = CmdUtils::StartSection(REQUEST_CMD_SET_DISPLAY_CLIENT_DAMAGE, requestPacker_);
175             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
176                 HDF_LOGE("%{public}s: StartSection failed", __func__));
177 
178             ret = requestPacker_.WriteUint32(devId) ? HDF_SUCCESS : HDF_FAILURE;
179             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
180                 HDF_LOGE("%{public}s: write devId failed", __func__));
181 
182             uint32_t vectSize = static_cast<uint32_t>(rects.size());
183             retBool = requestPacker_.WriteUint32(vectSize);
184             DISPLAY_CHK_BREAK(retBool == false,
185                 HDF_LOGE("%{public}s: write damage vector size failed", __func__));
186 
187             for (uint32_t i = 0; i < vectSize; i++) {
188                 ret = CmdUtils::RectPack(rects[i], requestPacker_);
189                 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
190                     HDF_LOGE("%{public}s: RectPack failed", __func__));
191             }
192             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
193                 HDF_LOGE("%{public}s: RectPack failed, break!", __func__));
194 
195             ret = CmdUtils::EndSection(requestPacker_);
196             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
197                 HDF_LOGE("%{public}s: EndSection failed", __func__));
198         } while (0);
199 
200         if (retBool == false || ret != HDF_SUCCESS) {
201             requestPacker_.RollBack(writePos);
202             HDF_LOGE("%{public}s: writePos_ rollback", __func__);
203             return HDF_FAILURE;
204         }
205         return HDF_SUCCESS;
206     }
207 
Commit(uint32_t devId,int32_t & fence)208     int32_t Commit(uint32_t devId, int32_t &fence)
209     {
210         uint32_t replyEleCnt = 0;
211         std::vector<HdifdInfo> outFds;
212         std::shared_ptr<char> replyData;
213 
214         int32_t ret = CmdUtils::StartSection(REQUEST_CMD_COMMIT, requestPacker_);
215         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
216 
217         ret = requestPacker_.WriteUint32(devId) ? HDF_SUCCESS : HDF_FAILURE;
218         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
219 
220         ret = CmdUtils::EndSection(requestPacker_);
221         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
222 
223         ret = CmdUtils::EndPack(requestPacker_);
224         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
225 
226         ret = DoRequest(replyEleCnt, outFds, replyData);
227         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
228 
229         ret = DoReplyResults(replyEleCnt, outFds, replyData, [&](void *data) -> int32_t {
230             fence = *(reinterpret_cast<int32_t *>(data));
231             return HDF_SUCCESS;
232         });
233         if (ret != HDF_SUCCESS) {
234             HDF_LOGE("DoReplyResults failure, ret=%{public}d", ret);
235         }
236 
237 EXIT:
238         return PeriodDataReset() == HDF_SUCCESS ? ret : HDF_FAILURE;
239     }
240 
SetLayerAlpha(uint32_t devId,uint32_t layerId,const LayerAlpha & alpha)241     int32_t SetLayerAlpha(uint32_t devId, uint32_t layerId, const LayerAlpha &alpha)
242     {
243         int32_t ret = 0;
244         bool retBool = false;
245         int32_t writePos = requestPacker_.ValidSize();
246 
247         do {
248             ret = CmdUtils::StartSection(REQUEST_CMD_SET_LAYER_ALPHA, requestPacker_);
249             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
250                 HDF_LOGE("%{public}s: StartSection failed", __func__));
251 
252             ret = CmdUtils::SetupDevice(devId, layerId, requestPacker_);
253             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
254                 HDF_LOGE("%{public}s: write devId failed", __func__));
255 
256             retBool = requestPacker_.WriteBool(alpha.enGlobalAlpha);
257             DISPLAY_CHK_BREAK(retBool == false,
258                 HDF_LOGE("%{public}s: write enGlobalAlpha failed", __func__));
259 
260             retBool = requestPacker_.WriteBool(alpha.enPixelAlpha);
261             DISPLAY_CHK_BREAK(retBool == false,
262                 HDF_LOGE("%{public}s: write enPixelAlpha failed", __func__));
263 
264             retBool = requestPacker_.WriteUint8(alpha.alpha0);
265             DISPLAY_CHK_BREAK(retBool == false,
266                 HDF_LOGE("%{public}s: write alpha0 failed", __func__));
267 
268             retBool = requestPacker_.WriteUint8(alpha.alpha1);
269             DISPLAY_CHK_BREAK(retBool == false,
270                 HDF_LOGE("%{public}s: write alpha1 failed", __func__));
271 
272             retBool = requestPacker_.WriteUint8(alpha.gAlpha);
273             DISPLAY_CHK_BREAK(retBool == false,
274                 HDF_LOGE("%{public}s: write gAlpha failed", __func__));
275 
276             ret = CmdUtils::EndSection(requestPacker_);
277             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
278                 HDF_LOGE("%{public}s: EndSection failed", __func__));
279         } while (0);
280 
281         if (retBool == false || ret != HDF_SUCCESS) {
282             requestPacker_.RollBack(writePos);
283             HDF_LOGE("%{public}s: writePos_ rollback", __func__);
284             return HDF_FAILURE;
285         }
286         return HDF_SUCCESS;
287     }
288 
SetLayerRegion(uint32_t devId,uint32_t layerId,const IRect & rect)289     int32_t SetLayerRegion(uint32_t devId, uint32_t layerId, const IRect &rect)
290     {
291         int32_t ret = 0;
292         int32_t writePos = requestPacker_.ValidSize();
293 
294         do {
295             ret = CmdUtils::StartSection(REQUEST_CMD_SET_LAYER_REGION, requestPacker_);
296             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
297                 HDF_LOGE("%{public}s: StartSection failed", __func__));
298 
299             ret = CmdUtils::SetupDevice(devId, layerId, requestPacker_);
300             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
301                 HDF_LOGE("%{public}s: SetupDevice failed", __func__));
302 
303             ret = CmdUtils::RectPack(rect, requestPacker_);
304             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
305                 HDF_LOGE("%{public}s: RectPack failed", __func__));
306 
307             ret = CmdUtils::EndSection(requestPacker_);
308             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
309                 HDF_LOGE("%{public}s: EndSection failed", __func__));
310         } while (0);
311 
312         if (ret != HDF_SUCCESS) {
313             requestPacker_.RollBack(writePos);
314             HDF_LOGE("%{public}s: writePos_ rollback", __func__);
315             return HDF_FAILURE;
316         }
317         return HDF_SUCCESS;
318     }
319 
SetLayerCrop(uint32_t devId,uint32_t layerId,const IRect & rect)320     int32_t SetLayerCrop(uint32_t devId, uint32_t layerId, const IRect &rect)
321     {
322         int32_t ret = 0;
323         int32_t writePos = requestPacker_.ValidSize();
324 
325         do {
326             ret = CmdUtils::StartSection(REQUEST_CMD_SET_LAYER_CROP, requestPacker_);
327             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
328                 HDF_LOGE("%{public}s: StartSection failed", __func__));
329 
330             ret = CmdUtils::SetupDevice(devId, layerId, requestPacker_);
331             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
332                 HDF_LOGE("%{public}s: SetupDevice failed", __func__));
333 
334             ret = CmdUtils::RectPack(rect, requestPacker_);
335             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
336                 HDF_LOGE("%{public}s: RectPack failed", __func__));
337 
338             ret = CmdUtils::EndSection(requestPacker_);
339             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
340                 HDF_LOGE("%{public}s: EndSection failed", __func__));
341         } while (0);
342 
343         if (ret != HDF_SUCCESS) {
344             requestPacker_.RollBack(writePos);
345             HDF_LOGE("%{public}s: writePos_ rollback", __func__);
346             return HDF_FAILURE;
347         }
348         return HDF_SUCCESS;
349     }
350 
SetLayerZorder(uint32_t devId,uint32_t layerId,uint32_t zorder)351     int32_t SetLayerZorder(uint32_t devId, uint32_t layerId, uint32_t zorder)
352     {
353         int32_t ret = 0;
354         bool retBool = false;
355         int32_t writePos = requestPacker_.ValidSize();
356 
357         do {
358             ret = CmdUtils::StartSection(REQUEST_CMD_SET_LAYER_ZORDER, requestPacker_);
359             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
360                 HDF_LOGE("%{public}s: StartSection failed", __func__));
361 
362             ret = CmdUtils::SetupDevice(devId, layerId, requestPacker_);
363             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
364                 HDF_LOGE("%{public}s: SetupDevice failed", __func__));
365 
366             retBool = requestPacker_.WriteUint32(zorder);
367             DISPLAY_CHK_BREAK(retBool == false,
368                 HDF_LOGE("%{public}s: write zorder failed", __func__));
369 
370             ret = CmdUtils::EndSection(requestPacker_);
371             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
372                 HDF_LOGE("%{public}s: EndSection failed", __func__));
373         } while (0);
374 
375         if (retBool == false || ret != HDF_SUCCESS) {
376             requestPacker_.RollBack(writePos);
377             HDF_LOGE("%{public}s: writePos_ rollback", __func__);
378             return HDF_FAILURE;
379         }
380         return HDF_SUCCESS;
381     }
382 
SetLayerPreMulti(uint32_t devId,uint32_t layerId,bool preMul)383     int32_t SetLayerPreMulti(uint32_t devId, uint32_t layerId, bool preMul)
384     {
385         int32_t ret = 0;
386         bool retBool = false;
387         int32_t writePos = requestPacker_.ValidSize();
388 
389         do {
390             ret = CmdUtils::StartSection(REQUEST_CMD_SET_LAYER_PREMULTI, requestPacker_);
391             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
392                 HDF_LOGE("%{public}s: StartSection failed", __func__));
393 
394             ret = CmdUtils::SetupDevice(devId, layerId, requestPacker_);
395             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
396                 HDF_LOGE("%{public}s: SetupDevice failed", __func__));
397 
398             retBool = requestPacker_.WriteBool(preMul);
399             DISPLAY_CHK_BREAK(retBool == false,
400                 HDF_LOGE("%{public}s: write preMul failed", __func__));
401 
402             ret = CmdUtils::EndSection(requestPacker_);
403             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
404                 HDF_LOGE("%{public}s: EndSection failed", __func__));
405         } while (0);
406 
407         if (retBool == false || ret != HDF_SUCCESS) {
408             requestPacker_.RollBack(writePos);
409             HDF_LOGE("%{public}s: writePos_ rollback", __func__);
410             return HDF_FAILURE;
411         }
412 
413         return HDF_SUCCESS;
414     }
415 
SetLayerTransformMode(uint32_t devId,uint32_t layerId,TransformType type)416     int32_t SetLayerTransformMode(uint32_t devId, uint32_t layerId, TransformType type)
417     {
418         int32_t ret = 0;
419         bool retBool = false;
420         int32_t writePos = requestPacker_.ValidSize();
421 
422         do {
423             ret = CmdUtils::StartSection(REQUEST_CMD_SET_LAYER_TRANSFORM_MODE, requestPacker_);
424             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
425                 HDF_LOGE("%{public}s: StartSection failed", __func__));
426 
427             ret = CmdUtils::SetupDevice(devId, layerId, requestPacker_);
428             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
429                 HDF_LOGE("%{public}s: SetupDevice failed", __func__));
430 
431             retBool = requestPacker_.WriteInt32(type);
432             DISPLAY_CHK_BREAK(retBool == false,
433                 HDF_LOGE("%{public}s: write transform-type failed", __func__));
434 
435             ret = CmdUtils::EndSection(requestPacker_);
436             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
437                 HDF_LOGE("%{public}s: EndSection failed", __func__));
438         } while (0);
439 
440         if (retBool == false || ret != HDF_SUCCESS) {
441             requestPacker_.RollBack(writePos);
442             HDF_LOGE("%{public}s: writePos_ rollback", __func__);
443             return HDF_FAILURE;
444         }
445         return HDF_SUCCESS;
446     }
447 
SetLayerDirtyRegion(uint32_t devId,uint32_t layerId,const std::vector<IRect> & rects)448     int32_t SetLayerDirtyRegion(uint32_t devId, uint32_t layerId, const std::vector<IRect> &rects)
449     {
450         int32_t ret = 0;
451         bool retBool = false;
452         int32_t writePos = requestPacker_.ValidSize();
453 
454         do {
455             ret = CmdUtils::StartSection(REQUEST_CMD_SET_LAYER_DIRTY_REGION, requestPacker_);
456             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
457                 HDF_LOGE("%{public}s: StartSection failed", __func__));
458 
459             ret = CmdUtils::SetupDevice(devId, layerId, requestPacker_);
460             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
461                 HDF_LOGE("%{public}s: SetupDevice failed", __func__));
462 
463             uint32_t vSize = rects.size();
464             retBool = requestPacker_.WriteUint32(vSize);
465             DISPLAY_CHK_BREAK(retBool == false,
466                 HDF_LOGE("%{public}s: write vSize failed", __func__));
467             for (uint32_t i = 0; i < vSize; i++) {
468                 ret = CmdUtils::RectPack(rects[i], requestPacker_);
469                 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
470                     HDF_LOGE("%{public}s: RectPack failed", __func__));
471             }
472             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
473                 HDF_LOGE("%{public}s: RectPack failed, break", __func__));
474 
475             ret = CmdUtils::EndSection(requestPacker_);
476             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
477                 HDF_LOGE("%{public}s: EndSection failed", __func__));
478         } while (0);
479 
480         if (retBool == false || ret != HDF_SUCCESS) {
481             requestPacker_.RollBack(writePos);
482             HDF_LOGE("%{public}s: writePos_ rollback", __func__);
483             return HDF_FAILURE;
484         }
485         return HDF_SUCCESS;
486     }
487 
SetLayerVisibleRegion(uint32_t devId,uint32_t layerId,std::vector<IRect> & rects)488     int32_t SetLayerVisibleRegion(uint32_t devId, uint32_t layerId, std::vector<IRect> &rects)
489     {
490         int32_t ret = 0;
491         bool retBool = false;
492         int32_t writePos = requestPacker_.ValidSize();
493 
494         do {
495             ret = CmdUtils::StartSection(REQUEST_CMD_SET_LAYER_VISIBLE_REGION, requestPacker_);
496             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
497                 HDF_LOGE("%{public}s: StartSection failed", __func__));
498 
499             ret = CmdUtils::SetupDevice(devId, layerId, requestPacker_);
500             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
501                 HDF_LOGE("%{public}s: SetupDevice failed", __func__));
502 
503             uint32_t vSize = rects.size();
504             retBool = requestPacker_.WriteUint32(vSize);
505             DISPLAY_CHK_BREAK(retBool == false,
506                 HDF_LOGE("%{public}s: write vSize failed", __func__));
507             for (uint32_t i = 0; i < vSize; i++) {
508                 ret = CmdUtils::RectPack(rects[i], requestPacker_);
509                 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
510                     HDF_LOGE("%{public}s: RectPack failed", __func__));
511             }
512             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
513                 HDF_LOGE("%{public}s: RectPack failed, break", __func__));
514 
515             ret = CmdUtils::EndSection(requestPacker_);
516             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
517                 HDF_LOGE("%{public}s: EndSection failed", __func__));
518         } while (0);
519 
520         if (retBool == false || ret != HDF_SUCCESS) {
521             requestPacker_.RollBack(writePos);
522             HDF_LOGE("%{public}s: writePos_ rollback", __func__);
523             return HDF_FAILURE;
524         }
525         return HDF_SUCCESS;
526     }
527 
SetLayerBuffer(uint32_t devId,uint32_t layerId,const BufferHandle * buffer,uint32_t seqNo,int32_t fence,const std::vector<uint32_t> & deletingList)528     int32_t SetLayerBuffer(uint32_t devId, uint32_t layerId, const BufferHandle* buffer, uint32_t seqNo,
529         int32_t fence, const std::vector<uint32_t>& deletingList)
530     {
531         int32_t ret = 0;
532         bool retBool = false;
533         bool result = false;
534         int32_t writePos = requestPacker_.ValidSize();
535 
536         do {
537             ret = CmdUtils::StartSection(REQUEST_CMD_SET_LAYER_BUFFER, requestPacker_);
538             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
539                 HDF_LOGE("%{public}s: StartSection failed", __func__));
540 
541             ret = CmdUtils::SetupDevice(devId, layerId, requestPacker_);
542             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
543                 HDF_LOGE("%{public}s: SetupDevice failed", __func__));
544 
545             ret = CmdUtils::BufferHandlePack(buffer, requestPacker_, requestHdiFds_);
546             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
547                 HDF_LOGE("%{public}s: BufferHandlePack failed", __func__));
548 
549             result = requestPacker_.WriteUint32(seqNo);
550             DISPLAY_CHK_BREAK(result == false,
551                 HDF_LOGE("%{public}s: write seqNo failed", __func__));
552 
553             ret = CmdUtils::FileDescriptorPack(fence, requestPacker_, requestHdiFds_);
554             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
555                 HDF_LOGE("%{public}s: FileDescriptorPack failed", __func__));
556             // write deletingList
557             uint32_t vectSize = static_cast<uint32_t>(deletingList.size());
558             retBool = requestPacker_.WriteUint32(vectSize);
559             DISPLAY_CHK_BREAK(retBool == false,
560                 HDF_LOGE("%{public}s: write vector size failed", __func__));
561 
562             for (uint32_t i = 0; i < vectSize; i++) {
563                 bool result = requestPacker_.WriteUint32(deletingList[i]);
564                 DISPLAY_CHK_BREAK(result == false,
565                     HDF_LOGE("%{public}s: write deletingList failed", __func__));
566             }
567             DISPLAY_CHK_BREAK(result == false,
568                 HDF_LOGE("%{public}s: write deletingList failed, break!", __func__));
569 
570             ret = CmdUtils::EndSection(requestPacker_);
571             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
572                 HDF_LOGE("%{public}s: EndSection failed", __func__));
573         } while (0);
574 
575         if (retBool == false || result == false || ret != HDF_SUCCESS) {
576             requestPacker_.RollBack(writePos);
577             HDF_LOGE("%{public}s: writePos_ rollback", __func__);
578             return HDF_FAILURE;
579         }
580         return HDF_SUCCESS;
581     }
582 
SetLayerCompositionType(uint32_t devId,uint32_t layerId,CompositionType type)583     int32_t SetLayerCompositionType(uint32_t devId, uint32_t layerId, CompositionType type)
584     {
585         int32_t ret = 0;
586         bool retBool = false;
587         int32_t writePos = requestPacker_.ValidSize();
588 
589         do {
590             ret = CmdUtils::StartSection(REQUEST_CMD_SET_LAYER_COMPOSITION_TYPE, requestPacker_);
591             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
592                 HDF_LOGE("%{public}s: StartSection failed", __func__));
593 
594             ret = CmdUtils::SetupDevice(devId, layerId, requestPacker_);
595             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
596                 HDF_LOGE("%{public}s: SetupDevice failed", __func__));
597 
598             retBool = requestPacker_.WriteInt32(type);
599             DISPLAY_CHK_BREAK(retBool == false,
600                 HDF_LOGE("%{public}s: write composition type failed", __func__));
601 
602             ret = CmdUtils::EndSection(requestPacker_);
603             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
604                 HDF_LOGE("%{public}s: EndSection failed", __func__));
605         } while (0);
606 
607         if (retBool == false || ret != HDF_SUCCESS) {
608             requestPacker_.RollBack(writePos);
609             HDF_LOGE("%{public}s: writePos_ rollback", __func__);
610             return HDF_FAILURE;
611         }
612         return HDF_SUCCESS;
613     }
614 
SetLayerBlendType(uint32_t devId,uint32_t layerId,BlendType type)615     int32_t SetLayerBlendType(uint32_t devId, uint32_t layerId, BlendType type)
616     {
617         int32_t ret = 0;
618         bool retBool = false;
619         int32_t writePos = requestPacker_.ValidSize();
620 
621         do {
622             ret = CmdUtils::StartSection(REQUEST_CMD_SET_LAYER_BLEND_TYPE, requestPacker_);
623             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
624                 HDF_LOGE("%{public}s: StartSection failed", __func__));
625 
626             ret = CmdUtils::SetupDevice(devId, layerId, requestPacker_);
627             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
628                 HDF_LOGE("%{public}s: SetupDevice failed", __func__));
629 
630             retBool = requestPacker_.WriteInt32(type);
631             DISPLAY_CHK_BREAK(retBool == false,
632                 HDF_LOGE("%{public}s: write blend type failed", __func__));
633 
634             ret = CmdUtils::EndSection(requestPacker_);
635             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
636                 HDF_LOGE("%{public}s: EndSection failed", __func__));
637         } while (0);
638 
639         if (retBool == false || ret != HDF_SUCCESS) {
640             requestPacker_.RollBack(writePos);
641             HDF_LOGE("%{public}s: writePos_ rollback", __func__);
642             return HDF_FAILURE;
643         }
644         return HDF_SUCCESS;
645     }
646 
SetLayerMaskInfo(uint32_t devId,uint32_t layerId,const MaskInfo maskInfo)647     int32_t SetLayerMaskInfo(uint32_t devId, uint32_t layerId, const MaskInfo maskInfo)
648     {
649         int32_t ret = 0;
650         bool retBool = false;
651         int32_t writePos = requestPacker_.ValidSize();
652 
653         do {
654             ret = CmdUtils::StartSection(REQUEST_CMD_SET_LAYER_MASK_INFO, requestPacker_);
655             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
656                 HDF_LOGE("%{public}s: StartSection failed", __func__));
657 
658             ret = CmdUtils::SetupDevice(devId, layerId, requestPacker_);
659             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
660                 HDF_LOGE("%{public}s: SetupDevice failed", __func__));
661 
662             retBool = requestPacker_.WriteUint32(maskInfo);
663             DISPLAY_CHK_BREAK(retBool == false,
664                 HDF_LOGE("%{public}s: write maskInfo failed", __func__));
665 
666             ret = CmdUtils::EndSection(requestPacker_);
667             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
668                 HDF_LOGE("%{public}s: EndSection failed", __func__));
669         } while (0);
670 
671         if (retBool == false || ret != HDF_SUCCESS) {
672             requestPacker_.RollBack(writePos);
673             HDF_LOGE("%{public}s: writePos_ rollback", __func__);
674             return HDF_FAILURE;
675         }
676         return HDF_SUCCESS;
677     }
678 
SetLayerColor(uint32_t devId,uint32_t layerId,const LayerColor & layerColor)679     int32_t SetLayerColor(uint32_t devId, uint32_t layerId, const LayerColor& layerColor)
680     {
681         int32_t ret = 0;
682         int32_t writePos = requestPacker_.ValidSize();
683 
684         do {
685             ret = CmdUtils::StartSection(REQUEST_CMD_SET_LAYER_COLOR, requestPacker_);
686             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
687                 HDF_LOGE("%{public}s: StartSection failed", __func__));
688 
689             ret = CmdUtils::SetupDevice(devId, layerId, requestPacker_);
690             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
691                 HDF_LOGE("%{public}s: SetupDevice failed", __func__));
692 
693             ret = CmdUtils::LayerColorPack(layerColor, requestPacker_);
694             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
695                 HDF_LOGE("%{public}s: RectPack failed", __func__));
696 
697             ret = CmdUtils::EndSection(requestPacker_);
698             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
699                 HDF_LOGE("%{public}s: EndSection failed", __func__));
700         } while (0);
701 
702         if (ret != HDF_SUCCESS) {
703             requestPacker_.RollBack(writePos);
704             HDF_LOGE("%{public}s: writePos_ rollback", __func__);
705             return HDF_FAILURE;
706         }
707         return HDF_SUCCESS;
708     }
709 
GetDisplayCompChange(uint32_t devId,std::vector<uint32_t> & layers,std::vector<int32_t> & types)710     int32_t GetDisplayCompChange(uint32_t devId, std::vector<uint32_t>& layers, std::vector<int32_t>& types)
711     {
712         layers = compChangeLayers_[devId];
713         types = compChangeTypes_[devId];
714         compChangeLayers_.erase(devId);
715         compChangeTypes_.erase(devId);
716         return HDF_SUCCESS;
717     }
718 protected:
OnReplySetError(CommandDataUnpacker & replyUnpacker,std::unordered_map<int32_t,int32_t> & errMaps)719     int32_t OnReplySetError(CommandDataUnpacker& replyUnpacker, std::unordered_map<int32_t, int32_t> &errMaps)
720     {
721         uint32_t errCnt = 0;
722         bool retBool = replyUnpacker.ReadUint32(errCnt);
723         DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE,
724             HDF_LOGE("%{public}s: read err cnt failed", __func__));
725 
726         int32_t errCmd = -1;
727         int32_t errCode = -1;
728         for (; errCnt > 0; errCnt--) {
729             retBool = replyUnpacker.ReadInt32(errCmd);
730             DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE,
731                 HDF_LOGE("%{public}s: read err cmd failed", __func__));
732             retBool = replyUnpacker.ReadInt32(errCode);
733             DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE,
734                 HDF_LOGE("%{public}s: read err code failed", __func__));
735             errMaps.emplace(errCmd, errCode);
736         }
737 
738         return HDF_SUCCESS;
739     }
740 
OnReplyPrepareDisplayLayers(CommandDataUnpacker & replyUnpacker,bool & needFlushFb)741     int32_t OnReplyPrepareDisplayLayers(CommandDataUnpacker& replyUnpacker, bool &needFlushFb)
742     {
743         uint32_t devId = 0;
744         int32_t retBool = replyUnpacker.ReadUint32(devId);
745         DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE, HDF_LOGE("%{public}s: read devId failed", __func__));
746 
747         retBool = replyUnpacker.ReadBool(needFlushFb);
748         DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE, HDF_LOGE("%{public}s: read needFlushFb failed", __func__));
749         // unpack layers vector
750         uint32_t vectSize = 0;
751         retBool = replyUnpacker.ReadUint32(vectSize);
752         DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE, HDF_LOGE("%{public}s: read vect size failed", __func__));
753         if (vectSize > CmdUtils::MAX_MEMORY) {
754             HDF_LOGE("%{public}s: layers vectSize:%{public}u is too large", __func__, vectSize);
755             return HDF_FAILURE;
756         }
757 
758         compChangeLayers_[devId].resize(vectSize);
759         for (uint32_t i = 0; i < vectSize; i++) {
760             DISPLAY_CHK_RETURN(replyUnpacker.ReadUint32(compChangeLayers_[devId][i]) == false, HDF_FAILURE,
761                 HDF_LOGE("%{public}s: read layer vector failed", __func__));
762         }
763         // unpack types vector
764         vectSize = 0;
765         retBool = replyUnpacker.ReadUint32(vectSize);
766         DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE, HDF_LOGE("%{public}s: read vect size failed", __func__));
767         if (vectSize > CmdUtils::MAX_MEMORY) {
768             HDF_LOGE("%{public}s: types vectSize:%{public}u is too large", __func__, vectSize);
769             return HDF_FAILURE;
770         }
771 
772         compChangeTypes_[devId].resize(vectSize);
773         for (uint32_t i = 0; i < vectSize; i++) {
774             DISPLAY_CHK_RETURN(replyUnpacker.ReadInt32(compChangeTypes_[devId][i]) == false, HDF_FAILURE,
775                 HDF_LOGE("%{public}s: read composition type vector failed", __func__));
776         }
777 
778         return HDF_SUCCESS;
779     }
780 
OnReplyCommit(CommandDataUnpacker & replyUnpacker,std::vector<HdifdInfo> & replyFds,int32_t & fenceFd)781     int32_t OnReplyCommit(
782         CommandDataUnpacker& replyUnpacker, std::vector<HdifdInfo>& replyFds, int32_t &fenceFd)
783     {
784         int32_t ret = CmdUtils::FileDescriptorUnpack(replyUnpacker, replyFds, fenceFd);
785         DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret,
786             HDF_LOGE("%{public}s: FileDescriptorUnpack failed", __func__));
787         return HDF_SUCCESS;
788     }
789 
ProcessUnpackCmd(CommandDataUnpacker & replyUnpacker,int32_t unpackCmd,std::vector<HdifdInfo> & replyFds,std::function<int32_t (void *)> fn)790     int32_t ProcessUnpackCmd(CommandDataUnpacker& replyUnpacker, int32_t unpackCmd,
791         std::vector<HdifdInfo>& replyFds, std::function<int32_t(void *)> fn)
792     {
793         int32_t ret = HDF_SUCCESS;
794         while (replyUnpacker.NextSection()) {
795             bool retBool = replyUnpacker.BeginSection(unpackCmd);
796             DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE,
797                 HDF_LOGE("%{public}s: BeginSection failed", __func__));
798 
799             bool needFlushFb;
800             int32_t fenceFd = -1;
801             std::unordered_map<int32_t, int32_t> errMaps;
802             switch (unpackCmd) {
803                 case REPLY_CMD_PREPARE_DISPLAY_LAYERS:
804                     ret = OnReplyPrepareDisplayLayers(replyUnpacker, needFlushFb);
805                     DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret,
806                         HDF_LOGE("%{public}s: OnReplyPrepareDisplayLayers failed", __func__));
807 
808                     ret = fn(&needFlushFb);
809                     DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret,
810                         HDF_LOGE("%{public}s: ReadBool failed, unpackCmd=%{public}s",
811                         __func__, CmdUtils::CommandToString(unpackCmd)));
812                     break;
813                 case REPLY_CMD_COMMIT:
814                     ret = OnReplyCommit(replyUnpacker, replyFds, fenceFd);
815                     DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret,
816                         HDF_LOGE("%{public}s: OnReplyCommit failed unpackCmd=%{public}s",
817                         __func__, CmdUtils::CommandToString(unpackCmd)));
818 
819                     ret = fn(&fenceFd);
820                     DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret,
821                         HDF_LOGE("%{public}s: return fence fd error, unpackCmd=%{public}s",
822                         __func__, CmdUtils::CommandToString(unpackCmd)));
823                     break;
824                 case REPLY_CMD_SET_ERROR:
825                     ret = OnReplySetError(replyUnpacker, errMaps);
826                     DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret,
827                         HDF_LOGE("%{public}s: OnReplySetError failed", __func__));
828                     DISPLAY_CHK_RETURN(errMaps.size() > 0, HDF_FAILURE,
829                         HDF_LOGE("error: server return errs, size=%{public}zu", errMaps.size()));
830                     break;
831                 default:
832                     HDF_LOGE("Unpack command failure");
833                     return HDF_FAILURE;
834             }
835         }
836         return HDF_SUCCESS;
837     }
838 
DoReplyResults(uint32_t replyEleCnt,std::vector<HdifdInfo> & replyFds,std::shared_ptr<char> replyData,std::function<int32_t (void *)> fn)839     int32_t DoReplyResults(uint32_t replyEleCnt, std::vector<HdifdInfo>& replyFds, std::shared_ptr<char> replyData,
840         std::function<int32_t(void *)> fn)
841     {
842         CommandDataUnpacker replyUnpacker;
843         replyUnpacker.Init(replyData.get(), replyEleCnt << CmdUtils::MOVE_SIZE);
844 #ifdef DEBUG_DISPLAY_CMD_RAW_DATA
845         replyUnpacker.Dump();
846 #endif // DEBUG_DISPLAY_CMD_RAW_DATA
847         int32_t unpackCmd = -1;
848         bool retBool = replyUnpacker.PackBegin(unpackCmd);
849         DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE,
850             HDF_LOGE("%{public}s: PackBegin failed", __func__));
851         DISPLAY_CHK_RETURN(unpackCmd != CONTROL_CMD_REPLY_BEGIN, HDF_FAILURE,
852             HDF_LOGE("%{public}s: PackBegin cmd not match, unpackCmd=%{public}d", __func__, unpackCmd));
853         if (ProcessUnpackCmd(replyUnpacker, unpackCmd, replyFds, fn) != HDF_SUCCESS) {
854             return HDF_FAILURE;
855         }
856 
857         retBool = replyUnpacker.PackEnd(unpackCmd);
858         DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE,
859             HDF_LOGE("%{public}s: PackEnd failed", __func__));
860 
861         DISPLAY_CHK_RETURN(unpackCmd != CONTROL_CMD_REPLY_END, HDF_FAILURE,
862             HDF_LOGE("%{public}s: PackEnd failed, endCmd = %{public}s",
863             __func__, CmdUtils::CommandToString(unpackCmd)));
864 
865         return HDF_SUCCESS;
866     }
867 
DoRequest(uint32_t & replyEleCnt,std::vector<HdifdInfo> & outFds,std::shared_ptr<char> & replyData)868     int32_t DoRequest(uint32_t &replyEleCnt, std::vector<HdifdInfo> &outFds, std::shared_ptr<char> &replyData)
869     {
870 #ifdef DEBUG_DISPLAY_CMD_RAW_DATA
871         requestPacker_.Dump();
872 #endif // DEBUG_DISPLAY_CMD_RAW_DATA
873         uint32_t eleCnt = requestPacker_.ValidSize() >> CmdUtils::MOVE_SIZE;
874         int32_t ret = request_->Write(
875             reinterpret_cast<int32_t *>(requestPacker_.GetDataPtr()), eleCnt, CmdUtils::TRANSFER_WAIT_TIME);
876         DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret,
877             HDF_LOGE("%{public}s: CmdRequest write failed", __func__));
878 
879         ret = hdi_->CmdRequest(eleCnt, requestHdiFds_, replyEleCnt, outFds);
880         DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret,
881             HDF_LOGE("%{public}s: CmdRequest failed", __func__));
882 
883         if (replyEleCnt != 0) {
884             replyData.reset(new char[replyEleCnt << CmdUtils::MOVE_SIZE], std::default_delete<char[]>());
885             DISPLAY_CHK_RETURN(replyData == nullptr, HDF_FAILURE,
886                 HDF_LOGE("%{public}s: get replyData failed", __func__));
887             ret = reply_->Read(reinterpret_cast<int32_t *>(replyData.get()), replyEleCnt, CmdUtils::TRANSFER_WAIT_TIME);
888             if (ret != HDF_SUCCESS) {
889                 HDF_LOGE("reply read data failure, ret=%{public}d", ret);
890             }
891         }
892 
893         return ret;
894     }
895 
PeriodDataReset()896     int32_t PeriodDataReset()
897     {
898         for (uint32_t i = 0; i < requestHdiFds_.size(); ++i) {
899             int32_t fd = requestHdiFds_[i].hdiFd->Move();
900             if (fd != -1) {
901                 close(fd);
902             }
903         }
904         requestHdiFds_.clear();
905         int32_t ret = CmdUtils::StartPack(CONTROL_CMD_REQUEST_BEGIN, requestPacker_);
906         DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret,
907             HDF_LOGE("%{public}s: StartPack failed", __func__));
908 
909         return HDF_SUCCESS;
910     }
911 
912 protected:
913     bool initFlag_;
914     sptr<CompHdi> hdi_;
915     std::shared_ptr<Transfer> request_;
916     std::shared_ptr<Transfer> reply_;
917     // Period data
918     CommandDataPacker requestPacker_;
919     std::vector<HdifdInfo> requestHdiFds_;
920     // Composition layers/types changed
921     std::unordered_map<uint32_t, std::vector<uint32_t>> compChangeLayers_;
922     std::unordered_map<uint32_t, std::vector<int32_t>> compChangeTypes_;
923 };
924 using HdiDisplayCmdRequester = DisplayCmdRequester<SharedMemQueue<int32_t>, IDisplayComposer>;
925 } // namespace V1_0
926 } // namespace Composer
927 } // namespace Display
928 } // namespace HDI
929 } // namespace OHOS
930 #endif // OHOS_HDI_DISPLAY_V1_0_DISPLAY_CMD_REQUESTER_H
931