blob: 3b2d337a211f62b6b0ef4cf40b392f9162fcac23 [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
Brian Lindahl628cff42024-10-30 11:50:28 -060041BufferItem::BufferItem()
42 : mGraphicBuffer(nullptr),
43 mFence(nullptr),
44 mCrop(Rect::INVALID_RECT),
45 mTransform(0),
46 mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
47 mTimestamp(0),
48 mIsAutoTimestamp(false),
49 mDataSpace(HAL_DATASPACE_UNKNOWN),
50 mFrameNumber(0),
51 mSlot(INVALID_BUFFER_SLOT),
52 mIsDroppable(false),
53 mAcquireCalled(false),
54 mTransformToDisplayInverse(false),
55 mSurfaceDamage(),
56 mAutoRefresh(false),
57 mQueuedBuffer(true),
58 mIsStale(false),
59 mApi(0) {}
Dan Stoza289ade12014-02-28 11:17:17 -080060
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);
Brian Lindahl628cff42024-10-30 11:50:28 -060078#if COM_ANDROID_GRAPHICS_LIBUI_FLAGS_APPLY_PICTURE_PROFILES
79 addAligned(size, mPictureProfileHandle.has_value());
80 addAligned(size, low32(PictureProfileHandle::NONE.getId()));
81 addAligned(size, high32(PictureProfileHandle::NONE.getId()));
82#endif // COM_ANDROID_GRAPHICS_LIBUI_FLAGS_APPLY_PICTURE_PROFILES
Colin Crossb1f30ba2016-09-30 17:24:06 -070083 addAligned(size, low32(mFrameNumber));
84 addAligned(size, high32(mFrameNumber));
Dan Stozaeea6d682015-04-20 12:07:13 -070085 addAligned(size, mSlot);
86 addAligned(size, mIsDroppable);
87 addAligned(size, mAcquireCalled);
88 addAligned(size, mTransformToDisplayInverse);
Pablo Ceballosbd3577e2016-06-20 17:40:34 -070089 addAligned(size, mAutoRefresh);
90 addAligned(size, mQueuedBuffer);
91 addAligned(size, mIsStale);
Chia-I Wu5c6e4632018-01-11 08:54:38 -080092 addAligned(size, mApi);
Dan Stozaeea6d682015-04-20 12:07:13 -070093 return size;
Dan Stoza289ade12014-02-28 11:17:17 -080094}
95
96size_t BufferItem::getFlattenedSize() const {
Dan Stozaeea6d682015-04-20 12:07:13 -070097 size_t size = sizeof(uint32_t); // Flags
Yi Kong48a619f2018-06-05 16:34:59 -070098 if (mGraphicBuffer != nullptr) {
Dan Stozaeea6d682015-04-20 12:07:13 -070099 size += mGraphicBuffer->getFlattenedSize();
Brian Anderson0f056f02016-10-10 16:06:21 -0700100 size = FlattenableUtils::align<4>(size);
Dan Stoza289ade12014-02-28 11:17:17 -0800101 }
Yi Kong48a619f2018-06-05 16:34:59 -0700102 if (mFence != nullptr) {
Dan Stozaeea6d682015-04-20 12:07:13 -0700103 size += mFence->getFlattenedSize();
Brian Anderson0f056f02016-10-10 16:06:21 -0700104 size = FlattenableUtils::align<4>(size);
Dan Stoza289ade12014-02-28 11:17:17 -0800105 }
Dan Stozaeea6d682015-04-20 12:07:13 -0700106 size += mSurfaceDamage.getFlattenedSize();
Courtney Goeltzenleuchter9bad0d72017-12-19 12:34:34 -0700107 size += mHdrMetadata.getFlattenedSize();
Dan Stozaeea6d682015-04-20 12:07:13 -0700108 size = FlattenableUtils::align<8>(size);
109 return size + getPodSize();
Dan Stoza289ade12014-02-28 11:17:17 -0800110}
111
112size_t BufferItem::getFdCount() const {
Dan Stozaeea6d682015-04-20 12:07:13 -0700113 size_t count = 0;
Yi Kong48a619f2018-06-05 16:34:59 -0700114 if (mGraphicBuffer != nullptr) {
Dan Stozaeea6d682015-04-20 12:07:13 -0700115 count += mGraphicBuffer->getFdCount();
Dan Stoza289ade12014-02-28 11:17:17 -0800116 }
Yi Kong48a619f2018-06-05 16:34:59 -0700117 if (mFence != nullptr) {
Dan Stozaeea6d682015-04-20 12:07:13 -0700118 count += mFence->getFdCount();
Dan Stoza289ade12014-02-28 11:17:17 -0800119 }
Dan Stozaeea6d682015-04-20 12:07:13 -0700120 return count;
121}
122
123template <typename T>
124static void writeAligned(void*& buffer, size_t& size, T value) {
125 size -= FlattenableUtils::align<alignof(T)>(buffer);
126 FlattenableUtils::write(buffer, size, value);
Dan Stoza289ade12014-02-28 11:17:17 -0800127}
128
129status_t BufferItem::flatten(
130 void*& buffer, size_t& size, int*& fds, size_t& count) const {
131
132 // make sure we have enough space
Dan Stozaeea6d682015-04-20 12:07:13 -0700133 if (size < BufferItem::getFlattenedSize()) {
Dan Stoza289ade12014-02-28 11:17:17 -0800134 return NO_MEMORY;
135 }
136
137 // content flags are stored first
138 uint32_t& flags = *static_cast<uint32_t*>(buffer);
139
140 // advance the pointer
141 FlattenableUtils::advance(buffer, size, sizeof(uint32_t));
142
143 flags = 0;
Yi Kong48a619f2018-06-05 16:34:59 -0700144 if (mGraphicBuffer != nullptr) {
Dan Stoza289ade12014-02-28 11:17:17 -0800145 status_t err = mGraphicBuffer->flatten(buffer, size, fds, count);
146 if (err) return err;
147 size -= FlattenableUtils::align<4>(buffer);
148 flags |= 1;
149 }
Yi Kong48a619f2018-06-05 16:34:59 -0700150 if (mFence != nullptr) {
Dan Stoza289ade12014-02-28 11:17:17 -0800151 status_t err = mFence->flatten(buffer, size, fds, count);
152 if (err) return err;
153 size -= FlattenableUtils::align<4>(buffer);
154 flags |= 2;
155 }
Dan Stozaeea6d682015-04-20 12:07:13 -0700156
Dan Stoza5065a552015-03-17 16:23:42 -0700157 status_t err = mSurfaceDamage.flatten(buffer, size);
158 if (err) return err;
Dan Stozaeea6d682015-04-20 12:07:13 -0700159 FlattenableUtils::advance(buffer, size, mSurfaceDamage.getFlattenedSize());
Dan Stoza289ade12014-02-28 11:17:17 -0800160
Courtney Goeltzenleuchter9bad0d72017-12-19 12:34:34 -0700161 err = mHdrMetadata.flatten(buffer, size);
162 if (err) return err;
163 FlattenableUtils::advance(buffer, size, mHdrMetadata.getFlattenedSize());
164
Dan Stozaeea6d682015-04-20 12:07:13 -0700165 // Check we still have enough space
Dan Stoza289ade12014-02-28 11:17:17 -0800166 if (size < getPodSize()) {
167 return NO_MEMORY;
168 }
169
Dan Stozaeea6d682015-04-20 12:07:13 -0700170 writeAligned(buffer, size, mCrop);
171 writeAligned(buffer, size, mTransform);
172 writeAligned(buffer, size, mScalingMode);
Colin Crossb1f30ba2016-09-30 17:24:06 -0700173 writeAligned(buffer, size, low32(mTimestamp));
174 writeAligned(buffer, size, high32(mTimestamp));
Dan Stozaeea6d682015-04-20 12:07:13 -0700175 writeAligned(buffer, size, mIsAutoTimestamp);
176 writeAligned(buffer, size, mDataSpace);
Brian Lindahl628cff42024-10-30 11:50:28 -0600177#if COM_ANDROID_GRAPHICS_LIBUI_FLAGS_APPLY_PICTURE_PROFILES
178 writeAligned(buffer, size, mPictureProfileHandle.has_value());
179 if (mPictureProfileHandle.has_value()) {
180 writeAligned(buffer, size, low32(mPictureProfileHandle->getId()));
181 writeAligned(buffer, size, high32(mPictureProfileHandle->getId()));
182 } else {
183 writeAligned(buffer, size, low32(PictureProfileHandle::NONE.getId()));
184 writeAligned(buffer, size, high32(PictureProfileHandle::NONE.getId()));
185 }
186#endif // COM_ANDROID_GRAPHICS_LIBUI_FLAGS_APPLY_PICTURE_PROFILES
Colin Crossb1f30ba2016-09-30 17:24:06 -0700187 writeAligned(buffer, size, low32(mFrameNumber));
188 writeAligned(buffer, size, high32(mFrameNumber));
Dan Stozaeea6d682015-04-20 12:07:13 -0700189 writeAligned(buffer, size, mSlot);
190 writeAligned(buffer, size, mIsDroppable);
191 writeAligned(buffer, size, mAcquireCalled);
192 writeAligned(buffer, size, mTransformToDisplayInverse);
Pablo Ceballosbd3577e2016-06-20 17:40:34 -0700193 writeAligned(buffer, size, mAutoRefresh);
194 writeAligned(buffer, size, mQueuedBuffer);
195 writeAligned(buffer, size, mIsStale);
Chia-I Wu5c6e4632018-01-11 08:54:38 -0800196 writeAligned(buffer, size, mApi);
Dan Stoza289ade12014-02-28 11:17:17 -0800197
198 return NO_ERROR;
199}
200
Dan Stozaeea6d682015-04-20 12:07:13 -0700201template <typename T>
202static void readAligned(const void*& buffer, size_t& size, T& value) {
203 size -= FlattenableUtils::align<alignof(T)>(buffer);
204 FlattenableUtils::read(buffer, size, value);
205}
206
Dan Stoza289ade12014-02-28 11:17:17 -0800207status_t BufferItem::unflatten(
208 void const*& buffer, size_t& size, int const*& fds, size_t& count) {
209
Dan Stozaeea6d682015-04-20 12:07:13 -0700210 if (size < sizeof(uint32_t)) {
Dan Stoza289ade12014-02-28 11:17:17 -0800211 return NO_MEMORY;
Dan Stozaeea6d682015-04-20 12:07:13 -0700212 }
Dan Stoza289ade12014-02-28 11:17:17 -0800213
214 uint32_t flags = 0;
215 FlattenableUtils::read(buffer, size, flags);
216
217 if (flags & 1) {
218 mGraphicBuffer = new GraphicBuffer();
219 status_t err = mGraphicBuffer->unflatten(buffer, size, fds, count);
220 if (err) return err;
221 size -= FlattenableUtils::align<4>(buffer);
222 }
223
224 if (flags & 2) {
225 mFence = new Fence();
226 status_t err = mFence->unflatten(buffer, size, fds, count);
227 if (err) return err;
228 size -= FlattenableUtils::align<4>(buffer);
Brian Anderson3d4039d2016-09-23 16:31:30 -0700229
230 mFenceTime = std::make_shared<FenceTime>(mFence);
Dan Stoza289ade12014-02-28 11:17:17 -0800231 }
Dan Stozaeea6d682015-04-20 12:07:13 -0700232
Dan Stoza5065a552015-03-17 16:23:42 -0700233 status_t err = mSurfaceDamage.unflatten(buffer, size);
234 if (err) return err;
Dan Stozaeea6d682015-04-20 12:07:13 -0700235 FlattenableUtils::advance(buffer, size, mSurfaceDamage.getFlattenedSize());
Dan Stoza289ade12014-02-28 11:17:17 -0800236
Courtney Goeltzenleuchter9bad0d72017-12-19 12:34:34 -0700237 err = mHdrMetadata.unflatten(buffer, size);
238 if (err) return err;
239 FlattenableUtils::advance(buffer, size, mHdrMetadata.getFlattenedSize());
240
Dan Stozaeea6d682015-04-20 12:07:13 -0700241 // Check we still have enough space
Dan Stoza289ade12014-02-28 11:17:17 -0800242 if (size < getPodSize()) {
243 return NO_MEMORY;
244 }
245
Colin Crossb1f30ba2016-09-30 17:24:06 -0700246 uint32_t timestampLo = 0, timestampHi = 0;
247 uint32_t frameNumberLo = 0, frameNumberHi = 0;
Brian Lindahl628cff42024-10-30 11:50:28 -0600248 int32_t pictureProfileIdLo = 0, pictureProfileIdHi = 0;
Colin Crossb1f30ba2016-09-30 17:24:06 -0700249
Dan Stozaeea6d682015-04-20 12:07:13 -0700250 readAligned(buffer, size, mCrop);
251 readAligned(buffer, size, mTransform);
252 readAligned(buffer, size, mScalingMode);
Colin Crossb1f30ba2016-09-30 17:24:06 -0700253 readAligned(buffer, size, timestampLo);
254 readAligned(buffer, size, timestampHi);
255 mTimestamp = to64<int64_t>(timestampLo, timestampHi);
Dan Stozaeea6d682015-04-20 12:07:13 -0700256 readAligned(buffer, size, mIsAutoTimestamp);
257 readAligned(buffer, size, mDataSpace);
Brian Lindahl628cff42024-10-30 11:50:28 -0600258#if COM_ANDROID_GRAPHICS_LIBUI_FLAGS_APPLY_PICTURE_PROFILES
259 bool hasPictureProfileHandle;
260 readAligned(buffer, size, hasPictureProfileHandle);
261 readAligned(buffer, size, pictureProfileIdLo);
262 readAligned(buffer, size, pictureProfileIdHi);
263 mPictureProfileHandle = hasPictureProfileHandle
264 ? std::optional(PictureProfileHandle(
265 to64<PictureProfileId>(pictureProfileIdLo, pictureProfileIdHi)))
266 : std::nullopt;
267#endif // COM_ANDROID_GRAPHICS_LIBUI_FLAGS_APPLY_PICTURE_PROFILES
Colin Crossb1f30ba2016-09-30 17:24:06 -0700268 readAligned(buffer, size, frameNumberLo);
269 readAligned(buffer, size, frameNumberHi);
270 mFrameNumber = to64<uint64_t>(frameNumberLo, frameNumberHi);
Dan Stozaeea6d682015-04-20 12:07:13 -0700271 readAligned(buffer, size, mSlot);
272 readAligned(buffer, size, mIsDroppable);
273 readAligned(buffer, size, mAcquireCalled);
274 readAligned(buffer, size, mTransformToDisplayInverse);
Pablo Ceballosbd3577e2016-06-20 17:40:34 -0700275 readAligned(buffer, size, mAutoRefresh);
276 readAligned(buffer, size, mQueuedBuffer);
277 readAligned(buffer, size, mIsStale);
Chia-I Wu5c6e4632018-01-11 08:54:38 -0800278 readAligned(buffer, size, mApi);
Dan Stoza289ade12014-02-28 11:17:17 -0800279
280 return NO_ERROR;
281}
282
283const char* BufferItem::scalingModeName(uint32_t scalingMode) {
284 switch (scalingMode) {
285 case NATIVE_WINDOW_SCALING_MODE_FREEZE: return "FREEZE";
286 case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: return "SCALE_TO_WINDOW";
287 case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: return "SCALE_CROP";
288 default: return "Unknown";
289 }
290}
291
292} // namespace android