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