From d3025256749501b6094693daecfa663e3b94bc73 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Mon, 24 Jul 2023 15:42:01 -0700 Subject: [PATCH] Add a way to query the validity of filament objects Engine::isValid() can be used to check the validity of most filament objects. --- NEW_RELEASE_NOTES.md | 2 + .../filament-android/src/main/cpp/Engine.cpp | 106 ++++++++++++ .../com/google/android/filament/Engine.java | 159 +++++++++++++++++- filament/include/filament/Engine.h | 19 +++ filament/src/Engine.cpp | 55 ++++++ filament/src/ResourceList.cpp | 5 +- filament/src/ResourceList.h | 5 + filament/src/details/Engine.cpp | 79 +++++++++ filament/src/details/Engine.h | 23 +++ web/filament-js/jsbindings.cpp | 48 +++++- 10 files changed, 495 insertions(+), 6 deletions(-) diff --git a/NEW_RELEASE_NOTES.md b/NEW_RELEASE_NOTES.md index 3e0b96ec75..77176462ef 100644 --- a/NEW_RELEASE_NOTES.md +++ b/NEW_RELEASE_NOTES.md @@ -8,3 +8,5 @@ appropriate header in [RELEASE_NOTES.md](./RELEASE_NOTES.md). ## Release notes for next branch cut - backend: Disable timer queries on all Mali GPUs (fixes b/233754398) +- engine: Add a way to query the validity of most filament objects (see `Engine::isValid`) +- opengl: fix b/290388359 : possible crash when shutting down the engine diff --git a/android/filament-android/src/main/cpp/Engine.cpp b/android/filament-android/src/main/cpp/Engine.cpp index 3d720a88a3..e530e7bb55 100644 --- a/android/filament-android/src/main/cpp/Engine.cpp +++ b/android/filament-android/src/main/cpp/Engine.cpp @@ -278,6 +278,112 @@ Java_com_google_android_filament_Engine_nDestroyEntity(JNIEnv*, jclass, engine->destroy(entity); } + +extern "C" JNIEXPORT jboolean JNICALL +Java_com_google_android_filament_Engine_nIsValidRenderer(JNIEnv*, jclass, + jlong nativeEngine, jlong nativeRenderer) { + Engine* engine = (Engine *)nativeEngine; + return (jboolean)engine->isValid((Renderer*)nativeRenderer); +} + +extern "C" JNIEXPORT jboolean JNICALL +Java_com_google_android_filament_Engine_nIsValidView(JNIEnv*, jclass, + jlong nativeEngine, jlong nativeView) { + Engine* engine = (Engine *)nativeEngine; + return (jboolean)engine->isValid((View*)nativeView); +} + +extern "C" JNIEXPORT jboolean JNICALL +Java_com_google_android_filament_Engine_nIsValidScene(JNIEnv*, jclass, + jlong nativeEngine, jlong nativeScene) { + Engine* engine = (Engine *)nativeEngine; + return (jboolean)engine->isValid((Scene*)nativeScene); +} + +extern "C" JNIEXPORT jboolean JNICALL +Java_com_google_android_filament_Engine_nIsValidFence(JNIEnv*, jclass, + jlong nativeEngine, jlong nativeFence) { + Engine* engine = (Engine *)nativeEngine; + return (jboolean)engine->isValid((Fence*)nativeFence); +} + +extern "C" JNIEXPORT jboolean JNICALL +Java_com_google_android_filament_Engine_nIsValidStream(JNIEnv*, jclass, + jlong nativeEngine, jlong nativeStream) { + Engine* engine = (Engine *)nativeEngine; + return (jboolean)engine->isValid((Stream*)nativeStream); +} + +extern "C" JNIEXPORT jboolean JNICALL +Java_com_google_android_filament_Engine_nIsValidIndexBuffer(JNIEnv*, jclass, + jlong nativeEngine, jlong nativeIndexBuffer) { + Engine* engine = (Engine *)nativeEngine; + return (jboolean)engine->isValid((IndexBuffer*)nativeIndexBuffer); +} + +extern "C" JNIEXPORT jboolean JNICALL +Java_com_google_android_filament_Engine_nIsValidVertexBuffer(JNIEnv*, jclass, + jlong nativeEngine, jlong nativeVertexBuffer) { + Engine* engine = (Engine *)nativeEngine; + return (jboolean)engine->isValid((VertexBuffer*)nativeVertexBuffer); +} + +extern "C" JNIEXPORT jboolean JNICALL +Java_com_google_android_filament_Engine_nIsValidSkinningBuffer(JNIEnv*, jclass, + jlong nativeEngine, jlong nativeSkinningBuffer) { + Engine* engine = (Engine *)nativeEngine; + return (jboolean)engine->isValid((SkinningBuffer*)nativeSkinningBuffer); +} + +extern "C" JNIEXPORT jboolean JNICALL +Java_com_google_android_filament_Engine_nIsValidIndirectLight(JNIEnv*, jclass, + jlong nativeEngine, jlong nativeIndirectLight) { + Engine* engine = (Engine *)nativeEngine; + return (jboolean)engine->isValid((IndirectLight*)nativeIndirectLight); +} + +extern "C" JNIEXPORT jboolean JNICALL +Java_com_google_android_filament_Engine_nIsValidMaterial(JNIEnv*, jclass, + jlong nativeEngine, jlong nativeMaterial) { + Engine* engine = (Engine *)nativeEngine; + return (jboolean)engine->isValid((Material*)nativeMaterial); +} + +extern "C" JNIEXPORT jboolean JNICALL +Java_com_google_android_filament_Engine_nIsValidSkybox(JNIEnv*, jclass, + jlong nativeEngine, jlong nativeSkybox) { + Engine* engine = (Engine *)nativeEngine; + return (jboolean)engine->isValid((Skybox*)nativeSkybox); +} + +extern "C" JNIEXPORT jboolean JNICALL +Java_com_google_android_filament_Engine_nIsValidColorGrading(JNIEnv*, jclass, + jlong nativeEngine, jlong nativeColorGrading) { + Engine* engine = (Engine *)nativeEngine; + return (jboolean)engine->isValid((ColorGrading*)nativeColorGrading); +} + +extern "C" JNIEXPORT jboolean JNICALL +Java_com_google_android_filament_Engine_nIsValidTexture(JNIEnv*, jclass, + jlong nativeEngine, jlong nativeTexture) { + Engine* engine = (Engine *)nativeEngine; + return (jboolean)engine->isValid((Texture*)nativeTexture); +} + +extern "C" JNIEXPORT jboolean JNICALL +Java_com_google_android_filament_Engine_nIsValidRenderTarget(JNIEnv*, jclass, + jlong nativeEngine, jlong nativeTarget) { + Engine* engine = (Engine *)nativeEngine; + return (jboolean)engine->isValid((RenderTarget*)nativeTarget); +} + +extern "C" JNIEXPORT jboolean JNICALL +Java_com_google_android_filament_Engine_nIsValidSwapChain(JNIEnv*, jclass, + jlong nativeEngine, jlong nativeSwapChain) { + Engine* engine = (Engine *)nativeEngine; + return (jboolean)engine->isValid((SwapChain*)nativeSwapChain); +} + extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_Engine_nFlushAndWait(JNIEnv*, jclass, jlong nativeEngine) { diff --git a/android/filament-android/src/main/java/com/google/android/filament/Engine.java b/android/filament-android/src/main/java/com/google/android/filament/Engine.java index c047c96224..e6bc4d9243 100644 --- a/android/filament-android/src/main/java/com/google/android/filament/Engine.java +++ b/android/filament-android/src/main/java/com/google/android/filament/Engine.java @@ -449,6 +449,141 @@ public class Engine { swapChain.clearNativeObject(); } + /** + * Returns whether the object is valid. + * @param object Object to check for validity + * @return returns true if the specified object is valid. + */ + public boolean isValidRenderer(@NonNull Renderer object) { + return nIsValidRenderer(getNativeObject(), object.getNativeObject()); + } + + /** + * Returns whether the object is valid. + * @param object Object to check for validity + * @return returns true if the specified object is valid. + */ + public boolean isValidView(@NonNull View object) { + return nIsValidView(getNativeObject(), object.getNativeObject()); + } + + /** + * Returns whether the object is valid. + * @param object Object to check for validity + * @return returns true if the specified object is valid. + */ + public boolean isValidScene(@NonNull Scene object) { + return nIsValidScene(getNativeObject(), object.getNativeObject()); + } + + /** + * Returns whether the object is valid. + * @param object Object to check for validity + * @return returns true if the specified object is valid. + */ + public boolean isValidFence(@NonNull Fence object) { + return nIsValidFence(getNativeObject(), object.getNativeObject()); + } + + /** + * Returns whether the object is valid. + * @param object Object to check for validity + * @return returns true if the specified object is valid. + */ + public boolean isValidStream(@NonNull Stream object) { + return nIsValidStream(getNativeObject(), object.getNativeObject()); + } + + /** + * Returns whether the object is valid. + * @param object Object to check for validity + * @return returns true if the specified object is valid. + */ + public boolean isValidIndexBuffer(@NonNull IndexBuffer object) { + return nIsValidIndexBuffer(getNativeObject(), object.getNativeObject()); + } + + /** + * Returns whether the object is valid. + * @param object Object to check for validity + * @return returns true if the specified object is valid. + */ + public boolean isValidVertexBuffer(@NonNull VertexBuffer object) { + return nIsValidVertexBuffer(getNativeObject(), object.getNativeObject()); + } + + /** + * Returns whether the object is valid. + * @param object Object to check for validity + * @return returns true if the specified object is valid. + */ + public boolean isValidSkinningBuffer(@NonNull SkinningBuffer object) { + return nIsValidSkinningBuffer(getNativeObject(), object.getNativeObject()); + } + + /** + * Returns whether the object is valid. + * @param object Object to check for validity + * @return returns true if the specified object is valid. + */ + public boolean isValidIndirectLight(@NonNull IndirectLight object) { + return nIsValidIndirectLight(getNativeObject(), object.getNativeObject()); + } + + /** + * Returns whether the object is valid. + * @param object Object to check for validity + * @return returns true if the specified object is valid. + */ + public boolean isValidMaterial(@NonNull Material object) { + return nIsValidMaterial(getNativeObject(), object.getNativeObject()); + } + + /** + * Returns whether the object is valid. + * @param object Object to check for validity + * @return returns true if the specified object is valid. + */ + public boolean isValidSkybox(@NonNull Skybox object) { + return nIsValidSkybox(getNativeObject(), object.getNativeObject()); + } + + /** + * Returns whether the object is valid. + * @param object Object to check for validity + * @return returns true if the specified object is valid. + */ + public boolean isValidColorGrading(@NonNull ColorGrading object) { + return nIsValidColorGrading(getNativeObject(), object.getNativeObject()); + } + + /** + * Returns whether the object is valid. + * @param object Object to check for validity + * @return returns true if the specified object is valid. + */ + public boolean isValidTexture(@NonNull Texture object) { + return nIsValidTexture(getNativeObject(), object.getNativeObject()); + } + + /** + * Returns whether the object is valid. + * @param object Object to check for validity + * @return returns true if the specified object is valid. + */ + public boolean isValidRenderTarget(@NonNull RenderTarget object) { + return nIsValidRenderTarget(getNativeObject(), object.getNativeObject()); + } + + /** + * Returns whether the object is valid. + * @param object Object to check for validity + * @return returns true if the specified object is valid. + */ + public boolean isValidSwapChain(@NonNull SwapChain object) { + return nIsValidSwapChain(getNativeObject(), object.getNativeObject()); + } + // View /** @@ -785,17 +920,17 @@ public class Engine { private static native long nCreateSwapChain(long nativeEngine, Object nativeWindow, long flags); private static native long nCreateSwapChainHeadless(long nativeEngine, int width, int height, long flags); private static native long nCreateSwapChainFromRawPointer(long nativeEngine, long pointer, long flags); - private static native boolean nDestroySwapChain(long nativeEngine, long nativeSwapChain); private static native long nCreateView(long nativeEngine); - private static native boolean nDestroyView(long nativeEngine, long nativeView); private static native long nCreateRenderer(long nativeEngine); - private static native boolean nDestroyRenderer(long nativeEngine, long nativeRenderer); private static native long nCreateCamera(long nativeEngine, int entity); private static native long nGetCameraComponent(long nativeEngine, int entity); private static native void nDestroyCameraComponent(long nativeEngine, int entity); private static native long nCreateScene(long nativeEngine); - private static native boolean nDestroyScene(long nativeEngine, long nativeScene); private static native long nCreateFence(long nativeEngine); + + private static native boolean nDestroyRenderer(long nativeEngine, long nativeRenderer); + private static native boolean nDestroyView(long nativeEngine, long nativeView); + private static native boolean nDestroyScene(long nativeEngine, long nativeScene); private static native boolean nDestroyFence(long nativeEngine, long nativeFence); private static native boolean nDestroyStream(long nativeEngine, long nativeStream); private static native boolean nDestroyIndexBuffer(long nativeEngine, long nativeIndexBuffer); @@ -808,6 +943,22 @@ public class Engine { private static native boolean nDestroyColorGrading(long nativeEngine, long nativeColorGrading); private static native boolean nDestroyTexture(long nativeEngine, long nativeTexture); private static native boolean nDestroyRenderTarget(long nativeEngine, long nativeTarget); + private static native boolean nDestroySwapChain(long nativeEngine, long nativeSwapChain); + private static native boolean nIsValidRenderer(long nativeEngine, long nativeRenderer); + private static native boolean nIsValidView(long nativeEngine, long nativeView); + private static native boolean nIsValidScene(long nativeEngine, long nativeScene); + private static native boolean nIsValidFence(long nativeEngine, long nativeFence); + private static native boolean nIsValidStream(long nativeEngine, long nativeStream); + private static native boolean nIsValidIndexBuffer(long nativeEngine, long nativeIndexBuffer); + private static native boolean nIsValidVertexBuffer(long nativeEngine, long nativeVertexBuffer); + private static native boolean nIsValidSkinningBuffer(long nativeEngine, long nativeSkinningBuffer); + private static native boolean nIsValidIndirectLight(long nativeEngine, long nativeIndirectLight); + private static native boolean nIsValidMaterial(long nativeEngine, long nativeMaterial); + private static native boolean nIsValidSkybox(long nativeEngine, long nativeSkybox); + private static native boolean nIsValidColorGrading(long nativeEngine, long nativeColorGrading); + private static native boolean nIsValidTexture(long nativeEngine, long nativeTexture); + private static native boolean nIsValidRenderTarget(long nativeEngine, long nativeTarget); + private static native boolean nIsValidSwapChain(long nativeEngine, long nativeSwapChain); private static native void nDestroyEntity(long nativeEngine, int entity); private static native void nFlushAndWait(long nativeEngine); private static native long nGetTransformManager(long nativeEngine); diff --git a/filament/include/filament/Engine.h b/filament/include/filament/Engine.h index 3795b89fb5..e4d601b3cd 100644 --- a/filament/include/filament/Engine.h +++ b/filament/include/filament/Engine.h @@ -676,6 +676,25 @@ public: bool destroy(const InstanceBuffer* p); //!< Destroys an InstanceBuffer object. void destroy(utils::Entity e); //!< Destroys all filament-known components from this entity + bool isValid(const BufferObject* p); //!< Tells whether a BufferObject object is valid + bool isValid(const VertexBuffer* p); //!< Tells whether an VertexBuffer object is valid + bool isValid(const Fence* p); //!< Tells whether a Fence object is valid + bool isValid(const IndexBuffer* p); //!< Tells whether an IndexBuffer object is valid + bool isValid(const SkinningBuffer* p); //!< Tells whether a SkinningBuffer object is valid + bool isValid(const MorphTargetBuffer* p); //!< Tells whether a MorphTargetBuffer object is valid + bool isValid(const IndirectLight* p); //!< Tells whether an IndirectLight object is valid + bool isValid(const Material* p); //!< Tells whether an IndirectLight object is valid + bool isValid(const Renderer* p); //!< Tells whether a Renderer object is valid + bool isValid(const Scene* p); //!< Tells whether a Scene object is valid + bool isValid(const Skybox* p); //!< Tells whether a SkyBox object is valid + bool isValid(const ColorGrading* p); //!< Tells whether a ColorGrading object is valid + bool isValid(const SwapChain* p); //!< Tells whether a SwapChain object is valid + bool isValid(const Stream* p); //!< Tells whether a Stream object is valid + bool isValid(const Texture* p); //!< Tells whether a Texture object is valid + bool isValid(const RenderTarget* p); //!< Tells whether a RenderTarget object is valid + bool isValid(const View* p); //!< Tells whether a View object is valid + bool isValid(const InstanceBuffer* p); //!< Tells whether an InstanceBuffer object is valid + /** * Kicks the hardware thread (e.g. the OpenGL, Vulkan or Metal thread) and blocks until * all commands to this point are executed. Note that does guarantee that the diff --git a/filament/src/Engine.cpp b/filament/src/Engine.cpp index ccb1748047..ce97bdfd0f 100644 --- a/filament/src/Engine.cpp +++ b/filament/src/Engine.cpp @@ -196,6 +196,61 @@ void Engine::destroy(Entity e) { downcast(this)->destroy(e); } +bool Engine::isValid(const BufferObject* p) { + return downcast(this)->isValid(downcast(p)); +} +bool Engine::isValid(const VertexBuffer* p) { + return downcast(this)->isValid(downcast(p)); +} +bool Engine::isValid(const Fence* p) { + return downcast(this)->isValid(downcast(p)); +} +bool Engine::isValid(const IndexBuffer* p) { + return downcast(this)->isValid(downcast(p)); +} +bool Engine::isValid(const SkinningBuffer* p) { + return downcast(this)->isValid(downcast(p)); +} +bool Engine::isValid(const MorphTargetBuffer* p) { + return downcast(this)->isValid(downcast(p)); +} +bool Engine::isValid(const IndirectLight* p) { + return downcast(this)->isValid(downcast(p)); +} +bool Engine::isValid(const Material* p) { + return downcast(this)->isValid(downcast(p)); +} +bool Engine::isValid(const Renderer* p) { + return downcast(this)->isValid(downcast(p)); +} +bool Engine::isValid(const Scene* p) { + return downcast(this)->isValid(downcast(p)); +} +bool Engine::isValid(const Skybox* p) { + return downcast(this)->isValid(downcast(p)); +} +bool Engine::isValid(const ColorGrading* p) { + return downcast(this)->isValid(downcast(p)); +} +bool Engine::isValid(const SwapChain* p) { + return downcast(this)->isValid(downcast(p)); +} +bool Engine::isValid(const Stream* p) { + return downcast(this)->isValid(downcast(p)); +} +bool Engine::isValid(const Texture* p) { + return downcast(this)->isValid(downcast(p)); +} +bool Engine::isValid(const RenderTarget* p) { + return downcast(this)->isValid(downcast(p)); +} +bool Engine::isValid(const View* p) { + return downcast(this)->isValid(downcast(p)); +} +bool Engine::isValid(const InstanceBuffer* p) { + return downcast(this)->isValid(downcast(p)); +} + void Engine::flushAndWait() { downcast(this)->flushAndWait(); } diff --git a/filament/src/ResourceList.cpp b/filament/src/ResourceList.cpp index b8e8c8f661..4579ed8a32 100644 --- a/filament/src/ResourceList.cpp +++ b/filament/src/ResourceList.cpp @@ -45,12 +45,15 @@ bool ResourceListBase::remove(void const* item) { return mList.erase(const_cast(item)) > 0; } +auto ResourceListBase::find(void const* item) -> iterator { + return mList.find(const_cast(item)); +} void ResourceListBase::clear() noexcept { mList.clear(); } -// this is not inlined so we don't pay the code-size cost of iterating the list +// this is not inlined, so we don't pay the code-size cost of iterating the list void ResourceListBase::forEach(void (* f)(void*, void*), void* user) const noexcept { std::for_each(mList.begin(), mList.end(), [=](void* p) { f(user, p); diff --git a/filament/src/ResourceList.h b/filament/src/ResourceList.h index 188a5925fe..1bdf188a56 100644 --- a/filament/src/ResourceList.h +++ b/filament/src/ResourceList.h @@ -38,6 +38,8 @@ public: bool remove(void const* item); + iterator find(void const* item); + void clear() noexcept; bool empty() const noexcept { @@ -76,9 +78,12 @@ public: using ResourceListBase::forEach; using ResourceListBase::insert; using ResourceListBase::remove; + using ResourceListBase::find; using ResourceListBase::empty; using ResourceListBase::size; using ResourceListBase::clear; + using ResourceListBase::begin; + using ResourceListBase::end; explicit ResourceList(const char* name) noexcept: ResourceListBase(name) {} diff --git a/filament/src/details/Engine.cpp b/filament/src/details/Engine.cpp index 4ebb359ef0..76e2d3d6b1 100644 --- a/filament/src/details/Engine.cpp +++ b/filament/src/details/Engine.cpp @@ -852,6 +852,12 @@ void FEngine::cleanupResourceListLocked(Lock& lock, ResourceList&& list) { // ----------------------------------------------------------------------------------------------- +template +UTILS_ALWAYS_INLINE +inline bool FEngine::isValid(const T* ptr, ResourceList& list) { + return list.find(ptr) != list.end(); +} + template UTILS_ALWAYS_INLINE inline bool FEngine::terminateAndDestroy(const T* ptr, ResourceList& list) { @@ -1019,6 +1025,79 @@ void FEngine::destroy(Entity e) { mCameraManager.destroy(e); } +bool FEngine::isValid(const FBufferObject* p) { + return isValid(p, mBufferObjects); +} + +bool FEngine::isValid(const FVertexBuffer* p) { + return isValid(p, mVertexBuffers); +} + +bool FEngine::isValid(const FFence* p) { + return isValid(p, mFences); +} + +bool FEngine::isValid(const FIndexBuffer* p) { + return isValid(p, mIndexBuffers); +} + +bool FEngine::isValid(const FSkinningBuffer* p) { + return isValid(p, mSkinningBuffers); +} + +bool FEngine::isValid(const FMorphTargetBuffer* p) { + return isValid(p, mMorphTargetBuffers); +} + +bool FEngine::isValid(const FIndirectLight* p) { + return isValid(p, mIndirectLights); +} + +bool FEngine::isValid(const FMaterial* p) { + return isValid(p, mMaterials); +} + +bool FEngine::isValid(const FRenderer* p) { + return isValid(p, mRenderers); +} + +bool FEngine::isValid(const FScene* p) { + return isValid(p, mScenes); +} + +bool FEngine::isValid(const FSkybox* p) { + return isValid(p, mSkyboxes); +} + +bool FEngine::isValid(const FColorGrading* p) { + return isValid(p, mColorGradings); +} + +bool FEngine::isValid(const FSwapChain* p) { + return isValid(p, mSwapChains); +} + +bool FEngine::isValid(const FStream* p) { + return isValid(p, mStreams); +} + +bool FEngine::isValid(const FTexture* p) { + return isValid(p, mTextures); +} + +bool FEngine::isValid(const FRenderTarget* p) { + return isValid(p, mRenderTargets); +} + +bool FEngine::isValid(const FView* p) { + return isValid(p, mViews); +} + +bool FEngine::isValid(const FInstanceBuffer* p) { + return isValid(p, mInstanceBuffers); +} + + void* FEngine::streamAlloc(size_t size, size_t alignment) noexcept { // we allow this only for small allocations if (size > 65536) { diff --git a/filament/src/details/Engine.h b/filament/src/details/Engine.h index fdb4d3a3a7..c9c10471fa 100644 --- a/filament/src/details/Engine.h +++ b/filament/src/details/Engine.h @@ -293,6 +293,26 @@ public: bool destroy(const FView* p); bool destroy(const FInstanceBuffer* p); + bool isValid(const FBufferObject* p); + bool isValid(const FVertexBuffer* p); + bool isValid(const FFence* p); + bool isValid(const FIndexBuffer* p); + bool isValid(const FSkinningBuffer* p); + bool isValid(const FMorphTargetBuffer* p); + bool isValid(const FIndirectLight* p); + bool isValid(const FMaterial* p); + bool isValid(const FMaterialInstance* p); + bool isValid(const FRenderer* p); + bool isValid(const FScene* p); + bool isValid(const FSkybox* p); + bool isValid(const FColorGrading* p); + bool isValid(const FSwapChain* p); + bool isValid(const FStream* p); + bool isValid(const FTexture* p); + bool isValid(const FRenderTarget* p); + bool isValid(const FView* p); + bool isValid(const FInstanceBuffer* p); + void destroy(utils::Entity e); void flushAndWait(); @@ -392,6 +412,9 @@ private: backend::Driver& getDriver() const noexcept { return *mDriver; } + template + bool isValid(const T* ptr, ResourceList& list); + template bool terminateAndDestroy(const T* p, ResourceList& list); diff --git a/web/filament-js/jsbindings.cpp b/web/filament-js/jsbindings.cpp index 1163410545..ce4401e976 100644 --- a/web/filament-js/jsbindings.cpp +++ b/web/filament-js/jsbindings.cpp @@ -540,7 +540,53 @@ class_("Engine") /// vb ::argument:: the [VertexBuffer] to destroy .function("destroyVertexBuffer", (void (*)(Engine*, VertexBuffer*)) [] (Engine* engine, VertexBuffer* vb) { engine->destroy(vb); }, - allow_raw_pointers()); + allow_raw_pointers()) + + .function("isValidRenderer", EMBIND_LAMBDA(bool, (Engine* engine, Renderer* object), { + return engine->isValid(object); + }), allow_raw_pointers()) + .function("isValidView", EMBIND_LAMBDA(bool, (Engine* engine, View* object), { + return engine->isValid(object); + }), allow_raw_pointers()) + .function("isValidScene", EMBIND_LAMBDA(bool, (Engine* engine, Scene* object), { + return engine->isValid(object); + }), allow_raw_pointers()) + .function("isValidFence", EMBIND_LAMBDA(bool, (Engine* engine, Fence* object), { + return engine->isValid(object); + }), allow_raw_pointers()) + .function("isValidStream", EMBIND_LAMBDA(bool, (Engine* engine, Stream* object), { + return engine->isValid(object); + }), allow_raw_pointers()) + .function("isValidIndexBuffer", EMBIND_LAMBDA(bool, (Engine* engine, IndexBuffer* object), { + return engine->isValid(object); + }), allow_raw_pointers()) + .function("isValidVertexBuffer", EMBIND_LAMBDA(bool, (Engine* engine, VertexBuffer* object), { + return engine->isValid(object); + }), allow_raw_pointers()) + .function("isValidSkinningBuffer", EMBIND_LAMBDA(bool, (Engine* engine, SkinningBuffer* object), { + return engine->isValid(object); + }), allow_raw_pointers()) + .function("isValidIndirectLight", EMBIND_LAMBDA(bool, (Engine* engine, IndirectLight* object), { + return engine->isValid(object); + }), allow_raw_pointers()) + .function("isValidMaterial", EMBIND_LAMBDA(bool, (Engine* engine, Material* object), { + return engine->isValid(object); + }), allow_raw_pointers()) + .function("isValidSkybox", EMBIND_LAMBDA(bool, (Engine* engine, Skybox* object), { + return engine->isValid(object); + }), allow_raw_pointers()) + .function("isValidColorGrading", EMBIND_LAMBDA(bool, (Engine* engine, ColorGrading* object), { + return engine->isValid(object); + }), allow_raw_pointers()) + .function("isValidTexture", EMBIND_LAMBDA(bool, (Engine* engine, Texture* object), { + return engine->isValid(object); + }), allow_raw_pointers()) + .function("isValidRenderTarget", EMBIND_LAMBDA(bool, (Engine* engine, RenderTarget* object), { + return engine->isValid(object); + }), allow_raw_pointers()) + .function("isValidSwapChain", EMBIND_LAMBDA(bool, (Engine* engine, SwapChain* object), { + return engine->isValid(object); + }), allow_raw_pointers()); /// SwapChain ::core class:: Represents the platform's native rendering surface. /// See also the [Engine] methods `createSwapChain` and `destroySwapChain`.