From d194eec0ad74dd4f81d27f8accf09aede0a6fe60 Mon Sep 17 00:00:00 2001 From: Pixelflinger Date: Fri, 8 May 2020 02:15:57 -0700 Subject: [PATCH] report to java when an object can't be destroyed The JNI layer already does this, but can only track objects it created, sometimes developers might create filament objects on the native side and wrap them into java objects and this might cause a failure to detected when objects are double-destroyed. However, this can often be caught by the native code -- so, when the native side is asked to destroy an object that doesn't exist, we now return an error (exception if enabled) and we throw an exception on the java side. Filament typically doesn't do this kind of tests, however these bugs can be very hard to find, and the cost is small. --- .../filament-android/src/main/cpp/Engine.cpp | 59 +++--- .../com/google/android/filament/Engine.java | 60 ++++--- filament/include/filament/Engine.h | 28 +-- filament/src/Engine.cpp | 170 +++++++++--------- filament/src/details/Engine.h | 31 ++-- 5 files changed, 175 insertions(+), 173 deletions(-) diff --git a/android/filament-android/src/main/cpp/Engine.cpp b/android/filament-android/src/main/cpp/Engine.cpp index 2ebbc10ed3..bb3d75d340 100644 --- a/android/filament-android/src/main/cpp/Engine.cpp +++ b/android/filament-android/src/main/cpp/Engine.cpp @@ -76,12 +76,12 @@ Java_com_google_android_filament_Engine_nCreateSwapChainFromRawPointer(JNIEnv*, return (jlong) engine->createSwapChain((void*)pointer, (uint64_t) flags); } -extern "C" JNIEXPORT void JNICALL +extern "C" JNIEXPORT jboolean JNICALL Java_com_google_android_filament_Engine_nDestroySwapChain(JNIEnv*, jclass, jlong nativeEngine, jlong nativeSwapChain) { Engine* engine = (Engine*) nativeEngine; SwapChain *swapChain = (SwapChain *) nativeSwapChain; - engine->destroy(swapChain); + return engine->destroy(swapChain); } // View @@ -93,12 +93,12 @@ Java_com_google_android_filament_Engine_nCreateView(JNIEnv*, jclass, return (jlong) engine->createView(); } -extern "C" JNIEXPORT void JNICALL +extern "C" JNIEXPORT jboolean JNICALL Java_com_google_android_filament_Engine_nDestroyView(JNIEnv*, jclass, jlong nativeEngine, jlong nativeView) { Engine* engine = (Engine*) nativeEngine; View *view = (View *) nativeView; - engine->destroy(view); + return engine->destroy(view); } // Renderer @@ -110,12 +110,12 @@ Java_com_google_android_filament_Engine_nCreateRenderer(JNIEnv*, jclass, return (jlong) engine->createRenderer(); } -extern "C" JNIEXPORT void JNICALL +extern "C" JNIEXPORT jboolean JNICALL Java_com_google_android_filament_Engine_nDestroyRenderer(JNIEnv*, jclass, jlong nativeEngine, jlong nativeRenderer) { Engine* engine = (Engine*) nativeEngine; Renderer *renderer = (Renderer *) nativeRenderer; - engine->destroy(renderer); + return engine->destroy(renderer); } // Camera @@ -152,12 +152,12 @@ Java_com_google_android_filament_Engine_nCreateScene(JNIEnv*, jclass, return (jlong) engine->createScene(); } -extern "C" JNIEXPORT void JNICALL +extern "C" JNIEXPORT jboolean JNICALL Java_com_google_android_filament_Engine_nDestroyScene(JNIEnv*, jclass, jlong nativeEngine, jlong nativeScene) { Engine* engine = (Engine*) nativeEngine; Scene *scene = (Scene *) nativeScene; - engine->destroy(scene); + return engine->destroy(scene); } // Fence @@ -169,89 +169,88 @@ Java_com_google_android_filament_Engine_nCreateFence(JNIEnv*, jclass, return (jlong) engine->createFence(); } -extern "C" JNIEXPORT void JNICALL +extern "C" JNIEXPORT jboolean JNICALL Java_com_google_android_filament_Engine_nDestroyFence(JNIEnv*, jclass, jlong nativeEngine, jlong nativeFence) { Engine* engine = (Engine*) nativeEngine; Fence *fence = (Fence *) nativeFence; - engine->destroy(fence); + return engine->destroy(fence); } // Stream -extern "C" JNIEXPORT void JNICALL +extern "C" JNIEXPORT jboolean JNICALL Java_com_google_android_filament_Engine_nDestroyStream(JNIEnv*, jclass, jlong nativeEngine, jlong nativeStream) { Engine* engine = (Engine*) nativeEngine; Stream *stream = (Stream *) nativeStream; - engine->destroy(stream); + return engine->destroy(stream); } // Others... -extern "C" JNIEXPORT void JNICALL +extern "C" JNIEXPORT jboolean JNICALL Java_com_google_android_filament_Engine_nDestroyIndexBuffer(JNIEnv*, jclass, jlong nativeEngine, jlong nativeIndexBuffer) { Engine* engine = (Engine*) nativeEngine; IndexBuffer *indexBuffer = (IndexBuffer *) nativeIndexBuffer; - engine->destroy(indexBuffer); + return engine->destroy(indexBuffer); } -extern "C" JNIEXPORT void JNICALL +extern "C" JNIEXPORT jboolean JNICALL Java_com_google_android_filament_Engine_nDestroyVertexBuffer(JNIEnv*, jclass, jlong nativeEngine, jlong nativeVertexBuffer) { Engine* engine = (Engine*) nativeEngine; VertexBuffer *vertexBuffer = (VertexBuffer *) nativeVertexBuffer; - engine->destroy(vertexBuffer); + return engine->destroy(vertexBuffer); } -extern "C" JNIEXPORT void JNICALL +extern "C" JNIEXPORT jboolean JNICALL Java_com_google_android_filament_Engine_nDestroyIndirectLight(JNIEnv*, jclass, jlong nativeEngine, jlong nativeIndirectLight) { Engine* engine = (Engine*) nativeEngine; IndirectLight *indirectLight = (IndirectLight *) nativeIndirectLight; - engine->destroy(indirectLight); + return engine->destroy(indirectLight); } -extern "C" JNIEXPORT void JNICALL +extern "C" JNIEXPORT jboolean JNICALL Java_com_google_android_filament_Engine_nDestroyMaterial(JNIEnv*, jclass, jlong nativeEngine, jlong nativeMaterial) { Engine* engine = (Engine*) nativeEngine; Material *material = (Material *) nativeMaterial; - engine->destroy(material); + return engine->destroy(material); } -extern "C" JNIEXPORT void JNICALL +extern "C" JNIEXPORT jboolean JNICALL Java_com_google_android_filament_Engine_nDestroyMaterialInstance(JNIEnv*, jclass, jlong nativeEngine, jlong nativeMaterialInstance) { Engine* engine = (Engine*) nativeEngine; - MaterialInstance* materialInstance = - (MaterialInstance*) nativeMaterialInstance; - engine->destroy(materialInstance); + MaterialInstance* materialInstance = (MaterialInstance*) nativeMaterialInstance; + return engine->destroy(materialInstance); } -extern "C" JNIEXPORT void JNICALL +extern "C" JNIEXPORT jboolean JNICALL Java_com_google_android_filament_Engine_nDestroySkybox(JNIEnv*, jclass, jlong nativeEngine, jlong nativeSkybox) { Engine* engine = (Engine*) nativeEngine; Skybox *skybox = (Skybox *) nativeSkybox; - engine->destroy(skybox); + return engine->destroy(skybox); } -extern "C" JNIEXPORT void JNICALL +extern "C" JNIEXPORT jboolean JNICALL Java_com_google_android_filament_Engine_nDestroyTexture(JNIEnv*, jclass, jlong nativeEngine, jlong nativeTexture) { Engine* engine = (Engine*) nativeEngine; Texture *texture = (Texture *) nativeTexture; - engine->destroy(texture); + return engine->destroy(texture); } -extern "C" JNIEXPORT void JNICALL +extern "C" JNIEXPORT jboolean JNICALL Java_com_google_android_filament_Engine_nDestroyRenderTarget(JNIEnv*, jclass, jlong nativeEngine, jlong nativeTarget) { Engine* engine = (Engine*) nativeEngine; RenderTarget* target = (RenderTarget*) nativeTarget; - engine->destroy(target); + return engine->destroy(target); } extern "C" JNIEXPORT void JNICALL 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 135b8fb6d7..c68657d78e 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 @@ -344,7 +344,7 @@ public class Engine { * @param swapChain the {@link SwapChain} to destroy */ public void destroySwapChain(@NonNull SwapChain swapChain) { - nDestroySwapChain(getNativeObject(), swapChain.getNativeObject()); + assertDestroy(nDestroySwapChain(getNativeObject(), swapChain.getNativeObject())); swapChain.clearNativeObject(); } @@ -367,7 +367,7 @@ public class Engine { * @param view the {@link View} to destroy */ public void destroyView(@NonNull View view) { - nDestroyView(getNativeObject(), view.getNativeObject()); + assertDestroy(nDestroyView(getNativeObject(), view.getNativeObject())); view.clearNativeObject(); } @@ -390,7 +390,7 @@ public class Engine { * @param renderer the {@link Renderer} to destroy */ public void destroyRenderer(@NonNull Renderer renderer) { - nDestroyRenderer(getNativeObject(), renderer.getNativeObject()); + assertDestroy(nDestroyRenderer(getNativeObject(), renderer.getNativeObject())); renderer.clearNativeObject(); } @@ -451,7 +451,7 @@ public class Engine { * @param scene the {@link Scene} to destroy */ public void destroyScene(@NonNull Scene scene) { - nDestroyScene(getNativeObject(), scene.getNativeObject()); + assertDestroy(nDestroyScene(getNativeObject(), scene.getNativeObject())); scene.clearNativeObject(); } @@ -462,7 +462,7 @@ public class Engine { * @param stream the {@link Stream} to destroy */ public void destroyStream(@NonNull Stream stream) { - nDestroyStream(getNativeObject(), stream.getNativeObject()); + assertDestroy(nDestroyStream(getNativeObject(), stream.getNativeObject())); stream.clearNativeObject(); } @@ -485,7 +485,7 @@ public class Engine { * @param fence the {@link Fence} to destroy */ public void destroyFence(@NonNull Fence fence) { - nDestroyFence(getNativeObject(), fence.getNativeObject()); + assertDestroy(nDestroyFence(getNativeObject(), fence.getNativeObject())); fence.clearNativeObject(); } @@ -496,7 +496,7 @@ public class Engine { * @param indexBuffer the {@link IndexBuffer} to destroy */ public void destroyIndexBuffer(@NonNull IndexBuffer indexBuffer) { - nDestroyIndexBuffer(getNativeObject(), indexBuffer.getNativeObject()); + assertDestroy(nDestroyIndexBuffer(getNativeObject(), indexBuffer.getNativeObject())); indexBuffer.clearNativeObject(); } @@ -505,7 +505,7 @@ public class Engine { * @param vertexBuffer the {@link VertexBuffer} to destroy */ public void destroyVertexBuffer(@NonNull VertexBuffer vertexBuffer) { - nDestroyVertexBuffer(getNativeObject(), vertexBuffer.getNativeObject()); + assertDestroy(nDestroyVertexBuffer(getNativeObject(), vertexBuffer.getNativeObject())); vertexBuffer.clearNativeObject(); } @@ -514,7 +514,7 @@ public class Engine { * @param ibl the {@link IndirectLight} to destroy */ public void destroyIndirectLight(@NonNull IndirectLight ibl) { - nDestroyIndirectLight(getNativeObject(), ibl.getNativeObject()); + assertDestroy(nDestroyIndirectLight(getNativeObject(), ibl.getNativeObject())); ibl.clearNativeObject(); } @@ -527,7 +527,7 @@ public class Engine { * @param material the {@link Material} to destroy */ public void destroyMaterial(@NonNull Material material) { - nDestroyMaterial(getNativeObject(), material.getNativeObject()); + assertDestroy(nDestroyMaterial(getNativeObject(), material.getNativeObject())); material.clearNativeObject(); } @@ -536,7 +536,7 @@ public class Engine { * @param materialInstance the {@link MaterialInstance} to destroy */ public void destroyMaterialInstance(@NonNull MaterialInstance materialInstance) { - nDestroyMaterialInstance(getNativeObject(), materialInstance.getNativeObject()); + assertDestroy(nDestroyMaterialInstance(getNativeObject(), materialInstance.getNativeObject())); materialInstance.clearNativeObject(); } @@ -545,7 +545,7 @@ public class Engine { * @param skybox the {@link Skybox} to destroy */ public void destroySkybox(@NonNull Skybox skybox) { - nDestroySkybox(getNativeObject(), skybox.getNativeObject()); + assertDestroy(nDestroySkybox(getNativeObject(), skybox.getNativeObject())); skybox.clearNativeObject(); } @@ -554,7 +554,7 @@ public class Engine { * @param texture the {@link Texture} to destroy */ public void destroyTexture(@NonNull Texture texture) { - nDestroyTexture(getNativeObject(), texture.getNativeObject()); + assertDestroy(nDestroyTexture(getNativeObject(), texture.getNativeObject())); texture.clearNativeObject(); } @@ -634,33 +634,39 @@ public class Engine { mNativeObject = 0; } + private static void assertDestroy(boolean success) { + if (!success) { + throw new IllegalStateException("Object couldn't be destoyed (double destroy()?)"); + } + } + private static native long nCreateEngine(long backend, long sharedContext); private static native void nDestroyEngine(long nativeEngine); private static native long nGetBackend(long nativeEngine); 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 void nDestroySwapChain(long nativeEngine, long nativeSwapChain); + private static native boolean nDestroySwapChain(long nativeEngine, long nativeSwapChain); private static native long nCreateView(long nativeEngine); - private static native void nDestroyView(long nativeEngine, long nativeView); + private static native boolean nDestroyView(long nativeEngine, long nativeView); private static native long nCreateRenderer(long nativeEngine); - private static native void nDestroyRenderer(long nativeEngine, long nativeRenderer); + private static native boolean nDestroyRenderer(long nativeEngine, long nativeRenderer); private static native long nCreateCamera(long nativeEngine); private static native long nCreateCameraWithEntity(long nativeEngine, int entity); private static native void nDestroyCamera(long nativeEngine, long nativeCamera); private static native long nCreateScene(long nativeEngine); - private static native void nDestroyScene(long nativeEngine, long nativeScene); + private static native boolean nDestroyScene(long nativeEngine, long nativeScene); private static native long nCreateFence(long nativeEngine); - private static native void nDestroyFence(long nativeEngine, long nativeFence); - private static native void nDestroyStream(long nativeEngine, long nativeStream); - private static native void nDestroyIndexBuffer(long nativeEngine, long nativeIndexBuffer); - private static native void nDestroyVertexBuffer(long nativeEngine, long nativeVertexBuffer); - private static native void nDestroyIndirectLight(long nativeEngine, long nativeIndirectLight); - private static native void nDestroyMaterial(long nativeEngine, long nativeMaterial); - private static native void nDestroyMaterialInstance(long nativeEngine, long nativeMaterialInstance); - private static native void nDestroySkybox(long nativeEngine, long nativeSkybox); - private static native void nDestroyTexture(long nativeEngine, long nativeTexture); - private static native void nDestroyRenderTarget(long nativeEngine, long nativeTarget); + 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); + private static native boolean nDestroyVertexBuffer(long nativeEngine, long nativeVertexBuffer); + private static native boolean nDestroyIndirectLight(long nativeEngine, long nativeIndirectLight); + private static native boolean nDestroyMaterial(long nativeEngine, long nativeMaterial); + private static native boolean nDestroyMaterialInstance(long nativeEngine, long nativeMaterialInstance); + private static native boolean nDestroySkybox(long nativeEngine, long nativeSkybox); + private static native boolean nDestroyTexture(long nativeEngine, long nativeTexture); + private static native boolean nDestroyRenderTarget(long nativeEngine, long nativeTarget); 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 29592dfa58..63ef6f375b 100644 --- a/filament/include/filament/Engine.h +++ b/filament/include/filament/Engine.h @@ -329,10 +329,10 @@ public: */ Fence* createFence() noexcept; - void destroy(const VertexBuffer* p); //!< Destroys an VertexBuffer object. - void destroy(const Fence* p); //!< Destroys a Fence object. - void destroy(const IndexBuffer* p); //!< Destroys an IndexBuffer object. - void destroy(const IndirectLight* p); //!< Destroys an IndirectLight object. + bool destroy(const VertexBuffer* p); //!< Destroys an VertexBuffer object. + bool destroy(const Fence* p); //!< Destroys a Fence object. + bool destroy(const IndexBuffer* p); //!< Destroys an IndexBuffer object. + bool destroy(const IndirectLight* p); //!< Destroys an IndirectLight object. /** * Destroys a Material object @@ -342,16 +342,16 @@ public: * @exception utils::PreConditionPanic is thrown if some MaterialInstances remain. * no-op if exceptions are disabled and some MaterialInstances remain. */ - void destroy(const Material* p); - void destroy(const MaterialInstance* p); //!< Destroys a MaterialInstance object. - void destroy(const Renderer* p); //!< Destroys a Renderer object. - void destroy(const Scene* p); //!< Destroys a Scene object. - void destroy(const Skybox* p); //!< Destroys a SkyBox object. - void destroy(const SwapChain* p); //!< Destroys a SwapChain object. - void destroy(const Stream* p); //!< Destroys a Stream object. - void destroy(const Texture* p); //!< Destroys a Texture object. - void destroy(const RenderTarget* p); //!< Destroys a RenderTarget object. - void destroy(const View* p); //!< Destroys a View object. + bool destroy(const Material* p); + bool destroy(const MaterialInstance* p); //!< Destroys a MaterialInstance object. + bool destroy(const Renderer* p); //!< Destroys a Renderer object. + bool destroy(const Scene* p); //!< Destroys a Scene object. + bool destroy(const Skybox* p); //!< Destroys a SkyBox object. + bool destroy(const SwapChain* p); //!< Destroys a SwapChain object. + bool destroy(const Stream* p); //!< Destroys a Stream object. + bool destroy(const Texture* p); //!< Destroys a Texture object. + bool destroy(const RenderTarget* p); //!< Destroys a RenderTarget object. + bool destroy(const View* p); //!< Destroys a View object. void destroy(utils::Entity e); //!< Destroys all filament-known components from this entity /** diff --git a/filament/src/Engine.cpp b/filament/src/Engine.cpp index 99ef2f331c..eb56f872ce 100644 --- a/filament/src/Engine.cpp +++ b/filament/src/Engine.cpp @@ -659,99 +659,95 @@ void FEngine::cleanupResourceList(ResourceList& list) { // ----------------------------------------------------------------------------------------------- template -void FEngine::terminateAndDestroy(const T* ptr, ResourceList& list) { - if (ptr != nullptr) { - if (list.remove(ptr)) { - const_cast(ptr)->terminate(*this); - mHeapAllocator.destroy(const_cast(ptr)); - } else { - // object not found, do nothing and log an error on DEBUG builds. -#ifndef NDEBUG - slog.d << "object " - << CallStack::typeName().c_str() - << " at " << ptr << " doesn't exist!" - << io::endl; -#endif - } +bool FEngine::terminateAndDestroy(const T* ptr, ResourceList& list) { + if (ptr == nullptr) return true; + bool success = list.remove(ptr); + if (ASSERT_PRECONDITION_NON_FATAL(success, + "Object %s at %p doesn't exist (double free?)", + CallStack::typeName().c_str(), ptr)) { + const_cast(ptr)->terminate(*this); + mHeapAllocator.destroy(const_cast(ptr)); } + return success; } // ----------------------------------------------------------------------------------------------- -void FEngine::destroy(const FVertexBuffer* p) { - terminateAndDestroy(p, mVertexBuffers); +bool FEngine::destroy(const FVertexBuffer* p) { + return terminateAndDestroy(p, mVertexBuffers); } -void FEngine::destroy(const FIndexBuffer* p) { - terminateAndDestroy(p, mIndexBuffers); +bool FEngine::destroy(const FIndexBuffer* p) { + return terminateAndDestroy(p, mIndexBuffers); } -inline void FEngine::destroy(const FRenderer* p) { - terminateAndDestroy(p, mRenderers); +inline bool FEngine::destroy(const FRenderer* p) { + return terminateAndDestroy(p, mRenderers); } -inline void FEngine::destroy(const FScene* p) { - terminateAndDestroy(p, mScenes); +inline bool FEngine::destroy(const FScene* p) { + return terminateAndDestroy(p, mScenes); } -inline void FEngine::destroy(const FSkybox* p) { - terminateAndDestroy(p, mSkyboxes); +inline bool FEngine::destroy(const FSkybox* p) { + return terminateAndDestroy(p, mSkyboxes); } UTILS_NOINLINE -void FEngine::destroy(const FTexture* p) { - terminateAndDestroy(p, mTextures); +bool FEngine::destroy(const FTexture* p) { + return terminateAndDestroy(p, mTextures); } -void FEngine::destroy(const FRenderTarget* p) { - terminateAndDestroy(p, mRenderTargets); +bool FEngine::destroy(const FRenderTarget* p) { + return terminateAndDestroy(p, mRenderTargets); } -inline void FEngine::destroy(const FView* p) { - terminateAndDestroy(p, mViews); +inline bool FEngine::destroy(const FView* p) { + return terminateAndDestroy(p, mViews); } -inline void FEngine::destroy(const FIndirectLight* p) { - terminateAndDestroy(p, mIndirectLights); +inline bool FEngine::destroy(const FIndirectLight* p) { + return terminateAndDestroy(p, mIndirectLights); } UTILS_NOINLINE -void FEngine::destroy(const FFence* p) { - terminateAndDestroy(p, mFences); +bool FEngine::destroy(const FFence* p) { + return terminateAndDestroy(p, mFences); } -void FEngine::destroy(const FSwapChain* p) { - terminateAndDestroy(p, mSwapChains); +bool FEngine::destroy(const FSwapChain* p) { + return terminateAndDestroy(p, mSwapChains); } -void FEngine::destroy(const FStream* p) { - terminateAndDestroy(p, mStreams); +bool FEngine::destroy(const FStream* p) { + return terminateAndDestroy(p, mStreams); } -void FEngine::destroy(const FMaterial* ptr) { - if (ptr != nullptr) { - auto pos = mMaterialInstances.find(ptr); - if (pos != mMaterialInstances.cend()) { - // ensure we've destroyed all instances before destroying the material - if (!ASSERT_PRECONDITION_NON_FATAL(pos->second.empty(), - "destroying material \"%s\" but %u instances still alive", - ptr->getName().c_str(), (*pos).second.size())) { - return; - } - } - terminateAndDestroy(ptr, mMaterials); - } -} - -void FEngine::destroy(const FMaterialInstance* ptr) { - if (ptr != nullptr) { - auto pos = mMaterialInstances.find(ptr->getMaterial()); - assert(pos != mMaterialInstances.cend()); - if (pos != mMaterialInstances.cend()) { - terminateAndDestroy(ptr, pos->second); +bool FEngine::destroy(const FMaterial* ptr) { + if (ptr == nullptr) return true; + auto pos = mMaterialInstances.find(ptr); + if (pos != mMaterialInstances.cend()) { + // ensure we've destroyed all instances before destroying the material + if (!ASSERT_PRECONDITION_NON_FATAL(pos->second.empty(), + "destroying material \"%s\" but %u instances still alive", + ptr->getName().c_str(), (*pos).second.size())) { + return false; } } + return terminateAndDestroy(ptr, mMaterials); +} + +bool FEngine::destroy(const FMaterialInstance* ptr) { + if (ptr == nullptr) return true; + auto pos = mMaterialInstances.find(ptr->getMaterial()); + assert(pos != mMaterialInstances.cend()); + if (pos != mMaterialInstances.cend()) { + return terminateAndDestroy(ptr, pos->second); + } + // if we don't find this instance's material it might be because it's the default instance + // in which case it fine to ignore. + return true; } void FEngine::destroy(Entity e) { @@ -867,60 +863,60 @@ SwapChain* Engine::createSwapChain(uint32_t width, uint32_t height, uint64_t fla return upcast(this)->createSwapChain(width, height, flags); } -void Engine::destroy(const VertexBuffer* p) { - upcast(this)->destroy(upcast(p)); +bool Engine::destroy(const VertexBuffer* p) { + return upcast(this)->destroy(upcast(p)); } -void Engine::destroy(const IndexBuffer* p) { - upcast(this)->destroy(upcast(p)); +bool Engine::destroy(const IndexBuffer* p) { + return upcast(this)->destroy(upcast(p)); } -void Engine::destroy(const IndirectLight* p) { - upcast(this)->destroy(upcast(p)); +bool Engine::destroy(const IndirectLight* p) { + return upcast(this)->destroy(upcast(p)); } -void Engine::destroy(const Material* p) { - upcast(this)->destroy(upcast(p)); +bool Engine::destroy(const Material* p) { + return upcast(this)->destroy(upcast(p)); } -void Engine::destroy(const MaterialInstance* p) { - upcast(this)->destroy(upcast(p)); +bool Engine::destroy(const MaterialInstance* p) { + return upcast(this)->destroy(upcast(p)); } -void Engine::destroy(const Renderer* p) { - upcast(this)->destroy(upcast(p)); +bool Engine::destroy(const Renderer* p) { + return upcast(this)->destroy(upcast(p)); } -void Engine::destroy(const View* p) { - upcast(this)->destroy(upcast(p)); +bool Engine::destroy(const View* p) { + return upcast(this)->destroy(upcast(p)); } -void Engine::destroy(const Scene* p) { - upcast(this)->destroy(upcast(p)); +bool Engine::destroy(const Scene* p) { + return upcast(this)->destroy(upcast(p)); } -void Engine::destroy(const Skybox* p) { - upcast(this)->destroy(upcast(p)); +bool Engine::destroy(const Skybox* p) { + return upcast(this)->destroy(upcast(p)); } -void Engine::destroy(const Stream* p) { - upcast(this)->destroy(upcast(p)); +bool Engine::destroy(const Stream* p) { + return upcast(this)->destroy(upcast(p)); } -void Engine::destroy(const Texture* p) { - upcast(this)->destroy(upcast(p)); +bool Engine::destroy(const Texture* p) { + return upcast(this)->destroy(upcast(p)); } -void Engine::destroy(const RenderTarget* p) { - upcast(this)->destroy(upcast(p)); +bool Engine::destroy(const RenderTarget* p) { + return upcast(this)->destroy(upcast(p)); } -void Engine::destroy(const Fence* p) { - upcast(this)->destroy(upcast(p)); +bool Engine::destroy(const Fence* p) { + return upcast(this)->destroy(upcast(p)); } -void Engine::destroy(const SwapChain* p) { - upcast(this)->destroy(upcast(p)); +bool Engine::destroy(const SwapChain* p) { + return upcast(this)->destroy(upcast(p)); } void Engine::destroy(Entity e) { diff --git a/filament/src/details/Engine.h b/filament/src/details/Engine.h index 81fce37ef5..77db80872d 100644 --- a/filament/src/details/Engine.h +++ b/filament/src/details/Engine.h @@ -243,20 +243,21 @@ public: void destroyCameraComponent(utils::Entity entity) noexcept; - void destroy(const FVertexBuffer* p); - void destroy(const FFence* p); - void destroy(const FIndexBuffer* p); - void destroy(const FIndirectLight* p); - void destroy(const FMaterial* p); - void destroy(const FMaterialInstance* p); - void destroy(const FRenderer* p); - void destroy(const FScene* p); - void destroy(const FSkybox* p); - void destroy(const FStream* p); - void destroy(const FTexture* p); - void destroy(const FRenderTarget* p); - void destroy(const FSwapChain* p); - void destroy(const FView* p); + bool destroy(const FVertexBuffer* p); + bool destroy(const FFence* p); + bool destroy(const FIndexBuffer* p); + bool destroy(const FIndirectLight* p); + bool destroy(const FMaterial* p); + bool destroy(const FMaterialInstance* p); + bool destroy(const FRenderer* p); + bool destroy(const FScene* p); + bool destroy(const FSkybox* p); + bool destroy(const FStream* p); + bool destroy(const FTexture* p); + bool destroy(const FRenderTarget* p); + bool destroy(const FSwapChain* p); + bool destroy(const FView* p); + void destroy(utils::Entity e); void flushAndWait(); @@ -302,7 +303,7 @@ private: void flushCommandBuffer(backend::CommandBufferQueue& commandBufferQueue); template - void terminateAndDestroy(const T* p, ResourceList& list); + bool terminateAndDestroy(const T* p, ResourceList& list); template void cleanupResourceList(ResourceList& list);