blob: 8716cc51f82674d51b1a8de6075a8317ee8d0324 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/android/vr/arcore_device/arcore_sdk.h"
#include <dlfcn.h>
#include "base/android/android_hardware_buffer_compat.h"
#include "base/android/build_info.h"
#include "base/logging.h"
namespace {
// Run CALL macro for every function defined in the API.
#define FOR_EACH_API_FN \
CALL(ArAnchorList_acquireItem) \
CALL(ArAnchorList_create) \
CALL(ArAnchorList_destroy) \
CALL(ArAnchorList_getSize) \
CALL(ArAnchor_detach) \
CALL(ArAnchor_getPose) \
CALL(ArAnchor_getTrackingState) \
CALL(ArAnchor_release) \
CALL(ArCamera_getDisplayOrientedPose) \
CALL(ArCamera_getProjectionMatrix) \
CALL(ArCamera_getTrackingState) \
CALL(ArCamera_getViewMatrix) \
CALL(ArConfig_create) \
CALL(ArConfig_destroy) \
CALL(ArFrame_acquireCamera) \
CALL(ArFrame_create) \
CALL(ArFrame_destroy) \
CALL(ArFrame_getUpdatedAnchors) \
CALL(ArFrame_getUpdatedTrackables) \
CALL(ArFrame_hitTestRay) \
CALL(ArFrame_transformCoordinates2d) \
CALL(ArHitResult_acquireTrackable) \
CALL(ArHitResult_create) \
CALL(ArHitResult_destroy) \
CALL(ArHitResult_getHitPose) \
CALL(ArHitResultList_create) \
CALL(ArHitResultList_destroy) \
CALL(ArHitResultList_getItem) \
CALL(ArHitResultList_getSize) \
CALL(ArPlane_acquireSubsumedBy) \
CALL(ArPlane_getCenterPose) \
CALL(ArPlane_getPolygon) \
CALL(ArPlane_getPolygonSize) \
CALL(ArPlane_getType) \
CALL(ArPlane_isPoseInPolygon) \
CALL(ArPose_create) \
CALL(ArPose_destroy) \
CALL(ArPose_getMatrix) \
CALL(ArPose_getPoseRaw) \
CALL(ArSession_acquireNewAnchor) \
CALL(ArSession_configure) \
CALL(ArSession_create) \
CALL(ArSession_destroy) \
CALL(ArSession_enableIncognitoMode_private) \
CALL(ArSession_getAllAnchors) \
CALL(ArSession_getAllTrackables) \
CALL(ArSession_pause) \
CALL(ArSession_resume) \
CALL(ArSession_setCameraTextureName) \
CALL(ArSession_setDisplayGeometry) \
CALL(ArSession_update) \
CALL(ArTrackable_acquireNewAnchor) \
CALL(ArTrackable_getTrackingState) \
CALL(ArTrackable_getType) \
CALL(ArTrackable_release) \
CALL(ArTrackableList_acquireItem) \
CALL(ArTrackableList_create) \
CALL(ArTrackableList_destroy) \
CALL(ArTrackableList_getSize)
#define CALL(fn) decltype(&fn) impl_##fn = nullptr;
struct ArCoreApi {
FOR_EACH_API_FN
};
#undef CALL
static void* sdk_handle = nullptr;
static ArCoreApi* arcore_api = nullptr;
template <typename Fn>
void LoadFunction(void* handle, const char* function_name, Fn* fn_out) {
void* fn = dlsym(handle, function_name);
if (!fn)
return;
*fn_out = reinterpret_cast<Fn>(fn);
}
} // namespace
namespace vr {
bool LoadArCoreSdk(const std::string& libraryPath) {
if (arcore_api)
return true;
sdk_handle = dlopen(libraryPath.c_str(), RTLD_GLOBAL | RTLD_NOW);
if (!sdk_handle) {
char* error_string = nullptr;
error_string = dlerror();
LOG(ERROR) << "Could not open libarcore_sdk_c.so: " << error_string;
return false;
} else {
VLOG(2) << "Opened shim shared library.";
}
// TODO(https://crbug.com/914999): check SDK version.
arcore_api = new ArCoreApi();
#define CALL(fn) LoadFunction(sdk_handle, #fn, &arcore_api->impl_##fn);
FOR_EACH_API_FN
#undef CALL
return true;
}
bool IsArCoreSupported() {
return base::android::BuildInfo::GetInstance()->sdk_int() >=
base::android::SDK_VERSION_NOUGAT;
}
} // namespace vr
#undef FOR_EACH_API_FN
void ArAnchorList_acquireItem(const ArSession* session,
const ArAnchorList* anchor_list,
int32_t index,
ArAnchor** out_anchor) {
arcore_api->impl_ArAnchorList_acquireItem(session, anchor_list, index,
out_anchor);
}
void ArAnchorList_create(const ArSession* session,
ArAnchorList** out_anchor_list) {
arcore_api->impl_ArAnchorList_create(session, out_anchor_list);
}
void ArAnchorList_destroy(ArAnchorList* anchor_list) {
arcore_api->impl_ArAnchorList_destroy(anchor_list);
}
void ArAnchorList_getSize(const ArSession* session,
const ArAnchorList* anchor_list,
int32_t* out_size) {
arcore_api->impl_ArAnchorList_getSize(session, anchor_list, out_size);
}
void ArAnchor_detach(ArSession* session, ArAnchor* anchor) {
arcore_api->impl_ArAnchor_detach(session, anchor);
}
void ArAnchor_getPose(const ArSession* session,
const ArAnchor* anchor,
ArPose* out_pose) {
arcore_api->impl_ArAnchor_getPose(session, anchor, out_pose);
}
void ArAnchor_getTrackingState(const ArSession* session,
const ArAnchor* anchor,
ArTrackingState* out_tracking_state) {
arcore_api->impl_ArAnchor_getTrackingState(session, anchor,
out_tracking_state);
}
void ArAnchor_release(ArAnchor* anchor) {
arcore_api->impl_ArAnchor_release(anchor);
}
void ArCamera_getDisplayOrientedPose(const ArSession* session,
const ArCamera* camera,
ArPose* out_pose) {
arcore_api->impl_ArCamera_getDisplayOrientedPose(session, camera, out_pose);
}
void ArCamera_getProjectionMatrix(const ArSession* session,
const ArCamera* camera,
float near,
float far,
float* dest_col_major_4x4) {
arcore_api->impl_ArCamera_getProjectionMatrix(session, camera, near, far,
dest_col_major_4x4);
}
void ArCamera_getTrackingState(const ArSession* session,
const ArCamera* camera,
ArTrackingState* out_tracking_state) {
arcore_api->impl_ArCamera_getTrackingState(session, camera,
out_tracking_state);
}
void ArCamera_getViewMatrix(const ArSession* session,
const ArCamera* camera,
float* out_matrix) {
arcore_api->impl_ArCamera_getViewMatrix(session, camera, out_matrix);
}
void ArConfig_create(const ArSession* session, ArConfig** out_config) {
arcore_api->impl_ArConfig_create(session, out_config);
}
void ArConfig_destroy(ArConfig* config) {
arcore_api->impl_ArConfig_destroy(config);
}
void ArFrame_acquireCamera(const ArSession* session,
const ArFrame* frame,
ArCamera** out_camera) {
arcore_api->impl_ArFrame_acquireCamera(session, frame, out_camera);
}
void ArFrame_create(const ArSession* session, ArFrame** out_frame) {
arcore_api->impl_ArFrame_create(session, out_frame);
}
void ArFrame_destroy(ArFrame* frame) {
arcore_api->impl_ArFrame_destroy(frame);
}
void ArFrame_getUpdatedAnchors(const ArSession* session,
const ArFrame* frame,
ArAnchorList* out_anchor_list) {
arcore_api->impl_ArFrame_getUpdatedAnchors(session, frame, out_anchor_list);
}
void ArFrame_getUpdatedTrackables(const ArSession* session,
const ArFrame* frame,
ArTrackableType filter_type,
ArTrackableList* out_trackable_list) {
arcore_api->impl_ArFrame_getUpdatedTrackables(session, frame, filter_type,
out_trackable_list);
}
void ArFrame_hitTestRay(const ArSession* session,
const ArFrame* frame,
const float* ray_origin_3,
const float* ray_direction_3,
ArHitResultList* out_hit_results) {
arcore_api->impl_ArFrame_hitTestRay(session, frame, ray_origin_3,
ray_direction_3, out_hit_results);
}
void ArFrame_transformCoordinates2d(const ArSession* session,
const ArFrame* frame,
ArCoordinates2dType input_coordinates,
int32_t number_of_vertices,
const float* vertices_2d,
ArCoordinates2dType output_coordinates,
float* out_vertices_2d) {
arcore_api->impl_ArFrame_transformCoordinates2d(
session, frame, input_coordinates, number_of_vertices, vertices_2d,
output_coordinates, out_vertices_2d);
}
void ArHitResult_create(const ArSession* session,
ArHitResult** out_hit_result) {
arcore_api->impl_ArHitResult_create(session, out_hit_result);
}
void ArHitResult_destroy(ArHitResult* hit_result) {
arcore_api->impl_ArHitResult_destroy(hit_result);
}
void ArHitResult_getHitPose(const ArSession* session,
const ArHitResult* hit_result,
ArPose* out_pose) {
arcore_api->impl_ArHitResult_getHitPose(session, hit_result, out_pose);
}
void ArHitResult_acquireTrackable(const ArSession* session,
const ArHitResult* hit_result,
ArTrackable** out_trackable) {
arcore_api->impl_ArHitResult_acquireTrackable(session, hit_result,
out_trackable);
}
ArStatus ArTrackable_acquireNewAnchor(ArSession* session,
ArTrackable* trackable,
ArPose* pose,
ArAnchor** out_anchor) {
return arcore_api->impl_ArTrackable_acquireNewAnchor(session, trackable, pose,
out_anchor);
}
void ArTrackable_getTrackingState(const ArSession* session,
const ArTrackable* trackable,
ArTrackingState* out_tracking_state) {
arcore_api->impl_ArTrackable_getTrackingState(session, trackable,
out_tracking_state);
}
void ArTrackable_getType(const ArSession* session,
const ArTrackable* trackable,
ArTrackableType* out_trackable_type) {
arcore_api->impl_ArTrackable_getType(session, trackable, out_trackable_type);
}
void ArTrackable_release(ArTrackable* trackable) {
arcore_api->impl_ArTrackable_release(trackable);
}
void ArTrackableList_acquireItem(const ArSession* session,
const ArTrackableList* trackable_list,
int32_t index,
ArTrackable** out_trackable) {
arcore_api->impl_ArTrackableList_acquireItem(session, trackable_list, index,
out_trackable);
}
void ArTrackableList_create(const ArSession* session,
ArTrackableList** out_trackable_list) {
arcore_api->impl_ArTrackableList_create(session, out_trackable_list);
}
void ArTrackableList_destroy(ArTrackableList* trackable_list) {
arcore_api->impl_ArTrackableList_destroy(trackable_list);
}
void ArTrackableList_getSize(const ArSession* session,
const ArTrackableList* trackable_list,
int32_t* out_size) {
arcore_api->impl_ArTrackableList_getSize(session, trackable_list, out_size);
}
void ArPlane_acquireSubsumedBy(const ArSession* session,
const ArPlane* plane,
ArPlane** out_subsumed_by) {
arcore_api->impl_ArPlane_acquireSubsumedBy(session, plane, out_subsumed_by);
}
void ArPlane_getCenterPose(const ArSession* session,
const ArPlane* plane,
ArPose* out_pose) {
arcore_api->impl_ArPlane_getCenterPose(session, plane, out_pose);
}
void ArPlane_getPolygon(const ArSession* session,
const ArPlane* plane,
float* out_polygon_xz) {
arcore_api->impl_ArPlane_getPolygon(session, plane, out_polygon_xz);
}
void ArPlane_getPolygonSize(const ArSession* session,
const ArPlane* plane,
int32_t* out_polygon_size) {
arcore_api->impl_ArPlane_getPolygonSize(session, plane, out_polygon_size);
}
void ArPlane_getType(const ArSession* session,
const ArPlane* plane,
ArPlaneType* out_plane_type) {
arcore_api->impl_ArPlane_getType(session, plane, out_plane_type);
}
void ArPlane_isPoseInPolygon(const ArSession* session,
const ArPlane* plane,
const ArPose* pose,
int32_t* out_pose_in_polygon) {
arcore_api->impl_ArPlane_isPoseInPolygon(session, plane, pose,
out_pose_in_polygon);
}
void ArHitResultList_create(const ArSession* session,
ArHitResultList** out_hit_result_list) {
arcore_api->impl_ArHitResultList_create(session, out_hit_result_list);
}
void ArHitResultList_destroy(ArHitResultList* hit_result_list) {
arcore_api->impl_ArHitResultList_destroy(hit_result_list);
}
void ArHitResultList_getItem(const ArSession* session,
const ArHitResultList* hit_result_list,
int index,
ArHitResult* out_hit_result) {
arcore_api->impl_ArHitResultList_getItem(session, hit_result_list, index,
out_hit_result);
}
void ArHitResultList_getSize(const ArSession* session,
const ArHitResultList* hit_result_list,
int* out_size) {
arcore_api->impl_ArHitResultList_getSize(session, hit_result_list, out_size);
}
void ArPose_create(const ArSession* session,
const float* pose_raw,
ArPose** out_pose) {
arcore_api->impl_ArPose_create(session, pose_raw, out_pose);
}
void ArPose_destroy(ArPose* pose) {
arcore_api->impl_ArPose_destroy(pose);
}
void ArPose_getMatrix(const ArSession* session,
const ArPose* pose,
float* out_matrix) {
arcore_api->impl_ArPose_getMatrix(session, pose, out_matrix);
}
void ArPose_getPoseRaw(const ArSession* session,
const ArPose* pose,
float* out_pose_raw) {
arcore_api->impl_ArPose_getPoseRaw(session, pose, out_pose_raw);
}
ArStatus ArSession_acquireNewAnchor(ArSession* session,
const ArPose* pose,
ArAnchor** out_anchor) {
return arcore_api->impl_ArSession_acquireNewAnchor(session, pose, out_anchor);
}
ArStatus ArSession_configure(ArSession* session, const ArConfig* config) {
return arcore_api->impl_ArSession_configure(session, config);
}
ArStatus ArSession_create(void* env,
void* application_context,
ArSession** out_session_pointer) {
return arcore_api->impl_ArSession_create(env, application_context,
out_session_pointer);
}
void ArSession_destroy(ArSession* session) {
arcore_api->impl_ArSession_destroy(session);
}
void ArSession_enableIncognitoMode_private(ArSession* session) {
arcore_api->impl_ArSession_enableIncognitoMode_private(session);
}
void ArSession_getAllAnchors(const ArSession* session,
ArAnchorList* out_anchor_list) {
arcore_api->impl_ArSession_getAllAnchors(session, out_anchor_list);
}
void ArSession_getAllTrackables(const ArSession* session,
ArTrackableType filter_type,
ArTrackableList* out_trackable_list) {
arcore_api->impl_ArSession_getAllTrackables(session, filter_type,
out_trackable_list);
}
ArStatus ArSession_pause(ArSession* session) {
return arcore_api->impl_ArSession_pause(session);
}
ArStatus ArSession_resume(ArSession* session) {
return arcore_api->impl_ArSession_resume(session);
}
void ArSession_setCameraTextureName(ArSession* session, uint32_t texture_id) {
return arcore_api->impl_ArSession_setCameraTextureName(session, texture_id);
}
void ArSession_setDisplayGeometry(ArSession* session,
int32_t rotation,
int32_t width,
int32_t height) {
return arcore_api->impl_ArSession_setDisplayGeometry(session, rotation, width,
height);
}
ArStatus ArSession_update(ArSession* session, ArFrame* out_frame) {
return arcore_api->impl_ArSession_update(session, out_frame);
}