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