2 * Copyright 2014 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include <gui/BufferItem.h>
20 #include <ui/GraphicBuffer.h>
22 #include <system/window.h>
27 static inline constexpr uint32_t low32(const T n) {
28 return static_cast<uint32_t>(static_cast<uint64_t>(n));
32 static inline constexpr uint32_t high32(const T n) {
33 return static_cast<uint32_t>(static_cast<uint64_t>(n)>>32);
37 static inline constexpr T to64(const uint32_t lo, const uint32_t hi) {
38 return static_cast<T>(static_cast<uint64_t>(hi)<<32 | lo);
41 BufferItem::BufferItem() :
44 mCrop(Rect::INVALID_RECT),
46 mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
48 mIsAutoTimestamp(false),
49 mDataSpace(HAL_DATASPACE_UNKNOWN),
51 mSlot(INVALID_BUFFER_SLOT),
53 mAcquireCalled(false),
54 mTransformToDisplayInverse(false),
61 BufferItem::~BufferItem() {}
64 static void addAligned(size_t& size, T /* value */) {
65 size = FlattenableUtils::align<sizeof(T)>(size);
69 size_t BufferItem::getPodSize() const {
71 addAligned(size, mCrop);
72 addAligned(size, mTransform);
73 addAligned(size, mScalingMode);
74 addAligned(size, low32(mTimestamp));
75 addAligned(size, high32(mTimestamp));
76 addAligned(size, mIsAutoTimestamp);
77 addAligned(size, mDataSpace);
78 addAligned(size, low32(mFrameNumber));
79 addAligned(size, high32(mFrameNumber));
80 addAligned(size, mSlot);
81 addAligned(size, mIsDroppable);
82 addAligned(size, mAcquireCalled);
83 addAligned(size, mTransformToDisplayInverse);
84 addAligned(size, mAutoRefresh);
85 addAligned(size, mQueuedBuffer);
86 addAligned(size, mIsStale);
90 size_t BufferItem::getFlattenedSize() const {
91 size_t size = sizeof(uint32_t); // Flags
92 if (mGraphicBuffer != 0) {
93 size += mGraphicBuffer->getFlattenedSize();
94 size = FlattenableUtils::align<4>(size);
97 size += mFence->getFlattenedSize();
98 size = FlattenableUtils::align<4>(size);
100 size += mSurfaceDamage.getFlattenedSize();
101 size = FlattenableUtils::align<8>(size);
102 return size + getPodSize();
105 size_t BufferItem::getFdCount() const {
107 if (mGraphicBuffer != 0) {
108 count += mGraphicBuffer->getFdCount();
111 count += mFence->getFdCount();
116 template <typename T>
117 static void writeAligned(void*& buffer, size_t& size, T value) {
118 size -= FlattenableUtils::align<alignof(T)>(buffer);
119 FlattenableUtils::write(buffer, size, value);
122 status_t BufferItem::flatten(
123 void*& buffer, size_t& size, int*& fds, size_t& count) const {
125 // make sure we have enough space
126 if (size < BufferItem::getFlattenedSize()) {
130 // content flags are stored first
131 uint32_t& flags = *static_cast<uint32_t*>(buffer);
133 // advance the pointer
134 FlattenableUtils::advance(buffer, size, sizeof(uint32_t));
137 if (mGraphicBuffer != 0) {
138 status_t err = mGraphicBuffer->flatten(buffer, size, fds, count);
140 size -= FlattenableUtils::align<4>(buffer);
144 status_t err = mFence->flatten(buffer, size, fds, count);
146 size -= FlattenableUtils::align<4>(buffer);
150 status_t err = mSurfaceDamage.flatten(buffer, size);
152 FlattenableUtils::advance(buffer, size, mSurfaceDamage.getFlattenedSize());
154 // Check we still have enough space
155 if (size < getPodSize()) {
159 writeAligned(buffer, size, mCrop);
160 writeAligned(buffer, size, mTransform);
161 writeAligned(buffer, size, mScalingMode);
162 writeAligned(buffer, size, low32(mTimestamp));
163 writeAligned(buffer, size, high32(mTimestamp));
164 writeAligned(buffer, size, mIsAutoTimestamp);
165 writeAligned(buffer, size, mDataSpace);
166 writeAligned(buffer, size, low32(mFrameNumber));
167 writeAligned(buffer, size, high32(mFrameNumber));
168 writeAligned(buffer, size, mSlot);
169 writeAligned(buffer, size, mIsDroppable);
170 writeAligned(buffer, size, mAcquireCalled);
171 writeAligned(buffer, size, mTransformToDisplayInverse);
172 writeAligned(buffer, size, mAutoRefresh);
173 writeAligned(buffer, size, mQueuedBuffer);
174 writeAligned(buffer, size, mIsStale);
179 template <typename T>
180 static void readAligned(const void*& buffer, size_t& size, T& value) {
181 size -= FlattenableUtils::align<alignof(T)>(buffer);
182 FlattenableUtils::read(buffer, size, value);
185 status_t BufferItem::unflatten(
186 void const*& buffer, size_t& size, int const*& fds, size_t& count) {
188 if (size < sizeof(uint32_t)) {
193 FlattenableUtils::read(buffer, size, flags);
196 mGraphicBuffer = new GraphicBuffer();
197 status_t err = mGraphicBuffer->unflatten(buffer, size, fds, count);
199 size -= FlattenableUtils::align<4>(buffer);
203 mFence = new Fence();
204 status_t err = mFence->unflatten(buffer, size, fds, count);
206 size -= FlattenableUtils::align<4>(buffer);
208 mFenceTime = std::make_shared<FenceTime>(mFence);
211 status_t err = mSurfaceDamage.unflatten(buffer, size);
213 FlattenableUtils::advance(buffer, size, mSurfaceDamage.getFlattenedSize());
215 // Check we still have enough space
216 if (size < getPodSize()) {
220 uint32_t timestampLo = 0, timestampHi = 0;
221 uint32_t frameNumberLo = 0, frameNumberHi = 0;
223 readAligned(buffer, size, mCrop);
224 readAligned(buffer, size, mTransform);
225 readAligned(buffer, size, mScalingMode);
226 readAligned(buffer, size, timestampLo);
227 readAligned(buffer, size, timestampHi);
228 mTimestamp = to64<int64_t>(timestampLo, timestampHi);
229 readAligned(buffer, size, mIsAutoTimestamp);
230 readAligned(buffer, size, mDataSpace);
231 readAligned(buffer, size, frameNumberLo);
232 readAligned(buffer, size, frameNumberHi);
233 mFrameNumber = to64<uint64_t>(frameNumberLo, frameNumberHi);
234 readAligned(buffer, size, mSlot);
235 readAligned(buffer, size, mIsDroppable);
236 readAligned(buffer, size, mAcquireCalled);
237 readAligned(buffer, size, mTransformToDisplayInverse);
238 readAligned(buffer, size, mAutoRefresh);
239 readAligned(buffer, size, mQueuedBuffer);
240 readAligned(buffer, size, mIsStale);
245 const char* BufferItem::scalingModeName(uint32_t scalingMode) {
246 switch (scalingMode) {
247 case NATIVE_WINDOW_SCALING_MODE_FREEZE: return "FREEZE";
248 case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: return "SCALE_TO_WINDOW";
249 case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: return "SCALE_CROP";
250 default: return "Unknown";
254 } // namespace android