|
21 | 21 |
|
22 | 22 | #ifdef __ANDROID__ |
23 | 23 | #include <android/bitmap.h> |
| 24 | +#include <android/hardware_buffer_jni.h> |
| 25 | +#include <backend/platforms/PlatformEGLAndroid.h> |
| 26 | +# if FILAMENT_SUPPORTS_VULKAN |
| 27 | +# include <backend/platforms/VulkanPlatformAndroid.h> |
| 28 | +# endif |
24 | 29 | #endif |
25 | 30 |
|
26 | 31 | #include <filament/Engine.h> |
@@ -388,6 +393,57 @@ Java_com_google_android_filament_Texture_nSetExternalImage(JNIEnv*, jclass, jlon |
388 | 393 | texture->setExternalImage(*engine, (void*)eglImage); |
389 | 394 | } |
390 | 395 |
|
| 396 | +extern "C" |
| 397 | +JNIEXPORT jboolean JNICALL |
| 398 | +Java_com_google_android_filament_Texture_nSetExternalImageByAHB(JNIEnv *env, jclass clazz, |
| 399 | + jlong nativeTexture, jlong nativeEngine, jobject ahb) { |
| 400 | + Texture *texture = (Texture *) nativeTexture; |
| 401 | + Engine *engine = (Engine *) nativeEngine; |
| 402 | + |
| 403 | +#ifdef __ANDROID__ |
| 404 | + Platform* platform = engine->getPlatform(); |
| 405 | + AHardwareBuffer* nativeBuffer = nullptr; |
| 406 | + if (__builtin_available(android 26, *)) { |
| 407 | + nativeBuffer = AHardwareBuffer_fromHardwareBuffer(env, ahb); |
| 408 | + } |
| 409 | + if (!nativeBuffer) { |
| 410 | + // either we're not on Android 26, or ahb wasn't a AHardwareBuffer |
| 411 | + return JNI_FALSE; |
| 412 | + } |
| 413 | + |
| 414 | + if (engine->getBackend() == Backend::OPENGL) { |
| 415 | + // CAVEAT: we assume that Backend::OPENGL on Android implies PlatformEGLAndroid. |
| 416 | +#if UTILS_HAS_RTTI |
| 417 | + if (!dynamic_cast<PlatformEGLAndroid*>(platform)) { |
| 418 | + return JNI_FALSE; |
| 419 | + } |
| 420 | +#endif |
| 421 | + auto* eglPlatform = (PlatformEGLAndroid*) platform; |
| 422 | + auto ref = eglPlatform->createExternalImage(nativeBuffer, false); |
| 423 | + texture->setExternalImage(*engine, ref); |
| 424 | + } |
| 425 | + |
| 426 | +#if FILAMENT_SUPPORTS_VULKAN |
| 427 | + else if (engine->getBackend() == Backend::VULKAN) { |
| 428 | + // CAVEAT: we assume that Backend::VULKAN on Android implies VulkanPlatformAndroid. |
| 429 | +#if UTILS_HAS_RTTI |
| 430 | + if (!dynamic_cast<VulkanPlatformAndroid*>(platform)) { |
| 431 | + return JNI_FALSE; |
| 432 | + } |
| 433 | +#endif |
| 434 | + auto* vulkanPlatform = (VulkanPlatformAndroid*) platform; |
| 435 | + auto ref = vulkanPlatform->createExternalImage(nativeBuffer, false); |
| 436 | + texture->setExternalImage(*engine, ref); |
| 437 | + } |
| 438 | +#endif // FILAMENT_SUPPORTS_VULKAN |
| 439 | + // success! |
| 440 | + return JNI_TRUE; |
| 441 | +#else |
| 442 | + // other platforms could come here |
| 443 | + return JNI_FALSE; |
| 444 | +#endif // __ANDROID__ |
| 445 | +} |
| 446 | + |
391 | 447 | extern "C" JNIEXPORT void JNICALL |
392 | 448 | Java_com_google_android_filament_Texture_nSetExternalStream(JNIEnv*, jclass, |
393 | 449 | jlong nativeTexture, jlong nativeEngine, jlong nativeStream) { |
@@ -607,3 +663,4 @@ Java_com_google_android_filament_android_TextureHelper_nSetBitmapWithCallback(JN |
607 | 663 | } |
608 | 664 |
|
609 | 665 | #endif |
| 666 | + |
0 commit comments