@swf2es/context3d 0.1.18 → 0.1.20

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/src/backend.ts CHANGED
@@ -1,6 +1,26 @@
1
1
  import type { ProgramType } from "./agal.js";
2
2
  import type { DxtEncoder } from "./dxt.js";
3
3
 
4
+ /**
5
+ * The widest and tallest back buffer configure() takes: Flash Player 32's and AIR 51's
6
+ * maxBackBufferWidth and maxBackBufferHeight on a desktop GPU, in every profile. A GPU that
7
+ * allows less still takes it, and draws it smaller (WebGLContext3D).
8
+ */
9
+ export const MOST_BACK_BUFFER = 16384;
10
+
11
+ /**
12
+ * A length in stage pixels at `scale` of the screen's to them, as AIR draws a back buffer
13
+ * configured for best resolution and its scissor rectangle: rounded half to even, as the
14
+ * FPU rounds by default (AIR 51 on Windows at 144 DPI: 33 to 50, 47 to 70).
15
+ */
16
+ export function screenPixels(length: number, scale: number): number {
17
+ const exact = length * scale;
18
+ const floor = Math.floor(exact);
19
+ const rest = exact - floor;
20
+
21
+ return rest > 0.5 || (rest === 0.5 && floor % 2 !== 0) ? floor + 1 : floor;
22
+ }
23
+
4
24
  export const COMPARE_MODES = [
5
25
  "always",
6
26
  "never",
@@ -53,10 +73,104 @@ export type SamplerFilter = (typeof SAMPLER_FILTERS)[number];
53
73
  export const SAMPLER_MIPS = ["mipnone", "mipnearest", "miplinear"] as const;
54
74
  export type SamplerMip = (typeof SAMPLER_MIPS)[number];
55
75
 
56
- /** The texture formats a backend stores: BGRA, and S3TC's DXT1 and DXT5 as Flash calls them. */
57
- export const TEXTURE_FORMATS = ["bgra", "compressed", "compressedAlpha"] as const;
76
+ /**
77
+ * The texture formats a backend stores: BGRA, S3TC's DXT1 and DXT5 as Flash calls them,
78
+ * 16-bit 5:6:5 colour and 4:4:4:4 colour with alpha, and RGBA in half floats.
79
+ */
80
+ export const TEXTURE_FORMATS = [
81
+ "bgra",
82
+ "compressed",
83
+ "compressedAlpha",
84
+ "bgrPacked565",
85
+ "bgraPacked4444",
86
+ "rgbaHalfFloat",
87
+ ] as const;
58
88
  export type TextureFormat = (typeof TEXTURE_FORMATS)[number];
59
89
 
90
+ /** Bytes a texel of each uncompressed format takes, as its byte uploads give it. */
91
+ export const TEXEL_BYTES: Partial<Record<TextureFormat, number>> = {
92
+ bgra: 4,
93
+ bgrPacked565: 2,
94
+ bgraPacked4444: 2,
95
+ rgbaHalfFloat: 8,
96
+ };
97
+
98
+ /** Whether a format holds S3TC blocks, which no draw renders into. */
99
+ export function compressedFormat(format: TextureFormat): boolean {
100
+ return format === "compressed" || format === "compressedAlpha";
101
+ }
102
+
103
+ /** Stage3D's profiles, from what the least GPU does to the most. */
104
+ export const PROFILES = [
105
+ "baselineConstrained",
106
+ "baseline",
107
+ "baselineExtended",
108
+ "standardConstrained",
109
+ "standard",
110
+ "standardExtended",
111
+ ] as const;
112
+ export type Profile = (typeof PROFILES)[number];
113
+
114
+ /** What a profile allows, as AIR 51 grants it on a desktop GPU (docs/architecture/rendering.md). */
115
+ export interface ProfileLimits {
116
+ /** The newest AGAL version its programs may be. */
117
+ readonly agal: number;
118
+ /** The widest and tallest Texture. */
119
+ readonly textureSize: number;
120
+ /** The widest and tallest RectangleTexture, 0 where the profile has none. */
121
+ readonly rectangleSize: number;
122
+ /** Whether it creates rgbaHalfFloat textures. */
123
+ readonly halfFloat: boolean;
124
+ /** How many textures a draw renders into at once. */
125
+ readonly colorOutputs: number;
126
+ }
127
+
128
+ const LIMITS: Record<Profile, ProfileLimits> = {
129
+ baselineConstrained: {
130
+ agal: 1,
131
+ textureSize: 2048,
132
+ rectangleSize: 0,
133
+ halfFloat: false,
134
+ colorOutputs: 1,
135
+ },
136
+ baseline: { agal: 1, textureSize: 2048, rectangleSize: 2048, halfFloat: false, colorOutputs: 1 },
137
+ baselineExtended: {
138
+ agal: 1,
139
+ textureSize: 4096,
140
+ rectangleSize: 4096,
141
+ halfFloat: false,
142
+ colorOutputs: 1,
143
+ },
144
+ standardConstrained: {
145
+ agal: 2,
146
+ textureSize: 4096,
147
+ rectangleSize: 4096,
148
+ halfFloat: true,
149
+ colorOutputs: 1,
150
+ },
151
+ standard: { agal: 2, textureSize: 4096, rectangleSize: 4096, halfFloat: true, colorOutputs: 4 },
152
+ standardExtended: {
153
+ agal: 3,
154
+ textureSize: 4096,
155
+ rectangleSize: 4096,
156
+ halfFloat: true,
157
+ colorOutputs: 4,
158
+ },
159
+ };
160
+
161
+ export function profileLimits(profile: Profile): ProfileLimits {
162
+ return LIMITS[profile];
163
+ }
164
+
165
+ /** Cube faces are at most this wide in every profile. */
166
+ export const MOST_CUBE = 1024;
167
+
168
+ /** Sampler, vertex attribute and constant registers a context holds in every profile. */
169
+ export const SAMPLER_SLOTS = 16;
170
+ export const VERTEX_SLOTS = 16;
171
+ export const VERTEX_CONSTANTS = 250;
172
+ export const FRAGMENT_CONSTANTS = 200;
173
+
60
174
  export const VERTEX_FORMATS = ["float1", "float2", "float3", "float4", "bytes4"] as const;
61
175
  export type VertexFormat = (typeof VERTEX_FORMATS)[number];
62
176
 
@@ -77,7 +191,8 @@ export class TextureBindingError extends Error {
77
191
  | "wrap"
78
192
  | "rectangleMip"
79
193
  | "feedback"
80
- | "format";
194
+ | "format"
195
+ | "streaming";
81
196
 
82
197
  /** The sampler it names, where it names one. */
83
198
  readonly sampler: number;
@@ -100,6 +215,10 @@ export interface Buffer3D {
100
215
  }
101
216
 
102
217
  export interface Program3D {
218
+ /** The colour outputs its fragment program writes, 1 to 4; 1 before an upload. */
219
+ readonly outputs: number;
220
+ /** The vertex attributes it reads, a bit each; 0 before an upload. */
221
+ readonly attributes: number;
103
222
  upload(vertex: Uint8Array, fragment: Uint8Array): void;
104
223
  dispose(): void;
105
224
  }
@@ -110,6 +229,11 @@ export interface Texture3D {
110
229
  readonly levels: number;
111
230
  readonly cube: boolean;
112
231
  readonly rectangle: boolean;
232
+ /**
233
+ * createTexture's streamingLevels: the levels from it to the smallest are enough to draw it
234
+ * with mip filtering, from the finest of them uploaded, as AIR draws a texture still loading.
235
+ */
236
+ readonly streaming: number;
113
237
  /** What samplers must read it as; a compressed texture also takes pixels, as AIR's do. */
114
238
  readonly format: TextureFormat;
115
239
  /** Top-down premultiplied ARGB pixels, copied before returning.
@@ -140,6 +264,11 @@ export interface Context3DLifecycle {
140
264
  /** Loss callbacks are asynchronous. Keep the lost surface until remove(), including
141
265
  * its restoration listener; remove() must detach both listeners before releasing it. */
142
266
  export interface Stage3DHost {
267
+ /**
268
+ * What a request waits for before create(): a host that loads its backend at the first
269
+ * request gives the load, null once loaded. A rejection makes the context unavailable (#3702).
270
+ */
271
+ ready?(): Promise<unknown> | null;
143
272
  create(slot: number, lifecycle: Context3DLifecycle): Context3D;
144
273
  place(slot: number, x: number, y: number, visible: boolean): void;
145
274
  remove(slot: number): void;
@@ -154,9 +283,24 @@ export interface Context3D {
154
283
  * format (TextureBindingError "format"): AIR checks from SWF 17 on.
155
284
  */
156
285
  samplerFormats: boolean;
286
+ /** The profile it was made for: what its programs, textures and targets may be. */
287
+ profile: Profile;
157
288
  /** Optional acceleration for pixels uploaded to compressed textures. */
158
289
  setDxtEncoder?(encoder: DxtEncoder): void;
159
- configure(width: number, height: number, depth?: boolean, antiAlias?: number): void;
290
+ /**
291
+ * Width and height from 32 to MOST_BACK_BUFFER, in the back buffer's pixels. `scale` is
292
+ * those to a CSS pixel where it shows, and to a scissor rectangle's unit: a back buffer
293
+ * configured for best resolution has the stage's contentsScaleFactor, any other 1.
294
+ */
295
+ configure(
296
+ width: number,
297
+ height: number,
298
+ depth?: boolean,
299
+ antiAlias?: number,
300
+ scale?: number,
301
+ ): void;
302
+ /** No back buffer, width and height 0, as a size configureBackBuffer refuses leaves AIR's. */
303
+ unconfigure(): void;
160
304
  clear(
161
305
  red: number,
162
306
  green: number,
@@ -180,10 +324,18 @@ export interface Context3D {
180
324
  setColorMask(red: boolean, green: boolean, blue: boolean, alpha: boolean): void;
181
325
  /** Null disables clipping; coordinates are in top-down target pixels. */
182
326
  setScissor(x: number | null, y?: number, width?: number, height?: number): void;
183
- createBuffer(count: number, stride: number): Buffer3D;
327
+ /** `stride` 32-bit values a vertex, or 0 for 16-bit indices; `dynamic` for data uploaded often. */
328
+ createBuffer(count: number, stride: number, dynamic?: boolean): Buffer3D;
184
329
  createProgram(): Program3D;
185
- createTexture(width: number, height: number, cube?: boolean, format?: TextureFormat): Texture3D;
186
- createRectangleTexture(width: number, height: number): Texture3D;
330
+ /** `streaming` from 0 to the texture's levels less one. */
331
+ createTexture(
332
+ width: number,
333
+ height: number,
334
+ cube?: boolean,
335
+ format?: TextureFormat,
336
+ streaming?: number,
337
+ ): Texture3D;
338
+ createRectangleTexture(width: number, height: number, format?: TextureFormat): Texture3D;
187
339
  /** Level-zero target; face selects a cube surface. Null resumes the back buffer. */
188
340
  setRenderTarget(
189
341
  texture: Texture3D | null,
@@ -191,6 +343,11 @@ export interface Context3D {
191
343
  face?: number,
192
344
  antiAlias?: number,
193
345
  ): void;
346
+ /**
347
+ * Colour output `index`, 1 to 3, draws into `texture` (`face` of a cube) beside
348
+ * setRenderTarget's; null stops it. The texture's size and format are the target's.
349
+ */
350
+ setColorOutput(index: number, texture: Texture3D | null, face?: number): void;
194
351
  setSampler(index: number, wrap: SamplerWrap, filter: SamplerFilter, mip: SamplerMip): void;
195
352
  setTexture(index: number, texture: Texture3D | null): void;
196
353
  setProgram(program: Program3D): void;
package/src/errors.ts CHANGED
@@ -56,7 +56,33 @@ export type Context3DErrorReason =
56
56
  | "agalDiscard"
57
57
  | "agalMask"
58
58
  | "agalReserved"
59
- | "agalSampler";
59
+ | "agalSampler"
60
+ | "agalProfileVersion"
61
+ | "agalOpcodeRange"
62
+ | "agalOpcodeVersion"
63
+ | "agalFragmentOnly"
64
+ | "agalSamplerStage"
65
+ | "agalElse"
66
+ | "agalEndIf"
67
+ | "agalEmptyBranch"
68
+ | "agalConditionDestination"
69
+ | "agalScalar"
70
+ | "agalNesting"
71
+ | "agalConditionOutput"
72
+ | "agalConditionTexture"
73
+ | "agalDepthStage"
74
+ | "agalDepthIndex"
75
+ | "agalDepthMask"
76
+ | "agalInstanceStage"
77
+ | "agalOutputTwice"
78
+ | "agalOutputSlots"
79
+ | "agalConditionDerivative"
80
+ | "agalConstants"
81
+ | "agalNativeLength"
82
+ | "agalSamplerIndex"
83
+ | "agalSamplerDimension"
84
+ | "agalSamplerMip"
85
+ | "agalSamplerFilter";
60
86
 
61
87
  export class Context3DError extends Error {
62
88
  readonly reason: Context3DErrorReason;
package/src/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- /** Experimental renderer contracts and AGAL v1 translation, without browser dependencies. */
1
+ /** Stage3D's renderer contracts and AGAL translation, without browser dependencies. */
2
2
 
3
3
  export { type ProgramType, type SamplerSource, type ShaderSource, translate } from "./agal.js";
4
4
  export {
@@ -11,9 +11,18 @@ export {
11
11
  type Context3DLifecycle,
12
12
  CULL_FACES,
13
13
  type CullFace,
14
+ compressedFormat,
15
+ FRAGMENT_CONSTANTS,
16
+ MOST_BACK_BUFFER,
17
+ MOST_CUBE,
18
+ PROFILES,
19
+ type Profile,
20
+ type ProfileLimits,
14
21
  type Program3D,
22
+ profileLimits,
15
23
  SAMPLER_FILTERS,
16
24
  SAMPLER_MIPS,
25
+ SAMPLER_SLOTS,
17
26
  SAMPLER_WRAPS,
18
27
  SamplerBiasError,
19
28
  type SamplerFilter,
@@ -23,11 +32,15 @@ export {
23
32
  STENCIL_ACTIONS,
24
33
  type Stage3DHost,
25
34
  type StencilAction,
35
+ screenPixels,
36
+ TEXEL_BYTES,
26
37
  TEXTURE_FORMATS,
27
38
  type Texture3D,
28
39
  TextureBindingError,
29
40
  type TextureFormat,
41
+ VERTEX_CONSTANTS,
30
42
  VERTEX_FORMATS,
43
+ VERTEX_SLOTS,
31
44
  type VertexFormat,
32
45
  VertexOffsetError,
33
46
  } from "./backend.js";