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