feat: support multiple ThermionWidget on Android

This commit is contained in:
Nick Fisher
2024-09-30 18:20:05 +08:00
parent e1efd5e4e0
commit 50ed0bdfda
25 changed files with 418 additions and 549 deletions

View File

@@ -2,6 +2,7 @@ import 'dart:ffi';
import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_dart.g.dart';
import 'package:thermion_dart/src/viewer/src/shared_types/camera.dart';
import 'package:thermion_dart/src/viewer/src/shared_types/shared_types.dart';
import '../../shared_types/view.dart';
import '../thermion_viewer_ffi.dart';
@@ -50,7 +51,7 @@ class FFIView extends View {
View_setPostProcessing(view, enabled);
}
Future setRenderable(bool renderable) async {
Viewer_markViewRenderable(viewer, view, renderable);
Future setRenderable(bool renderable, FFISwapChain swapChain) async {
Viewer_setViewRenderable(viewer, swapChain.swapChain, view, renderable);
}
}

View File

@@ -46,11 +46,18 @@ external void Viewer_destroyRenderTarget(
);
@ffi.Native<
ffi.Pointer<TSwapChain> Function(ffi.Pointer<TViewer>,
ffi.Pointer<ffi.Void>, ffi.Uint32, ffi.Uint32)>(isLeaf: true)
ffi.Pointer<TSwapChain> Function(
ffi.Pointer<TViewer>, ffi.Pointer<ffi.Void>)>(isLeaf: true)
external ffi.Pointer<TSwapChain> Viewer_createSwapChain(
ffi.Pointer<TViewer> viewer,
ffi.Pointer<ffi.Void> window,
);
@ffi.Native<
ffi.Pointer<TSwapChain> Function(
ffi.Pointer<TViewer>, ffi.Uint32, ffi.Uint32)>(isLeaf: true)
external ffi.Pointer<TSwapChain> Viewer_createHeadlessSwapChain(
ffi.Pointer<TViewer> viewer,
int width,
int height,
);
@@ -62,28 +69,9 @@ external void Viewer_destroySwapChain(
ffi.Pointer<TSwapChain> swapChain,
);
@ffi.Native<
ffi.Bool Function(
ffi.Pointer<TViewer>,
ffi.Pointer<TSwapChain>,
ffi.Uint64,
ffi.Pointer<ffi.Void>,
ffi.Pointer<
ffi.NativeFunction<
ffi.Void Function(ffi.Pointer<ffi.Void> buf, ffi.Size size,
ffi.Pointer<ffi.Void> data)>>,
ffi.Pointer<ffi.Void>)>(isLeaf: true)
external bool Viewer_render(
@ffi.Native<ffi.Void Function(ffi.Pointer<TViewer>)>(isLeaf: true)
external void Viewer_render(
ffi.Pointer<TViewer> viewer,
ffi.Pointer<TSwapChain> swapChain,
int frameTimeInNanos,
ffi.Pointer<ffi.Void> pixelBuffer,
ffi.Pointer<
ffi.NativeFunction<
ffi.Void Function(ffi.Pointer<ffi.Void> buf, ffi.Size size,
ffi.Pointer<ffi.Void> data)>>
callback,
ffi.Pointer<ffi.Void> data,
);
@ffi.Native<
@@ -145,10 +133,11 @@ external ffi.Pointer<TSwapChain> Viewer_getSwapChainAt(
);
@ffi.Native<
ffi.Void Function(
ffi.Pointer<TViewer>, ffi.Pointer<TView>, ffi.Bool)>(isLeaf: true)
external void Viewer_markViewRenderable(
ffi.Void Function(ffi.Pointer<TViewer>, ffi.Pointer<TSwapChain>,
ffi.Pointer<TView>, ffi.Bool)>(isLeaf: true)
external void Viewer_setViewRenderable(
ffi.Pointer<TViewer> viewer,
ffi.Pointer<TSwapChain> swapChain,
ffi.Pointer<TView> view,
bool renderable,
);
@@ -1374,7 +1363,7 @@ external void MaterialInstance_setParameterFloat2(
ffi.Pointer<
ffi.NativeFunction<
ffi.Void Function(ffi.Pointer<TViewer> viewer)>>)>(isLeaf: true)
external void create_filament_viewer_render_thread(
external void Viewer_createOnRenderThread(
ffi.Pointer<ffi.Void> context,
ffi.Pointer<ffi.Void> platform,
ffi.Pointer<ffi.Char> uberArchivePath,
@@ -1393,8 +1382,6 @@ external void create_filament_viewer_render_thread(
ffi.Void Function(
ffi.Pointer<TViewer>,
ffi.Pointer<ffi.Void>,
ffi.Uint32,
ffi.Uint32,
ffi.Pointer<
ffi
.NativeFunction<ffi.Void Function(ffi.Pointer<TSwapChain>)>>)>(
@@ -1402,6 +1389,21 @@ external void create_filament_viewer_render_thread(
external void Viewer_createSwapChainRenderThread(
ffi.Pointer<TViewer> viewer,
ffi.Pointer<ffi.Void> surface,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<TSwapChain>)>>
onComplete,
);
@ffi.Native<
ffi.Void Function(
ffi.Pointer<TViewer>,
ffi.Uint32,
ffi.Uint32,
ffi.Pointer<
ffi
.NativeFunction<ffi.Void Function(ffi.Pointer<TSwapChain>)>>)>(
isLeaf: true)
external void Viewer_createHeadlessSwapChainRenderThread(
ffi.Pointer<TViewer> viewer,
int width,
int height,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<TSwapChain>)>>
@@ -1459,11 +1461,10 @@ external void Viewer_captureRenderTargetRenderThread(
);
@ffi.Native<
ffi.Void Function(ffi.Pointer<TViewer>, ffi.Pointer<TSwapChain>,
ffi.Void Function(ffi.Pointer<TViewer>,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>(isLeaf: true)
external void Viewer_requestFrameRenderThread(
ffi.Pointer<TViewer> viewer,
ffi.Pointer<TSwapChain> tSwapChain,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> onComplete,
);

View File

@@ -149,11 +149,24 @@ class ThermionViewerFFI extends ThermionViewer {
}
}
Future<SwapChain> createSwapChain(int width, int height,
{Pointer<Void>? surface}) async {
///
///
///
Future<SwapChain> createHeadlessSwapChain(int width, int height) async {
var swapChain = await withPointerCallback<TSwapChain>((callback) {
return Viewer_createHeadlessSwapChainRenderThread(
_viewer!, width, height, callback);
});
return FFISwapChain(swapChain, _viewer!);
}
///
///
///
Future<SwapChain> createSwapChain(int surface) async {
var swapChain = await withPointerCallback<TSwapChain>((callback) {
return Viewer_createSwapChainRenderThread(
_viewer!, surface ?? nullptr, width, height, callback);
_viewer!, Pointer<Void>.fromAddress(surface), callback);
});
return FFISwapChain(swapChain, _viewer!);
}
@@ -167,7 +180,7 @@ class ThermionViewerFFI extends ThermionViewer {
nullptr;
_viewer = await withPointerCallback(
(Pointer<NativeFunction<Void Function(Pointer<TViewer>)>> callback) {
create_filament_viewer_render_thread(
Viewer_createOnRenderThread(
_sharedContext,
_driver,
uberarchivePtr,
@@ -2039,10 +2052,8 @@ class ThermionViewerFFI extends ThermionViewer {
completer.complete(true);
});
final swapChain = Viewer_getSwapChainAt(_viewer!, 0);
Viewer_requestFrameRenderThread(
_viewer!, swapChain, callback.nativeFunction);
_viewer!, callback.nativeFunction);
await completer.future.timeout(Duration(seconds: 1));
}

View File

@@ -1,4 +1,5 @@
import 'package:thermion_dart/thermion_dart.dart';
import 'swap_chain.dart';
class Viewport {
final int left;
@@ -17,5 +18,5 @@ abstract class View {
Camera getCamera();
Future setPostProcessing(bool enabled);
Future setAntiAliasing(bool msaa, bool fxaa, bool taa);
Future setRenderable(bool renderable);
Future setRenderable(bool renderable, covariant SwapChain swapChain);
}

View File

@@ -62,7 +62,12 @@ abstract class ThermionViewer {
///
///
///
Future<SwapChain> createSwapChain(int width, int height);
Future<SwapChain> createHeadlessSwapChain(int width, int height);
///
///
///
Future<SwapChain> createSwapChain(int handle);
///
///

View File

@@ -1006,12 +1006,6 @@ class ThermionViewerStub extends ThermionViewer {
throw UnimplementedError();
}
@override
Future<SwapChain> createSwapChain(int width, int height) {
// TODO: implement createSwapChain
throw UnimplementedError();
}
@override
Future<RenderTarget> createRenderTarget(int width, int height, int textureHandle) {
// TODO: implement createRenderTarget
@@ -1036,23 +1030,36 @@ class ThermionViewerStub extends ThermionViewer {
throw UnimplementedError();
}
@override
Future render(covariant SwapChain swapChain) {
// TODO: implement render
throw UnimplementedError();
}
@override
Future<Uint8List> capture(covariant SwapChain swapChain, {covariant View? view, covariant RenderTarget? renderTarget}) {
// TODO: implement capture
throw UnimplementedError();
}
@override
Future<Gizmo> createGizmo(covariant View view) {
// TODO: implement createGizmo
throw UnimplementedError();
}
@override
Future<SwapChain> createHeadlessSwapChain(int width, int height) {
// TODO: implement createHeadlessSwapChain
throw UnimplementedError();
}
@override
Future<Uint8List> capture({covariant SwapChain? swapChain, covariant View? view, covariant RenderTarget? renderTarget}) {
// TODO: implement capture
throw UnimplementedError();
}
@override
Future<SwapChain> createSwapChain(handle) {
// TODO: implement createSwapChain
throw UnimplementedError();
}
@override
Future render({covariant SwapChain? swapChain}) {
// TODO: implement render
throw UnimplementedError();
}
}

View File

@@ -68,12 +68,9 @@ namespace thermion
void removeEntity(EntityId asset);
void clearEntities();
bool render(
uint64_t frameTimeInNanos,
SwapChain* swapChain,
void *pixelBuffer,
void (*callback)(void *buf, size_t size, void *data),
void *data);
void render(
uint64_t frameTimeInNanos
);
void setFrameInterval(float interval);
void setMainCamera(View *view);
@@ -83,7 +80,8 @@ namespace thermion
float getCameraFov(bool horizontal);
void setCameraFov(double fovDegrees, bool horizontal);
SwapChain* createSwapChain(const void *surface, uint32_t width, uint32_t height);
SwapChain* createSwapChain(const void *surface);
SwapChain* createSwapChain(uint32_t width, uint32_t height);
void destroySwapChain(SwapChain* swapChain);
RenderTarget* createRenderTarget(intptr_t textureId, uint32_t width, uint32_t height);
@@ -91,21 +89,9 @@ namespace thermion
Renderer *getRenderer();
std::vector<View*> _renderable;
void setRenderable(View* view, bool renderable) {
auto it = std::find(_renderable.begin(), _renderable.end(), view);
if(renderable) {
if(it == _renderable.end()) {
_renderable.push_back(view);
}
} else {
if(it != _renderable.end()) {
_renderable.erase(it);
}
}
}
std::map<SwapChain*, std::vector<View*>> _renderable;
void setRenderable(View* view, SwapChain* swapChain, bool renderable);
void setBackgroundColor(const float r, const float g, const float b, const float a);
void setBackgroundImage(const char *resourcePath, bool fillHeight, uint32_t width, uint32_t height);

View File

@@ -54,20 +54,16 @@ extern "C"
{
#endif
EMSCRIPTEN_KEEPALIVE TViewer *create_filament_viewer(const void *const context, const void *const loader, void *const platform, const char *uberArchivePath);
EMSCRIPTEN_KEEPALIVE TViewer *Viewer_create(const void *const context, const void *const loader, void *const platform, const char *uberArchivePath);
EMSCRIPTEN_KEEPALIVE void destroy_filament_viewer(TViewer *viewer);
EMSCRIPTEN_KEEPALIVE TSceneManager *Viewer_getSceneManager(TViewer *viewer);
EMSCRIPTEN_KEEPALIVE TRenderTarget* Viewer_createRenderTarget(TViewer *viewer, intptr_t texture, uint32_t width, uint32_t height);
EMSCRIPTEN_KEEPALIVE void Viewer_destroyRenderTarget(TViewer *viewer, TRenderTarget* tRenderTarget);
EMSCRIPTEN_KEEPALIVE TSwapChain *Viewer_createSwapChain(TViewer *viewer, const void *const window, uint32_t width, uint32_t height);
EMSCRIPTEN_KEEPALIVE TSwapChain *Viewer_createSwapChain(TViewer *viewer, const void *const window);
EMSCRIPTEN_KEEPALIVE TSwapChain *Viewer_createHeadlessSwapChain(TViewer *viewer, uint32_t width, uint32_t height);
EMSCRIPTEN_KEEPALIVE void Viewer_destroySwapChain(TViewer *viewer, TSwapChain* swapChain);
EMSCRIPTEN_KEEPALIVE bool Viewer_render(
TViewer *viewer,
TSwapChain *swapChain,
uint64_t frameTimeInNanos,
void *pixelBuffer,
void (*callback)(void *buf, size_t size, void *data),
void *data);
EMSCRIPTEN_KEEPALIVE void Viewer_render(
TViewer *viewer);
EMSCRIPTEN_KEEPALIVE void Viewer_capture(
TViewer *viewer,
TView *view,
@@ -85,7 +81,7 @@ extern "C"
EMSCRIPTEN_KEEPALIVE TView* Viewer_getViewAt(TViewer *viewer, int index);
EMSCRIPTEN_KEEPALIVE void Viewer_setMainCamera(TViewer *tViewer, TView *tView);
EMSCRIPTEN_KEEPALIVE TSwapChain* Viewer_getSwapChainAt(TViewer *tViewer, int index);
EMSCRIPTEN_KEEPALIVE void Viewer_markViewRenderable(TViewer *viewer, TView* view, bool renderable);
EMSCRIPTEN_KEEPALIVE void Viewer_setViewRenderable(TViewer *viewer, TSwapChain *swapChain, TView* view, bool renderable);
// Engine
EMSCRIPTEN_KEEPALIVE TEngine *Viewer_getEngine(TViewer* viewer);

View File

@@ -17,7 +17,7 @@ extern "C"
typedef int32_t EntityId;
typedef void (*FilamentRenderCallback)(void *const owner);
EMSCRIPTEN_KEEPALIVE void create_filament_viewer_render_thread(
EMSCRIPTEN_KEEPALIVE void Viewer_createOnRenderThread(
void *const context,
void *const platform,
const char *uberArchivePath,
@@ -25,12 +25,13 @@ extern "C"
void (*renderCallback)(void *const renderCallbackOwner),
void *const renderCallbackOwner,
void (*callback)(TViewer *viewer));
EMSCRIPTEN_KEEPALIVE void Viewer_createSwapChainRenderThread(TViewer *viewer, void *const surface, uint32_t width, uint32_t height, void (*onComplete)(TSwapChain*));
EMSCRIPTEN_KEEPALIVE void Viewer_createSwapChainRenderThread(TViewer *viewer, void *const surface, void (*onComplete)(TSwapChain*));
EMSCRIPTEN_KEEPALIVE void Viewer_createHeadlessSwapChainRenderThread(TViewer *viewer, uint32_t width, uint32_t height, void (*onComplete)(TSwapChain*));
EMSCRIPTEN_KEEPALIVE void Viewer_destroySwapChainRenderThread(TViewer *viewer, TSwapChain* swapChain, void (*onComplete)());
EMSCRIPTEN_KEEPALIVE void Viewer_renderRenderThread(TViewer *viewer, TView* view, TSwapChain* swapChain);
EMSCRIPTEN_KEEPALIVE void Viewer_captureRenderThread(TViewer *viewer, TView* view, TSwapChain* swapChain, uint8_t* out, void (*onComplete)());
EMSCRIPTEN_KEEPALIVE void Viewer_captureRenderTargetRenderThread(TViewer *viewer, TView* view, TSwapChain* swapChain, TRenderTarget* renderTarget, uint8_t* out, void (*onComplete)());
EMSCRIPTEN_KEEPALIVE void Viewer_requestFrameRenderThread(TViewer *viewer, TSwapChain* tSwapChain, void(*onComplete)());
EMSCRIPTEN_KEEPALIVE void Viewer_requestFrameRenderThread(TViewer *viewer, void(*onComplete)());
EMSCRIPTEN_KEEPALIVE void destroy_filament_viewer_render_thread(TViewer *viewer);

View File

@@ -127,7 +127,16 @@ namespace thermion
FilamentViewer::FilamentViewer(const void *sharedContext, const ResourceLoaderWrapperImpl *const resourceLoader, void *const platform, const char *uberArchivePath)
: _resourceLoaderWrapper(resourceLoader)
{
_context = (void *)sharedContext;
if(!_context) {
Log("Creating, no shared context");
} else {
Log("Creating with shared context");
}
ASSERT_POSTCONDITION(_resourceLoaderWrapper != nullptr, "Resource loader must be non-null");
#if TARGET_OS_IPHONE
@@ -166,8 +175,6 @@ namespace thermion
createView();
setRenderable(_views[0], true);
const float aperture = _mainCamera->getAperture();
const float shutterSpeed = _mainCamera->getShutterSpeed();
const float sens = _mainCamera->getSensitivity();
@@ -665,20 +672,19 @@ namespace thermion
Renderer *FilamentViewer::getRenderer() { return _renderer; }
SwapChain *FilamentViewer::createSwapChain(const void *window, uint32_t width, uint32_t height)
SwapChain *FilamentViewer::createSwapChain(const void *window)
{
std::lock_guard lock(_renderMutex);
SwapChain *swapChain = _engine->createSwapChain((void *)window, filament::backend::SWAP_CHAIN_CONFIG_TRANSPARENT | filament::backend::SWAP_CHAIN_CONFIG_READABLE | filament::SwapChain::CONFIG_HAS_STENCIL_BUFFER);
_swapChains.push_back(swapChain);
return swapChain;
}
SwapChain *FilamentViewer::createSwapChain(uint32_t width, uint32_t height)
{
std::lock_guard lock(_renderMutex);
SwapChain *swapChain;
if (window)
{
swapChain = _engine->createSwapChain((void *)window, filament::backend::SWAP_CHAIN_CONFIG_TRANSPARENT | filament::backend::SWAP_CHAIN_CONFIG_READABLE);
Log("Created window swapchain.");
}
else
{
Log("Created headless swapchain %dx%d.", width, height);
swapChain = _engine->createSwapChain(width, height, filament::backend::SWAP_CHAIN_CONFIG_TRANSPARENT | filament::backend::SWAP_CHAIN_CONFIG_READABLE | filament::SwapChain::CONFIG_HAS_STENCIL_BUFFER);
}
swapChain = _engine->createSwapChain(width, height, filament::backend::SWAP_CHAIN_CONFIG_TRANSPARENT | filament::backend::SWAP_CHAIN_CONFIG_READABLE | filament::SwapChain::CONFIG_HAS_STENCIL_BUFFER);
_swapChains.push_back(swapChain);
return swapChain;
}
@@ -734,13 +740,13 @@ namespace thermion
void FilamentViewer::destroySwapChain(SwapChain *swapChain)
{
std::lock_guard lock(_renderMutex);
_renderable[swapChain].clear();
auto it = std::find(_swapChains.begin(), _swapChains.end(), swapChain);
if (it != _swapChains.end())
{
_swapChains.erase(it);
}
_engine->destroy(swapChain);
Log("Swapchain destroyed.");
#ifdef __EMSCRIPTEN__
_engine->execute();
#else
@@ -1016,53 +1022,49 @@ namespace thermion
}
}
bool FilamentViewer::render(
uint64_t frameTimeInNanos,
SwapChain *swapChain,
void *pixelBuffer,
void (*callback)(void *buf, size_t size, void *data),
void *data)
void FilamentViewer::setRenderable(View* view, SwapChain* swapChain, bool renderable) {
std::lock_guard lock(_renderMutex);
auto views = _renderable[swapChain];
auto it = std::find(views.begin(), views.end(), view);
if(renderable) {
if(it == views.end()) {
views.push_back(view);
}
} else {
if(it != views.end()) {
views.erase(it);
}
}
_renderable[swapChain] = views;
}
void FilamentViewer::render(
uint64_t frameTimeInNanos)
{
if (!swapChain)
{
return false;
}
auto now = std::chrono::high_resolution_clock::now();
auto secsSinceLastFpsCheck = float(std::chrono::duration_cast<std::chrono::seconds>(now - _fpsCounterStartTime).count());
if (secsSinceLastFpsCheck >= 1)
{
auto fps = _frameCount / secsSinceLastFpsCheck;
_frameCount = 0;
_skippedFrames = 0;
_fpsCounterStartTime = now;
}
Timer tmr;
_sceneManager->updateTransforms();
_sceneManager->updateAnimations();
_cumulativeAnimationUpdateTime += tmr.elapsed();
// Render the scene, unless the renderer wants to skip the frame.
bool beginFrame = _renderer->beginFrame(swapChain, frameTimeInNanos);
if (!beginFrame)
{
_skippedFrames++;
} else {
for(auto *view : _renderable) {
_renderer->render(view);
for(auto swapChain : _swapChains) {
auto views = _renderable[swapChain];
if(views.size() > 0) {
bool beginFrame = _renderer->beginFrame(swapChain, frameTimeInNanos);
if (beginFrame) {
for(auto view : views) {
_renderer->render(view);
}
}
}
_frameCount++;
_renderer->endFrame();
}
#ifdef __EMSCRIPTEN__
_engine->execute();
#endif
return beginFrame;
}
class CaptureCallbackHandler : public filament::backend::CallbackHandler

View File

@@ -44,8 +44,9 @@ extern "C"
filament::math::float4{float(d_mat.col4[0]), float(d_mat.col4[1]), float(d_mat.col4[2]), float(d_mat.col4[3])}};
}
EMSCRIPTEN_KEEPALIVE TViewer *create_filament_viewer(const void *context, const void *const loader, void *const platform, const char *uberArchivePath)
EMSCRIPTEN_KEEPALIVE TViewer *Viewer_create(const void *context, const void *const loader, void *const platform, const char *uberArchivePath)
{
Log("CREATE");
const auto *loaderImpl = new ResourceLoaderWrapperImpl((ResourceLoaderWrapper *)loader);
auto viewer = new FilamentViewer(context, loaderImpl, platform, uberArchivePath);
return reinterpret_cast<TViewer *>(viewer);
@@ -339,29 +340,18 @@ extern "C"
cam->setModelMatrix(mat);
}
EMSCRIPTEN_KEEPALIVE bool Viewer_render(
TViewer *tViewer,
TSwapChain *tSwapChain,
uint64_t frameTimeInNanos,
void *pixelBuffer,
void (*callback)(void *buf, size_t size, void *data),
void *data)
EMSCRIPTEN_KEEPALIVE void Viewer_render(
TViewer *tViewer)
{
auto viewer = reinterpret_cast<FilamentViewer *>(tViewer);
auto swapChain = reinterpret_cast<SwapChain *>(tSwapChain);
if(!swapChain) {
swapChain = viewer->getSwapChainAt(0);
}
return viewer->render(frameTimeInNanos, swapChain, pixelBuffer, callback, data);
viewer->render(0);
}
EMSCRIPTEN_KEEPALIVE void Viewer_markViewRenderable(TViewer *tViewer, TView* tView, bool renderable) {
EMSCRIPTEN_KEEPALIVE void Viewer_setViewRenderable(TViewer *tViewer, TSwapChain *tSwapChain, TView *tView, bool renderable) {
auto viewer = reinterpret_cast<FilamentViewer *>(tViewer);
auto swapChain = reinterpret_cast<SwapChain*>(tSwapChain);
auto *view = reinterpret_cast<View*>(tView);
viewer->setRenderable(view, renderable);
viewer->setRenderable(view, swapChain, renderable);
}
EMSCRIPTEN_KEEPALIVE void Viewer_capture(
@@ -416,10 +406,17 @@ extern "C"
viewer->destroySwapChain(swapChain);
}
EMSCRIPTEN_KEEPALIVE TSwapChain *Viewer_createSwapChain(TViewer *tViewer, const void *const window, uint32_t width, uint32_t height)
EMSCRIPTEN_KEEPALIVE TSwapChain *Viewer_createHeadlessSwapChain(TViewer *tViewer, uint32_t width, uint32_t height)
{
auto viewer = reinterpret_cast<FilamentViewer *>(tViewer);
auto swapChain = viewer->createSwapChain(window, width, height);
auto swapChain = viewer->createSwapChain(width, height);
return reinterpret_cast<TSwapChain *>(swapChain);
}
EMSCRIPTEN_KEEPALIVE TSwapChain *Viewer_createSwapChain(TViewer *tViewer, const void *const window)
{
auto viewer = reinterpret_cast<FilamentViewer *>(tViewer);
auto swapChain = viewer->createSwapChain(window);
return reinterpret_cast<TSwapChain *>(swapChain);
}
@@ -721,7 +718,8 @@ extern "C"
EMSCRIPTEN_KEEPALIVE void SceneManager_queueTransformUpdates(TSceneManager *tSceneManager, EntityId *entities, const double *const transforms, int numEntities)
{
auto *sceneManager = reinterpret_cast<SceneManager *>(tSceneManager);
math::mat4 matrices[numEntities];
math::mat4 matrices[
numEntities];
for (int i = 0; i < numEntities; i++)
{
matrices[i] = math::mat4(

View File

@@ -82,10 +82,9 @@ public:
}
}
void requestFrame(TSwapChain* tSwapChain, void (*callback)())
void requestFrame(void (*callback)())
{
std::unique_lock<std::mutex> lock(_mutex);
this->swapChain = tSwapChain;
this->_requestFrameRenderCallback = callback;
}
@@ -93,12 +92,12 @@ public:
{
{
std::unique_lock<std::mutex> lock(_mutex);
if (swapChain)
if (_requestFrameRenderCallback)
{
doRender(swapChain);
doRender();
lock.unlock();
this->_requestFrameRenderCallback();
swapChain = nullptr;
this->_requestFrameRenderCallback = nullptr;
// Calculate and print FPS
auto currentTime = std::chrono::high_resolution_clock::now();
@@ -158,10 +157,13 @@ public:
glClear(GL_COLOR_BUFFER_BIT);
// emscripten_webgl_commit_frame();
_viewer = (FilamentViewer *)create_filament_viewer((void *const)_context, loader, platform, uberArchivePath);
_viewer = (FilamentViewer *)Viewer_create((void *const)_context, loader, platform, uberArchivePath);
MAIN_THREAD_EM_ASM({ moduleArg.dartFilamentResolveCallback($0, $1); }, callback, _viewer);
#else
auto viewer = (FilamentViewer *)create_filament_viewer(context, loader, platform, uberArchivePath);
Log("CREATING1");
auto viewer = (FilamentViewer *)Viewer_create(context, loader, platform, uberArchivePath);
Log("CREATING2");
_viewer = reinterpret_cast<TViewer*>(viewer);
callback(_viewer);
#endif
@@ -180,26 +182,13 @@ public:
fut.wait();
}
bool doRender(TSwapChain *tSwapChain)
void doRender()
{
#ifdef __EMSCRIPTEN__
if (emscripten_is_webgl_context_lost(_context) == EM_TRUE)
{
Log("Context lost");
auto sleepFor = std::chrono::seconds(1);
std::this_thread::sleep_for(sleepFor);
return;
}
#endif
bool rendered = Viewer_render(_viewer, tSwapChain, 0, nullptr, nullptr, nullptr);
Viewer_render(_viewer);
if (_renderCallback)
{
_renderCallback(_renderCallbackOwner);
}
return rendered;
#ifdef __EMSCRIPTEN__
// emscripten_webgl_commit_frame();
#endif
}
void setFrameIntervalInMilliseconds(float frameIntervalInMilliseconds)
@@ -251,7 +240,7 @@ extern "C"
static RenderLoop *_rl;
EMSCRIPTEN_KEEPALIVE void create_filament_viewer_render_thread(
EMSCRIPTEN_KEEPALIVE void Viewer_createOnRenderThread(
void *const context, void *const platform, const char *uberArchivePath,
const void *const loader,
void (*renderCallback)(void *const renderCallbackOwner),
@@ -274,8 +263,7 @@ extern "C"
_rl = nullptr;
}
EMSCRIPTEN_KEEPALIVE void Viewer_createSwapChainRenderThread(TViewer *viewer,
void *const surface,
EMSCRIPTEN_KEEPALIVE void Viewer_createHeadlessSwapChainRenderThread(TViewer *viewer,
uint32_t width,
uint32_t height,
void (*onComplete)(TSwapChain*))
@@ -283,12 +271,21 @@ extern "C"
std::packaged_task<void()> lambda(
[=]() mutable
{
auto *swapChain = Viewer_createSwapChain(viewer, surface, width, height);
#ifdef __EMSCRIPTEN__
MAIN_THREAD_EM_ASM({ moduleArg.dartFilamentResolveCallback($0); }, onComplete);
#else
auto *swapChain = Viewer_createHeadlessSwapChain(viewer, width, height);
onComplete(swapChain);
});
auto fut = _rl->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void Viewer_createSwapChainRenderThread(TViewer *viewer,
void *const surface,
void (*onComplete)(TSwapChain*))
{
std::packaged_task<void()> lambda(
[=]() mutable
{
auto *swapChain = Viewer_createSwapChain(viewer, surface);
onComplete(swapChain);
#endif
});
auto fut = _rl->add_task(lambda);
}
@@ -309,7 +306,7 @@ extern "C"
}
EMSCRIPTEN_KEEPALIVE void Viewer_requestFrameRenderThread(TViewer *viewer, TSwapChain* tSwapChain, void(*onComplete)())
EMSCRIPTEN_KEEPALIVE void Viewer_requestFrameRenderThread(TViewer *viewer, void(*onComplete)())
{
if (!_rl)
{
@@ -317,7 +314,7 @@ extern "C"
}
else
{
_rl->requestFrame(tSwapChain, onComplete);
_rl->requestFrame(onComplete);
}
}
@@ -334,7 +331,7 @@ extern "C"
{
std::packaged_task<void()> lambda([=]() mutable
{
_rl->doRender(tSwapChain);
_rl->doRender();
});
auto fut = _rl->add_task(lambda);
}