@flighthq/render-gl 0.3.0-next.1032.e2b99fc → 0.3.0-next.1220.6982c21
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/contract.d.ts +4 -0
- package/dist/contract.d.ts.map +1 -1
- package/dist/contract.js +4 -0
- package/dist/contract.js.map +1 -1
- package/dist/enableGlRenderStateGuards.d.ts +4 -0
- package/dist/enableGlRenderStateGuards.d.ts.map +1 -0
- package/dist/enableGlRenderStateGuards.js +30 -0
- package/dist/enableGlRenderStateGuards.js.map +1 -0
- package/dist/enableGlTextureResolverGuards.d.ts +4 -0
- package/dist/enableGlTextureResolverGuards.d.ts.map +1 -0
- package/dist/enableGlTextureResolverGuards.js +8 -0
- package/dist/enableGlTextureResolverGuards.js.map +1 -0
- package/dist/explainGlTextureResolution.d.ts +3 -0
- package/dist/explainGlTextureResolution.d.ts.map +1 -0
- package/dist/explainGlTextureResolution.js +12 -0
- package/dist/explainGlTextureResolution.js.map +1 -0
- package/dist/glCompressedTexture.js +1 -1
- package/dist/glCompressedTexture.js.map +1 -1
- package/dist/glDraw.d.ts +2 -2
- package/dist/glDraw.d.ts.map +1 -1
- package/dist/glDraw.js +17 -14
- package/dist/glDraw.js.map +1 -1
- package/dist/glExternalTexture.d.ts.map +1 -1
- package/dist/glExternalTexture.js +23 -18
- package/dist/glExternalTexture.js.map +1 -1
- package/dist/glFullscreenPass.js +3 -4
- package/dist/glFullscreenPass.js.map +1 -1
- package/dist/glLinearToSrgbPass.js +3 -3
- package/dist/glLinearToSrgbPass.js.map +1 -1
- package/dist/glPresentRenderTarget.js +3 -3
- package/dist/glPresentRenderTarget.js.map +1 -1
- package/dist/glRenderPass.d.ts.map +1 -1
- package/dist/glRenderPass.js +82 -36
- package/dist/glRenderPass.js.map +1 -1
- package/dist/glRenderState.d.ts +11 -1
- package/dist/glRenderState.d.ts.map +1 -1
- package/dist/glRenderState.js +180 -5
- package/dist/glRenderState.js.map +1 -1
- package/dist/glRenderStateBracket.d.ts.map +1 -1
- package/dist/glRenderStateBracket.js +16 -4
- package/dist/glRenderStateBracket.js.map +1 -1
- package/dist/glRenderTarget.d.ts +10 -1
- package/dist/glRenderTarget.d.ts.map +1 -1
- package/dist/glRenderTarget.js +129 -60
- package/dist/glRenderTarget.js.map +1 -1
- package/dist/glRenderTargetPool.d.ts +4 -1
- package/dist/glRenderTargetPool.d.ts.map +1 -1
- package/dist/glRenderTargetPool.js +32 -23
- package/dist/glRenderTargetPool.js.map +1 -1
- package/dist/glRenderTexture.d.ts +4 -1
- package/dist/glRenderTexture.d.ts.map +1 -1
- package/dist/glRenderTexture.js +75 -17
- package/dist/glRenderTexture.js.map +1 -1
- package/dist/glRenderTexturePool.d.ts +7 -0
- package/dist/glRenderTexturePool.d.ts.map +1 -0
- package/dist/glRenderTexturePool.js +87 -0
- package/dist/glRenderTexturePool.js.map +1 -0
- package/dist/glTestHelper.js +2 -2
- package/dist/glTestHelper.js.map +1 -1
- package/dist/glTextureResolver.d.ts +3 -3
- package/dist/glTextureResolver.d.ts.map +1 -1
- package/dist/glTextureResolver.js +32 -31
- package/dist/glTextureResolver.js.map +1 -1
- package/dist/glTextureUpload.d.ts +2 -2
- package/dist/glTextureUpload.d.ts.map +1 -1
- package/dist/glTextureUpload.js +1 -1
- package/dist/glTextureUpload.js.map +1 -1
- package/dist/glTextureVideoUpload.d.ts +2 -2
- package/dist/glTextureVideoUpload.d.ts.map +1 -1
- package/dist/glTextureVideoUpload.js +3 -3
- package/dist/glTextureVideoUpload.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +9 -7
- package/src/enableGlRenderStateGuards.test.ts +27 -0
- package/src/enableGlTextureResolverGuards.test.ts +58 -0
- package/src/explainGlTextureResolution.test.ts +32 -0
- package/src/glCompressedTexture.test.ts +2 -2
- package/src/glDraw.test.ts +17 -18
- package/src/glExternalTexture.test.ts +3 -3
- package/src/glFullscreenPass.test.ts +13 -0
- package/src/glLinearToSrgbPass.test.ts +13 -0
- package/src/glPresentRenderTarget.test.ts +15 -1
- package/src/glReadback.test.ts +13 -0
- package/src/glRenderPass.test.ts +63 -0
- package/src/glRenderState.test.ts +135 -0
- package/src/glRenderStateBracket.test.ts +31 -1
- package/src/glRenderTarget.test.ts +186 -3
- package/src/glRenderTargetPool.test.ts +110 -5
- package/src/glRenderTexture.test.ts +71 -11
- package/src/glRenderTexturePool.test.ts +112 -0
- package/src/glTextureResolver.test.ts +73 -51
- package/src/glTextureUpload.test.ts +2 -2
- package/src/glTextureVideoUpload.test.ts +5 -5
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { explainGlRenderTexture, isGlRenderTextureReady, writeGlRenderTextureTarget } from './glRenderTexture';
|
|
2
|
+
import {
|
|
3
|
+
acquireGlRenderTexture,
|
|
4
|
+
createGlRenderTexturePool,
|
|
5
|
+
destroyGlRenderTexturePool,
|
|
6
|
+
releaseGlRenderTexture,
|
|
7
|
+
withGlRenderTextures,
|
|
8
|
+
} from './glRenderTexturePool';
|
|
9
|
+
import { createGlState } from './glTestHelper';
|
|
10
|
+
|
|
11
|
+
describe('acquireGlRenderTexture', () => {
|
|
12
|
+
it('reuses a released handle and applies current dimensions on every acquisition', () => {
|
|
13
|
+
const { state } = createGlState();
|
|
14
|
+
const pool = createGlRenderTexturePool();
|
|
15
|
+
const first = acquireGlRenderTexture(state, pool, { width: 32, height: 16 });
|
|
16
|
+
writeGlRenderTextureTarget(state, first, () => {});
|
|
17
|
+
releaseGlRenderTexture(state, pool, first);
|
|
18
|
+
|
|
19
|
+
expect(explainGlRenderTexture(state, first).status).toBe('released');
|
|
20
|
+
expect(isGlRenderTextureReady(state, first)).toBe(false);
|
|
21
|
+
|
|
22
|
+
const second = acquireGlRenderTexture(state, pool, { width: 80, height: 48 });
|
|
23
|
+
expect(second).toBe(first);
|
|
24
|
+
expect(second.source.width).toBe(80);
|
|
25
|
+
expect(second.source.height).toBe(48);
|
|
26
|
+
expect(explainGlRenderTexture(state, second).status).toBe('unrendered');
|
|
27
|
+
|
|
28
|
+
writeGlRenderTextureTarget(state, second, () => {});
|
|
29
|
+
expect(explainGlRenderTexture(state, second)).toEqual({ width: 80, height: 48, status: 'ready' });
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('does not allow a pool to cross WebGL contexts', () => {
|
|
33
|
+
const a = createGlState();
|
|
34
|
+
const b = createGlState();
|
|
35
|
+
const pool = createGlRenderTexturePool();
|
|
36
|
+
acquireGlRenderTexture(a.state, pool, { width: 8, height: 8 });
|
|
37
|
+
|
|
38
|
+
expect(() => acquireGlRenderTexture(b.state, pool, { width: 8, height: 8 })).toThrow('cannot cross WebGL contexts');
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
describe('createGlRenderTexturePool', () => {
|
|
43
|
+
it('creates an empty usable pool', () => {
|
|
44
|
+
const pool = createGlRenderTexturePool();
|
|
45
|
+
expect(pool.context).toBeNull();
|
|
46
|
+
expect(pool.destroyed).toBe(false);
|
|
47
|
+
expect(pool.free).toEqual([]);
|
|
48
|
+
expect(pool.leased.size).toBe(0);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
describe('destroyGlRenderTexturePool', () => {
|
|
53
|
+
it('destroys hidden targets for both free and outstanding leases at shutdown', () => {
|
|
54
|
+
const { state, gl } = createGlState();
|
|
55
|
+
const pool = createGlRenderTexturePool();
|
|
56
|
+
const free = acquireGlRenderTexture(state, pool, { width: 8, height: 8 });
|
|
57
|
+
const leased = acquireGlRenderTexture(state, pool, { width: 16, height: 16 });
|
|
58
|
+
writeGlRenderTextureTarget(state, free, () => {});
|
|
59
|
+
writeGlRenderTextureTarget(state, leased, () => {});
|
|
60
|
+
releaseGlRenderTexture(state, pool, free);
|
|
61
|
+
const deletes = vi.mocked(gl.deleteTexture).mock.calls.length;
|
|
62
|
+
|
|
63
|
+
destroyGlRenderTexturePool(state, pool);
|
|
64
|
+
|
|
65
|
+
expect(gl.deleteTexture).toHaveBeenCalledTimes(deletes + 2);
|
|
66
|
+
expect(pool.free).toHaveLength(0);
|
|
67
|
+
expect(pool.leased.size).toBe(0);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('rejects acquisition after destruction', () => {
|
|
71
|
+
const { state } = createGlState();
|
|
72
|
+
const pool = createGlRenderTexturePool();
|
|
73
|
+
destroyGlRenderTexturePool(state, pool);
|
|
74
|
+
expect(() => acquireGlRenderTexture(state, pool, { width: 8, height: 8 })).toThrow('has been destroyed');
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
describe('releaseGlRenderTexture', () => {
|
|
79
|
+
it('rejects a double release', () => {
|
|
80
|
+
const { state } = createGlState();
|
|
81
|
+
const pool = createGlRenderTexturePool();
|
|
82
|
+
const texture = acquireGlRenderTexture(state, pool, { width: 8, height: 8 });
|
|
83
|
+
releaseGlRenderTexture(state, pool, texture);
|
|
84
|
+
|
|
85
|
+
expect(() => releaseGlRenderTexture(state, pool, texture)).toThrow('texture is not leased');
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
describe('withGlRenderTextures', () => {
|
|
90
|
+
it('releases every lease when the bracket callback throws', () => {
|
|
91
|
+
const { state } = createGlState();
|
|
92
|
+
const pool = createGlRenderTexturePool();
|
|
93
|
+
|
|
94
|
+
expect(() =>
|
|
95
|
+
withGlRenderTextures(
|
|
96
|
+
state,
|
|
97
|
+
pool,
|
|
98
|
+
[
|
|
99
|
+
{ width: 8, height: 8 },
|
|
100
|
+
{ width: 8, height: 8 },
|
|
101
|
+
{ width: 8, height: 8 },
|
|
102
|
+
],
|
|
103
|
+
() => {
|
|
104
|
+
throw new Error('capture failed');
|
|
105
|
+
},
|
|
106
|
+
),
|
|
107
|
+
).toThrow('capture failed');
|
|
108
|
+
|
|
109
|
+
expect(pool.leased.size).toBe(0);
|
|
110
|
+
expect(pool.free).toHaveLength(3);
|
|
111
|
+
});
|
|
112
|
+
});
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { createEntity } from '@flighthq/entity/contract';
|
|
2
|
+
import type { Image, RenderTexture, TextureLike, TextureSource } from '@flighthq/types/contract';
|
|
2
3
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
VideoTextureBackingKind,
|
|
4
|
+
BitmapTextureSourceKind,
|
|
5
|
+
CompressedImageTextureSourceKind,
|
|
6
|
+
ImageTextureSourceKind,
|
|
7
|
+
RenderTargetTextureSourceKind,
|
|
8
8
|
} from '@flighthq/types/contract';
|
|
9
9
|
|
|
10
10
|
import { getGlRenderStateRuntime } from './glRenderState';
|
|
@@ -15,12 +15,12 @@ import {
|
|
|
15
15
|
registerGlBitmapTextureResolver,
|
|
16
16
|
registerGlCompressedImageTextureResolver,
|
|
17
17
|
registerGlRenderTextureResolver,
|
|
18
|
+
registerStandardGlTextureResolvers,
|
|
18
19
|
registerGlTextureResolver,
|
|
19
|
-
registerGlVideoTextureResolver,
|
|
20
20
|
resolveGlTexture,
|
|
21
21
|
} from './glTextureResolver';
|
|
22
22
|
|
|
23
|
-
function textureWithImage(image:
|
|
23
|
+
function textureWithImage(image: TextureSource | null): TextureLike {
|
|
24
24
|
return {
|
|
25
25
|
colorSpace: 'srgb',
|
|
26
26
|
flipX: false,
|
|
@@ -34,7 +34,8 @@ function textureWithImage(image: ImageResource | null): TextureLike {
|
|
|
34
34
|
wrapU: 'clamp-to-edge',
|
|
35
35
|
wrapV: 'clamp-to-edge',
|
|
36
36
|
},
|
|
37
|
-
|
|
37
|
+
dimension: '2d',
|
|
38
|
+
source: image,
|
|
38
39
|
uvOffset: { x: 0, y: 0 },
|
|
39
40
|
uvRotation: 0,
|
|
40
41
|
uvScale: { x: 1, y: 1 },
|
|
@@ -42,46 +43,59 @@ function textureWithImage(image: ImageResource | null): TextureLike {
|
|
|
42
43
|
} as unknown as TextureLike;
|
|
43
44
|
}
|
|
44
45
|
|
|
45
|
-
function imageResource(
|
|
46
|
-
source: CanvasImageSource = document.createElement('img'),
|
|
47
|
-
kind = ImageTextureBackingKind,
|
|
48
|
-
): ImageResource {
|
|
46
|
+
function imageResource(source: CanvasImageSource = document.createElement('img')): Image {
|
|
49
47
|
return {
|
|
50
48
|
height: 1,
|
|
51
|
-
kind,
|
|
49
|
+
kind: ImageTextureSourceKind,
|
|
52
50
|
source,
|
|
53
51
|
version: 0,
|
|
54
52
|
width: 1,
|
|
55
|
-
} as unknown as
|
|
53
|
+
} as unknown as Image;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function textureSource(kind: string): TextureSource {
|
|
57
|
+
return {
|
|
58
|
+
height: 1,
|
|
59
|
+
kind,
|
|
60
|
+
version: 0,
|
|
61
|
+
width: 1,
|
|
62
|
+
} as unknown as TextureSource;
|
|
56
63
|
}
|
|
57
64
|
|
|
58
65
|
function textureWithTarget(): TextureLike {
|
|
59
66
|
const texture = textureWithImage(null);
|
|
60
67
|
texture.colorSpace = 'linear';
|
|
61
|
-
texture.
|
|
68
|
+
if (texture.dimension !== '2d') throw new Error('test texture must be 2d');
|
|
69
|
+
texture.source = createEntity({
|
|
70
|
+
colorSpace: 'linear' as const,
|
|
71
|
+
height: 8,
|
|
72
|
+
kind: RenderTargetTextureSourceKind,
|
|
73
|
+
version: 0,
|
|
74
|
+
width: 8,
|
|
75
|
+
});
|
|
62
76
|
return texture;
|
|
63
77
|
}
|
|
64
78
|
|
|
65
79
|
describe('registerGlBitmapTextureResolver', () => {
|
|
66
|
-
it('registers only the Bitmap
|
|
80
|
+
it('registers only the Bitmap source key', () => {
|
|
67
81
|
const { state } = createGlState();
|
|
68
82
|
registerGlBitmapTextureResolver(state);
|
|
69
|
-
expect([...getGlRenderStateRuntime(state).glTextureResolverRegistry!.keys()]).toEqual([
|
|
83
|
+
expect([...getGlRenderStateRuntime(state).glTextureResolverRegistry!.keys()]).toEqual([BitmapTextureSourceKind]);
|
|
70
84
|
});
|
|
71
85
|
});
|
|
72
86
|
|
|
73
87
|
describe('registerGlCompressedImageTextureResolver', () => {
|
|
74
|
-
it('registers only the CompressedImage
|
|
88
|
+
it('registers only the CompressedImage source key', () => {
|
|
75
89
|
const { state } = createGlState();
|
|
76
90
|
registerGlCompressedImageTextureResolver(state);
|
|
77
91
|
expect([...getGlRenderStateRuntime(state).glTextureResolverRegistry!.keys()]).toEqual([
|
|
78
|
-
|
|
92
|
+
CompressedImageTextureSourceKind,
|
|
79
93
|
]);
|
|
80
94
|
});
|
|
81
95
|
});
|
|
82
96
|
|
|
83
97
|
describe('registerGlImageTextureResolver', () => {
|
|
84
|
-
it('registers the 2D image matcher and resolves through the
|
|
98
|
+
it('registers the 2D image matcher and resolves through the source-keyed upload cache', () => {
|
|
85
99
|
const { state, gl } = createGlState();
|
|
86
100
|
const texture = textureWithImage(imageResource());
|
|
87
101
|
registerGlImageTextureResolver(state);
|
|
@@ -94,11 +108,31 @@ describe('registerGlImageTextureResolver', () => {
|
|
|
94
108
|
expect(gl.texImage2D).toHaveBeenCalledOnce();
|
|
95
109
|
});
|
|
96
110
|
|
|
97
|
-
it('returns null for an unbound image
|
|
111
|
+
it('returns null for an unbound image source', () => {
|
|
98
112
|
const { state } = createGlState();
|
|
99
113
|
registerGlImageTextureResolver(state);
|
|
100
114
|
expect(resolveGlTexture(state, textureWithImage(null))).toBeNull();
|
|
101
115
|
});
|
|
116
|
+
|
|
117
|
+
it('uploads a host video through the image source kind and gates by version', () => {
|
|
118
|
+
const { state, gl } = createGlState();
|
|
119
|
+
const video = imageResource({
|
|
120
|
+
readyState: 4,
|
|
121
|
+
videoHeight: 240,
|
|
122
|
+
videoWidth: 320,
|
|
123
|
+
} as HTMLVideoElement);
|
|
124
|
+
const texture = textureWithImage(video);
|
|
125
|
+
registerGlImageTextureResolver(state);
|
|
126
|
+
|
|
127
|
+
const first = resolveGlTexture(state, texture);
|
|
128
|
+
const uploads = (gl.texImage2D as ReturnType<typeof vi.fn>).mock.calls.length;
|
|
129
|
+
const second = resolveGlTexture(state, texture);
|
|
130
|
+
|
|
131
|
+
expect(first).not.toBeNull();
|
|
132
|
+
expect(second).toBe(first);
|
|
133
|
+
expect(gl.texImage2D).toHaveBeenCalledWith(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, video.source);
|
|
134
|
+
expect(gl.texImage2D).toHaveBeenCalledTimes(uploads);
|
|
135
|
+
});
|
|
102
136
|
});
|
|
103
137
|
|
|
104
138
|
describe('registerGlRenderTextureResolver', () => {
|
|
@@ -123,59 +157,47 @@ describe('registerGlTextureResolver', () => {
|
|
|
123
157
|
it('keeps registrations state-scoped, replaces by string kind, and removes with null', () => {
|
|
124
158
|
const { state: a } = createGlState();
|
|
125
159
|
const { state: b } = createGlState();
|
|
126
|
-
const
|
|
160
|
+
const sourceKind = 'acme.generated';
|
|
127
161
|
const first = vi.fn(() => ({ first: true }) as unknown as WebGLTexture);
|
|
128
162
|
const second = vi.fn(() => ({ second: true }) as unknown as WebGLTexture);
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
const texture = textureWithImage(image);
|
|
163
|
+
const source = textureSource(sourceKind);
|
|
164
|
+
const texture = textureWithImage(source);
|
|
132
165
|
|
|
133
|
-
registerGlTextureResolver(a,
|
|
166
|
+
registerGlTextureResolver(a, sourceKind, first);
|
|
134
167
|
expect(resolveGlTexture(a, texture)).not.toBeNull();
|
|
135
168
|
expect(resolveGlTexture(b, texture)).toBeNull();
|
|
136
169
|
|
|
137
|
-
registerGlTextureResolver(a,
|
|
170
|
+
registerGlTextureResolver(a, sourceKind, second);
|
|
138
171
|
expect(resolveGlTexture(a, texture)).toEqual({ second: true });
|
|
139
172
|
expect(getGlRenderStateRuntime(a).glTextureResolverRegistry?.size).toBe(1);
|
|
140
173
|
|
|
141
|
-
registerGlTextureResolver(a,
|
|
174
|
+
registerGlTextureResolver(a, sourceKind, null);
|
|
142
175
|
expect(resolveGlTexture(a, texture)).toBeNull();
|
|
143
176
|
});
|
|
144
177
|
|
|
145
178
|
it('uses one exact keyed lookup and does not fall through to another kind', () => {
|
|
146
179
|
const { state } = createGlState();
|
|
147
|
-
const image =
|
|
148
|
-
image.kind = 'acme.specific';
|
|
180
|
+
const image = textureSource('acme.specific');
|
|
149
181
|
registerGlTextureResolver(state, 'image', () => ({ kind: 'image' }) as unknown as WebGLTexture);
|
|
150
182
|
registerGlTextureResolver(state, 'acme.specific', () => ({ kind: 'specific' }) as unknown as WebGLTexture);
|
|
151
183
|
expect(resolveGlTexture(state, textureWithImage(image))).toEqual({ kind: 'specific' });
|
|
152
184
|
});
|
|
153
185
|
});
|
|
154
186
|
|
|
155
|
-
describe('
|
|
156
|
-
it('
|
|
157
|
-
const { state
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
registerGlVideoTextureResolver(state);
|
|
165
|
-
|
|
166
|
-
const first = resolveGlTexture(state, texture);
|
|
167
|
-
const uploads = (gl.texImage2D as ReturnType<typeof vi.fn>).mock.calls.length;
|
|
168
|
-
const second = resolveGlTexture(state, texture);
|
|
169
|
-
|
|
170
|
-
expect(first).not.toBeNull();
|
|
171
|
-
expect(second).toBe(first);
|
|
172
|
-
expect(gl.texImage2D).toHaveBeenCalledWith(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, video.source);
|
|
173
|
-
expect(gl.texImage2D).toHaveBeenCalledTimes(uploads);
|
|
187
|
+
describe('registerStandardGlTextureResolvers', () => {
|
|
188
|
+
it('registers bitmap, image, and render texture sources without compressed images', () => {
|
|
189
|
+
const { state } = createGlState();
|
|
190
|
+
registerStandardGlTextureResolvers(state);
|
|
191
|
+
expect([...getGlRenderStateRuntime(state).glTextureResolverRegistry!.keys()]).toEqual([
|
|
192
|
+
BitmapTextureSourceKind,
|
|
193
|
+
ImageTextureSourceKind,
|
|
194
|
+
RenderTargetTextureSourceKind,
|
|
195
|
+
]);
|
|
174
196
|
});
|
|
175
197
|
});
|
|
176
198
|
|
|
177
199
|
describe('resolveGlTexture', () => {
|
|
178
|
-
it('returns null when the state has no registered
|
|
200
|
+
it('returns null when the state has no registered source resolver', () => {
|
|
179
201
|
const { state } = createGlState();
|
|
180
202
|
expect(resolveGlTexture(state, textureWithImage(imageResource()))).toBeNull();
|
|
181
203
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Image } from '@flighthq/types/contract';
|
|
2
2
|
|
|
3
3
|
import { uploadGlTextureData, uploadGlTextureElement, uploadGlTextureImageResource } from './glTextureUpload';
|
|
4
4
|
|
|
@@ -34,7 +34,7 @@ describe('uploadGlTextureImageResource', () => {
|
|
|
34
34
|
it('takes the element path when the resource carries a source', () => {
|
|
35
35
|
const gl = makeGl();
|
|
36
36
|
const source = {} as TexImageSource;
|
|
37
|
-
const image = { source, width: 4, height: 4 } as unknown as
|
|
37
|
+
const image = { source, width: 4, height: 4 } as unknown as Image;
|
|
38
38
|
uploadGlTextureImageResource(gl, gl.TEXTURE_2D, image);
|
|
39
39
|
expect(gl.texImage2D).toHaveBeenCalledWith(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);
|
|
40
40
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Image } from '@flighthq/types/contract';
|
|
2
2
|
|
|
3
3
|
import { uploadGlTextureVideoFrame } from './glTextureVideoUpload';
|
|
4
4
|
|
|
@@ -11,12 +11,12 @@ function makeGl(): WebGL2RenderingContext {
|
|
|
11
11
|
} as unknown as WebGL2RenderingContext;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
// A video
|
|
15
|
-
function makeVideoImage(version: number, readyState = 4, videoWidth = 320, videoHeight = 240):
|
|
14
|
+
// A video Image whose only relevant fields are version and the borrowed host element.
|
|
15
|
+
function makeVideoImage(version: number, readyState = 4, videoWidth = 320, videoHeight = 240): Image {
|
|
16
16
|
return {
|
|
17
17
|
source: { readyState, videoWidth, videoHeight } as unknown as HTMLVideoElement,
|
|
18
18
|
version,
|
|
19
|
-
} as unknown as
|
|
19
|
+
} as unknown as Image;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
describe('uploadGlTextureVideoFrame', () => {
|
|
@@ -46,7 +46,7 @@ describe('uploadGlTextureVideoFrame', () => {
|
|
|
46
46
|
|
|
47
47
|
it('skips when the element is null', () => {
|
|
48
48
|
const gl = makeGl();
|
|
49
|
-
const image = { source: null, version: 2 } as unknown as
|
|
49
|
+
const image = { source: null, version: 2 } as unknown as Image;
|
|
50
50
|
expect(uploadGlTextureVideoFrame(gl, image, -1)).toBe(-1);
|
|
51
51
|
expect(gl.texImage2D).not.toHaveBeenCalled();
|
|
52
52
|
});
|