Home | History | Annotate | Download | only in default
      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:
     57     CommandWriterBase(uint32_t initialMaxSize)
     58         : mDataMaxSize(initialMaxSize)
     59     {
     60         mData = std::make_unique<uint32_t[]>(mDataMaxSize);
     61         reset();
     62     }
     63 
     64     virtual ~CommandWriterBase()
     65     {
     66         reset();
     67     }
     68 
     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 
     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 
     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 
    140     const MQDescriptorSync<uint32_t>* getMQDescriptor() const
    141     {
    142         return (mQueue) ? mQueue->getDesc() : nullptr;
    143     }
    144 
    145     static constexpr uint16_t kSelectDisplayLength = 2;
    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;
    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;
    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;
    173     void setPresentOrValidateResult(uint32_t  state) {
    174        beginCommand(IComposerClient::Command::SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT, kPresentOrValidateDisplayResultLength);
    175        write(state);
    176        endCommand();
    177     }
    178 
    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 
    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;
    228     void setPresentFence(int presentFence)
    229     {
    230         beginCommand(IComposerClient::Command::SET_PRESENT_FENCE,
    231                 kSetPresentFenceLength);
    232         writeFence(presentFence);
    233         endCommand();
    234     }
    235 
    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;
    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 
    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;
    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;
    304     void validateDisplay()
    305     {
    306         beginCommand(IComposerClient::Command::VALIDATE_DISPLAY,
    307                 kValidateDisplayLength);
    308         endCommand();
    309     }
    310 
    311     static constexpr uint16_t kPresentOrValidateDisplayLength = 0;
    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;
    320     void acceptDisplayChanges()
    321     {
    322         beginCommand(IComposerClient::Command::ACCEPT_DISPLAY_CHANGES,
    323                 kAcceptDisplayChangesLength);
    324         endCommand();
    325     }
    326 
    327     static constexpr uint16_t kPresentDisplayLength = 0;
    328     void presentDisplay()
    329     {
    330         beginCommand(IComposerClient::Command::PRESENT_DISPLAY,
    331                 kPresentDisplayLength);
    332         endCommand();
    333     }
    334 
    335     static constexpr uint16_t kSetLayerCursorPositionLength = 2;
    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;
    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 
    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;
    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;
    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;
    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;
    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;
    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;
    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;
    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;
    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;
    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 
    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;
    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:
    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 
    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 
    512     void write(uint32_t val)
    513     {
    514         mData[mDataWritten++] = val;
    515     }
    516 
    517     void writeSigned(int32_t val)
    518     {
    519         memcpy(&mData[mDataWritten++], &val, sizeof(val));
    520     }
    521 
    522     void writeFloat(float val)
    523     {
    524         memcpy(&mData[mDataWritten++], &val, sizeof(val));
    525     }
    526 
    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 
    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 
    543     void writeRegion(const std::vector<IComposerClient::Rect>& region)
    544     {
    545         for (const auto& rect : region) {
    546             writeRect(rect);
    547         }
    548     }
    549 
    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 
    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
    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 
    580     void writeHandle(const native_handle_t* handle)
    581     {
    582         writeHandle(handle, false);
    583     }
    584 
    585     // ownership of fence is transferred
    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 
    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:
    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:
    656     CommandReaderBase() : mDataMaxSize(0)
    657     {
    658         reset();
    659     }
    660 
    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 
    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 
    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:
    712     bool isEmpty() const
    713     {
    714         return (mDataRead >= mDataSize);
    715     }
    716 
    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 
    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 
    763     uint32_t getCommandLoc() const
    764     {
    765         return mCommandBegin;
    766     }
    767 
    768     uint32_t read()
    769     {
    770         return mData[mDataRead++];
    771     }
    772 
    773     int32_t readSigned()
    774     {
    775         int32_t val;
    776         memcpy(&val, &mData[mDataRead++], sizeof(val));
    777         return val;
    778     }
    779 
    780     float readFloat()
    781     {
    782         float val;
    783         memcpy(&val, &mData[mDataRead++], sizeof(val));
    784         return val;
    785     }
    786 
    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 
    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
    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 
    831     const native_handle_t* readHandle()
    832     {
    833         bool useCache;
    834         return readHandle(&useCache);
    835     }
    836 
    837     // ownership of fence is transferred
    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