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