@next2d/builder 0.1.7 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +62 -26
- package/package.json +3 -2
- package/templates/xbox/CMakeLists.txt +69 -0
- package/templates/xbox/README.md +16 -8
- package/templates/xbox/cmake/FetchDawn.cmake +47 -6
- package/templates/xbox/cmake/FindV8.cmake +15 -0
- package/templates/xbox/js/bootstrap.js +31 -28
- package/templates/xbox/js/selftest.js +740 -90
- package/templates/xbox/src/EventLoop.cpp +28 -1
- package/templates/xbox/src/EventLoop.h +12 -0
- package/templates/xbox/src/bindings/Audio.cpp +99 -15
- package/templates/xbox/src/bindings/Bindings.h +10 -0
- package/templates/xbox/src/bindings/Canvas.cpp +45 -0
- package/templates/xbox/src/bindings/Canvas2D.cpp +2 -5
- package/templates/xbox/src/bindings/DomShims.cpp +127 -0
- package/templates/xbox/src/bindings/EventTarget.cpp +2 -0
- package/templates/xbox/src/bindings/Fetch.cpp +2 -8
- package/templates/xbox/src/bindings/Image.cpp +212 -10
- package/templates/xbox/src/bindings/Polyfills.cpp +791 -0
- package/templates/xbox/src/bindings/Video.cpp +96 -7
- package/templates/xbox/src/bindings/webgpu/WebGPU.cpp +815 -15
- package/templates/xbox/src/bindings/webgpu/WebGPUCommon.h +3 -8
- package/templates/xbox/src/gpu/DawnContext.cpp +90 -3
- package/templates/xbox/src/gpu/DawnContext.h +18 -0
- package/templates/xbox/src/main.cpp +88 -6
- package/templates/xbox/src/platform/AudioEngine.cpp +9 -3
- package/templates/xbox/src/v8/V8Runtime.cpp +69 -5
- package/templates/xbox/src/v8/V8Util.h +29 -0
- package/templates/xbox/src/v8/WeakHandle.h +45 -0
- package/templates/xbox/src/worker/WorkerRuntime.cpp +325 -41
- package/templates/xbox/src/worker/WorkerRuntime.h +20 -10
- package/templates/xbox/tests/check_local.sh +2 -1
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
#include "ImageSource.h"
|
|
14
14
|
#include "EventTarget.h"
|
|
15
15
|
#include "v8/V8Util.h"
|
|
16
|
+
#include "v8/WeakHandle.h"
|
|
16
17
|
|
|
17
18
|
#include <mfapi.h>
|
|
18
19
|
#include <mfidl.h>
|
|
@@ -47,6 +48,24 @@ struct VideoDecoder {
|
|
|
47
48
|
bool playing = false;
|
|
48
49
|
bool ended = false;
|
|
49
50
|
double duration = 0.0;
|
|
51
|
+
double position = 0.0; // 現在位置 (秒, サンプルタイムスタンプ由来)
|
|
52
|
+
|
|
53
|
+
// 先頭 (または指定秒) へシークする。loop 再生と currentTime 設定で使用。
|
|
54
|
+
bool Seek(double seconds)
|
|
55
|
+
{
|
|
56
|
+
if (!reader) return false;
|
|
57
|
+
PROPVARIANT var;
|
|
58
|
+
PropVariantInit(&var);
|
|
59
|
+
var.vt = VT_I8;
|
|
60
|
+
var.hVal.QuadPart = static_cast<LONGLONG>(seconds * 1e7); // s -> 100ns
|
|
61
|
+
const bool ok = SUCCEEDED(reader->SetCurrentPosition(GUID_NULL, var));
|
|
62
|
+
PropVariantClear(&var);
|
|
63
|
+
if (ok) {
|
|
64
|
+
ended = false;
|
|
65
|
+
position = seconds;
|
|
66
|
+
}
|
|
67
|
+
return ok;
|
|
68
|
+
}
|
|
50
69
|
|
|
51
70
|
bool Open(const std::vector<uint8_t>& bytes)
|
|
52
71
|
{
|
|
@@ -87,13 +106,15 @@ struct VideoDecoder {
|
|
|
87
106
|
{
|
|
88
107
|
if (!reader) return false;
|
|
89
108
|
DWORD flags = 0;
|
|
109
|
+
LONGLONG timestamp = 0;
|
|
90
110
|
ComPtr<IMFSample> sample;
|
|
91
111
|
if (FAILED(reader->ReadSample(MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0,
|
|
92
|
-
nullptr, &flags,
|
|
112
|
+
nullptr, &flags, ×tamp, &sample))) {
|
|
93
113
|
return false;
|
|
94
114
|
}
|
|
95
115
|
if (flags & MF_SOURCE_READERF_ENDOFSTREAM) { ended = true; return false; }
|
|
96
116
|
if (!sample) return false;
|
|
117
|
+
position = static_cast<double>(timestamp) / 1e7; // 100ns -> s
|
|
97
118
|
|
|
98
119
|
ComPtr<IMFMediaBuffer> buffer;
|
|
99
120
|
sample->ConvertToContiguousBuffer(&buffer);
|
|
@@ -112,8 +133,6 @@ struct VideoDecoder {
|
|
|
112
133
|
}
|
|
113
134
|
};
|
|
114
135
|
|
|
115
|
-
void ReleaseVideo(const v8::WeakCallbackInfo<VideoDecoder>& info) { delete info.GetParameter(); }
|
|
116
|
-
|
|
117
136
|
VideoDecoder* Decoder(v8::Local<v8::Object> obj)
|
|
118
137
|
{
|
|
119
138
|
return static_cast<VideoDecoder*>(obj->GetInternalField(0).As<v8::External>()->Value());
|
|
@@ -144,7 +163,10 @@ void LoadVideo(v8::Isolate* isolate, v8::Local<v8::Object> self, const std::stri
|
|
|
144
163
|
SetValue(isolate, self, "videoHeight", v8::Integer::NewFromUnsigned(isolate, dec->height));
|
|
145
164
|
SetValue(isolate, self, "duration", v8::Number::New(isolate, dec->duration));
|
|
146
165
|
SetValue(isolate, self, "readyState", v8::Integer::New(isolate, 4));
|
|
166
|
+
// player は loadedmetadata / progress / canplaythrough を購読する
|
|
167
|
+
// (VideoRegisterEventUseCase)。ローカル読み込みは即完了のため順に発火する。
|
|
147
168
|
FireVideoEvent(isolate, self, "loadedmetadata");
|
|
169
|
+
FireVideoEvent(isolate, self, "progress");
|
|
148
170
|
FireVideoEvent(isolate, self, "canplaythrough");
|
|
149
171
|
} else {
|
|
150
172
|
FireVideoEvent(isolate, self, "error");
|
|
@@ -162,7 +184,20 @@ bool GetVideoFramePixels(v8::Isolate* isolate, v8::Local<v8::Object> obj,
|
|
|
162
184
|
if (dec->playing && !dec->ended) {
|
|
163
185
|
dec->ReadNextFrame(); // 描画のたびに次フレームへ進める(簡易フレーム進行)
|
|
164
186
|
if (dec->ended) {
|
|
165
|
-
|
|
187
|
+
// loop 指定時は先頭へ戻して継続、そうでなければ ended を通知
|
|
188
|
+
v8::Local<v8::Value> loop_v;
|
|
189
|
+
const bool loop =
|
|
190
|
+
obj->Get(isolate->GetCurrentContext(),
|
|
191
|
+
v8util::Str(isolate, "loop")).ToLocal(&loop_v) &&
|
|
192
|
+
loop_v->BooleanValue(isolate);
|
|
193
|
+
if (loop && dec->Seek(0.0)) {
|
|
194
|
+
dec->ReadNextFrame();
|
|
195
|
+
} else {
|
|
196
|
+
dec->playing = false;
|
|
197
|
+
SetValue(isolate, obj, "ended", v8::Boolean::New(isolate, true));
|
|
198
|
+
SetValue(isolate, obj, "paused", v8::Boolean::New(isolate, true));
|
|
199
|
+
FireVideoEvent(isolate, obj, "ended");
|
|
200
|
+
}
|
|
166
201
|
}
|
|
167
202
|
}
|
|
168
203
|
*out_rgba = dec->frame.data();
|
|
@@ -180,19 +215,69 @@ v8::Local<v8::Object> CreateVideoElement(v8::Isolate* isolate, HostContext* /*ho
|
|
|
180
215
|
|
|
181
216
|
auto* dec = new VideoDecoder();
|
|
182
217
|
self->SetInternalField(0, v8::External::New(isolate, dec));
|
|
183
|
-
|
|
184
|
-
handle->SetWeak(dec, ReleaseVideo, v8::WeakCallbackType::kParameter);
|
|
218
|
+
v8util::AttachWeak(isolate, self, dec);
|
|
185
219
|
|
|
186
220
|
SetValue(isolate, self, "__isVideoElement", v8::Boolean::New(isolate, true));
|
|
187
221
|
SetValue(isolate, self, "tagName", Str(isolate, "VIDEO"));
|
|
188
222
|
SetValue(isolate, self, "videoWidth", v8::Integer::New(isolate, 0));
|
|
189
223
|
SetValue(isolate, self, "videoHeight", v8::Integer::New(isolate, 0));
|
|
190
|
-
SetValue(isolate, self, "currentTime", v8::Number::New(isolate, 0));
|
|
191
224
|
SetValue(isolate, self, "readyState", v8::Integer::New(isolate, 0));
|
|
192
225
|
SetValue(isolate, self, "loop", v8::Boolean::New(isolate, false));
|
|
226
|
+
SetValue(isolate, self, "paused", v8::Boolean::New(isolate, true));
|
|
227
|
+
SetValue(isolate, self, "ended", v8::Boolean::New(isolate, false));
|
|
228
|
+
SetValue(isolate, self, "muted", v8::Boolean::New(isolate, false));
|
|
229
|
+
SetValue(isolate, self, "volume", v8::Number::New(isolate, 1.0));
|
|
230
|
+
SetValue(isolate, self, "autoplay", v8::Boolean::New(isolate, false));
|
|
193
231
|
SetValue(isolate, self, "style", v8::Object::New(isolate));
|
|
194
232
|
InstallEventTarget(isolate, self);
|
|
195
233
|
|
|
234
|
+
// currentTime: 取得はデコーダの現在位置、設定はシーク
|
|
235
|
+
self->SetNativeDataProperty(ctx, Str(isolate, "currentTime"),
|
|
236
|
+
[](v8::Local<v8::Name>, const v8::PropertyCallbackInfo<v8::Value>& info) {
|
|
237
|
+
VideoDecoder* d = Decoder(info.This());
|
|
238
|
+
info.GetReturnValue().Set(
|
|
239
|
+
v8::Number::New(info.GetIsolate(), d ? d->position : 0.0));
|
|
240
|
+
},
|
|
241
|
+
[](v8::Local<v8::Name>, v8::Local<v8::Value> value,
|
|
242
|
+
const v8::PropertyCallbackInfo<void>& info) {
|
|
243
|
+
if (!value->IsNumber()) return;
|
|
244
|
+
VideoDecoder* d = Decoder(info.This());
|
|
245
|
+
if (d) {
|
|
246
|
+
d->Seek(value.As<v8::Number>()->Value());
|
|
247
|
+
}
|
|
248
|
+
}).Check();
|
|
249
|
+
|
|
250
|
+
// setAttribute / getAttribute (player は playsinline を設定する)
|
|
251
|
+
SetMethod(isolate, self, "setAttribute",
|
|
252
|
+
[](const v8::FunctionCallbackInfo<v8::Value>& a) {
|
|
253
|
+
if (a.Length() < 2) return;
|
|
254
|
+
v8::Isolate* iso = a.GetIsolate();
|
|
255
|
+
v8::Local<v8::Context> c = iso->GetCurrentContext();
|
|
256
|
+
v8::Local<v8::Value> attrs;
|
|
257
|
+
v8::Local<v8::Object> store;
|
|
258
|
+
if (a.This()->Get(c, v8util::Str(iso, "__attrs")).ToLocal(&attrs) && attrs->IsObject()) {
|
|
259
|
+
store = attrs.As<v8::Object>();
|
|
260
|
+
} else {
|
|
261
|
+
store = v8::Object::New(iso);
|
|
262
|
+
SetValue(iso, a.This(), "__attrs", store);
|
|
263
|
+
}
|
|
264
|
+
store->Set(c, a[0], a[1]).Check();
|
|
265
|
+
});
|
|
266
|
+
SetMethod(isolate, self, "getAttribute",
|
|
267
|
+
[](const v8::FunctionCallbackInfo<v8::Value>& a) {
|
|
268
|
+
a.GetReturnValue().SetNull();
|
|
269
|
+
if (a.Length() < 1) return;
|
|
270
|
+
v8::Isolate* iso = a.GetIsolate();
|
|
271
|
+
v8::Local<v8::Context> c = iso->GetCurrentContext();
|
|
272
|
+
v8::Local<v8::Value> attrs;
|
|
273
|
+
if (a.This()->Get(c, v8util::Str(iso, "__attrs")).ToLocal(&attrs) && attrs->IsObject()) {
|
|
274
|
+
v8::Local<v8::Value> v;
|
|
275
|
+
if (attrs.As<v8::Object>()->Get(c, a[0]).ToLocal(&v) && !v->IsUndefined()) {
|
|
276
|
+
a.GetReturnValue().Set(v);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
|
|
196
281
|
// src セッター: 代入で読み込み開始
|
|
197
282
|
self->SetNativeDataProperty(ctx, Str(isolate, "src"),
|
|
198
283
|
[](v8::Local<v8::Name>, const v8::PropertyCallbackInfo<v8::Value>& info) {
|
|
@@ -218,12 +303,16 @@ v8::Local<v8::Object> CreateVideoElement(v8::Isolate* isolate, HostContext* /*ho
|
|
|
218
303
|
SetMethod(isolate, self, "play", [](const v8::FunctionCallbackInfo<v8::Value>& a) {
|
|
219
304
|
v8::Isolate* iso = a.GetIsolate();
|
|
220
305
|
Decoder(a.This())->playing = true;
|
|
306
|
+
SetValue(iso, a.This(), "paused", v8::Boolean::New(iso, false));
|
|
307
|
+
SetValue(iso, a.This(), "ended", v8::Boolean::New(iso, false));
|
|
221
308
|
auto r = v8::Promise::Resolver::New(iso->GetCurrentContext()).ToLocalChecked();
|
|
222
309
|
r->Resolve(iso->GetCurrentContext(), v8::Undefined(iso)).Check();
|
|
223
310
|
a.GetReturnValue().Set(r->GetPromise());
|
|
224
311
|
});
|
|
225
312
|
SetMethod(isolate, self, "pause", [](const v8::FunctionCallbackInfo<v8::Value>& a) {
|
|
313
|
+
v8::Isolate* iso = a.GetIsolate();
|
|
226
314
|
Decoder(a.This())->playing = false;
|
|
315
|
+
SetValue(iso, a.This(), "paused", v8::Boolean::New(iso, true));
|
|
227
316
|
});
|
|
228
317
|
SetMethod(isolate, self, "canPlayType", [](const v8::FunctionCallbackInfo<v8::Value>& a) {
|
|
229
318
|
a.GetReturnValue().Set(Str(a.GetIsolate(), "maybe"));
|