blob: 1357a4aa1a4ef051660e0b57fba332d67fe3eb09 [file] [log] [blame]
Dan Stoza289ade12014-02-28 11:17:17 -08001/*
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
Colin Crossb1f30ba2016-09-30 17:24:06 -070026template<typename T>
27static inline constexpr uint32_t low32(const T n) {
28 return static_cast<uint32_t>(static_cast<uint64_t>(n));
29}
30
31template<typename T>
32static inline constexpr uint32_t high32(const T n) {
33 return static_cast<uint32_t>(static_cast<uint64_t>(n)>>32);
34}
35
36template<typename T>
37static inline constexpr T to64(const uint32_t lo, const uint32_t hi) {
38 return static_cast<T>(static_cast<uint64_t>(hi)<<32 | lo);
39}
40
Dan Stoza289ade12014-02-28 11:17:17 -080041BufferItem::BufferItem() :
Pablo Ceballosccdfd602015-10-07 15:05:45 -070042 mGraphicBuffer(NULL),
43 mFence(NULL),
Pablo Ceballos60d69222015-08-07 14:47:20 -070044 mCrop(Rect::INVALID_RECT),
Dan Stoza289ade12014-02-28 11:17:17 -080045 mTransform(0),
46 mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
47 mTimestamp(0),
48 mIsAutoTimestamp(false),
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -080049 mDataSpace(HAL_DATASPACE_UNKNOWN),
Dan Stoza289ade12014-02-28 11:17:17 -080050 mFrameNumber(0),
51 mSlot(INVALID_BUFFER_SLOT),
52 mIsDroppable(false),
53 mAcquireCalled(false),
Pablo Ceballosccdfd602015-10-07 15:05:45 -070054 mTransformToDisplayInverse(false),
Pablo Ceballos06312182015-10-07 16:32:12 -070055 mSurfaceDamage(),
Pablo Ceballosff95aab2016-01-13 17:09:58 -080056 mAutoRefresh(false),
Pablo Ceballos23b4abe2016-01-08 12:15:22 -080057 mQueuedBuffer(true),
58 mIsStale(false) {
Dan Stoza289ade12014-02-28 11:17:17 -080059}
60
Dan Stoza8dc55392014-11-04 11:37:46 -080061BufferItem::~BufferItem() {}
62
Dan Stozaeea6d682015-04-20 12:07:13 -070063template <typename T>
64static void addAligned(size_t& size, T /* value */) {
65 size = FlattenableUtils::align<sizeof(T)>(size);
66 size += sizeof(T);
67}
68
Dan Stoza289ade12014-02-28 11:17:17 -080069size_t BufferItem::getPodSize() const {
Dan Stozaeea6d682015-04-20 12:07:13 -070070 size_t size = 0;
71 addAligned(size, mCrop);
72 addAligned(size, mTransform);
73 addAligned(size, mScalingMode);
Colin Crossb1f30ba2016-09-30 17:24:06 -070074 addAligned(size, low32(mTimestamp));
75 addAligned(size, high32(mTimestamp));
Dan Stozaeea6d682015-04-20 12:07:13 -070076 addAligned(size, mIsAutoTimestamp);
77 addAligned(size, mDataSpace);
Colin Crossb1f30ba2016-09-30 17:24:06 -070078 addAligned(size, low32(mFrameNumber));
79 addAligned(size, high32(mFrameNumber));
Dan Stozaeea6d682015-04-20 12:07:13 -070080 addAligned(size, mSlot);
81 addAligned(size, mIsDroppable);
82 addAligned(size, mAcquireCalled);
83 addAligned(size, mTransformToDisplayInverse);
84 return size;
Dan Stoza289ade12014-02-28 11:17:17 -080085}
86
87size_t BufferItem::getFlattenedSize() const {
Dan Stozaeea6d682015-04-20 12:07:13 -070088 size_t size = sizeof(uint32_t); // Flags
Dan Stoza289ade12014-02-28 11:17:17 -080089 if (mGraphicBuffer != 0) {
Dan Stozaeea6d682015-04-20 12:07:13 -070090 size += mGraphicBuffer->getFlattenedSize();
91 FlattenableUtils::align<4>(size);
Dan Stoza289ade12014-02-28 11:17:17 -080092 }
93 if (mFence != 0) {
Dan Stozaeea6d682015-04-20 12:07:13 -070094 size += mFence->getFlattenedSize();
95 FlattenableUtils::align<4>(size);
Dan Stoza289ade12014-02-28 11:17:17 -080096 }
Dan Stozaeea6d682015-04-20 12:07:13 -070097 size += mSurfaceDamage.getFlattenedSize();
98 size = FlattenableUtils::align<8>(size);
99 return size + getPodSize();
Dan Stoza289ade12014-02-28 11:17:17 -0800100}
101
102size_t BufferItem::getFdCount() const {
Dan Stozaeea6d682015-04-20 12:07:13 -0700103 size_t count = 0;
Dan Stoza289ade12014-02-28 11:17:17 -0800104 if (mGraphicBuffer != 0) {
Dan Stozaeea6d682015-04-20 12:07:13 -0700105 count += mGraphicBuffer->getFdCount();
Dan Stoza289ade12014-02-28 11:17:17 -0800106 }
107 if (mFence != 0) {
Dan Stozaeea6d682015-04-20 12:07:13 -0700108 count += mFence->getFdCount();
Dan Stoza289ade12014-02-28 11:17:17 -0800109 }
Dan Stozaeea6d682015-04-20 12:07:13 -0700110 return count;
111}
112
113template <typename T>
114static void writeAligned(void*& buffer, size_t& size, T value) {
115 size -= FlattenableUtils::align<alignof(T)>(buffer);
116 FlattenableUtils::write(buffer, size, value);
Dan Stoza289ade12014-02-28 11:17:17 -0800117}
118
119status_t BufferItem::flatten(
120 void*& buffer, size_t& size, int*& fds, size_t& count) const {
121
122 // make sure we have enough space
Dan Stozaeea6d682015-04-20 12:07:13 -0700123 if (size < BufferItem::getFlattenedSize()) {
Dan Stoza289ade12014-02-28 11:17:17 -0800124 return NO_MEMORY;
125 }
126
127 // content flags are stored first
128 uint32_t& flags = *static_cast<uint32_t*>(buffer);
129
130 // advance the pointer
131 FlattenableUtils::advance(buffer, size, sizeof(uint32_t));
132
133 flags = 0;
134 if (mGraphicBuffer != 0) {
135 status_t err = mGraphicBuffer->flatten(buffer, size, fds, count);
136 if (err) return err;
137 size -= FlattenableUtils::align<4>(buffer);
138 flags |= 1;
139 }
140 if (mFence != 0) {
141 status_t err = mFence->flatten(buffer, size, fds, count);
142 if (err) return err;
143 size -= FlattenableUtils::align<4>(buffer);
144 flags |= 2;
145 }
Dan Stozaeea6d682015-04-20 12:07:13 -0700146
Dan Stoza5065a552015-03-17 16:23:42 -0700147 status_t err = mSurfaceDamage.flatten(buffer, size);
148 if (err) return err;
Dan Stozaeea6d682015-04-20 12:07:13 -0700149 FlattenableUtils::advance(buffer, size, mSurfaceDamage.getFlattenedSize());
Dan Stoza289ade12014-02-28 11:17:17 -0800150
Dan Stozaeea6d682015-04-20 12:07:13 -0700151 // Check we still have enough space
Dan Stoza289ade12014-02-28 11:17:17 -0800152 if (size < getPodSize()) {
153 return NO_MEMORY;
154 }
155
Dan Stozaeea6d682015-04-20 12:07:13 -0700156 writeAligned(buffer, size, mCrop);
157 writeAligned(buffer, size, mTransform);
158 writeAligned(buffer, size, mScalingMode);
Colin Crossb1f30ba2016-09-30 17:24:06 -0700159 writeAligned(buffer, size, low32(mTimestamp));
160 writeAligned(buffer, size, high32(mTimestamp));
Dan Stozaeea6d682015-04-20 12:07:13 -0700161 writeAligned(buffer, size, mIsAutoTimestamp);
162 writeAligned(buffer, size, mDataSpace);
Colin Crossb1f30ba2016-09-30 17:24:06 -0700163 writeAligned(buffer, size, low32(mFrameNumber));
164 writeAligned(buffer, size, high32(mFrameNumber));
Dan Stozaeea6d682015-04-20 12:07:13 -0700165 writeAligned(buffer, size, mSlot);
166 writeAligned(buffer, size, mIsDroppable);
167 writeAligned(buffer, size, mAcquireCalled);
168 writeAligned(buffer, size, mTransformToDisplayInverse);
Dan Stoza289ade12014-02-28 11:17:17 -0800169
170 return NO_ERROR;
171}
172
Dan Stozaeea6d682015-04-20 12:07:13 -0700173template <typename T>
174static void readAligned(const void*& buffer, size_t& size, T& value) {
175 size -= FlattenableUtils::align<alignof(T)>(buffer);
176 FlattenableUtils::read(buffer, size, value);
177}
178
Dan Stoza289ade12014-02-28 11:17:17 -0800179status_t BufferItem::unflatten(
180 void const*& buffer, size_t& size, int const*& fds, size_t& count) {
181
Dan Stozaeea6d682015-04-20 12:07:13 -0700182 if (size < sizeof(uint32_t)) {
Dan Stoza289ade12014-02-28 11:17:17 -0800183 return NO_MEMORY;
Dan Stozaeea6d682015-04-20 12:07:13 -0700184 }
Dan Stoza289ade12014-02-28 11:17:17 -0800185
186 uint32_t flags = 0;
187 FlattenableUtils::read(buffer, size, flags);
188
189 if (flags & 1) {
190 mGraphicBuffer = new GraphicBuffer();
191 status_t err = mGraphicBuffer->unflatten(buffer, size, fds, count);
192 if (err) return err;
193 size -= FlattenableUtils::align<4>(buffer);
194 }
195
196 if (flags & 2) {
197 mFence = new Fence();
198 status_t err = mFence->unflatten(buffer, size, fds, count);
199 if (err) return err;
200 size -= FlattenableUtils::align<4>(buffer);
201 }
Dan Stozaeea6d682015-04-20 12:07:13 -0700202
Dan Stoza5065a552015-03-17 16:23:42 -0700203 status_t err = mSurfaceDamage.unflatten(buffer, size);
204 if (err) return err;
Dan Stozaeea6d682015-04-20 12:07:13 -0700205 FlattenableUtils::advance(buffer, size, mSurfaceDamage.getFlattenedSize());
Dan Stoza289ade12014-02-28 11:17:17 -0800206
Dan Stozaeea6d682015-04-20 12:07:13 -0700207 // Check we still have enough space
Dan Stoza289ade12014-02-28 11:17:17 -0800208 if (size < getPodSize()) {
209 return NO_MEMORY;
210 }
211
Colin Crossb1f30ba2016-09-30 17:24:06 -0700212 uint32_t timestampLo = 0, timestampHi = 0;
213 uint32_t frameNumberLo = 0, frameNumberHi = 0;
214
Dan Stozaeea6d682015-04-20 12:07:13 -0700215 readAligned(buffer, size, mCrop);
216 readAligned(buffer, size, mTransform);
217 readAligned(buffer, size, mScalingMode);
Colin Crossb1f30ba2016-09-30 17:24:06 -0700218 readAligned(buffer, size, timestampLo);
219 readAligned(buffer, size, timestampHi);
220 mTimestamp = to64<int64_t>(timestampLo, timestampHi);
Dan Stozaeea6d682015-04-20 12:07:13 -0700221 readAligned(buffer, size, mIsAutoTimestamp);
222 readAligned(buffer, size, mDataSpace);
Colin Crossb1f30ba2016-09-30 17:24:06 -0700223 readAligned(buffer, size, frameNumberLo);
224 readAligned(buffer, size, frameNumberHi);
225 mFrameNumber = to64<uint64_t>(frameNumberLo, frameNumberHi);
Dan Stozaeea6d682015-04-20 12:07:13 -0700226 readAligned(buffer, size, mSlot);
227 readAligned(buffer, size, mIsDroppable);
228 readAligned(buffer, size, mAcquireCalled);
229 readAligned(buffer, size, mTransformToDisplayInverse);
Dan Stoza289ade12014-02-28 11:17:17 -0800230
231 return NO_ERROR;
232}
233
234const char* BufferItem::scalingModeName(uint32_t scalingMode) {
235 switch (scalingMode) {
236 case NATIVE_WINDOW_SCALING_MODE_FREEZE: return "FREEZE";
237 case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: return "SCALE_TO_WINDOW";
238 case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: return "SCALE_CROP";
239 default: return "Unknown";
240 }
241}
242
243} // namespace android