1f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/*
2f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * Copyright 2016, The Android Open Source Project
3f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
4f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * Licensed under the Apache License, Version 2.0 (the "License");
5f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * you may not use this file except in compliance with the License.
6f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * You may obtain a copy of the License at
7f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
8f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *      http://www.apache.org/licenses/LICENSE-2.0
9f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
10f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * Unless required by applicable law or agreed to in writing, software
11f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * distributed under the License is distributed on an "AS IS" BASIS,
12f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * See the License for the specific language governing permissions and
14f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * limitations under the License.
15f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
16f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
17517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa#ifndef ANDROID_HARDWARE_MEDIA_OMX_V1_0__CONVERSION_H
18517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa#define ANDROID_HARDWARE_MEDIA_OMX_V1_0__CONVERSION_H
19517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
200d3a5edf232916e81adbc46fc0f4a1753166b066Pawin Vongmasa#include <vector>
210d3a5edf232916e81adbc46fc0f4a1753166b066Pawin Vongmasa#include <list>
220d3a5edf232916e81adbc46fc0f4a1753166b066Pawin Vongmasa
230d3a5edf232916e81adbc46fc0f4a1753166b066Pawin Vongmasa#include <unistd.h>
240d3a5edf232916e81adbc46fc0f4a1753166b066Pawin Vongmasa
25517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa#include <hidl/MQDescriptor.h>
26f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa#include <hidl/Status.h>
27f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa#include <hidlmemory/mapping.h>
28517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
29f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa#include <binder/Binder.h>
30f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa#include <binder/Status.h>
31f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa#include <ui/FenceTime.h>
320d3a5edf232916e81adbc46fc0f4a1753166b066Pawin Vongmasa#include <media/OMXFenceParcelable.h>
33517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa#include <cutils/native_handle.h>
34f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa#include <gui/IGraphicBufferProducer.h>
35517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
360d3a5edf232916e81adbc46fc0f4a1753166b066Pawin Vongmasa#include <media/OMXBuffer.h>
37517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa#include <VideoAPI.h>
38517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
390d3a5edf232916e81adbc46fc0f4a1753166b066Pawin Vongmasa#include <android/hidl/memory/1.0/IMemory.h>
4004563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa#include <android/hardware/graphics/bufferqueue/1.0/IProducerListener.h>
41517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa#include <android/hardware/media/omx/1.0/types.h>
42517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa#include <android/hardware/media/omx/1.0/IOmx.h>
43517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa#include <android/hardware/media/omx/1.0/IOmxNode.h>
44517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa#include <android/hardware/media/omx/1.0/IOmxBufferSource.h>
45517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa#include <android/hardware/media/omx/1.0/IGraphicBufferSource.h>
4604563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa#include <android/hardware/media/omx/1.0/IOmxObserver.h>
47517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
480d3a5edf232916e81adbc46fc0f4a1753166b066Pawin Vongmasa#include <android/IGraphicBufferSource.h>
490d3a5edf232916e81adbc46fc0f4a1753166b066Pawin Vongmasa#include <android/IOMXBufferSource.h>
500d3a5edf232916e81adbc46fc0f4a1753166b066Pawin Vongmasa
51517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasanamespace android {
52517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasanamespace hardware {
53517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasanamespace media {
54517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasanamespace omx {
55517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasanamespace V1_0 {
56517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasanamespace implementation {
57517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
58517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasausing ::android::hardware::hidl_array;
59517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasausing ::android::hardware::hidl_string;
60517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasausing ::android::hardware::hidl_vec;
61f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasausing ::android::hardware::hidl_handle;
62517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasausing ::android::hardware::Return;
63517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasausing ::android::hardware::Void;
64517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasausing ::android::sp;
65517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
66517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasausing ::android::String8;
67517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasausing ::android::OMXFenceParcelable;
68517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
69517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasausing ::android::hardware::media::omx::V1_0::Message;
70517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasausing ::android::omx_message;
71517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
72517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasausing ::android::hardware::media::omx::V1_0::ColorAspects;
73f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasausing ::android::hardware::media::V1_0::Rect;
74f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasausing ::android::hardware::media::V1_0::Region;
75517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
76517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasausing ::android::hardware::graphics::common::V1_0::Dataspace;
77517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
78517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasausing ::android::hardware::graphics::common::V1_0::PixelFormat;
79517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
80517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasausing ::android::OMXBuffer;
81517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
82f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasausing ::android::hardware::media::V1_0::AnwBuffer;
83f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasausing ::android::GraphicBuffer;
84f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
85517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasausing ::android::hardware::media::omx::V1_0::IOmx;
86517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasausing ::android::IOMX;
87517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
88517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasausing ::android::hardware::media::omx::V1_0::IOmxNode;
89517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasausing ::android::IOMXNode;
90517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
91517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasausing ::android::hardware::media::omx::V1_0::IOmxObserver;
92517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasausing ::android::IOMXObserver;
93517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
94517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasausing ::android::hardware::media::omx::V1_0::IOmxBufferSource;
95517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasausing ::android::IOMXBufferSource;
96517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
9704563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasatypedef ::android::hardware::graphics::bufferqueue::V1_0::IGraphicBufferProducer
9804563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa        HGraphicBufferProducer;
9904563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasatypedef ::android::IGraphicBufferProducer
10004563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa        BGraphicBufferProducer;
101f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
102517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa// native_handle_t helper functions.
103517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
104517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa/**
105517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \brief Take an fd and create a native handle containing only the given fd.
106517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * The created handle will need to be deleted manually with
107517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * `native_handle_delete()`.
108517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
109517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[in] fd The source file descriptor (of type `int`).
110517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \return The create `native_handle_t*` that contains the given \p fd. If the
111517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * supplied \p fd is negative, the created native handle will contain no file
112517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * descriptors.
113517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
114517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * If the native handle cannot be created, the return value will be
115517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * `nullptr`.
116517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
117517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * This function does not duplicate the file descriptor.
118517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa */
119517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasainline native_handle_t* native_handle_create_from_fd(int fd) {
120517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    if (fd < 0) {
121517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        return native_handle_create(0, 0);
122517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    }
123517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    native_handle_t* nh = native_handle_create(1, 0);
124517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    if (nh == nullptr) {
125517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        return nullptr;
126517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    }
127517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    nh->data[0] = fd;
128517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    return nh;
129517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
130517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
131517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa/**
132517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \brief Extract a file descriptor from a native handle.
133517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
134517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[in] nh The source `native_handle_t*`.
135517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[in] index The index of the file descriptor in \p nh to read from. This
136517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * input has the default value of `0`.
137517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \return The `index`-th file descriptor in \p nh. If \p nh does not have
138517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * enough file descriptors, the returned value will be `-1`.
139517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
140517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * This function does not duplicate the file descriptor.
141517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa */
142517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasainline int native_handle_read_fd(native_handle_t const* nh, int index = 0) {
143517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    return ((nh == nullptr) || (nh->numFds == 0) ||
144517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            (nh->numFds <= index) || (index < 0)) ?
145517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            -1 : nh->data[index];
146517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
147517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
148517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa/**
149517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * Conversion functions
150517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * ====================
151517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
152517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * There are two main directions of conversion:
153517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * - `inTargetType(...)`: Create a wrapper whose lifetime depends on the
154517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *   input. The wrapper has type `TargetType`.
155517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * - `toTargetType(...)`: Create a standalone object of type `TargetType` that
156517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *   corresponds to the input. The lifetime of the output does not depend on the
157517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *   lifetime of the input.
158517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * - `wrapIn(TargetType*, ...)`: Same as `inTargetType()`, but for `TargetType`
159517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *   that cannot be copied and/or moved efficiently, or when there are multiple
160517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *   output arguments.
161517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * - `convertTo(TargetType*, ...)`: Same as `toTargetType()`, but for
162517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *   `TargetType` that cannot be copied and/or moved efficiently, or when there
163517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *   are multiple output arguments.
164517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
165517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * `wrapIn()` and `convertTo()` functions will take output arguments before
166517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * input arguments. Some of these functions might return a value to indicate
167517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * success or error.
168517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
169517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * In converting or wrapping something as a Treble type that contains a
170517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * `hidl_handle`, `native_handle_t*` will need to be created and returned as
171517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * an additional output argument, hence only `wrapIn()` or `convertTo()` would
172517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * be available. The caller must call `native_handle_delete()` to deallocate the
173517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * returned native handle when it is no longer needed.
174517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
175517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * For types that contain file descriptors, `inTargetType()` and `wrapAs()` do
176517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * not perform duplication of file descriptors, while `toTargetType()` and
177517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * `convertTo()` do.
178517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa */
179517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
180517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa/**
181e83be8af690ef1ac820a63414d522e77ca9d4db6Steven Moreland * \brief Convert `Return<void>` to `binder::Status`.
182517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
183e83be8af690ef1ac820a63414d522e77ca9d4db6Steven Moreland * \param[in] t The source `Return<void>`.
184517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \return The corresponding `binder::Status`.
185517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa */
186e83be8af690ef1ac820a63414d522e77ca9d4db6Steven Moreland// convert: Return<void> -> ::android::binder::Status
187517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasainline ::android::binder::Status toBinderStatus(
188e83be8af690ef1ac820a63414d522e77ca9d4db6Steven Moreland        Return<void> const& t) {
189517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    return ::android::binder::Status::fromExceptionCode(
190e83be8af690ef1ac820a63414d522e77ca9d4db6Steven Moreland            t.isOk() ? OK : UNKNOWN_ERROR,
191e83be8af690ef1ac820a63414d522e77ca9d4db6Steven Moreland            t.description().c_str());
192517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
193517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
194517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa/**
195517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \brief Convert `Return<Status>` to `status_t`. This is for legacy binder
196517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * calls.
197517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
198517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[in] t The source `Return<Status>`.
199517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \return The corresponding `status_t`.
200517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
201517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * This function first check if \p t has a transport error. If it does, then the
202517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * return value is the transport error code. Otherwise, the return value is
203517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * converted from `Status` contained inside \p t.
204517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
205517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * Note:
206517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * - This `Status` is omx-specific. It is defined in `types.hal`.
207517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * - The name of this function is not `convert`.
208517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa */
209517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa// convert: Status -> status_t
210517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasainline status_t toStatusT(Return<Status> const& t) {
211e83be8af690ef1ac820a63414d522e77ca9d4db6Steven Moreland    return t.isOk() ? static_cast<status_t>(static_cast<Status>(t)) : UNKNOWN_ERROR;
212517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
213517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
214517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa/**
215517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \brief Convert `Return<void>` to `status_t`. This is for legacy binder calls.
216517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
217517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[in] t The source `Return<void>`.
218517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \return The corresponding `status_t`.
219517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa */
220517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa// convert: Return<void> -> status_t
221517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasainline status_t toStatusT(Return<void> const& t) {
222e83be8af690ef1ac820a63414d522e77ca9d4db6Steven Moreland    return t.isOk() ? OK : UNKNOWN_ERROR;
223517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
224517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
225517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa/**
226517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \brief Convert `Status` to `status_t`. This is for legacy binder calls.
227517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
228517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[in] t The source `Status`.
229517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \return the corresponding `status_t`.
230517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa */
231517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa// convert: Status -> status_t
232517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasainline status_t toStatusT(Status const& t) {
233517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    return static_cast<status_t>(t);
234517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
235517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
236517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa/**
237517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \brief Convert `status_t` to `Status`.
238517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
239517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[in] l The source `status_t`.
240517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \return The corresponding `Status`.
241517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa */
242517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa// convert: status_t -> Status
243517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasainline Status toStatus(status_t l) {
244517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    return static_cast<Status>(l);
245517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
246517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
247517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa/**
248517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \brief Wrap `native_handle_t*` in `hidl_handle`.
249517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
250517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[in] nh The source `native_handle_t*`.
251517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \return The `hidl_handle` that points to \p nh.
252517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa */
253517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa// wrap: native_handle_t* -> hidl_handle
254517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasainline hidl_handle inHidlHandle(native_handle_t const* nh) {
255517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    return hidl_handle(nh);
256517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
257517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
258517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa/**
259517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \brief Wrap an `omx_message` and construct the corresponding `Message`.
260517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
261517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[out] t The wrapper of type `Message`.
262517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[out] nh The native_handle_t referred to by `t->fence`.
263517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[in] l The source `omx_message`.
264517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \return `true` if the wrapping is successful; `false` otherwise.
265517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
266517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * Upon success, \p nh will be created to hold the file descriptor stored in
267517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * `l.fenceFd`, and `t->fence` will point to \p nh. \p nh will need to be
268517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * destroyed manually by `native_handle_delete()` when \p t is no longer needed.
269517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
270517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * Upon failure, \p nh will not be created and will not need to be deleted. \p t
271517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * will be invalid.
272517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa */
273517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa// wrap, omx_message -> Message, native_handle_t*
274517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasainline bool wrapAs(Message* t, native_handle_t** nh, omx_message const& l) {
275517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    *nh = native_handle_create_from_fd(l.fenceFd);
276517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    if (!*nh) {
277517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        return false;
278517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    }
2798ff40189817e95c7a56e347398d20e60d7534ee6Pawin Vongmasa    t->fence = *nh;
280517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    switch (l.type) {
281517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        case omx_message::EVENT:
282517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            t->type = Message::Type::EVENT;
2838a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa            t->data.eventData.event = uint32_t(l.u.event_data.event);
284517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            t->data.eventData.data1 = l.u.event_data.data1;
285517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            t->data.eventData.data2 = l.u.event_data.data2;
286517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            t->data.eventData.data3 = l.u.event_data.data3;
287517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            t->data.eventData.data4 = l.u.event_data.data4;
288517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            break;
289517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        case omx_message::EMPTY_BUFFER_DONE:
290517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            t->type = Message::Type::EMPTY_BUFFER_DONE;
291517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            t->data.bufferData.buffer = l.u.buffer_data.buffer;
292517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            break;
293517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        case omx_message::FILL_BUFFER_DONE:
294517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            t->type = Message::Type::FILL_BUFFER_DONE;
295517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            t->data.extendedBufferData.buffer = l.u.extended_buffer_data.buffer;
296f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            t->data.extendedBufferData.rangeOffset =
297f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa                    l.u.extended_buffer_data.range_offset;
298f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            t->data.extendedBufferData.rangeLength =
299f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa                    l.u.extended_buffer_data.range_length;
300517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            t->data.extendedBufferData.flags = l.u.extended_buffer_data.flags;
301f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            t->data.extendedBufferData.timestampUs =
302f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa                    l.u.extended_buffer_data.timestamp;
303517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            break;
304517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        case omx_message::FRAME_RENDERED:
305517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            t->type = Message::Type::FRAME_RENDERED;
306517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            t->data.renderData.timestampUs = l.u.render_data.timestamp;
307517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            t->data.renderData.systemTimeNs = l.u.render_data.nanoTime;
308517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            break;
309517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        default:
310517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            native_handle_delete(*nh);
311517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            return false;
312517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    }
313517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    return true;
314517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
315517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
316517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa/**
317517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \brief Wrap a `Message` inside an `omx_message`.
318517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
319517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[out] l The wrapper of type `omx_message`.
320517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[in] t The source `Message`.
321517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \return `true` if the wrapping is successful; `false` otherwise.
322517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa */
323517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa// wrap: Message -> omx_message
324517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasainline bool wrapAs(omx_message* l, Message const& t) {
325517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    l->fenceFd = native_handle_read_fd(t.fence);
326517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    switch (t.type) {
327517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        case Message::Type::EVENT:
328517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            l->type = omx_message::EVENT;
3298a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa            l->u.event_data.event = OMX_EVENTTYPE(t.data.eventData.event);
330517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            l->u.event_data.data1 = t.data.eventData.data1;
331517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            l->u.event_data.data2 = t.data.eventData.data2;
332517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            l->u.event_data.data3 = t.data.eventData.data3;
333517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            l->u.event_data.data4 = t.data.eventData.data4;
334517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            break;
335517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        case Message::Type::EMPTY_BUFFER_DONE:
336517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            l->type = omx_message::EMPTY_BUFFER_DONE;
337517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            l->u.buffer_data.buffer = t.data.bufferData.buffer;
338517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            break;
339517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        case Message::Type::FILL_BUFFER_DONE:
340517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            l->type = omx_message::FILL_BUFFER_DONE;
341517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            l->u.extended_buffer_data.buffer = t.data.extendedBufferData.buffer;
342f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            l->u.extended_buffer_data.range_offset =
343f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa                    t.data.extendedBufferData.rangeOffset;
344f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            l->u.extended_buffer_data.range_length =
345f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa                    t.data.extendedBufferData.rangeLength;
346517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            l->u.extended_buffer_data.flags = t.data.extendedBufferData.flags;
347f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            l->u.extended_buffer_data.timestamp =
348f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa                    t.data.extendedBufferData.timestampUs;
349517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            break;
350517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        case Message::Type::FRAME_RENDERED:
351517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            l->type = omx_message::FRAME_RENDERED;
352517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            l->u.render_data.timestamp = t.data.renderData.timestampUs;
353517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            l->u.render_data.nanoTime = t.data.renderData.systemTimeNs;
354517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            break;
355517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        default:
356517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            return false;
357517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    }
358517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    return true;
359517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
360517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
361517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa/**
362517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \brief Similar to `wrapTo(omx_message*, Message const&)`, but the output will
363517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * have an extended lifetime.
364517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
365517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[out] l The output `omx_message`.
366517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[in] t The source `Message`.
367517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \return `true` if the conversion is successful; `false` otherwise.
368517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
369f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * This function calls `wrapto()`, then attempts to duplicate the file
370f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * descriptor for the fence if it is not `-1`. If duplication fails, `false`
371f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * will be returned.
372517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa */
373517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa// convert: Message -> omx_message
374517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasainline bool convertTo(omx_message* l, Message const& t) {
375517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    if (!wrapAs(l, t)) {
376517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        return false;
377517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    }
378517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    if (l->fenceFd == -1) {
379517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        return true;
380517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    }
381517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    l->fenceFd = dup(l->fenceFd);
382517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    return l->fenceFd != -1;
383517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
384517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
385517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa/**
386517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \brief Wrap an `OMXFenceParcelable` inside a `hidl_handle`.
387517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
388517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[out] t The wrapper of type `hidl_handle`.
389517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[out] nh The native handle created to hold the file descriptor inside
390517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \p l.
391517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[in] l The source `OMXFenceParcelable`, which essentially contains one
392517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * file descriptor.
393517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \return `true` if \p t and \p nh are successfully created to wrap around \p
394517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * l; `false` otherwise.
395517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
396517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * On success, \p nh needs to be deleted by the caller with
397517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * `native_handle_delete()` after \p t and \p nh are no longer needed.
398517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
399517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * On failure, \p nh will not need to be deleted, and \p t will hold an invalid
400517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * value.
401517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa */
402517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa// wrap: OMXFenceParcelable -> hidl_handle, native_handle_t*
403517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasainline bool wrapAs(hidl_handle* t, native_handle_t** nh,
404517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        OMXFenceParcelable const& l) {
405517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    *nh = native_handle_create_from_fd(l.get());
406517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    if (!*nh) {
407517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        return false;
408517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    }
409517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    *t = *nh;
410517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    return true;
411517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
412517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
413517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa/**
414517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \brief Wrap a `hidl_handle` inside an `OMXFenceParcelable`.
415517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
416517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[out] l The wrapper of type `OMXFenceParcelable`.
417517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[in] t The source `hidl_handle`.
418517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa */
419517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa// wrap: hidl_handle -> OMXFenceParcelable
420517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasainline void wrapAs(OMXFenceParcelable* l, hidl_handle const& t) {
421517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    l->mFenceFd = native_handle_read_fd(t);
422517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
423517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
424517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa/**
425517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \brief Convert a `hidl_handle` to `OMXFenceParcelable`. If `hidl_handle`
426517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * contains file descriptors, the first file descriptor will be duplicated and
427517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * stored in the output `OMXFenceParcelable`.
428517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
429517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[out] l The output `OMXFenceParcelable`.
430517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[in] t The input `hidl_handle`.
431517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \return `false` if \p t contains a valid file descriptor but duplication
432517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * fails; `true` otherwise.
433517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa */
434517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa// convert: hidl_handle -> OMXFenceParcelable
435517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasainline bool convertTo(OMXFenceParcelable* l, hidl_handle const& t) {
436517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    int fd = native_handle_read_fd(t);
437517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    if (fd != -1) {
438517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        fd = dup(fd);
439517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        if (fd == -1) {
440517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            return false;
441517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        }
442517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    }
443517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    l->mFenceFd = fd;
444517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    return true;
445517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
446517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
447517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa/**
448517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \brief Convert `::android::ColorAspects` to `ColorAspects`.
449517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
450517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[in] l The source `::android::ColorAspects`.
451517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \return The corresponding `ColorAspects`.
452517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa */
453517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa// convert: ::android::ColorAspects -> ColorAspects
454517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasainline ColorAspects toHardwareColorAspects(::android::ColorAspects const& l) {
455517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    return ColorAspects{
456517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            static_cast<ColorAspects::Range>(l.mRange),
457517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            static_cast<ColorAspects::Primaries>(l.mPrimaries),
458517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            static_cast<ColorAspects::Transfer>(l.mTransfer),
459517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            static_cast<ColorAspects::MatrixCoeffs>(l.mMatrixCoeffs)};
460517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
461517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
462517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa/**
463517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \brief Convert `int32_t` to `ColorAspects`.
464517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
465517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[in] l The source `int32_t`.
466517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \return The corresponding `ColorAspects`.
467517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa */
468517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa// convert: int32_t -> ColorAspects
469517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasainline ColorAspects toHardwareColorAspects(int32_t l) {
470517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    return ColorAspects{
471517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            static_cast<ColorAspects::Range>((l >> 24) & 0xFF),
472517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            static_cast<ColorAspects::Primaries>((l >> 16) & 0xFF),
473517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            static_cast<ColorAspects::Transfer>(l & 0xFF),
474517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            static_cast<ColorAspects::MatrixCoeffs>((l >> 8) & 0xFF)};
475517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
476517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
477517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa/**
478517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \brief Convert `ColorAspects` to `::android::ColorAspects`.
479517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
480517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[in] t The source `ColorAspects`.
481517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \return The corresponding `::android::ColorAspects`.
482517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa */
483517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa// convert: ColorAspects -> ::android::ColorAspects
484517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasainline int32_t toCompactColorAspects(ColorAspects const& t) {
485517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    return static_cast<int32_t>(
486517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            (static_cast<uint32_t>(t.range) << 24) |
487517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            (static_cast<uint32_t>(t.primaries) << 16) |
488517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            (static_cast<uint32_t>(t.transfer)) |
489517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            (static_cast<uint32_t>(t.matrixCoeffs) << 8));
490517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
491517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
492517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa/**
493517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \brief Convert `int32_t` to `Dataspace`.
494517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
495517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[in] l The source `int32_t`.
496517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \result The corresponding `Dataspace`.
497517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa */
498517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa// convert: int32_t -> Dataspace
499517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasainline Dataspace toHardwareDataspace(int32_t l) {
500517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    return static_cast<Dataspace>(l);
501517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
502517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
503517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa/**
504517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \brief Convert `Dataspace` to `int32_t`.
505517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
506517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[in] t The source `Dataspace`.
507517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \result The corresponding `int32_t`.
508517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa */
509517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa// convert: Dataspace -> int32_t
510517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasainline int32_t toRawDataspace(Dataspace const& t) {
511517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    return static_cast<int32_t>(t);
512517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
513517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
514517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa/**
515517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \brief Wrap an opaque buffer inside a `hidl_vec<uint8_t>`.
516517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
517517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[in] l The pointer to the beginning of the opaque buffer.
518517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[in] size The size of the buffer.
519517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \return A `hidl_vec<uint8_t>` that points to the buffer.
520517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa */
521517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa// wrap: void*, size_t -> hidl_vec<uint8_t>
522517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasainline hidl_vec<uint8_t> inHidlBytes(void const* l, size_t size) {
523517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    hidl_vec<uint8_t> t;
524517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    t.setToExternal(static_cast<uint8_t*>(const_cast<void*>(l)), size, false);
525517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    return t;
526517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
527517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
528517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa/**
529517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \brief Create a `hidl_vec<uint8_t>` that is a copy of an opaque buffer.
530517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
531517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[in] l The pointer to the beginning of the opaque buffer.
532517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[in] size The size of the buffer.
533517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \return A `hidl_vec<uint8_t>` that is a copy of the input buffer.
534517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa */
535517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa// convert: void*, size_t -> hidl_vec<uint8_t>
536517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasainline hidl_vec<uint8_t> toHidlBytes(void const* l, size_t size) {
537517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    hidl_vec<uint8_t> t;
538517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    t.resize(size);
539517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    uint8_t const* src = static_cast<uint8_t const*>(l);
540517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    std::copy(src, src + size, t.data());
541517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    return t;
542517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
543517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
544517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa/**
5459c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa * \brief Wrap `GraphicBuffer` in `AnwBuffer`.
5469c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa *
5479c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa * \param[out] t The wrapper of type `AnwBuffer`.
5489c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa * \param[in] l The source `GraphicBuffer`.
5499c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa */
5509c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa// wrap: GraphicBuffer -> AnwBuffer
5519c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasainline void wrapAs(AnwBuffer* t, GraphicBuffer const& l) {
5529c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    t->attr.width = l.getWidth();
5539c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    t->attr.height = l.getHeight();
5549c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    t->attr.stride = l.getStride();
5559c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    t->attr.format = static_cast<PixelFormat>(l.getPixelFormat());
5569c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    t->attr.layerCount = l.getLayerCount();
5579c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    t->attr.usage = l.getUsage();
5589c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    t->attr.id = l.getId();
5599c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    t->attr.generationNumber = l.getGenerationNumber();
5609c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    t->nativeHandle = hidl_handle(l.handle);
5619c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa}
5629c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa
5639c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa/**
5649c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa * \brief Convert `AnwBuffer` to `GraphicBuffer`.
5659c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa *
5669c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa * \param[out] l The destination `GraphicBuffer`.
5679c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa * \param[in] t The source `AnwBuffer`.
5689c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa *
5699c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa * This function will duplicate all file descriptors in \p t.
5709c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa */
5719c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa// convert: AnwBuffer -> GraphicBuffer
5729c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa// Ref: frameworks/native/libs/ui/GraphicBuffer.cpp: GraphicBuffer::flatten
5739c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasainline bool convertTo(GraphicBuffer* l, AnwBuffer const& t) {
5749c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    native_handle_t* handle = t.nativeHandle == nullptr ?
5759c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa            nullptr : native_handle_clone(t.nativeHandle);
5769c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa
5779c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    size_t const numInts = 12 + (handle ? handle->numInts : 0);
5789c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    int32_t* ints = new int32_t[numInts];
5799c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa
5809c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    size_t numFds = static_cast<size_t>(handle ? handle->numFds : 0);
5819c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    int* fds = new int[numFds];
5829c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa
5839c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    ints[0] = 'GBFR';
5849c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    ints[1] = static_cast<int32_t>(t.attr.width);
5859c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    ints[2] = static_cast<int32_t>(t.attr.height);
5869c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    ints[3] = static_cast<int32_t>(t.attr.stride);
5879c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    ints[4] = static_cast<int32_t>(t.attr.format);
5889c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    ints[5] = static_cast<int32_t>(t.attr.layerCount);
5899c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    ints[6] = static_cast<int32_t>(t.attr.usage);
5909c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    ints[7] = static_cast<int32_t>(t.attr.id >> 32);
5919c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    ints[8] = static_cast<int32_t>(t.attr.id & 0xFFFFFFFF);
5929c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    ints[9] = static_cast<int32_t>(t.attr.generationNumber);
5939c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    ints[10] = 0;
5949c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    ints[11] = 0;
5959c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    if (handle) {
5969c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa        ints[10] = static_cast<int32_t>(handle->numFds);
5979c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa        ints[11] = static_cast<int32_t>(handle->numInts);
5989c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa        int* intsStart = handle->data + handle->numFds;
5999c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa        std::copy(handle->data, intsStart, fds);
6009c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa        std::copy(intsStart, intsStart + handle->numInts, &ints[12]);
6019c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    }
6029c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa
6039c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    void const* constBuffer = static_cast<void const*>(ints);
6049c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    size_t size = numInts * sizeof(int32_t);
6059c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    int const* constFds = static_cast<int const*>(fds);
6069c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    status_t status = l->unflatten(constBuffer, size, constFds, numFds);
6079c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa
6089c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    delete [] fds;
6099c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    delete [] ints;
6109c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    native_handle_delete(handle);
6119c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    return status == NO_ERROR;
6129c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa}
6139c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa
6149c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa/**
615d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih * \brief Wrap `GraphicBuffer` in `CodecBuffer`.
616d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih *
617d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih * \param[out] t The wrapper of type `CodecBuffer`.
618d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih * \param[in] l The source `GraphicBuffer`.
619d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih */
620d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih// wrap: OMXBuffer -> CodecBuffer
621d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shihinline CodecBuffer *wrapAs(CodecBuffer *t, sp<GraphicBuffer> const& graphicBuffer) {
622d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    t->sharedMemory = hidl_memory();
623d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    t->nativeHandle = hidl_handle();
624d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    t->type = CodecBuffer::Type::ANW_BUFFER;
625d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    if (graphicBuffer == nullptr) {
626d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        t->attr.anwBuffer.width = 0;
627d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        t->attr.anwBuffer.height = 0;
628d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        t->attr.anwBuffer.stride = 0;
629d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        t->attr.anwBuffer.format = static_cast<PixelFormat>(1);
630d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        t->attr.anwBuffer.layerCount = 0;
631d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        t->attr.anwBuffer.usage = 0;
632d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return t;
633d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    }
634d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    t->attr.anwBuffer.width = graphicBuffer->getWidth();
635d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    t->attr.anwBuffer.height = graphicBuffer->getHeight();
636d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    t->attr.anwBuffer.stride = graphicBuffer->getStride();
637d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    t->attr.anwBuffer.format = static_cast<PixelFormat>(
638d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            graphicBuffer->getPixelFormat());
639d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    t->attr.anwBuffer.layerCount = graphicBuffer->getLayerCount();
640d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    t->attr.anwBuffer.usage = graphicBuffer->getUsage();
641d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    t->nativeHandle = graphicBuffer->handle;
642d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return t;
643d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih}
644d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
645d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih/**
646517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \brief Wrap `OMXBuffer` in `CodecBuffer`.
647517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
648517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[out] t The wrapper of type `CodecBuffer`.
649517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[in] l The source `OMXBuffer`.
650517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \return `true` if the wrapping is successful; `false` otherwise.
651517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa */
652517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa// wrap: OMXBuffer -> CodecBuffer
653517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasainline bool wrapAs(CodecBuffer* t, OMXBuffer const& l) {
654f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    t->sharedMemory = hidl_memory();
6559c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    t->nativeHandle = hidl_handle();
656517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    switch (l.mBufferType) {
657517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        case OMXBuffer::kBufferTypeInvalid: {
658517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            t->type = CodecBuffer::Type::INVALID;
659517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            return true;
660517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        }
661517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        case OMXBuffer::kBufferTypePreset: {
662517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            t->type = CodecBuffer::Type::PRESET;
663517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            t->attr.preset.rangeLength = static_cast<uint32_t>(l.mRangeLength);
664f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            t->attr.preset.rangeOffset = static_cast<uint32_t>(l.mRangeOffset);
665517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            return true;
666517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        }
667f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        case OMXBuffer::kBufferTypeHidlMemory: {
668517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            t->type = CodecBuffer::Type::SHARED_MEM;
669f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            t->sharedMemory = l.mHidlMemory;
670f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            return true;
671f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        }
672f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        case OMXBuffer::kBufferTypeSharedMem: {
673f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            // This is not supported.
674517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            return false;
675517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        }
676517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        case OMXBuffer::kBufferTypeANWBuffer: {
677d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            wrapAs(t, l.mGraphicBuffer);
678517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            return true;
679517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        }
680517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        case OMXBuffer::kBufferTypeNativeHandle: {
681517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            t->type = CodecBuffer::Type::NATIVE_HANDLE;
6829c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa            t->nativeHandle = l.mNativeHandle->handle();
683517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            return true;
684517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        }
685517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    }
686517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    return false;
687517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
688517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
689517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa/**
690517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \brief Convert `CodecBuffer` to `OMXBuffer`.
691517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
692517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[out] l The destination `OMXBuffer`.
693517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[in] t The source `CodecBuffer`.
694517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \return `true` if successful; `false` otherwise.
695517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa */
696517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa// convert: CodecBuffer -> OMXBuffer
697517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasainline bool convertTo(OMXBuffer* l, CodecBuffer const& t) {
698517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    switch (t.type) {
699517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        case CodecBuffer::Type::INVALID: {
700517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            *l = OMXBuffer();
701517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            return true;
702517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        }
703517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        case CodecBuffer::Type::PRESET: {
704f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            *l = OMXBuffer(
705f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa                    t.attr.preset.rangeOffset,
706f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa                    t.attr.preset.rangeLength);
707517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            return true;
708517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        }
709517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        case CodecBuffer::Type::SHARED_MEM: {
710f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            *l = OMXBuffer(t.sharedMemory);
711f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            return true;
712517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        }
713517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        case CodecBuffer::Type::ANW_BUFFER: {
7148ff40189817e95c7a56e347398d20e60d7534ee6Pawin Vongmasa            if (t.nativeHandle.getNativeHandle() == nullptr) {
7158ff40189817e95c7a56e347398d20e60d7534ee6Pawin Vongmasa                *l = OMXBuffer(sp<GraphicBuffer>(nullptr));
7168ff40189817e95c7a56e347398d20e60d7534ee6Pawin Vongmasa                return true;
7178ff40189817e95c7a56e347398d20e60d7534ee6Pawin Vongmasa            }
7189c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa            AnwBuffer anwBuffer;
7199c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa            anwBuffer.nativeHandle = t.nativeHandle;
7209c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa            anwBuffer.attr = t.attr.anwBuffer;
7219c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa            sp<GraphicBuffer> graphicBuffer = new GraphicBuffer();
7229c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa            if (!convertTo(graphicBuffer.get(), anwBuffer)) {
7239c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa                return false;
7249c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa            }
7259c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa            *l = OMXBuffer(graphicBuffer);
726517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            return true;
727517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        }
728517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        case CodecBuffer::Type::NATIVE_HANDLE: {
729517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            *l = OMXBuffer(NativeHandle::create(
730517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa                    native_handle_clone(t.nativeHandle), true));
731517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            return true;
732517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        }
733517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    }
734517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    return false;
735517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
736517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
737517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa/**
738517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \brief Convert `IOMX::ComponentInfo` to `IOmx::ComponentInfo`.
739517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
740517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[out] t The destination `IOmx::ComponentInfo`.
741517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[in] l The source `IOMX::ComponentInfo`.
742517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa */
743517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa// convert: IOMX::ComponentInfo -> IOmx::ComponentInfo
744517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasainline bool convertTo(IOmx::ComponentInfo* t, IOMX::ComponentInfo const& l) {
745517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    t->mName = l.mName.string();
746517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    t->mRoles.resize(l.mRoles.size());
747517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    size_t i = 0;
748517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    for (auto& role : l.mRoles) {
749517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        t->mRoles[i++] = role.string();
750517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    }
751517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    return true;
752517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
753517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
754517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa/**
755517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \brief Convert `IOmx::ComponentInfo` to `IOMX::ComponentInfo`.
756517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
757517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[out] l The destination `IOMX::ComponentInfo`.
758517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[in] t The source `IOmx::ComponentInfo`.
759517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa */
760517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa// convert: IOmx::ComponentInfo -> IOMX::ComponentInfo
761517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasainline bool convertTo(IOMX::ComponentInfo* l, IOmx::ComponentInfo const& t) {
762517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    l->mName = t.mName.c_str();
763517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    l->mRoles.clear();
764517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    for (size_t i = 0; i < t.mRoles.size(); ++i) {
765517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        l->mRoles.push_back(String8(t.mRoles[i].c_str()));
766517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    }
767517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    return true;
768517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
769517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
770517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa/**
771517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \brief Convert `OMX_BOOL` to `bool`.
772517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
773517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[in] l The source `OMX_BOOL`.
774517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \return The destination `bool`.
775517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa */
776517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa// convert: OMX_BOOL -> bool
777517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasainline bool toRawBool(OMX_BOOL l) {
778517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    return l == OMX_FALSE ? false : true;
779517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
780517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
781517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa/**
782517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \brief Convert `bool` to `OMX_BOOL`.
783517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
784517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[in] t The source `bool`.
785517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \return The destination `OMX_BOOL`.
786517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa */
787517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa// convert: bool -> OMX_BOOL
788517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasainline OMX_BOOL toEnumBool(bool t) {
789517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    return t ? OMX_TRUE : OMX_FALSE;
790517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
791517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
792517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa/**
793517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \brief Convert `OMX_COMMANDTYPE` to `uint32_t`.
794517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
795517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[in] l The source `OMX_COMMANDTYPE`.
796517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \return The underlying value of type `uint32_t`.
797517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
798517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * `OMX_COMMANDTYPE` is an enum type whose underlying type is `uint32_t`.
799517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa */
800517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa// convert: OMX_COMMANDTYPE -> uint32_t
801517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasainline uint32_t toRawCommandType(OMX_COMMANDTYPE l) {
802517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    return static_cast<uint32_t>(l);
803517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
804517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
805517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa/**
806517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \brief Convert `uint32_t` to `OMX_COMMANDTYPE`.
807517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
808517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[in] t The source `uint32_t`.
809517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \return The corresponding enum value of type `OMX_COMMANDTYPE`.
810517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
811517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * `OMX_COMMANDTYPE` is an enum type whose underlying type is `uint32_t`.
812517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa */
813517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa// convert: uint32_t -> OMX_COMMANDTYPE
814517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasainline OMX_COMMANDTYPE toEnumCommandType(uint32_t t) {
815517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    return static_cast<OMX_COMMANDTYPE>(t);
816517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
817517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
818517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa/**
819517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \brief Convert `OMX_INDEXTYPE` to `uint32_t`.
820517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
821517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[in] l The source `OMX_INDEXTYPE`.
822517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \return The underlying value of type `uint32_t`.
823517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
824517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * `OMX_INDEXTYPE` is an enum type whose underlying type is `uint32_t`.
825517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa */
826517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa// convert: OMX_INDEXTYPE -> uint32_t
827517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasainline uint32_t toRawIndexType(OMX_INDEXTYPE l) {
828517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    return static_cast<uint32_t>(l);
829517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
830517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
831517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa/**
832517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \brief Convert `uint32_t` to `OMX_INDEXTYPE`.
833517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
834517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[in] t The source `uint32_t`.
835517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \return The corresponding enum value of type `OMX_INDEXTYPE`.
836517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
837517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * `OMX_INDEXTYPE` is an enum type whose underlying type is `uint32_t`.
838517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa */
839517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa// convert: uint32_t -> OMX_INDEXTYPE
840517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasainline OMX_INDEXTYPE toEnumIndexType(uint32_t t) {
841517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    return static_cast<OMX_INDEXTYPE>(t);
842517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
843517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
844517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa/**
845517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \brief Convert `IOMX::PortMode` to `PortMode`.
846517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
847517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[in] l The source `IOMX::PortMode`.
848517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \return The destination `PortMode`.
849517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa */
850517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa// convert: IOMX::PortMode -> PortMode
851517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasainline PortMode toHardwarePortMode(IOMX::PortMode l) {
852517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    return static_cast<PortMode>(l);
853517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
854517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
855517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa/**
856517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \brief Convert `PortMode` to `IOMX::PortMode`.
857517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
858517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[in] t The source `PortMode`.
859517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \return The destination `IOMX::PortMode`.
860517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa */
861517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa// convert: PortMode -> IOMX::PortMode
862517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasainline IOMX::PortMode toIOMXPortMode(PortMode t) {
863517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    return static_cast<IOMX::PortMode>(t);
864517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
865517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
866517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa/**
867517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \brief Convert `OMX_TICKS` to `uint64_t`.
868517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
869517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[in] l The source `OMX_TICKS`.
870517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \return The destination `uint64_t`.
871517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa */
872517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa// convert: OMX_TICKS -> uint64_t
873517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasainline uint64_t toRawTicks(OMX_TICKS l) {
874517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa#ifndef OMX_SKIP64BIT
875517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    return static_cast<uint64_t>(l);
876517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa#else
877517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    return static_cast<uint64_t>(l.nLowPart) |
878517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            static_cast<uint64_t>(l.nHighPart << 32);
879517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa#endif
880517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
881517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
882517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa/**
883f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \brief Convert `uint64_t` to `OMX_TICKS`.
884517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa *
885517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \param[in] l The source `uint64_t`.
886517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa * \return The destination `OMX_TICKS`.
887517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa */
888517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa// convert: uint64_t -> OMX_TICKS
889517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasainline OMX_TICKS toOMXTicks(uint64_t t) {
890517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa#ifndef OMX_SKIP64BIT
891517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    return static_cast<OMX_TICKS>(t);
892517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa#else
893517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa    return OMX_TICKS{
894517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            static_cast<uint32_t>(t & 0xFFFFFFFF),
895517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa            static_cast<uint32_t>(t >> 32)};
896517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa#endif
897517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
898517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
899f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/**
900f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * Conversion functions for types outside media
901f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * ============================================
902f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
903f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * Some objects in libui and libgui that were made to go through binder calls do
904f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * not expose ways to read or write their fields to the public. To pass an
905f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * object of this kind through the HIDL boundary, translation functions need to
906f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * work around the access restriction by using the publicly available
907f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * `flatten()` and `unflatten()` functions.
908f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
909f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * All `flatten()` and `unflatten()` overloads follow the same convention as
910f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * follows:
911f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
912f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *     status_t flatten(ObjectType const& object,
913f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *                      [OtherType const& other, ...]
914f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *                      void*& buffer, size_t& size,
915f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *                      int*& fds, size_t& numFds)
916f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
917f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *     status_t unflatten(ObjectType* object,
918f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *                        [OtherType* other, ...,]
919f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *                        void*& buffer, size_t& size,
920f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *                        int*& fds, size_t& numFds)
921f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
922f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * The number of `other` parameters varies depending on the `ObjectType`. For
923f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * example, in the process of unflattening an object that contains
924f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * `hidl_handle`, `other` is needed to hold `native_handle_t` objects that will
925f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * be created.
926f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
927f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * The last four parameters always work the same way in all overloads of
928f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * `flatten()` and `unflatten()`:
929f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * - For `flatten()`, `buffer` is the pointer to the non-fd buffer to be filled,
930f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *   `size` is the size (in bytes) of the non-fd buffer pointed to by `buffer`,
931f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *   `fds` is the pointer to the fd buffer to be filled, and `numFds` is the
932f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *   size (in ints) of the fd buffer pointed to by `fds`.
933f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * - For `unflatten()`, `buffer` is the pointer to the non-fd buffer to be read
934f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *   from, `size` is the size (in bytes) of the non-fd buffer pointed to by
935f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *   `buffer`, `fds` is the pointer to the fd buffer to be read from, and
936f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *   `numFds` is the size (in ints) of the fd buffer pointed to by `fds`.
937f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * - After a successful call to `flatten()` or `unflatten()`, `buffer` and `fds`
938f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *   will be advanced, while `size` and `numFds` will be decreased to reflect
939f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *   how much storage/data of the two buffers (fd and non-fd) have been used.
940f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * - After an unsuccessful call, the values of `buffer`, `size`, `fds` and
941f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *   `numFds` are invalid.
942f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
943f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * The return value of a successful `flatten()` or `unflatten()` call will be
944f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * `OK` (also aliased as `NO_ERROR`). Any other values indicate a failure.
945f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
946f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * For each object type that supports flattening, there will be two accompanying
947f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * functions: `getFlattenedSize()` and `getFdCount()`. `getFlattenedSize()` will
948f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * return the size of the non-fd buffer that the object will need for
949f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * flattening. `getFdCount()` will return the size of the fd buffer that the
950f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * object will need for flattening.
951f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
952f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * The set of these four functions, `getFlattenedSize()`, `getFdCount()`,
953f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * `flatten()` and `unflatten()`, are similar to functions of the same name in
954f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * the abstract class `Flattenable`. The only difference is that functions in
955f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * this file are not member functions of the object type. For example, we write
956f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
957f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *     flatten(x, buffer, size, fds, numFds)
958f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
959f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * instead of
960f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
961f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *     x.flatten(buffer, size, fds, numFds)
962f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
963f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * because we cannot modify the type of `x`.
964f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
965f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * There is one exception to the naming convention: `hidl_handle` that
966f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * represents a fence. The four functions for this "Fence" type have the word
967f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * "Fence" attched to their names because the object type, which is
968f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * `hidl_handle`, does not carry the special meaning that the object itself can
969f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * only contain zero or one file descriptor.
970f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
971f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
972f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa// Ref: frameworks/native/libs/ui/Fence.cpp
973f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
974f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/**
975f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \brief Return the size of the non-fd buffer required to flatten a fence.
976f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
977f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in] fence The input fence of type `hidl_handle`.
978f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \return The required size of the flat buffer.
979f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
980f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * The current version of this function always returns 4, which is the number of
981f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * bytes required to store the number of file descriptors contained in the fd
982f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * part of the flat buffer.
983f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
984f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasainline size_t getFenceFlattenedSize(hidl_handle const& /* fence */) {
985f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    return 4;
986f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa};
987f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
988f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/**
989f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \brief Return the number of file descriptors contained in a fence.
990f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
991f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in] fence The input fence of type `hidl_handle`.
992f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \return `0` if \p fence does not contain a valid file descriptor, or `1`
993f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * otherwise.
994f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
995f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasainline size_t getFenceFdCount(hidl_handle const& fence) {
996f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    return native_handle_read_fd(fence) == -1 ? 0 : 1;
997f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa}
998f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
999f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/**
1000f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \brief Unflatten `Fence` to `hidl_handle`.
1001f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
1002f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[out] fence The destination `hidl_handle`.
1003f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[out] nh The underlying native handle.
1004f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] buffer The pointer to the flat non-fd buffer.
1005f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] size The size of the flat non-fd buffer.
1006f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] fds The pointer to the flat fd buffer.
1007f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] numFds The size of the flat fd buffer.
1008f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \return `NO_ERROR` on success; other value on failure.
1009f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
1010f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * If the return value is `NO_ERROR`, \p nh will point to a newly created
1011f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * native handle, which needs to be deleted with `native_handle_delete()`
1012f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * afterwards.
1013f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
1014f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasainline status_t unflattenFence(hidl_handle* fence, native_handle_t** nh,
1015f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
1016f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (size < 4) {
1017f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return NO_MEMORY;
1018f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1019f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1020f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    uint32_t numFdsInHandle;
1021f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::read(buffer, size, numFdsInHandle);
1022f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1023f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (numFdsInHandle > 1) {
1024f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return BAD_VALUE;
1025f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1026f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1027f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (numFds < numFdsInHandle) {
1028f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return NO_MEMORY;
1029f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1030f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1031f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (numFdsInHandle) {
1032f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        *nh = native_handle_create_from_fd(*fds);
1033f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        if (*nh == nullptr) {
1034f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            return NO_MEMORY;
1035f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        }
10368b13a00825f1ea44f5822087851fd4971d09ccacPawin Vongmasa        *fence = *nh;
1037f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        ++fds;
1038f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        --numFds;
1039f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    } else {
1040f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        *nh = nullptr;
1041f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        *fence = hidl_handle();
1042f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1043f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1044f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    return NO_ERROR;
1045f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa}
1046f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1047f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/**
1048f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \brief Flatten `hidl_handle` as `Fence`.
1049f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
1050f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in] t The source `hidl_handle`.
1051f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] buffer The pointer to the flat non-fd buffer.
1052f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] size The size of the flat non-fd buffer.
1053f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] fds The pointer to the flat fd buffer.
1054f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] numFds The size of the flat fd buffer.
1055f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \return `NO_ERROR` on success; other value on failure.
1056f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
1057f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasainline status_t flattenFence(hidl_handle const& fence,
1058f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        void*& buffer, size_t& size, int*& fds, size_t& numFds) {
1059f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (size < getFenceFlattenedSize(fence) ||
1060f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            numFds < getFenceFdCount(fence)) {
1061f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return NO_MEMORY;
1062f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1063f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    // Cast to uint32_t since the size of a size_t can vary between 32- and
1064f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    // 64-bit processes
1065f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::write(buffer, size,
1066f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            static_cast<uint32_t>(getFenceFdCount(fence)));
1067f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    int fd = native_handle_read_fd(fence);
1068f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (fd != -1) {
1069f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        *fds = fd;
1070f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        ++fds;
1071f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        --numFds;
1072f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1073f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    return NO_ERROR;
1074f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa}
1075f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1076f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/**
1077f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \brief Wrap `Fence` in `hidl_handle`.
1078f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
1079f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[out] t The wrapper of type `hidl_handle`.
1080f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[out] nh The native handle pointed to by \p t.
1081f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in] l The source `Fence`.
1082f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
1083f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * On success, \p nh will hold a newly created native handle, which must be
1084f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * deleted manually with `native_handle_delete()` afterwards.
1085f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
1086f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa// wrap: Fence -> hidl_handle
1087f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasainline bool wrapAs(hidl_handle* t, native_handle_t** nh, Fence const& l) {
1088f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    size_t const baseSize = l.getFlattenedSize();
1089f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    std::unique_ptr<uint8_t[]> baseBuffer(
1090f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            new (std::nothrow) uint8_t[baseSize]);
1091f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (!baseBuffer) {
1092f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return false;
1093f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1094f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1095f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    size_t const baseNumFds = l.getFdCount();
1096f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    std::unique_ptr<int[]> baseFds(
1097f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            new (std::nothrow) int[baseNumFds]);
1098f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (!baseFds) {
1099f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return false;
1100f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1101f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1102f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    void* buffer = static_cast<void*>(baseBuffer.get());
1103f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    size_t size = baseSize;
1104f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    int* fds = static_cast<int*>(baseFds.get());
1105f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    size_t numFds = baseNumFds;
1106f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (l.flatten(buffer, size, fds, numFds) != NO_ERROR) {
1107f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return false;
1108f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1109f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1110f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
1111f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    size = baseSize;
1112f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    int const* constFds = static_cast<int const*>(baseFds.get());
1113f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    numFds = baseNumFds;
1114f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (unflattenFence(t, nh, constBuffer, size, constFds, numFds)
1115f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            != NO_ERROR) {
1116f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return false;
1117f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1118f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1119f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    return true;
1120f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa}
1121f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1122f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/**
1123f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \brief Convert `hidl_handle` to `Fence`.
1124f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
1125f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[out] l The destination `Fence`. `l` must not have been used
1126f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * (`l->isValid()` must return `false`) before this function is called.
1127f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in] t The source `hidl_handle`.
1128f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
1129f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * If \p t contains a valid file descriptor, it will be duplicated.
1130f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
1131f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa// convert: hidl_handle -> Fence
1132f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasainline bool convertTo(Fence* l, hidl_handle const& t) {
1133f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    int fd = native_handle_read_fd(t);
1134f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (fd != -1) {
1135f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        fd = dup(fd);
1136f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        if (fd == -1) {
1137f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            return false;
1138f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        }
1139f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1140f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    native_handle_t* nh = native_handle_create_from_fd(fd);
1141f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (nh == nullptr) {
1142f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        if (fd != -1) {
1143f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            close(fd);
1144f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        }
1145f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return false;
1146f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1147f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1148f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    size_t const baseSize = getFenceFlattenedSize(t);
1149f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    std::unique_ptr<uint8_t[]> baseBuffer(
1150f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            new (std::nothrow) uint8_t[baseSize]);
1151f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (!baseBuffer) {
1152f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        native_handle_delete(nh);
1153f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return false;
1154f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1155f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1156f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    size_t const baseNumFds = getFenceFdCount(t);
1157f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    std::unique_ptr<int[]> baseFds(
1158f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            new (std::nothrow) int[baseNumFds]);
1159f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (!baseFds) {
1160f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        native_handle_delete(nh);
1161f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return false;
1162f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1163f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1164f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    void* buffer = static_cast<void*>(baseBuffer.get());
1165f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    size_t size = baseSize;
1166f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    int* fds = static_cast<int*>(baseFds.get());
1167f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    size_t numFds = baseNumFds;
1168f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (flattenFence(hidl_handle(nh), buffer, size, fds, numFds) != NO_ERROR) {
1169f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        native_handle_delete(nh);
1170f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return false;
1171f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1172f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    native_handle_delete(nh);
1173f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1174f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
1175f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    size = baseSize;
1176f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    int const* constFds = static_cast<int const*>(baseFds.get());
1177f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    numFds = baseNumFds;
1178f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (l->unflatten(constBuffer, size, constFds, numFds) != NO_ERROR) {
1179f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return false;
1180f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1181f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1182f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    return true;
1183f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa}
1184f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1185f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa// Ref: frameworks/native/libs/ui/FenceTime.cpp: FenceTime::Snapshot
1186f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1187f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/**
1188f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \brief Return the size of the non-fd buffer required to flatten
1189f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * `FenceTimeSnapshot`.
1190f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
1191f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in] t The input `FenceTimeSnapshot`.
1192f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \return The required size of the flat buffer.
1193f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
1194f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasainline size_t getFlattenedSize(
119504563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa        HGraphicBufferProducer::FenceTimeSnapshot const& t) {
1196f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    constexpr size_t min = sizeof(t.state);
1197f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    switch (t.state) {
119804563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa        case HGraphicBufferProducer::FenceTimeSnapshot::State::EMPTY:
1199f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            return min;
120004563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa        case HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE:
1201f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            return min + getFenceFlattenedSize(t.fence);
120204563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa        case HGraphicBufferProducer::FenceTimeSnapshot::State::SIGNAL_TIME:
1203f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            return min + sizeof(
1204f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa                    ::android::FenceTime::Snapshot::signalTime);
1205f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1206f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    return 0;
1207f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa}
1208f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1209f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/**
1210f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \brief Return the number of file descriptors contained in
1211f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * `FenceTimeSnapshot`.
1212f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
1213f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in] t The input `FenceTimeSnapshot`.
1214f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \return The number of file descriptors contained in \p snapshot.
1215f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
1216f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasainline size_t getFdCount(
121704563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa        HGraphicBufferProducer::FenceTimeSnapshot const& t) {
1218f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    return t.state ==
121904563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa            HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE ?
1220f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            getFenceFdCount(t.fence) : 0;
1221f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa}
1222f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1223f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/**
1224f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \brief Flatten `FenceTimeSnapshot`.
1225f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
1226f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in] t The source `FenceTimeSnapshot`.
1227f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] buffer The pointer to the flat non-fd buffer.
1228f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] size The size of the flat non-fd buffer.
1229f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] fds The pointer to the flat fd buffer.
1230f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] numFds The size of the flat fd buffer.
1231f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \return `NO_ERROR` on success; other value on failure.
1232f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
1233f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * This function will duplicate the file descriptor in `t.fence` if `t.state ==
1234f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * FENCE`.
1235f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
123604563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasainline status_t flatten(HGraphicBufferProducer::FenceTimeSnapshot const& t,
1237f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        void*& buffer, size_t& size, int*& fds, size_t& numFds) {
1238f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (size < getFlattenedSize(t)) {
1239f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return NO_MEMORY;
1240f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1241f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1242f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    switch (t.state) {
124304563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa        case HGraphicBufferProducer::FenceTimeSnapshot::State::EMPTY:
1244f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            FlattenableUtils::write(buffer, size,
1245f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa                    ::android::FenceTime::Snapshot::State::EMPTY);
1246f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            return NO_ERROR;
124704563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa        case HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE:
1248f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            FlattenableUtils::write(buffer, size,
1249f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa                    ::android::FenceTime::Snapshot::State::FENCE);
1250f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            return flattenFence(t.fence, buffer, size, fds, numFds);
125104563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa        case HGraphicBufferProducer::FenceTimeSnapshot::State::SIGNAL_TIME:
1252f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            FlattenableUtils::write(buffer, size,
1253f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa                    ::android::FenceTime::Snapshot::State::SIGNAL_TIME);
1254f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            FlattenableUtils::write(buffer, size, t.signalTimeNs);
1255f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            return NO_ERROR;
1256f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1257f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    return NO_ERROR;
1258f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa}
1259f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1260f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/**
1261f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \brief Unflatten `FenceTimeSnapshot`.
1262f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
1263f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[out] t The destination `FenceTimeSnapshot`.
1264f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[out] nh The underlying native handle.
1265f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] buffer The pointer to the flat non-fd buffer.
1266f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] size The size of the flat non-fd buffer.
1267f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] fds The pointer to the flat fd buffer.
1268f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] numFds The size of the flat fd buffer.
1269f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \return `NO_ERROR` on success; other value on failure.
1270f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
1271f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * If the return value is `NO_ERROR` and the constructed snapshot contains a
1272f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * file descriptor, \p nh will be created to hold that file descriptor. In this
1273f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * case, \p nh needs to be deleted with `native_handle_delete()` afterwards.
1274f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
1275f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasainline status_t unflatten(
127604563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa        HGraphicBufferProducer::FenceTimeSnapshot* t, native_handle_t** nh,
1277f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
1278f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (size < sizeof(t->state)) {
1279f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return NO_MEMORY;
1280f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1281f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
12828b13a00825f1ea44f5822087851fd4971d09ccacPawin Vongmasa    *nh = nullptr;
1283f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    ::android::FenceTime::Snapshot::State state;
1284f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::read(buffer, size, state);
1285f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    switch (state) {
1286f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        case ::android::FenceTime::Snapshot::State::EMPTY:
128704563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa            t->state = HGraphicBufferProducer::FenceTimeSnapshot::State::EMPTY;
1288f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            return NO_ERROR;
1289f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        case ::android::FenceTime::Snapshot::State::FENCE:
129004563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa            t->state = HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE;
1291f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            return unflattenFence(&t->fence, nh, buffer, size, fds, numFds);
1292f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        case ::android::FenceTime::Snapshot::State::SIGNAL_TIME:
129304563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa            t->state = HGraphicBufferProducer::FenceTimeSnapshot::State::SIGNAL_TIME;
1294f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            if (size < sizeof(t->signalTimeNs)) {
1295f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa                return NO_MEMORY;
1296f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            }
1297f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            FlattenableUtils::read(buffer, size, t->signalTimeNs);
1298f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            return NO_ERROR;
1299f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1300f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    return NO_ERROR;
1301f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa}
1302f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1303f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa// Ref: frameworks/native/libs/gui/FrameTimestamps.cpp: FrameEventsDelta
1304f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1305f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/**
1306f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \brief Return a lower bound on the size of the non-fd buffer required to
1307f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * flatten `FrameEventsDelta`.
1308f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
1309f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in] t The input `FrameEventsDelta`.
1310f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \return A lower bound on the size of the flat buffer.
1311f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
1312f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasaconstexpr size_t minFlattenedSize(
131304563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa        HGraphicBufferProducer::FrameEventsDelta const& /* t */) {
1314f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    return sizeof(uint64_t) + // mFrameNumber
1315f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            sizeof(uint8_t) + // mIndex
1316f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            sizeof(uint8_t) + // mAddPostCompositeCalled
1317f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            sizeof(uint8_t) + // mAddRetireCalled
1318f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            sizeof(uint8_t) + // mAddReleaseCalled
1319f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            sizeof(nsecs_t) + // mPostedTime
1320f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            sizeof(nsecs_t) + // mRequestedPresentTime
1321f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            sizeof(nsecs_t) + // mLatchTime
1322f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            sizeof(nsecs_t) + // mFirstRefreshStartTime
1323f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            sizeof(nsecs_t); // mLastRefreshStartTime
1324f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa}
1325f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1326f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/**
1327f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \brief Return the size of the non-fd buffer required to flatten
1328f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * `FrameEventsDelta`.
1329f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
1330f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in] t The input `FrameEventsDelta`.
1331f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \return The required size of the flat buffer.
1332f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
1333f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasainline size_t getFlattenedSize(
133404563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa        HGraphicBufferProducer::FrameEventsDelta const& t) {
1335f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    return minFlattenedSize(t) +
1336f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            getFlattenedSize(t.gpuCompositionDoneFence) +
1337f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            getFlattenedSize(t.displayPresentFence) +
1338f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            getFlattenedSize(t.displayRetireFence) +
1339f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            getFlattenedSize(t.releaseFence);
1340f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa};
1341f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1342f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/**
1343f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \brief Return the number of file descriptors contained in
1344f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * `FrameEventsDelta`.
1345f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
1346f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in] t The input `FrameEventsDelta`.
1347f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \return The number of file descriptors contained in \p t.
1348f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
1349f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasainline size_t getFdCount(
135004563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa        HGraphicBufferProducer::FrameEventsDelta const& t) {
1351f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    return getFdCount(t.gpuCompositionDoneFence) +
1352f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            getFdCount(t.displayPresentFence) +
1353f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            getFdCount(t.displayRetireFence) +
1354f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            getFdCount(t.releaseFence);
1355f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa};
1356f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1357f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/**
1358f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \brief Unflatten `FrameEventsDelta`.
1359f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
1360f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[out] t The destination `FrameEventsDelta`.
1361f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[out] nh The underlying array of native handles.
1362f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] buffer The pointer to the flat non-fd buffer.
1363f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] size The size of the flat non-fd buffer.
1364f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] fds The pointer to the flat fd buffer.
1365f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] numFds The size of the flat fd buffer.
1366f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \return `NO_ERROR` on success; other value on failure.
1367f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
1368f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * If the return value is `NO_ERROR`, \p nh will have length 4, and it will be
1369f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * populated with `nullptr` or newly created handles. Each non-null slot in \p
1370f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * nh will need to be deleted manually with `native_handle_delete()`.
1371f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
137204563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasainline status_t unflatten(HGraphicBufferProducer::FrameEventsDelta* t,
1373f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        std::vector<native_handle_t*>* nh,
1374f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
1375f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (size < minFlattenedSize(*t)) {
1376f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return NO_MEMORY;
1377f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1378f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::read(buffer, size, t->frameNumber);
1379f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1380f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    // These were written as uint8_t for alignment.
1381f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    uint8_t temp = 0;
1382f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::read(buffer, size, temp);
1383f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    size_t index = static_cast<size_t>(temp);
1384f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (index >= ::android::FrameEventHistory::MAX_FRAME_HISTORY) {
1385f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return BAD_VALUE;
1386f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1387f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    t->index = static_cast<uint32_t>(index);
1388f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1389f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::read(buffer, size, temp);
1390f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    t->addPostCompositeCalled = static_cast<bool>(temp);
1391f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::read(buffer, size, temp);
1392f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    t->addRetireCalled = static_cast<bool>(temp);
1393f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::read(buffer, size, temp);
1394f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    t->addReleaseCalled = static_cast<bool>(temp);
1395f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1396f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::read(buffer, size, t->postedTimeNs);
1397f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::read(buffer, size, t->requestedPresentTimeNs);
1398f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::read(buffer, size, t->latchTimeNs);
1399f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::read(buffer, size, t->firstRefreshStartTimeNs);
1400f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::read(buffer, size, t->lastRefreshStartTimeNs);
1401f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::read(buffer, size, t->dequeueReadyTime);
1402f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1403f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    // Fences
140404563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa    HGraphicBufferProducer::FenceTimeSnapshot* tSnapshot[4];
1405f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    tSnapshot[0] = &t->gpuCompositionDoneFence;
1406f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    tSnapshot[1] = &t->displayPresentFence;
1407f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    tSnapshot[2] = &t->displayRetireFence;
1408f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    tSnapshot[3] = &t->releaseFence;
1409f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    nh->resize(4);
1410f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    for (size_t snapshotIndex = 0; snapshotIndex < 4; ++snapshotIndex) {
1411f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        status_t status = unflatten(
1412f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa                tSnapshot[snapshotIndex], &((*nh)[snapshotIndex]),
1413f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa                buffer, size, fds, numFds);
1414f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        if (status != NO_ERROR) {
1415f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            while (snapshotIndex > 0) {
1416f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa                --snapshotIndex;
1417f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa                if ((*nh)[snapshotIndex] != nullptr) {
1418f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa                    native_handle_delete((*nh)[snapshotIndex]);
1419f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa                }
1420f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            }
1421f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            return status;
1422f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        }
1423f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1424f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    return NO_ERROR;
1425f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa}
1426f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1427f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/**
1428f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \brief Flatten `FrameEventsDelta`.
1429f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
1430f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in] t The source `FrameEventsDelta`.
1431f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] buffer The pointer to the flat non-fd buffer.
1432f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] size The size of the flat non-fd buffer.
1433f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] fds The pointer to the flat fd buffer.
1434f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] numFds The size of the flat fd buffer.
1435f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \return `NO_ERROR` on success; other value on failure.
1436f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
1437f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * This function will duplicate file descriptors contained in \p t.
1438f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
1439f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa// Ref: frameworks/native/libs/gui/FrameTimestamp.cpp:
1440f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa//      FrameEventsDelta::flatten
144104563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasainline status_t flatten(HGraphicBufferProducer::FrameEventsDelta const& t,
1442f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        void*& buffer, size_t& size, int*& fds, size_t numFds) {
1443f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    // Check that t.index is within a valid range.
1444f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (t.index >= static_cast<uint32_t>(FrameEventHistory::MAX_FRAME_HISTORY)
1445f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            || t.index > std::numeric_limits<uint8_t>::max()) {
1446f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return BAD_VALUE;
1447f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1448f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1449f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::write(buffer, size, t.frameNumber);
1450f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1451f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    // These are static_cast to uint8_t for alignment.
1452f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::write(buffer, size, static_cast<uint8_t>(t.index));
1453f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::write(
1454f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            buffer, size, static_cast<uint8_t>(t.addPostCompositeCalled));
1455f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::write(
1456f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            buffer, size, static_cast<uint8_t>(t.addRetireCalled));
1457f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::write(
1458f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            buffer, size, static_cast<uint8_t>(t.addReleaseCalled));
1459f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1460f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::write(buffer, size, t.postedTimeNs);
1461f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::write(buffer, size, t.requestedPresentTimeNs);
1462f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::write(buffer, size, t.latchTimeNs);
1463f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::write(buffer, size, t.firstRefreshStartTimeNs);
1464f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::write(buffer, size, t.lastRefreshStartTimeNs);
1465f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::write(buffer, size, t.dequeueReadyTime);
1466f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1467f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    // Fences
146804563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa    HGraphicBufferProducer::FenceTimeSnapshot const* tSnapshot[4];
1469f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    tSnapshot[0] = &t.gpuCompositionDoneFence;
1470f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    tSnapshot[1] = &t.displayPresentFence;
1471f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    tSnapshot[2] = &t.displayRetireFence;
1472f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    tSnapshot[3] = &t.releaseFence;
1473f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    for (size_t snapshotIndex = 0; snapshotIndex < 4; ++snapshotIndex) {
1474f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        status_t status = flatten(
1475f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa                *(tSnapshot[snapshotIndex]), buffer, size, fds, numFds);
1476f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        if (status != NO_ERROR) {
1477f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            return status;
1478f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        }
1479f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1480f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    return NO_ERROR;
1481f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa}
1482f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1483f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa// Ref: frameworks/native/libs/gui/FrameTimestamps.cpp: FrameEventHistoryDelta
1484f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1485f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/**
1486f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \brief Return the size of the non-fd buffer required to flatten
148704563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * `HGraphicBufferProducer::FrameEventHistoryDelta`.
1488f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
148904563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * \param[in] t The input `HGraphicBufferProducer::FrameEventHistoryDelta`.
1490f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \return The required size of the flat buffer.
1491f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
1492f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasainline size_t getFlattenedSize(
149304563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa        HGraphicBufferProducer::FrameEventHistoryDelta const& t) {
14941f82e093581e6175c0ea0a99f1f9e8ee335502b9Brian Anderson    size_t size = 4 + // mDeltas.size()
14951f82e093581e6175c0ea0a99f1f9e8ee335502b9Brian Anderson            sizeof(t.compositorTiming);
14961f82e093581e6175c0ea0a99f1f9e8ee335502b9Brian Anderson    for (size_t i = 0; i < t.deltas.size(); ++i) {
14971f82e093581e6175c0ea0a99f1f9e8ee335502b9Brian Anderson        size += getFlattenedSize(t.deltas[i]);
1498f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1499f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    return size;
1500f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa}
1501f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1502f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/**
1503f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \brief Return the number of file descriptors contained in
150404563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * `HGraphicBufferProducer::FrameEventHistoryDelta`.
1505f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
150604563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * \param[in] t The input `HGraphicBufferProducer::FrameEventHistoryDelta`.
1507f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \return The number of file descriptors contained in \p t.
1508f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
1509f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasainline size_t getFdCount(
151004563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa        HGraphicBufferProducer::FrameEventHistoryDelta const& t) {
1511f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    size_t numFds = 0;
15121f82e093581e6175c0ea0a99f1f9e8ee335502b9Brian Anderson    for (size_t i = 0; i < t.deltas.size(); ++i) {
15131f82e093581e6175c0ea0a99f1f9e8ee335502b9Brian Anderson        numFds += getFdCount(t.deltas[i]);
1514f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1515f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    return numFds;
1516f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa}
1517f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1518f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/**
1519f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \brief Unflatten `FrameEventHistoryDelta`.
1520f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
1521f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[out] t The destination `FrameEventHistoryDelta`.
1522f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[out] nh The underlying array of arrays of native handles.
1523f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] buffer The pointer to the flat non-fd buffer.
1524f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] size The size of the flat non-fd buffer.
1525f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] fds The pointer to the flat fd buffer.
1526f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] numFds The size of the flat fd buffer.
1527f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \return `NO_ERROR` on success; other value on failure.
1528f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
1529f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * If the return value is `NO_ERROR`, \p nh will be populated with `nullptr` or
1530f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * newly created handles. The second dimension of \p nh will be 4. Each non-null
1531f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * slot in \p nh will need to be deleted manually with `native_handle_delete()`.
1532f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
1533f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasainline status_t unflatten(
153404563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa        HGraphicBufferProducer::FrameEventHistoryDelta* t,
1535f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        std::vector<std::vector<native_handle_t*> >* nh,
1536f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
1537f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (size < 4) {
1538f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return NO_MEMORY;
1539f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1540f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
15411f82e093581e6175c0ea0a99f1f9e8ee335502b9Brian Anderson    FlattenableUtils::read(buffer, size, t->compositorTiming);
15421f82e093581e6175c0ea0a99f1f9e8ee335502b9Brian Anderson
1543f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    uint32_t deltaCount = 0;
1544f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::read(buffer, size, deltaCount);
1545f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (static_cast<size_t>(deltaCount) >
1546f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            ::android::FrameEventHistory::MAX_FRAME_HISTORY) {
1547f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return BAD_VALUE;
1548f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
15491f82e093581e6175c0ea0a99f1f9e8ee335502b9Brian Anderson    t->deltas.resize(deltaCount);
1550f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    nh->resize(deltaCount);
1551f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    for (size_t deltaIndex = 0; deltaIndex < deltaCount; ++deltaIndex) {
1552f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        status_t status = unflatten(
15531f82e093581e6175c0ea0a99f1f9e8ee335502b9Brian Anderson                &(t->deltas[deltaIndex]), &((*nh)[deltaIndex]),
1554f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa                buffer, size, fds, numFds);
1555f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        if (status != NO_ERROR) {
1556f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            return status;
1557f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        }
1558f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1559f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    return NO_ERROR;
1560f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa}
1561f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1562f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/**
1563f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \brief Flatten `FrameEventHistoryDelta`.
1564f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
1565f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in] t The source `FrameEventHistoryDelta`.
1566f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] buffer The pointer to the flat non-fd buffer.
1567f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] size The size of the flat non-fd buffer.
1568f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] fds The pointer to the flat fd buffer.
1569f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] numFds The size of the flat fd buffer.
1570f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \return `NO_ERROR` on success; other value on failure.
1571f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
1572f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * This function will duplicate file descriptors contained in \p t.
1573f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
1574f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasainline status_t flatten(
157504563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa        HGraphicBufferProducer::FrameEventHistoryDelta const& t,
1576f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        void*& buffer, size_t& size, int*& fds, size_t& numFds) {
15771f82e093581e6175c0ea0a99f1f9e8ee335502b9Brian Anderson    if (t.deltas.size() > ::android::FrameEventHistory::MAX_FRAME_HISTORY) {
1578f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return BAD_VALUE;
1579f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1580f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (size < getFlattenedSize(t)) {
1581f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return NO_MEMORY;
1582f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1583f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
15841f82e093581e6175c0ea0a99f1f9e8ee335502b9Brian Anderson    FlattenableUtils::write(buffer, size, t.compositorTiming);
15851f82e093581e6175c0ea0a99f1f9e8ee335502b9Brian Anderson
15861f82e093581e6175c0ea0a99f1f9e8ee335502b9Brian Anderson    FlattenableUtils::write(buffer, size, static_cast<uint32_t>(t.deltas.size()));
15871f82e093581e6175c0ea0a99f1f9e8ee335502b9Brian Anderson    for (size_t deltaIndex = 0; deltaIndex < t.deltas.size(); ++deltaIndex) {
15881f82e093581e6175c0ea0a99f1f9e8ee335502b9Brian Anderson        status_t status = flatten(t.deltas[deltaIndex], buffer, size, fds, numFds);
1589f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        if (status != NO_ERROR) {
1590f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            return status;
1591f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        }
1592f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1593f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    return NO_ERROR;
1594f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa}
1595f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1596f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/**
1597f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \brief Wrap `::android::FrameEventHistoryData` in
159804563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * `HGraphicBufferProducer::FrameEventHistoryDelta`.
1599f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
1600f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[out] t The wrapper of type
160104563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * `HGraphicBufferProducer::FrameEventHistoryDelta`.
1602f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[out] nh The array of array of native handles that are referred to by
1603f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * members of \p t.
1604f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in] l The source `::android::FrameEventHistoryDelta`.
1605f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
1606f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * On success, each member of \p nh will be either `nullptr` or a newly created
1607f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * native handle. All the non-`nullptr` elements must be deleted individually
1608f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * with `native_handle_delete()`.
1609f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
161004563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasainline bool wrapAs(HGraphicBufferProducer::FrameEventHistoryDelta* t,
1611f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        std::vector<std::vector<native_handle_t*> >* nh,
1612f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        ::android::FrameEventHistoryDelta const& l) {
1613f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1614f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    size_t const baseSize = l.getFlattenedSize();
1615f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    std::unique_ptr<uint8_t[]> baseBuffer(
1616f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            new (std::nothrow) uint8_t[baseSize]);
1617f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (!baseBuffer) {
1618f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return false;
1619f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1620f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1621f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    size_t const baseNumFds = l.getFdCount();
1622f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    std::unique_ptr<int[]> baseFds(
1623f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            new (std::nothrow) int[baseNumFds]);
1624f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (!baseFds) {
1625f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return false;
1626f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1627f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1628f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    void* buffer = static_cast<void*>(baseBuffer.get());
1629f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    size_t size = baseSize;
1630f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    int* fds = baseFds.get();
1631f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    size_t numFds = baseNumFds;
1632f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (l.flatten(buffer, size, fds, numFds) != NO_ERROR) {
1633f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return false;
1634f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1635f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1636f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
1637f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    size = baseSize;
1638f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    int const* constFds = static_cast<int const*>(baseFds.get());
1639f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    numFds = baseNumFds;
1640f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (unflatten(t, nh, constBuffer, size, constFds, numFds) != NO_ERROR) {
1641f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return false;
1642f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1643f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1644f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    return true;
1645f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa}
1646f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1647f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/**
164804563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * \brief Convert `HGraphicBufferProducer::FrameEventHistoryDelta` to
1649f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * `::android::FrameEventHistoryDelta`.
1650f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
1651f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[out] l The destination `::android::FrameEventHistoryDelta`.
165204563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * \param[in] t The source `HGraphicBufferProducer::FrameEventHistoryDelta`.
1653f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
1654f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * This function will duplicate all file descriptors contained in \p t.
1655f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
1656f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasainline bool convertTo(
1657f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        ::android::FrameEventHistoryDelta* l,
165804563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa        HGraphicBufferProducer::FrameEventHistoryDelta const& t) {
1659f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1660f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    size_t const baseSize = getFlattenedSize(t);
1661f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    std::unique_ptr<uint8_t[]> baseBuffer(
1662f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            new (std::nothrow) uint8_t[baseSize]);
1663f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (!baseBuffer) {
1664f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return false;
1665f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1666f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1667f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    size_t const baseNumFds = getFdCount(t);
1668f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    std::unique_ptr<int[]> baseFds(
1669f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            new (std::nothrow) int[baseNumFds]);
1670f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (!baseFds) {
1671f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return false;
1672f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1673f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1674f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    void* buffer = static_cast<void*>(baseBuffer.get());
1675f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    size_t size = baseSize;
1676f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    int* fds = static_cast<int*>(baseFds.get());
1677f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    size_t numFds = baseNumFds;
1678f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (flatten(t, buffer, size, fds, numFds) != NO_ERROR) {
1679f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return false;
1680f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1681f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1682f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
1683f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    size = baseSize;
1684f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    int const* constFds = static_cast<int const*>(baseFds.get());
1685f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    numFds = baseNumFds;
1686f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (l->unflatten(constBuffer, size, constFds, numFds) != NO_ERROR) {
1687f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return false;
1688f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1689f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1690f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    return true;
1691f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa}
1692f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1693f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa// Ref: frameworks/native/libs/ui/Region.cpp
1694f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1695f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/**
1696f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \brief Return the size of the buffer required to flatten `Region`.
1697f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
1698f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in] t The input `Region`.
1699f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \return The required size of the flat buffer.
1700f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
1701f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasainline size_t getFlattenedSize(Region const& t) {
1702f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    return sizeof(uint32_t) + t.size() * sizeof(::android::Rect);
1703f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa}
1704f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1705f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/**
1706f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \brief Unflatten `Region`.
1707f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
1708f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[out] t The destination `Region`.
1709f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] buffer The pointer to the flat buffer.
1710f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] size The size of the flat buffer.
1711f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \return `NO_ERROR` on success; other value on failure.
1712f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
1713f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasainline status_t unflatten(Region* t, void const*& buffer, size_t& size) {
1714f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (size < sizeof(uint32_t)) {
1715f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return NO_MEMORY;
1716f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1717f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1718f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    uint32_t numRects = 0;
1719f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::read(buffer, size, numRects);
1720f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (size < numRects * sizeof(Rect)) {
1721f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return NO_MEMORY;
1722f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1723f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (numRects > (UINT32_MAX / sizeof(Rect))) {
1724f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return NO_MEMORY;
1725f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1726f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1727f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    t->resize(numRects);
1728f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    for (size_t r = 0; r < numRects; ++r) {
1729f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        ::android::Rect rect(::android::Rect::EMPTY_RECT);
1730f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        status_t status = rect.unflatten(buffer, size);
1731f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        if (status != NO_ERROR) {
1732f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            return status;
1733f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        }
1734f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        FlattenableUtils::advance(buffer, size, sizeof(rect));
1735f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        (*t)[r] = Rect{
1736f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa                static_cast<int32_t>(rect.left),
1737f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa                static_cast<int32_t>(rect.top),
1738f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa                static_cast<int32_t>(rect.right),
1739f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa                static_cast<int32_t>(rect.bottom)};
1740f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1741f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    return NO_ERROR;
1742f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa}
1743f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1744f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/**
1745f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \brief Flatten `Region`.
1746f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
1747f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in] t The source `Region`.
1748f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] buffer The pointer to the flat buffer.
1749f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] size The size of the flat buffer.
1750f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \return `NO_ERROR` on success; other value on failure.
1751f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
1752f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasainline status_t flatten(Region const& t, void*& buffer, size_t& size) {
1753f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (size < getFlattenedSize(t)) {
1754f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return NO_MEMORY;
1755f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1756f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1757f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::write(buffer, size, static_cast<uint32_t>(t.size()));
1758f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    for (size_t r = 0; r < t.size(); ++r) {
1759f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        ::android::Rect rect(
1760f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa                static_cast<int32_t>(t[r].left),
1761f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa                static_cast<int32_t>(t[r].top),
1762f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa                static_cast<int32_t>(t[r].right),
1763f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa                static_cast<int32_t>(t[r].bottom));
1764f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        status_t status = rect.flatten(buffer, size);
1765f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        if (status != NO_ERROR) {
1766f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            return status;
1767f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        }
1768f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        FlattenableUtils::advance(buffer, size, sizeof(rect));
1769f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1770f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    return NO_ERROR;
1771f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa}
1772f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1773f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/**
1774f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \brief Convert `::android::Region` to `Region`.
1775f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
1776f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[out] t The destination `Region`.
1777f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in] l The source `::android::Region`.
1778f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
1779f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa// convert: ::android::Region -> Region
1780f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasainline bool convertTo(Region* t, ::android::Region const& l) {
1781f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    size_t const baseSize = l.getFlattenedSize();
1782f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    std::unique_ptr<uint8_t[]> baseBuffer(
1783f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            new (std::nothrow) uint8_t[baseSize]);
1784f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (!baseBuffer) {
1785f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return false;
1786f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1787f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1788f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    void* buffer = static_cast<void*>(baseBuffer.get());
1789f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    size_t size = baseSize;
1790f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (l.flatten(buffer, size) != NO_ERROR) {
1791f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return false;
1792f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1793f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1794f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
1795f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    size = baseSize;
1796f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (unflatten(t, constBuffer, size) != NO_ERROR) {
1797f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return false;
1798f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1799f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1800f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    return true;
1801f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa}
1802f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1803f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/**
1804f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \brief Convert `Region` to `::android::Region`.
1805f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
1806f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[out] l The destination `::android::Region`.
1807f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in] t The source `Region`.
1808f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
1809f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa// convert: Region -> ::android::Region
1810f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasainline bool convertTo(::android::Region* l, Region const& t) {
1811f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    size_t const baseSize = getFlattenedSize(t);
1812f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    std::unique_ptr<uint8_t[]> baseBuffer(
1813f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            new (std::nothrow) uint8_t[baseSize]);
1814f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (!baseBuffer) {
1815f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return false;
1816f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1817f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1818f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    void* buffer = static_cast<void*>(baseBuffer.get());
1819f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    size_t size = baseSize;
1820f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (flatten(t, buffer, size) != NO_ERROR) {
1821f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return false;
1822f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1823f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1824f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
1825f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    size = baseSize;
1826f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (l->unflatten(constBuffer, size) != NO_ERROR) {
1827f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return false;
1828f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1829f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1830f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    return true;
1831f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa}
1832f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
183304563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa// Ref: frameworks/native/libs/gui/BGraphicBufferProducer.cpp:
183404563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa//      BGraphicBufferProducer::QueueBufferInput
1835f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1836f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/**
1837f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \brief Return a lower bound on the size of the buffer required to flatten
183804563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * `HGraphicBufferProducer::QueueBufferInput`.
1839f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
184004563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * \param[in] t The input `HGraphicBufferProducer::QueueBufferInput`.
1841f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \return A lower bound on the size of the flat buffer.
1842f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
1843f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasaconstexpr size_t minFlattenedSize(
184404563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa        HGraphicBufferProducer::QueueBufferInput const& /* t */) {
1845f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    return sizeof(int64_t) + // timestamp
1846f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            sizeof(int) + // isAutoTimestamp
1847f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            sizeof(android_dataspace) + // dataSpace
1848f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            sizeof(::android::Rect) + // crop
1849f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            sizeof(int) + // scalingMode
1850f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            sizeof(uint32_t) + // transform
1851f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            sizeof(uint32_t) + // stickyTransform
1852f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            sizeof(bool); // getFrameTimestamps
1853f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa}
1854f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1855f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/**
1856f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \brief Return the size of the buffer required to flatten
185704563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * `HGraphicBufferProducer::QueueBufferInput`.
1858f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
185904563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * \param[in] t The input `HGraphicBufferProducer::QueueBufferInput`.
1860f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \return The required size of the flat buffer.
1861f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
186204563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasainline size_t getFlattenedSize(HGraphicBufferProducer::QueueBufferInput const& t) {
1863f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    return minFlattenedSize(t) +
1864f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            getFenceFlattenedSize(t.fence) +
1865f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            getFlattenedSize(t.surfaceDamage);
1866f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa}
1867f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1868f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/**
1869f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \brief Return the number of file descriptors contained in
187004563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * `HGraphicBufferProducer::QueueBufferInput`.
1871f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
187204563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * \param[in] t The input `HGraphicBufferProducer::QueueBufferInput`.
1873f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \return The number of file descriptors contained in \p t.
1874f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
1875f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasainline size_t getFdCount(
187604563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa        HGraphicBufferProducer::QueueBufferInput const& t) {
1877f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    return getFenceFdCount(t.fence);
1878f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa}
1879f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1880f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/**
188104563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * \brief Flatten `HGraphicBufferProducer::QueueBufferInput`.
1882f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
188304563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * \param[in] t The source `HGraphicBufferProducer::QueueBufferInput`.
18848b13a00825f1ea44f5822087851fd4971d09ccacPawin Vongmasa * \param[out] nh The native handle cloned from `t.fence`.
1885f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] buffer The pointer to the flat non-fd buffer.
1886f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] size The size of the flat non-fd buffer.
1887f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] fds The pointer to the flat fd buffer.
1888f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] numFds The size of the flat fd buffer.
1889f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \return `NO_ERROR` on success; other value on failure.
1890f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
1891f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * This function will duplicate the file descriptor in `t.fence`. */
189204563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasainline status_t flatten(HGraphicBufferProducer::QueueBufferInput const& t,
18938b13a00825f1ea44f5822087851fd4971d09ccacPawin Vongmasa        native_handle_t** nh,
1894f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        void*& buffer, size_t& size, int*& fds, size_t& numFds) {
1895f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (size < getFlattenedSize(t)) {
1896f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return NO_MEMORY;
1897f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1898f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1899f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::write(buffer, size, t.timestamp);
1900f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::write(buffer, size, static_cast<int>(t.isAutoTimestamp));
1901f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::write(buffer, size,
1902f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            static_cast<android_dataspace_t>(t.dataSpace));
1903f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::write(buffer, size, ::android::Rect(
1904f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            static_cast<int32_t>(t.crop.left),
1905f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            static_cast<int32_t>(t.crop.top),
1906f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            static_cast<int32_t>(t.crop.right),
1907f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            static_cast<int32_t>(t.crop.bottom)));
1908f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::write(buffer, size, static_cast<int>(t.scalingMode));
1909f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::write(buffer, size, t.transform);
1910f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::write(buffer, size, t.stickyTransform);
1911f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::write(buffer, size, t.getFrameTimestamps);
1912f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
19138b13a00825f1ea44f5822087851fd4971d09ccacPawin Vongmasa    *nh = t.fence.getNativeHandle() == nullptr ?
19148b13a00825f1ea44f5822087851fd4971d09ccacPawin Vongmasa            nullptr : native_handle_clone(t.fence);
19158b13a00825f1ea44f5822087851fd4971d09ccacPawin Vongmasa    status_t status = flattenFence(hidl_handle(*nh), buffer, size, fds, numFds);
1916f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (status != NO_ERROR) {
1917f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return status;
1918f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1919f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    return flatten(t.surfaceDamage, buffer, size);
1920f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa}
1921f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1922f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/**
192304563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * \brief Unflatten `HGraphicBufferProducer::QueueBufferInput`.
1924f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
192504563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * \param[out] t The destination `HGraphicBufferProducer::QueueBufferInput`.
1926f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[out] nh The underlying native handle for `t->fence`.
1927f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] buffer The pointer to the flat non-fd buffer.
1928f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] size The size of the flat non-fd buffer.
1929f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] fds The pointer to the flat fd buffer.
1930f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[in,out] numFds The size of the flat fd buffer.
1931f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \return `NO_ERROR` on success; other value on failure.
1932f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
1933f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * If the return value is `NO_ERROR` and `t->fence` contains a valid file
1934f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * descriptor, \p nh will be a newly created native handle holding that file
1935f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * descriptor. \p nh needs to be deleted with `native_handle_delete()`
1936f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * afterwards.
1937f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
1938f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasainline status_t unflatten(
193904563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa        HGraphicBufferProducer::QueueBufferInput* t, native_handle_t** nh,
1940f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
1941f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (size < minFlattenedSize(*t)) {
1942f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return NO_MEMORY;
1943f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1944f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1945f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::read(buffer, size, t->timestamp);
1946f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    int lIsAutoTimestamp;
1947f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::read(buffer, size, lIsAutoTimestamp);
1948f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    t->isAutoTimestamp = static_cast<int32_t>(lIsAutoTimestamp);
1949f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    android_dataspace_t lDataSpace;
1950f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::read(buffer, size, lDataSpace);
1951f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    t->dataSpace = static_cast<Dataspace>(lDataSpace);
1952f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    Rect lCrop;
1953f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::read(buffer, size, lCrop);
1954f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    t->crop = Rect{
1955f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            static_cast<int32_t>(lCrop.left),
1956f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            static_cast<int32_t>(lCrop.top),
1957f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            static_cast<int32_t>(lCrop.right),
1958f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            static_cast<int32_t>(lCrop.bottom)};
1959f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    int lScalingMode;
1960f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::read(buffer, size, lScalingMode);
1961f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    t->scalingMode = static_cast<int32_t>(lScalingMode);
1962f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::read(buffer, size, t->transform);
1963f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::read(buffer, size, t->stickyTransform);
1964f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    FlattenableUtils::read(buffer, size, t->getFrameTimestamps);
1965f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1966f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    status_t status = unflattenFence(&(t->fence), nh,
1967f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            buffer, size, fds, numFds);
1968f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (status != NO_ERROR) {
1969f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return status;
1970f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1971f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    return unflatten(&(t->surfaceDamage), buffer, size);
1972f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa}
1973f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1974f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/**
197504563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * \brief Wrap `BGraphicBufferProducer::QueueBufferInput` in
197604563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * `HGraphicBufferProducer::QueueBufferInput`.
1977f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
1978f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[out] t The wrapper of type
197904563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * `HGraphicBufferProducer::QueueBufferInput`.
1980f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[out] nh The underlying native handle for `t->fence`.
198104563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * \param[in] l The source `BGraphicBufferProducer::QueueBufferInput`.
1982f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
1983f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * If the return value is `true` and `t->fence` contains a valid file
1984f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * descriptor, \p nh will be a newly created native handle holding that file
1985f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * descriptor. \p nh needs to be deleted with `native_handle_delete()`
1986f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * afterwards.
1987f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
1988f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasainline bool wrapAs(
198904563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa        HGraphicBufferProducer::QueueBufferInput* t,
1990f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        native_handle_t** nh,
199104563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa        BGraphicBufferProducer::QueueBufferInput const& l) {
1992f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
1993f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    size_t const baseSize = l.getFlattenedSize();
1994f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    std::unique_ptr<uint8_t[]> baseBuffer(
1995f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            new (std::nothrow) uint8_t[baseSize]);
1996f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (!baseBuffer) {
1997f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return false;
1998f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
1999f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
2000f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    size_t const baseNumFds = l.getFdCount();
2001f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    std::unique_ptr<int[]> baseFds(
2002f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            new (std::nothrow) int[baseNumFds]);
2003f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (!baseFds) {
2004f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return false;
2005f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
2006f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
2007f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    void* buffer = static_cast<void*>(baseBuffer.get());
2008f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    size_t size = baseSize;
2009f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    int* fds = baseFds.get();
2010f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    size_t numFds = baseNumFds;
2011f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (l.flatten(buffer, size, fds, numFds) != NO_ERROR) {
2012f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return false;
2013f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
2014f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
2015f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
2016f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    size = baseSize;
2017f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    int const* constFds = static_cast<int const*>(baseFds.get());
2018f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    numFds = baseNumFds;
2019f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (unflatten(t, nh, constBuffer, size, constFds, numFds) != NO_ERROR) {
2020f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return false;
2021f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
2022f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
2023f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    return true;
2024f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa}
2025f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
2026f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/**
202704563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * \brief Convert `HGraphicBufferProducer::QueueBufferInput` to
202804563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * `BGraphicBufferProducer::QueueBufferInput`.
2029f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
203004563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * \param[out] l The destination `BGraphicBufferProducer::QueueBufferInput`.
203104563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * \param[in] t The source `HGraphicBufferProducer::QueueBufferInput`.
2032f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
2033f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * If `t.fence` has a valid file descriptor, it will be duplicated.
2034f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
2035f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasainline bool convertTo(
203604563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa        BGraphicBufferProducer::QueueBufferInput* l,
203704563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa        HGraphicBufferProducer::QueueBufferInput const& t) {
2038f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
2039f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    size_t const baseSize = getFlattenedSize(t);
2040f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    std::unique_ptr<uint8_t[]> baseBuffer(
2041f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            new (std::nothrow) uint8_t[baseSize]);
2042f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (!baseBuffer) {
2043f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return false;
2044f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
2045f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
2046f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    size_t const baseNumFds = getFdCount(t);
2047f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    std::unique_ptr<int[]> baseFds(
2048f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa            new (std::nothrow) int[baseNumFds]);
2049f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (!baseFds) {
2050f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return false;
2051f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
2052f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
2053f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    void* buffer = static_cast<void*>(baseBuffer.get());
2054f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    size_t size = baseSize;
2055f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    int* fds = baseFds.get();
2056f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    size_t numFds = baseNumFds;
20578b13a00825f1ea44f5822087851fd4971d09ccacPawin Vongmasa    native_handle_t* nh;
20588b13a00825f1ea44f5822087851fd4971d09ccacPawin Vongmasa    if (flatten(t, &nh, buffer, size, fds, numFds) != NO_ERROR) {
2059f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return false;
2060f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
2061f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
2062f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
2063f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    size = baseSize;
2064f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    int const* constFds = static_cast<int const*>(baseFds.get());
2065f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    numFds = baseNumFds;
2066f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (l->unflatten(constBuffer, size, constFds, numFds) != NO_ERROR) {
20678b13a00825f1ea44f5822087851fd4971d09ccacPawin Vongmasa        native_handle_close(nh);
20688b13a00825f1ea44f5822087851fd4971d09ccacPawin Vongmasa        native_handle_delete(nh);
2069f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return false;
2070f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
2071f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
20728b13a00825f1ea44f5822087851fd4971d09ccacPawin Vongmasa    native_handle_delete(nh);
2073f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    return true;
2074f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa}
2075f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
207604563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa// Ref: frameworks/native/libs/gui/BGraphicBufferProducer.cpp:
207704563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa//      BGraphicBufferProducer::QueueBufferOutput
2078f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
2079f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/**
208004563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * \brief Wrap `BGraphicBufferProducer::QueueBufferOutput` in
208104563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * `HGraphicBufferProducer::QueueBufferOutput`.
2082f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
2083f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[out] t The wrapper of type
208404563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * `HGraphicBufferProducer::QueueBufferOutput`.
2085f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * \param[out] nh The array of array of native handles that are referred to by
2086f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * members of \p t.
208704563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * \param[in] l The source `BGraphicBufferProducer::QueueBufferOutput`.
2088f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
2089f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * On success, each member of \p nh will be either `nullptr` or a newly created
2090f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * native handle. All the non-`nullptr` elements must be deleted individually
2091f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * with `native_handle_delete()`.
2092f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
209304563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa// wrap: BGraphicBufferProducer::QueueBufferOutput ->
209404563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa// HGraphicBufferProducer::QueueBufferOutput
209504563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasainline bool wrapAs(HGraphicBufferProducer::QueueBufferOutput* t,
2096f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        std::vector<std::vector<native_handle_t*> >* nh,
209704563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa        BGraphicBufferProducer::QueueBufferOutput const& l) {
2098f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (!wrapAs(&(t->frameTimestamps), nh, l.frameTimestamps)) {
2099f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return false;
2100f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
2101f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    t->width = l.width;
2102f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    t->height = l.height;
2103f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    t->transformHint = l.transformHint;
2104f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    t->numPendingBuffers = l.numPendingBuffers;
2105f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    t->nextFrameNumber = l.nextFrameNumber;
210692b6b72deb1e4225620806446c782d6cffb4cf17Pawin Vongmasa    t->bufferReplaced = l.bufferReplaced;
2107f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    return true;
2108f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa}
2109f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
2110f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/**
211104563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * \brief Convert `HGraphicBufferProducer::QueueBufferOutput` to
211204563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * `BGraphicBufferProducer::QueueBufferOutput`.
2113f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
211404563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * \param[out] l The destination `BGraphicBufferProducer::QueueBufferOutput`.
211504563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * \param[in] t The source `HGraphicBufferProducer::QueueBufferOutput`.
2116f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
2117f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * This function will duplicate all file descriptors contained in \p t.
2118f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
211904563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa// convert: HGraphicBufferProducer::QueueBufferOutput ->
212004563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa// BGraphicBufferProducer::QueueBufferOutput
2121f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasainline bool convertTo(
212204563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa        BGraphicBufferProducer::QueueBufferOutput* l,
212304563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa        HGraphicBufferProducer::QueueBufferOutput const& t) {
2124f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    if (!convertTo(&(l->frameTimestamps), t.frameTimestamps)) {
2125f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa        return false;
2126f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
2127f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    l->width = t.width;
2128f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    l->height = t.height;
2129f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    l->transformHint = t.transformHint;
2130f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    l->numPendingBuffers = t.numPendingBuffers;
2131f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    l->nextFrameNumber = t.nextFrameNumber;
213292b6b72deb1e4225620806446c782d6cffb4cf17Pawin Vongmasa    l->bufferReplaced = t.bufferReplaced;
2133f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    return true;
2134f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa}
2135f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
2136f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/**
213704563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * \brief Convert `BGraphicBufferProducer::DisconnectMode` to
213804563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * `HGraphicBufferProducer::DisconnectMode`.
2139f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
214004563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * \param[in] l The source `BGraphicBufferProducer::DisconnectMode`.
214104563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * \return The corresponding `HGraphicBufferProducer::DisconnectMode`.
2142f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
214304563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasainline HGraphicBufferProducer::DisconnectMode toOmxDisconnectMode(
214404563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa        BGraphicBufferProducer::DisconnectMode l) {
2145f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    switch (l) {
214604563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa        case BGraphicBufferProducer::DisconnectMode::Api:
214704563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa            return HGraphicBufferProducer::DisconnectMode::API;
214804563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa        case BGraphicBufferProducer::DisconnectMode::AllLocal:
214904563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa            return HGraphicBufferProducer::DisconnectMode::ALL_LOCAL;
2150f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
215104563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa    return HGraphicBufferProducer::DisconnectMode::API;
2152f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa}
2153f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
2154f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/**
215504563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * \brief Convert `HGraphicBufferProducer::DisconnectMode` to
215604563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * `BGraphicBufferProducer::DisconnectMode`.
2157f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
215804563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * \param[in] l The source `HGraphicBufferProducer::DisconnectMode`.
215904563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa * \return The corresponding `BGraphicBufferProducer::DisconnectMode`.
2160f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
216104563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasainline BGraphicBufferProducer::DisconnectMode toGuiDisconnectMode(
216204563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa        HGraphicBufferProducer::DisconnectMode t) {
2163f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    switch (t) {
216404563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa        case HGraphicBufferProducer::DisconnectMode::API:
216504563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa            return BGraphicBufferProducer::DisconnectMode::Api;
216604563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa        case HGraphicBufferProducer::DisconnectMode::ALL_LOCAL:
216704563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa            return BGraphicBufferProducer::DisconnectMode::AllLocal;
2168f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa    }
216904563aafa0debc95d50951ca944abf37ef2777cePawin Vongmasa    return BGraphicBufferProducer::DisconnectMode::Api;
2170f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa}
2171517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
2172517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}  // namespace implementation
2173517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}  // namespace V1_0
2174517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}  // namespace omx
2175517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}  // namespace media
2176517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}  // namespace hardware
2177517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}  // namespace android
2178517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
2179517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa#endif  // ANDROID_HARDWARE_MEDIA_OMX_V1_0__CONVERSION_H
2180