• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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_2_DISPLAY_CMD_REQUESTER_H
17 #define OHOS_HDI_DISPLAY_V1_2_DISPLAY_CMD_REQUESTER_H
18 
19 #include "v1_0/display_command/display_cmd_responser.h"
20 #include "v1_1/display_command/display_cmd_responser.h"
21 #include "v1_2/display_composer_type.h"
22 #include "v1_2/display_command/display_cmd_utils.h"
23 
24 #define DISPLAY_TRACE HdfTrace trace(__func__, "HDI:DISP:")
25 
26 namespace OHOS {
27 namespace HDI {
28 namespace Display {
29 namespace Composer {
30 namespace V1_2 {
31 using namespace OHOS::HDI::Base;
32 
33 typedef struct CommitInfo {
34     int32_t fence;
35     int32_t skipRet;
36     bool needFlush;
37     std::vector<uint32_t> compLayers;
38     std::vector<int32_t> compTypes;
39     std::vector<uint32_t> layers;
40     std::vector<int32_t> fences;
41 } CommitInfo;
42 
43 template <typename Transfer, typename VdiImpl>
44 class DisplayCmdResponser : public V1_1::DisplayCmdResponser<Transfer, VdiImpl> {
45 public:
Create(VdiImpl * impl,std::shared_ptr<DeviceCacheManager> cacheMgr)46     static std::unique_ptr<DisplayCmdResponser> Create(VdiImpl* impl, std::shared_ptr<DeviceCacheManager> cacheMgr)
47     {
48         DISPLAY_CHK_RETURN(impl == nullptr, nullptr,
49             HDF_LOGE("%{public}s: error, VdiImpl is nullptr", __func__));
50         DISPLAY_CHK_RETURN(cacheMgr == nullptr, nullptr,
51             HDF_LOGE("%{public}s: error, VdiImpl is nullptr", __func__));
52         return std::make_unique<DisplayCmdResponser>(impl, cacheMgr);
53     }
54 
DisplayCmdResponser(VdiImpl * impl,std::shared_ptr<DeviceCacheManager> cacheMgr)55     DisplayCmdResponser(VdiImpl* impl, std::shared_ptr<DeviceCacheManager> cacheMgr) : BaseType1_1(impl, cacheMgr) {}
56 
~DisplayCmdResponser()57     virtual ~DisplayCmdResponser() {}
58 
ProcessRequestCmd(CommandDataUnpacker & unpacker,int32_t cmd,const std::vector<HdifdInfo> & inFds,std::vector<HdifdInfo> & outFds)59     int32_t ProcessRequestCmd(CommandDataUnpacker& unpacker, int32_t cmd,
60         const std::vector<HdifdInfo>& inFds, std::vector<HdifdInfo>& outFds)
61     {
62         HDF_LOGD("%{public}s: HDI 1.2 PackSection, cmd-[%{public}d] = %{public}s",
63             __func__, cmd, CmdUtils::CommandToString(cmd));
64         if (cmd == REQUEST_CMD_COMMIT_AND_GET_RELEASE_FENCE) {
65             OnCommitAndGetReleaseFence(unpacker, outFds);
66         } else if (cmd == REQUEST_CMD_SET_DISPLAY_CONSTRAINT) {
67             OnSetDisplayConstraint(unpacker);
68         } else {
69             return V1_0::DisplayCmdResponser<Transfer, VdiImpl>::ProcessRequestCmd(unpacker, cmd, inFds, outFds);
70         }
71         return HDF_SUCCESS;
72     }
73 
ReplyNotSkipInfo(uint32_t & devId,CommitInfo & commitInfo)74     void ReplyNotSkipInfo(uint32_t& devId, CommitInfo& commitInfo)
75     {
76         DISPLAY_CHECK(replyPacker_.WriteUint32(devId) == false,
77             HDF_LOGE("%{public}s, write devId error", __func__));
78 
79         DISPLAY_CHECK(replyPacker_.WriteBool(commitInfo.needFlush) == false,
80             HDF_LOGE("%{public}s, write needFlush error", __func__));
81 
82         // Write compLayers vector
83         uint32_t vectSize = static_cast<uint32_t>(commitInfo.compLayers.size());
84         DISPLAY_CHECK(replyPacker_.WriteUint32(vectSize) == false,
85             HDF_LOGE("%{public}s, write compLayers.size error", __func__));
86 
87         for (uint32_t i = 0; i < vectSize; i++) {
88             DISPLAY_CHECK(replyPacker_.WriteUint32(commitInfo.compLayers[i]) == false,
89                 HDF_LOGE("%{public}s, write compLayers error", __func__));
90         }
91         // Write compTypes vector
92         vectSize = static_cast<uint32_t>(commitInfo.compTypes.size());
93         DISPLAY_CHECK(replyPacker_.WriteUint32(vectSize) == false,
94             HDF_LOGE("%{public}s, write compTypes.size error", __func__));
95 
96         for (uint32_t i = 0; i < vectSize; i++) {
97             DISPLAY_CHECK(replyPacker_.WriteUint32(commitInfo.compTypes[i]) == false,
98                 HDF_LOGE("%{public}s, write compTypes error", __func__));
99         }
100     }
101 
ReplyCommitAndGetReleaseFence(std::vector<HdifdInfo> & outFds,uint32_t & devId,CommitInfo & commitInfo)102     void ReplyCommitAndGetReleaseFence(std::vector<HdifdInfo>& outFds, uint32_t& devId, CommitInfo& commitInfo)
103     {
104         int32_t ret = HDF_SUCCESS;
105         uint32_t vectSize = 0;
106 
107         HdifdParcelable fdParcel(commitInfo.fence);
108         DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS,
109             CmdUtils::StartSection(REPLY_CMD_COMMIT_AND_GET_RELEASE_FENCE, replyPacker_),
110             HDF_LOGE("%{public}s, StartSection error", __func__));
111 
112         DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::FileDescriptorPack(fdParcel.GetFd(), replyPacker_, outFds),
113             HDF_LOGE("%{public}s, FileDescriptorPack error", __func__));
114 
115         DISPLAY_CHECK(replyPacker_.WriteInt32(commitInfo.skipRet) == false,
116             HDF_LOGE("%{public}s, write skip validate return value error", __func__));
117 
118         if (commitInfo.skipRet != HDF_SUCCESS) {
119             ReplyNotSkipInfo(devId, commitInfo);
120         } else {
121             // Write layers vector
122             vectSize = static_cast<uint32_t>(commitInfo.layers.size());
123             DISPLAY_CHECK(replyPacker_.WriteUint32(vectSize) == false,
124                 HDF_LOGE("%{public}s, write layers.size error", __func__));
125 
126             for (uint32_t i = 0; i < vectSize; i++) {
127                 DISPLAY_CHECK(replyPacker_.WriteUint32(commitInfo.layers[i]) == false,
128                     HDF_LOGE("%{public}s, write layers error", __func__));
129             }
130 
131             // Write fences vector
132             vectSize = static_cast<uint32_t>(commitInfo.fences.size());
133             DISPLAY_CHECK(replyPacker_.WriteUint32(vectSize) == false,
134                 HDF_LOGE("%{public}s, write fences.size error", __func__));
135 
136             for (uint32_t i = 0; i < vectSize; i++) {
137                 ret = CmdUtils::FileDescriptorPack(commitInfo.fences[i], replyPacker_, outFds, false);
138                 DISPLAY_CHECK(ret != HDF_SUCCESS, HDF_LOGE("%{public}s, write fences error", __func__));
139             }
140         }
141 
142         DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::EndSection(replyPacker_),
143             HDF_LOGE("%{public}s, EndSection error", __func__));
144 
145         replyCommandCnt_++;
146 
147 #ifndef DISPLAY_COMMUNITY
148         fdParcel.Move();
149 #endif // DISPLAY_COMMUNITY
150 
151         if (ret != HDF_SUCCESS) {
152             errMaps_.emplace(REQUEST_CMD_COMMIT_AND_GET_RELEASE_FENCE, ret);
153         }
154     }
155 
CommitInfoDump(void)156     void CommitInfoDump(void)
157     {
158 #ifdef DISPLAY_COMSPOER_DEBUG_DUMP
159         const std::string SWITCH_ON = "on";
160         const uint32_t DUMP_CACHE_SWITCH_LEN = 4;
161         char dumpSwitch[DUMP_CACHE_SWITCH_LEN] = {0};
162         GetParameter("hdi.composer.dumpcache", "off", dumpSwitch, DUMP_CACHE_SWITCH_LEN);
163 
164         if (SWITCH_ON.compare(dumpSwitch) == 0) {
165             cacheMgr_->Dump();
166         }
167 #endif
168     }
169 
OnCommitAndGetReleaseFence(CommandDataUnpacker & unpacker,std::vector<HdifdInfo> & outFds)170     void OnCommitAndGetReleaseFence(CommandDataUnpacker& unpacker, std::vector<HdifdInfo>& outFds)
171     {
172         DISPLAY_TRACE;
173         uint32_t devId = 0;
174         bool isSupportSkipValidate = false;
175         bool isValidated = false;
176         int32_t ret = HDF_SUCCESS;
177         CommitInfo commitInfo;
178         commitInfo.fence = -1;
179         commitInfo.skipRet = HDF_FAILURE;
180         commitInfo.needFlush = false;
181 
182         CommitInfoDump();
183         if (!unpacker.ReadUint32(devId)) {
184             HDF_LOGE("%{public}s, read devId error", __func__);
185             goto REPLY;
186         }
187         if (!unpacker.ReadBool(isSupportSkipValidate)) {
188             HDF_LOGE("%{public}s, read isSupportSkipValidate error", __func__);
189             goto REPLY;
190         }
191 
192         if (!unpacker.ReadBool(isValidated)) {
193             HDF_LOGE("%{public}s, read isValidated error", __func__);
194             goto REPLY;
195         }
196         if (isSupportSkipValidate || isValidated) {
197             HdfTrace traceVdi("Commit", "HDI:DISP:HARDWARE");
198             commitInfo.skipRet = impl_->Commit(devId, commitInfo.fence);
199         }
200 
201         if (commitInfo.skipRet != HDF_SUCCESS && isValidated == false) {
202             {
203                 HdfTrace traceVdi("PrepareDisplayLayers", "HDI:DISP:HARDWARE");
204                 ret = impl_->PrepareDisplayLayers(devId, commitInfo.needFlush);
205             }
206             if (ret == HDF_SUCCESS) {
207                 HdfTrace traceVdi("GetDisplayCompChange", "HDI:DISP:HARDWARE");
208                 ret = impl_->GetDisplayCompChange(devId, commitInfo.compLayers, commitInfo.compTypes);
209             }
210         } else {
211             HdfTrace traceVdi("GetDisplayReleaseFence", "HDI:DISP:HARDWARE");
212             if (impl_->GetDisplayReleaseFence(devId, commitInfo.layers, commitInfo.fences) != HDF_SUCCESS) {
213                 HDF_LOGE("%{public}s, GetDisplayReleaseFence failed with ret = %{public}d", __func__, ret);
214             }
215         }
216         HDF_LOGD("skipRet:%{public}d,fence:%{public}d,needFlush:%{public}d, ssv:%{public}d, iv:%{public}d",
217             commitInfo.skipRet, commitInfo.fence, commitInfo.needFlush, isSupportSkipValidate, isValidated);
218 REPLY:
219         ReplyCommitAndGetReleaseFence(outFds, devId, commitInfo);
220     }
221 
CmdRequest(uint32_t inEleCnt,const std::vector<HdifdInfo> & inFds,uint32_t & outEleCnt,std::vector<HdifdInfo> & outFds)222     int32_t CmdRequest(uint32_t inEleCnt, const std::vector<HdifdInfo>& inFds, uint32_t& outEleCnt,
223         std::vector<HdifdInfo>& outFds)
224     {
225         std::shared_ptr<char> requestData(new char[inEleCnt * CmdUtils::ELEMENT_SIZE], std::default_delete<char[]>());
226         int32_t ret = HDF_SUCCESS;
227         {
228             std::lock_guard<std::mutex> lock(requestMutex_);
229             ret = request_->Read(reinterpret_cast<int32_t *>(requestData.get()), inEleCnt,
230                 CmdUtils::TRANSFER_WAIT_TIME);
231         }
232         CommandDataUnpacker unpacker;
233         unpacker.Init(requestData.get(), inEleCnt << CmdUtils::MOVE_SIZE);
234 #ifdef DEBUG_DISPLAY_CMD_RAW_DATA
235         unpacker.Dump();
236 #endif // DEBUG_DISPLAY_CMD_RAW_DATA
237 
238         int32_t unpackCmd = -1;
239         bool retBool = unpacker.PackBegin(unpackCmd);
240         DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE,
241             HDF_LOGE("%{public}s: error: Check RequestBegin failed", __func__));
242         DISPLAY_CHK_RETURN(unpackCmd != CONTROL_CMD_REQUEST_BEGIN, HDF_FAILURE,
243             HDF_LOGI("error: unpacker PackBegin cmd not match, cmd(%{public}d)=%{public}s.", unpackCmd,
244             CmdUtils::CommandToString(unpackCmd)));
245 
246         DISPLAY_CHK_RETURN(PeriodDataReset() == HDF_FAILURE, HDF_FAILURE,
247                            HDF_LOGE("%{public}s: error: PeriodDataReset failed", __func__));
248         while (ret == HDF_SUCCESS && unpacker.NextSection()) {
249             if (!unpacker.BeginSection(unpackCmd)) {
250                 HDF_LOGE("error: PackSection failed, unpackCmd=%{public}s.",
251                     CmdUtils::CommandToString(unpackCmd));
252                 return HDF_FAILURE;
253             }
254             ret = ProcessRequestCmd(unpacker, unpackCmd, inFds, outFds);
255         }
256 
257         DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret,
258             HDF_LOGE("%{public}s: ProcessRequestCmd failed", __func__));
259         /* pack request end commands */
260         replyPacker_.PackEnd(CONTROL_CMD_REPLY_END);
261 
262 #ifdef DEBUG_DISPLAY_CMD_RAW_DATA
263         /* just for debug */
264         replyPacker_.Dump();
265         HDF_LOGI("CmdReply command cnt=%{public}d", replyCommandCnt_);
266 #endif // DEBUG_DISPLAY_CMD_RAW_DATA
267 
268         /*  Write reply pack */
269         outEleCnt = replyPacker_.ValidSize() >> CmdUtils::MOVE_SIZE;
270         {
271             std::lock_guard<std::mutex> lock(replyMutex_);
272             ret = reply_->Write(reinterpret_cast<int32_t *>(replyPacker_.GetDataPtr()), outEleCnt,
273                 CmdUtils::TRANSFER_WAIT_TIME);
274         }
275         if (ret != HDF_SUCCESS) {
276             HDF_LOGE("Reply write failure, ret=%{public}d", ret);
277             outEleCnt = 0;
278         }
279         return ret;
280     }
281 
OnSetDisplayConstraint(CommandDataUnpacker & unpacker)282     int32_t OnSetDisplayConstraint(CommandDataUnpacker& unpacker)
283     {
284         DISPLAY_TRACE;
285         uint32_t devId = 0;
286         uint64_t frameID = 0;
287         uint64_t ns = 0;
288         uint32_t type = 0;
289 
290         int32_t ret = unpacker.ReadUint32(devId) ? HDF_SUCCESS : HDF_FAILURE;
291         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
292 
293         ret = unpacker.ReadUint64(frameID) ? HDF_SUCCESS : HDF_FAILURE;
294         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
295 
296         ret = unpacker.ReadUint64(ns) ? HDF_SUCCESS : HDF_FAILURE;
297         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
298 
299         ret = unpacker.ReadUint32(type) ? HDF_SUCCESS : HDF_FAILURE;
300         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
301 
302         if (impl_ != nullptr && impl_->SetDisplayConstraint != nullptr) {
303             ret = impl_->SetDisplayConstraint(devId, frameID, ns, type);
304         }
305 
306         if (ret != HDF_SUCCESS && ret != DISPLAY_NOT_SUPPORT && ret != HDF_ERR_NOT_SUPPORT) {
307             HDF_LOGE("SetDisplayConstraint failed with ret = %{public}d", ret);
308         }
309 EXIT:
310         if (ret != HDF_SUCCESS) {
311             errMaps_.emplace(REQUEST_CMD_SET_DISPLAY_CONSTRAINT, ret);
312         }
313         return ret;
314     }
315 
316 private:
317     using BaseType1_1 = V1_1::DisplayCmdResponser<Transfer, VdiImpl>;
318     using BaseType1_1::replyPacker_;
319     using BaseType1_1::cacheMgr_;
320     using BaseType1_1::impl_;
321     using BaseType1_1::replyCommandCnt_;
322     using BaseType1_1::errMaps_;
323     using BaseType1_1::request_;
324     using BaseType1_1::reply_;
325     using BaseType1_1::PeriodDataReset;
326     using BaseType1_1::OnPrepareDisplayLayers;
327     using BaseType1_1::OnSetDisplayClientBuffer;
328     using BaseType1_1::OnSetDisplayClientDamage;
329     using BaseType1_1::OnCommit;
330     using BaseType1_1::OnSetLayerAlpha;
331     using BaseType1_1::OnSetLayerRegion;
332     using BaseType1_1::OnSetLayerCrop;
333     using BaseType1_1::OnSetLayerZorder;
334     using BaseType1_1::OnSetLayerPreMulti;
335     using BaseType1_1::OnSetLayerTransformMode;
336     using BaseType1_1::OnSetLayerDirtyRegion;
337     using BaseType1_1::OnSetLayerVisibleRegion;
338     using BaseType1_1::OnSetLayerBuffer;
339     using BaseType1_1::OnSetLayerCompositionType;
340     using BaseType1_1::OnSetLayerBlendType;
341     using BaseType1_1::OnSetLayerMaskInfo;
342     using BaseType1_1::OnRequestEnd;
343     using BaseType1_1::OnSetLayerColor;
344     using BaseType1_1::requestMutex_;
345     using BaseType1_1::replyMutex_;
346 };
347 
348 using HdiDisplayCmdResponser = DisplayCmdResponser<SharedMemQueue<int32_t>, DisplayComposerVdiAdapter>;
349 } // namespace V1_2
350 } // namespace Composer
351 } // namespace Display
352 } // namespace HDI
353 } // namespace OHOS
354 #endif // OHOS_HDI_DISPLAY_V1_2_DISPLAY_CMD_REQUESTER_H