• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <fstream>
20 #include <poll.h>
21 #include <securec.h>
22 #include <sstream>
23 #include <string>
24 #include <sys/time.h>
25 #include <unistd.h>
26 #include <unordered_map>
27 #include <queue>
28 
29 #include "base/hdi_smq.h"
30 #include "buffer_handle_utils.h"
31 #include "command_pack/command_data_packer.h"
32 #include "command_pack/command_data_unpacker.h"
33 #include "display_cmd_utils.h"
34 #include "hdf_base.h"
35 #include "hdf_trace.h"
36 #include "hdifd_parcelable.h"
37 #include "hilog/log.h"
38 #include "idisplay_composer_vdi.h"
39 #include "parameter.h"
40 #include "v1_0/display_composer_type.h"
41 #include "v1_0/mapper_stub.h"
42 
43 #define DISPLAY_TRACE HdfTrace trace(__func__, "HDI:DISP:")
44 
45 namespace OHOS {
46 namespace HDI {
47 namespace Display {
48 namespace Composer {
49 namespace V1_0 {
50 using namespace OHOS::HDI::Base;
51 using namespace OHOS::HDI::Display::Composer::V1_0;
52 using namespace OHOS::HDI::Display::Buffer::V1_0;
53 using HdifdSet = std::vector<std::shared_ptr<HdifdParcelable>>;
54 
55 static constexpr uint32_t TIME_BUFFER_MAX_LEN = 15;
56 static constexpr uint32_t BUFFER_QUEUE_MAX_SIZE = 6;
57 static constexpr unsigned int REDUCE_COUNT = 50;
58 static sptr<IMapper> g_bufferServiceImpl = nullptr;
59 
60 static constexpr uint32_t COMMIT_PRINT_INTERVAL = 1200;
61 
62 template <typename Transfer, typename VdiImpl>
63 class DisplayCmdResponser {
64 public:
Create(VdiImpl * impl,std::shared_ptr<DeviceCacheManager> cacheMgr)65     static std::unique_ptr<DisplayCmdResponser> Create(VdiImpl* impl, std::shared_ptr<DeviceCacheManager> cacheMgr)
66     {
67         DISPLAY_CHK_RETURN(impl == nullptr, nullptr,
68             HDF_LOGE("%{public}s: error, VdiImpl is nullptr", __func__));
69         DISPLAY_CHK_RETURN(cacheMgr == nullptr, nullptr,
70             HDF_LOGE("%{public}s: error, VdiImpl is nullptr", __func__));
71         return std::make_unique<DisplayCmdResponser>(impl, cacheMgr);
72     }
73 
DisplayCmdResponser(VdiImpl * impl,std::shared_ptr<DeviceCacheManager> cacheMgr)74     DisplayCmdResponser(VdiImpl* impl, std::shared_ptr<DeviceCacheManager> cacheMgr)
75         : impl_(impl),
76         cacheMgr_(cacheMgr),
77         request_(nullptr),
78         isReplyUpdated_(false),
79         reply_(nullptr),
80         replyCommandCnt_(0) {}
81 
~DisplayCmdResponser()82     virtual ~DisplayCmdResponser()
83     {
84         while (delayFreeQueue_.size() > 0) {
85             BufferHandle *temp = delayFreeQueue_.front();
86             delayFreeQueue_.pop();
87             FreeBufferHandle(temp);
88             temp = nullptr;
89         }
90     }
91 
InitCmdRequest(const std::shared_ptr<Transfer> & request)92     int32_t InitCmdRequest(const std::shared_ptr<Transfer>& request)
93     {
94         DISPLAY_CHK_RETURN(request == nullptr, HDF_FAILURE,
95             HDF_LOGE("%{public}s: error, request is nullptr", __func__));
96         std::lock_guard<std::mutex> lock(requestMutex_);
97         if (request_ != nullptr) {
98             request_.reset();
99         }
100         request_ = request;
101 
102         return HDF_SUCCESS;
103     }
104 
GetCmdReply(std::shared_ptr<Transfer> & reply)105     int32_t GetCmdReply(std::shared_ptr<Transfer>& reply)
106     {
107         std::lock_guard<std::mutex> lock(replyMutex_);
108         int32_t ret = HDF_SUCCESS;
109         if (isReplyUpdated_ == false) {
110             ret = InitReply(CmdUtils::INIT_ELEMENT_COUNT);
111         }
112         if (ret == HDF_SUCCESS) {
113             if (reply_ != nullptr) {
114                 reply = reply_;
115             } else {
116                 ret = HDF_FAILURE;
117             }
118         }
119         isReplyUpdated_ = false;
120         if (ret != HDF_SUCCESS) {
121             HDF_LOGE("error: GetCmdReply failure");
122         }
123 
124         return ret;
125     }
126 
ProcessRequestCmd(CommandDataUnpacker & unpacker,int32_t cmd,const std::vector<HdifdInfo> & inFds,std::vector<HdifdInfo> & outFds)127     int32_t ProcessRequestCmd(CommandDataUnpacker& unpacker, int32_t cmd,
128         const std::vector<HdifdInfo>& inFds, std::vector<HdifdInfo>& outFds)
129     {
130         int32_t ret = HDF_SUCCESS;
131         switch (cmd) {
132             case REQUEST_CMD_PREPARE_DISPLAY_LAYERS: OnPrepareDisplayLayers(unpacker); break;
133             case REQUEST_CMD_SET_DISPLAY_CLIENT_BUFFER: OnSetDisplayClientBuffer(unpacker, inFds); break;
134             case REQUEST_CMD_SET_DISPLAY_CLIENT_DAMAGE: OnSetDisplayClientDamage(unpacker); break;
135             case REQUEST_CMD_COMMIT: OnCommit(unpacker, outFds); break;
136             case REQUEST_CMD_SET_LAYER_ALPHA: OnSetLayerAlpha(unpacker); break;
137             case REQUEST_CMD_SET_LAYER_REGION: OnSetLayerRegion(unpacker); break;
138             case REQUEST_CMD_SET_LAYER_CROP: OnSetLayerCrop(unpacker); break;
139             case REQUEST_CMD_SET_LAYER_ZORDER: OnSetLayerZorder(unpacker); break;
140             case REQUEST_CMD_SET_LAYER_PREMULTI: OnSetLayerPreMulti(unpacker); break;
141             case REQUEST_CMD_SET_LAYER_TRANSFORM_MODE: OnSetLayerTransformMode(unpacker); break;
142             case REQUEST_CMD_SET_LAYER_DIRTY_REGION: OnSetLayerDirtyRegion(unpacker); break;
143             case REQUEST_CMD_SET_LAYER_VISIBLE_REGION: OnSetLayerVisibleRegion(unpacker); break;
144             case REQUEST_CMD_SET_LAYER_BUFFER: OnSetLayerBuffer(unpacker, inFds); break;
145             case REQUEST_CMD_SET_LAYER_COMPOSITION_TYPE: OnSetLayerCompositionType(unpacker); break;
146             case REQUEST_CMD_SET_LAYER_BLEND_TYPE: OnSetLayerBlendType(unpacker); break;
147             case REQUEST_CMD_SET_LAYER_MASK_INFO: OnSetLayerMaskInfo(unpacker); break;
148             case CONTROL_CMD_REQUEST_END: ret = OnRequestEnd(unpacker); break;
149             case REQUEST_CMD_SET_LAYER_COLOR: OnSetLayerColor(unpacker); break;
150             default:
151                 HDF_LOGE("%{public}s: not support this cmd, unpacked cmd = %{public}d", __func__, cmd);
152                 ret = HDF_FAILURE;
153                 break;
154         }
155         return ret;
156     }
157 
CmdRequest(uint32_t inEleCnt,const std::vector<HdifdInfo> & inFds,uint32_t & outEleCnt,std::vector<HdifdInfo> & outFds)158     int32_t CmdRequest(uint32_t inEleCnt, const std::vector<HdifdInfo>& inFds, uint32_t& outEleCnt,
159         std::vector<HdifdInfo>& outFds)
160     {
161         if (inEleCnt > CmdUtils::MAX_ELE_COUNT) {
162             HDF_LOGE("%{public}s: inEleCnt:%{public}u is too large", __func__, inEleCnt);
163             return HDF_FAILURE;
164         }
165         std::shared_ptr<char> requestData(new char[inEleCnt * CmdUtils::ELEMENT_SIZE], std::default_delete<char[]>());
166         int32_t ret = HDF_SUCCESS;
167         {
168             std::lock_guard<std::mutex> lock(requestMutex_);
169             ret = request_->Read(reinterpret_cast<int32_t *>(requestData.get()), inEleCnt,
170                 CmdUtils::TRANSFER_WAIT_TIME);
171         }
172         CommandDataUnpacker unpacker;
173         unpacker.Init(requestData.get(), inEleCnt << CmdUtils::MOVE_SIZE);
174 #ifdef DEBUG_DISPLAY_CMD_RAW_DATA
175         unpacker.Dump();
176 #endif // DEBUG_DISPLAY_CMD_RAW_DATA
177 
178         int32_t unpackCmd = -1;
179         bool retBool = unpacker.PackBegin(unpackCmd);
180         DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE,
181             HDF_LOGE("%{public}s: error: Check RequestBegin failed", __func__));
182         DISPLAY_CHK_RETURN(unpackCmd != CONTROL_CMD_REQUEST_BEGIN, HDF_FAILURE,
183             HDF_LOGI("error: unpacker PackBegin cmd not match, cmd(%{public}d)=%{public}s.", unpackCmd,
184             CmdUtils::CommandToString(unpackCmd)));
185 
186         while (ret == HDF_SUCCESS && unpacker.NextSection()) {
187             if (!unpacker.BeginSection(unpackCmd)) {
188                 HDF_LOGE("error: PackSection failed, unpackCmd=%{public}s.", CmdUtils::CommandToString(unpackCmd));
189                 return HDF_FAILURE;
190             }
191             ret = ProcessRequestCmd(unpacker, unpackCmd, inFds, outFds);
192         }
193 
194         DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret, HDF_LOGE("%{public}s:ProcessRequestCmd failed", __func__));
195         /* pack request end commands */
196         replyPacker_.PackEnd(CONTROL_CMD_REPLY_END);
197 
198 #ifdef DEBUG_DISPLAY_CMD_RAW_DATA
199         /* just for debug */
200         replyPacker_.Dump();
201         HDF_LOGI("CmdReply command cnt=%{public}d", replyCommandCnt_);
202 #endif // DEBUG_DISPLAY_CMD_RAW_DATA
203 
204         /*  Write reply pack */
205         outEleCnt = replyPacker_.ValidSize() >> CmdUtils::MOVE_SIZE;
206         {
207             std::lock_guard<std::mutex> lock(replyMutex_);
208             ret = reply_->Write(reinterpret_cast<int32_t *>(replyPacker_.GetDataPtr()), outEleCnt,
209                 CmdUtils::TRANSFER_WAIT_TIME);
210         }
211         if (ret != HDF_SUCCESS) {
212             HDF_LOGE("Reply write failure, ret=%{public}d", ret);
213             outEleCnt = 0;
214         }
215         int32_t ec = PeriodDataReset();
216         return (ret == HDF_SUCCESS ? ec : ret);
217     }
218 
219 protected:
InitReply(uint32_t size)220     int32_t InitReply(uint32_t size)
221     {
222         if (size > CmdUtils::MAX_MEMORY) {
223             HDF_LOGE("%{public}s: size:%{public}u is too large", __func__, size);
224             return HDF_FAILURE;
225         }
226 
227         reply_ = std::make_shared<Transfer>(size, SmqType::SYNCED_SMQ);
228         DISPLAY_CHK_RETURN(reply_ == nullptr, HDF_FAILURE,
229             HDF_LOGE("%{public}s: reply_ construct failed", __func__));
230 
231         bool retBool = replyPacker_.Init(reply_->GetSize() << CmdUtils::MOVE_SIZE);
232         DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE,
233             HDF_LOGE("%{public}s: replyPacker_ init failed", __func__));
234 
235         return CmdUtils::StartPack(CONTROL_CMD_REPLY_BEGIN, replyPacker_);
236     }
237 
OnRequestEnd(CommandDataUnpacker & unpacker)238     int32_t OnRequestEnd(CommandDataUnpacker& unpacker)
239     {
240         DISPLAY_TRACE;
241 
242         size_t errCnt = errMaps_.size();
243         if (errCnt >= 0) {
244             int32_t ret = CmdUtils::StartSection(REPLY_CMD_SET_ERROR, replyPacker_);
245             DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret,
246                 HDF_LOGE("%{public}s: StartSection failed", __func__));
247 
248             bool result = replyPacker_.WriteUint32(errCnt);
249             DISPLAY_CHK_RETURN(result == false, HDF_FAILURE,
250                 HDF_LOGE("%{public}s: write errCnt failed", __func__));
251             for (auto it = errMaps_.begin(); it != errMaps_.end(); ++it) {
252                 result = replyPacker_.WriteInt32(it->first);
253                 DISPLAY_CHK_RETURN(result == false, HDF_FAILURE,
254                     HDF_LOGE("%{public}s: write err-cmd failed, cmdId:%{public}s",
255                     __func__, CmdUtils::CommandToString(it->first)));
256 
257                 result = replyPacker_.WriteInt32(it->second);
258                 DISPLAY_CHK_RETURN(result == false, HDF_FAILURE,
259                     HDF_LOGE("%{public}s: write errNo failed, errNo:%{public}d", __func__, it->second));
260             }
261             result = CmdUtils::EndSection(replyPacker_);
262             DISPLAY_CHK_RETURN(result == false, HDF_FAILURE,
263                 HDF_LOGE("%{public}s: write replyPacker_ EndSection failed", __func__));
264             replyCommandCnt_++;
265         }
266         return HDF_SUCCESS;
267     }
268 
OnPrepareDisplayLayers(CommandDataUnpacker & unpacker)269     void OnPrepareDisplayLayers(CommandDataUnpacker& unpacker)
270     {
271         DISPLAY_TRACE;
272 
273         uint32_t devId = 0;
274         bool needFlush = false;
275         uint32_t vectSize = 0;
276         std::vector<uint32_t> layers;
277         std::vector<int32_t> types;
278 
279         int32_t ret = unpacker.ReadUint32(devId) ? HDF_SUCCESS : HDF_FAILURE;
280         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
281         {
282             HdfTrace traceVdi("PrepareDisplayLayers", "HDI:DISP:HARDWARE");
283             ret = impl_->PrepareDisplayLayers(devId, needFlush);
284         }
285 
286         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
287         {
288             HdfTrace traceVdi("GetDisplayCompChange", "HDI:DISP:HARDWARE");
289             ret = impl_->GetDisplayCompChange(devId, layers, types);
290         }
291 
292         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
293 
294         ret = CmdUtils::StartSection(REPLY_CMD_PREPARE_DISPLAY_LAYERS, replyPacker_);
295         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
296 
297         DISPLAY_CHECK(replyPacker_.WriteUint32(devId) == false, goto EXIT);
298 
299         DISPLAY_CHECK(replyPacker_.WriteBool(needFlush) == false, goto EXIT);
300         // Write layers vector
301         vectSize = static_cast<uint32_t>(layers.size());
302         DISPLAY_CHECK(replyPacker_.WriteUint32(vectSize) == false, goto EXIT);
303 
304         for (uint32_t i = 0; i < vectSize; i++) {
305             DISPLAY_CHECK(replyPacker_.WriteUint32(layers[i]) == false, goto EXIT);
306         }
307         // Write composer types vector
308         vectSize = static_cast<uint32_t>(types.size());
309         DISPLAY_CHECK(replyPacker_.WriteUint32(vectSize) == false, goto EXIT);
310 
311         for (uint32_t i = 0; i < vectSize; i++) {
312             DISPLAY_CHECK(replyPacker_.WriteUint32(types[i]) == false, goto EXIT);
313         }
314         // End this cmd section
315         ret = CmdUtils::EndSection(replyPacker_);
316         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
317         replyCommandCnt_++;
318 EXIT:
319         if (ret != HDF_SUCCESS) {
320             errMaps_.emplace(REQUEST_CMD_PREPARE_DISPLAY_LAYERS, ret);
321         }
322         return;
323     }
324 
325     typedef struct ClientBufferData {
326         uint32_t devId;
327         uint32_t seqNo;
328         int32_t fence;
329         BufferHandle *buffer;
330         bool isValidBuffer;
331     } ClientBufferData;
332 
UnpackDisplayClientBufferInfo(CommandDataUnpacker & unpacker,const std::vector<HdifdInfo> & inFds,ClientBufferData & data)333     int32_t UnpackDisplayClientBufferInfo(CommandDataUnpacker& unpacker,
334         const std::vector<HdifdInfo>& inFds, ClientBufferData& data)
335     {
336         if (!unpacker.ReadUint32(data.devId)) {
337             return HDF_FAILURE;
338         }
339 
340         if (CmdUtils::BufferHandleUnpack(unpacker, inFds, data.buffer) != HDF_SUCCESS) {
341             data.isValidBuffer = false;
342             HDF_LOGE("%{public}s, read buffer handle error", __func__);
343             return HDF_FAILURE;
344         }
345         data.isValidBuffer = true;
346 
347         if (!unpacker.ReadUint32(data.seqNo)) {
348             HDF_LOGE("%{public}s, read seqNo error", __func__);
349             return HDF_FAILURE;
350         }
351 
352         if (CmdUtils::FileDescriptorUnpack(unpacker, inFds, data.fence) != HDF_SUCCESS) {
353             HDF_LOGE("%{public}s, FileDescriptorUnpack error", __func__);
354             return HDF_FAILURE;
355         }
356 
357         return HDF_SUCCESS;
358     }
359 
SetDisplayClientBuffer(ClientBufferData & data,bool & needFreeBuffer,bool & needMoveFd,int fd)360     int32_t SetDisplayClientBuffer(ClientBufferData& data, bool &needFreeBuffer, bool &needMoveFd, int fd)
361     {
362         if (cacheMgr_ == nullptr) {
363             HDF_LOGE("%{public}s, get cache manager error", __func__);
364             return HDF_FAILURE;
365         }
366         std::lock_guard<std::mutex> lock(cacheMgr_->GetCacheMgrMutex());
367 
368         DeviceCache* devCache = cacheMgr_->DeviceCacheInstance(data.devId);
369         if (devCache == nullptr) {
370             HDF_LOGE("%{public}s, get device cache error", __func__);
371             return HDF_FAILURE;
372         }
373 
374         int32_t ret = devCache->SetDisplayClientBuffer(data.buffer, data.seqNo, needFreeBuffer,
375             [&](const BufferHandle& handle)->int32_t {
376 #ifdef DISPLAY_COMSPOER_DEBUG_DUMP
377             DumpLayerBuffer(data.devId, data.seqNo, data.fence, handle, "client_");
378 #endif
379             HdfTrace traceVdi("SetDisplayClientBuffer", data.buffer == nullptr ? ("data.buffer is nullptr! seqNo:" +
380             std::to_string(data.seqNo)) : ("HDI:DISP:HARDWARE height:" + std::to_string(data.buffer->height) +
381             " width:" + std::to_string(data.buffer->width) + " seqNo:" + std::to_string(data.seqNo)));
382             needMoveFd = true;
383             int rc = impl_->SetDisplayClientBuffer(data.devId, handle, fd);
384             DISPLAY_CHK_RETURN(rc != HDF_SUCCESS, HDF_FAILURE, HDF_LOGE(" fail"));
385             return HDF_SUCCESS;
386         });
387         return ret;
388     }
389 
OnSetDisplayClientBuffer(CommandDataUnpacker & unpacker,const std::vector<HdifdInfo> & inFds)390     void OnSetDisplayClientBuffer(CommandDataUnpacker& unpacker, const std::vector<HdifdInfo>& inFds)
391     {
392         DISPLAY_TRACE;
393 
394         ClientBufferData data = {0};
395         data.fence = -1;
396         bool needFreeBuffer = false;
397         bool needMoveFd = false;
398         int32_t ret = UnpackDisplayClientBufferInfo(unpacker, inFds, data);
399         HdifdParcelable fdParcel(data.fence);
400         if (ret == HDF_SUCCESS) {
401             ret = SetDisplayClientBuffer(data, needFreeBuffer, needMoveFd, fdParcel.GetFd());
402         }
403 #ifndef DISPLAY_COMMUNITY
404         // fix fd leak
405         if (data.buffer != nullptr && needFreeBuffer) {
406             FreeBufferWithDelay(data.buffer);
407             data.buffer = nullptr;
408             data.isValidBuffer = false;
409         }
410         if (needMoveFd) {
411             fdParcel.Move();
412         }
413 #endif // DISPLAY_COMMUNITY
414         if (ret != HDF_SUCCESS) {
415             HDF_LOGE("%{public}s, SetDisplayClientBuffer error", __func__);
416             if (data.isValidBuffer && data.buffer != nullptr) {
417                 FreeBufferHandle(data.buffer);
418                 data.buffer = nullptr;
419             }
420             errMaps_.emplace(REQUEST_CMD_SET_DISPLAY_CLIENT_BUFFER, ret);
421         }
422     }
423 
OnSetDisplayClientDamage(CommandDataUnpacker & unpacker)424     void OnSetDisplayClientDamage(CommandDataUnpacker& unpacker)
425     {
426         DISPLAY_TRACE;
427 
428         uint32_t devId = 0;
429         uint32_t vectSize = 0;
430         bool retBool = true;
431         DISPLAY_CHK_CONDITION(retBool, true, unpacker.ReadUint32(devId),
432             HDF_LOGE("%{public}s, read devId error", __func__));
433 
434         DISPLAY_CHK_CONDITION(retBool, true, unpacker.ReadUint32(vectSize),
435             HDF_LOGE("%{public}s, read vectSize error", __func__));
436 
437         int32_t ret = (retBool ? HDF_SUCCESS : HDF_FAILURE);
438         std::vector<IRect> rects(vectSize);
439         if (ret == HDF_SUCCESS) {
440             for (uint32_t i = 0; i < vectSize; i++) {
441                 DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::RectUnpack(unpacker, rects[i]),
442                     HDF_LOGE("%{public}s, read vect error at i = %{public}d", __func__, i));
443                 if (ret != HDF_SUCCESS) {
444                     break;
445                 }
446             }
447         }
448         if (ret == HDF_SUCCESS) {
449             HdfTrace traceVdi("SetDisplayClientDamage", "HDI:DISP:HARDWARE");
450             impl_->SetDisplayClientDamage(devId, rects);
451         } else {
452             HDF_LOGE("%{public}s, SetDisplayClientDamage error", __func__);
453             errMaps_.emplace(REQUEST_CMD_SET_DISPLAY_CLIENT_DAMAGE, ret);
454         }
455         return;
456     }
457 
OnCommit(CommandDataUnpacker & unpacker,std::vector<HdifdInfo> & outFds)458     void OnCommit(CommandDataUnpacker& unpacker, std::vector<HdifdInfo>& outFds)
459     {
460         DISPLAY_TRACE;
461 
462         uint32_t devId = 0;
463         int32_t fence = -1;
464 #ifdef DISPLAY_COMSPOER_DEBUG_DUMP
465         const std::string SWITCH_ON = "on";
466         const uint32_t DUMP_CACHE_SWITCH_LEN = 4;
467         char dumpSwitch[DUMP_CACHE_SWITCH_LEN] = {0};
468         GetParameter("hdi.composer.dumpcache", "off", dumpSwitch, DUMP_CACHE_SWITCH_LEN);
469 
470         if (SWITCH_ON.compare(dumpSwitch) == 0) {
471             cacheMgr_->Dump();
472         }
473 #endif
474         int32_t ret = HDF_SUCCESS;
475         if (!unpacker.ReadUint32(devId)) {
476             HDF_LOGE("%{public}s, read devId error", __func__);
477             ret = HDF_FAILURE;
478             goto REPLY;
479         }
480 
481         {
482             HdfTrace traceVdi("Commit", "HDI:DISP:HARDWARE");
483             ret = impl_->Commit(devId, fence);
484         }
485         static unsigned int count = 0;
486         if (ret == HDF_SUCCESS) {
487             count = 0;
488         } else {
489             if (++count > REDUCE_COUNT) {
490                 HDF_LOGE("%{public}s, commit failed with ret = %{public}d", __func__, ret);
491                 count = 0;
492             }
493         }
494 
495 REPLY:
496         HdifdParcelable fdParcel(fence);
497         DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::StartSection(REPLY_CMD_COMMIT, replyPacker_),
498             HDF_LOGE("%{public}s, StartSection error", __func__));
499 
500         DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::FileDescriptorPack(fdParcel.GetFd(), replyPacker_, outFds),
501             HDF_LOGE("%{public}s, FileDescriptorPack error", __func__));
502 
503         DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::EndSection(replyPacker_),
504             HDF_LOGE("%{public}s, EndSection error", __func__));
505 
506         replyCommandCnt_++;
507 
508 #ifndef DISPLAY_COMMUNITY
509         fdParcel.Move();
510 #endif // DISPLAY_COMMUNITY
511 
512         if (ret != HDF_SUCCESS) {
513             errMaps_.emplace(REQUEST_CMD_COMMIT, ret);
514         }
515 
516         return;
517     }
518 
OnSetLayerAlpha(CommandDataUnpacker & unpacker)519     void OnSetLayerAlpha(CommandDataUnpacker& unpacker)
520     {
521         DISPLAY_TRACE;
522 
523         uint32_t devId = 0;
524         uint32_t layerId = 0;
525         LayerAlpha alpha = {0};
526         bool retBool = true;
527 
528         int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId);
529         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
530 
531         retBool = unpacker.ReadBool(alpha.enGlobalAlpha);
532         DISPLAY_CHECK(retBool == false, goto EXIT);
533 
534         retBool = unpacker.ReadBool(alpha.enPixelAlpha);
535         DISPLAY_CHECK(retBool == false, goto EXIT);
536 
537         retBool = unpacker.ReadUint8(alpha.alpha0);
538         DISPLAY_CHECK(retBool == false, goto EXIT);
539 
540         retBool = unpacker.ReadUint8(alpha.alpha1);
541         DISPLAY_CHECK(retBool == false, goto EXIT);
542 
543         retBool = unpacker.ReadUint8(alpha.gAlpha);
544         DISPLAY_CHECK(retBool == false, goto EXIT);
545 
546         {
547             HdfTrace traceVdi("SetLayerAlpha", "HDI:DISP:HARDWARE");
548             ret = impl_->SetLayerAlpha(devId, layerId, alpha);
549         }
550         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
551 
552 EXIT:
553         if (ret != HDF_SUCCESS || retBool == false) {
554             errMaps_.emplace(REQUEST_CMD_SET_LAYER_ALPHA, ret);
555         }
556         return;
557     }
558 
OnSetLayerRegion(CommandDataUnpacker & unpacker)559     void OnSetLayerRegion(CommandDataUnpacker& unpacker)
560     {
561         DISPLAY_TRACE;
562 
563         uint32_t devId = 0;
564         uint32_t layerId = 0;
565         IRect rect = {0};
566 
567         int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId);
568         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
569 
570         ret = CmdUtils::RectUnpack(unpacker, rect);
571         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
572 
573         {
574             HdfTrace traceVdi("SetLayerRegion", "HDI:DISP:HARDWARE");
575             ret = impl_->SetLayerRegion(devId, layerId, rect);
576         }
577         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
578 EXIT:
579         if (ret != HDF_SUCCESS) {
580             errMaps_.emplace(REQUEST_CMD_SET_LAYER_REGION, ret);
581         }
582         return;
583     }
584 
OnSetLayerCrop(CommandDataUnpacker & unpacker)585     void OnSetLayerCrop(CommandDataUnpacker& unpacker)
586     {
587         DISPLAY_TRACE;
588 
589         uint32_t devId = 0;
590         uint32_t layerId = 0;
591         IRect rect = {0};
592 
593         int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId);
594         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
595 
596         ret = CmdUtils::RectUnpack(unpacker, rect);
597         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
598 
599         {
600             HdfTrace traceVdi("SetLayerCrop", "HDI:DISP:HARDWARE");
601             ret = impl_->SetLayerCrop(devId, layerId, rect);
602         }
603         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
604 EXIT:
605         if (ret != HDF_SUCCESS) {
606             errMaps_.emplace(REQUEST_CMD_SET_LAYER_CROP, ret);
607         }
608         return;
609     }
610 
OnSetLayerZorder(CommandDataUnpacker & unpacker)611     void OnSetLayerZorder(CommandDataUnpacker& unpacker)
612     {
613         DISPLAY_TRACE;
614 
615         uint32_t devId = 0;
616         uint32_t layerId = 0;
617         uint32_t zorder = 0;
618 
619         int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId);
620         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
621 
622         ret = unpacker.ReadUint32(zorder) ? HDF_SUCCESS : HDF_FAILURE;
623         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
624 
625         {
626             HdfTrace traceVdi("SetLayerZorder", "HDI:DISP:HARDWARE");
627             ret = impl_->SetLayerZorder(devId, layerId, zorder);
628         }
629         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
630 EXIT:
631         if (ret != HDF_SUCCESS) {
632             errMaps_.emplace(REQUEST_CMD_SET_LAYER_ZORDER, ret);
633         }
634         return;
635     }
636 
OnSetLayerPreMulti(CommandDataUnpacker & unpacker)637     void OnSetLayerPreMulti(CommandDataUnpacker& unpacker)
638     {
639         DISPLAY_TRACE;
640 
641         uint32_t devId = 0;
642         uint32_t layerId = 0;
643         bool preMulti = false;
644 
645         int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId);
646         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
647 
648         ret = unpacker.ReadBool(preMulti) ? HDF_SUCCESS : HDF_FAILURE;
649         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
650 
651         {
652             HdfTrace traceVdi("SetLayerPreMulti", "HDI:DISP:HARDWARE");
653             ret = impl_->SetLayerPreMulti(devId, layerId, preMulti);
654         }
655         DISPLAY_CHECK(ret != HDF_SUCCESS && ret != DISPLAY_NOT_SUPPORT && ret != HDF_ERR_NOT_SUPPORT, goto EXIT);
656 EXIT:
657         if (ret != HDF_SUCCESS) {
658             errMaps_.emplace(REQUEST_CMD_SET_LAYER_PREMULTI, ret);
659         }
660         return;
661     }
662 
OnSetLayerTransformMode(CommandDataUnpacker & unpacker)663     void OnSetLayerTransformMode(CommandDataUnpacker& unpacker)
664     {
665         DISPLAY_TRACE;
666 
667         uint32_t devId = 0;
668         uint32_t layerId = 0;
669         int32_t type = 0;
670 
671         int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId);
672         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
673 
674         ret = unpacker.ReadInt32(type) ? HDF_SUCCESS : HDF_FAILURE;
675         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
676 
677         {
678             HdfTrace traceVdi("SetLayerTransformMode", "HDI:DISP:HARDWARE");
679             ret = impl_->SetLayerTransformMode(devId, layerId, static_cast<TransformType>(type));
680         }
681         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
682 EXIT:
683         if (ret != HDF_SUCCESS) {
684             errMaps_.emplace(REQUEST_CMD_SET_LAYER_TRANSFORM_MODE, ret);
685         }
686 
687         return;
688     }
689 
OnSetLayerDirtyRegion(CommandDataUnpacker & unpacker)690     void OnSetLayerDirtyRegion(CommandDataUnpacker& unpacker)
691     {
692         DISPLAY_TRACE;
693 
694         uint32_t devId = 0;
695         uint32_t layerId = 0;
696         uint32_t vectSize = 0;
697         int32_t ret = HDF_SUCCESS;
698 
699         DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId),
700             HDF_LOGE("%{public}s, read devId error", __func__));
701 
702         DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, unpacker.ReadUint32(vectSize) ? HDF_SUCCESS : HDF_FAILURE,
703             HDF_LOGE("%{public}s, read vectSize error", __func__));
704 
705         std::vector<IRect> rects(vectSize);
706         if (ret == HDF_SUCCESS) {
707             for (uint32_t i = 0; i < vectSize; i++) {
708                 DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::RectUnpack(unpacker, rects[i]),
709                     HDF_LOGE("%{public}s, read vect error, at i = %{public}d", __func__, i));
710                 if (ret != HDF_SUCCESS) {
711                     break;
712                 }
713             }
714         }
715         if (ret == HDF_SUCCESS) {
716             HdfTrace traceVdi("SetLayerDirtyRegion", "HDI:DISP:HARDWARE");
717             impl_->SetLayerDirtyRegion(devId, layerId, rects);
718         } else {
719             HDF_LOGE("%{public}s, SetLayerDirtyRegion error", __func__);
720             errMaps_.emplace(REQUEST_CMD_SET_LAYER_DIRTY_REGION, ret);
721         }
722         return;
723     }
724 
OnSetLayerVisibleRegion(CommandDataUnpacker & unpacker)725     void OnSetLayerVisibleRegion(CommandDataUnpacker& unpacker)
726     {
727         DISPLAY_TRACE;
728 
729         uint32_t devId = 0;
730         uint32_t layerId = 0;
731         uint32_t vectSize = 0;
732         int32_t ret = HDF_SUCCESS;
733 
734         DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId),
735             HDF_LOGE("%{public}s, read devId error", __func__));
736 
737         DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, unpacker.ReadUint32(vectSize) ? HDF_SUCCESS : HDF_FAILURE,
738             HDF_LOGE("%{public}s, read vectSize error", __func__));
739 
740         std::vector<IRect> rects(vectSize);
741         if (ret == HDF_SUCCESS) {
742             for (uint32_t i = 0; i < vectSize; i++) {
743                 DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::RectUnpack(unpacker, rects[i]),
744                     HDF_LOGE("%{public}s, read vect error, at i = %{public}d", __func__, i));
745                 if (ret != HDF_SUCCESS) {
746                     break;
747                 }
748             }
749         }
750         if (ret == HDF_SUCCESS) {
751             HdfTrace traceVdi("SetLayerVisibleRegion", "HDI:DISP:HARDWARE");
752             impl_->SetLayerVisibleRegion(devId, layerId, rects);
753         } else {
754             HDF_LOGE("%{public}s, SetLayerDirtyRegion error", __func__);
755             errMaps_.emplace(REQUEST_CMD_SET_LAYER_VISIBLE_REGION, ret);
756         }
757         return;
758     }
759 
760     typedef struct LayerBufferData {
761         bool isValidBuffer;
762         uint32_t devId;
763         uint32_t layerId;
764         uint32_t seqNo;
765         int32_t fence;
766         BufferHandle *buffer;
767     } LayerBufferData;
768 
UnPackLayerBufferInfo(CommandDataUnpacker & unpacker,const std::vector<HdifdInfo> & inFds,struct LayerBufferData * data,std::vector<uint32_t> & deletingList)769     int32_t UnPackLayerBufferInfo(CommandDataUnpacker& unpacker, const std::vector<HdifdInfo>& inFds,
770         struct LayerBufferData *data, std::vector<uint32_t> &deletingList)
771     {
772         DISPLAY_CHK_RETURN(HDF_SUCCESS != CmdUtils::SetupDeviceUnpack(unpacker, data->devId, data->layerId),
773             HDF_FAILURE, HDF_LOGE("%{public}s, read devId error", __func__));
774 
775         DISPLAY_CHK_RETURN(HDF_SUCCESS != CmdUtils::BufferHandleUnpack(unpacker, inFds, data->buffer), HDF_FAILURE,
776             HDF_LOGE("%{public}s, read BufferHandleUnpack error", __func__));
777 
778         data->isValidBuffer = true;
779 
780         DISPLAY_CHK_RETURN(true != unpacker.ReadUint32(data->seqNo), HDF_FAILURE,
781             HDF_LOGE("%{public}s, read seqNo error", __func__));
782 
783         DISPLAY_CHK_RETURN(HDF_SUCCESS != CmdUtils::FileDescriptorUnpack(unpacker, inFds, data->fence), HDF_FAILURE,
784             HDF_LOGE("%{public}s, FileDescriptorUnpack error", __func__));
785 
786         // unpack deletingList
787         uint32_t vectSize = 0;
788         DISPLAY_CHK_RETURN(true != unpacker.ReadUint32(vectSize), HDF_FAILURE,
789             HDF_LOGE("%{public}s, read vectSize error", __func__));
790         if (vectSize > CmdUtils::MAX_MEMORY) {
791             HDF_LOGE("%{public}s: vectSize:%{public}u is too large", __func__, vectSize);
792             return HDF_FAILURE;
793         }
794 
795         deletingList.resize(vectSize);
796         for (uint32_t i = 0; i < vectSize; i++) {
797             DISPLAY_CHK_RETURN(true != unpacker.ReadUint32(deletingList[i]), HDF_FAILURE,
798                 HDF_LOGE("%{public}s, read seqNo error, at i = %{public}d", __func__, i));
799         }
800         return HDF_SUCCESS;
801     }
802 
SetLayerBuffer(LayerBufferData & data,std::vector<uint32_t> & deletingList,bool & needFreeBuffer,bool & needMoveFd,int fd)803     int32_t SetLayerBuffer(LayerBufferData& data, std::vector<uint32_t> &deletingList,
804         bool &needFreeBuffer, bool &needMoveFd, int fd)
805     {
806         DISPLAY_CHECK(cacheMgr_ == nullptr, return HDF_FAILURE);
807         std::lock_guard<std::mutex> lock(cacheMgr_->GetCacheMgrMutex());
808         DeviceCache* devCache = nullptr;
809         LayerCache* layerCache = nullptr;
810         devCache = cacheMgr_->DeviceCacheInstance(data.devId);
811         DISPLAY_CHECK(devCache == nullptr, return HDF_FAILURE);
812         layerCache = devCache->LayerCacheInstance(data.layerId);
813         DISPLAY_CHECK(layerCache == nullptr, return HDF_FAILURE);
814 
815         int32_t ret = layerCache->SetLayerBuffer(data.buffer, data.seqNo, needFreeBuffer, deletingList,
816             [&](const BufferHandle& handle)->int32_t {
817 #ifdef DISPLAY_COMSPOER_DEBUG_DUMP
818             DumpLayerBuffer(data.devId, data.layerId, data.fence, handle, "layer_");
819 #endif
820             HdfTrace traceVdi("SetLayerBuffer", "HDI:DISP:HARDWARE");
821             needMoveFd = true;
822             int rc = impl_->SetLayerBuffer(data.devId, data.layerId, handle, fd);
823             DISPLAY_CHK_RETURN(rc != HDF_SUCCESS, HDF_FAILURE, HDF_LOGE(" fail"));
824             return HDF_SUCCESS;
825         });
826         return ret;
827     }
828 
OnSetLayerBuffer(CommandDataUnpacker & unpacker,const std::vector<HdifdInfo> & inFds)829     void OnSetLayerBuffer(CommandDataUnpacker& unpacker, const std::vector<HdifdInfo>& inFds)
830     {
831         DISPLAY_TRACE;
832 
833         struct LayerBufferData data;
834         std::vector<uint32_t> deletingList;
835 
836         int32_t ret = UnPackLayerBufferInfo(unpacker, inFds, &data, deletingList);
837         HdifdParcelable fdParcel(data.fence);
838         bool needFreeBuffer = false;
839         bool needMoveFd = false;
840 
841         if (ret == HDF_SUCCESS) {
842             ret = SetLayerBuffer(data, deletingList, needFreeBuffer, needMoveFd, fdParcel.GetFd());
843         }
844 #ifndef DISPLAY_COMMUNITY
845         // fix fd leak
846         if (data.buffer != nullptr && needFreeBuffer) {
847             FreeBufferWithDelay(data.buffer);
848             data.buffer = nullptr;
849             data.isValidBuffer = false;
850         }
851         if (needMoveFd) {
852             fdParcel.Move();
853         }
854 #endif // DISPLAY_COMMUNITY
855         if (ret != HDF_SUCCESS) {
856             HDF_LOGE("%{public}s, SetLayerBuffer error", __func__);
857             if (data.isValidBuffer && data.buffer != nullptr) {
858                 FreeBufferHandle(data.buffer);
859                 data.buffer = nullptr;
860             }
861             errMaps_.emplace(REQUEST_CMD_SET_DISPLAY_CLIENT_BUFFER, ret);
862         }
863 
864         return;
865     }
866 
OnSetLayerCompositionType(CommandDataUnpacker & unpacker)867     void OnSetLayerCompositionType(CommandDataUnpacker& unpacker)
868     {
869         DISPLAY_TRACE;
870 
871         uint32_t devId = 0;
872         uint32_t layerId = 0;
873         int32_t type;
874         int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId);
875         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
876 
877         ret = unpacker.ReadInt32(type) ? HDF_SUCCESS : HDF_FAILURE;
878         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
879 
880         {
881             HdfTrace traceVdi("SetLayerCompositionType", "HDI:DISP:HARDWARE");
882             ret = impl_->SetLayerCompositionType(devId, layerId, static_cast<CompositionType>(type));
883         }
884         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
885 EXIT:
886         if (ret != HDF_SUCCESS) {
887             errMaps_.emplace(REQUEST_CMD_SET_LAYER_COMPOSITION_TYPE, ret);
888         }
889         return;
890     }
891 
OnSetLayerBlendType(CommandDataUnpacker & unpacker)892     void OnSetLayerBlendType(CommandDataUnpacker& unpacker)
893     {
894         DISPLAY_TRACE;
895 
896         uint32_t devId = 0;
897         uint32_t layerId = 0;
898         int32_t type;
899         int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId);
900         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
901 
902         ret = unpacker.ReadInt32(type) ? HDF_SUCCESS : HDF_FAILURE;
903         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
904 
905         {
906             HdfTrace traceVdi("SetLayerBlendType", "HDI:DISP:HARDWARE");
907             ret = impl_->SetLayerBlendType(devId, layerId, static_cast<BlendType>(type));
908         }
909         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
910 EXIT:
911         if (ret != HDF_SUCCESS) {
912             errMaps_.emplace(REQUEST_CMD_SET_LAYER_BLEND_TYPE, ret);
913         }
914         return;
915     }
916 
OnSetLayerMaskInfo(CommandDataUnpacker & unpacker)917     void OnSetLayerMaskInfo(CommandDataUnpacker& unpacker)
918     {
919         DISPLAY_TRACE;
920 
921         uint32_t devId = 0;
922         uint32_t layerId = 0;
923         uint32_t maskInfo = 0;
924 
925         int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId);
926         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
927 
928         ret = unpacker.ReadUint32(maskInfo) ? HDF_SUCCESS : HDF_FAILURE;
929         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
930 
931         {
932             HdfTrace traceVdi("SetLayerMaskInfo", "HDI:DISP:HARDWARE");
933             ret = impl_->SetLayerMaskInfo(devId, layerId, static_cast<MaskInfo>(maskInfo));
934         }
935         DISPLAY_CHECK(ret != HDF_SUCCESS && ret != DISPLAY_NOT_SUPPORT && ret != HDF_ERR_NOT_SUPPORT, goto EXIT);
936 EXIT:
937         if (ret != HDF_SUCCESS) {
938             errMaps_.emplace(REQUEST_CMD_SET_LAYER_MASK_INFO, ret);
939         }
940         return;
941     }
942 
OnSetLayerColor(CommandDataUnpacker & unpacker)943     void OnSetLayerColor(CommandDataUnpacker& unpacker)
944     {
945         DISPLAY_TRACE;
946 
947         uint32_t devId = 0;
948         uint32_t layerId = 0;
949         LayerColor layerColor = {0};
950 
951         int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId);
952         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
953 
954         ret = CmdUtils::LayerColorUnpack(unpacker, layerColor);
955         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
956 
957         {
958             HdfTrace traceVdi("SetLayerColor", "HDI:DISP:HARDWARE");
959             ret = impl_->SetLayerColor(devId, layerId, layerColor);
960         }
961         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
962 EXIT:
963         if (ret != HDF_SUCCESS) {
964             errMaps_.emplace(REQUEST_CMD_SET_LAYER_COLOR, ret);
965         }
966         return;
967     }
968 
PeriodDataReset()969     int32_t PeriodDataReset()
970     {
971         replyCommandCnt_ = 0;
972         errMaps_.clear();
973 
974         int32_t ret = CmdUtils::StartPack(CONTROL_CMD_REPLY_BEGIN, replyPacker_);
975         if (ret != HDF_SUCCESS) {
976             HDF_LOGE("PackBegin failure, ret=%{public}d", ret);
977         }
978         return ret;
979     }
980 
GetFileName(uint32_t devId,uint32_t layerId,const BufferHandle & buffer)981     static std::string GetFileName(uint32_t devId, uint32_t layerId, const BufferHandle& buffer)
982     {
983         struct timeval tv;
984         char nowStr[TIME_BUFFER_MAX_LEN] = {0};
985 
986         gettimeofday(&tv, nullptr);
987         if (strftime(nowStr, sizeof(nowStr), "%m-%d-%H-%M-%S", localtime(&tv.tv_sec)) == 0) {
988             HDF_LOGE("strftime failed");
989             return "";
990         };
991 
992         std::ostringstream strStream;
993         const int32_t PIXEL_BYTES = 4;
994         strStream << "hdi_layer_" << devId << "_" << layerId << "_" << buffer.stride / PIXEL_BYTES << "x" <<
995             buffer.height << "_" << nowStr << "-" << tv.tv_usec;
996         return strStream.str();
997     }
998 #ifdef DISPLAY_COMSPOER_DEBUG_DUMP
DumpLayerBuffer(uint32_t devId,uint32_t layerId,int32_t fence,const BufferHandle & buffer,std::string tag)999     static void DumpLayerBuffer(uint32_t devId, uint32_t layerId, int32_t fence, const BufferHandle& buffer,
1000         std::string tag)
1001     {
1002         const std::string SWITCH_ON = "on";
1003         const uint32_t DUMP_BUFFER_SWITCH_LEN = 4;
1004         char dumpSwitch[DUMP_BUFFER_SWITCH_LEN] = {0};
1005         GetParameter("hdi.composer.dumpbuffer", "off", dumpSwitch, DUMP_BUFFER_SWITCH_LEN);
1006 
1007         if (SWITCH_ON.compare(dumpSwitch) != 0) {
1008             return;
1009         }
1010 
1011         const uint32_t FENCE_TIMEOUT = 3000;
1012         int32_t retCode = WaitFence(fence, FENCE_TIMEOUT);
1013         if (retCode != HDF_SUCCESS) {
1014             return;
1015         }
1016 
1017         if (g_bufferServiceImpl == nullptr) {
1018             g_bufferServiceImpl = IMapper::Get(true);
1019             DISPLAY_CHECK((g_bufferServiceImpl == nullptr), HDF_LOGE("get IMapper failed"));
1020         }
1021 
1022         std::string fileName = GetFileName(devId, layerId, buffer);
1023         DISPLAY_CHECK((fileName == ""), HDF_LOGE("GetFileName failed"));
1024         HDF_LOGI("fileName = %{public}s", fileName.c_str());
1025 
1026         const std::string PATH_PREFIX = "/data/local/traces/";
1027         std::stringstream filePath;
1028         filePath << PATH_PREFIX << tag << fileName;
1029         std::ofstream rawDataFile(filePath.str(), std::ofstream::binary);
1030         DISPLAY_CHECK((!rawDataFile.good()), HDF_LOGE("open file failed, %{public}s",
1031             std::strerror(errno)));
1032 
1033         sptr<NativeBuffer> hdiBuffer = new NativeBuffer();
1034         hdiBuffer->SetBufferHandle(const_cast<BufferHandle*>(&buffer));
1035 
1036         int32_t ret = 0;
1037         ret = g_bufferServiceImpl->Mmap(hdiBuffer);
1038         DISPLAY_CHECK((ret != HDF_SUCCESS), HDF_LOGE("Mmap buffer failed"));
1039 
1040         std::chrono::milliseconds time_before = std::chrono::duration_cast<std::chrono::milliseconds> (
1041             std::chrono::system_clock::now().time_since_epoch()
1042         );
1043         rawDataFile.write(static_cast<const char *>(buffer.virAddr), buffer.size);
1044         std::chrono::milliseconds time_after = std::chrono::duration_cast<std::chrono::milliseconds> (
1045             std::chrono::system_clock::now().time_since_epoch()
1046         );
1047         HDF_LOGI("wirte file take time %{public}lld", time_after.count() - time_before.count());
1048         rawDataFile.close();
1049 
1050         ret = g_bufferServiceImpl->Unmap(hdiBuffer);
1051         DISPLAY_CHECK((ret != HDF_SUCCESS), HDF_LOGE("Unmap buffer failed"));
1052     }
1053 #endif
1054 
WaitFence(int32_t fence,uint32_t timeout)1055     static int32_t WaitFence(int32_t fence, uint32_t timeout)
1056     {
1057         int retCode = -1;
1058         if (fence < 0) {
1059             HDF_LOGE("The fence id is invalid.");
1060             return retCode;
1061         }
1062 
1063         struct pollfd pollfds = {0};
1064         pollfds.fd = fence;
1065         pollfds.events = POLLIN;
1066 
1067         do {
1068             retCode = poll(&pollfds, 1, timeout);
1069         } while (retCode == -1 && (errno == EINTR || errno == EAGAIN));
1070 
1071         if (retCode == 0) {
1072             retCode = -1;
1073             errno = ETIME;
1074         } else if (retCode > 0) {
1075             retCode = 0;
1076             if (pollfds.revents & (POLLERR | POLLNVAL)) {
1077                 retCode = -1;
1078                 errno = EINVAL;
1079             }
1080         }
1081 
1082         return retCode < 0 ? -errno : HDF_SUCCESS;
1083     }
1084 
FreeBufferWithDelay(BufferHandle * handle)1085     void FreeBufferWithDelay(BufferHandle *handle)
1086     {
1087         delayFreeQueue_.push(handle);
1088         if (delayFreeQueue_.size() >= BUFFER_QUEUE_MAX_SIZE) {
1089             BufferHandle *temp = delayFreeQueue_.front();
1090             delayFreeQueue_.pop();
1091             FreeBufferHandle(temp);
1092             temp = nullptr;
1093         }
1094     }
1095 
1096 protected:
1097     VdiImpl* impl_ = nullptr;
1098     std::shared_ptr<DeviceCacheManager> cacheMgr_;
1099     std::shared_ptr<Transfer> request_;
1100     bool isReplyUpdated_;
1101     std::shared_ptr<Transfer> reply_;
1102     /* period data */
1103     uint32_t replyCommandCnt_;
1104     CommandDataPacker replyPacker_;
1105     std::unordered_map<int32_t, int32_t> errMaps_;
1106     /* fix fd leak */
1107     std::queue<BufferHandle *> delayFreeQueue_;
1108     std::mutex requestMutex_;
1109     std::mutex replyMutex_;
1110 };
1111 using HdiDisplayCmdResponser = DisplayCmdResponser<SharedMemQueue<int32_t>, IDisplayComposerVdi>;
1112 } // namespace V1_0
1113 } // namespace Composer
1114 } // namespace Display
1115 } // namespace HDI
1116 } // namespace OHOS
1117 #endif // OHOS_HDI_DISPLAY_V1_0_DISPLAY_CMD_REQUESTER_H