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