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