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