1 /*
2 * Copyright (C) 2023 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <dlfcn.h>
18
19 #include "OMXAL/OpenMAXAL.h"
20 #include "OMXAL/OpenMAXAL_Android.h"
21
22 #include "berberis/base/struct_check.h"
23 #include "berberis/guest_abi/function_wrappers.h"
24 #include "berberis/guest_abi/guest_params.h"
25 #include "berberis/guest_state/guest_addr.h"
26 #include "berberis/proxy_loader/proxy_library_builder.h"
27
28 namespace berberis {
29
30 namespace {
31
32 // TODO(b/312279687): Maybe share this with SLES translation.
33 #define REGISTER_TRAMPOLINE(itf_name, func_name) \
34 WrapHostFunction((*itf)->func_name, #itf_name "::" #func_name)
35
36 #define REGISTER_CUSTOM_TRAMPOLINE(itf_name, func_name) \
37 WrapHostFunctionImpl(reinterpret_cast<void*>((*itf)->func_name), \
38 DoCustomTrampoline_##itf_name##_##func_name, \
39 #itf_name "::" #func_name)
40
41 // Interfaces are just structures listing function pointers, thus are layout-compatible.
42 typedef XAObjectItf Guest_XAObjectItf;
43 typedef XAEngineItf Guest_XAEngineItf;
44 typedef XAPlayItf Guest_XAPlayItf;
45 typedef XAAndroidBufferQueueItf Guest_XAAndroidBufferQueueItf;
46 typedef XAStreamInformationItf Guest_XAStreamInformationItf;
47 typedef XAVolumeItf Guest_XAVolumeItf;
48
49 CHECK_STRUCT_LAYOUT(XAEngineOption, 64, 32);
50 CHECK_FIELD_LAYOUT(XAEngineOption, feature, 0, 32);
51 CHECK_FIELD_LAYOUT(XAEngineOption, data, 32, 32);
52 typedef XAEngineOption Guest_XAEngineOption;
53
54 // Note, that this is not an integer, but is a pointer to structure!
55 typedef std::remove_reference_t<decltype(*std::declval<XAInterfaceID>())> XAInterfaceID_deref;
56 CHECK_STRUCT_LAYOUT(XAInterfaceID_deref, 128, 32);
57 CHECK_FIELD_LAYOUT(XAInterfaceID_deref, time_low, 0, 32);
58 CHECK_FIELD_LAYOUT(XAInterfaceID_deref, time_mid, 32, 16);
59 CHECK_FIELD_LAYOUT(XAInterfaceID_deref, time_hi_and_version, 48, 16);
60 CHECK_FIELD_LAYOUT(XAInterfaceID_deref, clock_seq, 64, 16);
61 CHECK_FIELD_LAYOUT(XAInterfaceID_deref, node, 80, 48);
62 typedef XAInterfaceID Guest_XAInterfaceID;
63
64 #if defined(NATIVE_BRIDGE_GUEST_ARCH_ARM)
65
66 CHECK_STRUCT_LAYOUT(XADataSource, 64, 32);
67 CHECK_FIELD_LAYOUT(XADataSource, pLocator, 0, 32);
68 CHECK_FIELD_LAYOUT(XADataSource, pFormat, 32, 32);
69
70 CHECK_STRUCT_LAYOUT(XADataSink, 64, 32);
71 CHECK_FIELD_LAYOUT(XADataSink, pLocator, 0, 32);
72 CHECK_FIELD_LAYOUT(XADataSink, pFormat, 32, 32);
73
74 #elif defined(NATIVE_BRIDGE_GUEST_ARCH_ARM64)
75
76 CHECK_STRUCT_LAYOUT(XADataSource, 128, 64);
77 CHECK_FIELD_LAYOUT(XADataSource, pLocator, 0, 64);
78 CHECK_FIELD_LAYOUT(XADataSource, pFormat, 64, 64);
79
80 CHECK_STRUCT_LAYOUT(XADataSink, 128, 64);
81 CHECK_FIELD_LAYOUT(XADataSink, pLocator, 0, 64);
82 CHECK_FIELD_LAYOUT(XADataSink, pFormat, 64, 64);
83
84 #elif defined(NATIVE_BRIDGE_GUEST_ARCH_RISCV64)
85
86 CHECK_STRUCT_LAYOUT(XADataSource, 128, 64);
87 CHECK_FIELD_LAYOUT(XADataSource, pLocator, 0, 64);
88 CHECK_FIELD_LAYOUT(XADataSource, pFormat, 64, 64);
89
90 CHECK_STRUCT_LAYOUT(XADataSink, 128, 64);
91 CHECK_FIELD_LAYOUT(XADataSink, pLocator, 0, 64);
92 CHECK_FIELD_LAYOUT(XADataSink, pFormat, 64, 64);
93
94 #else
95
96 #error "Unknown guest arch"
97
98 #endif
99
100 CHECK_STRUCT_LAYOUT(XALEDDescriptor, 64, 32);
101 CHECK_FIELD_LAYOUT(XALEDDescriptor, ledCount, 0, 8);
102 CHECK_FIELD_LAYOUT(XALEDDescriptor, primaryLED, 8, 8);
103 CHECK_FIELD_LAYOUT(XALEDDescriptor, colorMask, 32, 32);
104
105 CHECK_STRUCT_LAYOUT(XAVibraDescriptor, 128, 32);
106 CHECK_FIELD_LAYOUT(XAVibraDescriptor, supportsFrequency, 0, 32);
107 CHECK_FIELD_LAYOUT(XAVibraDescriptor, supportsIntensity, 32, 32);
108 CHECK_FIELD_LAYOUT(XAVibraDescriptor, minFrequency, 64, 32);
109 CHECK_FIELD_LAYOUT(XAVibraDescriptor, maxFrequency, 96, 32);
110
RegisterXAEngineItfMethods(Guest_XAEngineItf itf)111 void RegisterXAEngineItfMethods(Guest_XAEngineItf itf) {
112 REGISTER_TRAMPOLINE(XAEngine, CreateOutputMix);
113 REGISTER_TRAMPOLINE(XAEngine, CreateMediaPlayer);
114 REGISTER_TRAMPOLINE(XAEngine, CreateMediaRecorder);
115 REGISTER_TRAMPOLINE(XAEngine, CreateCameraDevice);
116 REGISTER_TRAMPOLINE(XAEngine, CreateRadioDevice);
117 REGISTER_TRAMPOLINE(XAEngine, CreateLEDDevice);
118 REGISTER_TRAMPOLINE(XAEngine, CreateVibraDevice);
119 REGISTER_TRAMPOLINE(XAEngine, CreateMetadataExtractor);
120 REGISTER_TRAMPOLINE(XAEngine, CreateExtensionObject);
121 REGISTER_TRAMPOLINE(XAEngine, GetImplementationInfo);
122 REGISTER_TRAMPOLINE(XAEngine, QuerySupportedProfiles);
123 REGISTER_TRAMPOLINE(XAEngine, QueryNumSupportedInterfaces);
124 REGISTER_TRAMPOLINE(XAEngine, QuerySupportedInterfaces);
125 REGISTER_TRAMPOLINE(XAEngine, QueryNumSupportedExtensions);
126 REGISTER_TRAMPOLINE(XAEngine, QuerySupportedExtension);
127 REGISTER_TRAMPOLINE(XAEngine, IsExtensionSupported);
128 REGISTER_TRAMPOLINE(XAEngine, QueryLEDCapabilities);
129 REGISTER_TRAMPOLINE(XAEngine, QueryVibraCapabilities);
130 }
131
132 // XAresult (*RegisterCallback) (XAPlayItf self, xaPlayCallback callback, void * pContext);
DoCustomTrampoline_XAPlay_RegisterCallback(HostCode,ProcessState * state)133 void DoCustomTrampoline_XAPlay_RegisterCallback(HostCode /*callee*/, ProcessState* state) {
134 using PFN_callee = decltype(std::declval<XAPlayItf_>().RegisterCallback);
135 auto [self, guest_callback, callback_context] = GuestParamsValues<PFN_callee>(state);
136
137 // typedef void (XAAPIENTRY * xaPlayCallback) (XAPlayItf caller, void * pContext, XAuint32 event);
138 auto host_callback = WrapGuestFunction(guest_callback, "XAPlay_RegisterCallback-callback");
139
140 auto&& [ret] = GuestReturnReference<PFN_callee>(state);
141 ret = (*self)->RegisterCallback(self, host_callback, callback_context);
142 }
143
RegisterXAPlayItfMethods(Guest_XAPlayItf itf)144 void RegisterXAPlayItfMethods(Guest_XAPlayItf itf) {
145 REGISTER_TRAMPOLINE(XAPlay, SetPlayState);
146 REGISTER_TRAMPOLINE(XAPlay, GetPlayState);
147 REGISTER_TRAMPOLINE(XAPlay, GetDuration);
148 REGISTER_TRAMPOLINE(XAPlay, GetPosition);
149 REGISTER_TRAMPOLINE(XAPlay, SetMarkerPosition);
150 REGISTER_TRAMPOLINE(XAPlay, ClearMarkerPosition);
151 REGISTER_TRAMPOLINE(XAPlay, GetMarkerPosition);
152 REGISTER_TRAMPOLINE(XAPlay, SetPositionUpdatePeriod);
153 REGISTER_TRAMPOLINE(XAPlay, GetPositionUpdatePeriod);
154 REGISTER_TRAMPOLINE(XAPlay, SetCallbackEventsMask);
155 REGISTER_TRAMPOLINE(XAPlay, GetCallbackEventsMask);
156 REGISTER_CUSTOM_TRAMPOLINE(XAPlay, RegisterCallback);
157 }
158
159 // XAresult (*RegisterCallback) (XAAndroidBufferQueueItf self);
160 // xaAndroidBufferQueueCallback callback,
161 // void* pCallbackContext);
DoCustomTrampoline_XABufferQueue_RegisterCallback(HostCode,ProcessState * state)162 void DoCustomTrampoline_XABufferQueue_RegisterCallback(HostCode /*callee*/, ProcessState* state) {
163 using PFN_callee = decltype(std::declval<XAAndroidBufferQueueItf_>().RegisterCallback);
164 auto [self, guest_callback, callback_context] = GuestParamsValues<PFN_callee>(state);
165
166 // typedef XAresult (XAAPIENTRY *xaAndroidBufferQueueCallback)(
167 // XAAndroidBufferQueueItf caller,/* input */
168 // void *pCallbackContext, /* input */
169 // void *pBufferContext, /* input */
170 // void *pBufferData, /* input */
171 // XAuint32 dataSize, /* input */
172 // XAuint32 dataUsed, /* input */
173 // const XAAndroidBufferItem *pItems,/* input */
174 // XAuint32 itemsLength /* input */
175 // );
176 auto host_callback = WrapGuestFunction(guest_callback, "XABufferQueue_RegisterCallback-callback");
177
178 auto&& [ret] = GuestReturnReference<PFN_callee>(state);
179 ret = (*self)->RegisterCallback(self, host_callback, callback_context);
180 }
181
182 CHECK_STRUCT_LAYOUT(XAAndroidBufferQueueState, 64, 32);
183 CHECK_FIELD_LAYOUT(XAAndroidBufferQueueState, count, 0, 32);
184 CHECK_FIELD_LAYOUT(XAAndroidBufferQueueState, index, 32, 32);
185
RegisterXAAndroidBufferQueueItfMethods(Guest_XAAndroidBufferQueueItf itf)186 void RegisterXAAndroidBufferQueueItfMethods(Guest_XAAndroidBufferQueueItf itf) {
187 REGISTER_CUSTOM_TRAMPOLINE(XABufferQueue, RegisterCallback);
188 REGISTER_TRAMPOLINE(XABufferQueue, SetCallbackEventsMask);
189 REGISTER_TRAMPOLINE(XABufferQueue, Enqueue);
190 REGISTER_TRAMPOLINE(XABufferQueue, Clear);
191 REGISTER_TRAMPOLINE(XABufferQueue, GetState);
192 REGISTER_TRAMPOLINE(XABufferQueue, GetCallbackEventsMask);
193 }
194
195 // XAresult (*RegisterStreamChangeCallback) (XAStreamInformationItf self,
196 // xaStreamEventChangeCallback callback,
197 // void * pContext);
DoCustomTrampoline_XAStreamInformation_RegisterStreamChangeCallback(HostCode,ProcessState * state)198 void DoCustomTrampoline_XAStreamInformation_RegisterStreamChangeCallback(HostCode /*callee*/,
199 ProcessState* state) {
200 using PFN_callee = decltype(std::declval<XAStreamInformationItf_>().RegisterStreamChangeCallback);
201 auto [self, guest_callback, callback_context] = GuestParamsValues<PFN_callee>(state);
202
203 // typedef void (XAAPIENTRY * xaStreamEventChangeCallback) (
204 // XAStreamInformationItf caller, XAuint32 eventId,
205 // XAuint32 streamIndex, void * pEventData, void * pContext);
206 auto host_callback = WrapGuestFunction(
207 guest_callback, "XAStreamInformation_RegisterStreamChangeCallback-callback");
208
209 auto&& [ret] = GuestReturnReference<PFN_callee>(state);
210 ret = (*self)->RegisterStreamChangeCallback(self, host_callback, callback_context);
211 }
212
213 CHECK_STRUCT_LAYOUT(XAMediaContainerInformation, 96, 32);
214 CHECK_FIELD_LAYOUT(XAMediaContainerInformation, containerType, 0, 32);
215 CHECK_FIELD_LAYOUT(XAMediaContainerInformation, mediaDuration, 32, 32);
216 CHECK_FIELD_LAYOUT(XAMediaContainerInformation, numStreams, 64, 32);
217
RegisterXAStreamInformationItfMethods(Guest_XAStreamInformationItf itf)218 void RegisterXAStreamInformationItfMethods(Guest_XAStreamInformationItf itf) {
219 REGISTER_CUSTOM_TRAMPOLINE(XAStreamInformation, RegisterStreamChangeCallback);
220 REGISTER_TRAMPOLINE(XAStreamInformation, QueryMediaContainerInformation);
221 REGISTER_TRAMPOLINE(XAStreamInformation, QueryStreamType);
222 REGISTER_TRAMPOLINE(XAStreamInformation, QueryStreamInformation);
223 REGISTER_TRAMPOLINE(XAStreamInformation, QueryStreamName);
224 REGISTER_TRAMPOLINE(XAStreamInformation, QueryActiveStreams);
225 REGISTER_TRAMPOLINE(XAStreamInformation, SetActiveStream);
226 }
227
RegisterXAVideoDecoderCapabilitiesItfMethods(XAVideoDecoderCapabilitiesItf itf)228 void RegisterXAVideoDecoderCapabilitiesItfMethods(XAVideoDecoderCapabilitiesItf itf) {
229 REGISTER_TRAMPOLINE(XAVideoDecoderCapabilities, GetVideoDecoders);
230 REGISTER_TRAMPOLINE(XAVideoDecoderCapabilities, GetVideoDecoderCapabilities);
231 }
232
RegisterXAVolumeItfMethods(Guest_XAVolumeItf itf)233 void RegisterXAVolumeItfMethods(Guest_XAVolumeItf itf) {
234 REGISTER_TRAMPOLINE(XAVolume, SetVolumeLevel);
235 REGISTER_TRAMPOLINE(XAVolume, GetVolumeLevel);
236 REGISTER_TRAMPOLINE(XAVolume, GetMaxVolumeLevel);
237 REGISTER_TRAMPOLINE(XAVolume, SetMute);
238 REGISTER_TRAMPOLINE(XAVolume, GetMute);
239 REGISTER_TRAMPOLINE(XAVolume, EnableStereoPosition);
240 REGISTER_TRAMPOLINE(XAVolume, IsEnabledStereoPosition);
241 REGISTER_TRAMPOLINE(XAVolume, SetStereoPosition);
242 REGISTER_TRAMPOLINE(XAVolume, GetStereoPosition);
243 }
244
245 // XAresult (*GetInterface) (XAObjectItf self, const XAInterfaceID iid, void * pInterface);
DoCustomTrampoline_XAObject_GetInterface(HostCode,ProcessState * state)246 void DoCustomTrampoline_XAObject_GetInterface(HostCode /*callee*/, ProcessState* state) {
247 using PFN_callee = decltype(std::declval<XAObjectItf_>().GetInterface);
248 auto [self, iid, interface] = GuestParamsValues<PFN_callee>(state);
249
250 auto&& [ret] = GuestReturnReference<PFN_callee>(state);
251 ret = (*self)->GetInterface(self, iid, interface);
252
253 if (ret != XA_RESULT_SUCCESS) {
254 return;
255 }
256
257 // Note, that iid is not an integer (see comment to Guest_XAInterfaceID).
258 if (iid == XA_IID_ANDROIDBUFFERQUEUESOURCE) {
259 RegisterXAAndroidBufferQueueItfMethods(*static_cast<Guest_XAAndroidBufferQueueItf*>(interface));
260 } else if (iid == XA_IID_AUDIODECODERCAPABILITIES) {
261 LOG_ALWAYS_FATAL("Unknown XA_IID_AUDIODECODERCAPABILITIES");
262 } else if (iid == XA_IID_AUDIOENCODER) {
263 LOG_ALWAYS_FATAL("Unknown XA_IID_AUDIOENCODER");
264 } else if (iid == XA_IID_AUDIOENCODERCAPABILITIES) {
265 LOG_ALWAYS_FATAL("Unknown XA_IID_AUDIOENCODERCAPABILITIES");
266 } else if (iid == XA_IID_AUDIOIODEVICECAPABILITIES) {
267 LOG_ALWAYS_FATAL("Unknown XA_IID_AUDIOIODEVICECAPABILITIES");
268 } else if (iid == XA_IID_CAMERA) {
269 LOG_ALWAYS_FATAL("Unknown XA_IID_CAMERA");
270 } else if (iid == XA_IID_CAMERACAPABILITIES) {
271 LOG_ALWAYS_FATAL("Unknown XA_IID_CAMERACAPABILITIES");
272 } else if (iid == XA_IID_CONFIGEXTENSION) {
273 LOG_ALWAYS_FATAL("Unknown XA_IID_CONFIGEXTENSION");
274 } else if (iid == XA_IID_DEVICEVOLUME) {
275 LOG_ALWAYS_FATAL("Unknown XA_IID_DEVICEVOLUME");
276 } else if (iid == XA_IID_DYNAMICINTERFACEMANAGEMENT) {
277 LOG_ALWAYS_FATAL("Unknown XA_IID_DYNAMICINTERFACEMANAGEMENT");
278 } else if (iid == XA_IID_DYNAMICSOURCE) {
279 LOG_ALWAYS_FATAL("Unknown XA_IID_DYNAMICSOURCE");
280 } else if (iid == XA_IID_ENGINE) {
281 RegisterXAEngineItfMethods(*static_cast<Guest_XAEngineItf*>(interface));
282 } else if (iid == XA_IID_EQUALIZER) {
283 LOG_ALWAYS_FATAL("Unknown XA_IID_EQUALIZER");
284 } else if (iid == XA_IID_IMAGECONTROLS) {
285 LOG_ALWAYS_FATAL("Unknown XA_IID_IMAGECONTROLS");
286 } else if (iid == XA_IID_IMAGEDECODERCAPABILITIES) {
287 LOG_ALWAYS_FATAL("Unknown XA_IID_IMAGEDECODERCAPABILITIES");
288 } else if (iid == XA_IID_IMAGEEFFECTS) {
289 LOG_ALWAYS_FATAL("Unknown XA_IID_IMAGEEFFECTS");
290 } else if (iid == XA_IID_IMAGEENCODER) {
291 LOG_ALWAYS_FATAL("Unknown XA_IID_IMAGEENCODER");
292 } else if (iid == XA_IID_IMAGEENCODERCAPABILITIES) {
293 LOG_ALWAYS_FATAL("Unknown XA_IID_IMAGEENCODERCAPABILITIES");
294 } else if (iid == XA_IID_LED) {
295 LOG_ALWAYS_FATAL("Unknown XA_IID_LED");
296 } else if (iid == XA_IID_METADATAEXTRACTION) {
297 LOG_ALWAYS_FATAL("Unknown XA_IID_METADATAEXTRACTION");
298 } else if (iid == XA_IID_METADATAINSERTION) {
299 LOG_ALWAYS_FATAL("Unknown XA_IID_METADATAINSERTION");
300 } else if (iid == XA_IID_METADATATRAVERSAL) {
301 LOG_ALWAYS_FATAL("Unknown XA_IID_METADATATRAVERSAL");
302 } else if (iid == XA_IID_NULL) {
303 LOG_ALWAYS_FATAL("Unknown XA_IID_NULL");
304 } else if (iid == XA_IID_OBJECT) {
305 LOG_ALWAYS_FATAL("Unknown XA_IID_OBJECT");
306 } else if (iid == XA_IID_OUTPUTMIX) {
307 LOG_ALWAYS_FATAL("Unknown XA_IID_OUTPUTMIX");
308 } else if (iid == XA_IID_PLAY) {
309 RegisterXAPlayItfMethods(*static_cast<Guest_XAPlayItf*>(interface));
310 } else if (iid == XA_IID_PLAYBACKRATE) {
311 LOG_ALWAYS_FATAL("Unknown XA_IID_PLAYBACKRATE");
312 } else if (iid == XA_IID_PREFETCHSTATUS) {
313 LOG_ALWAYS_FATAL("Unknown XA_IID_PREFETCHSTATUS");
314 } else if (iid == XA_IID_RADIO) {
315 LOG_ALWAYS_FATAL("Unknown XA_IID_RADIO");
316 } else if (iid == XA_IID_RDS) {
317 LOG_ALWAYS_FATAL("Unknown XA_IID_RDS");
318 } else if (iid == XA_IID_RECORD) {
319 LOG_ALWAYS_FATAL("Unknown XA_IID_RECORD");
320 } else if (iid == XA_IID_SEEK) {
321 LOG_ALWAYS_FATAL("Unknown XA_IID_SEEK");
322 } else if (iid == XA_IID_SNAPSHOT) {
323 LOG_ALWAYS_FATAL("Unknown XA_IID_SNAPSHOT");
324 } else if (iid == XA_IID_STREAMINFORMATION) {
325 RegisterXAStreamInformationItfMethods(*static_cast<Guest_XAStreamInformationItf*>(interface));
326 } else if (iid == XA_IID_THREADSYNC) {
327 LOG_ALWAYS_FATAL("Unknown XA_IID_THREADSYNC");
328 } else if (iid == XA_IID_VIBRA) {
329 LOG_ALWAYS_FATAL("Unknown XA_IID_VIBRA");
330 } else if (iid == XA_IID_VIDEODECODERCAPABILITIES) {
331 RegisterXAVideoDecoderCapabilitiesItfMethods(
332 *static_cast<XAVideoDecoderCapabilitiesItf*>(interface));
333 } else if (iid == XA_IID_VIDEOENCODER) {
334 LOG_ALWAYS_FATAL("Unknown XA_IID_VIDEOENCODER");
335 } else if (iid == XA_IID_VIDEOENCODERCAPABILITIES) {
336 LOG_ALWAYS_FATAL("Unknown XA_IID_VIDEOENCODERCAPABILITIES");
337 } else if (iid == XA_IID_VIDEOPOSTPROCESSING) {
338 LOG_ALWAYS_FATAL("Unknown XA_IID_VIDEOPOSTPROCESSING");
339 } else if (iid == XA_IID_VOLUME) {
340 RegisterXAVolumeItfMethods(*static_cast<Guest_XAVolumeItf*>(interface));
341 } else {
342 LOG_ALWAYS_FATAL("Unknown XAInterfaceID");
343 }
344 }
345
346 // XAresult (*RegisterCallback) (XAObjectItf self, xaObjectCallback callback, void * pContext);
DoCustomTrampoline_XAObject_RegisterCallback(HostCode,ProcessState * state)347 void DoCustomTrampoline_XAObject_RegisterCallback(HostCode /*callee*/, ProcessState* state) {
348 using PFN_callee = decltype(std::declval<XAObjectItf_>().RegisterCallback);
349 auto [self, guest_callback, callback_context] = GuestParamsValues<PFN_callee>(state);
350
351 // typedef void (XAAPIENTRY * xaObjectCallback) (
352 // XAObjectItf caller,
353 // const void * pContext,
354 // XAuint32 event,
355 // XAresult result,
356 // XAuint32 param,
357 // void * pInterface);
358 auto host_callback = WrapGuestFunction(guest_callback, "XAObject_RegisterCallback-callback");
359
360 auto&& [ret] = GuestReturnReference<PFN_callee>(state);
361 ret = (*self)->RegisterCallback(self, host_callback, callback_context);
362 }
363
RegisterXAObjectItfMethods(Guest_XAObjectItf itf)364 void RegisterXAObjectItfMethods(Guest_XAObjectItf itf) {
365 REGISTER_TRAMPOLINE(XAObject, Realize);
366 REGISTER_CUSTOM_TRAMPOLINE(XAObject, GetInterface);
367 REGISTER_TRAMPOLINE(XAObject, Destroy);
368 REGISTER_TRAMPOLINE(XAObject, Resume);
369 REGISTER_TRAMPOLINE(XAObject, GetState);
370 REGISTER_TRAMPOLINE(XAObject, AbortAsyncOperation);
371 REGISTER_TRAMPOLINE(XAObject, SetPriority);
372 REGISTER_TRAMPOLINE(XAObject, GetPriority);
373 REGISTER_TRAMPOLINE(XAObject, SetLossOfControlInterfaces);
374 REGISTER_CUSTOM_TRAMPOLINE(XAObject, RegisterCallback);
375 };
376
DoThunk_xaCreateEngine(Guest_XAObjectItf * engine,uint32_t num_options,const Guest_XAEngineOption * engine_options,uint32_t num_interfaces,const Guest_XAInterfaceID * interface_ids,uint32_t * interface_required)377 uint32_t DoThunk_xaCreateEngine(Guest_XAObjectItf* engine,
378 uint32_t num_options,
379 const Guest_XAEngineOption* engine_options,
380 uint32_t num_interfaces,
381 const Guest_XAInterfaceID* interface_ids,
382 uint32_t* interface_required) {
383 auto res = xaCreateEngine(
384 engine, num_options, engine_options, num_interfaces, interface_ids, interface_required);
385 RegisterXAObjectItfMethods(*engine);
386 return res;
387 }
388
389 #if defined(NATIVE_BRIDGE_GUEST_ARCH_ARM) && defined(__i386__)
390
391 #include "trampolines_arm_to_x86-inl.h" // generated file NOLINT [build/include]
392
393 #elif defined(NATIVE_BRIDGE_GUEST_ARCH_ARM64) && defined(__x86_64__)
394
395 #include "trampolines_arm64_to_x86_64-inl.h" // generated file NOLINT [build/include]
396
397 #elif defined(NATIVE_BRIDGE_GUEST_ARCH_RISCV64) && defined(__x86_64__)
398
399 #include "trampolines_riscv64_to_x86_64-inl.h" // generated file NOLINT [build/include]
400
401 #else
402
403 #error "Unknown guest/host arch combination"
404
405 #endif
406
407 DEFINE_INIT_PROXY_LIBRARY("libOpenMAXAL.so")
408
409 } // namespace
410
411 } // namespace berberis
412