separate out RenderLoop/FilamentViewer construction/destruction
This commit is contained in:
@@ -1396,6 +1396,12 @@ external int TransformManager_getAncestor(
|
|||||||
int childEntityId,
|
int childEntityId,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ffi.Native<ffi.Void Function()>(isLeaf: true)
|
||||||
|
external void RenderLoop_create();
|
||||||
|
|
||||||
|
@ffi.Native<ffi.Void Function()>(isLeaf: true)
|
||||||
|
external void RenderLoop_destroy();
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Void Function(
|
ffi.Void Function(
|
||||||
ffi.Pointer<ffi.Void>,
|
ffi.Pointer<ffi.Void>,
|
||||||
|
|||||||
@@ -179,6 +179,11 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future _initialize() async {
|
Future _initialize() async {
|
||||||
|
_logger.info("Initializing ThermionViewerFFI");
|
||||||
|
|
||||||
|
RenderLoop_destroy();
|
||||||
|
RenderLoop_create();
|
||||||
|
|
||||||
final uberarchivePtr =
|
final uberarchivePtr =
|
||||||
uberArchivePath?.toNativeUtf8(allocator: allocator).cast<Char>() ??
|
uberArchivePath?.toNativeUtf8(allocator: allocator).cast<Char>() ??
|
||||||
nullptr;
|
nullptr;
|
||||||
@@ -205,6 +210,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
_nameComponentManager =
|
_nameComponentManager =
|
||||||
SceneManager_getNameComponentManager(_sceneManager!);
|
SceneManager_getNameComponentManager(_sceneManager!);
|
||||||
_renderableManager = Engine_getRenderableManager(_engine!);
|
_renderableManager = Engine_getRenderableManager(_engine!);
|
||||||
|
|
||||||
this._initialized.complete(true);
|
this._initialized.complete(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -302,14 +308,17 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
await mInstance.dispose();
|
await mInstance.dispose();
|
||||||
}
|
}
|
||||||
await destroyLights();
|
await destroyLights();
|
||||||
|
|
||||||
Viewer_destroyOnRenderThread(_viewer!);
|
Viewer_destroyOnRenderThread(_viewer!);
|
||||||
|
|
||||||
|
RenderLoop_destroy();
|
||||||
|
|
||||||
_sceneManager = null;
|
_sceneManager = null;
|
||||||
_viewer = null;
|
_viewer = null;
|
||||||
|
|
||||||
for (final callback in _onDispose) {
|
for (final callback in _onDispose) {
|
||||||
await callback.call();
|
await callback.call();
|
||||||
}
|
}
|
||||||
|
|
||||||
_onDispose.clear();
|
_onDispose.clear();
|
||||||
_disposing = false;
|
_disposing = false;
|
||||||
}
|
}
|
||||||
@@ -2194,7 +2203,8 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
///
|
///
|
||||||
///
|
///
|
||||||
Future setReceiveShadows(ThermionEntity entity, bool receiveShadows) async {
|
Future setReceiveShadows(ThermionEntity entity, bool receiveShadows) async {
|
||||||
RenderableManager_setReceiveShadows(_renderableManager!, entity, receiveShadows);
|
RenderableManager_setReceiveShadows(
|
||||||
|
_renderableManager!, entity, receiveShadows);
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -22,6 +22,9 @@ namespace thermion
|
|||||||
typedef int32_t EntityId;
|
typedef int32_t EntityId;
|
||||||
typedef void (*FilamentRenderCallback)(void *const owner);
|
typedef void (*FilamentRenderCallback)(void *const owner);
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE void RenderLoop_create();
|
||||||
|
EMSCRIPTEN_KEEPALIVE void RenderLoop_destroy();
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void Viewer_createOnRenderThread(
|
EMSCRIPTEN_KEEPALIVE void Viewer_createOnRenderThread(
|
||||||
void *const context,
|
void *const context,
|
||||||
void *const platform,
|
void *const platform,
|
||||||
|
|||||||
@@ -516,9 +516,8 @@ namespace thermion
|
|||||||
|
|
||||||
FilamentViewer::~FilamentViewer()
|
FilamentViewer::~FilamentViewer()
|
||||||
{
|
{
|
||||||
|
TRACE("Destroying FilamentViewer");
|
||||||
_sceneManager->destroyAll();
|
_sceneManager->destroyAll();
|
||||||
|
|
||||||
for (auto view : _views)
|
for (auto view : _views)
|
||||||
{
|
{
|
||||||
view->setRenderTarget(nullptr);
|
view->setRenderTarget(nullptr);
|
||||||
@@ -526,20 +525,20 @@ namespace thermion
|
|||||||
}
|
}
|
||||||
|
|
||||||
_views.clear();
|
_views.clear();
|
||||||
|
TRACE("Destroying render targets");
|
||||||
for(auto rt : _renderTargets) {
|
for(auto rt : _renderTargets) {
|
||||||
destroyRenderTarget(rt);
|
destroyRenderTarget(rt);
|
||||||
}
|
}
|
||||||
|
|
||||||
_renderTargets.clear();
|
_renderTargets.clear();
|
||||||
|
TRACE("Destroying swapchains");
|
||||||
for (auto swapChain : _swapChains)
|
for (auto swapChain : _swapChains)
|
||||||
{
|
{
|
||||||
_engine->destroy(swapChain);
|
_engine->destroy(swapChain);
|
||||||
}
|
}
|
||||||
|
|
||||||
_swapChains.clear();
|
_swapChains.clear();
|
||||||
|
TRACE("Destroying background image");
|
||||||
if (!_imageEntity.isNull())
|
if (!_imageEntity.isNull())
|
||||||
{
|
{
|
||||||
_engine->destroy(_imageEntity);
|
_engine->destroy(_imageEntity);
|
||||||
@@ -548,13 +547,18 @@ namespace thermion
|
|||||||
_engine->destroy(_imageIb);
|
_engine->destroy(_imageIb);
|
||||||
_engine->destroy(_imageMaterial);
|
_engine->destroy(_imageMaterial);
|
||||||
}
|
}
|
||||||
|
TRACE("Destroying SceneManager");
|
||||||
delete _sceneManager;
|
delete _sceneManager;
|
||||||
|
TRACE("SceneManager destroyed");
|
||||||
_engine->destroyCameraComponent(_mainCamera->getEntity());
|
_engine->destroyCameraComponent(_mainCamera->getEntity());
|
||||||
_mainCamera = nullptr;
|
_mainCamera = nullptr;
|
||||||
_engine->destroy(_scene);
|
_engine->destroy(_scene);
|
||||||
_engine->destroy(_renderer);
|
_engine->destroy(_renderer);
|
||||||
|
TRACE("Destroying engine");
|
||||||
Engine::destroy(&_engine);
|
Engine::destroy(&_engine);
|
||||||
|
TRACE("Engine destroyed");
|
||||||
delete _resourceLoaderWrapper;
|
delete _resourceLoaderWrapper;
|
||||||
|
TRACE("Destruction complete.");
|
||||||
}
|
}
|
||||||
|
|
||||||
Renderer *FilamentViewer::getRenderer() { return _renderer; }
|
Renderer *FilamentViewer::getRenderer() { return _renderer; }
|
||||||
|
|||||||
@@ -49,9 +49,10 @@ extern "C"
|
|||||||
viewer->destroyRenderTarget(renderTarget);
|
viewer->destroyRenderTarget(renderTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void Viewer_destroy(TViewer *viewer)
|
EMSCRIPTEN_KEEPALIVE void Viewer_destroy(TViewer *tViewer)
|
||||||
{
|
{
|
||||||
delete ((FilamentViewer *)viewer);
|
auto *viewer = reinterpret_cast<FilamentViewer*>(tViewer);
|
||||||
|
delete viewer;
|
||||||
}
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void set_background_color(TViewer *viewer, const float r, const float g, const float b, const float a)
|
EMSCRIPTEN_KEEPALIVE void set_background_color(TViewer *viewer, const float r, const float g, const float b, const float a)
|
||||||
|
|||||||
@@ -35,20 +35,12 @@ public:
|
|||||||
|
|
||||||
~RenderLoop()
|
~RenderLoop()
|
||||||
{
|
{
|
||||||
|
TRACE("Destroying RenderLoop");
|
||||||
_stop = true;
|
_stop = true;
|
||||||
_cv.notify_one();
|
_cv.notify_one();
|
||||||
|
TRACE("Joining RenderLoop thread..");
|
||||||
t->join();
|
t->join();
|
||||||
}
|
TRACE("RenderLoop destructor complete");
|
||||||
|
|
||||||
static void mainLoop(void *arg)
|
|
||||||
{
|
|
||||||
((RenderLoop *)arg)->iter();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *startHelper(void *parm)
|
|
||||||
{
|
|
||||||
((RenderLoop *)parm)->start();
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void start()
|
void start()
|
||||||
@@ -59,6 +51,42 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void destroyViewer() {
|
||||||
|
std::packaged_task<void()> lambda([=]() mutable
|
||||||
|
{
|
||||||
|
if(viewer) {
|
||||||
|
Viewer_destroy(viewer);
|
||||||
|
}
|
||||||
|
viewer = nullptr;
|
||||||
|
_renderCallback = nullptr;
|
||||||
|
_renderCallbackOwner = nullptr;
|
||||||
|
|
||||||
|
});
|
||||||
|
auto fut = add_task(lambda);
|
||||||
|
fut.wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
void createViewer(
|
||||||
|
void *const context,
|
||||||
|
void *const platform,
|
||||||
|
const char *uberArchivePath,
|
||||||
|
const void *const loader,
|
||||||
|
void (*renderCallback)(void *),
|
||||||
|
void *const owner,
|
||||||
|
void (*callback)(TViewer *))
|
||||||
|
{
|
||||||
|
_renderCallback = renderCallback;
|
||||||
|
_renderCallbackOwner = owner;
|
||||||
|
std::packaged_task<void()> lambda([=]() mutable
|
||||||
|
{
|
||||||
|
if(viewer) {
|
||||||
|
Viewer_destroy(viewer);
|
||||||
|
}
|
||||||
|
viewer = Viewer_create(context, loader, platform, uberArchivePath);
|
||||||
|
callback(viewer); });
|
||||||
|
add_task(lambda);
|
||||||
|
}
|
||||||
|
|
||||||
void requestFrame(void (*callback)())
|
void requestFrame(void (*callback)())
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(_mutex);
|
std::unique_lock<std::mutex> lock(_mutex);
|
||||||
@@ -109,37 +137,9 @@ public:
|
|||||||
{ return !_tasks.empty() || _stop; });
|
{ return !_tasks.empty() || _stop; });
|
||||||
}
|
}
|
||||||
|
|
||||||
void createViewer(void *const context,
|
|
||||||
void *const platform,
|
|
||||||
const char *uberArchivePath,
|
|
||||||
const ResourceLoaderWrapper *const loader,
|
|
||||||
void (*renderCallback)(void *),
|
|
||||||
void *const owner,
|
|
||||||
void (*callback)(TViewer *))
|
|
||||||
{
|
|
||||||
_renderCallback = renderCallback;
|
|
||||||
_renderCallbackOwner = owner;
|
|
||||||
std::packaged_task<void()> lambda([=]() mutable
|
|
||||||
{
|
|
||||||
auto viewer = (FilamentViewer *)Viewer_create(context, loader, platform, uberArchivePath);
|
|
||||||
_viewer = reinterpret_cast<TViewer*>(viewer);
|
|
||||||
callback(_viewer); });
|
|
||||||
auto fut = add_task(lambda);
|
|
||||||
}
|
|
||||||
|
|
||||||
void destroyViewer(FilamentViewer *viewer)
|
|
||||||
{
|
|
||||||
std::packaged_task<void()> lambda([=]() mutable
|
|
||||||
{
|
|
||||||
_viewer = nullptr;
|
|
||||||
Viewer_destroy(reinterpret_cast<TViewer*>(viewer)); });
|
|
||||||
auto fut = add_task(lambda);
|
|
||||||
fut.wait();
|
|
||||||
}
|
|
||||||
|
|
||||||
void doRender()
|
void doRender()
|
||||||
{
|
{
|
||||||
Viewer_render(_viewer);
|
Viewer_render(viewer);
|
||||||
if (_renderCallback)
|
if (_renderCallback)
|
||||||
{
|
{
|
||||||
_renderCallback(_renderCallbackOwner);
|
_renderCallback(_renderCallbackOwner);
|
||||||
@@ -163,6 +163,8 @@ public:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TViewer *viewer = std::nullptr_t();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void (*_requestFrameRenderCallback)() = nullptr;
|
void (*_requestFrameRenderCallback)() = nullptr;
|
||||||
bool _stop = false;
|
bool _stop = false;
|
||||||
@@ -173,7 +175,6 @@ private:
|
|||||||
void (*_renderCallback)(void *const) = nullptr;
|
void (*_renderCallback)(void *const) = nullptr;
|
||||||
void *_renderCallbackOwner = nullptr;
|
void *_renderCallbackOwner = nullptr;
|
||||||
std::deque<std::function<void()>> _tasks;
|
std::deque<std::function<void()>> _tasks;
|
||||||
TViewer *_viewer = nullptr;
|
|
||||||
std::chrono::high_resolution_clock::time_point _lastFrameTime;
|
std::chrono::high_resolution_clock::time_point _lastFrameTime;
|
||||||
int _frameCount = 0;
|
int _frameCount = 0;
|
||||||
float _accumulatedTime = 0.0f;
|
float _accumulatedTime = 0.0f;
|
||||||
@@ -184,7 +185,25 @@ private:
|
|||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
|
|
||||||
static RenderLoop *_rl;
|
static std::unique_ptr<RenderLoop> _rl;
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE void RenderLoop_create() {
|
||||||
|
TRACE("RenderLoop_create");
|
||||||
|
if (_rl)
|
||||||
|
{
|
||||||
|
Log("WARNING - you are attempting to create a RenderLoop when the previous one has not been disposed.");
|
||||||
|
}
|
||||||
|
_rl = std::make_unique<RenderLoop>();
|
||||||
|
}
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE void RenderLoop_destroy() {
|
||||||
|
TRACE("RenderLoop_destroy");
|
||||||
|
if (_rl)
|
||||||
|
{
|
||||||
|
_rl->destroyViewer();
|
||||||
|
_rl = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void Viewer_createOnRenderThread(
|
EMSCRIPTEN_KEEPALIVE void Viewer_createOnRenderThread(
|
||||||
void *const context, void *const platform, const char *uberArchivePath,
|
void *const context, void *const platform, const char *uberArchivePath,
|
||||||
@@ -193,20 +212,27 @@ extern "C"
|
|||||||
void *const renderCallbackOwner,
|
void *const renderCallbackOwner,
|
||||||
void (*callback)(TViewer *))
|
void (*callback)(TViewer *))
|
||||||
{
|
{
|
||||||
|
TRACE("Viewer_createOnRenderThread");
|
||||||
if (!_rl)
|
_rl->createViewer(
|
||||||
{
|
context,
|
||||||
_rl = new RenderLoop();
|
platform,
|
||||||
}
|
uberArchivePath,
|
||||||
_rl->createViewer(context, platform, uberArchivePath, (const ResourceLoaderWrapper *const)loader,
|
loader,
|
||||||
renderCallback, renderCallbackOwner, callback);
|
renderCallback,
|
||||||
|
renderCallbackOwner,
|
||||||
|
callback
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void Viewer_destroyOnRenderThread(TViewer *viewer)
|
EMSCRIPTEN_KEEPALIVE void Viewer_destroyOnRenderThread(TViewer *viewer)
|
||||||
{
|
{
|
||||||
_rl->destroyViewer((FilamentViewer *)viewer);
|
TRACE("Viewer_destroyOnRenderThread");
|
||||||
delete _rl;
|
if (!_rl)
|
||||||
_rl = nullptr;
|
{
|
||||||
|
Log("Warning - cannot destroy viewer, no RenderLoop has been created");
|
||||||
|
} else {
|
||||||
|
_rl->destroyViewer();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void Viewer_createHeadlessSwapChainRenderThread(TViewer *viewer,
|
EMSCRIPTEN_KEEPALIVE void Viewer_createHeadlessSwapChainRenderThread(TViewer *viewer,
|
||||||
@@ -320,14 +346,15 @@ extern "C"
|
|||||||
auto fut = _rl->add_task(lambda);
|
auto fut = _rl->add_task(lambda);
|
||||||
}
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void Engine_destroyTextureRenderThread(TEngine *engine, TTexture* tTexture, void (*onComplete)()) {
|
EMSCRIPTEN_KEEPALIVE void Engine_destroyTextureRenderThread(TEngine *engine, TTexture *tTexture, void (*onComplete)())
|
||||||
|
{
|
||||||
std::packaged_task<void()> lambda(
|
std::packaged_task<void()> lambda(
|
||||||
[=]() mutable
|
[=]() mutable
|
||||||
{
|
{
|
||||||
Engine_destroyTexture(engine, tTexture);
|
Engine_destroyTexture(engine, tTexture);
|
||||||
onComplete();
|
onComplete();
|
||||||
});
|
});
|
||||||
auto fut = _rl->add_task(lambda);
|
auto fut = _rl->add_task(lambda);
|
||||||
}
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void Engine_buildMaterialRenderThread(TEngine *tEngine, const uint8_t *materialData, size_t length, void (*onComplete)(TMaterial *))
|
EMSCRIPTEN_KEEPALIVE void Engine_buildMaterialRenderThread(TEngine *tEngine, const uint8_t *materialData, size_t length, void (*onComplete)(TMaterial *))
|
||||||
|
|||||||
@@ -124,17 +124,21 @@ namespace thermion
|
|||||||
|
|
||||||
SceneManager::~SceneManager()
|
SceneManager::~SceneManager()
|
||||||
{
|
{
|
||||||
|
TRACE("Destroying cameras");
|
||||||
for (auto camera : _cameras)
|
for (auto camera : _cameras)
|
||||||
{
|
{
|
||||||
auto entity = camera->getEntity();
|
auto entity = camera->getEntity();
|
||||||
_engine->destroyCameraComponent(entity);
|
_engine->destroyCameraComponent(entity);
|
||||||
_engine->getEntityManager().destroy(entity);
|
_engine->getEntityManager().destroy(entity);
|
||||||
}
|
}
|
||||||
|
TRACE("Cameras destroyed");
|
||||||
|
|
||||||
destroyAll();
|
destroyAll();
|
||||||
|
TRACE("Destroyed all assets");
|
||||||
|
|
||||||
_engine->destroy(_unlitFixedSizeMaterial);
|
_engine->destroy(_unlitFixedSizeMaterial);
|
||||||
_engine->destroy(_gizmoMaterial);
|
_engine->destroy(_gizmoMaterial);
|
||||||
|
TRACE("Destroyed materials");
|
||||||
_cameras.clear();
|
_cameras.clear();
|
||||||
|
|
||||||
_grid = nullptr;
|
_grid = nullptr;
|
||||||
@@ -150,7 +154,9 @@ namespace thermion
|
|||||||
delete _stbDecoder;
|
delete _stbDecoder;
|
||||||
delete _ktxDecoder;
|
delete _ktxDecoder;
|
||||||
delete _ubershaderProvider;
|
delete _ubershaderProvider;
|
||||||
|
TRACE("Destroying asset loader");
|
||||||
AssetLoader::destroy(&_assetLoader);
|
AssetLoader::destroy(&_assetLoader);
|
||||||
|
TRACE("Destroyed asset loader");
|
||||||
}
|
}
|
||||||
|
|
||||||
SceneAsset *SceneManager::createGrid(Material *material)
|
SceneAsset *SceneManager::createGrid(Material *material)
|
||||||
|
|||||||
Reference in New Issue
Block a user