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