• 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_UTILS_H
17 #define OHOS_HDI_DISPLAY_V1_0_DISPLAY_CMD_UTILS_H
18 
19 #include "buffer_handle_utils.h"
20 #include "command_pack/command_data_packer.h"
21 #include "command_pack/command_data_unpacker.h"
22 #include "common/include/display_interface_utils.h"
23 #include "v1_0/display_composer_type.h"
24 
25 #undef LOG_TAG
26 #define LOG_TAG "DISP_CMD"
27 #undef LOG_DOMAIN
28 #define LOG_DOMAIN 0xD002500
29 
30 namespace OHOS {
31 namespace HDI {
32 namespace Display {
33 namespace Composer {
34 namespace V1_0 {
35 using namespace OHOS::HDI::Display::Composer::V1_0;
36 
37 class DisplayCmdUtils {
38 public:
39     static constexpr int32_t MAX_INT = 0x7fffffff;
40     static constexpr uint32_t ELEMENT_SIZE = sizeof(int32_t);
41     static constexpr uint32_t TRANSFER_WAIT_TIME = 100000000; // ms
42     static constexpr uint32_t INIT_ELEMENT_COUNT = 32 * 1024;
43 
44     #define SWITCHCASE(x) case (x): {return #x;}
CommandToString(int32_t cmdId)45     static const char *CommandToString(int32_t cmdId)
46     {
47         switch (cmdId) {
48             /* request cmd */
49             SWITCHCASE(REQUEST_CMD_PREPARE_DISPLAY_LAYERS);
50             SWITCHCASE(REQUEST_CMD_SET_DISPLAY_CLIENT_BUFFER);
51             SWITCHCASE(REQUEST_CMD_SET_DISPLAY_CLIENT_DAMAGE);
52             SWITCHCASE(REQUEST_CMD_COMMIT);
53             SWITCHCASE(REQUEST_CMD_SET_LAYER_ALPHA);
54             SWITCHCASE(REQUEST_CMD_SET_LAYER_REGION);
55             SWITCHCASE(REQUEST_CMD_SET_LAYER_CROP);
56             SWITCHCASE(REQUEST_CMD_SET_LAYER_ZORDER);
57             SWITCHCASE(REQUEST_CMD_SET_LAYER_PREMULTI);
58             SWITCHCASE(REQUEST_CMD_SET_LAYER_TRANSFORM_MODE);
59             SWITCHCASE(REQUEST_CMD_SET_LAYER_DIRTY_REGION);
60             SWITCHCASE(REQUEST_CMD_SET_LAYER_VISIBLE_REGION);
61             SWITCHCASE(REQUEST_CMD_SET_LAYER_BUFFER);
62             SWITCHCASE(REQUEST_CMD_SET_LAYER_COMPOSITION_TYPE);
63             SWITCHCASE(REQUEST_CMD_SET_LAYER_BLEND_TYPE);
64             SWITCHCASE(REQUEST_CMD_SET_LAYER_COLOR);
65             /* reply cmd */
66             SWITCHCASE(REPLY_CMD_SET_ERROR);
67             SWITCHCASE(REPLY_CMD_PREPARE_DISPLAY_LAYERS);
68             SWITCHCASE(REPLY_CMD_COMMIT);
69             /* pack control cmd */
70             SWITCHCASE(CONTROL_CMD_REQUEST_BEGIN);
71             SWITCHCASE(CONTROL_CMD_REPLY_BEGIN);
72             SWITCHCASE(CONTROL_CMD_REQUEST_END);
73             SWITCHCASE(CONTROL_CMD_REPLY_END);
74             default:
75                 return "unknow command id.";
76         }
77     }
78 
StartPack(int32_t cmdId,std::shared_ptr<CommandDataPacker> packer)79     static int32_t StartPack(int32_t cmdId, std::shared_ptr<CommandDataPacker> packer)
80     {
81         return packer->PackBegin(cmdId) ? HDF_SUCCESS : HDF_FAILURE;
82     }
83 
EndPack(std::shared_ptr<CommandDataPacker> packer)84     static int32_t EndPack(std::shared_ptr<CommandDataPacker> packer)
85     {
86         return packer->PackEnd(CONTROL_CMD_REQUEST_END) ? HDF_SUCCESS : HDF_FAILURE;
87     }
88 
StartSection(int32_t cmdId,std::shared_ptr<CommandDataPacker> packer)89     static int32_t StartSection(int32_t cmdId, std::shared_ptr<CommandDataPacker> packer)
90     {
91         return packer->BeginSection(cmdId) ? HDF_SUCCESS : HDF_FAILURE;
92     }
93 
SetupDevice(uint32_t devId,uint32_t layerId,std::shared_ptr<CommandDataPacker> packer)94     static int32_t SetupDevice(uint32_t devId, uint32_t layerId, std::shared_ptr<CommandDataPacker> packer)
95     {
96         DISPLAY_CHK_RETURN(packer->WriteUint32(devId) == false, HDF_FAILURE,
97             HDF_LOGE("%{public}s, write devId error", __func__));
98         DISPLAY_CHK_RETURN(packer->WriteUint32(layerId) == false, HDF_FAILURE,
99             HDF_LOGE("%{public}s, write layerId error", __func__));
100         return HDF_SUCCESS;
101     }
102 
EndSection(std::shared_ptr<CommandDataPacker> packer)103     static int32_t EndSection(std::shared_ptr<CommandDataPacker> packer)
104     {
105         return packer->EndSection() ? HDF_SUCCESS : HDF_FAILURE;
106     }
107 
GenerateHdifdSeqid()108     static int32_t GenerateHdifdSeqid()
109     {
110         static int32_t HdifdSeqidCursor = 0;
111 
112         if (HdifdSeqidCursor <= MAX_INT) {
113             ++HdifdSeqidCursor;
114             return HdifdSeqidCursor;
115         } else {
116             return 0;
117         }
118     }
119 
MatchHdiFd(int32_t id,std::vector<HdifdInfo> hdiFds,int32_t & fd)120     static bool MatchHdiFd(int32_t id, std::vector<HdifdInfo> hdiFds, int32_t& fd)
121     {
122         for (uint32_t i = 0; i < hdiFds.size(); ++i) {
123             if (hdiFds[i].id == id) {
124                 fd = hdiFds[i].hdiFd->Move();
125                 return true;
126             }
127         }
128         return false;
129     }
130 
RectPack(const IRect & rect,std::shared_ptr<CommandDataPacker> packer)131     static int32_t RectPack(const IRect& rect, std::shared_ptr<CommandDataPacker> packer)
132     {
133         DISPLAY_CHK_RETURN(packer->WriteInt32(rect.x) == false, HDF_FAILURE,
134             HDF_LOGE("%{public}s, write rect.x error", __func__));
135         DISPLAY_CHK_RETURN(packer->WriteInt32(rect.y) == false, HDF_FAILURE,
136             HDF_LOGE("%{public}s, write rect.y error", __func__));
137         DISPLAY_CHK_RETURN(packer->WriteInt32(rect.w) == false, HDF_FAILURE,
138             HDF_LOGE("%{public}s, write rect.w error", __func__));
139         DISPLAY_CHK_RETURN(packer->WriteInt32(rect.h) == false, HDF_FAILURE,
140             HDF_LOGE("%{public}s, write rect.h error", __func__));
141         return HDF_SUCCESS;
142     }
143 
LayerColorPack(const LayerColor & layerColor,std::shared_ptr<CommandDataPacker> packer)144     static int32_t LayerColorPack(const LayerColor& layerColor, std::shared_ptr<CommandDataPacker> packer)
145     {
146         DISPLAY_CHK_RETURN(packer->WriteUint8(layerColor.r) == false, HDF_FAILURE,
147             HDF_LOGE("%{public}s, write layerColor.r error", __func__));
148         DISPLAY_CHK_RETURN(packer->WriteUint8(layerColor.g) == false, HDF_FAILURE,
149             HDF_LOGE("%{public}s, write layerColor.g error", __func__));
150         DISPLAY_CHK_RETURN(packer->WriteUint8(layerColor.b) == false, HDF_FAILURE,
151             HDF_LOGE("%{public}s, write layerColor.b error", __func__));
152         DISPLAY_CHK_RETURN(packer->WriteUint8(layerColor.a) == false, HDF_FAILURE,
153             HDF_LOGE("%{public}s, write layerColor.a error", __func__));
154         return HDF_SUCCESS;
155     }
156 
FileDescriptorPack(const int32_t fd,std::shared_ptr<CommandDataPacker> packer,std::vector<HdifdInfo> & hdiFds)157     static int32_t FileDescriptorPack(
158         const int32_t fd, std::shared_ptr<CommandDataPacker> packer, std::vector<HdifdInfo>& hdiFds)
159     {
160         HdifdInfo hdifdInfo;
161         hdifdInfo.id = GenerateHdifdSeqid();
162         hdifdInfo.hdiFd = new HdifdParcelable();
163         DISPLAY_CHK_RETURN(hdifdInfo.hdiFd == nullptr, HDF_FAILURE,
164             HDF_LOGE("%{public}s, new HdifdParcelable failed", __func__));
165         if (fd >= 0) {
166             // A normal fd is transfered by binder, here just write id for unpacking to match fd.
167             DISPLAY_CHK_RETURN(hdifdInfo.hdiFd->Init(fd) == false, HDF_FAILURE,
168                 HDF_LOGE("%{public}s, hdiFd init failed", __func__));
169             hdiFds.push_back(hdifdInfo);
170             DISPLAY_CHK_RETURN(packer->WriteInt32(hdifdInfo.id) == false, HDF_FAILURE,
171                 HDF_LOGE("%{public}s, hdiFd init failed", __func__));
172         } else {
173             // A illegal fd is transfered by smq directly.
174             DISPLAY_CHK_RETURN(packer->WriteInt32(fd) == false, HDF_FAILURE,
175                 HDF_LOGE("%{public}s, write fd error", __func__));
176         }
177         return HDF_SUCCESS;
178     }
179 
BufferHandlePack(const BufferHandle * buffer,std::shared_ptr<CommandDataPacker> packer,std::vector<HdifdInfo> & hdiFds)180     static int32_t BufferHandlePack(const BufferHandle* buffer, std::shared_ptr<CommandDataPacker> packer,
181         std::vector<HdifdInfo>& hdiFds)
182     {
183         if (buffer == nullptr) {
184             DISPLAY_CHK_RETURN(packer->WriteUint32(UINT32_MAX) == false, HDF_FAILURE,
185                 HDF_LOGE("%{public}s, write null buffer reserveFds error", __func__));
186             DISPLAY_CHK_RETURN(packer->WriteUint32(UINT32_MAX) == false, HDF_FAILURE,
187                 HDF_LOGE("%{public}s, write null buffer reservceInts error", __func__));
188             return HDF_SUCCESS;
189         } else {
190             DISPLAY_CHK_RETURN(packer->WriteUint32(buffer->reserveFds) == false, HDF_FAILURE,
191                 HDF_LOGE("%{public}s, write buffer->reserveFds error", __func__));
192             DISPLAY_CHK_RETURN(packer->WriteUint32(buffer->reserveInts) == false, HDF_FAILURE,
193                 HDF_LOGE("%{public}s, write buffer->reserveInts error", __func__));
194         }
195         int32_t ret = FileDescriptorPack(buffer->fd, packer, hdiFds);
196         if (ret != HDF_SUCCESS) {
197             return ret;
198         }
199         DISPLAY_CHK_RETURN(packer->WriteInt32(buffer->width) == false, HDF_FAILURE,
200             HDF_LOGE("%{public}s, write buffer->width failed", __func__));
201         DISPLAY_CHK_RETURN(packer->WriteInt32(buffer->stride) == false, HDF_FAILURE,
202             HDF_LOGE("%{public}s, write buffer->stride failed", __func__));
203         DISPLAY_CHK_RETURN(packer->WriteInt32(buffer->height) == false, HDF_FAILURE,
204             HDF_LOGE("%{public}s, write buffer->height failed", __func__));
205         DISPLAY_CHK_RETURN(packer->WriteInt32(buffer->size) == false, HDF_FAILURE,
206             HDF_LOGE("%{public}s, write buffer->size failed", __func__));
207         DISPLAY_CHK_RETURN(packer->WriteInt32(buffer->format) == false, HDF_FAILURE,
208             HDF_LOGE("%{public}s, write buffer->format failed", __func__));
209         DISPLAY_CHK_RETURN(packer->WriteUint64(buffer->usage) == false, HDF_FAILURE,
210             HDF_LOGE("%{public}s, write buffer->usage failed", __func__));
211         DISPLAY_CHK_RETURN(packer->WriteUint64(buffer->phyAddr) == false, HDF_FAILURE,
212             HDF_LOGE("%{public}s, write buffer->phyAddr failed", __func__));
213         uint32_t i = 0;
214         for (i = 0; i < buffer->reserveFds; i++) {
215             ret = FileDescriptorPack(buffer->reserve[i], packer, hdiFds);
216             if (ret != HDF_SUCCESS) {
217                 return ret;
218             }
219         }
220         for (uint32_t j = 0; j < buffer->reserveInts; j++) {
221             DISPLAY_CHK_RETURN(packer->WriteInt32(buffer->reserve[i++]) == false, HDF_FAILURE,
222                 HDF_LOGE("%{public}s, write buffer->reserve failed", __func__));
223         }
224         return HDF_SUCCESS;
225     }
226 
SetupDeviceUnpack(std::shared_ptr<CommandDataUnpacker> unpacker,uint32_t & devId,uint32_t & layerId)227     static int32_t SetupDeviceUnpack(std::shared_ptr<CommandDataUnpacker> unpacker, uint32_t& devId, uint32_t& layerId)
228     {
229         DISPLAY_CHK_RETURN(unpacker->ReadUint32(devId) == false, HDF_FAILURE,
230             HDF_LOGE("%{public}s, read devId failed", __func__));
231         DISPLAY_CHK_RETURN(unpacker->ReadUint32(layerId) == false, HDF_FAILURE,
232             HDF_LOGE("%{public}s, read layerId failed", __func__));
233         return HDF_SUCCESS;
234     }
235 
RectUnpack(std::shared_ptr<CommandDataUnpacker> unpacker,IRect & rect)236     static int32_t RectUnpack(std::shared_ptr<CommandDataUnpacker> unpacker, IRect& rect)
237     {
238         DISPLAY_CHK_RETURN(unpacker->ReadInt32(rect.x) == false, HDF_FAILURE,
239             HDF_LOGE("%{public}s, read rect.x failed", __func__));
240         DISPLAY_CHK_RETURN(unpacker->ReadInt32(rect.y) == false, HDF_FAILURE,
241             HDF_LOGE("%{public}s, read rect.y failed", __func__));
242         DISPLAY_CHK_RETURN(unpacker->ReadInt32(rect.w) == false, HDF_FAILURE,
243             HDF_LOGE("%{public}s, read rect.w failed", __func__));
244         DISPLAY_CHK_RETURN(unpacker->ReadInt32(rect.h) == false, HDF_FAILURE,
245             HDF_LOGE("%{public}s, read rect.h failed", __func__));
246         return HDF_SUCCESS;
247     }
248 
FileDescriptorUnpack(std::shared_ptr<CommandDataUnpacker> unpacker,const std::vector<HdifdInfo> & hdiFds,int32_t & fd)249     static int32_t FileDescriptorUnpack(
250         std::shared_ptr<CommandDataUnpacker> unpacker, const std::vector<HdifdInfo>& hdiFds, int32_t& fd)
251     {
252         int32_t fdId = -1;
253         DISPLAY_CHK_RETURN(unpacker->ReadInt32(fdId) == false, HDF_FAILURE,
254             HDF_LOGE("%{public}s, read fdId failed", __func__));
255         if (fdId < 0 || MatchHdiFd(fdId, hdiFds, fd) == false) {
256             // If matching failure, the illegal fd is transfered by smq directly, not by binder IPC.
257             fd = fdId;
258         }
259         return HDF_SUCCESS;
260     }
261 
BufferHandleUnpack(std::shared_ptr<CommandDataUnpacker> unpacker,const std::vector<HdifdInfo> & hdiFds,BufferHandle * & buffer)262     static int32_t BufferHandleUnpack(std::shared_ptr<CommandDataUnpacker> unpacker,
263         const std::vector<HdifdInfo>& hdiFds, BufferHandle*& buffer)
264     {
265         uint32_t fdsNum = 0;
266         uint32_t intsNum = 0;
267         DISPLAY_CHK_RETURN(unpacker->ReadUint32(fdsNum) == false, HDF_FAILURE,
268             HDF_LOGE("%{public}s, read fdsNum error", __func__));
269         DISPLAY_CHK_RETURN(unpacker->ReadUint32(intsNum) == false, HDF_FAILURE,
270             HDF_LOGE("%{public}s, write intsNum error", __func__));
271         if (fdsNum == UINT32_MAX && intsNum == UINT32_MAX) {
272             buffer = nullptr;
273             return HDF_SUCCESS;
274         }
275         BufferHandle *handle = AllocateBufferHandle(fdsNum, intsNum);
276         if (handle == nullptr) {
277             return HDF_FAILURE;
278         }
279         handle->reserveFds = fdsNum;
280         handle->reserveInts = intsNum;
281         int32_t ret = FileDescriptorUnpack(unpacker, hdiFds, handle->fd);
282         bool retVal = (ret == HDF_SUCCESS ? true : false);
283         DISPLAY_CHK_CONDITION(retVal, true, unpacker->ReadInt32(handle->width),
284             HDF_LOGE("%{public}s, read handle->width error", __func__));
285         DISPLAY_CHK_CONDITION(retVal, true, unpacker->ReadInt32(handle->stride),
286             HDF_LOGE("%{public}s, read handle->stride error", __func__));
287         DISPLAY_CHK_CONDITION(retVal, true, unpacker->ReadInt32(handle->height),
288             HDF_LOGE("%{public}s, read handle->height error", __func__));
289         DISPLAY_CHK_CONDITION(retVal, true, unpacker->ReadInt32(handle->size),
290             HDF_LOGE("%{public}s, read handle->size error", __func__));
291         DISPLAY_CHK_CONDITION(retVal, true, unpacker->ReadInt32(handle->format),
292             HDF_LOGE("%{public}s, read handle->format error", __func__));
293         DISPLAY_CHK_CONDITION(retVal, true, unpacker->ReadUint64(handle->usage),
294             HDF_LOGE("%{public}s, read handle->usage error", __func__));
295         DISPLAY_CHK_CONDITION(retVal, true, unpacker->ReadUint64(handle->phyAddr),
296             HDF_LOGE("%{public}s, read handle->phyAddr error", __func__));
297         if (retVal) {
298             uint32_t i = 0;
299             for (i = 0; i < handle->reserveFds; i++) {
300                 ret = FileDescriptorUnpack(unpacker, hdiFds, handle->reserve[i]);
301                 if (ret != HDF_SUCCESS) {
302                     retVal = false;
303                     break;
304                 }
305             }
306             for (uint32_t j = 0; j < handle->reserveInts; j++) {
307                 DISPLAY_CHK_CONDITION(retVal, true, unpacker->ReadInt32(handle->reserve[i++]),
308                     HDF_LOGE("%{public}s, read handle->reserve error", __func__));
309                 if (!retVal) {
310                     HDF_LOGE("%{public}s, get reserve date error, i:%{public}u, j:%{public}u",
311                        __func__, i, j);
312                     break;
313                 }
314             }
315         }
316         if (!retVal) {
317             if (handle != nullptr) {
318                 FreeBufferHandle(handle);
319                 handle = nullptr;
320             }
321             HDF_LOGE("%{public}s: buffer handle unpack failed", __func__);
322         }
323         buffer = handle;
324         return retVal ? HDF_SUCCESS : HDF_FAILURE;
325     }
326 
LayerColorUnpack(std::shared_ptr<CommandDataUnpacker> unpacker,LayerColor & layerColor)327     static int32_t LayerColorUnpack(std::shared_ptr<CommandDataUnpacker> unpacker, LayerColor& layerColor)
328     {
329         DISPLAY_CHK_RETURN(unpacker->ReadUint8(layerColor.r) == false, HDF_FAILURE,
330             HDF_LOGE("%{public}s, read layerColor.r failed", __func__));
331         DISPLAY_CHK_RETURN(unpacker->ReadUint8(layerColor.g) == false, HDF_FAILURE,
332             HDF_LOGE("%{public}s, read layerColor.g failed", __func__));
333         DISPLAY_CHK_RETURN(unpacker->ReadUint8(layerColor.b) == false, HDF_FAILURE,
334             HDF_LOGE("%{public}s, read layerColor.b failed", __func__));
335         DISPLAY_CHK_RETURN(unpacker->ReadUint8(layerColor.a) == false, HDF_FAILURE,
336             HDF_LOGE("%{public}s, read layerColor.a failed", __func__));
337         return HDF_SUCCESS;
338     }
339 };
340 using CmdUtils = DisplayCmdUtils;
341 } // namespace V1_0
342 } // namespace Composer
343 } // namespace Display
344 } // namespace HDI
345 } // namespace OHOS
346 #endif // OHOS_HDI_DISPLAY_V1_0_DISPLAY_CMD_UTILS_H
347