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