1 /* 2 * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. 3 * Not a Contribution. 4 * 5 * Copyright (C) 2017 The Android Open Source Project 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 20 #ifndef __QTICOMPOSERCOMMANDBUFFER_H__ 21 #define __QTICOMPOSERCOMMANDBUFFER_H__ 22 23 #include <log/log.h> 24 #include <sync/sync.h> 25 #include <fmq/MessageQueue.h> 26 #include <hidl/MQDescriptor.h> 27 #include <utils/fence.h> 28 29 #include <limits> 30 #include <algorithm> 31 #include <vector> 32 #include <string> 33 34 namespace vendor { 35 namespace qti { 36 namespace hardware { 37 namespace display { 38 namespace composer { 39 namespace V3_0 { 40 41 using ::android::hardware::graphics::common::V1_0::ColorTransform; 42 using ::android::hardware::graphics::common::V1_0::Dataspace; 43 using ::android::hardware::graphics::common::V1_0::Transform; 44 using ::android::hardware::graphics::composer::V2_1::Error; 45 using ::android::hardware::graphics::composer::V2_1::Display; 46 using ::android::hardware::graphics::composer::V2_1::Layer; 47 using ::android::hardware::MessageQueue; 48 using ::android::hardware::MQDescriptorSync; 49 using ::android::hardware::hidl_vec; 50 using ::android::hardware::hidl_handle; 51 52 using CommandQueueType = MessageQueue<uint32_t, ::android::hardware::kSynchronizedReadWrite>; 53 54 using std::shared_ptr; 55 using std::string; 56 using sdm::Fence; 57 58 // This class helps build a command queue. Note that all sizes/lengths are in units of uint32_t's. 59 class CommandWriter { 60 public: CommandWriter(uint32_t initialMaxSize)61 explicit CommandWriter(uint32_t initialMaxSize) : mDataMaxSize(initialMaxSize) { 62 mData = std::make_unique<uint32_t[]>(mDataMaxSize); 63 reset(); 64 } 65 ~CommandWriter()66 ~CommandWriter() { reset(); } 67 reset()68 void reset() { 69 mDataWritten = 0; 70 mCommandEnd = 0; 71 72 // handles in mDataHandles are owned by the caller 73 mDataHandles.clear(); 74 75 // handles in mTemporaryHandles are owned by the writer 76 for (auto handle : mTemporaryHandles) { 77 native_handle_close(handle); 78 native_handle_delete(handle); 79 } 80 mTemporaryHandles.clear(); 81 } 82 getCommand(uint32_t offset)83 IQtiComposerClient::Command getCommand(uint32_t offset) { 84 uint32_t val = (offset < mDataWritten) ? mData[offset] : 0; 85 return static_cast<IQtiComposerClient::Command>(val & 86 static_cast<uint32_t>(IQtiComposerClient::Command::OPCODE_MASK)); 87 } 88 writeQueue(bool & queueChanged,uint32_t & commandLength,hidl_vec<hidl_handle> & commandHandles)89 bool writeQueue(bool& queueChanged, uint32_t& commandLength, 90 hidl_vec<hidl_handle>& commandHandles) { 91 if (mDataWritten == 0) { 92 queueChanged = false; 93 commandLength = 0; 94 commandHandles.setToExternal(nullptr, 0); 95 return true; 96 } 97 98 // After data are written to the queue, it may not be read by the 99 // remote reader when 100 // 101 // - the writer does not send them (because of other errors) 102 // - the hwbinder transaction fails 103 // - the reader does not read them (because of other errors) 104 // 105 // Discard the stale data here. 106 size_t staleDataSize = mQueue ? mQueue->availableToRead() : 0; 107 if (staleDataSize > 0) { 108 ALOGW("discarding stale data from message queue"); 109 CommandQueueType::MemTransaction tx; 110 if (mQueue->beginRead(staleDataSize, &tx)) { 111 mQueue->commitRead(staleDataSize); 112 } 113 } 114 // write data to queue, optionally resizing it 115 if (mQueue && (mDataMaxSize <= mQueue->getQuantumCount())) { 116 if (!mQueue->write(mData.get(), mDataWritten)) { 117 ALOGE("failed to write commands to message queue"); 118 return false; 119 } 120 121 queueChanged = false; 122 } else { 123 auto newQueue = std::make_unique<CommandQueueType>(mDataMaxSize); 124 if (!newQueue->isValid() || !newQueue->write(mData.get(), mDataWritten)) { 125 ALOGE("failed to prepare a new message queue "); 126 return false; 127 } 128 129 mQueue = std::move(newQueue); 130 queueChanged = true; 131 } 132 133 commandLength = mDataWritten; 134 commandHandles.setToExternal(const_cast<hidl_handle*>(mDataHandles.data()), 135 mDataHandles.size()); 136 137 return true; 138 } 139 getMQDescriptor()140 const MQDescriptorSync<uint32_t>* getMQDescriptor() const { 141 return (mQueue) ? mQueue->getDesc() : nullptr; 142 } 143 144 // Commands from ::android::hardware::graphics::composer::V2_1::IComposerClient follow. 145 static constexpr uint16_t kSelectDisplayLength = 2; selectDisplay(Display display)146 void selectDisplay(Display display) { 147 beginCommand(IQtiComposerClient::Command::SELECT_DISPLAY, kSelectDisplayLength); 148 write64(display); 149 endCommand(); 150 } 151 152 static constexpr uint16_t kSelectLayerLength = 2; selectLayer(Layer layer)153 void selectLayer(Layer layer) { 154 beginCommand(IQtiComposerClient::Command::SELECT_LAYER, kSelectLayerLength); 155 write64(layer); 156 endCommand(); 157 } 158 159 static constexpr uint16_t kSetErrorLength = 2; setError(uint32_t location,Error error)160 void setError(uint32_t location, Error error) { 161 beginCommand(IQtiComposerClient::Command::SET_ERROR, kSetErrorLength); 162 write(location); 163 writeSigned(static_cast<int32_t>(error)); 164 endCommand(); 165 } 166 167 static constexpr uint32_t kPresentOrValidateDisplayResultLength = 1; setPresentOrValidateResult(uint32_t state)168 void setPresentOrValidateResult(uint32_t state) { 169 beginCommand(IQtiComposerClient::Command::SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT, 170 kPresentOrValidateDisplayResultLength); 171 write(state); 172 endCommand(); 173 } 174 setChangedCompositionTypes(const std::vector<Layer> & layers,const std::vector<IQtiComposerClient::Composition> & types)175 void setChangedCompositionTypes(const std::vector<Layer>& layers, 176 const std::vector<IQtiComposerClient::Composition>& types) { 177 size_t totalLayers = std::min(layers.size(), types.size()); 178 size_t currentLayer = 0; 179 180 while (currentLayer < totalLayers) { 181 size_t count = std::min(totalLayers - currentLayer, static_cast<size_t>(kMaxLength) / 3); 182 183 beginCommand(IQtiComposerClient::Command::SET_CHANGED_COMPOSITION_TYPES, count * 3); 184 for (size_t i = 0; i < count; i++) { 185 write64(layers[currentLayer + i]); 186 writeSigned(static_cast<int32_t>(types[currentLayer + i])); 187 } 188 endCommand(); 189 190 currentLayer += count; 191 } 192 } 193 setDisplayRequests(uint32_t displayRequestMask,const std::vector<Layer> & layers,const std::vector<uint32_t> & layerRequestMasks)194 void setDisplayRequests(uint32_t displayRequestMask, const std::vector<Layer>& layers, 195 const std::vector<uint32_t>& layerRequestMasks) { 196 size_t totalLayers = std::min(layers.size(), layerRequestMasks.size()); 197 size_t currentLayer = 0; 198 199 while (currentLayer < totalLayers) { 200 size_t count = std::min(totalLayers - currentLayer, static_cast<size_t>(kMaxLength - 1) / 3); 201 202 beginCommand(IQtiComposerClient::Command::SET_DISPLAY_REQUESTS, 1 + count * 3); 203 write(displayRequestMask); 204 for (size_t i = 0; i < count; i++) { 205 write64(layers[currentLayer + i]); 206 write(static_cast<int32_t>(layerRequestMasks[currentLayer + i])); 207 } 208 endCommand(); 209 210 currentLayer += count; 211 } 212 } 213 214 static constexpr uint16_t kSetPresentFenceLength = 1; setPresentFence(const shared_ptr<Fence> & presentFence)215 void setPresentFence(const shared_ptr<Fence> &presentFence) { 216 beginCommand(IQtiComposerClient::Command::SET_PRESENT_FENCE, kSetPresentFenceLength); 217 writeFence(presentFence); 218 endCommand(); 219 } 220 setReleaseFences(const std::vector<Layer> & layers,const std::vector<shared_ptr<Fence>> & releaseFences)221 void setReleaseFences(const std::vector<Layer>& layers, 222 const std::vector<shared_ptr<Fence>>& releaseFences) { 223 size_t totalLayers = std::min(layers.size(), releaseFences.size()); 224 size_t currentLayer = 0; 225 226 while (currentLayer < totalLayers) { 227 size_t count = std::min(totalLayers - currentLayer, static_cast<size_t>(kMaxLength) / 3); 228 229 beginCommand(IQtiComposerClient::Command::SET_RELEASE_FENCES, count * 3); 230 for (size_t i = 0; i < count; i++) { 231 write64(layers[currentLayer + i]); 232 writeFence(releaseFences[currentLayer + i]); 233 } 234 endCommand(); 235 236 currentLayer += count; 237 } 238 } 239 240 static constexpr uint16_t kSetColorTransformLength = 17; setColorTransform(const float * matrix,ColorTransform hint)241 void setColorTransform(const float* matrix, ColorTransform hint) { 242 beginCommand(IQtiComposerClient::Command::SET_COLOR_TRANSFORM, kSetColorTransformLength); 243 for (int i = 0; i < 16; i++) { 244 writeFloat(matrix[i]); 245 } 246 writeSigned(static_cast<int32_t>(hint)); 247 endCommand(); 248 } 249 setClientTarget(uint32_t slot,const native_handle_t * target,const shared_ptr<Fence> & acquireFence,Dataspace dataspace,const std::vector<IQtiComposerClient::Rect> & damage)250 void setClientTarget(uint32_t slot, const native_handle_t* target, 251 const shared_ptr<Fence>& acquireFence, Dataspace dataspace, 252 const std::vector<IQtiComposerClient::Rect>& damage) { 253 bool doWrite = (damage.size() <= (kMaxLength - 4) / 4); 254 size_t length = 4 + ((doWrite) ? damage.size() * 4 : 0); 255 256 beginCommand(IQtiComposerClient::Command::SET_CLIENT_TARGET, length); 257 write(slot); 258 writeHandle(target, true); 259 writeFence(acquireFence); 260 writeSigned(static_cast<int32_t>(dataspace)); 261 // When there are too many rectangles in the damage region and doWrite 262 // is false, we write no rectangle at all which means the entire 263 // client target is damaged. 264 if (doWrite) { 265 writeRegion(damage); 266 } 267 endCommand(); 268 } 269 270 static constexpr uint16_t kSetOutputBufferLength = 3; setOutputBuffer(uint32_t slot,const native_handle_t * buffer,const shared_ptr<Fence> & releaseFence)271 void setOutputBuffer(uint32_t slot, const native_handle_t* buffer, 272 const shared_ptr<Fence>& releaseFence) { 273 beginCommand(IQtiComposerClient::Command::SET_OUTPUT_BUFFER, kSetOutputBufferLength); 274 write(slot); 275 writeHandle(buffer, true); 276 writeFence(releaseFence); 277 endCommand(); 278 } 279 280 static constexpr uint16_t kValidateDisplayLength = 0; validateDisplay()281 void validateDisplay() { 282 beginCommand(IQtiComposerClient::Command::VALIDATE_DISPLAY, kValidateDisplayLength); 283 endCommand(); 284 } 285 286 static constexpr uint16_t kPresentOrValidateDisplayLength = 0; presentOrvalidateDisplay()287 void presentOrvalidateDisplay() { 288 beginCommand(IQtiComposerClient::Command::PRESENT_OR_VALIDATE_DISPLAY, 289 kPresentOrValidateDisplayLength); 290 endCommand(); 291 } 292 293 static constexpr uint16_t kAcceptDisplayChangesLength = 0; acceptDisplayChanges()294 void acceptDisplayChanges() { 295 beginCommand(IQtiComposerClient::Command::ACCEPT_DISPLAY_CHANGES, kAcceptDisplayChangesLength); 296 endCommand(); 297 } 298 299 static constexpr uint16_t kPresentDisplayLength = 0; presentDisplay()300 void presentDisplay() { 301 beginCommand(IQtiComposerClient::Command::PRESENT_DISPLAY, kPresentDisplayLength); 302 endCommand(); 303 } 304 305 static constexpr uint16_t kSetLayerCursorPositionLength = 2; setLayerCursorPosition(int32_t x,int32_t y)306 void setLayerCursorPosition(int32_t x, int32_t y) { 307 beginCommand(IQtiComposerClient::Command::SET_LAYER_CURSOR_POSITION, 308 kSetLayerCursorPositionLength); 309 writeSigned(x); 310 writeSigned(y); 311 endCommand(); 312 } 313 314 static constexpr uint16_t kSetLayerBufferLength = 3; setLayerBuffer(uint32_t slot,const native_handle_t * buffer,const shared_ptr<Fence> & acquireFence)315 void setLayerBuffer(uint32_t slot, const native_handle_t* buffer, 316 const shared_ptr<Fence>& acquireFence) { 317 beginCommand(IQtiComposerClient::Command::SET_LAYER_BUFFER, kSetLayerBufferLength); 318 write(slot); 319 writeHandle(buffer, true); 320 writeFence(acquireFence); 321 endCommand(); 322 } 323 setLayerSurfaceDamage(const std::vector<IQtiComposerClient::Rect> & damage)324 void setLayerSurfaceDamage(const std::vector<IQtiComposerClient::Rect>& damage) { 325 bool doWrite = (damage.size() <= kMaxLength / 4); 326 size_t length = (doWrite) ? damage.size() * 4 : 0; 327 328 beginCommand(IQtiComposerClient::Command::SET_LAYER_SURFACE_DAMAGE, length); 329 // When there are too many rectangles in the damage region and doWrite 330 // is false, we write no rectangle at all which means the entire 331 // layer is damaged. 332 if (doWrite) { 333 writeRegion(damage); 334 } 335 endCommand(); 336 } 337 338 static constexpr uint16_t kSetLayerBlendModeLength = 1; setLayerBlendMode(IQtiComposerClient::BlendMode mode)339 void setLayerBlendMode(IQtiComposerClient::BlendMode mode) { 340 beginCommand(IQtiComposerClient::Command::SET_LAYER_BLEND_MODE, kSetLayerBlendModeLength); 341 writeSigned(static_cast<int32_t>(mode)); 342 endCommand(); 343 } 344 345 static constexpr uint16_t kSetLayerColorLength = 1; setLayerColor(IQtiComposerClient::Color color)346 void setLayerColor(IQtiComposerClient::Color color) { 347 beginCommand(IQtiComposerClient::Command::SET_LAYER_COLOR, kSetLayerColorLength); 348 writeColor(color); 349 endCommand(); 350 } 351 352 static constexpr uint16_t kSetLayerCompositionTypeLength = 1; setLayerCompositionType(IQtiComposerClient::Composition type)353 void setLayerCompositionType(IQtiComposerClient::Composition type) { 354 beginCommand(IQtiComposerClient::Command::SET_LAYER_COMPOSITION_TYPE, 355 kSetLayerCompositionTypeLength); 356 writeSigned(static_cast<int32_t>(type)); 357 endCommand(); 358 } 359 360 static constexpr uint16_t kSetLayerDataspaceLength = 1; setLayerDataspace(Dataspace dataspace)361 void setLayerDataspace(Dataspace dataspace) { 362 beginCommand(IQtiComposerClient::Command::SET_LAYER_DATASPACE, kSetLayerDataspaceLength); 363 writeSigned(static_cast<int32_t>(dataspace)); 364 endCommand(); 365 } 366 367 static constexpr uint16_t kSetLayerDisplayFrameLength = 4; setLayerDisplayFrame(const IQtiComposerClient::Rect & frame)368 void setLayerDisplayFrame(const IQtiComposerClient::Rect& frame) { 369 beginCommand(IQtiComposerClient::Command::SET_LAYER_DISPLAY_FRAME, kSetLayerDisplayFrameLength); 370 writeRect(frame); 371 endCommand(); 372 } 373 374 static constexpr uint16_t kSetLayerPlaneAlphaLength = 1; setLayerPlaneAlpha(float alpha)375 void setLayerPlaneAlpha(float alpha) { 376 beginCommand(IQtiComposerClient::Command::SET_LAYER_PLANE_ALPHA, kSetLayerPlaneAlphaLength); 377 writeFloat(alpha); 378 endCommand(); 379 } 380 381 static constexpr uint16_t kSetLayerSidebandStreamLength = 1; setLayerSidebandStream(const native_handle_t * stream)382 void setLayerSidebandStream(const native_handle_t* stream) { 383 beginCommand(IQtiComposerClient::Command::SET_LAYER_SIDEBAND_STREAM, 384 kSetLayerSidebandStreamLength); 385 writeHandle(stream); 386 endCommand(); 387 } 388 389 static constexpr uint16_t kSetLayerSourceCropLength = 4; setLayerSourceCrop(const IQtiComposerClient::FRect & crop)390 void setLayerSourceCrop(const IQtiComposerClient::FRect& crop) { 391 beginCommand(IQtiComposerClient::Command::SET_LAYER_SOURCE_CROP, kSetLayerSourceCropLength); 392 writeFRect(crop); 393 endCommand(); 394 } 395 396 static constexpr uint16_t kSetLayerTransformLength = 1; setLayerTransform(Transform transform)397 void setLayerTransform(Transform transform) { 398 beginCommand(IQtiComposerClient::Command::SET_LAYER_TRANSFORM, kSetLayerTransformLength); 399 writeSigned(static_cast<int32_t>(transform)); 400 endCommand(); 401 } 402 setLayerVisibleRegion(const std::vector<IQtiComposerClient::Rect> & visible)403 void setLayerVisibleRegion(const std::vector<IQtiComposerClient::Rect>& visible) { 404 bool doWrite = (visible.size() <= kMaxLength / 4); 405 size_t length = (doWrite) ? visible.size() * 4 : 0; 406 407 beginCommand(IQtiComposerClient::Command::SET_LAYER_VISIBLE_REGION, length); 408 // When there are too many rectangles in the visible region and 409 // doWrite is false, we write no rectangle at all which means the 410 // entire layer is visible. 411 if (doWrite) { 412 writeRegion(visible); 413 } 414 endCommand(); 415 } 416 417 static constexpr uint16_t kSetLayerZOrderLength = 1; setLayerZOrder(uint32_t z)418 void setLayerZOrder(uint32_t z) { 419 beginCommand(IQtiComposerClient::Command::SET_LAYER_Z_ORDER, kSetLayerZOrderLength); 420 write(z); 421 endCommand(); 422 } 423 424 static constexpr uint16_t kSetLayerTypeLength = 1; setLayerType(uint32_t z)425 void setLayerType(uint32_t z) { 426 beginCommand(IQtiComposerClient::Command::SET_LAYER_TYPE, kSetLayerTypeLength); 427 write(z); 428 endCommand(); 429 } 430 431 // Commands from ::android::hardware::graphics::composer::V2_2::IComposerClient follow. 432 static constexpr uint16_t kSetLayerFloatColorLength = 4; setLayerFloatColor(IQtiComposerClient::FloatColor color)433 void setLayerFloatColor(IQtiComposerClient::FloatColor color) { 434 beginCommand(IQtiComposerClient::Command::SET_LAYER_FLOAT_COLOR, kSetLayerFloatColorLength); 435 writeFloatColor(color); 436 endCommand(); 437 } 438 setLayerPerFrameMetadata(const hidl_vec<IQtiComposerClient::PerFrameMetadata> & metadataVec)439 void setLayerPerFrameMetadata(const hidl_vec<IQtiComposerClient::PerFrameMetadata>& metadataVec) { 440 beginCommand(IQtiComposerClient::Command::SET_LAYER_PER_FRAME_METADATA, 441 metadataVec.size() * 2); 442 for (const auto& metadata : metadataVec) { 443 writeSigned(static_cast<int32_t>(metadata.key)); 444 writeFloat(metadata.value); 445 } 446 endCommand(); 447 } 448 449 // Commands from ::android::hardware::graphics::composer::V2_3::IComposerClient follow. 450 static constexpr uint16_t kSetLayerColorTransformLength = 16; setLayerColorTransform(const float * matrix)451 void setLayerColorTransform(const float* matrix) { 452 beginCommand(IQtiComposerClient::Command::SET_LAYER_COLOR_TRANSFORM, 453 kSetLayerColorTransformLength); 454 for (int i = 0; i < 16; i++) { 455 writeFloat(matrix[i]); 456 } 457 endCommand(); 458 } 459 setLayerPerFrameMetadataBlobs(const hidl_vec<IQtiComposerClient::PerFrameMetadataBlob> & metadata)460 void setLayerPerFrameMetadataBlobs( 461 const hidl_vec<IQtiComposerClient::PerFrameMetadataBlob>& metadata) { 462 size_t commandLength = 0; 463 464 if (metadata.size() > std::numeric_limits<uint32_t>::max()) { 465 LOG_FATAL("too many metadata blobs - dynamic metadata size is too large"); 466 return; 467 } 468 469 // number of blobs 470 commandLength += metadata.size(); 471 472 for (auto metadataBlob : metadata) { 473 commandLength += sizeof(int32_t); // key of metadata blob 474 commandLength += 1; // size information of metadata blob 475 476 // metadata content size 477 size_t metadataSize = metadataBlob.blob.size() / sizeof(uint32_t); 478 commandLength += metadataSize; 479 commandLength += (metadataBlob.blob.size() - (metadataSize * sizeof(uint32_t)) > 0) ? 1 : 0; 480 } 481 482 if (commandLength > std::numeric_limits<uint16_t>::max()) { 483 LOG_FATAL("dynamic metadata size is too large"); 484 return; 485 } 486 487 // Blobs are written as: 488 // {numElements, key1, size1, blob1, key2, size2, blob2, key3, size3...} 489 uint16_t length = static_cast<uint16_t>(commandLength); 490 beginCommand(IQtiComposerClient::Command::SET_LAYER_PER_FRAME_METADATA_BLOBS, length); 491 write(static_cast<uint32_t>(metadata.size())); 492 for (auto metadataBlob : metadata) { 493 writeSigned(static_cast<int32_t>(metadataBlob.key)); 494 write(static_cast<uint32_t>(metadataBlob.blob.size())); 495 writeBlob(static_cast<uint32_t>(metadataBlob.blob.size()), metadataBlob.blob.data()); 496 } 497 endCommand(); 498 } 499 500 static constexpr uint16_t kSetDisplayElapseTime = 2; setDisplayElapseTime(uint64_t time)501 void setDisplayElapseTime(uint64_t time) { 502 beginCommand(IQtiComposerClient::Command::SET_DISPLAY_ELAPSE_TIME, kSetDisplayElapseTime); 503 write64(time); 504 endCommand(); 505 } 506 507 // Commands from ::android::hardware::graphics::composer::V2_4::IComposerClient follow. 508 static constexpr uint16_t kSetClientTargetPropertyLength = 2; setClientTargetProperty(const IQtiComposerClient::ClientTargetProperty & clientTargetProperty)509 void setClientTargetProperty( 510 const IQtiComposerClient::ClientTargetProperty& clientTargetProperty) { 511 beginCommand(IQtiComposerClient::Command::SET_CLIENT_TARGET_PROPERTY, 512 kSetClientTargetPropertyLength); 513 writeSigned(static_cast<int32_t>(clientTargetProperty.pixelFormat)); 514 writeSigned(static_cast<int32_t>(clientTargetProperty.dataspace)); 515 endCommand(); 516 } 517 518 protected: 519 // Commands from ::android::hardware::graphics::composer::V2_1::IComposerClient follow. beginCommand(IQtiComposerClient::Command command,uint16_t length)520 void beginCommand(IQtiComposerClient::Command command, uint16_t length) { 521 if (mCommandEnd) { 522 LOG_FATAL("endCommand was not called before command 0x%x", command); 523 } 524 525 growData(1 + length); 526 write(static_cast<uint32_t>(command) | length); 527 528 mCommandEnd = mDataWritten + length; 529 } 530 endCommand()531 void endCommand() { 532 if (!mCommandEnd) { 533 LOG_FATAL("beginCommand was not called"); 534 } else if (mDataWritten > mCommandEnd) { 535 LOG_FATAL("too much data written"); 536 mDataWritten = mCommandEnd; 537 } else if (mDataWritten < mCommandEnd) { 538 LOG_FATAL("too little data written"); 539 while (mDataWritten < mCommandEnd) { 540 write(0); 541 } 542 } 543 544 mCommandEnd = 0; 545 } 546 write(uint32_t val)547 void write(uint32_t val) { mData[mDataWritten++] = val; } 548 writeSigned(int32_t val)549 void writeSigned(int32_t val) { memcpy(&mData[mDataWritten++], &val, sizeof(val)); } 550 writeFloat(float val)551 void writeFloat(float val) { memcpy(&mData[mDataWritten++], &val, sizeof(val)); } 552 write64(uint64_t val)553 void write64(uint64_t val) { 554 uint32_t lo = static_cast<uint32_t>(val & 0xffffffff); 555 uint32_t hi = static_cast<uint32_t>(val >> 32); 556 write(lo); 557 write(hi); 558 } 559 writeRect(const IQtiComposerClient::Rect & rect)560 void writeRect(const IQtiComposerClient::Rect& rect) { 561 writeSigned(rect.left); 562 writeSigned(rect.top); 563 writeSigned(rect.right); 564 writeSigned(rect.bottom); 565 } 566 writeRegion(const std::vector<IQtiComposerClient::Rect> & region)567 void writeRegion(const std::vector<IQtiComposerClient::Rect>& region) { 568 for (const auto& rect : region) { 569 writeRect(rect); 570 } 571 } 572 writeFRect(const IQtiComposerClient::FRect & rect)573 void writeFRect(const IQtiComposerClient::FRect& rect) { 574 writeFloat(rect.left); 575 writeFloat(rect.top); 576 writeFloat(rect.right); 577 writeFloat(rect.bottom); 578 } 579 writeColor(const IQtiComposerClient::Color & color)580 void writeColor(const IQtiComposerClient::Color& color) { 581 write((color.r << 0) | (color.g << 8) | (color.b << 16) | (color.a << 24)); 582 } 583 584 // ownership of handle is not transferred writeHandle(const native_handle_t * handle,bool useCache)585 void writeHandle(const native_handle_t* handle, bool useCache) { 586 if (!handle) { 587 writeSigned(static_cast<int32_t>((useCache) ? 588 IQtiComposerClient::HandleIndex::CACHED : IQtiComposerClient::HandleIndex::EMPTY)); 589 return; 590 } 591 592 mDataHandles.push_back(handle); 593 writeSigned(mDataHandles.size() - 1); 594 } 595 writeHandle(const native_handle_t * handle)596 void writeHandle(const native_handle_t* handle) { 597 writeHandle(handle, false); 598 } 599 600 // Handle would own fence hereafter. Hence provide a dupped fd. writeFence(const shared_ptr<Fence> & fence)601 void writeFence(const shared_ptr<Fence>& fence) { 602 native_handle_t* handle = nullptr; 603 if (fence) { 604 handle = getTemporaryHandle(1, 0); 605 if (handle) { 606 handle->data[0] = Fence::Dup(fence); 607 } else { 608 ALOGW("failed to get temporary handle for fence %s", Fence::GetStr(fence).c_str()); 609 Fence::Wait(fence); 610 } 611 } 612 613 writeHandle(handle); 614 } 615 getTemporaryHandle(int numFds,int numInts)616 native_handle_t* getTemporaryHandle(int numFds, int numInts) { 617 native_handle_t* handle = native_handle_create(numFds, numInts); 618 if (handle) { 619 mTemporaryHandles.push_back(handle); 620 } 621 return handle; 622 } 623 624 static constexpr uint16_t kMaxLength = std::numeric_limits<uint16_t>::max(); 625 626 // Commands from ::android::hardware::graphics::composer::V2_2::IComposerClient follow. writeFloatColor(const IQtiComposerClient::FloatColor & color)627 void writeFloatColor(const IQtiComposerClient::FloatColor& color) { 628 writeFloat(color.r); 629 writeFloat(color.g); 630 writeFloat(color.b); 631 writeFloat(color.a); 632 } 633 634 // Commands from ::android::hardware::graphics::composer::V2_3::IComposerClient follow. writeBlob(uint32_t length,const unsigned char * blob)635 void writeBlob(uint32_t length, const unsigned char* blob) { 636 memcpy(&mData[mDataWritten], blob, length); 637 uint32_t numElements = length / 4; 638 mDataWritten += numElements; 639 mDataWritten += (length - (numElements * 4) > 0) ? 1 : 0; 640 } 641 642 private: growData(uint32_t grow)643 void growData(uint32_t grow) { 644 uint32_t newWritten = mDataWritten + grow; 645 if (newWritten < mDataWritten) { 646 LOG_ALWAYS_FATAL("buffer overflowed; data written %" PRIu32 647 ", growing by %" PRIu32, mDataWritten, grow); 648 } 649 650 if (newWritten <= mDataMaxSize) { 651 return; 652 } 653 654 uint32_t newMaxSize = mDataMaxSize << 1; 655 if (newMaxSize < newWritten) { 656 newMaxSize = newWritten; 657 } 658 659 auto newData = std::make_unique<uint32_t[]>(newMaxSize); 660 std::copy_n(mData.get(), mDataWritten, newData.get()); 661 mDataMaxSize = newMaxSize; 662 mData = std::move(newData); 663 } 664 665 uint32_t mDataMaxSize; 666 std::unique_ptr<uint32_t[]> mData; 667 668 uint32_t mDataWritten; 669 // end offset of the current command 670 uint32_t mCommandEnd; 671 672 std::vector<hidl_handle> mDataHandles; 673 std::vector<native_handle_t *> mTemporaryHandles; 674 675 std::unique_ptr<CommandQueueType> mQueue; 676 }; 677 678 // This class helps parse a command queue. Note that all sizes/lengths are in units of uint32_t's. 679 class CommandReaderBase { 680 public: CommandReaderBase()681 CommandReaderBase() : mDataMaxSize(0) { reset(); } 682 setMQDescriptor(const MQDescriptorSync<uint32_t> & descriptor)683 bool setMQDescriptor(const MQDescriptorSync<uint32_t>& descriptor) { 684 mQueue = std::make_unique<CommandQueueType>(descriptor, false); 685 if (mQueue->isValid()) { 686 return true; 687 } else { 688 mQueue = nullptr; 689 return false; 690 } 691 } 692 readQueue(uint32_t commandLength,const hidl_vec<hidl_handle> & commandHandles)693 bool readQueue(uint32_t commandLength, const hidl_vec<hidl_handle>& commandHandles) { 694 if (!mQueue) { 695 return false; 696 } 697 698 auto quantumCount = mQueue->getQuantumCount(); 699 if (mDataMaxSize < quantumCount) { 700 mDataMaxSize = quantumCount; 701 mData = std::make_unique<uint32_t[]>(mDataMaxSize); 702 } 703 704 if (commandLength > mDataMaxSize || !mQueue->read(mData.get(), commandLength)) { 705 ALOGE("failed to read commands from message queue"); 706 return false; 707 } 708 709 mDataSize = commandLength; 710 mDataRead = 0; 711 mCommandBegin = 0; 712 mCommandEnd = 0; 713 mDataHandles.setToExternal(const_cast<hidl_handle*>(commandHandles.data()), 714 commandHandles.size()); 715 716 return true; 717 } 718 reset()719 void reset() { 720 mDataSize = 0; 721 mDataRead = 0; 722 mCommandBegin = 0; 723 mCommandEnd = 0; 724 mDataHandles.setToExternal(nullptr, 0); 725 } 726 727 protected: isEmpty()728 bool isEmpty() const { return (mDataRead >= mDataSize); } 729 beginCommand(IQtiComposerClient::Command & command,uint16_t & length)730 bool beginCommand(IQtiComposerClient::Command& command, uint16_t& length) { 731 if (mCommandEnd) { 732 LOG_FATAL("endCommand was not called before command 0x%x", command); 733 } 734 735 constexpr uint32_t opcode_mask = 736 static_cast<uint32_t>(IQtiComposerClient::Command::OPCODE_MASK); 737 constexpr uint32_t length_mask = 738 static_cast<uint32_t>(IQtiComposerClient::Command::LENGTH_MASK); 739 740 uint32_t val = read(); 741 command = static_cast<IQtiComposerClient::Command>(val & opcode_mask); 742 length = static_cast<uint16_t>(val & length_mask); 743 744 if (mDataRead + length > mDataSize) { 745 ALOGE("command 0x%x has invalid command length %" PRIu16, command, length); 746 // undo the read() above 747 mDataRead--; 748 return false; 749 } 750 751 mCommandEnd = mDataRead + length; 752 753 return true; 754 } 755 endCommand()756 void endCommand() { 757 if (!mCommandEnd) { 758 LOG_FATAL("beginCommand was not called"); 759 } else if (mDataRead > mCommandEnd) { 760 LOG_FATAL("too much data read"); 761 mDataRead = mCommandEnd; 762 } else if (mDataRead < mCommandEnd) { 763 LOG_FATAL("too little data read"); 764 mDataRead = mCommandEnd; 765 } 766 767 mCommandBegin = mCommandEnd; 768 mCommandEnd = 0; 769 } 770 getCommandLoc()771 uint32_t getCommandLoc() const { return mCommandBegin; } 772 read()773 uint32_t read() { return mData[mDataRead++]; } 774 readSigned()775 int32_t readSigned() { 776 int32_t val; 777 memcpy(&val, &mData[mDataRead++], sizeof(val)); 778 return val; 779 } 780 readFloat()781 float readFloat() { 782 float val; 783 memcpy(&val, &mData[mDataRead++], sizeof(val)); 784 return val; 785 } 786 read64()787 uint64_t read64() { 788 uint32_t lo = read(); 789 uint32_t hi = read(); 790 return (static_cast<uint64_t>(hi) << 32) | lo; 791 } 792 readBlob(uint32_t size,void * blob)793 void readBlob(uint32_t size, void* blob) { 794 memcpy(blob, &mData[mDataRead], size); 795 uint32_t numElements = size / sizeof(uint32_t); 796 mDataRead += numElements; 797 mDataRead += (size - numElements * sizeof(uint32_t) != 0) ? 1 : 0; 798 } 799 readColor()800 IQtiComposerClient::Color readColor() { 801 uint32_t val = read(); 802 return IQtiComposerClient::Color{ 803 static_cast<uint8_t>((val >> 0) & 0xff), 804 static_cast<uint8_t>((val >> 8) & 0xff), 805 static_cast<uint8_t>((val >> 16) & 0xff), 806 static_cast<uint8_t>((val >> 24) & 0xff), 807 }; 808 } 809 810 // ownership of handle is not transferred readHandle(bool & useCache)811 const native_handle_t* readHandle(bool& useCache) { 812 const native_handle_t* handle = nullptr; 813 814 int32_t index = readSigned(); 815 switch (index) { 816 case static_cast<int32_t>(IQtiComposerClient::HandleIndex::EMPTY): 817 useCache = false; 818 break; 819 case static_cast<int32_t>(IQtiComposerClient::HandleIndex::CACHED): 820 useCache = true; 821 break; 822 default: 823 if (static_cast<size_t>(index) < mDataHandles.size()) { 824 handle = mDataHandles[index].getNativeHandle(); 825 } else { 826 ALOGE("invalid handle index %zu", static_cast<size_t>(index)); 827 } 828 useCache = false; 829 break; 830 } 831 832 return handle; 833 } 834 readHandle()835 const native_handle_t* readHandle() { 836 bool useCache; 837 return readHandle(useCache); 838 } 839 840 // Handle would still own original fence. Hence create a Fence object on duped fd. readFence(shared_ptr<Fence> * fence,const string & name)841 void readFence(shared_ptr<Fence>* fence, const string &name) { 842 auto handle = readHandle(); 843 if (!handle || handle->numFds == 0) { 844 return; 845 } 846 847 if (handle->numFds != 1) { 848 ALOGE("invalid fence handle with %d fds", handle->numFds); 849 return; 850 } 851 852 *fence = Fence::Create(dup(handle->data[0]), name); 853 if (*fence == nullptr) { 854 ALOGW("failed to dup fence %d", handle->data[0]); 855 sync_wait(handle->data[0], -1); 856 } 857 } 858 859 private: 860 std::unique_ptr<CommandQueueType> mQueue; 861 uint32_t mDataMaxSize; 862 std::unique_ptr<uint32_t[]> mData; 863 864 uint32_t mDataSize; 865 uint32_t mDataRead; 866 867 // begin/end offsets of the current command 868 uint32_t mCommandBegin; 869 uint32_t mCommandEnd; 870 871 hidl_vec<hidl_handle> mDataHandles; 872 }; 873 874 } // namespace V3_0 875 } // namespace composer 876 } // namespace display 877 } // namespace hardware 878 } // namespace qti 879 } // namespace vendor 880 881 #endif // __QTICOMPOSERCOMMANDBUFFER_H__ 882