add a couple way of validating MaterialInstances (#7754)
* add a couple way of validating MaterialInstances BUGS=[333907416] * Update filament/include/filament/Engine.h Co-authored-by: Powei Feng <powei@google.com> * Update filament/include/filament/Engine.h Co-authored-by: Powei Feng <powei@google.com> --------- Co-authored-by: Powei Feng <powei@google.com>
This commit is contained in:
@@ -342,6 +342,21 @@ Java_com_google_android_filament_Engine_nIsValidMaterial(JNIEnv*, jclass,
|
||||
return (jboolean)engine->isValid((Material*)nativeMaterial);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_Engine_nIsValidMaterialInstance(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jlong nativeMaterial, jlong nativeMaterialInstance) {
|
||||
Engine* engine = (Engine *)nativeEngine;
|
||||
return (jboolean)engine->isValid((Material*)nativeMaterial,
|
||||
(MaterialInstance*)nativeMaterialInstance);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_Engine_nIsValidExpensiveMaterialInstance(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jlong nativeMaterialInstance) {
|
||||
Engine* engine = (Engine *)nativeEngine;
|
||||
return (jboolean)engine->isValidExpensive((MaterialInstance*)nativeMaterialInstance);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_Engine_nIsValidSkybox(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jlong nativeSkybox) {
|
||||
|
||||
@@ -849,6 +849,24 @@ public class Engine {
|
||||
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 isValidMaterialInstance(@NonNull Material ma, MaterialInstance mi) {
|
||||
return nIsValidMaterialInstance(getNativeObject(), ma.getNativeObject(), mi.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 isValidExpensiveMaterialInstance(@NonNull MaterialInstance object) {
|
||||
return nIsValidExpensiveMaterialInstance(getNativeObject(), object.getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the object is valid.
|
||||
* @param object Object to check for validity
|
||||
@@ -1291,6 +1309,8 @@ public class Engine {
|
||||
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 nIsValidMaterialInstance(long nativeEngine, long nativeMaterial, long nativeMaterialInstance);
|
||||
private static native boolean nIsValidExpensiveMaterialInstance(long nativeEngine, long nativeMaterialInstance);
|
||||
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);
|
||||
|
||||
@@ -800,24 +800,51 @@ public:
|
||||
bool destroy(const InstanceBuffer* UTILS_NULLABLE p); //!< Destroys an InstanceBuffer object.
|
||||
void destroy(utils::Entity e); //!< Destroys all filament-known components from this entity
|
||||
|
||||
bool isValid(const BufferObject* UTILS_NULLABLE p); //!< Tells whether a BufferObject object is valid
|
||||
bool isValid(const VertexBuffer* UTILS_NULLABLE p); //!< Tells whether an VertexBuffer object is valid
|
||||
bool isValid(const Fence* UTILS_NULLABLE p); //!< Tells whether a Fence object is valid
|
||||
bool isValid(const IndexBuffer* UTILS_NULLABLE p); //!< Tells whether an IndexBuffer object is valid
|
||||
bool isValid(const SkinningBuffer* UTILS_NULLABLE p); //!< Tells whether a SkinningBuffer object is valid
|
||||
bool isValid(const MorphTargetBuffer* UTILS_NULLABLE p); //!< Tells whether a MorphTargetBuffer object is valid
|
||||
bool isValid(const IndirectLight* UTILS_NULLABLE p); //!< Tells whether an IndirectLight object is valid
|
||||
bool isValid(const Material* UTILS_NULLABLE p); //!< Tells whether an IndirectLight object is valid
|
||||
bool isValid(const Renderer* UTILS_NULLABLE p); //!< Tells whether a Renderer object is valid
|
||||
bool isValid(const Scene* UTILS_NULLABLE p); //!< Tells whether a Scene object is valid
|
||||
bool isValid(const Skybox* UTILS_NULLABLE p); //!< Tells whether a SkyBox object is valid
|
||||
bool isValid(const ColorGrading* UTILS_NULLABLE p); //!< Tells whether a ColorGrading object is valid
|
||||
bool isValid(const SwapChain* UTILS_NULLABLE p); //!< Tells whether a SwapChain object is valid
|
||||
bool isValid(const Stream* UTILS_NULLABLE p); //!< Tells whether a Stream object is valid
|
||||
bool isValid(const Texture* UTILS_NULLABLE p); //!< Tells whether a Texture object is valid
|
||||
bool isValid(const RenderTarget* UTILS_NULLABLE p); //!< Tells whether a RenderTarget object is valid
|
||||
bool isValid(const View* UTILS_NULLABLE p); //!< Tells whether a View object is valid
|
||||
bool isValid(const InstanceBuffer* UTILS_NULLABLE p); //!< Tells whether an InstanceBuffer object is valid
|
||||
/** Tells whether a BufferObject object is valid */
|
||||
bool isValid(const BufferObject* UTILS_NULLABLE p) const;
|
||||
/** Tells whether an VertexBuffer object is valid */
|
||||
bool isValid(const VertexBuffer* UTILS_NULLABLE p) const;
|
||||
/** Tells whether a Fence object is valid */
|
||||
bool isValid(const Fence* UTILS_NULLABLE p) const;
|
||||
/** Tells whether an IndexBuffer object is valid */
|
||||
bool isValid(const IndexBuffer* UTILS_NULLABLE p) const;
|
||||
/** Tells whether a SkinningBuffer object is valid */
|
||||
bool isValid(const SkinningBuffer* UTILS_NULLABLE p) const;
|
||||
/** Tells whether a MorphTargetBuffer object is valid */
|
||||
bool isValid(const MorphTargetBuffer* UTILS_NULLABLE p) const;
|
||||
/** Tells whether an IndirectLight object is valid */
|
||||
bool isValid(const IndirectLight* UTILS_NULLABLE p) const;
|
||||
/** Tells whether an Material object is valid */
|
||||
bool isValid(const Material* UTILS_NULLABLE p) const;
|
||||
/** Tells whether an MaterialInstance object is valid. Use this if you already know
|
||||
* which Material this MaterialInstance belongs to. DO NOT USE getMaterial(), this would
|
||||
* defeat the purpose of validating the MaterialInstance.
|
||||
*/
|
||||
bool isValid(const Material* UTILS_NONNULL m, const MaterialInstance* UTILS_NULLABLE p) const;
|
||||
/** Tells whether an MaterialInstance object is valid. Use this if the Material the
|
||||
* MaterialInstance belongs to is not known. This method can be expensive.
|
||||
*/
|
||||
bool isValidExpensive(const MaterialInstance* UTILS_NULLABLE p) const;
|
||||
/** Tells whether a Renderer object is valid */
|
||||
bool isValid(const Renderer* UTILS_NULLABLE p) const;
|
||||
/** Tells whether a Scene object is valid */
|
||||
bool isValid(const Scene* UTILS_NULLABLE p) const;
|
||||
/** Tells whether a SkyBox object is valid */
|
||||
bool isValid(const Skybox* UTILS_NULLABLE p) const;
|
||||
/** Tells whether a ColorGrading object is valid */
|
||||
bool isValid(const ColorGrading* UTILS_NULLABLE p) const;
|
||||
/** Tells whether a SwapChain object is valid */
|
||||
bool isValid(const SwapChain* UTILS_NULLABLE p) const;
|
||||
/** Tells whether a Stream object is valid */
|
||||
bool isValid(const Stream* UTILS_NULLABLE p) const;
|
||||
/** Tells whether a Texture object is valid */
|
||||
bool isValid(const Texture* UTILS_NULLABLE p) const;
|
||||
/** Tells whether a RenderTarget object is valid */
|
||||
bool isValid(const RenderTarget* UTILS_NULLABLE p) const;
|
||||
/** Tells whether a View object is valid */
|
||||
bool isValid(const View* UTILS_NULLABLE p) const;
|
||||
/** Tells whether an InstanceBuffer object is valid */
|
||||
bool isValid(const InstanceBuffer* UTILS_NULLABLE p) const;
|
||||
|
||||
/**
|
||||
* Kicks the hardware thread (e.g. the OpenGL, Vulkan or Metal thread) and blocks until
|
||||
|
||||
@@ -31,18 +31,25 @@
|
||||
#include "details/Texture.h"
|
||||
#include "details/VertexBuffer.h"
|
||||
#include "details/View.h"
|
||||
#include "filament/Engine.h"
|
||||
|
||||
#include <filament/Engine.h>
|
||||
|
||||
#include <backend/DriverEnums.h>
|
||||
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/Panic.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
using namespace utils;
|
||||
|
||||
namespace filament {
|
||||
|
||||
namespace backend {
|
||||
class Platform;
|
||||
}
|
||||
|
||||
using namespace math;
|
||||
using namespace backend;
|
||||
|
||||
@@ -196,58 +203,64 @@ void Engine::destroy(Entity e) {
|
||||
downcast(this)->destroy(e);
|
||||
}
|
||||
|
||||
bool Engine::isValid(const BufferObject* p) {
|
||||
bool Engine::isValid(const BufferObject* p) const {
|
||||
return downcast(this)->isValid(downcast(p));
|
||||
}
|
||||
bool Engine::isValid(const VertexBuffer* p) {
|
||||
bool Engine::isValid(const VertexBuffer* p) const {
|
||||
return downcast(this)->isValid(downcast(p));
|
||||
}
|
||||
bool Engine::isValid(const Fence* p) {
|
||||
bool Engine::isValid(const Fence* p) const {
|
||||
return downcast(this)->isValid(downcast(p));
|
||||
}
|
||||
bool Engine::isValid(const IndexBuffer* p) {
|
||||
bool Engine::isValid(const IndexBuffer* p) const {
|
||||
return downcast(this)->isValid(downcast(p));
|
||||
}
|
||||
bool Engine::isValid(const SkinningBuffer* p) {
|
||||
bool Engine::isValid(const SkinningBuffer* p) const {
|
||||
return downcast(this)->isValid(downcast(p));
|
||||
}
|
||||
bool Engine::isValid(const MorphTargetBuffer* p) {
|
||||
bool Engine::isValid(const MorphTargetBuffer* p) const {
|
||||
return downcast(this)->isValid(downcast(p));
|
||||
}
|
||||
bool Engine::isValid(const IndirectLight* p) {
|
||||
bool Engine::isValid(const IndirectLight* p) const {
|
||||
return downcast(this)->isValid(downcast(p));
|
||||
}
|
||||
bool Engine::isValid(const Material* p) {
|
||||
bool Engine::isValid(const Material* p) const {
|
||||
return downcast(this)->isValid(downcast(p));
|
||||
}
|
||||
bool Engine::isValid(const Renderer* p) {
|
||||
bool Engine::isValid(const Material* m, const MaterialInstance* p) const {
|
||||
return downcast(this)->isValid(downcast(m), downcast(p));
|
||||
}
|
||||
bool Engine::isValidExpensive(const MaterialInstance* p) const {
|
||||
return downcast(this)->isValidExpensive(downcast(p));
|
||||
}
|
||||
bool Engine::isValid(const Renderer* p) const {
|
||||
return downcast(this)->isValid(downcast(p));
|
||||
}
|
||||
bool Engine::isValid(const Scene* p) {
|
||||
bool Engine::isValid(const Scene* p) const {
|
||||
return downcast(this)->isValid(downcast(p));
|
||||
}
|
||||
bool Engine::isValid(const Skybox* p) {
|
||||
bool Engine::isValid(const Skybox* p) const {
|
||||
return downcast(this)->isValid(downcast(p));
|
||||
}
|
||||
bool Engine::isValid(const ColorGrading* p) {
|
||||
bool Engine::isValid(const ColorGrading* p) const {
|
||||
return downcast(this)->isValid(downcast(p));
|
||||
}
|
||||
bool Engine::isValid(const SwapChain* p) {
|
||||
bool Engine::isValid(const SwapChain* p) const {
|
||||
return downcast(this)->isValid(downcast(p));
|
||||
}
|
||||
bool Engine::isValid(const Stream* p) {
|
||||
bool Engine::isValid(const Stream* p) const {
|
||||
return downcast(this)->isValid(downcast(p));
|
||||
}
|
||||
bool Engine::isValid(const Texture* p) {
|
||||
bool Engine::isValid(const Texture* p) const {
|
||||
return downcast(this)->isValid(downcast(p));
|
||||
}
|
||||
bool Engine::isValid(const RenderTarget* p) {
|
||||
bool Engine::isValid(const RenderTarget* p) const {
|
||||
return downcast(this)->isValid(downcast(p));
|
||||
}
|
||||
bool Engine::isValid(const View* p) {
|
||||
bool Engine::isValid(const View* p) const {
|
||||
return downcast(this)->isValid(downcast(p));
|
||||
}
|
||||
bool Engine::isValid(const InstanceBuffer* p) {
|
||||
bool Engine::isValid(const InstanceBuffer* p) const {
|
||||
return downcast(this)->isValid(downcast(p));
|
||||
}
|
||||
|
||||
|
||||
@@ -915,8 +915,9 @@ void FEngine::cleanupResourceListLocked(Lock& lock, ResourceList<T>&& list) {
|
||||
|
||||
template<typename T>
|
||||
UTILS_ALWAYS_INLINE
|
||||
inline bool FEngine::isValid(const T* ptr, ResourceList<T>& list) {
|
||||
return list.find(ptr) != list.end();
|
||||
inline bool FEngine::isValid(const T* ptr, ResourceList<T> const& list) const {
|
||||
auto& l = const_cast<ResourceList<T>&>(list);
|
||||
return l.find(ptr) != l.end();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -1086,75 +1087,99 @@ void FEngine::destroy(Entity e) {
|
||||
mCameraManager.destroy(*this, e);
|
||||
}
|
||||
|
||||
bool FEngine::isValid(const FBufferObject* p) {
|
||||
bool FEngine::isValid(const FBufferObject* p) const {
|
||||
return isValid(p, mBufferObjects);
|
||||
}
|
||||
|
||||
bool FEngine::isValid(const FVertexBuffer* p) {
|
||||
bool FEngine::isValid(const FVertexBuffer* p) const {
|
||||
return isValid(p, mVertexBuffers);
|
||||
}
|
||||
|
||||
bool FEngine::isValid(const FFence* p) {
|
||||
bool FEngine::isValid(const FFence* p) const {
|
||||
return isValid(p, mFences);
|
||||
}
|
||||
|
||||
bool FEngine::isValid(const FIndexBuffer* p) {
|
||||
bool FEngine::isValid(const FIndexBuffer* p) const {
|
||||
return isValid(p, mIndexBuffers);
|
||||
}
|
||||
|
||||
bool FEngine::isValid(const FSkinningBuffer* p) {
|
||||
bool FEngine::isValid(const FSkinningBuffer* p) const {
|
||||
return isValid(p, mSkinningBuffers);
|
||||
}
|
||||
|
||||
bool FEngine::isValid(const FMorphTargetBuffer* p) {
|
||||
bool FEngine::isValid(const FMorphTargetBuffer* p) const {
|
||||
return isValid(p, mMorphTargetBuffers);
|
||||
}
|
||||
|
||||
bool FEngine::isValid(const FIndirectLight* p) {
|
||||
bool FEngine::isValid(const FIndirectLight* p) const {
|
||||
return isValid(p, mIndirectLights);
|
||||
}
|
||||
|
||||
bool FEngine::isValid(const FMaterial* p) {
|
||||
bool FEngine::isValid(const FMaterial* p) const {
|
||||
return isValid(p, mMaterials);
|
||||
}
|
||||
|
||||
bool FEngine::isValid(const FRenderer* p) {
|
||||
bool FEngine::isValid(const FMaterial* m, const FMaterialInstance* p) const {
|
||||
// first make sure the material we're given is valid.
|
||||
if (!isValid(m)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// then find the material instance list for that material
|
||||
auto it = mMaterialInstances.find(m);
|
||||
if (it == mMaterialInstances.end()) {
|
||||
// this could happen if this material has no material instances at all
|
||||
return false;
|
||||
}
|
||||
|
||||
// finally validate the material instance
|
||||
return isValid(p, it->second);
|
||||
}
|
||||
|
||||
bool FEngine::isValidExpensive(const FMaterialInstance* p) const {
|
||||
return std::any_of(mMaterialInstances.cbegin(), mMaterialInstances.cend(),
|
||||
[this, p](auto&& entry) {
|
||||
return isValid(p, entry.second);
|
||||
});
|
||||
}
|
||||
|
||||
bool FEngine::isValid(const FRenderer* p) const {
|
||||
return isValid(p, mRenderers);
|
||||
}
|
||||
|
||||
bool FEngine::isValid(const FScene* p) {
|
||||
bool FEngine::isValid(const FScene* p) const {
|
||||
return isValid(p, mScenes);
|
||||
}
|
||||
|
||||
bool FEngine::isValid(const FSkybox* p) {
|
||||
bool FEngine::isValid(const FSkybox* p) const {
|
||||
return isValid(p, mSkyboxes);
|
||||
}
|
||||
|
||||
bool FEngine::isValid(const FColorGrading* p) {
|
||||
bool FEngine::isValid(const FColorGrading* p) const {
|
||||
return isValid(p, mColorGradings);
|
||||
}
|
||||
|
||||
bool FEngine::isValid(const FSwapChain* p) {
|
||||
bool FEngine::isValid(const FSwapChain* p) const {
|
||||
return isValid(p, mSwapChains);
|
||||
}
|
||||
|
||||
bool FEngine::isValid(const FStream* p) {
|
||||
bool FEngine::isValid(const FStream* p) const {
|
||||
return isValid(p, mStreams);
|
||||
}
|
||||
|
||||
bool FEngine::isValid(const FTexture* p) {
|
||||
bool FEngine::isValid(const FTexture* p) const {
|
||||
return isValid(p, mTextures);
|
||||
}
|
||||
|
||||
bool FEngine::isValid(const FRenderTarget* p) {
|
||||
bool FEngine::isValid(const FRenderTarget* p) const {
|
||||
return isValid(p, mRenderTargets);
|
||||
}
|
||||
|
||||
bool FEngine::isValid(const FView* p) {
|
||||
bool FEngine::isValid(const FView* p) const {
|
||||
return isValid(p, mViews);
|
||||
}
|
||||
|
||||
bool FEngine::isValid(const FInstanceBuffer* p) {
|
||||
bool FEngine::isValid(const FInstanceBuffer* p) const {
|
||||
return isValid(p, mInstanceBuffers);
|
||||
}
|
||||
|
||||
|
||||
@@ -318,25 +318,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);
|
||||
bool isValid(const FBufferObject* p) const;
|
||||
bool isValid(const FVertexBuffer* p) const;
|
||||
bool isValid(const FFence* p) const;
|
||||
bool isValid(const FIndexBuffer* p) const;
|
||||
bool isValid(const FSkinningBuffer* p) const;
|
||||
bool isValid(const FMorphTargetBuffer* p) const;
|
||||
bool isValid(const FIndirectLight* p) const;
|
||||
bool isValid(const FMaterial* p) const;
|
||||
bool isValid(const FMaterial* m, const FMaterialInstance* p) const;
|
||||
bool isValidExpensive(const FMaterialInstance* p) const;
|
||||
bool isValid(const FRenderer* p) const;
|
||||
bool isValid(const FScene* p) const;
|
||||
bool isValid(const FSkybox* p) const;
|
||||
bool isValid(const FColorGrading* p) const;
|
||||
bool isValid(const FSwapChain* p) const;
|
||||
bool isValid(const FStream* p) const;
|
||||
bool isValid(const FTexture* p) const;
|
||||
bool isValid(const FRenderTarget* p) const;
|
||||
bool isValid(const FView* p) const;
|
||||
bool isValid(const FInstanceBuffer* p) const;
|
||||
|
||||
void destroy(utils::Entity e);
|
||||
|
||||
@@ -444,7 +445,7 @@ private:
|
||||
backend::Driver& getDriver() const noexcept { return *mDriver; }
|
||||
|
||||
template<typename T>
|
||||
bool isValid(const T* ptr, ResourceList<T>& list);
|
||||
bool isValid(const T* ptr, ResourceList<T> const& list) const;
|
||||
|
||||
template<typename T>
|
||||
bool terminateAndDestroy(const T* p, ResourceList<T>& list);
|
||||
|
||||
@@ -576,6 +576,12 @@ class_<Engine>("Engine")
|
||||
.function("isValidMaterial", EMBIND_LAMBDA(bool, (Engine* engine, Material* object), {
|
||||
return engine->isValid(object);
|
||||
}), allow_raw_pointers())
|
||||
.function("isValidMaterialInstance", EMBIND_LAMBDA(bool, (Engine* engine, Material* ma, MaterialInstance* mi), {
|
||||
return engine->isValid(ma, mi);
|
||||
}), allow_raw_pointers())
|
||||
.function("isValidExpensiveMaterialInstance", EMBIND_LAMBDA(bool, (Engine* engine, MaterialInstance* object), {
|
||||
return engine->isValidExpensive(object);
|
||||
}), allow_raw_pointers())
|
||||
.function("isValidSkybox", EMBIND_LAMBDA(bool, (Engine* engine, Skybox* object), {
|
||||
return engine->isValid(object);
|
||||
}), allow_raw_pointers())
|
||||
|
||||
Reference in New Issue
Block a user