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