Home | History | Annotate | Download | only in gui
      1 /*
      2  * Copyright 2014 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 #include <gui/BufferItem.h>
     18 
     19 #include <ui/Fence.h>
     20 #include <ui/GraphicBuffer.h>
     21 
     22 #include <system/window.h>
     23 
     24 namespace android {
     25 
     26 template<typename T>
     27 static inline constexpr uint32_t low32(const T n) {
     28     return static_cast<uint32_t>(static_cast<uint64_t>(n));
     29 }
     30 
     31 template<typename T>
     32 static inline constexpr uint32_t high32(const T n) {
     33     return static_cast<uint32_t>(static_cast<uint64_t>(n)>>32);
     34 }
     35 
     36 template<typename T>
     37 static inline constexpr T to64(const uint32_t lo, const uint32_t hi) {
     38     return static_cast<T>(static_cast<uint64_t>(hi)<<32 | lo);
     39 }
     40 
     41 BufferItem::BufferItem() :
     42     mGraphicBuffer(NULL),
     43     mFence(NULL),
     44     mCrop(Rect::INVALID_RECT),
     45     mTransform(0),
     46     mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
     47     mTimestamp(0),
     48     mIsAutoTimestamp(false),
     49     mDataSpace(HAL_DATASPACE_UNKNOWN),
     50     mFrameNumber(0),
     51     mSlot(INVALID_BUFFER_SLOT),
     52     mIsDroppable(false),
     53     mAcquireCalled(false),
     54     mTransformToDisplayInverse(false),
     55     mSurfaceDamage(),
     56     mAutoRefresh(false),
     57     mQueuedBuffer(true),
     58     mIsStale(false),
     59     mApi(0) {
     60 }
     61 
     62 BufferItem::~BufferItem() {}
     63 
     64 template <typename T>
     65 static void addAligned(size_t& size, T /* value */) {
     66     size = FlattenableUtils::align<sizeof(T)>(size);
     67     size += sizeof(T);
     68 }
     69 
     70 size_t BufferItem::getPodSize() const {
     71     size_t size = 0;
     72     addAligned(size, mCrop);
     73     addAligned(size, mTransform);
     74     addAligned(size, mScalingMode);
     75     addAligned(size, low32(mTimestamp));
     76     addAligned(size, high32(mTimestamp));
     77     addAligned(size, mIsAutoTimestamp);
     78     addAligned(size, mDataSpace);
     79     addAligned(size, low32(mFrameNumber));
     80     addAligned(size, high32(mFrameNumber));
     81     addAligned(size, mSlot);
     82     addAligned(size, mIsDroppable);
     83     addAligned(size, mAcquireCalled);
     84     addAligned(size, mTransformToDisplayInverse);
     85     addAligned(size, mAutoRefresh);
     86     addAligned(size, mQueuedBuffer);
     87     addAligned(size, mIsStale);
     88     addAligned(size, mApi);
     89     return size;
     90 }
     91 
     92 size_t BufferItem::getFlattenedSize() const {
     93     size_t size = sizeof(uint32_t); // Flags
     94     if (mGraphicBuffer != 0) {
     95         size += mGraphicBuffer->getFlattenedSize();
     96         size = FlattenableUtils::align<4>(size);
     97     }
     98     if (mFence != 0) {
     99         size += mFence->getFlattenedSize();
    100         size = FlattenableUtils::align<4>(size);
    101     }
    102     size += mSurfaceDamage.getFlattenedSize();
    103     size += mHdrMetadata.getFlattenedSize();
    104     size = FlattenableUtils::align<8>(size);
    105     return size + getPodSize();
    106 }
    107 
    108 size_t BufferItem::getFdCount() const {
    109     size_t count = 0;
    110     if (mGraphicBuffer != 0) {
    111         count += mGraphicBuffer->getFdCount();
    112     }
    113     if (mFence != 0) {
    114         count += mFence->getFdCount();
    115     }
    116     return count;
    117 }
    118 
    119 template <typename T>
    120 static void writeAligned(void*& buffer, size_t& size, T value) {
    121     size -= FlattenableUtils::align<alignof(T)>(buffer);
    122     FlattenableUtils::write(buffer, size, value);
    123 }
    124 
    125 status_t BufferItem::flatten(
    126         void*& buffer, size_t& size, int*& fds, size_t& count) const {
    127 
    128     // make sure we have enough space
    129     if (size < BufferItem::getFlattenedSize()) {
    130         return NO_MEMORY;
    131     }
    132 
    133     // content flags are stored first
    134     uint32_t& flags = *static_cast<uint32_t*>(buffer);
    135 
    136     // advance the pointer
    137     FlattenableUtils::advance(buffer, size, sizeof(uint32_t));
    138 
    139     flags = 0;
    140     if (mGraphicBuffer != 0) {
    141         status_t err = mGraphicBuffer->flatten(buffer, size, fds, count);
    142         if (err) return err;
    143         size -= FlattenableUtils::align<4>(buffer);
    144         flags |= 1;
    145     }
    146     if (mFence != 0) {
    147         status_t err = mFence->flatten(buffer, size, fds, count);
    148         if (err) return err;
    149         size -= FlattenableUtils::align<4>(buffer);
    150         flags |= 2;
    151     }
    152 
    153     status_t err = mSurfaceDamage.flatten(buffer, size);
    154     if (err) return err;
    155     FlattenableUtils::advance(buffer, size, mSurfaceDamage.getFlattenedSize());
    156 
    157     err = mHdrMetadata.flatten(buffer, size);
    158     if (err) return err;
    159     FlattenableUtils::advance(buffer, size, mHdrMetadata.getFlattenedSize());
    160 
    161     // Check we still have enough space
    162     if (size < getPodSize()) {
    163         return NO_MEMORY;
    164     }
    165 
    166     writeAligned(buffer, size, mCrop);
    167     writeAligned(buffer, size, mTransform);
    168     writeAligned(buffer, size, mScalingMode);
    169     writeAligned(buffer, size, low32(mTimestamp));
    170     writeAligned(buffer, size, high32(mTimestamp));
    171     writeAligned(buffer, size, mIsAutoTimestamp);
    172     writeAligned(buffer, size, mDataSpace);
    173     writeAligned(buffer, size, low32(mFrameNumber));
    174     writeAligned(buffer, size, high32(mFrameNumber));
    175     writeAligned(buffer, size, mSlot);
    176     writeAligned(buffer, size, mIsDroppable);
    177     writeAligned(buffer, size, mAcquireCalled);
    178     writeAligned(buffer, size, mTransformToDisplayInverse);
    179     writeAligned(buffer, size, mAutoRefresh);
    180     writeAligned(buffer, size, mQueuedBuffer);
    181     writeAligned(buffer, size, mIsStale);
    182     writeAligned(buffer, size, mApi);
    183 
    184     return NO_ERROR;
    185 }
    186 
    187 template <typename T>
    188 static void readAligned(const void*& buffer, size_t& size, T& value) {
    189     size -= FlattenableUtils::align<alignof(T)>(buffer);
    190     FlattenableUtils::read(buffer, size, value);
    191 }
    192 
    193 status_t BufferItem::unflatten(
    194         void const*& buffer, size_t& size, int const*& fds, size_t& count) {
    195 
    196     if (size < sizeof(uint32_t)) {
    197         return NO_MEMORY;
    198     }
    199 
    200     uint32_t flags = 0;
    201     FlattenableUtils::read(buffer, size, flags);
    202 
    203     if (flags & 1) {
    204         mGraphicBuffer = new GraphicBuffer();
    205         status_t err = mGraphicBuffer->unflatten(buffer, size, fds, count);
    206         if (err) return err;
    207         size -= FlattenableUtils::align<4>(buffer);
    208     }
    209 
    210     if (flags & 2) {
    211         mFence = new Fence();
    212         status_t err = mFence->unflatten(buffer, size, fds, count);
    213         if (err) return err;
    214         size -= FlattenableUtils::align<4>(buffer);
    215 
    216         mFenceTime = std::make_shared<FenceTime>(mFence);
    217     }
    218 
    219     status_t err = mSurfaceDamage.unflatten(buffer, size);
    220     if (err) return err;
    221     FlattenableUtils::advance(buffer, size, mSurfaceDamage.getFlattenedSize());
    222 
    223     err = mHdrMetadata.unflatten(buffer, size);
    224     if (err) return err;
    225     FlattenableUtils::advance(buffer, size, mHdrMetadata.getFlattenedSize());
    226 
    227     // Check we still have enough space
    228     if (size < getPodSize()) {
    229         return NO_MEMORY;
    230     }
    231 
    232     uint32_t timestampLo = 0, timestampHi = 0;
    233     uint32_t frameNumberLo = 0, frameNumberHi = 0;
    234 
    235     readAligned(buffer, size, mCrop);
    236     readAligned(buffer, size, mTransform);
    237     readAligned(buffer, size, mScalingMode);
    238     readAligned(buffer, size, timestampLo);
    239     readAligned(buffer, size, timestampHi);
    240     mTimestamp = to64<int64_t>(timestampLo, timestampHi);
    241     readAligned(buffer, size, mIsAutoTimestamp);
    242     readAligned(buffer, size, mDataSpace);
    243     readAligned(buffer, size, frameNumberLo);
    244     readAligned(buffer, size, frameNumberHi);
    245     mFrameNumber = to64<uint64_t>(frameNumberLo, frameNumberHi);
    246     readAligned(buffer, size, mSlot);
    247     readAligned(buffer, size, mIsDroppable);
    248     readAligned(buffer, size, mAcquireCalled);
    249     readAligned(buffer, size, mTransformToDisplayInverse);
    250     readAligned(buffer, size, mAutoRefresh);
    251     readAligned(buffer, size, mQueuedBuffer);
    252     readAligned(buffer, size, mIsStale);
    253     readAligned(buffer, size, mApi);
    254 
    255     return NO_ERROR;
    256 }
    257 
    258 const char* BufferItem::scalingModeName(uint32_t scalingMode) {
    259     switch (scalingMode) {
    260         case NATIVE_WINDOW_SCALING_MODE_FREEZE: return "FREEZE";
    261         case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: return "SCALE_TO_WINDOW";
    262         case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: return "SCALE_CROP";
    263         default: return "Unknown";
    264     }
    265 }
    266 
    267 } // namespace android
    268