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