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 BufferItem::BufferItem() :
     27     mTransform(0),
     28     mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
     29     mTimestamp(0),
     30     mIsAutoTimestamp(false),
     31     mDataSpace(HAL_DATASPACE_UNKNOWN),
     32     mFrameNumber(0),
     33     mSlot(INVALID_BUFFER_SLOT),
     34     mIsDroppable(false),
     35     mAcquireCalled(false),
     36     mTransformToDisplayInverse(false) {
     37     mCrop.makeInvalid();
     38 }
     39 
     40 BufferItem::~BufferItem() {}
     41 
     42 template <typename T>
     43 static void addAligned(size_t& size, T /* value */) {
     44     size = FlattenableUtils::align<sizeof(T)>(size);
     45     size += sizeof(T);
     46 }
     47 
     48 size_t BufferItem::getPodSize() const {
     49     size_t size = 0;
     50     addAligned(size, mCrop);
     51     addAligned(size, mTransform);
     52     addAligned(size, mScalingMode);
     53     addAligned(size, mTimestampLo);
     54     addAligned(size, mTimestampHi);
     55     addAligned(size, mIsAutoTimestamp);
     56     addAligned(size, mDataSpace);
     57     addAligned(size, mFrameNumberLo);
     58     addAligned(size, mFrameNumberHi);
     59     addAligned(size, mSlot);
     60     addAligned(size, mIsDroppable);
     61     addAligned(size, mAcquireCalled);
     62     addAligned(size, mTransformToDisplayInverse);
     63     return size;
     64 }
     65 
     66 size_t BufferItem::getFlattenedSize() const {
     67     size_t size = sizeof(uint32_t); // Flags
     68     if (mGraphicBuffer != 0) {
     69         size += mGraphicBuffer->getFlattenedSize();
     70         FlattenableUtils::align<4>(size);
     71     }
     72     if (mFence != 0) {
     73         size += mFence->getFlattenedSize();
     74         FlattenableUtils::align<4>(size);
     75     }
     76     size += mSurfaceDamage.getFlattenedSize();
     77     size = FlattenableUtils::align<8>(size);
     78     return size + getPodSize();
     79 }
     80 
     81 size_t BufferItem::getFdCount() const {
     82     size_t count = 0;
     83     if (mGraphicBuffer != 0) {
     84         count += mGraphicBuffer->getFdCount();
     85     }
     86     if (mFence != 0) {
     87         count += mFence->getFdCount();
     88     }
     89     return count;
     90 }
     91 
     92 template <typename T>
     93 static void writeAligned(void*& buffer, size_t& size, T value) {
     94     size -= FlattenableUtils::align<alignof(T)>(buffer);
     95     FlattenableUtils::write(buffer, size, value);
     96 }
     97 
     98 status_t BufferItem::flatten(
     99         void*& buffer, size_t& size, int*& fds, size_t& count) const {
    100 
    101     // make sure we have enough space
    102     if (size < BufferItem::getFlattenedSize()) {
    103         return NO_MEMORY;
    104     }
    105 
    106     // content flags are stored first
    107     uint32_t& flags = *static_cast<uint32_t*>(buffer);
    108 
    109     // advance the pointer
    110     FlattenableUtils::advance(buffer, size, sizeof(uint32_t));
    111 
    112     flags = 0;
    113     if (mGraphicBuffer != 0) {
    114         status_t err = mGraphicBuffer->flatten(buffer, size, fds, count);
    115         if (err) return err;
    116         size -= FlattenableUtils::align<4>(buffer);
    117         flags |= 1;
    118     }
    119     if (mFence != 0) {
    120         status_t err = mFence->flatten(buffer, size, fds, count);
    121         if (err) return err;
    122         size -= FlattenableUtils::align<4>(buffer);
    123         flags |= 2;
    124     }
    125 
    126     status_t err = mSurfaceDamage.flatten(buffer, size);
    127     if (err) return err;
    128     FlattenableUtils::advance(buffer, size, mSurfaceDamage.getFlattenedSize());
    129 
    130     // Check we still have enough space
    131     if (size < getPodSize()) {
    132         return NO_MEMORY;
    133     }
    134 
    135     writeAligned(buffer, size, mCrop);
    136     writeAligned(buffer, size, mTransform);
    137     writeAligned(buffer, size, mScalingMode);
    138     writeAligned(buffer, size, mTimestampLo);
    139     writeAligned(buffer, size, mTimestampHi);
    140     writeAligned(buffer, size, mIsAutoTimestamp);
    141     writeAligned(buffer, size, mDataSpace);
    142     writeAligned(buffer, size, mFrameNumberLo);
    143     writeAligned(buffer, size, mFrameNumberHi);
    144     writeAligned(buffer, size, mSlot);
    145     writeAligned(buffer, size, mIsDroppable);
    146     writeAligned(buffer, size, mAcquireCalled);
    147     writeAligned(buffer, size, mTransformToDisplayInverse);
    148 
    149     return NO_ERROR;
    150 }
    151 
    152 template <typename T>
    153 static void readAligned(const void*& buffer, size_t& size, T& value) {
    154     size -= FlattenableUtils::align<alignof(T)>(buffer);
    155     FlattenableUtils::read(buffer, size, value);
    156 }
    157 
    158 status_t BufferItem::unflatten(
    159         void const*& buffer, size_t& size, int const*& fds, size_t& count) {
    160 
    161     if (size < sizeof(uint32_t)) {
    162         return NO_MEMORY;
    163     }
    164 
    165     uint32_t flags = 0;
    166     FlattenableUtils::read(buffer, size, flags);
    167 
    168     if (flags & 1) {
    169         mGraphicBuffer = new GraphicBuffer();
    170         status_t err = mGraphicBuffer->unflatten(buffer, size, fds, count);
    171         if (err) return err;
    172         size -= FlattenableUtils::align<4>(buffer);
    173     }
    174 
    175     if (flags & 2) {
    176         mFence = new Fence();
    177         status_t err = mFence->unflatten(buffer, size, fds, count);
    178         if (err) return err;
    179         size -= FlattenableUtils::align<4>(buffer);
    180     }
    181 
    182     status_t err = mSurfaceDamage.unflatten(buffer, size);
    183     if (err) return err;
    184     FlattenableUtils::advance(buffer, size, mSurfaceDamage.getFlattenedSize());
    185 
    186     // Check we still have enough space
    187     if (size < getPodSize()) {
    188         return NO_MEMORY;
    189     }
    190 
    191     readAligned(buffer, size, mCrop);
    192     readAligned(buffer, size, mTransform);
    193     readAligned(buffer, size, mScalingMode);
    194     readAligned(buffer, size, mTimestampLo);
    195     readAligned(buffer, size, mTimestampHi);
    196     readAligned(buffer, size, mIsAutoTimestamp);
    197     readAligned(buffer, size, mDataSpace);
    198     readAligned(buffer, size, mFrameNumberLo);
    199     readAligned(buffer, size, mFrameNumberHi);
    200     readAligned(buffer, size, mSlot);
    201     readAligned(buffer, size, mIsDroppable);
    202     readAligned(buffer, size, mAcquireCalled);
    203     readAligned(buffer, size, mTransformToDisplayInverse);
    204 
    205     return NO_ERROR;
    206 }
    207 
    208 const char* BufferItem::scalingModeName(uint32_t scalingMode) {
    209     switch (scalingMode) {
    210         case NATIVE_WINDOW_SCALING_MODE_FREEZE: return "FREEZE";
    211         case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: return "SCALE_TO_WINDOW";
    212         case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: return "SCALE_CROP";
    213         default: return "Unknown";
    214     }
    215 }
    216 
    217 } // namespace android
    218