1use std::borrow::Cow;
6use std::fmt;
7use std::num::{NonZeroU32, NonZeroU64};
8use std::ops::Deref;
9
10use base::Epoch;
11pub use base::generic_channel::GenericReceiver as WebGLReceiver;
13pub use base::generic_channel::GenericSender as WebGLSender;
15pub use base::generic_channel::SendResult as WebGLSendResult;
17use euclid::default::{Rect, Size2D};
18use glow::{
19 self as gl, NativeBuffer, NativeFence, NativeFramebuffer, NativeProgram, NativeQuery,
20 NativeRenderbuffer, NativeSampler, NativeShader, NativeTexture, NativeVertexArray,
21};
22use ipc_channel::ipc::{IpcBytesReceiver, IpcBytesSender, IpcSender, IpcSharedMemory};
23use malloc_size_of_derive::MallocSizeOf;
24use pixels::{PixelFormat, SnapshotAlphaMode};
25use serde::{Deserialize, Serialize};
26use webrender_api::ImageKey;
27use webxr_api::{
28 ContextId as WebXRContextId, Error as WebXRError, LayerId as WebXRLayerId,
29 LayerInit as WebXRLayerInit, SubImages as WebXRSubImages,
30};
31
32pub fn webgl_channel<T>() -> Option<(WebGLSender<T>, WebGLReceiver<T>)>
34where
35 T: for<'de> Deserialize<'de> + Serialize,
36{
37 base::generic_channel::channel()
38}
39
40#[derive(Clone, Debug, Deserialize, Serialize)]
42pub struct WebGLChan(pub WebGLSender<WebGLMsg>);
43
44impl WebGLChan {
45 #[inline]
46 pub fn send(&self, msg: WebGLMsg) -> WebGLSendResult {
47 self.0.send(msg)
48 }
49}
50
51#[derive(Clone, Debug, Deserialize, Serialize)]
53pub struct WebGLPipeline(pub WebGLChan);
54
55impl WebGLPipeline {
56 pub fn channel(&self) -> WebGLChan {
57 self.0.clone()
58 }
59}
60
61#[derive(Clone, Debug, Deserialize, Serialize)]
62pub struct WebGLCommandBacktrace {
63 #[cfg(feature = "webgl_backtrace")]
64 pub backtrace: String,
65 #[cfg(feature = "webgl_backtrace")]
66 pub js_backtrace: Option<String>,
67}
68
69#[derive(Clone)]
71pub struct WebGLThreads(pub WebGLSender<WebGLMsg>);
72
73impl WebGLThreads {
74 pub fn pipeline(&self) -> WebGLPipeline {
76 WebGLPipeline(WebGLChan(self.0.clone()))
78 }
79
80 pub fn exit(&self, sender: IpcSender<()>) -> Result<(), &'static str> {
82 self.0
83 .send(WebGLMsg::Exit(sender))
84 .map_err(|_| "Failed to send Exit message")
85 }
86}
87
88#[derive(Debug, Deserialize, Serialize)]
90pub enum WebGLMsg {
91 CreateContext(
93 WebGLVersion,
94 Size2D<u32>,
95 GLContextAttributes,
96 WebGLSender<Result<WebGLCreateContextResult, String>>,
97 ),
98 SetImageKey(WebGLContextId, ImageKey),
100 ResizeContext(WebGLContextId, Size2D<u32>, WebGLSender<Result<(), String>>),
102 RemoveContext(WebGLContextId),
104 WebGLCommand(WebGLContextId, WebGLCommand, WebGLCommandBacktrace),
106 WebXRCommand(WebXRCommand),
109 SwapBuffers(Vec<WebGLContextId>, Option<Epoch>, u64),
115 Exit(IpcSender<()>),
117}
118
119#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
120pub enum GlType {
121 Gl,
122 Gles,
123}
124
125#[derive(Clone, Debug, Deserialize, Serialize)]
127pub struct WebGLCreateContextResult {
128 pub sender: WebGLMsgSender,
130 pub limits: GLLimits,
132 pub glsl_version: WebGLSLVersion,
134 pub api_type: GlType,
136}
137
138#[derive(Clone, Copy, Debug, Deserialize, Eq, MallocSizeOf, PartialEq, PartialOrd, Serialize)]
140pub enum WebGLVersion {
141 WebGL1,
144 WebGL2,
147}
148
149#[derive(
151 Clone, Copy, Debug, Deserialize, Eq, MallocSizeOf, Ord, PartialEq, PartialOrd, Serialize,
152)]
153pub struct WebGLSLVersion {
154 pub major: u32,
156 pub minor: u32,
158}
159
160#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
162pub struct WebGLMsgSender {
163 ctx_id: WebGLContextId,
164 #[ignore_malloc_size_of = "channels are hard"]
165 sender: WebGLChan,
166}
167
168impl WebGLMsgSender {
169 pub fn new(id: WebGLContextId, sender: WebGLChan) -> Self {
170 WebGLMsgSender { ctx_id: id, sender }
171 }
172
173 pub fn context_id(&self) -> WebGLContextId {
175 self.ctx_id
176 }
177
178 #[inline]
180 pub fn send(&self, command: WebGLCommand, backtrace: WebGLCommandBacktrace) -> WebGLSendResult {
181 self.sender
182 .send(WebGLMsg::WebGLCommand(self.ctx_id, command, backtrace))
183 }
184
185 #[inline]
187 pub fn set_image_key(&self, image_key: ImageKey) {
188 let _ = self
189 .sender
190 .send(WebGLMsg::SetImageKey(self.ctx_id, image_key));
191 }
192
193 #[inline]
195 pub fn send_resize(
196 &self,
197 size: Size2D<u32>,
198 sender: WebGLSender<Result<(), String>>,
199 ) -> WebGLSendResult {
200 self.sender
201 .send(WebGLMsg::ResizeContext(self.ctx_id, size, sender))
202 }
203
204 #[inline]
205 pub fn send_remove(&self) -> WebGLSendResult {
206 self.sender.send(WebGLMsg::RemoveContext(self.ctx_id))
207 }
208}
209
210#[derive(Deserialize, Serialize)]
211pub struct TruncatedDebug<T>(T);
212
213impl<T> From<T> for TruncatedDebug<T> {
214 fn from(v: T) -> TruncatedDebug<T> {
215 TruncatedDebug(v)
216 }
217}
218
219impl<T: fmt::Debug> fmt::Debug for TruncatedDebug<T> {
220 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
221 let mut s = format!("{:?}", self.0);
222 if s.len() > 20 {
223 s.truncate(20);
224 s.push_str("...");
225 }
226 write!(f, "{}", s)
227 }
228}
229
230impl<T> Deref for TruncatedDebug<T> {
231 type Target = T;
232 fn deref(&self) -> &T {
233 &self.0
234 }
235}
236
237#[derive(Debug, Deserialize, Serialize)]
239pub enum WebGLCommand {
240 GetContextAttributes(WebGLSender<GLContextAttributes>),
241 ActiveTexture(u32),
242 BlendColor(f32, f32, f32, f32),
243 BlendEquation(u32),
244 BlendEquationSeparate(u32, u32),
245 BlendFunc(u32, u32),
246 BlendFuncSeparate(u32, u32, u32, u32),
247 AttachShader(WebGLProgramId, WebGLShaderId),
248 DetachShader(WebGLProgramId, WebGLShaderId),
249 BindAttribLocation(WebGLProgramId, u32, String),
250 BufferData(u32, IpcBytesReceiver, u32),
251 BufferSubData(u32, isize, IpcBytesReceiver),
252 GetBufferSubData(u32, usize, usize, IpcBytesSender),
253 CopyBufferSubData(u32, u32, i64, i64, i64),
254 Clear(u32),
255 ClearColor(f32, f32, f32, f32),
256 ClearDepth(f32),
257 ClearStencil(i32),
258 ColorMask(bool, bool, bool, bool),
259 CullFace(u32),
260 FrontFace(u32),
261 DepthFunc(u32),
262 DepthMask(bool),
263 DepthRange(f32, f32),
264 Enable(u32),
265 Disable(u32),
266 CompileShader(WebGLShaderId, String),
267 CopyTexImage2D(u32, i32, u32, i32, i32, i32, i32, i32),
268 CopyTexSubImage2D(u32, i32, i32, i32, i32, i32, i32, i32),
269 CreateBuffer(WebGLSender<Option<WebGLBufferId>>),
270 CreateFramebuffer(WebGLSender<Option<WebGLFramebufferId>>),
271 CreateRenderbuffer(WebGLSender<Option<WebGLRenderbufferId>>),
272 CreateTexture(WebGLSender<Option<WebGLTextureId>>),
273 CreateProgram(WebGLSender<Option<WebGLProgramId>>),
274 CreateShader(u32, WebGLSender<Option<WebGLShaderId>>),
275 DeleteBuffer(WebGLBufferId),
276 DeleteFramebuffer(WebGLFramebufferId),
277 DeleteRenderbuffer(WebGLRenderbufferId),
278 DeleteTexture(WebGLTextureId),
279 DeleteProgram(WebGLProgramId),
280 DeleteShader(WebGLShaderId),
281 BindBuffer(u32, Option<WebGLBufferId>),
282 BindFramebuffer(u32, WebGLFramebufferBindingRequest),
283 BindRenderbuffer(u32, Option<WebGLRenderbufferId>),
284 BindTexture(u32, Option<WebGLTextureId>),
285 BlitFrameBuffer(i32, i32, i32, i32, i32, i32, i32, i32, u32, u32),
286 DisableVertexAttribArray(u32),
287 EnableVertexAttribArray(u32),
288 FramebufferRenderbuffer(u32, u32, u32, Option<WebGLRenderbufferId>),
289 FramebufferTexture2D(u32, u32, u32, Option<WebGLTextureId>, i32),
290 GetExtensions(WebGLSender<String>),
291 GetShaderPrecisionFormat(u32, u32, WebGLSender<(i32, i32, i32)>),
292 GetFragDataLocation(WebGLProgramId, String, WebGLSender<i32>),
293 GetUniformLocation(WebGLProgramId, String, WebGLSender<i32>),
294 GetShaderInfoLog(WebGLShaderId, WebGLSender<String>),
295 GetProgramInfoLog(WebGLProgramId, WebGLSender<String>),
296 GetFramebufferAttachmentParameter(u32, u32, u32, WebGLSender<i32>),
297 GetRenderbufferParameter(u32, u32, WebGLSender<i32>),
298 CreateTransformFeedback(WebGLSender<u32>),
299 DeleteTransformFeedback(u32),
300 IsTransformFeedback(u32, WebGLSender<bool>),
301 BindTransformFeedback(u32, u32),
302 BeginTransformFeedback(u32),
303 EndTransformFeedback(),
304 PauseTransformFeedback(),
305 ResumeTransformFeedback(),
306 GetTransformFeedbackVarying(WebGLProgramId, u32, WebGLSender<(i32, u32, String)>),
307 TransformFeedbackVaryings(WebGLProgramId, Vec<String>, u32),
308 PolygonOffset(f32, f32),
309 RenderbufferStorage(u32, u32, i32, i32),
310 RenderbufferStorageMultisample(u32, i32, u32, i32, i32),
311 ReadPixels(
312 Rect<u32>,
313 u32,
314 u32,
315 IpcSender<(IpcSharedMemory, SnapshotAlphaMode)>,
316 ),
317 ReadPixelsPP(Rect<i32>, u32, u32, usize),
318 SampleCoverage(f32, bool),
319 Scissor(i32, i32, u32, u32),
320 StencilFunc(u32, i32, u32),
321 StencilFuncSeparate(u32, u32, i32, u32),
322 StencilMask(u32),
323 StencilMaskSeparate(u32, u32),
324 StencilOp(u32, u32, u32),
325 StencilOpSeparate(u32, u32, u32, u32),
326 FenceSync(WebGLSender<WebGLSyncId>),
327 IsSync(WebGLSyncId, WebGLSender<bool>),
328 ClientWaitSync(WebGLSyncId, u32, u64, WebGLSender<u32>),
329 WaitSync(WebGLSyncId, u32, i64),
330 GetSyncParameter(WebGLSyncId, u32, WebGLSender<u32>),
331 DeleteSync(WebGLSyncId),
332 Hint(u32, u32),
333 LineWidth(f32),
334 PixelStorei(u32, i32),
335 LinkProgram(WebGLProgramId, WebGLSender<ProgramLinkInfo>),
336 Uniform1f(i32, f32),
337 Uniform1fv(i32, Vec<f32>),
338 Uniform1i(i32, i32),
339 Uniform1ui(i32, u32),
340 Uniform1iv(i32, Vec<i32>),
341 Uniform1uiv(i32, Vec<u32>),
342 Uniform2f(i32, f32, f32),
343 Uniform2fv(i32, Vec<f32>),
344 Uniform2i(i32, i32, i32),
345 Uniform2ui(i32, u32, u32),
346 Uniform2iv(i32, Vec<i32>),
347 Uniform2uiv(i32, Vec<u32>),
348 Uniform3f(i32, f32, f32, f32),
349 Uniform3fv(i32, Vec<f32>),
350 Uniform3i(i32, i32, i32, i32),
351 Uniform3ui(i32, u32, u32, u32),
352 Uniform3iv(i32, Vec<i32>),
353 Uniform3uiv(i32, Vec<u32>),
354 Uniform4f(i32, f32, f32, f32, f32),
355 Uniform4fv(i32, Vec<f32>),
356 Uniform4i(i32, i32, i32, i32, i32),
357 Uniform4ui(i32, u32, u32, u32, u32),
358 Uniform4iv(i32, Vec<i32>),
359 Uniform4uiv(i32, Vec<u32>),
360 UniformMatrix2fv(i32, Vec<f32>),
361 UniformMatrix3fv(i32, Vec<f32>),
362 UniformMatrix4fv(i32, Vec<f32>),
363 UniformMatrix3x2fv(i32, Vec<f32>),
364 UniformMatrix4x2fv(i32, Vec<f32>),
365 UniformMatrix2x3fv(i32, Vec<f32>),
366 UniformMatrix4x3fv(i32, Vec<f32>),
367 UniformMatrix2x4fv(i32, Vec<f32>),
368 UniformMatrix3x4fv(i32, Vec<f32>),
369 UseProgram(Option<WebGLProgramId>),
370 ValidateProgram(WebGLProgramId),
371 VertexAttrib(u32, f32, f32, f32, f32),
372 VertexAttribI(u32, i32, i32, i32, i32),
373 VertexAttribU(u32, u32, u32, u32, u32),
374 VertexAttribPointer(u32, i32, u32, bool, i32, u32),
375 VertexAttribPointer2f(u32, i32, bool, i32, u32),
376 SetViewport(i32, i32, i32, i32),
377 TexImage3D {
378 target: u32,
379 level: u32,
380 internal_format: TexFormat,
381 size: Size2D<u32>,
382 depth: u32,
383 format: TexFormat,
384 data_type: TexDataType,
385 effective_data_type: u32,
387 unpacking_alignment: u32,
388 alpha_treatment: Option<AlphaTreatment>,
389 y_axis_treatment: YAxisTreatment,
390 pixel_format: Option<PixelFormat>,
391 data: TruncatedDebug<IpcSharedMemory>,
392 },
393 TexImage2D {
394 target: u32,
395 level: u32,
396 internal_format: TexFormat,
397 size: Size2D<u32>,
398 format: TexFormat,
399 data_type: TexDataType,
400 effective_data_type: u32,
402 unpacking_alignment: u32,
403 alpha_treatment: Option<AlphaTreatment>,
404 y_axis_treatment: YAxisTreatment,
405 pixel_format: Option<PixelFormat>,
406 data: TruncatedDebug<IpcSharedMemory>,
407 },
408 TexImage2DPBO {
409 target: u32,
410 level: u32,
411 internal_format: TexFormat,
412 size: Size2D<u32>,
413 format: TexFormat,
414 effective_data_type: u32,
415 unpacking_alignment: u32,
416 offset: i64,
417 },
418 TexSubImage2D {
419 target: u32,
420 level: u32,
421 xoffset: i32,
422 yoffset: i32,
423 size: Size2D<u32>,
424 format: TexFormat,
425 data_type: TexDataType,
426 effective_data_type: u32,
428 unpacking_alignment: u32,
429 alpha_treatment: Option<AlphaTreatment>,
430 y_axis_treatment: YAxisTreatment,
431 pixel_format: Option<PixelFormat>,
432 data: TruncatedDebug<IpcSharedMemory>,
433 },
434 CompressedTexImage2D {
435 target: u32,
436 level: u32,
437 internal_format: u32,
438 size: Size2D<u32>,
439 data: TruncatedDebug<IpcSharedMemory>,
440 },
441 CompressedTexSubImage2D {
442 target: u32,
443 level: i32,
444 xoffset: i32,
445 yoffset: i32,
446 size: Size2D<u32>,
447 format: u32,
448 data: TruncatedDebug<IpcSharedMemory>,
449 },
450 DrawingBufferWidth(WebGLSender<i32>),
451 DrawingBufferHeight(WebGLSender<i32>),
452 Finish(WebGLSender<()>),
453 Flush,
454 GenerateMipmap(u32),
455 CreateVertexArray(WebGLSender<Option<WebGLVertexArrayId>>),
456 DeleteVertexArray(WebGLVertexArrayId),
457 BindVertexArray(Option<WebGLVertexArrayId>),
458 GetParameterBool(ParameterBool, WebGLSender<bool>),
459 GetParameterBool4(ParameterBool4, WebGLSender<[bool; 4]>),
460 GetParameterInt(ParameterInt, WebGLSender<i32>),
461 GetParameterInt2(ParameterInt2, WebGLSender<[i32; 2]>),
462 GetParameterInt4(ParameterInt4, WebGLSender<[i32; 4]>),
463 GetParameterFloat(ParameterFloat, WebGLSender<f32>),
464 GetParameterFloat2(ParameterFloat2, WebGLSender<[f32; 2]>),
465 GetParameterFloat4(ParameterFloat4, WebGLSender<[f32; 4]>),
466 GetProgramValidateStatus(WebGLProgramId, WebGLSender<bool>),
467 GetProgramActiveUniforms(WebGLProgramId, WebGLSender<i32>),
468 GetCurrentVertexAttrib(u32, WebGLSender<[f32; 4]>),
469 GetTexParameterFloat(u32, TexParameterFloat, WebGLSender<f32>),
470 GetTexParameterInt(u32, TexParameterInt, WebGLSender<i32>),
471 GetTexParameterBool(u32, TexParameterBool, WebGLSender<bool>),
472 GetInternalFormatIntVec(u32, u32, InternalFormatIntVec, WebGLSender<Vec<i32>>),
473 TexParameteri(u32, u32, i32),
474 TexParameterf(u32, u32, f32),
475 TexStorage2D(u32, u32, TexFormat, u32, u32),
476 TexStorage3D(u32, u32, TexFormat, u32, u32, u32),
477 DrawArrays {
478 mode: u32,
479 first: i32,
480 count: i32,
481 },
482 DrawArraysInstanced {
483 mode: u32,
484 first: i32,
485 count: i32,
486 primcount: i32,
487 },
488 DrawElements {
489 mode: u32,
490 count: i32,
491 type_: u32,
492 offset: u32,
493 },
494 DrawElementsInstanced {
495 mode: u32,
496 count: i32,
497 type_: u32,
498 offset: u32,
499 primcount: i32,
500 },
501 VertexAttribDivisor {
502 index: u32,
503 divisor: u32,
504 },
505 GetUniformBool(WebGLProgramId, i32, WebGLSender<bool>),
506 GetUniformBool2(WebGLProgramId, i32, WebGLSender<[bool; 2]>),
507 GetUniformBool3(WebGLProgramId, i32, WebGLSender<[bool; 3]>),
508 GetUniformBool4(WebGLProgramId, i32, WebGLSender<[bool; 4]>),
509 GetUniformInt(WebGLProgramId, i32, WebGLSender<i32>),
510 GetUniformInt2(WebGLProgramId, i32, WebGLSender<[i32; 2]>),
511 GetUniformInt3(WebGLProgramId, i32, WebGLSender<[i32; 3]>),
512 GetUniformInt4(WebGLProgramId, i32, WebGLSender<[i32; 4]>),
513 GetUniformUint(WebGLProgramId, i32, WebGLSender<u32>),
514 GetUniformUint2(WebGLProgramId, i32, WebGLSender<[u32; 2]>),
515 GetUniformUint3(WebGLProgramId, i32, WebGLSender<[u32; 3]>),
516 GetUniformUint4(WebGLProgramId, i32, WebGLSender<[u32; 4]>),
517 GetUniformFloat(WebGLProgramId, i32, WebGLSender<f32>),
518 GetUniformFloat2(WebGLProgramId, i32, WebGLSender<[f32; 2]>),
519 GetUniformFloat3(WebGLProgramId, i32, WebGLSender<[f32; 3]>),
520 GetUniformFloat4(WebGLProgramId, i32, WebGLSender<[f32; 4]>),
521 GetUniformFloat9(WebGLProgramId, i32, WebGLSender<[f32; 9]>),
522 GetUniformFloat16(WebGLProgramId, i32, WebGLSender<[f32; 16]>),
523 GetUniformFloat2x3(WebGLProgramId, i32, WebGLSender<[f32; 2 * 3]>),
524 GetUniformFloat2x4(WebGLProgramId, i32, WebGLSender<[f32; 2 * 4]>),
525 GetUniformFloat3x2(WebGLProgramId, i32, WebGLSender<[f32; 3 * 2]>),
526 GetUniformFloat3x4(WebGLProgramId, i32, WebGLSender<[f32; 3 * 4]>),
527 GetUniformFloat4x2(WebGLProgramId, i32, WebGLSender<[f32; 4 * 2]>),
528 GetUniformFloat4x3(WebGLProgramId, i32, WebGLSender<[f32; 4 * 3]>),
529 GetUniformBlockIndex(WebGLProgramId, String, WebGLSender<u32>),
530 GetUniformIndices(WebGLProgramId, Vec<String>, WebGLSender<Vec<u32>>),
531 GetActiveUniforms(WebGLProgramId, Vec<u32>, u32, WebGLSender<Vec<i32>>),
532 GetActiveUniformBlockName(WebGLProgramId, u32, WebGLSender<String>),
533 GetActiveUniformBlockParameter(WebGLProgramId, u32, u32, WebGLSender<Vec<i32>>),
534 UniformBlockBinding(WebGLProgramId, u32, u32),
535 InitializeFramebuffer {
536 color: bool,
537 depth: bool,
538 stencil: bool,
539 },
540 BeginQuery(u32, WebGLQueryId),
541 DeleteQuery(WebGLQueryId),
542 EndQuery(u32),
543 GenerateQuery(WebGLSender<WebGLQueryId>),
544 GetQueryState(WebGLSender<u32>, WebGLQueryId, u32),
545 GenerateSampler(WebGLSender<WebGLSamplerId>),
546 DeleteSampler(WebGLSamplerId),
547 BindSampler(u32, WebGLSamplerId),
548 SetSamplerParameterFloat(WebGLSamplerId, u32, f32),
549 SetSamplerParameterInt(WebGLSamplerId, u32, i32),
550 GetSamplerParameterFloat(WebGLSamplerId, u32, WebGLSender<f32>),
551 GetSamplerParameterInt(WebGLSamplerId, u32, WebGLSender<i32>),
552 BindBufferBase(u32, u32, Option<WebGLBufferId>),
553 BindBufferRange(u32, u32, Option<WebGLBufferId>, i64, i64),
554 ClearBufferfv(u32, i32, Vec<f32>),
555 ClearBufferiv(u32, i32, Vec<i32>),
556 ClearBufferuiv(u32, i32, Vec<u32>),
557 ClearBufferfi(u32, i32, f32, i32),
558 InvalidateFramebuffer(u32, Vec<u32>),
559 InvalidateSubFramebuffer(u32, Vec<u32>, i32, i32, i32, i32),
560 FramebufferTextureLayer(u32, u32, Option<WebGLTextureId>, i32, i32),
561 ReadBuffer(u32),
562 DrawBuffers(Vec<u32>),
563}
564
565#[derive(Debug, Deserialize, Serialize)]
567pub enum WebXRCommand {
568 CreateLayerManager(WebGLSender<Result<WebXRLayerManagerId, WebXRError>>),
569 DestroyLayerManager(WebXRLayerManagerId),
570 CreateLayer(
571 WebXRLayerManagerId,
572 WebXRContextId,
573 WebXRLayerInit,
574 WebGLSender<Result<WebXRLayerId, WebXRError>>,
575 ),
576 DestroyLayer(WebXRLayerManagerId, WebXRContextId, WebXRLayerId),
577 BeginFrame(
578 WebXRLayerManagerId,
579 Vec<(WebXRContextId, WebXRLayerId)>,
580 WebGLSender<Result<Vec<WebXRSubImages>, WebXRError>>,
581 ),
582 EndFrame(
583 WebXRLayerManagerId,
584 Vec<(WebXRContextId, WebXRLayerId)>,
585 WebGLSender<Result<(), WebXRError>>,
586 ),
587}
588
589macro_rules! nonzero_type {
590 (u32) => {
591 NonZeroU32
592 };
593 (u64) => {
594 NonZeroU64
595 };
596}
597
598macro_rules! define_resource_id {
599 ($name:ident, $type:tt) => {
600 #[derive(Clone, Copy, Eq, Hash, PartialEq)]
601 pub struct $name(nonzero_type!($type));
602
603 impl $name {
604 #[inline]
605 pub fn new(id: nonzero_type!($type)) -> Self {
606 Self(id)
607 }
608
609 #[inline]
610 pub fn maybe_new(id: $type) -> Option<Self> {
611 <nonzero_type!($type)>::new(id).map($name)
612 }
613
614 #[inline]
615 pub fn get(self) -> $type {
616 self.0.get()
617 }
618 }
619
620 impl<'de> ::serde::Deserialize<'de> for $name {
621 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
622 where
623 D: ::serde::Deserializer<'de>,
624 {
625 let id = <$type>::deserialize(deserializer)?;
626 if let Some(id) = <nonzero_type!($type)>::new(id) {
627 Ok($name(id))
628 } else {
629 Err(::serde::de::Error::custom("expected a non-zero value"))
630 }
631 }
632 }
633
634 impl ::serde::Serialize for $name {
635 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
636 where
637 S: ::serde::Serializer,
638 {
639 self.get().serialize(serializer)
640 }
641 }
642
643 impl ::std::fmt::Debug for $name {
644 fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
645 fmt.debug_tuple(stringify!($name))
646 .field(&self.get())
647 .finish()
648 }
649 }
650
651 impl ::std::fmt::Display for $name {
652 fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
653 write!(fmt, "{}", self.get())
654 }
655 }
656
657 impl ::malloc_size_of::MallocSizeOf for $name {
658 fn size_of(&self, _ops: &mut ::malloc_size_of::MallocSizeOfOps) -> usize {
659 0
660 }
661 }
662 };
663 ($name:ident, $type:tt, $glow:tt) => {
664 impl $name {
665 #[inline]
666 pub fn glow(self) -> $glow {
667 $glow(self.0)
668 }
669
670 #[inline]
671 pub fn from_glow(glow: $glow) -> Self {
672 Self(glow.0)
673 }
674 }
675 define_resource_id!($name, $type);
676 };
677}
678
679define_resource_id!(WebGLBufferId, u32, NativeBuffer);
680define_resource_id!(WebGLFramebufferId, u32, NativeFramebuffer);
681define_resource_id!(WebGLRenderbufferId, u32, NativeRenderbuffer);
682define_resource_id!(WebGLTextureId, u32, NativeTexture);
683define_resource_id!(WebGLProgramId, u32, NativeProgram);
684define_resource_id!(WebGLQueryId, u32, NativeQuery);
685define_resource_id!(WebGLSamplerId, u32, NativeSampler);
686define_resource_id!(WebGLShaderId, u32, NativeShader);
687define_resource_id!(WebGLSyncId, u64);
688impl WebGLSyncId {
689 #[inline]
690 pub fn glow(&self) -> NativeFence {
691 NativeFence(self.0.get() as _)
692 }
693
694 #[inline]
695 pub fn from_glow(glow: NativeFence) -> Self {
696 Self::maybe_new(glow.0 as _).expect("Glow should have valid fence")
697 }
698}
699define_resource_id!(WebGLVertexArrayId, u32, NativeVertexArray);
700define_resource_id!(WebXRLayerManagerId, u32);
701
702#[derive(
703 Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, Ord, PartialEq, PartialOrd, Serialize,
704)]
705pub struct WebGLContextId(pub u64);
706
707impl From<WebXRContextId> for WebGLContextId {
708 fn from(id: WebXRContextId) -> Self {
709 Self(id.0)
710 }
711}
712
713impl From<WebGLContextId> for WebXRContextId {
714 fn from(id: WebGLContextId) -> Self {
715 Self(id.0)
716 }
717}
718
719#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
720pub enum WebGLError {
721 InvalidEnum,
722 InvalidFramebufferOperation,
723 InvalidOperation,
724 InvalidValue,
725 OutOfMemory,
726 ContextLost,
727}
728
729#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
730pub enum WebGLFramebufferBindingRequest {
731 Explicit(WebGLFramebufferId),
732 Default,
733}
734
735pub type WebGLResult<T> = Result<T, WebGLError>;
736
737#[derive(Clone, Debug, Deserialize, Serialize)]
739pub struct ProgramLinkInfo {
740 pub linked: bool,
742 pub active_attribs: Box<[ActiveAttribInfo]>,
744 pub active_uniforms: Box<[ActiveUniformInfo]>,
746 pub active_uniform_blocks: Box<[ActiveUniformBlockInfo]>,
748 pub transform_feedback_length: i32,
750 pub transform_feedback_mode: i32,
752}
753
754#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
756pub struct ActiveAttribInfo {
757 pub name: String,
759 pub size: i32,
761 pub type_: u32,
763 pub location: Option<u32>,
765}
766
767#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
769pub struct ActiveUniformInfo {
770 pub base_name: Box<str>,
772 pub size: Option<i32>,
774 pub type_: u32,
776 pub bind_index: Option<u32>,
778}
779
780impl ActiveUniformInfo {
781 pub fn name(&self) -> Cow<'_, str> {
782 if self.size.is_some() {
783 let mut name = String::from(&*self.base_name);
784 name.push_str("[0]");
785 Cow::Owned(name)
786 } else {
787 Cow::Borrowed(&self.base_name)
788 }
789 }
790}
791
792#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
794pub struct ActiveUniformBlockInfo {
795 pub name: String,
797 pub size: i32,
799}
800
801macro_rules! parameters {
802 ($name:ident { $(
803 $variant:ident($kind:ident { $(
804 $param:ident = gl::$value:ident,
805 )+ }),
806 )+ }) => {
807 #[derive(Clone, Copy, Debug, Deserialize, Serialize)]
808 pub enum $name { $(
809 $variant($kind),
810 )+}
811
812 $(
813 #[derive(Clone, Copy, Debug, Deserialize, Serialize)]
814 #[repr(u32)]
815 pub enum $kind { $(
816 $param = gl::$value,
817 )+}
818 )+
819
820 impl $name {
821 pub fn from_u32(value: u32) -> WebGLResult<Self> {
822 match value {
823 $($(gl::$value => Ok($name::$variant($kind::$param)),)+)+
824 _ => Err(WebGLError::InvalidEnum)
825 }
826 }
827 }
828 }
829}
830
831parameters! {
832 Parameter {
833 Bool(ParameterBool {
834 DepthWritemask = gl::DEPTH_WRITEMASK,
835 SampleCoverageInvert = gl::SAMPLE_COVERAGE_INVERT,
836 TransformFeedbackActive = gl::TRANSFORM_FEEDBACK_ACTIVE,
837 TransformFeedbackPaused = gl::TRANSFORM_FEEDBACK_PAUSED,
838 RasterizerDiscard = gl::RASTERIZER_DISCARD,
839 }),
840 Bool4(ParameterBool4 {
841 ColorWritemask = gl::COLOR_WRITEMASK,
842 }),
843 Int(ParameterInt {
844 ActiveTexture = gl::ACTIVE_TEXTURE,
845 AlphaBits = gl::ALPHA_BITS,
846 BlendDstAlpha = gl::BLEND_DST_ALPHA,
847 BlendDstRgb = gl::BLEND_DST_RGB,
848 BlendEquationAlpha = gl::BLEND_EQUATION_ALPHA,
849 BlendEquationRgb = gl::BLEND_EQUATION_RGB,
850 BlendSrcAlpha = gl::BLEND_SRC_ALPHA,
851 BlendSrcRgb = gl::BLEND_SRC_RGB,
852 BlueBits = gl::BLUE_BITS,
853 CullFaceMode = gl::CULL_FACE_MODE,
854 DepthBits = gl::DEPTH_BITS,
855 DepthFunc = gl::DEPTH_FUNC,
856 FragmentShaderDerivativeHint = gl::FRAGMENT_SHADER_DERIVATIVE_HINT,
857 FrontFace = gl::FRONT_FACE,
858 GenerateMipmapHint = gl::GENERATE_MIPMAP_HINT,
859 GreenBits = gl::GREEN_BITS,
860 RedBits = gl::RED_BITS,
861 SampleBuffers = gl::SAMPLE_BUFFERS,
862 Samples = gl::SAMPLES,
863 StencilBackFail = gl::STENCIL_BACK_FAIL,
864 StencilBackFunc = gl::STENCIL_BACK_FUNC,
865 StencilBackPassDepthFail = gl::STENCIL_BACK_PASS_DEPTH_FAIL,
866 StencilBackPassDepthPass = gl::STENCIL_BACK_PASS_DEPTH_PASS,
867 StencilBackRef = gl::STENCIL_BACK_REF,
868 StencilBackValueMask = gl::STENCIL_BACK_VALUE_MASK,
869 StencilBackWritemask = gl::STENCIL_BACK_WRITEMASK,
870 StencilBits = gl::STENCIL_BITS,
871 StencilClearValue = gl::STENCIL_CLEAR_VALUE,
872 StencilFail = gl::STENCIL_FAIL,
873 StencilFunc = gl::STENCIL_FUNC,
874 StencilPassDepthFail = gl::STENCIL_PASS_DEPTH_FAIL,
875 StencilPassDepthPass = gl::STENCIL_PASS_DEPTH_PASS,
876 StencilRef = gl::STENCIL_REF,
877 StencilValueMask = gl::STENCIL_VALUE_MASK,
878 StencilWritemask = gl::STENCIL_WRITEMASK,
879 SubpixelBits = gl::SUBPIXEL_BITS,
880 TransformFeedbackBinding = gl::TRANSFORM_FEEDBACK_BINDING,
881 MaxTransformFeedbackInterleavedComponents = gl::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS,
882 MaxTransformFeedbackSeparateAttribs = gl::MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS,
883 MaxTransformFeedbackSeparateComponents = gl::MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS,
884 TransformFeedbackBufferSize = gl::TRANSFORM_FEEDBACK_BUFFER_SIZE,
885 TransformFeedbackBufferStart = gl::TRANSFORM_FEEDBACK_BUFFER_START,
886 PackRowLength = gl::PACK_ROW_LENGTH,
887 PackSkipPixels = gl::PACK_SKIP_PIXELS,
888 PackSkipRows = gl::PACK_SKIP_ROWS,
889 UnpackImageHeight = gl::UNPACK_IMAGE_HEIGHT,
890 UnpackRowLength = gl::UNPACK_ROW_LENGTH,
891 UnpackSkipImages = gl::UNPACK_SKIP_IMAGES,
892 UnpackSkipPixels = gl::UNPACK_SKIP_PIXELS,
893 UnpackSkipRows = gl::UNPACK_SKIP_ROWS,
894 }),
895 Int2(ParameterInt2 {
896 MaxViewportDims = gl::MAX_VIEWPORT_DIMS,
897 }),
898 Int4(ParameterInt4 {
899 ScissorBox = gl::SCISSOR_BOX,
900 Viewport = gl::VIEWPORT,
901 }),
902 Float(ParameterFloat {
903 DepthClearValue = gl::DEPTH_CLEAR_VALUE,
904 LineWidth = gl::LINE_WIDTH,
905 MaxTextureMaxAnisotropyExt = gl::MAX_TEXTURE_MAX_ANISOTROPY_EXT,
906 PolygonOffsetFactor = gl::POLYGON_OFFSET_FACTOR,
907 PolygonOffsetUnits = gl::POLYGON_OFFSET_UNITS,
908 SampleCoverageValue = gl::SAMPLE_COVERAGE_VALUE,
909 }),
910 Float2(ParameterFloat2 {
911 AliasedPointSizeRange = gl::ALIASED_POINT_SIZE_RANGE,
912 AliasedLineWidthRange = gl::ALIASED_LINE_WIDTH_RANGE,
913 DepthRange = gl::DEPTH_RANGE,
914 }),
915 Float4(ParameterFloat4 {
916 BlendColor = gl::BLEND_COLOR,
917 ColorClearValue = gl::COLOR_CLEAR_VALUE,
918 }),
919 }
920}
921
922parameters! {
923 TexParameter {
924 Float(TexParameterFloat {
925 TextureMaxAnisotropyExt = gl::TEXTURE_MAX_ANISOTROPY_EXT,
926 TextureMaxLod = gl::TEXTURE_MAX_LOD,
927 TextureMinLod = gl::TEXTURE_MIN_LOD,
928 }),
929 Int(TexParameterInt {
930 TextureWrapS = gl::TEXTURE_WRAP_S,
931 TextureWrapT = gl::TEXTURE_WRAP_T,
932 TextureWrapR = gl::TEXTURE_WRAP_R,
933 TextureBaseLevel = gl::TEXTURE_BASE_LEVEL,
934 TextureMinFilter = gl::TEXTURE_MIN_FILTER,
935 TextureMagFilter = gl::TEXTURE_MAG_FILTER,
936 TextureMaxLevel = gl::TEXTURE_MAX_LEVEL,
937 TextureCompareFunc = gl::TEXTURE_COMPARE_FUNC,
938 TextureCompareMode = gl::TEXTURE_COMPARE_MODE,
939 TextureImmutableLevels = gl::TEXTURE_IMMUTABLE_LEVELS,
940 }),
941 Bool(TexParameterBool {
942 TextureImmutableFormat = gl::TEXTURE_IMMUTABLE_FORMAT,
943 }),
944 }
945}
946
947impl TexParameter {
948 pub fn required_webgl_version(self) -> WebGLVersion {
949 match self {
950 Self::Float(TexParameterFloat::TextureMaxAnisotropyExt) |
951 Self::Int(TexParameterInt::TextureWrapS) |
952 Self::Int(TexParameterInt::TextureWrapT) => WebGLVersion::WebGL1,
953 _ => WebGLVersion::WebGL2,
954 }
955 }
956}
957
958parameters! {
959 InternalFormatParameter {
960 IntVec(InternalFormatIntVec {
961 Samples = gl::SAMPLES,
962 }),
963 }
964}
965
966#[macro_export]
967macro_rules! gl_enums {
968 ($(pub enum $name:ident { $($variant:ident = $mod:ident::$constant:ident,)+ })*) => {
969 $(
970 #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, malloc_size_of_derive::MallocSizeOf)]
971 #[derive(PartialEq, Serialize)]
972 #[repr(u32)]
973 pub enum $name { $($variant = $mod::$constant,)+ }
974
975 impl $name {
976 pub fn from_gl_constant(constant: u32) -> Option<Self> {
977 Some(match constant {
978 $($mod::$constant => $name::$variant, )+
979 _ => return None,
980 })
981 }
982
983 #[inline]
984 pub fn as_gl_constant(&self) -> u32 {
985 *self as u32
986 }
987 }
988 )*
989 }
990}
991
992mod gl_ext_constants {
994 pub const COMPRESSED_RGB_ETC1_WEBGL: u32 = 0x8D64;
995
996 pub const ALPHA16F_ARB: u32 = 0x881C;
997 pub const ALPHA32F_ARB: u32 = 0x8816;
998 pub const LUMINANCE16F_ARB: u32 = 0x881E;
999 pub const LUMINANCE32F_ARB: u32 = 0x8818;
1000 pub const LUMINANCE_ALPHA16F_ARB: u32 = 0x881F;
1001 pub const LUMINANCE_ALPHA32F_ARB: u32 = 0x8819;
1002}
1003
1004gl_enums! {
1005 pub enum TexFormat {
1006 DepthComponent = gl::DEPTH_COMPONENT,
1007 DepthStencil = gl::DEPTH_STENCIL,
1008 Alpha = gl::ALPHA,
1009 Alpha32f = gl_ext_constants::ALPHA32F_ARB,
1010 Alpha16f = gl_ext_constants::ALPHA16F_ARB,
1011 Red = gl::RED,
1012 RedInteger = gl::RED_INTEGER,
1013 RG = gl::RG,
1014 RGInteger = gl::RG_INTEGER,
1015 RGB = gl::RGB,
1016 RGBInteger = gl::RGB_INTEGER,
1017 RGBA = gl::RGBA,
1018 RGBAInteger = gl::RGBA_INTEGER,
1019 Luminance = gl::LUMINANCE,
1020 LuminanceAlpha = gl::LUMINANCE_ALPHA,
1021 Luminance32f = gl_ext_constants::LUMINANCE32F_ARB,
1022 Luminance16f = gl_ext_constants::LUMINANCE16F_ARB,
1023 LuminanceAlpha32f = gl_ext_constants::LUMINANCE_ALPHA32F_ARB,
1024 LuminanceAlpha16f = gl_ext_constants::LUMINANCE_ALPHA16F_ARB,
1025 CompressedRgbS3tcDxt1 = gl::COMPRESSED_RGB_S3TC_DXT1_EXT,
1026 CompressedRgbaS3tcDxt1 = gl::COMPRESSED_RGBA_S3TC_DXT1_EXT,
1027 CompressedRgbaS3tcDxt3 = gl::COMPRESSED_RGBA_S3TC_DXT3_EXT,
1028 CompressedRgbaS3tcDxt5 = gl::COMPRESSED_RGBA_S3TC_DXT5_EXT,
1029 CompressedRgbEtc1 = gl_ext_constants::COMPRESSED_RGB_ETC1_WEBGL,
1030 R8 = gl::R8,
1031 R8SNorm = gl::R8_SNORM,
1032 R16f = gl::R16F,
1033 R32f = gl::R32F,
1034 R8ui = gl::R8UI,
1035 R8i = gl::R8I,
1036 R16ui = gl::R16UI,
1037 R16i = gl::R16I,
1038 R32ui = gl::R32UI,
1039 R32i = gl::R32I,
1040 RG8 = gl::RG8,
1041 RG8SNorm = gl::RG8_SNORM,
1042 RG16f = gl::RG16F,
1043 RG32f = gl::RG32F,
1044 RG8ui = gl::RG8UI,
1045 RG8i = gl::RG8I,
1046 RG16ui = gl::RG16UI,
1047 RG16i = gl::RG16I,
1048 RG32ui = gl::RG32UI,
1049 RG32i = gl::RG32I,
1050 RGB8 = gl::RGB8,
1051 SRGB8 = gl::SRGB8,
1052 RGB565 = gl::RGB565,
1053 RGB8SNorm = gl::RGB8_SNORM,
1054 R11fG11fB10f = gl::R11F_G11F_B10F,
1055 RGB9E5 = gl::RGB9_E5,
1056 RGB16f = gl::RGB16F,
1057 RGB32f = gl::RGB32F,
1058 RGB8ui = gl::RGB8UI,
1059 RGB8i = gl::RGB8I,
1060 RGB16ui = gl::RGB16UI,
1061 RGB16i = gl::RGB16I,
1062 RGB32ui = gl::RGB32UI,
1063 RGB32i = gl::RGB32I,
1064 RGBA8 = gl::RGBA8,
1065 SRGB8Alpha8 = gl::SRGB8_ALPHA8,
1066 RGBA8SNorm = gl::RGBA8_SNORM,
1067 RGB5A1 = gl::RGB5_A1,
1068 RGBA4 = gl::RGBA4,
1069 RGB10A2 = gl::RGB10_A2,
1070 RGBA16f = gl::RGBA16F,
1071 RGBA32f = gl::RGBA32F,
1072 RGBA8ui = gl::RGBA8UI,
1073 RGBA8i = gl::RGBA8I,
1074 RGB10A2ui = gl::RGB10_A2UI,
1075 RGBA16ui = gl::RGBA16UI,
1076 RGBA16i = gl::RGBA16I,
1077 RGBA32i = gl::RGBA32I,
1078 RGBA32ui = gl::RGBA32UI,
1079 DepthComponent16 = gl::DEPTH_COMPONENT16,
1080 DepthComponent24 = gl::DEPTH_COMPONENT24,
1081 DepthComponent32f = gl::DEPTH_COMPONENT32F,
1082 Depth24Stencil8 = gl::DEPTH24_STENCIL8,
1083 Depth32fStencil8 = gl::DEPTH32F_STENCIL8,
1084 }
1085
1086 pub enum TexDataType {
1087 Byte = gl::BYTE,
1088 Int = gl::INT,
1089 Short = gl::SHORT,
1090 UnsignedByte = gl::UNSIGNED_BYTE,
1091 UnsignedInt = gl::UNSIGNED_INT,
1092 UnsignedInt10f11f11fRev = gl::UNSIGNED_INT_10F_11F_11F_REV,
1093 UnsignedInt2101010Rev = gl::UNSIGNED_INT_2_10_10_10_REV,
1094 UnsignedInt5999Rev = gl::UNSIGNED_INT_5_9_9_9_REV,
1095 UnsignedInt248 = gl::UNSIGNED_INT_24_8,
1096 UnsignedShort = gl::UNSIGNED_SHORT,
1097 UnsignedShort4444 = gl::UNSIGNED_SHORT_4_4_4_4,
1098 UnsignedShort5551 = gl::UNSIGNED_SHORT_5_5_5_1,
1099 UnsignedShort565 = gl::UNSIGNED_SHORT_5_6_5,
1100 Float = gl::FLOAT,
1101 HalfFloat = gl::HALF_FLOAT_OES,
1102 Float32UnsignedInt248Rev = gl::FLOAT_32_UNSIGNED_INT_24_8_REV,
1103 }
1104}
1105
1106impl TexFormat {
1107 pub fn components(&self) -> u32 {
1110 match self.to_unsized() {
1111 TexFormat::DepthStencil => 2,
1112 TexFormat::LuminanceAlpha => 2,
1113 TexFormat::RG | TexFormat::RGInteger => 2,
1114 TexFormat::RGB | TexFormat::RGBInteger => 3,
1115 TexFormat::RGBA | TexFormat::RGBAInteger => 4,
1116 _ => 1,
1117 }
1118 }
1119
1120 pub fn is_compressed(&self) -> bool {
1122 let gl_const = self.as_gl_constant();
1123 matches!(
1124 gl_const,
1125 gl::COMPRESSED_RGB_S3TC_DXT1_EXT |
1126 gl::COMPRESSED_RGBA_S3TC_DXT1_EXT |
1127 gl::COMPRESSED_RGBA_S3TC_DXT3_EXT |
1128 gl::COMPRESSED_RGBA_S3TC_DXT5_EXT |
1129 gl_ext_constants::COMPRESSED_RGB_ETC1_WEBGL
1130 )
1131 }
1132
1133 pub fn is_sized(&self) -> bool {
1135 !matches!(
1136 self,
1137 TexFormat::DepthComponent |
1138 TexFormat::DepthStencil |
1139 TexFormat::Alpha |
1140 TexFormat::Red |
1141 TexFormat::RG |
1142 TexFormat::RGB |
1143 TexFormat::RGBA |
1144 TexFormat::Luminance |
1145 TexFormat::LuminanceAlpha
1146 )
1147 }
1148
1149 pub fn to_unsized(self) -> TexFormat {
1150 match self {
1151 TexFormat::R8 => TexFormat::Red,
1152 TexFormat::R8SNorm => TexFormat::Red,
1153 TexFormat::R16f => TexFormat::Red,
1154 TexFormat::R32f => TexFormat::Red,
1155 TexFormat::R8ui => TexFormat::RedInteger,
1156 TexFormat::R8i => TexFormat::RedInteger,
1157 TexFormat::R16ui => TexFormat::RedInteger,
1158 TexFormat::R16i => TexFormat::RedInteger,
1159 TexFormat::R32ui => TexFormat::RedInteger,
1160 TexFormat::R32i => TexFormat::RedInteger,
1161 TexFormat::RG8 => TexFormat::RG,
1162 TexFormat::RG8SNorm => TexFormat::RG,
1163 TexFormat::RG16f => TexFormat::RG,
1164 TexFormat::RG32f => TexFormat::RG,
1165 TexFormat::RG8ui => TexFormat::RGInteger,
1166 TexFormat::RG8i => TexFormat::RGInteger,
1167 TexFormat::RG16ui => TexFormat::RGInteger,
1168 TexFormat::RG16i => TexFormat::RGInteger,
1169 TexFormat::RG32ui => TexFormat::RGInteger,
1170 TexFormat::RG32i => TexFormat::RGInteger,
1171 TexFormat::RGB8 => TexFormat::RGB,
1172 TexFormat::SRGB8 => TexFormat::RGB,
1173 TexFormat::RGB565 => TexFormat::RGB,
1174 TexFormat::RGB8SNorm => TexFormat::RGB,
1175 TexFormat::R11fG11fB10f => TexFormat::RGB,
1176 TexFormat::RGB9E5 => TexFormat::RGB,
1177 TexFormat::RGB16f => TexFormat::RGB,
1178 TexFormat::RGB32f => TexFormat::RGB,
1179 TexFormat::RGB8ui => TexFormat::RGBInteger,
1180 TexFormat::RGB8i => TexFormat::RGBInteger,
1181 TexFormat::RGB16ui => TexFormat::RGBInteger,
1182 TexFormat::RGB16i => TexFormat::RGBInteger,
1183 TexFormat::RGB32ui => TexFormat::RGBInteger,
1184 TexFormat::RGB32i => TexFormat::RGBInteger,
1185 TexFormat::RGBA8 => TexFormat::RGBA,
1186 TexFormat::SRGB8Alpha8 => TexFormat::RGBA,
1187 TexFormat::RGBA8SNorm => TexFormat::RGBA,
1188 TexFormat::RGB5A1 => TexFormat::RGBA,
1189 TexFormat::RGBA4 => TexFormat::RGBA,
1190 TexFormat::RGB10A2 => TexFormat::RGBA,
1191 TexFormat::RGBA16f => TexFormat::RGBA,
1192 TexFormat::RGBA32f => TexFormat::RGBA,
1193 TexFormat::RGBA8ui => TexFormat::RGBAInteger,
1194 TexFormat::RGBA8i => TexFormat::RGBAInteger,
1195 TexFormat::RGB10A2ui => TexFormat::RGBAInteger,
1196 TexFormat::RGBA16ui => TexFormat::RGBAInteger,
1197 TexFormat::RGBA16i => TexFormat::RGBAInteger,
1198 TexFormat::RGBA32i => TexFormat::RGBAInteger,
1199 TexFormat::RGBA32ui => TexFormat::RGBAInteger,
1200 TexFormat::DepthComponent16 => TexFormat::DepthComponent,
1201 TexFormat::DepthComponent24 => TexFormat::DepthComponent,
1202 TexFormat::DepthComponent32f => TexFormat::DepthComponent,
1203 TexFormat::Depth24Stencil8 => TexFormat::DepthStencil,
1204 TexFormat::Depth32fStencil8 => TexFormat::DepthStencil,
1205 TexFormat::Alpha32f => TexFormat::Alpha,
1206 TexFormat::Alpha16f => TexFormat::Alpha,
1207 TexFormat::Luminance32f => TexFormat::Luminance,
1208 TexFormat::Luminance16f => TexFormat::Luminance,
1209 TexFormat::LuminanceAlpha32f => TexFormat::LuminanceAlpha,
1210 TexFormat::LuminanceAlpha16f => TexFormat::LuminanceAlpha,
1211 _ => self,
1212 }
1213 }
1214
1215 pub fn compatible_data_types(self) -> &'static [TexDataType] {
1216 match self {
1217 TexFormat::RGB => &[
1218 TexDataType::UnsignedByte,
1219 TexDataType::UnsignedShort565,
1220 TexDataType::Float,
1221 TexDataType::HalfFloat,
1222 ][..],
1223 TexFormat::RGBA => &[
1224 TexDataType::UnsignedByte,
1225 TexDataType::UnsignedShort4444,
1226 TexDataType::UnsignedShort5551,
1227 TexDataType::Float,
1228 TexDataType::HalfFloat,
1229 ][..],
1230 TexFormat::LuminanceAlpha => &[
1231 TexDataType::UnsignedByte,
1232 TexDataType::Float,
1233 TexDataType::HalfFloat,
1234 ][..],
1235 TexFormat::Luminance => &[
1236 TexDataType::UnsignedByte,
1237 TexDataType::Float,
1238 TexDataType::HalfFloat,
1239 ][..],
1240 TexFormat::Alpha => &[
1241 TexDataType::UnsignedByte,
1242 TexDataType::Float,
1243 TexDataType::HalfFloat,
1244 ][..],
1245 TexFormat::LuminanceAlpha32f => &[TexDataType::Float][..],
1246 TexFormat::LuminanceAlpha16f => &[TexDataType::HalfFloat][..],
1247 TexFormat::Luminance32f => &[TexDataType::Float][..],
1248 TexFormat::Luminance16f => &[TexDataType::HalfFloat][..],
1249 TexFormat::Alpha32f => &[TexDataType::Float][..],
1250 TexFormat::Alpha16f => &[TexDataType::HalfFloat][..],
1251 TexFormat::R8 => &[TexDataType::UnsignedByte][..],
1252 TexFormat::R8SNorm => &[TexDataType::Byte][..],
1253 TexFormat::R16f => &[TexDataType::HalfFloat, TexDataType::Float][..],
1254 TexFormat::R32f => &[TexDataType::Float][..],
1255 TexFormat::R8ui => &[TexDataType::UnsignedByte][..],
1256 TexFormat::R8i => &[TexDataType::Byte][..],
1257 TexFormat::R16ui => &[TexDataType::UnsignedShort][..],
1258 TexFormat::R16i => &[TexDataType::Short][..],
1259 TexFormat::R32ui => &[TexDataType::UnsignedInt][..],
1260 TexFormat::R32i => &[TexDataType::Int][..],
1261 TexFormat::RG8 => &[TexDataType::UnsignedByte][..],
1262 TexFormat::RG8SNorm => &[TexDataType::Byte][..],
1263 TexFormat::RG16f => &[TexDataType::HalfFloat, TexDataType::Float][..],
1264 TexFormat::RG32f => &[TexDataType::Float][..],
1265 TexFormat::RG8ui => &[TexDataType::UnsignedByte][..],
1266 TexFormat::RG8i => &[TexDataType::Byte][..],
1267 TexFormat::RG16ui => &[TexDataType::UnsignedShort][..],
1268 TexFormat::RG16i => &[TexDataType::Short][..],
1269 TexFormat::RG32ui => &[TexDataType::UnsignedInt][..],
1270 TexFormat::RG32i => &[TexDataType::Int][..],
1271 TexFormat::RGB8 => &[TexDataType::UnsignedByte][..],
1272 TexFormat::SRGB8 => &[TexDataType::UnsignedByte][..],
1273 TexFormat::RGB565 => &[TexDataType::UnsignedByte, TexDataType::UnsignedShort565][..],
1274 TexFormat::RGB8SNorm => &[TexDataType::Byte][..],
1275 TexFormat::R11fG11fB10f => &[
1276 TexDataType::UnsignedInt10f11f11fRev,
1277 TexDataType::HalfFloat,
1278 TexDataType::Float,
1279 ][..],
1280 TexFormat::RGB9E5 => &[
1281 TexDataType::UnsignedInt5999Rev,
1282 TexDataType::HalfFloat,
1283 TexDataType::Float,
1284 ][..],
1285 TexFormat::RGB16f => &[TexDataType::HalfFloat, TexDataType::Float][..],
1286 TexFormat::RGB32f => &[TexDataType::Float][..],
1287 TexFormat::RGB8ui => &[TexDataType::UnsignedByte][..],
1288 TexFormat::RGB8i => &[TexDataType::Byte][..],
1289 TexFormat::RGB16ui => &[TexDataType::UnsignedShort][..],
1290 TexFormat::RGB16i => &[TexDataType::Short][..],
1291 TexFormat::RGB32ui => &[TexDataType::UnsignedInt][..],
1292 TexFormat::RGB32i => &[TexDataType::Int][..],
1293 TexFormat::RGBA8 => &[TexDataType::UnsignedByte][..],
1294 TexFormat::SRGB8Alpha8 => &[TexDataType::UnsignedByte][..],
1295 TexFormat::RGBA8SNorm => &[TexDataType::Byte][..],
1296 TexFormat::RGB5A1 => &[
1297 TexDataType::UnsignedByte,
1298 TexDataType::UnsignedShort5551,
1299 TexDataType::UnsignedInt2101010Rev,
1300 ][..],
1301 TexFormat::RGBA4 => &[TexDataType::UnsignedByte, TexDataType::UnsignedShort4444][..],
1302 TexFormat::RGB10A2 => &[TexDataType::UnsignedInt2101010Rev][..],
1303 TexFormat::RGBA16f => &[TexDataType::HalfFloat, TexDataType::Float][..],
1304 TexFormat::RGBA32f => &[TexDataType::Float][..],
1305 TexFormat::RGBA8ui => &[TexDataType::UnsignedByte][..],
1306 TexFormat::RGBA8i => &[TexDataType::Byte][..],
1307 TexFormat::RGB10A2ui => &[TexDataType::UnsignedInt2101010Rev][..],
1308 TexFormat::RGBA16ui => &[TexDataType::UnsignedShort][..],
1309 TexFormat::RGBA16i => &[TexDataType::Short][..],
1310 TexFormat::RGBA32i => &[TexDataType::Int][..],
1311 TexFormat::RGBA32ui => &[TexDataType::UnsignedInt][..],
1312 TexFormat::DepthComponent16 => {
1313 &[TexDataType::UnsignedShort, TexDataType::UnsignedInt][..]
1314 },
1315 TexFormat::DepthComponent24 => &[TexDataType::UnsignedInt][..],
1316 TexFormat::DepthComponent32f => &[TexDataType::Float][..],
1317 TexFormat::Depth24Stencil8 => &[TexDataType::UnsignedInt248][..],
1318 TexFormat::Depth32fStencil8 => &[TexDataType::Float32UnsignedInt248Rev][..],
1319 TexFormat::CompressedRgbS3tcDxt1 |
1320 TexFormat::CompressedRgbaS3tcDxt1 |
1321 TexFormat::CompressedRgbaS3tcDxt3 |
1322 TexFormat::CompressedRgbaS3tcDxt5 => &[TexDataType::UnsignedByte][..],
1323 _ => &[][..],
1324 }
1325 }
1326
1327 pub fn required_webgl_version(self) -> WebGLVersion {
1328 match self {
1329 TexFormat::DepthComponent |
1330 TexFormat::Alpha |
1331 TexFormat::RGB |
1332 TexFormat::RGBA |
1333 TexFormat::Luminance |
1334 TexFormat::LuminanceAlpha |
1335 TexFormat::CompressedRgbS3tcDxt1 |
1336 TexFormat::CompressedRgbaS3tcDxt1 |
1337 TexFormat::CompressedRgbaS3tcDxt3 |
1338 TexFormat::CompressedRgbaS3tcDxt5 => WebGLVersion::WebGL1,
1339 _ => WebGLVersion::WebGL2,
1340 }
1341 }
1342
1343 pub fn usable_as_internal(self) -> bool {
1344 !self.compatible_data_types().is_empty()
1345 }
1346}
1347
1348#[derive(PartialEq)]
1349pub enum SizedDataType {
1350 Int8,
1351 Int16,
1352 Int32,
1353 Uint8,
1354 Uint16,
1355 Uint32,
1356 Float32,
1357}
1358
1359impl TexDataType {
1360 pub fn sized_data_type(&self) -> SizedDataType {
1362 match self {
1363 TexDataType::Byte => SizedDataType::Int8,
1364 TexDataType::UnsignedByte => SizedDataType::Uint8,
1365 TexDataType::Short => SizedDataType::Int16,
1366 TexDataType::UnsignedShort |
1367 TexDataType::UnsignedShort4444 |
1368 TexDataType::UnsignedShort5551 |
1369 TexDataType::UnsignedShort565 => SizedDataType::Uint16,
1370 TexDataType::Int => SizedDataType::Int32,
1371 TexDataType::UnsignedInt |
1372 TexDataType::UnsignedInt10f11f11fRev |
1373 TexDataType::UnsignedInt2101010Rev |
1374 TexDataType::UnsignedInt5999Rev |
1375 TexDataType::UnsignedInt248 => SizedDataType::Uint32,
1376 TexDataType::HalfFloat => SizedDataType::Uint16,
1377 TexDataType::Float | TexDataType::Float32UnsignedInt248Rev => SizedDataType::Float32,
1378 }
1379 }
1380
1381 pub fn element_size(&self) -> u32 {
1383 use self::*;
1384 match *self {
1385 TexDataType::Byte | TexDataType::UnsignedByte => 1,
1386 TexDataType::Short |
1387 TexDataType::UnsignedShort |
1388 TexDataType::UnsignedShort4444 |
1389 TexDataType::UnsignedShort5551 |
1390 TexDataType::UnsignedShort565 => 2,
1391 TexDataType::Int |
1392 TexDataType::UnsignedInt |
1393 TexDataType::UnsignedInt10f11f11fRev |
1394 TexDataType::UnsignedInt2101010Rev |
1395 TexDataType::UnsignedInt5999Rev => 4,
1396 TexDataType::UnsignedInt248 => 4,
1397 TexDataType::Float => 4,
1398 TexDataType::HalfFloat => 2,
1399 TexDataType::Float32UnsignedInt248Rev => 4,
1400 }
1401 }
1402
1403 pub fn components_per_element(&self) -> u32 {
1406 match *self {
1407 TexDataType::Byte => 1,
1408 TexDataType::UnsignedByte => 1,
1409 TexDataType::Short => 1,
1410 TexDataType::UnsignedShort => 1,
1411 TexDataType::UnsignedShort565 => 3,
1412 TexDataType::UnsignedShort5551 => 4,
1413 TexDataType::UnsignedShort4444 => 4,
1414 TexDataType::Int => 1,
1415 TexDataType::UnsignedInt => 1,
1416 TexDataType::UnsignedInt10f11f11fRev => 3,
1417 TexDataType::UnsignedInt2101010Rev => 4,
1418 TexDataType::UnsignedInt5999Rev => 4,
1419 TexDataType::UnsignedInt248 => 2,
1420 TexDataType::Float => 1,
1421 TexDataType::HalfFloat => 1,
1422 TexDataType::Float32UnsignedInt248Rev => 2,
1423 }
1424 }
1425
1426 pub fn required_webgl_version(self) -> WebGLVersion {
1427 match self {
1428 TexDataType::UnsignedByte |
1429 TexDataType::UnsignedShort4444 |
1430 TexDataType::UnsignedShort5551 |
1431 TexDataType::UnsignedShort565 |
1432 TexDataType::Float |
1433 TexDataType::HalfFloat => WebGLVersion::WebGL1,
1434 _ => WebGLVersion::WebGL2,
1435 }
1436 }
1437}
1438
1439#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
1440pub enum AlphaTreatment {
1441 Premultiply,
1442 Unmultiply,
1443}
1444
1445#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
1446pub enum YAxisTreatment {
1447 AsIs,
1448 Flipped,
1449}
1450
1451#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
1452pub struct GLContextAttributes {
1453 pub alpha: bool,
1454 pub depth: bool,
1455 pub stencil: bool,
1456 pub antialias: bool,
1457 pub premultiplied_alpha: bool,
1458 pub preserve_drawing_buffer: bool,
1459}
1460
1461#[derive(Clone, Debug, Deserialize, Serialize)]
1462pub struct GLLimits {
1463 pub max_vertex_attribs: u32,
1464 pub max_tex_size: u32,
1465 pub max_3d_tex_size: u32,
1466 pub max_cube_map_tex_size: u32,
1467 pub max_combined_texture_image_units: u32,
1468 pub max_fragment_uniform_vectors: u32,
1469 pub max_renderbuffer_size: u32,
1470 pub max_texture_image_units: u32,
1471 pub max_varying_vectors: u32,
1472 pub max_vertex_texture_image_units: u32,
1473 pub max_vertex_uniform_vectors: u32,
1474 pub max_client_wait_timeout_webgl: std::time::Duration,
1475 pub max_transform_feedback_separate_attribs: u32,
1476 pub max_vertex_output_vectors: u32,
1477 pub max_fragment_input_vectors: u32,
1478 pub max_draw_buffers: u32,
1479 pub max_color_attachments: u32,
1480 pub max_uniform_buffer_bindings: u32,
1481 pub min_program_texel_offset: i32,
1482 pub max_program_texel_offset: u32,
1483 pub max_uniform_block_size: u64,
1484 pub max_combined_uniform_blocks: u32,
1485 pub max_combined_vertex_uniform_components: u64,
1486 pub max_combined_fragment_uniform_components: u64,
1487 pub max_vertex_uniform_blocks: u32,
1488 pub max_vertex_uniform_components: u32,
1489 pub max_fragment_uniform_blocks: u32,
1490 pub max_fragment_uniform_components: u32,
1491 pub max_3d_texture_size: u32,
1492 pub max_array_texture_layers: u32,
1493 pub uniform_buffer_offset_alignment: u32,
1494 pub max_element_index: u64,
1495 pub max_elements_indices: u32,
1496 pub max_elements_vertices: u32,
1497 pub max_fragment_input_components: u32,
1498 pub max_samples: u32,
1499 pub max_server_wait_timeout: std::time::Duration,
1500 pub max_texture_lod_bias: f32,
1501 pub max_varying_components: u32,
1502 pub max_vertex_output_components: u32,
1503}