Skip to content

Commit 2ca2076

Browse files
committed
Use ArrayBufferView input and return Blob
1 parent 19da7ed commit 2ca2076

File tree

4 files changed

+22
-20
lines changed

4 files changed

+22
-20
lines changed

CMakeLists.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,9 @@ FetchContent_Declare(ios-cmake
3636
GIT_REPOSITORY https://github.com/leetal/ios-cmake.git
3737
GIT_TAG 4.5.0)
3838
FetchContent_Declare(JsRuntimeHost
39-
GIT_REPOSITORY https://github.com/BabylonJS/JsRuntimeHost.git
40-
GIT_TAG ef57990dc5533990b2bb194978a12f8c8d83565c)
39+
# TODO: Update with latest upstream once https://github.com/BabylonJS/JsRuntimeHost/pull/120 is in
40+
GIT_REPOSITORY https://github.com/alexchuber/JsRuntimeHost.git
41+
GIT_TAG 2bf8034be4348bb573cb005671184bf9fdaf9ae3)
4142
FetchContent_Declare(SPIRV-Cross
4243
GIT_REPOSITORY https://github.com/BabylonJS/SPIRV-Cross.git
4344
GIT_TAG 6abfcf066d171e9ade7604d91381ebebe4209edc)

Install/Install.cmake

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,3 +187,8 @@ if(TARGET XMLHttpRequest)
187187
install_targets(XMLHttpRequest)
188188
install_include_for_targets(XMLHttpRequest)
189189
endif()
190+
191+
if(TARGET Blob)
192+
install_targets(Blob)
193+
install_include_for_targets(Blob)
194+
endif()

Plugins/NativeEncoding/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ target_link_libraries(NativeEncoding
1212
PUBLIC napi
1313
PRIVATE GraphicsDevice
1414
PRIVATE GraphicsDeviceContext
15-
PRIVATE JsRuntimeInternal)
15+
PRIVATE JsRuntimeInternal
16+
PRIVATE Blob)
1617

1718
set_property(TARGET NativeEncoding PROPERTY FOLDER Plugins)
1819
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCES})

Plugins/NativeEncoding/Source/NativeEncoding.cpp

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <Babylon/JsRuntime.h>
33
#include <Babylon/JsRuntimeScheduler.h>
44
#include <Babylon/Graphics/DeviceContext.h>
5+
#include <Babylon/Polyfills/Blob.h>
56

67
#include <napi/napi.h>
78

@@ -15,7 +16,7 @@ namespace Babylon::Plugins
1516
{
1617
namespace
1718
{
18-
std::shared_ptr<std::vector<uint8_t>> EncodePNG(const std::vector<uint8_t>& pixelData, uint32_t width, uint32_t height, bool invertY)
19+
std::unique_ptr<std::vector<std::byte>> EncodePNG(const std::vector<uint8_t>& pixelData, uint32_t width, uint32_t height, bool invertY)
1920
{
2021
auto memoryBlock{bx::MemoryBlock(&Graphics::DeviceContext::GetDefaultAllocator())};
2122
auto writer{bx::MemoryWriter(&memoryBlock)};
@@ -35,28 +36,22 @@ namespace Babylon::Plugins
3536
throw std::runtime_error("Failed to encode PNG image: output is empty");
3637
}
3738

38-
auto result{std::make_shared<std::vector<uint8_t>>(byteLength)};
39+
auto result{std::make_unique<std::vector<std::byte>>(byteLength)};
3940
std::memcpy(result->data(), memoryBlock.more(0), byteLength);
4041

4142
return result;
4243
}
4344

4445
Napi::Value EncodeImageAsync(const Napi::CallbackInfo& info)
4546
{
46-
auto buffer{info[0].As<Napi::Uint8Array>()};
47+
auto buffer{info[0].As<Napi::TypedArray>()}; // ArrayBufferView
4748
auto width{info[1].As<Napi::Number>().Uint32Value()};
4849
auto height{info[2].As<Napi::Number>().Uint32Value()};
49-
auto mimeType{info[3].As<Napi::String>().Utf8Value()};
50-
auto invertY{info[4].As<Napi::Boolean>().Value()};
50+
//auto mimeType{info[3].As<Napi::String>().Utf8Value()}; // Discard for now, only PNG is supported
51+
auto invertY{info.Length() > 4 && info[4].ToBoolean().Value()};
5152

5253
auto env{info.Env()};
5354
auto deferred{Napi::Promise::Deferred::New(env)};
54-
55-
if (mimeType != "image/png")
56-
{
57-
deferred.Reject(Napi::Error::New(env, "Unsupported mime type: " + mimeType + ". Only image/png is currently supported.").Value());
58-
return deferred.Promise();
59-
}
6055

6156
if (buffer.ByteLength() != width * height * 4)
6257
{
@@ -65,14 +60,15 @@ namespace Babylon::Plugins
6560
}
6661

6762
auto runtimeScheduler{std::make_shared<JsRuntimeScheduler>(JsRuntime::GetFromJavaScript(env))};
68-
auto pixelData{std::vector<uint8_t>(buffer.Data(), buffer.Data() + buffer.ByteLength())};
63+
auto start = static_cast<uint8_t*>(buffer.ArrayBuffer().Data()) + buffer.ByteOffset();
64+
auto pixelData{std::vector<uint8_t>(start, start + buffer.ByteLength())};
6965

7066
arcana::make_task(arcana::threadpool_scheduler, arcana::cancellation_source::none(),
7167
[pixelData{std::move(pixelData)}, width, height, invertY]() {
7268
return EncodePNG(pixelData, width, height, invertY);
7369
})
7470
.then(*runtimeScheduler, arcana::cancellation_source::none(),
75-
[runtimeScheduler, deferred, env](const arcana::expected<std::shared_ptr<std::vector<uint8_t>>, std::exception_ptr>& result) {
71+
[runtimeScheduler, deferred, env](const arcana::expected<std::unique_ptr<std::vector<std::byte>>, std::exception_ptr>& result) {
7672
// TODO: Crash risk on JS teardown - this async work isn't tied to any JS object lifetime,
7773
// unlike other plugins that cancel / clean up pending work in their destructors.
7874
if (result.has_error())
@@ -81,10 +77,9 @@ namespace Babylon::Plugins
8177
return;
8278
}
8379

84-
auto& imageData = result.value();
85-
auto arrayBuffer{Napi::ArrayBuffer::New(env, imageData->data(), imageData->size(), [imageData](Napi::Env, void*) {})};
86-
87-
deferred.Resolve(arrayBuffer);
80+
auto blob{Babylon::Polyfills::Blob::CreateInstance(env, std::move(*result.value()), "image/png")};
81+
82+
deferred.Resolve(blob);
8883
});
8984

9085
return deferred.Promise();

0 commit comments

Comments
 (0)