• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 = sp<Fence>::make();
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) + sizeof(isSlotExpansionAllowed);
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     FlattenableUtils::write(buffer, size, isSlotExpansionAllowed);
156 
157     status_t result = frameTimestamps.flatten(buffer, size, fds, count);
158     if (result != NO_ERROR) {
159         return result;
160     }
161     FlattenableUtils::write(buffer, size, result);
162     return NO_ERROR;
163 }
164 
unflatten(void const * & buffer,size_t & size,int const * & fds,size_t & count)165 status_t IGraphicBufferProducer::QueueBufferOutput::unflatten(
166         void const*& buffer, size_t& size, int const*& fds, size_t& count)
167 {
168     if (size < minFlattenedSize()) {
169         return NO_MEMORY;
170     }
171 
172     FlattenableUtils::read(buffer, size, width);
173     FlattenableUtils::read(buffer, size, height);
174     FlattenableUtils::read(buffer, size, transformHint);
175     FlattenableUtils::read(buffer, size, numPendingBuffers);
176     FlattenableUtils::read(buffer, size, nextFrameNumber);
177     FlattenableUtils::read(buffer, size, bufferReplaced);
178     FlattenableUtils::read(buffer, size, maxBufferCount);
179     FlattenableUtils::read(buffer, size, isSlotExpansionAllowed);
180 
181     status_t result = frameTimestamps.unflatten(buffer, size, fds, count);
182     if (result != NO_ERROR) {
183         return result;
184     }
185     FlattenableUtils::read(buffer, size, result);
186     return NO_ERROR;
187 }
188 
189 ////////////////////////////////////////////////////////////////////////
minFlattenedSize()190 constexpr size_t IGraphicBufferProducer::RequestBufferOutput::minFlattenedSize() {
191     return sizeof(result) +
192             sizeof(int32_t); // IsBufferNull
193 }
194 
getFlattenedSize() const195 size_t IGraphicBufferProducer::RequestBufferOutput::getFlattenedSize() const {
196     return minFlattenedSize() + (buffer == nullptr ? 0 : buffer->getFlattenedSize());
197 }
198 
getFdCount() const199 size_t IGraphicBufferProducer::RequestBufferOutput::getFdCount() const {
200     return (buffer == nullptr ? 0 : buffer->getFdCount());
201 }
202 
flatten(void * & fBuffer,size_t & size,int * & fds,size_t & count) const203 status_t IGraphicBufferProducer::RequestBufferOutput::flatten(
204         void*& fBuffer, size_t& size, int*& fds, size_t& count) const {
205     if (size < getFlattenedSize()) {
206         return NO_MEMORY;
207     }
208 
209     FlattenableUtils::write(fBuffer, size, result);
210     const int32_t isBufferNull = (buffer == nullptr ? 1 : 0);
211     FlattenableUtils::write(fBuffer, size, isBufferNull);
212 
213     if (!isBufferNull) {
214         status_t status = buffer->flatten(fBuffer, size, fds, count);
215         if (status != NO_ERROR) {
216             return status;
217         }
218     }
219     return NO_ERROR;
220 }
221 
unflatten(void const * & fBuffer,size_t & size,int const * & fds,size_t & count)222 status_t IGraphicBufferProducer::RequestBufferOutput::unflatten(
223         void const*& fBuffer, size_t& size, int const*& fds, size_t& count) {
224     if (size < minFlattenedSize()) {
225         return NO_MEMORY;
226     }
227 
228     FlattenableUtils::read(fBuffer, size, result);
229     int32_t isBufferNull = 0;
230     FlattenableUtils::read(fBuffer, size, isBufferNull);
231     buffer = sp<GraphicBuffer>::make();
232     if (!isBufferNull) {
233         status_t status = buffer->unflatten(fBuffer, size, fds, count);
234         if (status != NO_ERROR) {
235             return status;
236         }
237     }
238     return NO_ERROR;
239 }
240 
241 ////////////////////////////////////////////////////////////////////////
242 
getFlattenedSize() const243 size_t IGraphicBufferProducer::DequeueBufferInput::getFlattenedSize() const {
244     return sizeof(width) + sizeof(height) + sizeof(format) + sizeof(usage) +
245             sizeof(int32_t/*getTimestamps*/);
246 }
247 
flatten(void * buffer,size_t size) const248 status_t IGraphicBufferProducer::DequeueBufferInput::flatten(void* buffer, size_t size) const {
249     if (size < getFlattenedSize()) {
250         return NO_MEMORY;
251     }
252     FlattenableUtils::write(buffer, size, width);
253     FlattenableUtils::write(buffer, size, height);
254     FlattenableUtils::write(buffer, size, format);
255     FlattenableUtils::write(buffer, size, usage);
256     const int32_t getTimestampsInt = (getTimestamps ? 1 : 0);
257     FlattenableUtils::write(buffer, size, getTimestampsInt);
258 
259     return NO_ERROR;
260 }
261 
unflatten(void const * buffer,size_t size)262 status_t IGraphicBufferProducer::DequeueBufferInput::unflatten(void const* buffer, size_t size) {
263     if (size < getFlattenedSize()) {
264         return NO_MEMORY;
265     }
266 
267     FlattenableUtils::read(buffer, size, width);
268     FlattenableUtils::read(buffer, size, height);
269     FlattenableUtils::read(buffer, size, format);
270     FlattenableUtils::read(buffer, size, usage);
271     int32_t getTimestampsInt = 0;
272     FlattenableUtils::read(buffer, size, getTimestampsInt);
273     getTimestamps = (getTimestampsInt == 1);
274 
275     return NO_ERROR;
276 }
277 
278 ////////////////////////////////////////////////////////////////////////
279 
minFlattenedSize()280 constexpr size_t IGraphicBufferProducer::DequeueBufferOutput::minFlattenedSize() {
281     return sizeof(result) + sizeof(slot) + sizeof(bufferAge) + sizeof(int32_t/*hasTimestamps*/);
282 }
283 
getFlattenedSize() const284 size_t IGraphicBufferProducer::DequeueBufferOutput::getFlattenedSize() const {
285     return minFlattenedSize() +
286             fence->getFlattenedSize() +
287             (timestamps.has_value() ? timestamps->getFlattenedSize() : 0);
288 }
289 
getFdCount() const290 size_t IGraphicBufferProducer::DequeueBufferOutput::getFdCount() const {
291     return fence->getFdCount() +
292             (timestamps.has_value() ? timestamps->getFdCount() : 0);
293 }
294 
flatten(void * & buffer,size_t & size,int * & fds,size_t & count) const295 status_t IGraphicBufferProducer::DequeueBufferOutput::flatten(
296         void*& buffer, size_t& size, int*& fds, size_t& count) const {
297     if (size < getFlattenedSize()) {
298         return NO_MEMORY;
299     }
300 
301     FlattenableUtils::write(buffer, size, result);
302     FlattenableUtils::write(buffer, size, slot);
303     FlattenableUtils::write(buffer, size, bufferAge);
304     status_t status = fence->flatten(buffer, size, fds, count);
305     if (status != NO_ERROR) {
306         return result;
307     }
308     const int32_t hasTimestamps = timestamps.has_value() ? 1 : 0;
309     FlattenableUtils::write(buffer, size, hasTimestamps);
310     if (timestamps.has_value()) {
311         status = timestamps->flatten(buffer, size, fds, count);
312     }
313     return status;
314 }
315 
unflatten(void const * & buffer,size_t & size,int const * & fds,size_t & count)316 status_t IGraphicBufferProducer::DequeueBufferOutput::unflatten(
317         void const*& buffer, size_t& size, int const*& fds, size_t& count) {
318     if (size < minFlattenedSize()) {
319         return NO_MEMORY;
320     }
321 
322     FlattenableUtils::read(buffer, size, result);
323     FlattenableUtils::read(buffer, size, slot);
324     FlattenableUtils::read(buffer, size, bufferAge);
325 
326     fence = sp<Fence>::make();
327     status_t status = fence->unflatten(buffer, size, fds, count);
328     if (status != NO_ERROR) {
329         return status;
330     }
331     int32_t hasTimestamps = 0;
332     FlattenableUtils::read(buffer, size, hasTimestamps);
333     if (hasTimestamps) {
334         timestamps.emplace();
335         status = timestamps->unflatten(buffer, size, fds, count);
336     }
337     return status;
338 }
339 
340 ////////////////////////////////////////////////////////////////////////
341 
getFlattenedSize() const342 size_t IGraphicBufferProducer::AttachBufferOutput::getFlattenedSize() const {
343     return sizeof(result) + sizeof(slot);
344 }
345 
flatten(void * buffer,size_t size) const346 status_t IGraphicBufferProducer::AttachBufferOutput::flatten(void* buffer, size_t size) const {
347     if (size < getFlattenedSize()) {
348         return NO_MEMORY;
349     }
350     FlattenableUtils::write(buffer, size, result);
351     FlattenableUtils::write(buffer, size, slot);
352 
353     return NO_ERROR;
354 }
355 
unflatten(void const * buffer,size_t size)356 status_t IGraphicBufferProducer::AttachBufferOutput::unflatten(void const* buffer, size_t size) {
357     if (size < getFlattenedSize()) {
358         return NO_MEMORY;
359     }
360     FlattenableUtils::read(buffer, size, result);
361     FlattenableUtils::read(buffer, size, slot);
362 
363     return NO_ERROR;
364 }
365 
366 ////////////////////////////////////////////////////////////////////////
367 
minFlattenedSize()368 constexpr size_t IGraphicBufferProducer::CancelBufferInput::minFlattenedSize() {
369     return sizeof(slot);
370 }
371 
getFlattenedSize() const372 size_t IGraphicBufferProducer::CancelBufferInput::getFlattenedSize() const {
373     return minFlattenedSize() + fence->getFlattenedSize();
374 }
375 
getFdCount() const376 size_t IGraphicBufferProducer::CancelBufferInput::getFdCount() const {
377     return fence->getFdCount();
378 }
379 
flatten(void * & buffer,size_t & size,int * & fds,size_t & count) const380 status_t IGraphicBufferProducer::CancelBufferInput::flatten(
381         void*& buffer, size_t& size, int*& fds, size_t& count) const {
382     if (size < getFlattenedSize()) {
383         return NO_MEMORY;
384     }
385 
386     FlattenableUtils::write(buffer, size, slot);
387     return fence->flatten(buffer, size, fds, count);
388 }
389 
unflatten(void const * & buffer,size_t & size,int const * & fds,size_t & count)390 status_t IGraphicBufferProducer::CancelBufferInput::unflatten(
391         void const*& buffer, size_t& size, int const*& fds, size_t& count) {
392     if (size < minFlattenedSize()) {
393         return NO_MEMORY;
394     }
395 
396     FlattenableUtils::read(buffer, size, slot);
397 
398     fence = sp<Fence>::make();
399     return fence->unflatten(buffer, size, fds, count);
400 }
401 
402 ////////////////////////////////////////////////////////////////////////
403 
getFlattenedSize() const404 size_t IGraphicBufferProducer::QueryOutput::getFlattenedSize() const {
405     return sizeof(result) + sizeof(value);
406 }
407 
flatten(void * buffer,size_t size) const408 status_t IGraphicBufferProducer::QueryOutput::flatten(void* buffer, size_t size) const {
409     if (size < getFlattenedSize()) {
410         return NO_MEMORY;
411     }
412     FlattenableUtils::write(buffer, size, result);
413     FlattenableUtils::write(buffer, size, value);
414 
415     return NO_ERROR;
416 }
417 
unflatten(void const * buffer,size_t size)418 status_t IGraphicBufferProducer::QueryOutput::unflatten(void const* buffer, size_t size) {
419     if (size < getFlattenedSize()) {
420         return NO_MEMORY;
421     }
422     FlattenableUtils::read(buffer, size, result);
423     FlattenableUtils::read(buffer, size, value);
424 
425     return NO_ERROR;
426 }
427 
428 } // namespace android
429