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