BufferItem.cpp revision eea6d682b8b0f7081f0fe8fab8feadb16e22b30b
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 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 40BufferItem::~BufferItem() {} 41 42template <typename T> 43static void addAligned(size_t& size, T /* value */) { 44 size = FlattenableUtils::align<sizeof(T)>(size); 45 size += sizeof(T); 46} 47 48size_t BufferItem::getPodSize() const { 49 // Must align<8> before writing these fields for this to be correct 50 size_t size = 0; 51 addAligned(size, mCrop); 52 addAligned(size, mTransform); 53 addAligned(size, mScalingMode); 54 addAligned(size, mTimestamp); 55 addAligned(size, mIsAutoTimestamp); 56 addAligned(size, mDataSpace); 57 addAligned(size, mFrameNumber); 58 addAligned(size, mSlot); 59 addAligned(size, mIsDroppable); 60 addAligned(size, mAcquireCalled); 61 addAligned(size, mTransformToDisplayInverse); 62 return size; 63} 64 65size_t BufferItem::getFlattenedSize() const { 66 size_t size = sizeof(uint32_t); // Flags 67 if (mGraphicBuffer != 0) { 68 size += mGraphicBuffer->getFlattenedSize(); 69 FlattenableUtils::align<4>(size); 70 } 71 if (mFence != 0) { 72 size += mFence->getFlattenedSize(); 73 FlattenableUtils::align<4>(size); 74 } 75 size += mSurfaceDamage.getFlattenedSize(); 76 size = FlattenableUtils::align<8>(size); 77 return size + getPodSize(); 78} 79 80size_t BufferItem::getFdCount() const { 81 size_t count = 0; 82 if (mGraphicBuffer != 0) { 83 count += mGraphicBuffer->getFdCount(); 84 } 85 if (mFence != 0) { 86 count += mFence->getFdCount(); 87 } 88 return count; 89} 90 91template <typename T> 92static void writeAligned(void*& buffer, size_t& size, T value) { 93 size -= FlattenableUtils::align<alignof(T)>(buffer); 94 FlattenableUtils::write(buffer, size, value); 95} 96 97status_t BufferItem::flatten( 98 void*& buffer, size_t& size, int*& fds, size_t& count) const { 99 100 // make sure we have enough space 101 if (size < BufferItem::getFlattenedSize()) { 102 return NO_MEMORY; 103 } 104 105 // content flags are stored first 106 uint32_t& flags = *static_cast<uint32_t*>(buffer); 107 108 // advance the pointer 109 FlattenableUtils::advance(buffer, size, sizeof(uint32_t)); 110 111 flags = 0; 112 if (mGraphicBuffer != 0) { 113 status_t err = mGraphicBuffer->flatten(buffer, size, fds, count); 114 if (err) return err; 115 size -= FlattenableUtils::align<4>(buffer); 116 flags |= 1; 117 } 118 if (mFence != 0) { 119 status_t err = mFence->flatten(buffer, size, fds, count); 120 if (err) return err; 121 size -= FlattenableUtils::align<4>(buffer); 122 flags |= 2; 123 } 124 125 status_t err = mSurfaceDamage.flatten(buffer, size); 126 if (err) return err; 127 FlattenableUtils::advance(buffer, size, mSurfaceDamage.getFlattenedSize()); 128 129 // Must align<8> so that getPodSize returns the correct value 130 size -= FlattenableUtils::align<8>(buffer); 131 132 // Check we still have enough space 133 if (size < getPodSize()) { 134 return NO_MEMORY; 135 } 136 137 writeAligned(buffer, size, mCrop); 138 writeAligned(buffer, size, mTransform); 139 writeAligned(buffer, size, mScalingMode); 140 writeAligned(buffer, size, mTimestamp); 141 writeAligned(buffer, size, mIsAutoTimestamp); 142 writeAligned(buffer, size, mDataSpace); 143 writeAligned(buffer, size, mFrameNumber); 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 152template <typename T> 153static 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 158status_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 // Must align<8> so that getPodSize returns the correct value 187 size -= FlattenableUtils::align<8>(buffer); 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, mTimestamp); 198 readAligned(buffer, size, mIsAutoTimestamp); 199 readAligned(buffer, size, mDataSpace); 200 readAligned(buffer, size, mFrameNumber); 201 readAligned(buffer, size, mSlot); 202 readAligned(buffer, size, mIsDroppable); 203 readAligned(buffer, size, mAcquireCalled); 204 readAligned(buffer, size, mTransformToDisplayInverse); 205 206 return NO_ERROR; 207} 208 209const char* BufferItem::scalingModeName(uint32_t scalingMode) { 210 switch (scalingMode) { 211 case NATIVE_WINDOW_SCALING_MODE_FREEZE: return "FREEZE"; 212 case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: return "SCALE_TO_WINDOW"; 213 case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: return "SCALE_CROP"; 214 default: return "Unknown"; 215 } 216} 217 218} // namespace android 219