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 mFrameNumber(0), 32 mSlot(INVALID_BUFFER_SLOT), 33 mIsDroppable(false), 34 mAcquireCalled(false), 35 mTransformToDisplayInverse(false) { 36 mCrop.makeInvalid(); 37 } 38 39 BufferItem::~BufferItem() {} 40 41 BufferItem::operator IGraphicBufferConsumer::BufferItem() const { 42 IGraphicBufferConsumer::BufferItem bufferItem; 43 bufferItem.mGraphicBuffer = mGraphicBuffer; 44 bufferItem.mFence = mFence; 45 bufferItem.mCrop = mCrop; 46 bufferItem.mTransform = mTransform; 47 bufferItem.mScalingMode = mScalingMode; 48 bufferItem.mTimestamp = mTimestamp; 49 bufferItem.mIsAutoTimestamp = mIsAutoTimestamp; 50 bufferItem.mFrameNumber = mFrameNumber; 51 bufferItem.mBuf = mSlot; 52 bufferItem.mIsDroppable = mIsDroppable; 53 bufferItem.mAcquireCalled = mAcquireCalled; 54 bufferItem.mTransformToDisplayInverse = mTransformToDisplayInverse; 55 return bufferItem; 56 } 57 58 size_t BufferItem::getPodSize() const { 59 size_t c = sizeof(mCrop) + 60 sizeof(mTransform) + 61 sizeof(mScalingMode) + 62 sizeof(mTimestamp) + 63 sizeof(mIsAutoTimestamp) + 64 sizeof(mFrameNumber) + 65 sizeof(mSlot) + 66 sizeof(mIsDroppable) + 67 sizeof(mAcquireCalled) + 68 sizeof(mTransformToDisplayInverse); 69 return c; 70 } 71 72 size_t BufferItem::getFlattenedSize() const { 73 size_t c = 0; 74 if (mGraphicBuffer != 0) { 75 c += mGraphicBuffer->getFlattenedSize(); 76 FlattenableUtils::align<4>(c); 77 } 78 if (mFence != 0) { 79 c += mFence->getFlattenedSize(); 80 FlattenableUtils::align<4>(c); 81 } 82 return sizeof(int32_t) + c + getPodSize(); 83 } 84 85 size_t BufferItem::getFdCount() const { 86 size_t c = 0; 87 if (mGraphicBuffer != 0) { 88 c += mGraphicBuffer->getFdCount(); 89 } 90 if (mFence != 0) { 91 c += mFence->getFdCount(); 92 } 93 return c; 94 } 95 96 status_t BufferItem::flatten( 97 void*& buffer, size_t& size, int*& fds, size_t& count) const { 98 99 // make sure we have enough space 100 if (count < BufferItem::getFlattenedSize()) { 101 return NO_MEMORY; 102 } 103 104 // content flags are stored first 105 uint32_t& flags = *static_cast<uint32_t*>(buffer); 106 107 // advance the pointer 108 FlattenableUtils::advance(buffer, size, sizeof(uint32_t)); 109 110 flags = 0; 111 if (mGraphicBuffer != 0) { 112 status_t err = mGraphicBuffer->flatten(buffer, size, fds, count); 113 if (err) return err; 114 size -= FlattenableUtils::align<4>(buffer); 115 flags |= 1; 116 } 117 if (mFence != 0) { 118 status_t err = mFence->flatten(buffer, size, fds, count); 119 if (err) return err; 120 size -= FlattenableUtils::align<4>(buffer); 121 flags |= 2; 122 } 123 124 // check we have enough space (in case flattening the fence/graphicbuffer lied to us) 125 if (size < getPodSize()) { 126 return NO_MEMORY; 127 } 128 129 FlattenableUtils::write(buffer, size, mCrop); 130 FlattenableUtils::write(buffer, size, mTransform); 131 FlattenableUtils::write(buffer, size, mScalingMode); 132 FlattenableUtils::write(buffer, size, mTimestamp); 133 FlattenableUtils::write(buffer, size, mIsAutoTimestamp); 134 FlattenableUtils::write(buffer, size, mFrameNumber); 135 FlattenableUtils::write(buffer, size, mSlot); 136 FlattenableUtils::write(buffer, size, mIsDroppable); 137 FlattenableUtils::write(buffer, size, mAcquireCalled); 138 FlattenableUtils::write(buffer, size, mTransformToDisplayInverse); 139 140 return NO_ERROR; 141 } 142 143 status_t BufferItem::unflatten( 144 void const*& buffer, size_t& size, int const*& fds, size_t& count) { 145 146 if (size < sizeof(uint32_t)) 147 return NO_MEMORY; 148 149 uint32_t flags = 0; 150 FlattenableUtils::read(buffer, size, flags); 151 152 if (flags & 1) { 153 mGraphicBuffer = new GraphicBuffer(); 154 status_t err = mGraphicBuffer->unflatten(buffer, size, fds, count); 155 if (err) return err; 156 size -= FlattenableUtils::align<4>(buffer); 157 } 158 159 if (flags & 2) { 160 mFence = new Fence(); 161 status_t err = mFence->unflatten(buffer, size, fds, count); 162 if (err) return err; 163 size -= FlattenableUtils::align<4>(buffer); 164 } 165 166 // check we have enough space 167 if (size < getPodSize()) { 168 return NO_MEMORY; 169 } 170 171 FlattenableUtils::read(buffer, size, mCrop); 172 FlattenableUtils::read(buffer, size, mTransform); 173 FlattenableUtils::read(buffer, size, mScalingMode); 174 FlattenableUtils::read(buffer, size, mTimestamp); 175 FlattenableUtils::read(buffer, size, mIsAutoTimestamp); 176 FlattenableUtils::read(buffer, size, mFrameNumber); 177 FlattenableUtils::read(buffer, size, mSlot); 178 FlattenableUtils::read(buffer, size, mIsDroppable); 179 FlattenableUtils::read(buffer, size, mAcquireCalled); 180 FlattenableUtils::read(buffer, size, mTransformToDisplayInverse); 181 182 return NO_ERROR; 183 } 184 185 const char* BufferItem::scalingModeName(uint32_t scalingMode) { 186 switch (scalingMode) { 187 case NATIVE_WINDOW_SCALING_MODE_FREEZE: return "FREEZE"; 188 case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: return "SCALE_TO_WINDOW"; 189 case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: return "SCALE_CROP"; 190 default: return "Unknown"; 191 } 192 } 193 194 } // namespace android 195