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