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