@flighthq/texture 0.5.1-next.1295.2b6bfa3 → 0.5.1-next.1345.0995dc5
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/README.md +2 -2
- package/dist/videoTexture.d.ts +7 -7
- package/dist/videoTexture.d.ts.map +1 -1
- package/dist/videoTexture.js +27 -24
- package/dist/videoTexture.js.map +1 -1
- package/package.json +4 -4
- package/src/videoTexture.test.ts +105 -39
package/README.md
CHANGED
|
@@ -13,5 +13,5 @@ Import the supported application-facing API from `@flighthq/texture`. The `@flig
|
|
|
13
13
|
This package is part of the locked-version Flight SDK graph. Applications may instead install and import `@flighthq/sdk` when package-level tree shaking is sufficient.
|
|
14
14
|
|
|
15
15
|
- [Flight project](https://github.com/flighthq/flight)
|
|
16
|
-
- [Source for @flighthq/texture@0.5.1-next.
|
|
17
|
-
- [License](https://github.com/flighthq/flight/blob/
|
|
16
|
+
- [Source for @flighthq/texture@0.5.1-next.1345.0995dc5](https://github.com/flighthq/flight/tree/0995dc5f840e6b57c3e85ecd2123aa798cf60b29/packages/texture)
|
|
17
|
+
- [License](https://github.com/flighthq/flight/blob/0995dc5f840e6b57c3e85ecd2123aa798cf60b29/LICENSE.md)
|
package/dist/videoTexture.d.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import type { EntityConstruction, HostImageSource, ImageResource, Matrix3Like, Texture, Texture2D, TextureLike, VideoResource } from '@flighthq/types/contract';
|
|
2
|
-
export declare function advanceVideoTexture(texture: TextureLike): number;
|
|
1
|
+
import type { EntityConstruction, HostImageSource, HostVideoProvider, ImageResource, Matrix3Like, Texture, Texture2D, TextureLike, VideoResource } from '@flighthq/types/contract';
|
|
2
|
+
export declare function advanceVideoTexture(hostVideo: Readonly<HostVideoProvider>, texture: TextureLike): number;
|
|
3
3
|
export declare function cloneVideoTexture(source: Readonly<TextureLike>): Texture;
|
|
4
4
|
export declare function copyVideoTexture(out: TextureLike, source: Readonly<TextureLike>): void;
|
|
5
|
-
export declare function createVideoTexture(source: VideoResource, opts?: Readonly<Partial<TextureLike>>): Texture2D;
|
|
5
|
+
export declare function createVideoTexture(hostVideo: Readonly<HostVideoProvider>, source: VideoResource, opts?: Readonly<Partial<TextureLike>>): Texture2D;
|
|
6
6
|
export declare function destroyVideoTexture(texture: Texture2D): void;
|
|
7
|
-
export declare function getVideoTextureHeight(texture: Readonly<TextureLike>): number;
|
|
7
|
+
export declare function getVideoTextureHeight(hostVideo: Readonly<HostVideoProvider>, texture: Readonly<TextureLike>): number;
|
|
8
8
|
export declare function getVideoTextureInverseUvMatrix(out: Matrix3Like, texture: Readonly<TextureLike>): void;
|
|
9
9
|
export declare function getVideoTextureUvMatrix(out: Matrix3Like, texture: Readonly<TextureLike>): void;
|
|
10
|
-
export declare function getVideoTextureWidth(texture: Readonly<TextureLike>): number;
|
|
10
|
+
export declare function getVideoTextureWidth(hostVideo: Readonly<HostVideoProvider>, texture: Readonly<TextureLike>): number;
|
|
11
11
|
export declare function initializeVideoImageResource(out: EntityConstruction<ImageResource>, source: HostImageSource, version: number): void;
|
|
12
|
-
export declare function isVideoTextureFrameReady(texture: Readonly<TextureLike>): boolean;
|
|
12
|
+
export declare function isVideoTextureFrameReady(hostVideo: Readonly<HostVideoProvider>, texture: Readonly<TextureLike>): boolean;
|
|
13
13
|
export declare function resetVideoTextureFrame(texture: TextureLike): void;
|
|
14
|
-
export declare function setVideoTextureSource(texture: TextureLike, source: VideoResource): void;
|
|
14
|
+
export declare function setVideoTextureSource(hostVideo: Readonly<HostVideoProvider>, texture: TextureLike, source: VideoResource): void;
|
|
15
15
|
//# sourceMappingURL=videoTexture.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"videoTexture.d.ts","sourceRoot":"","sources":["../src/videoTexture.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,kBAAkB,EAClB,eAAe,EACf,aAAa,EACb,WAAW,EACX,OAAO,EACP,SAAS,EACT,WAAW,EACX,aAAa,EACd,MAAM,0BAA0B,CAAC;AAOlC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"videoTexture.d.ts","sourceRoot":"","sources":["../src/videoTexture.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,OAAO,EACP,SAAS,EACT,WAAW,EACX,aAAa,EACd,MAAM,0BAA0B,CAAC;AAOlC,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,EAAE,WAAW,GAAG,MAAM,CAOxG;AAGD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,QAAQ,CAAC,WAAW,CAAC,GAAG,OAAO,CAExE;AAGD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,CAAC,WAAW,CAAC,GAAG,IAAI,CAEtF;AAKD,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,QAAQ,CAAC,iBAAiB,CAAC,EACtC,MAAM,EAAE,aAAa,EACrB,IAAI,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,GACpC,SAAS,CAQX;AAID,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,SAAS,GAAG,IAAI,CAG5D;AAGD,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,WAAW,CAAC,GAAG,MAAM,CAIpH;AAGD,wBAAgB,8BAA8B,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,CAAC,WAAW,CAAC,GAAG,IAAI,CAGrG;AAGD,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,CAAC,WAAW,CAAC,GAAG,IAAI,CAE9F;AAGD,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,WAAW,CAAC,GAAG,MAAM,CAInH;AAED,wBAAgB,4BAA4B,CAC1C,GAAG,EAAE,kBAAkB,CAAC,aAAa,CAAC,EACtC,MAAM,EAAE,eAAe,EACvB,OAAO,EAAE,MAAM,GACd,IAAI,CAQN;AAGD,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,QAAQ,CAAC,iBAAiB,CAAC,EACtC,OAAO,EAAE,QAAQ,CAAC,WAAW,CAAC,GAC7B,OAAO,CAQT;AAGD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAIjE;AAID,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,QAAQ,CAAC,iBAAiB,CAAC,EACtC,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,aAAa,GACpB,IAAI,CAIN"}
|
package/dist/videoTexture.js
CHANGED
|
@@ -4,11 +4,11 @@ import { ImageTextureSourceKind } from '@flighthq/types/contract';
|
|
|
4
4
|
import { cloneTexture, copyTexture, createTexture, getTextureUvMatrix } from './texture';
|
|
5
5
|
// Marks a fresh decoded frame on a video-backed Texture. The ImageResource is the shared CPU-origin source
|
|
6
6
|
// and owns the upload revision; Texture.version mirrors it as the sampled object's dirty-bit.
|
|
7
|
-
export function advanceVideoTexture(texture) {
|
|
7
|
+
export function advanceVideoTexture(hostVideo, texture) {
|
|
8
8
|
const image = getVideoImage(texture);
|
|
9
9
|
if (image == null)
|
|
10
10
|
return texture.version;
|
|
11
|
-
updateVideoImageSize(image);
|
|
11
|
+
updateVideoImageSize(hostVideo, image);
|
|
12
12
|
image.version = (image.version + 1) >>> 0;
|
|
13
13
|
texture.version = image.version;
|
|
14
14
|
return texture.version;
|
|
@@ -24,8 +24,8 @@ export function copyVideoTexture(out, source) {
|
|
|
24
24
|
// Wraps a VideoResource's borrowed host element in an ImageResource source and returns the same
|
|
25
25
|
// universal Texture type used by still images and render targets. The all-ones initial revision
|
|
26
26
|
// preserves the former first advanceVideoTexture result of 0 after u32 wrap.
|
|
27
|
-
export function createVideoTexture(source, opts) {
|
|
28
|
-
const image = createVideoImageResource(source);
|
|
27
|
+
export function createVideoTexture(hostVideo, source, opts) {
|
|
28
|
+
const image = createVideoImageResource(hostVideo, source);
|
|
29
29
|
return createTexture({
|
|
30
30
|
...opts,
|
|
31
31
|
dimension: '2d',
|
|
@@ -40,9 +40,10 @@ export function destroyVideoTexture(texture) {
|
|
|
40
40
|
texture.version = INITIAL_VIDEO_VERSION;
|
|
41
41
|
}
|
|
42
42
|
// Returns the decoded frame height, or -1 while the borrowed host element is absent/unready.
|
|
43
|
-
export function getVideoTextureHeight(texture) {
|
|
44
|
-
const
|
|
45
|
-
|
|
43
|
+
export function getVideoTextureHeight(hostVideo, texture) {
|
|
44
|
+
const source = getVideoSource(texture);
|
|
45
|
+
const height = source !== null ? (hostVideo.getHeight?.(source) ?? 0) : 0;
|
|
46
|
+
return height > 0 ? height : -1;
|
|
46
47
|
}
|
|
47
48
|
// Video-named compatibility entry over the universal Texture UV transform.
|
|
48
49
|
export function getVideoTextureInverseUvMatrix(out, texture) {
|
|
@@ -54,9 +55,10 @@ export function getVideoTextureUvMatrix(out, texture) {
|
|
|
54
55
|
getTextureUvMatrix(out, texture);
|
|
55
56
|
}
|
|
56
57
|
// Returns the decoded frame width, or -1 while the borrowed host element is absent/unready.
|
|
57
|
-
export function getVideoTextureWidth(texture) {
|
|
58
|
-
const
|
|
59
|
-
|
|
58
|
+
export function getVideoTextureWidth(hostVideo, texture) {
|
|
59
|
+
const source = getVideoSource(texture);
|
|
60
|
+
const width = source !== null ? (hostVideo.getWidth?.(source) ?? 0) : 0;
|
|
61
|
+
return width > 0 ? width : -1;
|
|
60
62
|
}
|
|
61
63
|
export function initializeVideoImageResource(out, source, version) {
|
|
62
64
|
out.alphaType = 'straight';
|
|
@@ -68,9 +70,12 @@ export function initializeVideoImageResource(out, source, version) {
|
|
|
68
70
|
out.width = 0;
|
|
69
71
|
}
|
|
70
72
|
// True once the borrowed host element exposes a decoded current frame and non-zero dimensions.
|
|
71
|
-
export function isVideoTextureFrameReady(texture) {
|
|
72
|
-
const
|
|
73
|
-
return (
|
|
73
|
+
export function isVideoTextureFrameReady(hostVideo, texture) {
|
|
74
|
+
const source = getVideoSource(texture);
|
|
75
|
+
return (source !== null &&
|
|
76
|
+
hostVideo.isReady?.(source) === true &&
|
|
77
|
+
(hostVideo.getWidth?.(source) ?? 0) > 0 &&
|
|
78
|
+
(hostVideo.getHeight?.(source) ?? 0) > 0);
|
|
74
79
|
}
|
|
75
80
|
// Resets the shared source revision so its next advance wraps to 0 and every state re-uploads.
|
|
76
81
|
export function resetVideoTextureFrame(texture) {
|
|
@@ -81,32 +86,30 @@ export function resetVideoTextureFrame(texture) {
|
|
|
81
86
|
}
|
|
82
87
|
// Replaces the immutable host-backed identity and resets its upload revision. The VideoResource
|
|
83
88
|
// remains the loader/lifecycle object; Texture stores only its current host handle.
|
|
84
|
-
export function setVideoTextureSource(texture, source) {
|
|
89
|
+
export function setVideoTextureSource(hostVideo, texture, source) {
|
|
85
90
|
if (texture.dimension !== '2d')
|
|
86
91
|
throw new Error('setVideoTextureSource requires a Texture2D');
|
|
87
|
-
texture.source = createVideoImageResource(source);
|
|
92
|
+
texture.source = createVideoImageResource(hostVideo, source);
|
|
88
93
|
texture.version = INITIAL_VIDEO_VERSION;
|
|
89
94
|
}
|
|
90
|
-
function createVideoImageResource(source) {
|
|
95
|
+
function createVideoImageResource(hostVideo, source) {
|
|
91
96
|
if (source.element === null)
|
|
92
97
|
return null;
|
|
93
98
|
const image = allocateEntity();
|
|
94
99
|
initializeVideoImageResource(image, source.element, INITIAL_VIDEO_VERSION);
|
|
95
|
-
updateVideoImageSize(image);
|
|
100
|
+
updateVideoImageSize(hostVideo, image);
|
|
96
101
|
return finishEntity(image);
|
|
97
102
|
}
|
|
98
|
-
function
|
|
103
|
+
function getVideoSource(texture) {
|
|
99
104
|
return getVideoImage(texture)?.source ?? null;
|
|
100
105
|
}
|
|
101
106
|
function getVideoImage(texture) {
|
|
102
107
|
return texture.dimension === '2d' ? texture.source : null;
|
|
103
108
|
}
|
|
104
|
-
function updateVideoImageSize(image) {
|
|
105
|
-
|
|
106
|
-
image.
|
|
107
|
-
image.height = element.videoHeight || 0;
|
|
109
|
+
function updateVideoImageSize(hostVideo, image) {
|
|
110
|
+
image.width = hostVideo.getWidth?.(image.source) ?? 0;
|
|
111
|
+
image.height = hostVideo.getHeight?.(image.source) ?? 0;
|
|
108
112
|
}
|
|
109
|
-
//
|
|
110
|
-
const HAVE_CURRENT_DATA = 2;
|
|
113
|
+
// The u32 predecessor of the first public frame revision.
|
|
111
114
|
const INITIAL_VIDEO_VERSION = 0xffffffff;
|
|
112
115
|
//# sourceMappingURL=videoTexture.js.map
|
package/dist/videoTexture.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"videoTexture.js","sourceRoot":"","sources":["../src/videoTexture.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"videoTexture.js","sourceRoot":"","sources":["../src/videoTexture.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flighthq/texture",
|
|
3
|
-
"version": "0.5.1-next.
|
|
3
|
+
"version": "0.5.1-next.1345.0995dc5",
|
|
4
4
|
"author": "Joshua Granick and other contributors",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -38,9 +38,9 @@
|
|
|
38
38
|
"clean:dist": "tsx ../../scripts/clean-package-dist.ts"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@flighthq/entity": "0.5.1-next.
|
|
42
|
-
"@flighthq/geometry": "0.5.1-next.
|
|
43
|
-
"@flighthq/types": "0.5.1-next.
|
|
41
|
+
"@flighthq/entity": "0.5.1-next.1345.0995dc5",
|
|
42
|
+
"@flighthq/geometry": "0.5.1-next.1345.0995dc5",
|
|
43
|
+
"@flighthq/types": "0.5.1-next.1345.0995dc5"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@flighthq/video": "*",
|
package/src/videoTexture.test.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createMatrix3, createVector2 } from '@flighthq/geometry/contract';
|
|
2
|
-
import type { ImageResource, VideoResource } from '@flighthq/types/contract';
|
|
2
|
+
import type { HostVideoProvider, ImageResource, VideoResource } from '@flighthq/types/contract';
|
|
3
3
|
import { createVideoResource } from '@flighthq/video/contract';
|
|
4
4
|
|
|
5
5
|
import { getTextureSource } from './texture';
|
|
@@ -19,16 +19,27 @@ import {
|
|
|
19
19
|
setVideoTextureSource,
|
|
20
20
|
} from './videoTexture';
|
|
21
21
|
|
|
22
|
+
const testVideoHost = {
|
|
23
|
+
canPlayType: () => true,
|
|
24
|
+
getHeight: (source) => (source as HTMLVideoElement).videoHeight,
|
|
25
|
+
getWidth: (source) => (source as HTMLVideoElement).videoWidth,
|
|
26
|
+
isReady: (source) => (source as HTMLVideoElement).readyState >= 2,
|
|
27
|
+
} satisfies HostVideoProvider;
|
|
28
|
+
|
|
22
29
|
function makeVideoResource(readyState = 4, videoWidth = 320, videoHeight = 240): VideoResource {
|
|
23
|
-
return createVideoResource({
|
|
30
|
+
return createVideoResource({
|
|
31
|
+
readyState,
|
|
32
|
+
videoWidth,
|
|
33
|
+
videoHeight,
|
|
34
|
+
} as unknown as HTMLVideoElement);
|
|
24
35
|
}
|
|
25
36
|
|
|
26
37
|
describe('advanceVideoTexture', () => {
|
|
27
38
|
it('bumps the source and Texture versions and returns the new value', () => {
|
|
28
|
-
const vt = createVideoTexture(makeVideoResource());
|
|
39
|
+
const vt = createVideoTexture(testVideoHost, makeVideoResource());
|
|
29
40
|
expect(vt.version).toBe(0xffffffff);
|
|
30
|
-
expect(advanceVideoTexture(vt)).toBe(0);
|
|
31
|
-
expect(advanceVideoTexture(vt)).toBe(1);
|
|
41
|
+
expect(advanceVideoTexture(testVideoHost, vt)).toBe(0);
|
|
42
|
+
expect(advanceVideoTexture(testVideoHost, vt)).toBe(1);
|
|
32
43
|
expect(vt.version).toBe(1);
|
|
33
44
|
expect(getTextureSource(vt)?.version).toBe(1);
|
|
34
45
|
});
|
|
@@ -37,8 +48,8 @@ describe('advanceVideoTexture', () => {
|
|
|
37
48
|
describe('cloneVideoTexture', () => {
|
|
38
49
|
it('shares the source but deep-clones sampler and uv vectors', () => {
|
|
39
50
|
const source = makeVideoResource();
|
|
40
|
-
const vt = createVideoTexture(source, { uvOffset: createVector2(2, 3) });
|
|
41
|
-
advanceVideoTexture(vt);
|
|
51
|
+
const vt = createVideoTexture(testVideoHost, source, { uvOffset: createVector2(2, 3) });
|
|
52
|
+
advanceVideoTexture(testVideoHost, vt);
|
|
42
53
|
const clone = cloneVideoTexture(vt);
|
|
43
54
|
expect(getTextureSource(clone)).toBe(getTextureSource(vt));
|
|
44
55
|
expect(clone.sampler).not.toBe(vt.sampler);
|
|
@@ -50,9 +61,12 @@ describe('cloneVideoTexture', () => {
|
|
|
50
61
|
|
|
51
62
|
describe('copyVideoTexture', () => {
|
|
52
63
|
it('copies fields into out and is safe when out aliases source', () => {
|
|
53
|
-
const a = createVideoTexture(makeVideoResource(), {
|
|
54
|
-
|
|
55
|
-
|
|
64
|
+
const a = createVideoTexture(testVideoHost, makeVideoResource(), {
|
|
65
|
+
colorSpace: 'linear',
|
|
66
|
+
uvScale: createVector2(4, 5),
|
|
67
|
+
});
|
|
68
|
+
advanceVideoTexture(testVideoHost, a);
|
|
69
|
+
const b = createVideoTexture(testVideoHost, makeVideoResource());
|
|
56
70
|
copyVideoTexture(b, a);
|
|
57
71
|
expect(b.colorSpace).toBe('linear');
|
|
58
72
|
expect(b.version).toBe(0);
|
|
@@ -66,7 +80,7 @@ describe('copyVideoTexture', () => {
|
|
|
66
80
|
describe('createVideoTexture', () => {
|
|
67
81
|
it('returns a universal srgb Texture with a borrowed host-image source', () => {
|
|
68
82
|
const source = makeVideoResource();
|
|
69
|
-
const vt = createVideoTexture(source);
|
|
83
|
+
const vt = createVideoTexture(testVideoHost, source);
|
|
70
84
|
expect(vt.colorSpace).toBe('srgb');
|
|
71
85
|
expect((getTextureSource(vt) as ImageResource).source).toBe(source.element);
|
|
72
86
|
expect(vt.version).toBe(0xffffffff);
|
|
@@ -74,12 +88,47 @@ describe('createVideoTexture', () => {
|
|
|
74
88
|
expect(vt.uvScale.x).toBe(1);
|
|
75
89
|
expect(vt.uvRotation).toBe(0);
|
|
76
90
|
});
|
|
91
|
+
|
|
92
|
+
it('reads dimensions and readiness only through the supplied host provider', () => {
|
|
93
|
+
const resource = makeVideoResource(0, 320, 240);
|
|
94
|
+
const getHeight = vi.fn(() => 12);
|
|
95
|
+
const getWidth = vi.fn(() => 34);
|
|
96
|
+
const isReady = vi.fn(() => true);
|
|
97
|
+
const hostVideo = {
|
|
98
|
+
canPlayType: () => true,
|
|
99
|
+
getHeight,
|
|
100
|
+
getWidth,
|
|
101
|
+
isReady,
|
|
102
|
+
} satisfies HostVideoProvider;
|
|
103
|
+
|
|
104
|
+
const texture = createVideoTexture(hostVideo, resource);
|
|
105
|
+
|
|
106
|
+
expect(getTextureSource(texture)?.height).toBe(12);
|
|
107
|
+
expect(getTextureSource(texture)?.width).toBe(34);
|
|
108
|
+
expect(getVideoTextureHeight(hostVideo, texture)).toBe(12);
|
|
109
|
+
expect(getVideoTextureWidth(hostVideo, texture)).toBe(34);
|
|
110
|
+
expect(isVideoTextureFrameReady(hostVideo, texture)).toBe(true);
|
|
111
|
+
expect(getHeight).toHaveBeenCalledWith(resource.element);
|
|
112
|
+
expect(getWidth).toHaveBeenCalledWith(resource.element);
|
|
113
|
+
expect(isReady).toHaveBeenCalledWith(resource.element);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('uses dimension and readiness sentinels when the provider omits inspection methods', () => {
|
|
117
|
+
const hostVideo = { canPlayType: () => false } satisfies HostVideoProvider;
|
|
118
|
+
const texture = createVideoTexture(hostVideo, makeVideoResource());
|
|
119
|
+
|
|
120
|
+
expect(getTextureSource(texture)?.height).toBe(0);
|
|
121
|
+
expect(getTextureSource(texture)?.width).toBe(0);
|
|
122
|
+
expect(getVideoTextureHeight(hostVideo, texture)).toBe(-1);
|
|
123
|
+
expect(getVideoTextureWidth(hostVideo, texture)).toBe(-1);
|
|
124
|
+
expect(isVideoTextureFrameReady(hostVideo, texture)).toBe(false);
|
|
125
|
+
});
|
|
77
126
|
});
|
|
78
127
|
|
|
79
128
|
describe('destroyVideoTexture', () => {
|
|
80
129
|
it('nulls the texture source and resets the version', () => {
|
|
81
|
-
const vt = createVideoTexture(makeVideoResource());
|
|
82
|
-
advanceVideoTexture(vt);
|
|
130
|
+
const vt = createVideoTexture(testVideoHost, makeVideoResource());
|
|
131
|
+
advanceVideoTexture(testVideoHost, vt);
|
|
83
132
|
expect(getTextureSource(vt)).not.toBeNull();
|
|
84
133
|
destroyVideoTexture(vt);
|
|
85
134
|
expect(getTextureSource(vt)).toBeNull();
|
|
@@ -89,39 +138,46 @@ describe('destroyVideoTexture', () => {
|
|
|
89
138
|
it('does not modify the borrowed video resource', () => {
|
|
90
139
|
const resource = makeVideoResource();
|
|
91
140
|
const element = resource.element;
|
|
92
|
-
const vt = createVideoTexture(resource);
|
|
141
|
+
const vt = createVideoTexture(testVideoHost, resource);
|
|
93
142
|
destroyVideoTexture(vt);
|
|
94
143
|
expect(resource.element).toBe(element);
|
|
95
144
|
});
|
|
96
145
|
|
|
97
146
|
it('is idempotent', () => {
|
|
98
|
-
const vt = createVideoTexture(makeVideoResource());
|
|
147
|
+
const vt = createVideoTexture(testVideoHost, makeVideoResource());
|
|
99
148
|
destroyVideoTexture(vt);
|
|
100
149
|
destroyVideoTexture(vt);
|
|
101
150
|
expect(getTextureSource(vt)).toBeNull();
|
|
102
151
|
});
|
|
103
152
|
|
|
104
153
|
it('makes subsequent accessor calls return sentinel values', () => {
|
|
105
|
-
const vt = createVideoTexture(makeVideoResource());
|
|
154
|
+
const vt = createVideoTexture(testVideoHost, makeVideoResource());
|
|
106
155
|
destroyVideoTexture(vt);
|
|
107
|
-
expect(getVideoTextureWidth(vt)).toBe(-1);
|
|
108
|
-
expect(getVideoTextureHeight(vt)).toBe(-1);
|
|
109
|
-
expect(isVideoTextureFrameReady(vt)).toBe(false);
|
|
110
|
-
expect(advanceVideoTexture(vt)).toBe(0xffffffff);
|
|
156
|
+
expect(getVideoTextureWidth(testVideoHost, vt)).toBe(-1);
|
|
157
|
+
expect(getVideoTextureHeight(testVideoHost, vt)).toBe(-1);
|
|
158
|
+
expect(isVideoTextureFrameReady(testVideoHost, vt)).toBe(false);
|
|
159
|
+
expect(advanceVideoTexture(testVideoHost, vt)).toBe(0xffffffff);
|
|
111
160
|
});
|
|
112
161
|
});
|
|
113
162
|
|
|
114
163
|
describe('getVideoTextureHeight', () => {
|
|
115
164
|
it('returns the element videoHeight when a frame is decoded, else -1', () => {
|
|
116
|
-
expect(
|
|
117
|
-
|
|
118
|
-
|
|
165
|
+
expect(
|
|
166
|
+
getVideoTextureHeight(testVideoHost, createVideoTexture(testVideoHost, makeVideoResource(4, 320, 240))),
|
|
167
|
+
).toBe(240);
|
|
168
|
+
expect(getVideoTextureHeight(testVideoHost, createVideoTexture(testVideoHost, makeVideoResource(0, 0, 0)))).toBe(
|
|
169
|
+
-1,
|
|
170
|
+
);
|
|
171
|
+
expect(getVideoTextureHeight(testVideoHost, createVideoTexture(testVideoHost, createVideoResource()))).toBe(-1);
|
|
119
172
|
});
|
|
120
173
|
});
|
|
121
174
|
|
|
122
175
|
describe('getVideoTextureInverseUvMatrix', () => {
|
|
123
176
|
it('inverts the forward uv-transform', () => {
|
|
124
|
-
const vt = createVideoTexture(makeVideoResource(), {
|
|
177
|
+
const vt = createVideoTexture(testVideoHost, makeVideoResource(), {
|
|
178
|
+
uvScale: createVector2(2, 2),
|
|
179
|
+
uvOffset: createVector2(1, 0),
|
|
180
|
+
});
|
|
125
181
|
const forward = createMatrix3();
|
|
126
182
|
const inverse = createMatrix3();
|
|
127
183
|
getVideoTextureUvMatrix(forward, vt);
|
|
@@ -140,7 +196,7 @@ describe('getVideoTextureInverseUvMatrix', () => {
|
|
|
140
196
|
|
|
141
197
|
describe('getVideoTextureUvMatrix', () => {
|
|
142
198
|
it('composes scale, rotation, and offset in column-major layout', () => {
|
|
143
|
-
const vt = createVideoTexture(makeVideoResource(), {
|
|
199
|
+
const vt = createVideoTexture(testVideoHost, makeVideoResource(), {
|
|
144
200
|
uvScale: createVector2(2, 3),
|
|
145
201
|
uvOffset: createVector2(5, 7),
|
|
146
202
|
});
|
|
@@ -156,9 +212,11 @@ describe('getVideoTextureUvMatrix', () => {
|
|
|
156
212
|
|
|
157
213
|
describe('getVideoTextureWidth', () => {
|
|
158
214
|
it('returns the element videoWidth when a frame is decoded, else -1', () => {
|
|
159
|
-
expect(getVideoTextureWidth(createVideoTexture(makeVideoResource(4, 320, 240)))).toBe(
|
|
160
|
-
|
|
161
|
-
|
|
215
|
+
expect(getVideoTextureWidth(testVideoHost, createVideoTexture(testVideoHost, makeVideoResource(4, 320, 240)))).toBe(
|
|
216
|
+
320,
|
|
217
|
+
);
|
|
218
|
+
expect(getVideoTextureWidth(testVideoHost, createVideoTexture(testVideoHost, makeVideoResource(0, 0, 0)))).toBe(-1);
|
|
219
|
+
expect(getVideoTextureWidth(testVideoHost, createVideoTexture(testVideoHost, createVideoResource()))).toBe(-1);
|
|
162
220
|
});
|
|
163
221
|
});
|
|
164
222
|
|
|
@@ -170,18 +228,26 @@ describe('initializeVideoImageResource', () => {
|
|
|
170
228
|
|
|
171
229
|
describe('isVideoTextureFrameReady', () => {
|
|
172
230
|
it('is true only when the element has a decoded frame with known dimensions', () => {
|
|
173
|
-
expect(
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
expect(
|
|
231
|
+
expect(
|
|
232
|
+
isVideoTextureFrameReady(testVideoHost, createVideoTexture(testVideoHost, makeVideoResource(4, 320, 240))),
|
|
233
|
+
).toBe(true);
|
|
234
|
+
expect(
|
|
235
|
+
isVideoTextureFrameReady(testVideoHost, createVideoTexture(testVideoHost, makeVideoResource(1, 320, 240))),
|
|
236
|
+
).toBe(false);
|
|
237
|
+
expect(isVideoTextureFrameReady(testVideoHost, createVideoTexture(testVideoHost, makeVideoResource(4, 0, 0)))).toBe(
|
|
238
|
+
false,
|
|
239
|
+
);
|
|
240
|
+
expect(isVideoTextureFrameReady(testVideoHost, createVideoTexture(testVideoHost, createVideoResource()))).toBe(
|
|
241
|
+
false,
|
|
242
|
+
);
|
|
177
243
|
});
|
|
178
244
|
});
|
|
179
245
|
|
|
180
246
|
describe('resetVideoTextureFrame', () => {
|
|
181
247
|
it('sets the shared revision to the u32 pre-first-frame sentinel', () => {
|
|
182
|
-
const vt = createVideoTexture(makeVideoResource());
|
|
183
|
-
advanceVideoTexture(vt);
|
|
184
|
-
advanceVideoTexture(vt);
|
|
248
|
+
const vt = createVideoTexture(testVideoHost, makeVideoResource());
|
|
249
|
+
advanceVideoTexture(testVideoHost, vt);
|
|
250
|
+
advanceVideoTexture(testVideoHost, vt);
|
|
185
251
|
resetVideoTextureFrame(vt);
|
|
186
252
|
expect(vt.version).toBe(0xffffffff);
|
|
187
253
|
expect(getTextureSource(vt)?.version).toBe(0xffffffff);
|
|
@@ -189,12 +255,12 @@ describe('resetVideoTextureFrame', () => {
|
|
|
189
255
|
});
|
|
190
256
|
describe('setVideoTextureSource', () => {
|
|
191
257
|
it('swaps the borrowed host handle and resets the version', () => {
|
|
192
|
-
const vt = createVideoTexture(makeVideoResource());
|
|
193
|
-
advanceVideoTexture(vt);
|
|
258
|
+
const vt = createVideoTexture(testVideoHost, makeVideoResource());
|
|
259
|
+
advanceVideoTexture(testVideoHost, vt);
|
|
194
260
|
const next = makeVideoResource(4, 640, 480);
|
|
195
|
-
setVideoTextureSource(vt, next);
|
|
261
|
+
setVideoTextureSource(testVideoHost, vt, next);
|
|
196
262
|
expect((getTextureSource(vt) as ImageResource).source).toBe(next.element);
|
|
197
263
|
expect(vt.version).toBe(0xffffffff);
|
|
198
|
-
expect(getVideoTextureWidth(vt)).toBe(640);
|
|
264
|
+
expect(getVideoTextureWidth(testVideoHost, vt)).toBe(640);
|
|
199
265
|
});
|
|
200
266
|
});
|