blob: 5beba02e63361ef6c57634d0fe403cb616455e2a [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() :
Yi Kong48a619f2018-06-05 16:34:59 -070042 mGraphicBuffer(nullptr),
43 mFence(nullptr),
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),
Chia-I Wu5c6e4632018-01-11 08:54:38 -080058 mIsStale(false),
59 mApi(0) {
Dan Stoza289ade12014-02-28 11:17:17 -080060}
61
Dan Stoza8dc55392014-11-04 11:37:46 -080062BufferItem::~BufferItem() {}
63
Dan Stozaeea6d682015-04-20 12:07:13 -070064template <typename T>
65static void addAligned(size_t& size, T /* value */) {
66 size = FlattenableUtils::align<sizeof(T)>(size);
67 size += sizeof(T);
68}
69
Dan Stoza289ade12014-02-28 11:17:17 -080070size_t BufferItem::getPodSize() const {
Dan Stozaeea6d682015-04-20 12:07:13 -070071 size_t size = 0;
72 addAligned(size, mCrop);
73 addAligned(size, mTransform);
74 addAligned(size, mScalingMode);
Colin Crossb1f30ba2016-09-30 17:24:06 -070075 addAligned(size, low32(mTimestamp));
76 addAligned(size, high32(mTimestamp));
Dan Stozaeea6d682015-04-20 12:07:13 -070077 addAligned(size, mIsAutoTimestamp);
78 addAligned(size, mDataSpace);
Colin Crossb1f30ba2016-09-30 17:24:06 -070079 addAligned(size, low32(mFrameNumber));
80 addAligned(size, high32(mFrameNumber));
Dan Stozaeea6d682015-04-20 12:07:13 -070081 addAligned(size, mSlot);
82 addAligned(size, mIsDroppable);
83 addAligned(size, mAcquireCalled);
84 addAligned(size, mTransformToDisplayInverse);
Pablo Ceballosbd3577e2016-06-20 17:40:34 -070085 addAligned(size, mAutoRefresh);
86 addAligned(size, mQueuedBuffer);
87 addAligned(size, mIsStale);
Chia-I Wu5c6e4632018-01-11 08:54:38 -080088 addAligned(size, mApi);
Dan Stozaeea6d682015-04-20 12:07:13 -070089 return size;
Dan Stoza289ade12014-02-28 11:17:17 -080090}
91
92size_t BufferItem::getFlattenedSize() const {
Dan Stozaeea6d682015-04-20 12:07:13 -070093 size_t size = sizeof(uint32_t); // Flags
Yi Kong48a619f2018-06-05 16:34:59 -070094 if (mGraphicBuffer != nullptr) {
Dan Stozaeea6d682015-04-20 12:07:13 -070095 size += mGraphicBuffer->getFlattenedSize();
Brian Anderson0f056f02016-10-10 16:06:21 -070096 size = FlattenableUtils::align<4>(size);
Dan Stoza289ade12014-02-28 11:17:17 -080097 }
Yi Kong48a619f2018-06-05 16:34:59 -070098 if (mFence != nullptr) {
Dan Stozaeea6d682015-04-20 12:07:13 -070099 size += mFence->getFlattenedSize();
Brian Anderson0f056f02016-10-10 16:06:21 -0700100 size = FlattenableUtils::align<4>(size);
Dan Stoza289ade12014-02-28 11:17:17 -0800101 }
Dan Stozaeea6d682015-04-20 12:07:13 -0700102 size += mSurfaceDamage.getFlattenedSize();
Courtney Goeltzenleuchter9bad0d72017-12-19 12:34:34 -0700103 size += mHdrMetadata.getFlattenedSize();
Dan Stozaeea6d682015-04-20 12:07:13 -0700104 size = FlattenableUtils::align<8>(size);
105 return size + getPodSize();
Dan Stoza289ade12014-02-28 11:17:17 -0800106}
107
108size_t BufferItem::getFdCount() const {
Dan Stozaeea6d682015-04-20 12:07:13 -0700109 size_t count = 0;
Yi Kong48a619f2018-06-05 16:34:59 -0700110 if (mGraphicBuffer != nullptr) {
Dan Stozaeea6d682015-04-20 12:07:13 -0700111 count += mGraphicBuffer->getFdCount();
Dan Stoza289ade12014-02-28 11:17:17 -0800112 }
Yi Kong48a619f2018-06-05 16:34:59 -0700113 if (mFence != nullptr) {
Dan Stozaeea6d682015-04-20 12:07:13 -0700114 count += mFence->getFdCount();
Dan Stoza289ade12014-02-28 11:17:17 -0800115 }
Dan Stozaeea6d682015-04-20 12:07:13 -0700116 return count;
117}
118
119template <typename T>
120static void writeAligned(void*& buffer, size_t& size, T value) {
121 size -= FlattenableUtils::align<alignof(T)>(buffer);
122 FlattenableUtils::write(buffer, size, value);
Dan Stoza289ade12014-02-28 11:17:17 -0800123}
124
125status_t BufferItem::flatten(
126 void*& buffer, size_t& size, int*& fds, size_t& count) const {
127
128 // make sure we have enough space
Dan Stozaeea6d682015-04-20 12:07:13 -0700129 if (size < BufferItem::getFlattenedSize()) {
Dan Stoza289ade12014-02-28 11:17:17 -0800130 return NO_MEMORY;
131 }
132
133 // content flags are stored first
134 uint32_t& flags = *static_cast<uint32_t*>(buffer);
135
136 // advance the pointer
137 FlattenableUtils::advance(buffer, size, sizeof(uint32_t));
138
139 flags = 0;
Yi Kong48a619f2018-06-05 16:34:59 -0700140 if (mGraphicBuffer != nullptr) {
Dan Stoza289ade12014-02-28 11:17:17 -0800141 status_t err = mGraphicBuffer->flatten(buffer, size, fds, count);
142 if (err) return err;
143 size -= FlattenableUtils::align<4>(buffer);
144 flags |= 1;
145 }
Yi Kong48a619f2018-06-05 16:34:59 -0700146 if (mFence != nullptr) {
Dan Stoza289ade12014-02-28 11:17:17 -0800147 status_t err = mFence->flatten(buffer, size, fds, count);
148 if (err) return err;
149 size -= FlattenableUtils::align<4>(buffer);
150 flags |= 2;
151 }
Dan Stozaeea6d682015-04-20 12:07:13 -0700152
Dan Stoza5065a552015-03-17 16:23:42 -0700153 status_t err = mSurfaceDamage.flatten(buffer, size);
154 if (err) return err;
Dan Stozaeea6d682015-04-20 12:07:13 -0700155 FlattenableUtils::advance(buffer, size, mSurfaceDamage.getFlattenedSize());
Dan Stoza289ade12014-02-28 11:17:17 -0800156
Courtney Goeltzenleuchter9bad0d72017-12-19 12:34:34 -0700157 err = mHdrMetadata.flatten(buffer, size);
158 if (err) return err;
159 FlattenableUtils::advance(buffer, size, mHdrMetadata.getFlattenedSize());
160
Dan Stozaeea6d682015-04-20 12:07:13 -0700161 // Check we still have enough space
Dan Stoza289ade12014-02-28 11:17:17 -0800162 if (size < getPodSize()) {
163 return NO_MEMORY;
164 }
165
Dan Stozaeea6d682015-04-20 12:07:13 -0700166 writeAligned(buffer, size, mCrop);
167 writeAligned(buffer, size, mTransform);
168 writeAligned(buffer, size, mScalingMode);
Colin Crossb1f30ba2016-09-30 17:24:06 -0700169 writeAligned(buffer, size, low32(mTimestamp));
170 writeAligned(buffer, size, high32(mTimestamp));
Dan Stozaeea6d682015-04-20 12:07:13 -0700171 writeAligned(buffer, size, mIsAutoTimestamp);
172 writeAligned(buffer, size, mDataSpace);
Colin Crossb1f30ba2016-09-30 17:24:06 -0700173 writeAligned(buffer, size, low32(mFrameNumber));
174 writeAligned(buffer, size, high32(mFrameNumber));
Dan Stozaeea6d682015-04-20 12:07:13 -0700175 writeAligned(buffer, size, mSlot);
176 writeAligned(buffer, size, mIsDroppable);
177 writeAligned(buffer, size, mAcquireCalled);
178 writeAligned(buffer, size, mTransformToDisplayInverse);
Pablo Ceballosbd3577e2016-06-20 17:40:34 -0700179 writeAligned(buffer, size, mAutoRefresh);
180 writeAligned(buffer, size, mQueuedBuffer);
181 writeAligned(buffer, size, mIsStale);
Chia-I Wu5c6e4632018-01-11 08:54:38 -0800182 writeAligned(buffer, size, mApi);
Dan Stoza289ade12014-02-28 11:17:17 -0800183
184 return NO_ERROR;
185}
186
Dan Stozaeea6d682015-04-20 12:07:13 -0700187template <typename T>
188static void readAligned(const void*& buffer, size_t& size, T& value) {
189 size -= FlattenableUtils::align<alignof(T)>(buffer);
190 FlattenableUtils::read(buffer, size, value);
191}
192
Dan Stoza289ade12014-02-28 11:17:17 -0800193status_t BufferItem::unflatten(
194 void const*& buffer, size_t& size, int const*& fds, size_t& count) {
195
Dan Stozaeea6d682015-04-20 12:07:13 -0700196 if (size < sizeof(uint32_t)) {
Dan Stoza289ade12014-02-28 11:17:17 -0800197 return NO_MEMORY;
Dan Stozaeea6d682015-04-20 12:07:13 -0700198 }
Dan Stoza289ade12014-02-28 11:17:17 -0800199
200 uint32_t flags = 0;
201 FlattenableUtils::read(buffer, size, flags);
202
203 if (flags & 1) {
204 mGraphicBuffer = new GraphicBuffer();
205 status_t err = mGraphicBuffer->unflatten(buffer, size, fds, count);
206 if (err) return err;
207 size -= FlattenableUtils::align<4>(buffer);
208 }
209
210 if (flags & 2) {
211 mFence = new Fence();
212 status_t err = mFence->unflatten(buffer, size, fds, count);
213 if (err) return err;
214 size -= FlattenableUtils::align<4>(buffer);
Brian Anderson3d4039d2016-09-23 16:31:30 -0700215
216 mFenceTime = std::make_shared<FenceTime>(mFence);
Dan Stoza289ade12014-02-28 11:17:17 -0800217 }
Dan Stozaeea6d682015-04-20 12:07:13 -0700218
Dan Stoza5065a552015-03-17 16:23:42 -0700219 status_t err = mSurfaceDamage.unflatten(buffer, size);
220 if (err) return err;
Dan Stozaeea6d682015-04-20 12:07:13 -0700221 FlattenableUtils::advance(buffer, size, mSurfaceDamage.getFlattenedSize());
Dan Stoza289ade12014-02-28 11:17:17 -0800222
Courtney Goeltzenleuchter9bad0d72017-12-19 12:34:34 -0700223 err = mHdrMetadata.unflatten(buffer, size);
224 if (err) return err;
225 FlattenableUtils::advance(buffer, size, mHdrMetadata.getFlattenedSize());
226
Dan Stozaeea6d682015-04-20 12:07:13 -0700227 // Check we still have enough space
Dan Stoza289ade12014-02-28 11:17:17 -0800228 if (size < getPodSize()) {
229 return NO_MEMORY;
230 }
231
Colin Crossb1f30ba2016-09-30 17:24:06 -0700232 uint32_t timestampLo = 0, timestampHi = 0;
233 uint32_t frameNumberLo = 0, frameNumberHi = 0;
234
Dan Stozaeea6d682015-04-20 12:07:13 -0700235 readAligned(buffer, size, mCrop);
236 readAligned(buffer, size, mTransform);
237 readAligned(buffer, size, mScalingMode);
Colin Crossb1f30ba2016-09-30 17:24:06 -0700238 readAligned(buffer, size, timestampLo);
239 readAligned(buffer, size, timestampHi);
240 mTimestamp = to64<int64_t>(timestampLo, timestampHi);
Dan Stozaeea6d682015-04-20 12:07:13 -0700241 readAligned(buffer, size, mIsAutoTimestamp);
242 readAligned(buffer, size, mDataSpace);
Colin Crossb1f30ba2016-09-30 17:24:06 -0700243 readAligned(buffer, size, frameNumberLo);
244 readAligned(buffer, size, frameNumberHi);
245 mFrameNumber = to64<uint64_t>(frameNumberLo, frameNumberHi);
Dan Stozaeea6d682015-04-20 12:07:13 -0700246 readAligned(buffer, size, mSlot);
247 readAligned(buffer, size, mIsDroppable);
248 readAligned(buffer, size, mAcquireCalled);
249 readAligned(buffer, size, mTransformToDisplayInverse);
Pablo Ceballosbd3577e2016-06-20 17:40:34 -0700250 readAligned(buffer, size, mAutoRefresh);
251 readAligned(buffer, size, mQueuedBuffer);
252 readAligned(buffer, size, mIsStale);
Chia-I Wu5c6e4632018-01-11 08:54:38 -0800253 readAligned(buffer, size, mApi);
Dan Stoza289ade12014-02-28 11:17:17 -0800254
255 return NO_ERROR;
256}
257
258const char* BufferItem::scalingModeName(uint32_t scalingMode) {
259 switch (scalingMode) {
260 case NATIVE_WINDOW_SCALING_MODE_FREEZE: return "FREEZE";
261 case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: return "SCALE_TO_WINDOW";
262 case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: return "SCALE_CROP";
263 default: return "Unknown";
264 }
265}
266
267} // namespace android