@@ -458,6 +458,7 @@ namespace Babylon
458
458
InstanceMethod (" updateDynamicVertexBuffer" , &NativeEngine::UpdateDynamicVertexBuffer),
459
459
460
460
InstanceMethod (" createProgram" , &NativeEngine::CreateProgram),
461
+ InstanceMethod (" createProgramAsync" , &NativeEngine::CreateProgramAsync),
461
462
InstanceMethod (" getUniforms" , &NativeEngine::GetUniforms),
462
463
InstanceMethod (" getAttributes" , &NativeEngine::GetAttributes),
463
464
@@ -687,22 +688,11 @@ namespace Babylon
687
688
return vertexSource;
688
689
}
689
690
690
- Napi::Value NativeEngine::CreateProgram (const Napi::CallbackInfo& info )
691
+ std::unique_ptr<ProgramData> NativeEngine::CreateProgramInternal (const std::string vertexSource, const std::string fragmentSource )
691
692
{
692
- const std::string vertexSource = info[0 ].As <Napi::String>().Utf8Value ();
693
- const std::string fragmentSource = info[1 ].As <Napi::String>().Utf8Value ();
693
+ ShaderCompiler::BgfxShaderInfo shaderInfo = m_shaderCompiler.Compile (ProcessShaderCoordinates (vertexSource), ProcessSamplerFlip (fragmentSource));
694
694
695
- ProgramData* program = new ProgramData{};
696
- ShaderCompiler::BgfxShaderInfo shaderInfo{};
697
-
698
- try
699
- {
700
- shaderInfo = m_shaderCompiler.Compile (ProcessShaderCoordinates (vertexSource), ProcessSamplerFlip (fragmentSource));
701
- }
702
- catch (const std::exception& ex)
703
- {
704
- throw Napi::Error::New (info.Env (), ex.what ());
705
- }
695
+ std::unique_ptr<ProgramData> program = std::make_unique<ProgramData>();
706
696
707
697
static auto InitUniformInfos{
708
698
[](bgfx::ShaderHandle shader, const std::unordered_map<std::string, uint8_t >& uniformStages, std::unordered_map<uint16_t , UniformInfo>& uniformInfos, std::unordered_map<std::string, uint16_t >& uniformNameToIndex) {
@@ -724,13 +714,67 @@ namespace Babylon
724
714
725
715
auto vertexShader = bgfx::createShader (bgfx::copy (shaderInfo.VertexBytes .data (), static_cast <uint32_t >(shaderInfo.VertexBytes .size ())));
726
716
InitUniformInfos (vertexShader, shaderInfo.UniformStages , program->UniformInfos , program->UniformNameToIndex );
727
- program->VertexAttributeLocations = std::move (shaderInfo.VertexAttributeLocations );
728
717
729
718
auto fragmentShader = bgfx::createShader (bgfx::copy (shaderInfo.FragmentBytes .data (), static_cast <uint32_t >(shaderInfo.FragmentBytes .size ())));
730
719
InitUniformInfos (fragmentShader, shaderInfo.UniformStages , program->UniformInfos , program->UniformNameToIndex );
731
720
732
721
program->Handle = bgfx::createProgram (vertexShader, fragmentShader, true );
733
- return Napi::Pointer<ProgramData>::Create (info.Env (), program, Napi::NapiPointerDeleter (program));
722
+ program->VertexAttributeLocations = std::move (shaderInfo.VertexAttributeLocations );
723
+
724
+ return program;
725
+ }
726
+
727
+ Napi::Value NativeEngine::CreateProgram (const Napi::CallbackInfo& info)
728
+ {
729
+ const std::string vertexSource = info[0 ].As <Napi::String>().Utf8Value ();
730
+ const std::string fragmentSource = info[1 ].As <Napi::String>().Utf8Value ();
731
+ ProgramData* program = new ProgramData{};
732
+ Napi::Value jsProgram = Napi::Pointer<ProgramData>::Create (info.Env (), program, Napi::NapiPointerDeleter (program));
733
+ try
734
+ {
735
+ *program = std::move (*CreateProgramInternal (vertexSource, fragmentSource));
736
+ }
737
+ catch (const std::exception& ex)
738
+ {
739
+ throw Napi::Error::New (info.Env (), ex.what ());
740
+ }
741
+ return jsProgram;
742
+ }
743
+
744
+ Napi::Value NativeEngine::CreateProgramAsync (const Napi::CallbackInfo& info)
745
+ {
746
+ const std::string vertexSource = info[0 ].As <Napi::String>().Utf8Value ();
747
+ const std::string fragmentSource = info[1 ].As <Napi::String>().Utf8Value ();
748
+ const Napi::Function onSuccess = info[2 ].As <Napi::Function>();
749
+ const Napi::Function onError = info[3 ].As <Napi::Function>();
750
+
751
+ ProgramData* program = new ProgramData{};
752
+ Napi::Value jsProgram = Napi::Pointer<ProgramData>::Create (info.Env (), program, Napi::NapiPointerDeleter (program));
753
+
754
+ arcana::make_task (arcana::threadpool_scheduler, *m_cancellationSource,
755
+ [this , vertexSource, fragmentSource, cancellationSource{m_cancellationSource}]() -> std::unique_ptr<ProgramData>
756
+ {
757
+ return CreateProgramInternal (vertexSource, fragmentSource);
758
+ })
759
+ .then (m_runtimeScheduler, *m_cancellationSource,
760
+ [program,
761
+ jsProgramRef{Napi::Persistent (jsProgram)},
762
+ onSuccessRef{Napi::Persistent (onSuccess)},
763
+ onErrorRef{Napi::Persistent (onError)},
764
+ cancellationSource{m_cancellationSource}](const arcana::expected<std::unique_ptr<ProgramData>, std::exception_ptr>& result)
765
+ {
766
+ if (result.has_error ())
767
+ {
768
+ onErrorRef.Call ({Napi::Error::New (onErrorRef.Env (), result.error ()).Value ()});
769
+ }
770
+ else
771
+ {
772
+ *program = std::move (*result.value ());
773
+ onSuccessRef.Call ({});
774
+ }
775
+ });
776
+
777
+ return jsProgram;
734
778
}
735
779
736
780
Napi::Value NativeEngine::GetUniforms (const Napi::CallbackInfo& info)
0 commit comments