xref: /aosp_15_r20/frameworks/native/libs/gui/IGraphicBufferProducerFlattenables.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
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