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