1 /*
2 * Copyright 2021 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 <inttypes.h>
18 #include <gui/IGraphicBufferProducer.h>
19
20 namespace android {
21
minFlattenedSize()22 constexpr size_t IGraphicBufferProducer::QueueBufferInput::minFlattenedSize() {
23 return sizeof(timestamp) + sizeof(isAutoTimestamp) + sizeof(dataSpace) + sizeof(crop) +
24 sizeof(scalingMode) + sizeof(transform) + sizeof(stickyTransform) +
25 sizeof(getFrameTimestamps) + sizeof(slot) +
26 #if COM_ANDROID_GRAPHICS_LIBUI_FLAGS_APPLY_PICTURE_PROFILES
27 sizeof(decltype(pictureProfileHandle.has_value())) +
28 sizeof(decltype(pictureProfileHandle.getId()));
29 #else
30 0;
31 #endif // COM_ANDROID_GRAPHICS_LIBUI_FLAGS_APPLY_PICTURE_PROFILES
32 }
33
getFlattenedSize() const34 size_t IGraphicBufferProducer::QueueBufferInput::getFlattenedSize() const {
35 return minFlattenedSize() + fence->getFlattenedSize() + surfaceDamage.getFlattenedSize() +
36 hdrMetadata.getFlattenedSize();
37 }
38
getFdCount() const39 size_t IGraphicBufferProducer::QueueBufferInput::getFdCount() const {
40 return fence->getFdCount();
41 }
42
flatten(void * & buffer,size_t & size,int * & fds,size_t & count) const43 status_t IGraphicBufferProducer::QueueBufferInput::flatten(
44 void*& buffer, size_t& size, int*& fds, size_t& count) const
45 {
46 if (size < getFlattenedSize()) {
47 return NO_MEMORY;
48 }
49
50 FlattenableUtils::write(buffer, size, timestamp);
51 FlattenableUtils::write(buffer, size, isAutoTimestamp);
52 FlattenableUtils::write(buffer, size, dataSpace);
53 FlattenableUtils::write(buffer, size, crop);
54 FlattenableUtils::write(buffer, size, scalingMode);
55 FlattenableUtils::write(buffer, size, transform);
56 FlattenableUtils::write(buffer, size, stickyTransform);
57 FlattenableUtils::write(buffer, size, getFrameTimestamps);
58 #if COM_ANDROID_GRAPHICS_LIBUI_FLAGS_APPLY_PICTURE_PROFILES
59 FlattenableUtils::write(buffer, size, pictureProfileHandle.has_value());
60 FlattenableUtils::write(buffer, size,
61 pictureProfileHandle.has_value() ? pictureProfileHandle->getId()
62 : PictureProfileHandle::NONE.getId());
63 #endif // COM_ANDROID_GRAPHICS_LIBUI_FLAGS_APPLY_PICTURE_PROFILES
64
65 status_t result = fence->flatten(buffer, size, fds, count);
66 if (result != NO_ERROR) {
67 return result;
68 }
69 result = surfaceDamage.flatten(buffer, size);
70 if (result != NO_ERROR) {
71 return result;
72 }
73 FlattenableUtils::advance(buffer, size, surfaceDamage.getFlattenedSize());
74 result = hdrMetadata.flatten(buffer, size);
75 if (result != NO_ERROR) {
76 return result;
77 }
78 FlattenableUtils::advance(buffer, size, hdrMetadata.getFlattenedSize());
79 FlattenableUtils::write(buffer, size, slot);
80 return NO_ERROR;
81 }
82
unflatten(void const * & buffer,size_t & size,int const * & fds,size_t & count)83 status_t IGraphicBufferProducer::QueueBufferInput::unflatten(
84 void const*& buffer, size_t& size, int const*& fds, size_t& count)
85 {
86 if (size < minFlattenedSize()) {
87 return NO_MEMORY;
88 }
89
90 FlattenableUtils::read(buffer, size, timestamp);
91 FlattenableUtils::read(buffer, size, isAutoTimestamp);
92 FlattenableUtils::read(buffer, size, dataSpace);
93 FlattenableUtils::read(buffer, size, crop);
94 FlattenableUtils::read(buffer, size, scalingMode);
95 FlattenableUtils::read(buffer, size, transform);
96 FlattenableUtils::read(buffer, size, stickyTransform);
97 FlattenableUtils::read(buffer, size, getFrameTimestamps);
98 #if COM_ANDROID_GRAPHICS_LIBUI_FLAGS_APPLY_PICTURE_PROFILES
99 bool hasPictureProfileHandle;
100 FlattenableUtils::read(buffer, size, hasPictureProfileHandle);
101 PictureProfileId pictureProfileId;
102 FlattenableUtils::read(buffer, size, pictureProfileId);
103 pictureProfileHandle = hasPictureProfileHandle
104 ? std::optional(PictureProfileHandle(pictureProfileId))
105 : std::nullopt;
106 #endif // COM_ANDROID_GRAPHICS_LIBUI_FLAGS_APPLY_PICTURE_PROFILES
107
108 fence = new Fence();
109 status_t result = fence->unflatten(buffer, size, fds, count);
110 if (result != NO_ERROR) {
111 return result;
112 }
113 result = surfaceDamage.unflatten(buffer, size);
114 if (result != NO_ERROR) {
115 return result;
116 }
117 FlattenableUtils::advance(buffer, size, surfaceDamage.getFlattenedSize());
118 result = hdrMetadata.unflatten(buffer, size);
119 if (result != NO_ERROR) {
120 return result;
121 }
122 FlattenableUtils::advance(buffer, size, hdrMetadata.getFlattenedSize());
123 FlattenableUtils::read(buffer, size, slot);
124 return NO_ERROR;
125 }
126
127 ////////////////////////////////////////////////////////////////////////
minFlattenedSize()128 constexpr size_t IGraphicBufferProducer::QueueBufferOutput::minFlattenedSize() {
129 return sizeof(width) + sizeof(height) + sizeof(transformHint) + sizeof(numPendingBuffers) +
130 sizeof(nextFrameNumber) + sizeof(bufferReplaced) + sizeof(maxBufferCount) +
131 sizeof(result);
132 }
getFlattenedSize() const133 size_t IGraphicBufferProducer::QueueBufferOutput::getFlattenedSize() const {
134 return minFlattenedSize() + frameTimestamps.getFlattenedSize();
135 }
136
getFdCount() const137 size_t IGraphicBufferProducer::QueueBufferOutput::getFdCount() const {
138 return frameTimestamps.getFdCount();
139 }
140
flatten(void * & buffer,size_t & size,int * & fds,size_t & count) const141 status_t IGraphicBufferProducer::QueueBufferOutput::flatten(
142 void*& buffer, size_t& size, int*& fds, size_t& count) const
143 {
144 if (size < getFlattenedSize()) {
145 return NO_MEMORY;
146 }
147
148 FlattenableUtils::write(buffer, size, width);
149 FlattenableUtils::write(buffer, size, height);
150 FlattenableUtils::write(buffer, size, transformHint);
151 FlattenableUtils::write(buffer, size, numPendingBuffers);
152 FlattenableUtils::write(buffer, size, nextFrameNumber);
153 FlattenableUtils::write(buffer, size, bufferReplaced);
154 FlattenableUtils::write(buffer, size, maxBufferCount);
155
156 status_t result = frameTimestamps.flatten(buffer, size, fds, count);
157 if (result != NO_ERROR) {
158 return result;
159 }
160 FlattenableUtils::write(buffer, size, result);
161 return NO_ERROR;
162 }
163
unflatten(void const * & buffer,size_t & size,int const * & fds,size_t & count)164 status_t IGraphicBufferProducer::QueueBufferOutput::unflatten(
165 void const*& buffer, size_t& size, int const*& fds, size_t& count)
166 {
167 if (size < minFlattenedSize()) {
168 return NO_MEMORY;
169 }
170
171 FlattenableUtils::read(buffer, size, width);
172 FlattenableUtils::read(buffer, size, height);
173 FlattenableUtils::read(buffer, size, transformHint);
174 FlattenableUtils::read(buffer, size, numPendingBuffers);
175 FlattenableUtils::read(buffer, size, nextFrameNumber);
176 FlattenableUtils::read(buffer, size, bufferReplaced);
177 FlattenableUtils::read(buffer, size, maxBufferCount);
178
179 status_t result = frameTimestamps.unflatten(buffer, size, fds, count);
180 if (result != NO_ERROR) {
181 return result;
182 }
183 FlattenableUtils::read(buffer, size, result);
184 return NO_ERROR;
185 }
186
187 ////////////////////////////////////////////////////////////////////////
minFlattenedSize()188 constexpr size_t IGraphicBufferProducer::RequestBufferOutput::minFlattenedSize() {
189 return sizeof(result) +
190 sizeof(int32_t); // IsBufferNull
191 }
192
getFlattenedSize() const193 size_t IGraphicBufferProducer::RequestBufferOutput::getFlattenedSize() const {
194 return minFlattenedSize() + (buffer == nullptr ? 0 : buffer->getFlattenedSize());
195 }
196
getFdCount() const197 size_t IGraphicBufferProducer::RequestBufferOutput::getFdCount() const {
198 return (buffer == nullptr ? 0 : buffer->getFdCount());
199 }
200
flatten(void * & fBuffer,size_t & size,int * & fds,size_t & count) const201 status_t IGraphicBufferProducer::RequestBufferOutput::flatten(
202 void*& fBuffer, size_t& size, int*& fds, size_t& count) const {
203 if (size < getFlattenedSize()) {
204 return NO_MEMORY;
205 }
206
207 FlattenableUtils::write(fBuffer, size, result);
208 const int32_t isBufferNull = (buffer == nullptr ? 1 : 0);
209 FlattenableUtils::write(fBuffer, size, isBufferNull);
210
211 if (!isBufferNull) {
212 status_t status = buffer->flatten(fBuffer, size, fds, count);
213 if (status != NO_ERROR) {
214 return status;
215 }
216 }
217 return NO_ERROR;
218 }
219
unflatten(void const * & fBuffer,size_t & size,int const * & fds,size_t & count)220 status_t IGraphicBufferProducer::RequestBufferOutput::unflatten(
221 void const*& fBuffer, size_t& size, int const*& fds, size_t& count) {
222 if (size < minFlattenedSize()) {
223 return NO_MEMORY;
224 }
225
226 FlattenableUtils::read(fBuffer, size, result);
227 int32_t isBufferNull = 0;
228 FlattenableUtils::read(fBuffer, size, isBufferNull);
229 buffer = new GraphicBuffer();
230 if (!isBufferNull) {
231 status_t status = buffer->unflatten(fBuffer, size, fds, count);
232 if (status != NO_ERROR) {
233 return status;
234 }
235 }
236 return NO_ERROR;
237 }
238
239 ////////////////////////////////////////////////////////////////////////
240
getFlattenedSize() const241 size_t IGraphicBufferProducer::DequeueBufferInput::getFlattenedSize() const {
242 return sizeof(width) + sizeof(height) + sizeof(format) + sizeof(usage) +
243 sizeof(int32_t/*getTimestamps*/);
244 }
245
flatten(void * buffer,size_t size) const246 status_t IGraphicBufferProducer::DequeueBufferInput::flatten(void* buffer, size_t size) const {
247 if (size < getFlattenedSize()) {
248 return NO_MEMORY;
249 }
250 FlattenableUtils::write(buffer, size, width);
251 FlattenableUtils::write(buffer, size, height);
252 FlattenableUtils::write(buffer, size, format);
253 FlattenableUtils::write(buffer, size, usage);
254 const int32_t getTimestampsInt = (getTimestamps ? 1 : 0);
255 FlattenableUtils::write(buffer, size, getTimestampsInt);
256
257 return NO_ERROR;
258 }
259
unflatten(void const * buffer,size_t size)260 status_t IGraphicBufferProducer::DequeueBufferInput::unflatten(void const* buffer, size_t size) {
261 if (size < getFlattenedSize()) {
262 return NO_MEMORY;
263 }
264
265 FlattenableUtils::read(buffer, size, width);
266 FlattenableUtils::read(buffer, size, height);
267 FlattenableUtils::read(buffer, size, format);
268 FlattenableUtils::read(buffer, size, usage);
269 int32_t getTimestampsInt = 0;
270 FlattenableUtils::read(buffer, size, getTimestampsInt);
271 getTimestamps = (getTimestampsInt == 1);
272
273 return NO_ERROR;
274 }
275
276 ////////////////////////////////////////////////////////////////////////
277
minFlattenedSize()278 constexpr size_t IGraphicBufferProducer::DequeueBufferOutput::minFlattenedSize() {
279 return sizeof(result) + sizeof(slot) + sizeof(bufferAge) + sizeof(int32_t/*hasTimestamps*/);
280 }
281
getFlattenedSize() const282 size_t IGraphicBufferProducer::DequeueBufferOutput::getFlattenedSize() const {
283 return minFlattenedSize() +
284 fence->getFlattenedSize() +
285 (timestamps.has_value() ? timestamps->getFlattenedSize() : 0);
286 }
287
getFdCount() const288 size_t IGraphicBufferProducer::DequeueBufferOutput::getFdCount() const {
289 return fence->getFdCount() +
290 (timestamps.has_value() ? timestamps->getFdCount() : 0);
291 }
292
flatten(void * & buffer,size_t & size,int * & fds,size_t & count) const293 status_t IGraphicBufferProducer::DequeueBufferOutput::flatten(
294 void*& buffer, size_t& size, int*& fds, size_t& count) const {
295 if (size < getFlattenedSize()) {
296 return NO_MEMORY;
297 }
298
299 FlattenableUtils::write(buffer, size, result);
300 FlattenableUtils::write(buffer, size, slot);
301 FlattenableUtils::write(buffer, size, bufferAge);
302 status_t status = fence->flatten(buffer, size, fds, count);
303 if (status != NO_ERROR) {
304 return result;
305 }
306 const int32_t hasTimestamps = timestamps.has_value() ? 1 : 0;
307 FlattenableUtils::write(buffer, size, hasTimestamps);
308 if (timestamps.has_value()) {
309 status = timestamps->flatten(buffer, size, fds, count);
310 }
311 return status;
312 }
313
unflatten(void const * & buffer,size_t & size,int const * & fds,size_t & count)314 status_t IGraphicBufferProducer::DequeueBufferOutput::unflatten(
315 void const*& buffer, size_t& size, int const*& fds, size_t& count) {
316 if (size < minFlattenedSize()) {
317 return NO_MEMORY;
318 }
319
320 FlattenableUtils::read(buffer, size, result);
321 FlattenableUtils::read(buffer, size, slot);
322 FlattenableUtils::read(buffer, size, bufferAge);
323
324 fence = new Fence();
325 status_t status = fence->unflatten(buffer, size, fds, count);
326 if (status != NO_ERROR) {
327 return status;
328 }
329 int32_t hasTimestamps = 0;
330 FlattenableUtils::read(buffer, size, hasTimestamps);
331 if (hasTimestamps) {
332 timestamps.emplace();
333 status = timestamps->unflatten(buffer, size, fds, count);
334 }
335 return status;
336 }
337
338 ////////////////////////////////////////////////////////////////////////
339
getFlattenedSize() const340 size_t IGraphicBufferProducer::AttachBufferOutput::getFlattenedSize() const {
341 return sizeof(result) + sizeof(slot);
342 }
343
flatten(void * buffer,size_t size) const344 status_t IGraphicBufferProducer::AttachBufferOutput::flatten(void* buffer, size_t size) const {
345 if (size < getFlattenedSize()) {
346 return NO_MEMORY;
347 }
348 FlattenableUtils::write(buffer, size, result);
349 FlattenableUtils::write(buffer, size, slot);
350
351 return NO_ERROR;
352 }
353
unflatten(void const * buffer,size_t size)354 status_t IGraphicBufferProducer::AttachBufferOutput::unflatten(void const* buffer, size_t size) {
355 if (size < getFlattenedSize()) {
356 return NO_MEMORY;
357 }
358 FlattenableUtils::read(buffer, size, result);
359 FlattenableUtils::read(buffer, size, slot);
360
361 return NO_ERROR;
362 }
363
364 ////////////////////////////////////////////////////////////////////////
365
minFlattenedSize()366 constexpr size_t IGraphicBufferProducer::CancelBufferInput::minFlattenedSize() {
367 return sizeof(slot);
368 }
369
getFlattenedSize() const370 size_t IGraphicBufferProducer::CancelBufferInput::getFlattenedSize() const {
371 return minFlattenedSize() + fence->getFlattenedSize();
372 }
373
getFdCount() const374 size_t IGraphicBufferProducer::CancelBufferInput::getFdCount() const {
375 return fence->getFdCount();
376 }
377
flatten(void * & buffer,size_t & size,int * & fds,size_t & count) const378 status_t IGraphicBufferProducer::CancelBufferInput::flatten(
379 void*& buffer, size_t& size, int*& fds, size_t& count) const {
380 if (size < getFlattenedSize()) {
381 return NO_MEMORY;
382 }
383
384 FlattenableUtils::write(buffer, size, slot);
385 return fence->flatten(buffer, size, fds, count);
386 }
387
unflatten(void const * & buffer,size_t & size,int const * & fds,size_t & count)388 status_t IGraphicBufferProducer::CancelBufferInput::unflatten(
389 void const*& buffer, size_t& size, int const*& fds, size_t& count) {
390 if (size < minFlattenedSize()) {
391 return NO_MEMORY;
392 }
393
394 FlattenableUtils::read(buffer, size, slot);
395
396 fence = new Fence();
397 return fence->unflatten(buffer, size, fds, count);
398 }
399
400 ////////////////////////////////////////////////////////////////////////
401
getFlattenedSize() const402 size_t IGraphicBufferProducer::QueryOutput::getFlattenedSize() const {
403 return sizeof(result) + sizeof(value);
404 }
405
flatten(void * buffer,size_t size) const406 status_t IGraphicBufferProducer::QueryOutput::flatten(void* buffer, size_t size) const {
407 if (size < getFlattenedSize()) {
408 return NO_MEMORY;
409 }
410 FlattenableUtils::write(buffer, size, result);
411 FlattenableUtils::write(buffer, size, value);
412
413 return NO_ERROR;
414 }
415
unflatten(void const * buffer,size_t size)416 status_t IGraphicBufferProducer::QueryOutput::unflatten(void const* buffer, size_t size) {
417 if (size < getFlattenedSize()) {
418 return NO_MEMORY;
419 }
420 FlattenableUtils::read(buffer, size, result);
421 FlattenableUtils::read(buffer, size, value);
422
423 return NO_ERROR;
424 }
425
426 } // namespace android
427