Home | History | Annotate | Download | only in 2.1
      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:
     57     CommandWriterBase(uint32_t initialMaxSize) : mDataMaxSize(initialMaxSize) {
     58         mData = std::make_unique<uint32_t[]>(mDataMaxSize);
     59         reset();
     60     }
     61 
     62     virtual ~CommandWriterBase() { reset(); }
     63 
     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 
     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 
     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 
    137     const MQDescriptorSync<uint32_t>* getMQDescriptor() const {
    138         return (mQueue) ? mQueue->getDesc() : nullptr;
    139     }
    140 
    141     static constexpr uint16_t kSelectDisplayLength = 2;
    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;
    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;
    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;
    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 
    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 
    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;
    213     void setPresentFence(int presentFence) {
    214         beginCommand(IComposerClient::Command::SET_PRESENT_FENCE, kSetPresentFenceLength);
    215         writeFence(presentFence);
    216         endCommand();
    217     }
    218 
    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;
    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 
    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;
    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;
    264     void validateDisplay() {
    265         beginCommand(IComposerClient::Command::VALIDATE_DISPLAY, kValidateDisplayLength);
    266         endCommand();
    267     }
    268 
    269     static constexpr uint16_t kPresentOrValidateDisplayLength = 0;
    270     void presentOrvalidateDisplay() {
    271         beginCommand(IComposerClient::Command::PRESENT_OR_VALIDATE_DISPLAY,
    272                      kPresentOrValidateDisplayLength);
    273         endCommand();
    274     }
    275 
    276     static constexpr uint16_t kAcceptDisplayChangesLength = 0;
    277     void acceptDisplayChanges() {
    278         beginCommand(IComposerClient::Command::ACCEPT_DISPLAY_CHANGES, kAcceptDisplayChangesLength);
    279         endCommand();
    280     }
    281 
    282     static constexpr uint16_t kPresentDisplayLength = 0;
    283     void presentDisplay() {
    284         beginCommand(IComposerClient::Command::PRESENT_DISPLAY, kPresentDisplayLength);
    285         endCommand();
    286     }
    287 
    288     static constexpr uint16_t kSetLayerCursorPositionLength = 2;
    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;
    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 
    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;
    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;
    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;
    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;
    343     void setLayerDataspace(Dataspace dataspace) {
    344         setLayerDataspaceInternal(static_cast<int32_t>(dataspace));
    345     }
    346 
    347     static constexpr uint16_t kSetLayerDisplayFrameLength = 4;
    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;
    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;
    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;
    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;
    378     void setLayerTransform(Transform transform) {
    379         beginCommand(IComposerClient::Command::SET_LAYER_TRANSFORM, kSetLayerTransformLength);
    380         writeSigned(static_cast<int32_t>(transform));
    381         endCommand();
    382     }
    383 
    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;
    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     void setClientTargetInternal(uint32_t slot, const native_handle_t* target, int acquireFence,
    407                                  int32_t dataspace,
    408                                  const std::vector<IComposerClient::Rect>& damage) {
    409         bool doWrite = (damage.size() <= (kMaxLength - 4) / 4);
    410         size_t length = 4 + ((doWrite) ? damage.size() * 4 : 0);
    411 
    412         beginCommand(IComposerClient::Command::SET_CLIENT_TARGET, length);
    413         write(slot);
    414         writeHandle(target, true);
    415         writeFence(acquireFence);
    416         writeSigned(dataspace);
    417         // When there are too many rectangles in the damage region and doWrite
    418         // is false, we write no rectangle at all which means the entire
    419         // client target is damaged.
    420         if (doWrite) {
    421             writeRegion(damage);
    422         }
    423         endCommand();
    424     }
    425 
    426     void setLayerDataspaceInternal(int32_t dataspace) {
    427         beginCommand(IComposerClient::Command::SET_LAYER_DATASPACE, kSetLayerDataspaceLength);
    428         writeSigned(dataspace);
    429         endCommand();
    430     }
    431 
    432     void beginCommand(IComposerClient::Command command, uint16_t length) {
    433         if (mCommandEnd) {
    434             LOG_FATAL("endCommand was not called before command 0x%x", command);
    435         }
    436 
    437         growData(1 + length);
    438         write(static_cast<uint32_t>(command) | length);
    439 
    440         mCommandEnd = mDataWritten + length;
    441     }
    442 
    443     void endCommand() {
    444         if (!mCommandEnd) {
    445             LOG_FATAL("beginCommand was not called");
    446         } else if (mDataWritten > mCommandEnd) {
    447             LOG_FATAL("too much data written");
    448             mDataWritten = mCommandEnd;
    449         } else if (mDataWritten < mCommandEnd) {
    450             LOG_FATAL("too little data written");
    451             while (mDataWritten < mCommandEnd) {
    452                 write(0);
    453             }
    454         }
    455 
    456         mCommandEnd = 0;
    457     }
    458 
    459     void write(uint32_t val) { mData[mDataWritten++] = val; }
    460 
    461     void writeSigned(int32_t val) { memcpy(&mData[mDataWritten++], &val, sizeof(val)); }
    462 
    463     void writeFloat(float val) { memcpy(&mData[mDataWritten++], &val, sizeof(val)); }
    464 
    465     void write64(uint64_t val) {
    466         uint32_t lo = static_cast<uint32_t>(val & 0xffffffff);
    467         uint32_t hi = static_cast<uint32_t>(val >> 32);
    468         write(lo);
    469         write(hi);
    470     }
    471 
    472     void writeRect(const IComposerClient::Rect& rect) {
    473         writeSigned(rect.left);
    474         writeSigned(rect.top);
    475         writeSigned(rect.right);
    476         writeSigned(rect.bottom);
    477     }
    478 
    479     void writeRegion(const std::vector<IComposerClient::Rect>& region) {
    480         for (const auto& rect : region) {
    481             writeRect(rect);
    482         }
    483     }
    484 
    485     void writeFRect(const IComposerClient::FRect& rect) {
    486         writeFloat(rect.left);
    487         writeFloat(rect.top);
    488         writeFloat(rect.right);
    489         writeFloat(rect.bottom);
    490     }
    491 
    492     void writeColor(const IComposerClient::Color& color) {
    493         write((color.r << 0) | (color.g << 8) | (color.b << 16) | (color.a << 24));
    494     }
    495 
    496     // ownership of handle is not transferred
    497     void writeHandle(const native_handle_t* handle, bool useCache) {
    498         if (!handle) {
    499             writeSigned(static_cast<int32_t>((useCache) ? IComposerClient::HandleIndex::CACHED
    500                                                         : IComposerClient::HandleIndex::EMPTY));
    501             return;
    502         }
    503 
    504         mDataHandles.push_back(handle);
    505         writeSigned(mDataHandles.size() - 1);
    506     }
    507 
    508     void writeHandle(const native_handle_t* handle) { writeHandle(handle, false); }
    509 
    510     // ownership of fence is transferred
    511     void writeFence(int fence) {
    512         native_handle_t* handle = nullptr;
    513         if (fence >= 0) {
    514             handle = getTemporaryHandle(1, 0);
    515             if (handle) {
    516                 handle->data[0] = fence;
    517             } else {
    518                 ALOGW("failed to get temporary handle for fence %d", fence);
    519                 sync_wait(fence, -1);
    520                 close(fence);
    521             }
    522         }
    523 
    524         writeHandle(handle);
    525     }
    526 
    527     native_handle_t* getTemporaryHandle(int numFds, int numInts) {
    528         native_handle_t* handle = native_handle_create(numFds, numInts);
    529         if (handle) {
    530             mTemporaryHandles.push_back(handle);
    531         }
    532         return handle;
    533     }
    534 
    535     static constexpr uint16_t kMaxLength = std::numeric_limits<uint16_t>::max();
    536 
    537    private:
    538     void growData(uint32_t grow) {
    539         uint32_t newWritten = mDataWritten + grow;
    540         if (newWritten < mDataWritten) {
    541             LOG_ALWAYS_FATAL("buffer overflowed; data written %" PRIu32 ", growing by %" PRIu32,
    542                              mDataWritten, grow);
    543         }
    544 
    545         if (newWritten <= mDataMaxSize) {
    546             return;
    547         }
    548 
    549         uint32_t newMaxSize = mDataMaxSize << 1;
    550         if (newMaxSize < newWritten) {
    551             newMaxSize = newWritten;
    552         }
    553 
    554         auto newData = std::make_unique<uint32_t[]>(newMaxSize);
    555         std::copy_n(mData.get(), mDataWritten, newData.get());
    556         mDataMaxSize = newMaxSize;
    557         mData = std::move(newData);
    558     }
    559 
    560     uint32_t mDataMaxSize;
    561     std::unique_ptr<uint32_t[]> mData;
    562 
    563     uint32_t mDataWritten;
    564     // end offset of the current command
    565     uint32_t mCommandEnd;
    566 
    567     std::vector<hidl_handle> mDataHandles;
    568     std::vector<native_handle_t*> mTemporaryHandles;
    569 
    570     std::unique_ptr<CommandQueueType> mQueue;
    571 };
    572 
    573 // This class helps parse a command queue.  Note that all sizes/lengths are in
    574 // units of uint32_t's.
    575 class CommandReaderBase {
    576    public:
    577     CommandReaderBase() : mDataMaxSize(0) { reset(); }
    578 
    579     bool setMQDescriptor(const MQDescriptorSync<uint32_t>& descriptor) {
    580         mQueue = std::make_unique<CommandQueueType>(descriptor, false);
    581         if (mQueue->isValid()) {
    582             return true;
    583         } else {
    584             mQueue = nullptr;
    585             return false;
    586         }
    587     }
    588 
    589     bool readQueue(uint32_t commandLength, const hidl_vec<hidl_handle>& commandHandles) {
    590         if (!mQueue) {
    591             return false;
    592         }
    593 
    594         auto quantumCount = mQueue->getQuantumCount();
    595         if (mDataMaxSize < quantumCount) {
    596             mDataMaxSize = quantumCount;
    597             mData = std::make_unique<uint32_t[]>(mDataMaxSize);
    598         }
    599 
    600         if (commandLength > mDataMaxSize || !mQueue->read(mData.get(), commandLength)) {
    601             ALOGE("failed to read commands from message queue");
    602             return false;
    603         }
    604 
    605         mDataSize = commandLength;
    606         mDataRead = 0;
    607         mCommandBegin = 0;
    608         mCommandEnd = 0;
    609         mDataHandles.setToExternal(const_cast<hidl_handle*>(commandHandles.data()),
    610                                    commandHandles.size());
    611 
    612         return true;
    613     }
    614 
    615     void reset() {
    616         mDataSize = 0;
    617         mDataRead = 0;
    618         mCommandBegin = 0;
    619         mCommandEnd = 0;
    620         mDataHandles.setToExternal(nullptr, 0);
    621     }
    622 
    623    protected:
    624     bool isEmpty() const { return (mDataRead >= mDataSize); }
    625 
    626     bool beginCommand(IComposerClient::Command* outCommand, uint16_t* outLength) {
    627         if (mCommandEnd) {
    628             LOG_FATAL("endCommand was not called for last command");
    629         }
    630 
    631         constexpr uint32_t opcode_mask =
    632             static_cast<uint32_t>(IComposerClient::Command::OPCODE_MASK);
    633         constexpr uint32_t length_mask =
    634             static_cast<uint32_t>(IComposerClient::Command::LENGTH_MASK);
    635 
    636         uint32_t val = read();
    637         *outCommand = static_cast<IComposerClient::Command>(val & opcode_mask);
    638         *outLength = static_cast<uint16_t>(val & length_mask);
    639 
    640         if (mDataRead + *outLength > mDataSize) {
    641             ALOGE("command 0x%x has invalid command length %" PRIu16, *outCommand, *outLength);
    642             // undo the read() above
    643             mDataRead--;
    644             return false;
    645         }
    646 
    647         mCommandEnd = mDataRead + *outLength;
    648 
    649         return true;
    650     }
    651 
    652     void endCommand() {
    653         if (!mCommandEnd) {
    654             LOG_FATAL("beginCommand was not called");
    655         } else if (mDataRead > mCommandEnd) {
    656             LOG_FATAL("too much data read");
    657             mDataRead = mCommandEnd;
    658         } else if (mDataRead < mCommandEnd) {
    659             LOG_FATAL("too little data read");
    660             mDataRead = mCommandEnd;
    661         }
    662 
    663         mCommandBegin = mCommandEnd;
    664         mCommandEnd = 0;
    665     }
    666 
    667     uint32_t getCommandLoc() const { return mCommandBegin; }
    668 
    669     uint32_t read() { return mData[mDataRead++]; }
    670 
    671     int32_t readSigned() {
    672         int32_t val;
    673         memcpy(&val, &mData[mDataRead++], sizeof(val));
    674         return val;
    675     }
    676 
    677     float readFloat() {
    678         float val;
    679         memcpy(&val, &mData[mDataRead++], sizeof(val));
    680         return val;
    681     }
    682 
    683     uint64_t read64() {
    684         uint32_t lo = read();
    685         uint32_t hi = read();
    686         return (static_cast<uint64_t>(hi) << 32) | lo;
    687     }
    688 
    689     IComposerClient::Color readColor() {
    690         uint32_t val = read();
    691         return IComposerClient::Color{
    692             static_cast<uint8_t>((val >> 0) & 0xff), static_cast<uint8_t>((val >> 8) & 0xff),
    693             static_cast<uint8_t>((val >> 16) & 0xff), static_cast<uint8_t>((val >> 24) & 0xff),
    694         };
    695     }
    696 
    697     // ownership of handle is not transferred
    698     const native_handle_t* readHandle(bool* outUseCache) {
    699         const native_handle_t* handle = nullptr;
    700 
    701         int32_t index = readSigned();
    702         switch (index) {
    703             case static_cast<int32_t>(IComposerClient::HandleIndex::EMPTY):
    704                 *outUseCache = false;
    705                 break;
    706             case static_cast<int32_t>(IComposerClient::HandleIndex::CACHED):
    707                 *outUseCache = true;
    708                 break;
    709             default:
    710                 if (static_cast<size_t>(index) < mDataHandles.size()) {
    711                     handle = mDataHandles[index].getNativeHandle();
    712                 } else {
    713                     ALOGE("invalid handle index %zu", static_cast<size_t>(index));
    714                 }
    715                 *outUseCache = false;
    716                 break;
    717         }
    718 
    719         return handle;
    720     }
    721 
    722     const native_handle_t* readHandle() {
    723         bool useCache;
    724         return readHandle(&useCache);
    725     }
    726 
    727     // ownership of fence is transferred
    728     int readFence() {
    729         auto handle = readHandle();
    730         if (!handle || handle->numFds == 0) {
    731             return -1;
    732         }
    733 
    734         if (handle->numFds != 1) {
    735             ALOGE("invalid fence handle with %d fds", handle->numFds);
    736             return -1;
    737         }
    738 
    739         int fd = dup(handle->data[0]);
    740         if (fd < 0) {
    741             ALOGW("failed to dup fence %d", handle->data[0]);
    742             sync_wait(handle->data[0], -1);
    743             fd = -1;
    744         }
    745 
    746         return fd;
    747     }
    748 
    749    private:
    750     std::unique_ptr<CommandQueueType> mQueue;
    751     uint32_t mDataMaxSize;
    752     std::unique_ptr<uint32_t[]> mData;
    753 
    754     uint32_t mDataSize;
    755     uint32_t mDataRead;
    756 
    757     // begin/end offsets of the current command
    758     uint32_t mCommandBegin;
    759     uint32_t mCommandEnd;
    760 
    761     hidl_vec<hidl_handle> mDataHandles;
    762 };
    763 
    764 }  // namespace V2_1
    765 }  // namespace composer
    766 }  // namespace graphics
    767 }  // namespace hardware
    768 }  // namespace android
    769 
    770 #endif  // ANDROID_HARDWARE_GRAPHICS_COMPOSER_COMMAND_BUFFER_H
    771