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<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 VertexAttribPointer2f(u32, i32, bool, i32, u32),
408 SetViewport(i32, i32, i32, i32),
409 TexImage3D {
410 target: u32,
411 level: u32,
412 internal_format: TexFormat,
413 size: Size2D<u32>,
414 depth: u32,
415 format: TexFormat,
416 data_type: TexDataType,
417 effective_data_type: u32,
419 unpacking_alignment: u32,
420 alpha_treatment: Option<AlphaTreatment>,
421 y_axis_treatment: YAxisTreatment,
422 pixel_format: Option<PixelFormat>,
423 data: TruncatedDebug<GenericSharedMemory>,
424 },
425 TexImage2D {
426 target: u32,
427 level: u32,
428 internal_format: TexFormat,
429 size: Size2D<u32>,
430 format: TexFormat,
431 data_type: TexDataType,
432 effective_data_type: u32,
434 unpacking_alignment: u32,
435 alpha_treatment: Option<AlphaTreatment>,
436 y_axis_treatment: YAxisTreatment,
437 pixel_format: Option<PixelFormat>,
438 data: TruncatedDebug<GenericSharedMemory>,
439 },
440 TexImage2DPBO {
441 target: u32,
442 level: u32,
443 internal_format: TexFormat,
444 size: Size2D<u32>,
445 format: TexFormat,
446 effective_data_type: u32,
447 unpacking_alignment: u32,
448 offset: i64,
449 },
450 TexSubImage2D {
451 target: u32,
452 level: u32,
453 xoffset: i32,
454 yoffset: i32,
455 size: Size2D<u32>,
456 format: TexFormat,
457 data_type: TexDataType,
458 effective_data_type: u32,
460 unpacking_alignment: u32,
461 alpha_treatment: Option<AlphaTreatment>,
462 y_axis_treatment: YAxisTreatment,
463 pixel_format: Option<PixelFormat>,
464 data: TruncatedDebug<GenericSharedMemory>,
465 },
466 CompressedTexImage2D {
467 target: u32,
468 level: u32,
469 internal_format: u32,
470 size: Size2D<u32>,
471 data: TruncatedDebug<GenericSharedMemory>,
472 },
473 CompressedTexSubImage2D {
474 target: u32,
475 level: i32,
476 xoffset: i32,
477 yoffset: i32,
478 size: Size2D<u32>,
479 format: u32,
480 data: TruncatedDebug<GenericSharedMemory>,
481 },
482 DrawingBufferWidth(GenericSender<i32>),
483 DrawingBufferHeight(GenericSender<i32>),
484 Finish(GenericSender<()>),
485 Flush,
486 GenerateMipmap(u32),
487 CreateVertexArray(GenericSender<Option<WebGLVertexArrayId>>),
488 DeleteVertexArray(WebGLVertexArrayId),
489 BindVertexArray(Option<WebGLVertexArrayId>),
490 GetParameterBool(ParameterBool, GenericSender<bool>),
491 GetParameterBool4(ParameterBool4, GenericSender<[bool; 4]>),
492 GetParameterInt(ParameterInt, GenericSender<i32>),
493 GetParameterUInt(ParameterUInt, GenericSender<u32>),
494 GetParameterInt2(ParameterInt2, GenericSender<[i32; 2]>),
495 GetParameterInt4(ParameterInt4, GenericSender<[i32; 4]>),
496 GetParameterFloat(ParameterFloat, GenericSender<f32>),
497 GetParameterFloat2(ParameterFloat2, GenericSender<[f32; 2]>),
498 GetParameterFloat4(ParameterFloat4, GenericSender<[f32; 4]>),
499 GetProgramValidateStatus(WebGLProgramId, GenericSender<bool>),
500 GetProgramActiveUniforms(WebGLProgramId, GenericSender<i32>),
501 GetCurrentVertexAttrib(u32, GenericSender<[f32; 4]>),
502 GetTexParameterFloat(u32, TexParameterFloat, GenericSender<f32>),
503 GetTexParameterInt(u32, TexParameterInt, GenericSender<i32>),
504 GetTexParameterBool(u32, TexParameterBool, GenericSender<bool>),
505 GetInternalFormatIntVec(u32, u32, InternalFormatIntVec, GenericSender<Vec<i32>>),
506 TexParameteri(u32, u32, i32),
507 TexParameterf(u32, u32, f32),
508 TexStorage2D(u32, u32, TexFormat, u32, u32),
509 TexStorage3D(u32, u32, TexFormat, u32, u32, u32),
510 DrawArrays {
511 mode: u32,
512 first: i32,
513 count: i32,
514 },
515 DrawArraysInstanced {
516 mode: u32,
517 first: i32,
518 count: i32,
519 primcount: i32,
520 },
521 DrawElements {
522 mode: u32,
523 count: i32,
524 type_: u32,
525 offset: u32,
526 },
527 DrawElementsInstanced {
528 mode: u32,
529 count: i32,
530 type_: u32,
531 offset: u32,
532 primcount: i32,
533 },
534 VertexAttribDivisor {
535 index: u32,
536 divisor: u32,
537 },
538 GetUniformBool(WebGLProgramId, i32, GenericSender<bool>),
539 GetUniformBool2(WebGLProgramId, i32, GenericSender<[bool; 2]>),
540 GetUniformBool3(WebGLProgramId, i32, GenericSender<[bool; 3]>),
541 GetUniformBool4(WebGLProgramId, i32, GenericSender<[bool; 4]>),
542 GetUniformInt(WebGLProgramId, i32, GenericSender<i32>),
543 GetUniformInt2(WebGLProgramId, i32, GenericSender<[i32; 2]>),
544 GetUniformInt3(WebGLProgramId, i32, GenericSender<[i32; 3]>),
545 GetUniformInt4(WebGLProgramId, i32, GenericSender<[i32; 4]>),
546 GetUniformUint(WebGLProgramId, i32, GenericSender<u32>),
547 GetUniformUint2(WebGLProgramId, i32, GenericSender<[u32; 2]>),
548 GetUniformUint3(WebGLProgramId, i32, GenericSender<[u32; 3]>),
549 GetUniformUint4(WebGLProgramId, i32, GenericSender<[u32; 4]>),
550 GetUniformFloat(WebGLProgramId, i32, GenericSender<f32>),
551 GetUniformFloat2(WebGLProgramId, i32, GenericSender<[f32; 2]>),
552 GetUniformFloat3(WebGLProgramId, i32, GenericSender<[f32; 3]>),
553 GetUniformFloat4(WebGLProgramId, i32, GenericSender<[f32; 4]>),
554 GetUniformFloat9(WebGLProgramId, i32, GenericSender<[f32; 9]>),
555 GetUniformFloat16(WebGLProgramId, i32, GenericSender<[f32; 16]>),
556 GetUniformFloat2x3(WebGLProgramId, i32, GenericSender<[f32; 2 * 3]>),
557 GetUniformFloat2x4(WebGLProgramId, i32, GenericSender<[f32; 2 * 4]>),
558 GetUniformFloat3x2(WebGLProgramId, i32, GenericSender<[f32; 3 * 2]>),
559 GetUniformFloat3x4(WebGLProgramId, i32, GenericSender<[f32; 3 * 4]>),
560 GetUniformFloat4x2(WebGLProgramId, i32, GenericSender<[f32; 4 * 2]>),
561 GetUniformFloat4x3(WebGLProgramId, i32, GenericSender<[f32; 4 * 3]>),
562 GetUniformBlockIndex(WebGLProgramId, String, GenericSender<u32>),
563 GetUniformIndices(WebGLProgramId, Vec<String>, GenericSender<Vec<u32>>),
564 GetActiveUniforms(WebGLProgramId, Vec<u32>, u32, GenericSender<Vec<i32>>),
565 GetActiveUniformBlockName(WebGLProgramId, u32, GenericSender<String>),
566 GetActiveUniformBlockParameter(WebGLProgramId, u32, u32, GenericSender<Vec<i32>>),
567 UniformBlockBinding(WebGLProgramId, u32, u32),
568 InitializeFramebuffer {
569 color: bool,
570 depth: bool,
571 stencil: bool,
572 },
573 BeginQuery(u32, WebGLQueryId),
574 DeleteQuery(WebGLQueryId),
575 EndQuery(u32),
576 GenerateQuery(GenericSender<WebGLQueryId>),
577 GetQueryState(GenericSender<u32>, WebGLQueryId, u32),
578 GenerateSampler(GenericSender<WebGLSamplerId>),
579 DeleteSampler(WebGLSamplerId),
580 BindSampler(u32, WebGLSamplerId),
581 SetSamplerParameterFloat(WebGLSamplerId, u32, f32),
582 SetSamplerParameterInt(WebGLSamplerId, u32, i32),
583 GetSamplerParameterFloat(WebGLSamplerId, u32, GenericSender<f32>),
584 GetSamplerParameterInt(WebGLSamplerId, u32, GenericSender<i32>),
585 BindBufferBase(u32, u32, Option<WebGLBufferId>),
586 BindBufferRange(u32, u32, Option<WebGLBufferId>, i64, i64),
587 ClearBufferfv(u32, i32, Vec<f32>),
588 ClearBufferiv(u32, i32, Vec<i32>),
589 ClearBufferuiv(u32, i32, Vec<u32>),
590 ClearBufferfi(u32, i32, f32, i32),
591 InvalidateFramebuffer(u32, Vec<u32>),
592 InvalidateSubFramebuffer(u32, Vec<u32>, i32, i32, i32, i32),
593 FramebufferTextureLayer(u32, u32, Option<WebGLTextureId>, i32, i32),
594 ReadBuffer(u32),
595 DrawBuffers(Vec<u32>),
596}
597
598#[derive(Debug, Deserialize, Serialize)]
600pub enum WebXRCommand {
601 CreateLayerManager(GenericSender<Result<WebXRLayerManagerId, WebXRError>>),
602 DestroyLayerManager(WebXRLayerManagerId),
603 CreateLayer(
604 WebXRLayerManagerId,
605 WebXRContextId,
606 WebXRLayerInit,
607 GenericSender<Result<WebXRLayerId, WebXRError>>,
608 ),
609 DestroyLayer(WebXRLayerManagerId, WebXRContextId, WebXRLayerId),
610 BeginFrame(
611 WebXRLayerManagerId,
612 Vec<(WebXRContextId, WebXRLayerId)>,
613 GenericSender<Result<Vec<WebXRSubImages>, WebXRError>>,
614 ),
615 EndFrame(
616 WebXRLayerManagerId,
617 Vec<(WebXRContextId, WebXRLayerId)>,
618 GenericSender<Result<(), WebXRError>>,
619 ),
620}
621
622macro_rules! nonzero_type {
623 (u32) => {
624 NonZeroU32
625 };
626 (u64) => {
627 NonZeroU64
628 };
629}
630
631macro_rules! define_resource_id {
632 ($name:ident, $type:tt) => {
633 #[derive(Clone, Copy, Eq, Hash, PartialEq)]
634 pub struct $name(nonzero_type!($type));
635
636 impl $name {
637 #[inline]
638 pub fn new(id: nonzero_type!($type)) -> Self {
639 Self(id)
640 }
641
642 #[inline]
643 pub fn maybe_new(id: $type) -> Option<Self> {
644 <nonzero_type!($type)>::new(id).map($name)
645 }
646
647 #[inline]
648 pub fn get(self) -> $type {
649 self.0.get()
650 }
651 }
652
653 impl<'de> ::serde::Deserialize<'de> for $name {
654 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
655 where
656 D: ::serde::Deserializer<'de>,
657 {
658 let id = <$type>::deserialize(deserializer)?;
659 if let Some(id) = <nonzero_type!($type)>::new(id) {
660 Ok($name(id))
661 } else {
662 Err(::serde::de::Error::custom("expected a non-zero value"))
663 }
664 }
665 }
666
667 impl ::serde::Serialize for $name {
668 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
669 where
670 S: ::serde::Serializer,
671 {
672 self.get().serialize(serializer)
673 }
674 }
675
676 impl ::std::fmt::Debug for $name {
677 fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
678 fmt.debug_tuple(stringify!($name))
679 .field(&self.get())
680 .finish()
681 }
682 }
683
684 impl ::std::fmt::Display for $name {
685 fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
686 write!(fmt, "{}", self.get())
687 }
688 }
689
690 impl ::malloc_size_of::MallocSizeOf for $name {
691 fn size_of(&self, _ops: &mut ::malloc_size_of::MallocSizeOfOps) -> usize {
692 0
693 }
694 }
695 };
696 ($name:ident, $type:tt, $glow:tt) => {
697 impl $name {
698 #[inline]
699 pub fn glow(self) -> $glow {
700 $glow(self.0)
701 }
702
703 #[inline]
704 pub fn from_glow(glow: $glow) -> Self {
705 Self(glow.0)
706 }
707 }
708 define_resource_id!($name, $type);
709 };
710}
711
712define_resource_id!(WebGLBufferId, u32, NativeBuffer);
713define_resource_id!(WebGLFramebufferId, u32, NativeFramebuffer);
714define_resource_id!(WebGLRenderbufferId, u32, NativeRenderbuffer);
715define_resource_id!(WebGLTextureId, u32, NativeTexture);
716define_resource_id!(WebGLProgramId, u32, NativeProgram);
717define_resource_id!(WebGLQueryId, u32, NativeQuery);
718define_resource_id!(WebGLSamplerId, u32, NativeSampler);
719define_resource_id!(WebGLShaderId, u32, NativeShader);
720define_resource_id!(WebGLSyncId, u64);
721impl WebGLSyncId {
722 #[inline]
723 pub fn glow(&self) -> NativeFence {
724 NativeFence(self.0.get() as _)
725 }
726
727 #[inline]
728 pub fn from_glow(glow: NativeFence) -> Self {
729 Self::maybe_new(glow.0 as _).expect("Glow should have valid fence")
730 }
731}
732define_resource_id!(WebGLVertexArrayId, u32, NativeVertexArray);
733define_resource_id!(WebXRLayerManagerId, u32);
734
735#[derive(
736 Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, Ord, PartialEq, PartialOrd, Serialize,
737)]
738pub struct WebGLContextId(pub u64);
739
740impl From<WebXRContextId> for WebGLContextId {
741 fn from(id: WebXRContextId) -> Self {
742 Self(id.0)
743 }
744}
745
746impl From<WebGLContextId> for WebXRContextId {
747 fn from(id: WebGLContextId) -> Self {
748 Self(id.0)
749 }
750}
751
752#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize, MallocSizeOf)]
753pub enum WebGLError {
754 InvalidEnum,
755 InvalidFramebufferOperation,
756 InvalidOperation,
757 InvalidValue,
758 OutOfMemory,
759 ContextLost,
760}
761
762#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
763pub enum WebGLFramebufferBindingRequest {
764 Explicit(WebGLFramebufferId),
765 Default,
766}
767
768pub type WebGLResult<T> = Result<T, WebGLError>;
769
770#[derive(Clone, Debug, Deserialize, Serialize)]
772pub struct ProgramLinkInfo {
773 pub linked: bool,
775 pub active_attribs: Box<[ActiveAttribInfo]>,
777 pub active_uniforms: Box<[ActiveUniformInfo]>,
779 pub active_uniform_blocks: Box<[ActiveUniformBlockInfo]>,
781 pub transform_feedback_length: i32,
783 pub transform_feedback_mode: i32,
785}
786
787#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
789pub struct ActiveAttribInfo {
790 pub name: String,
792 pub size: i32,
794 pub type_: u32,
796 pub location: Option<u32>,
798}
799
800#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
802pub struct ActiveUniformInfo {
803 pub base_name: Box<str>,
805 pub size: Option<i32>,
807 pub type_: u32,
809 pub bind_index: Option<u32>,
811}
812
813impl ActiveUniformInfo {
814 pub fn name(&self) -> Cow<'_, str> {
815 if self.size.is_some() {
816 let mut name = String::from(&*self.base_name);
817 name.push_str("[0]");
818 Cow::Owned(name)
819 } else {
820 Cow::Borrowed(&self.base_name)
821 }
822 }
823}
824
825#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
827pub struct ActiveUniformBlockInfo {
828 pub name: String,
830 pub size: i32,
832}
833
834macro_rules! parameters {
835 ($name:ident { $(
836 $variant:ident($kind:ident { $(
837 $param:ident = gl::$value:ident,
838 )+ }),
839 )+ }) => {
840 #[derive(Clone, Copy, Debug, Deserialize, Serialize)]
841 pub enum $name { $(
842 $variant($kind),
843 )+}
844
845 $(
846 #[derive(Clone, Copy, Debug, Deserialize, Serialize)]
847 #[repr(u32)]
848 pub enum $kind { $(
849 $param = gl::$value,
850 )+}
851 )+
852
853 impl $name {
854 pub fn from_u32(value: u32) -> WebGLResult<Self> {
855 match value {
856 $($(gl::$value => Ok($name::$variant($kind::$param)),)+)+
857 _ => Err(WebGLError::InvalidEnum)
858 }
859 }
860 }
861 }
862}
863
864parameters! {
865 Parameter {
866 Bool(ParameterBool {
867 DepthWritemask = gl::DEPTH_WRITEMASK,
868 SampleCoverageInvert = gl::SAMPLE_COVERAGE_INVERT,
869 TransformFeedbackActive = gl::TRANSFORM_FEEDBACK_ACTIVE,
870 TransformFeedbackPaused = gl::TRANSFORM_FEEDBACK_PAUSED,
871 RasterizerDiscard = gl::RASTERIZER_DISCARD,
872 }),
873 Bool4(ParameterBool4 {
874 ColorWritemask = gl::COLOR_WRITEMASK,
875 }),
876 Int(ParameterInt {
877 ActiveTexture = gl::ACTIVE_TEXTURE,
878 AlphaBits = gl::ALPHA_BITS,
879 BlendDstAlpha = gl::BLEND_DST_ALPHA,
880 BlendDstRgb = gl::BLEND_DST_RGB,
881 BlendEquationAlpha = gl::BLEND_EQUATION_ALPHA,
882 BlendEquationRgb = gl::BLEND_EQUATION_RGB,
883 BlendSrcAlpha = gl::BLEND_SRC_ALPHA,
884 BlendSrcRgb = gl::BLEND_SRC_RGB,
885 BlueBits = gl::BLUE_BITS,
886 CullFaceMode = gl::CULL_FACE_MODE,
887 DepthBits = gl::DEPTH_BITS,
888 DepthFunc = gl::DEPTH_FUNC,
889 FragmentShaderDerivativeHint = gl::FRAGMENT_SHADER_DERIVATIVE_HINT,
890 FrontFace = gl::FRONT_FACE,
891 GenerateMipmapHint = gl::GENERATE_MIPMAP_HINT,
892 GreenBits = gl::GREEN_BITS,
893 RedBits = gl::RED_BITS,
894 SampleBuffers = gl::SAMPLE_BUFFERS,
895 Samples = gl::SAMPLES,
896 StencilBackFail = gl::STENCIL_BACK_FAIL,
897 StencilBackFunc = gl::STENCIL_BACK_FUNC,
898 StencilBackPassDepthFail = gl::STENCIL_BACK_PASS_DEPTH_FAIL,
899 StencilBackPassDepthPass = gl::STENCIL_BACK_PASS_DEPTH_PASS,
900 StencilBackRef = gl::STENCIL_BACK_REF,
901 StencilBits = gl::STENCIL_BITS,
902 StencilClearValue = gl::STENCIL_CLEAR_VALUE,
903 StencilFail = gl::STENCIL_FAIL,
904 StencilFunc = gl::STENCIL_FUNC,
905 StencilPassDepthFail = gl::STENCIL_PASS_DEPTH_FAIL,
906 StencilPassDepthPass = gl::STENCIL_PASS_DEPTH_PASS,
907 StencilRef = gl::STENCIL_REF,
908 SubpixelBits = gl::SUBPIXEL_BITS,
909 TransformFeedbackBinding = gl::TRANSFORM_FEEDBACK_BINDING,
910 MaxTransformFeedbackInterleavedComponents = gl::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS,
911 MaxTransformFeedbackSeparateAttribs = gl::MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS,
912 MaxTransformFeedbackSeparateComponents = gl::MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS,
913 TransformFeedbackBufferSize = gl::TRANSFORM_FEEDBACK_BUFFER_SIZE,
914 TransformFeedbackBufferStart = gl::TRANSFORM_FEEDBACK_BUFFER_START,
915 PackRowLength = gl::PACK_ROW_LENGTH,
916 PackSkipPixels = gl::PACK_SKIP_PIXELS,
917 PackSkipRows = gl::PACK_SKIP_ROWS,
918 UnpackImageHeight = gl::UNPACK_IMAGE_HEIGHT,
919 UnpackRowLength = gl::UNPACK_ROW_LENGTH,
920 UnpackSkipImages = gl::UNPACK_SKIP_IMAGES,
921 UnpackSkipPixels = gl::UNPACK_SKIP_PIXELS,
922 UnpackSkipRows = gl::UNPACK_SKIP_ROWS,
923 }),
924 UInt(ParameterUInt {
925 StencilBackValueMask = gl::STENCIL_BACK_VALUE_MASK,
926 StencilBackWritemask = gl::STENCIL_BACK_WRITEMASK,
927 StencilValueMask = gl::STENCIL_VALUE_MASK,
928 StencilWritemask = gl::STENCIL_WRITEMASK,
929 }),
930 Int2(ParameterInt2 {
931 MaxViewportDims = gl::MAX_VIEWPORT_DIMS,
932 }),
933 Int4(ParameterInt4 {
934 ScissorBox = gl::SCISSOR_BOX,
935 Viewport = gl::VIEWPORT,
936 }),
937 Float(ParameterFloat {
938 DepthClearValue = gl::DEPTH_CLEAR_VALUE,
939 LineWidth = gl::LINE_WIDTH,
940 MaxTextureMaxAnisotropyExt = gl::MAX_TEXTURE_MAX_ANISOTROPY_EXT,
941 PolygonOffsetFactor = gl::POLYGON_OFFSET_FACTOR,
942 PolygonOffsetUnits = gl::POLYGON_OFFSET_UNITS,
943 SampleCoverageValue = gl::SAMPLE_COVERAGE_VALUE,
944 }),
945 Float2(ParameterFloat2 {
946 AliasedPointSizeRange = gl::ALIASED_POINT_SIZE_RANGE,
947 AliasedLineWidthRange = gl::ALIASED_LINE_WIDTH_RANGE,
948 DepthRange = gl::DEPTH_RANGE,
949 }),
950 Float4(ParameterFloat4 {
951 BlendColor = gl::BLEND_COLOR,
952 ColorClearValue = gl::COLOR_CLEAR_VALUE,
953 }),
954 }
955}
956
957parameters! {
958 TexParameter {
959 Float(TexParameterFloat {
960 TextureMaxAnisotropyExt = gl::TEXTURE_MAX_ANISOTROPY_EXT,
961 TextureMaxLod = gl::TEXTURE_MAX_LOD,
962 TextureMinLod = gl::TEXTURE_MIN_LOD,
963 }),
964 Int(TexParameterInt {
965 TextureWrapS = gl::TEXTURE_WRAP_S,
966 TextureWrapT = gl::TEXTURE_WRAP_T,
967 TextureWrapR = gl::TEXTURE_WRAP_R,
968 TextureBaseLevel = gl::TEXTURE_BASE_LEVEL,
969 TextureMinFilter = gl::TEXTURE_MIN_FILTER,
970 TextureMagFilter = gl::TEXTURE_MAG_FILTER,
971 TextureMaxLevel = gl::TEXTURE_MAX_LEVEL,
972 TextureCompareFunc = gl::TEXTURE_COMPARE_FUNC,
973 TextureCompareMode = gl::TEXTURE_COMPARE_MODE,
974 TextureImmutableLevels = gl::TEXTURE_IMMUTABLE_LEVELS,
975 }),
976 Bool(TexParameterBool {
977 TextureImmutableFormat = gl::TEXTURE_IMMUTABLE_FORMAT,
978 }),
979 }
980}
981
982impl TexParameter {
983 pub fn required_webgl_version(self) -> WebGLVersion {
984 match self {
985 Self::Float(TexParameterFloat::TextureMaxAnisotropyExt) |
986 Self::Int(TexParameterInt::TextureWrapS) |
987 Self::Int(TexParameterInt::TextureWrapT) => WebGLVersion::WebGL1,
988 _ => WebGLVersion::WebGL2,
989 }
990 }
991}
992
993parameters! {
994 InternalFormatParameter {
995 IntVec(InternalFormatIntVec {
996 Samples = gl::SAMPLES,
997 }),
998 }
999}
1000
1001#[macro_export]
1002macro_rules! gl_enums {
1003 ($(pub enum $name:ident { $($variant:ident = $mod:ident::$constant:ident,)+ })*) => {
1004 $(
1005 #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, malloc_size_of_derive::MallocSizeOf)]
1006 #[derive(PartialEq, Serialize)]
1007 #[repr(u32)]
1008 pub enum $name { $($variant = $mod::$constant,)+ }
1009
1010 impl $name {
1011 pub fn from_gl_constant(constant: u32) -> Option<Self> {
1012 Some(match constant {
1013 $($mod::$constant => $name::$variant, )+
1014 _ => return None,
1015 })
1016 }
1017
1018 #[inline]
1019 pub fn as_gl_constant(&self) -> u32 {
1020 *self as u32
1021 }
1022 }
1023 )*
1024 }
1025}
1026
1027mod gl_ext_constants {
1029 pub const COMPRESSED_RGB_ETC1_WEBGL: u32 = 0x8D64;
1030
1031 pub const ALPHA16F_ARB: u32 = 0x881C;
1032 pub const ALPHA32F_ARB: u32 = 0x8816;
1033 pub const LUMINANCE16F_ARB: u32 = 0x881E;
1034 pub const LUMINANCE32F_ARB: u32 = 0x8818;
1035 pub const LUMINANCE_ALPHA16F_ARB: u32 = 0x881F;
1036 pub const LUMINANCE_ALPHA32F_ARB: u32 = 0x8819;
1037}
1038
1039gl_enums! {
1040 pub enum TexFormat {
1041 DepthComponent = gl::DEPTH_COMPONENT,
1042 DepthStencil = gl::DEPTH_STENCIL,
1043 Alpha = gl::ALPHA,
1044 Alpha32f = gl_ext_constants::ALPHA32F_ARB,
1045 Alpha16f = gl_ext_constants::ALPHA16F_ARB,
1046 Red = gl::RED,
1047 RedInteger = gl::RED_INTEGER,
1048 RG = gl::RG,
1049 RGInteger = gl::RG_INTEGER,
1050 RGB = gl::RGB,
1051 RGBInteger = gl::RGB_INTEGER,
1052 RGBA = gl::RGBA,
1053 RGBAInteger = gl::RGBA_INTEGER,
1054 Luminance = gl::LUMINANCE,
1055 LuminanceAlpha = gl::LUMINANCE_ALPHA,
1056 Luminance32f = gl_ext_constants::LUMINANCE32F_ARB,
1057 Luminance16f = gl_ext_constants::LUMINANCE16F_ARB,
1058 LuminanceAlpha32f = gl_ext_constants::LUMINANCE_ALPHA32F_ARB,
1059 LuminanceAlpha16f = gl_ext_constants::LUMINANCE_ALPHA16F_ARB,
1060 CompressedRgbS3tcDxt1 = gl::COMPRESSED_RGB_S3TC_DXT1_EXT,
1061 CompressedRgbaS3tcDxt1 = gl::COMPRESSED_RGBA_S3TC_DXT1_EXT,
1062 CompressedRgbaS3tcDxt3 = gl::COMPRESSED_RGBA_S3TC_DXT3_EXT,
1063 CompressedRgbaS3tcDxt5 = gl::COMPRESSED_RGBA_S3TC_DXT5_EXT,
1064 CompressedRgbEtc1 = gl_ext_constants::COMPRESSED_RGB_ETC1_WEBGL,
1065 R8 = gl::R8,
1066 R8SNorm = gl::R8_SNORM,
1067 R16f = gl::R16F,
1068 R32f = gl::R32F,
1069 R8ui = gl::R8UI,
1070 R8i = gl::R8I,
1071 R16ui = gl::R16UI,
1072 R16i = gl::R16I,
1073 R32ui = gl::R32UI,
1074 R32i = gl::R32I,
1075 RG8 = gl::RG8,
1076 RG8SNorm = gl::RG8_SNORM,
1077 RG16f = gl::RG16F,
1078 RG32f = gl::RG32F,
1079 RG8ui = gl::RG8UI,
1080 RG8i = gl::RG8I,
1081 RG16ui = gl::RG16UI,
1082 RG16i = gl::RG16I,
1083 RG32ui = gl::RG32UI,
1084 RG32i = gl::RG32I,
1085 RGB8 = gl::RGB8,
1086 SRGB8 = gl::SRGB8,
1087 RGB565 = gl::RGB565,
1088 RGB8SNorm = gl::RGB8_SNORM,
1089 R11fG11fB10f = gl::R11F_G11F_B10F,
1090 RGB9E5 = gl::RGB9_E5,
1091 RGB16f = gl::RGB16F,
1092 RGB32f = gl::RGB32F,
1093 RGB8ui = gl::RGB8UI,
1094 RGB8i = gl::RGB8I,
1095 RGB16ui = gl::RGB16UI,
1096 RGB16i = gl::RGB16I,
1097 RGB32ui = gl::RGB32UI,
1098 RGB32i = gl::RGB32I,
1099 RGBA8 = gl::RGBA8,
1100 SRGB8Alpha8 = gl::SRGB8_ALPHA8,
1101 RGBA8SNorm = gl::RGBA8_SNORM,
1102 RGB5A1 = gl::RGB5_A1,
1103 RGBA4 = gl::RGBA4,
1104 RGB10A2 = gl::RGB10_A2,
1105 RGBA16f = gl::RGBA16F,
1106 RGBA32f = gl::RGBA32F,
1107 RGBA8ui = gl::RGBA8UI,
1108 RGBA8i = gl::RGBA8I,
1109 RGB10A2ui = gl::RGB10_A2UI,
1110 RGBA16ui = gl::RGBA16UI,
1111 RGBA16i = gl::RGBA16I,
1112 RGBA32i = gl::RGBA32I,
1113 RGBA32ui = gl::RGBA32UI,
1114 DepthComponent16 = gl::DEPTH_COMPONENT16,
1115 DepthComponent24 = gl::DEPTH_COMPONENT24,
1116 DepthComponent32f = gl::DEPTH_COMPONENT32F,
1117 Depth24Stencil8 = gl::DEPTH24_STENCIL8,
1118 Depth32fStencil8 = gl::DEPTH32F_STENCIL8,
1119 }
1120
1121 pub enum TexDataType {
1122 Byte = gl::BYTE,
1123 Int = gl::INT,
1124 Short = gl::SHORT,
1125 UnsignedByte = gl::UNSIGNED_BYTE,
1126 UnsignedInt = gl::UNSIGNED_INT,
1127 UnsignedInt10f11f11fRev = gl::UNSIGNED_INT_10F_11F_11F_REV,
1128 UnsignedInt2101010Rev = gl::UNSIGNED_INT_2_10_10_10_REV,
1129 UnsignedInt5999Rev = gl::UNSIGNED_INT_5_9_9_9_REV,
1130 UnsignedInt248 = gl::UNSIGNED_INT_24_8,
1131 UnsignedShort = gl::UNSIGNED_SHORT,
1132 UnsignedShort4444 = gl::UNSIGNED_SHORT_4_4_4_4,
1133 UnsignedShort5551 = gl::UNSIGNED_SHORT_5_5_5_1,
1134 UnsignedShort565 = gl::UNSIGNED_SHORT_5_6_5,
1135 Float = gl::FLOAT,
1136 HalfFloat = gl::HALF_FLOAT_OES,
1137 Float32UnsignedInt248Rev = gl::FLOAT_32_UNSIGNED_INT_24_8_REV,
1138 }
1139}
1140
1141impl TexFormat {
1142 pub fn components(&self) -> u32 {
1145 match self.to_unsized() {
1146 TexFormat::DepthStencil => 2,
1147 TexFormat::LuminanceAlpha => 2,
1148 TexFormat::RG | TexFormat::RGInteger => 2,
1149 TexFormat::RGB | TexFormat::RGBInteger => 3,
1150 TexFormat::RGBA | TexFormat::RGBAInteger => 4,
1151 _ => 1,
1152 }
1153 }
1154
1155 pub fn is_compressed(&self) -> bool {
1157 let gl_const = self.as_gl_constant();
1158 matches!(
1159 gl_const,
1160 gl::COMPRESSED_RGB_S3TC_DXT1_EXT |
1161 gl::COMPRESSED_RGBA_S3TC_DXT1_EXT |
1162 gl::COMPRESSED_RGBA_S3TC_DXT3_EXT |
1163 gl::COMPRESSED_RGBA_S3TC_DXT5_EXT |
1164 gl_ext_constants::COMPRESSED_RGB_ETC1_WEBGL
1165 )
1166 }
1167
1168 pub fn is_sized(&self) -> bool {
1170 !matches!(
1171 self,
1172 TexFormat::DepthComponent |
1173 TexFormat::DepthStencil |
1174 TexFormat::Alpha |
1175 TexFormat::Red |
1176 TexFormat::RG |
1177 TexFormat::RGB |
1178 TexFormat::RGBA |
1179 TexFormat::Luminance |
1180 TexFormat::LuminanceAlpha
1181 )
1182 }
1183
1184 pub fn to_unsized(self) -> TexFormat {
1185 match self {
1186 TexFormat::R8 => TexFormat::Red,
1187 TexFormat::R8SNorm => TexFormat::Red,
1188 TexFormat::R16f => TexFormat::Red,
1189 TexFormat::R32f => TexFormat::Red,
1190 TexFormat::R8ui => TexFormat::RedInteger,
1191 TexFormat::R8i => TexFormat::RedInteger,
1192 TexFormat::R16ui => TexFormat::RedInteger,
1193 TexFormat::R16i => TexFormat::RedInteger,
1194 TexFormat::R32ui => TexFormat::RedInteger,
1195 TexFormat::R32i => TexFormat::RedInteger,
1196 TexFormat::RG8 => TexFormat::RG,
1197 TexFormat::RG8SNorm => TexFormat::RG,
1198 TexFormat::RG16f => TexFormat::RG,
1199 TexFormat::RG32f => TexFormat::RG,
1200 TexFormat::RG8ui => TexFormat::RGInteger,
1201 TexFormat::RG8i => TexFormat::RGInteger,
1202 TexFormat::RG16ui => TexFormat::RGInteger,
1203 TexFormat::RG16i => TexFormat::RGInteger,
1204 TexFormat::RG32ui => TexFormat::RGInteger,
1205 TexFormat::RG32i => TexFormat::RGInteger,
1206 TexFormat::RGB8 => TexFormat::RGB,
1207 TexFormat::SRGB8 => TexFormat::RGB,
1208 TexFormat::RGB565 => TexFormat::RGB,
1209 TexFormat::RGB8SNorm => TexFormat::RGB,
1210 TexFormat::R11fG11fB10f => TexFormat::RGB,
1211 TexFormat::RGB9E5 => TexFormat::RGB,
1212 TexFormat::RGB16f => TexFormat::RGB,
1213 TexFormat::RGB32f => TexFormat::RGB,
1214 TexFormat::RGB8ui => TexFormat::RGBInteger,
1215 TexFormat::RGB8i => TexFormat::RGBInteger,
1216 TexFormat::RGB16ui => TexFormat::RGBInteger,
1217 TexFormat::RGB16i => TexFormat::RGBInteger,
1218 TexFormat::RGB32ui => TexFormat::RGBInteger,
1219 TexFormat::RGB32i => TexFormat::RGBInteger,
1220 TexFormat::RGBA8 => TexFormat::RGBA,
1221 TexFormat::SRGB8Alpha8 => TexFormat::RGBA,
1222 TexFormat::RGBA8SNorm => TexFormat::RGBA,
1223 TexFormat::RGB5A1 => TexFormat::RGBA,
1224 TexFormat::RGBA4 => TexFormat::RGBA,
1225 TexFormat::RGB10A2 => TexFormat::RGBA,
1226 TexFormat::RGBA16f => TexFormat::RGBA,
1227 TexFormat::RGBA32f => TexFormat::RGBA,
1228 TexFormat::RGBA8ui => TexFormat::RGBAInteger,
1229 TexFormat::RGBA8i => TexFormat::RGBAInteger,
1230 TexFormat::RGB10A2ui => TexFormat::RGBAInteger,
1231 TexFormat::RGBA16ui => TexFormat::RGBAInteger,
1232 TexFormat::RGBA16i => TexFormat::RGBAInteger,
1233 TexFormat::RGBA32i => TexFormat::RGBAInteger,
1234 TexFormat::RGBA32ui => TexFormat::RGBAInteger,
1235 TexFormat::DepthComponent16 => TexFormat::DepthComponent,
1236 TexFormat::DepthComponent24 => TexFormat::DepthComponent,
1237 TexFormat::DepthComponent32f => TexFormat::DepthComponent,
1238 TexFormat::Depth24Stencil8 => TexFormat::DepthStencil,
1239 TexFormat::Depth32fStencil8 => TexFormat::DepthStencil,
1240 TexFormat::Alpha32f => TexFormat::Alpha,
1241 TexFormat::Alpha16f => TexFormat::Alpha,
1242 TexFormat::Luminance32f => TexFormat::Luminance,
1243 TexFormat::Luminance16f => TexFormat::Luminance,
1244 TexFormat::LuminanceAlpha32f => TexFormat::LuminanceAlpha,
1245 TexFormat::LuminanceAlpha16f => TexFormat::LuminanceAlpha,
1246 _ => self,
1247 }
1248 }
1249
1250 pub fn compatible_data_types(self) -> &'static [TexDataType] {
1251 match self {
1252 TexFormat::RGB => &[
1253 TexDataType::UnsignedByte,
1254 TexDataType::UnsignedShort565,
1255 TexDataType::Float,
1256 TexDataType::HalfFloat,
1257 ][..],
1258 TexFormat::RGBA => &[
1259 TexDataType::UnsignedByte,
1260 TexDataType::UnsignedShort4444,
1261 TexDataType::UnsignedShort5551,
1262 TexDataType::Float,
1263 TexDataType::HalfFloat,
1264 ][..],
1265 TexFormat::LuminanceAlpha => &[
1266 TexDataType::UnsignedByte,
1267 TexDataType::Float,
1268 TexDataType::HalfFloat,
1269 ][..],
1270 TexFormat::Luminance => &[
1271 TexDataType::UnsignedByte,
1272 TexDataType::Float,
1273 TexDataType::HalfFloat,
1274 ][..],
1275 TexFormat::Alpha => &[
1276 TexDataType::UnsignedByte,
1277 TexDataType::Float,
1278 TexDataType::HalfFloat,
1279 ][..],
1280 TexFormat::LuminanceAlpha32f => &[TexDataType::Float][..],
1281 TexFormat::LuminanceAlpha16f => &[TexDataType::HalfFloat][..],
1282 TexFormat::Luminance32f => &[TexDataType::Float][..],
1283 TexFormat::Luminance16f => &[TexDataType::HalfFloat][..],
1284 TexFormat::Alpha32f => &[TexDataType::Float][..],
1285 TexFormat::Alpha16f => &[TexDataType::HalfFloat][..],
1286 TexFormat::R8 => &[TexDataType::UnsignedByte][..],
1287 TexFormat::R8SNorm => &[TexDataType::Byte][..],
1288 TexFormat::R16f => &[TexDataType::HalfFloat, TexDataType::Float][..],
1289 TexFormat::R32f => &[TexDataType::Float][..],
1290 TexFormat::R8ui => &[TexDataType::UnsignedByte][..],
1291 TexFormat::R8i => &[TexDataType::Byte][..],
1292 TexFormat::R16ui => &[TexDataType::UnsignedShort][..],
1293 TexFormat::R16i => &[TexDataType::Short][..],
1294 TexFormat::R32ui => &[TexDataType::UnsignedInt][..],
1295 TexFormat::R32i => &[TexDataType::Int][..],
1296 TexFormat::RG8 => &[TexDataType::UnsignedByte][..],
1297 TexFormat::RG8SNorm => &[TexDataType::Byte][..],
1298 TexFormat::RG16f => &[TexDataType::HalfFloat, TexDataType::Float][..],
1299 TexFormat::RG32f => &[TexDataType::Float][..],
1300 TexFormat::RG8ui => &[TexDataType::UnsignedByte][..],
1301 TexFormat::RG8i => &[TexDataType::Byte][..],
1302 TexFormat::RG16ui => &[TexDataType::UnsignedShort][..],
1303 TexFormat::RG16i => &[TexDataType::Short][..],
1304 TexFormat::RG32ui => &[TexDataType::UnsignedInt][..],
1305 TexFormat::RG32i => &[TexDataType::Int][..],
1306 TexFormat::RGB8 => &[TexDataType::UnsignedByte][..],
1307 TexFormat::SRGB8 => &[TexDataType::UnsignedByte][..],
1308 TexFormat::RGB565 => &[TexDataType::UnsignedByte, TexDataType::UnsignedShort565][..],
1309 TexFormat::RGB8SNorm => &[TexDataType::Byte][..],
1310 TexFormat::R11fG11fB10f => &[
1311 TexDataType::UnsignedInt10f11f11fRev,
1312 TexDataType::HalfFloat,
1313 TexDataType::Float,
1314 ][..],
1315 TexFormat::RGB9E5 => &[
1316 TexDataType::UnsignedInt5999Rev,
1317 TexDataType::HalfFloat,
1318 TexDataType::Float,
1319 ][..],
1320 TexFormat::RGB16f => &[TexDataType::HalfFloat, TexDataType::Float][..],
1321 TexFormat::RGB32f => &[TexDataType::Float][..],
1322 TexFormat::RGB8ui => &[TexDataType::UnsignedByte][..],
1323 TexFormat::RGB8i => &[TexDataType::Byte][..],
1324 TexFormat::RGB16ui => &[TexDataType::UnsignedShort][..],
1325 TexFormat::RGB16i => &[TexDataType::Short][..],
1326 TexFormat::RGB32ui => &[TexDataType::UnsignedInt][..],
1327 TexFormat::RGB32i => &[TexDataType::Int][..],
1328 TexFormat::RGBA8 => &[TexDataType::UnsignedByte][..],
1329 TexFormat::SRGB8Alpha8 => &[TexDataType::UnsignedByte][..],
1330 TexFormat::RGBA8SNorm => &[TexDataType::Byte][..],
1331 TexFormat::RGB5A1 => &[
1332 TexDataType::UnsignedByte,
1333 TexDataType::UnsignedShort5551,
1334 TexDataType::UnsignedInt2101010Rev,
1335 ][..],
1336 TexFormat::RGBA4 => &[TexDataType::UnsignedByte, TexDataType::UnsignedShort4444][..],
1337 TexFormat::RGB10A2 => &[TexDataType::UnsignedInt2101010Rev][..],
1338 TexFormat::RGBA16f => &[TexDataType::HalfFloat, TexDataType::Float][..],
1339 TexFormat::RGBA32f => &[TexDataType::Float][..],
1340 TexFormat::RGBA8ui => &[TexDataType::UnsignedByte][..],
1341 TexFormat::RGBA8i => &[TexDataType::Byte][..],
1342 TexFormat::RGB10A2ui => &[TexDataType::UnsignedInt2101010Rev][..],
1343 TexFormat::RGBA16ui => &[TexDataType::UnsignedShort][..],
1344 TexFormat::RGBA16i => &[TexDataType::Short][..],
1345 TexFormat::RGBA32i => &[TexDataType::Int][..],
1346 TexFormat::RGBA32ui => &[TexDataType::UnsignedInt][..],
1347 TexFormat::DepthComponent16 => {
1348 &[TexDataType::UnsignedShort, TexDataType::UnsignedInt][..]
1349 },
1350 TexFormat::DepthComponent24 => &[TexDataType::UnsignedInt][..],
1351 TexFormat::DepthComponent32f => &[TexDataType::Float][..],
1352 TexFormat::Depth24Stencil8 => &[TexDataType::UnsignedInt248][..],
1353 TexFormat::Depth32fStencil8 => &[TexDataType::Float32UnsignedInt248Rev][..],
1354 TexFormat::CompressedRgbS3tcDxt1 |
1355 TexFormat::CompressedRgbaS3tcDxt1 |
1356 TexFormat::CompressedRgbaS3tcDxt3 |
1357 TexFormat::CompressedRgbaS3tcDxt5 => &[TexDataType::UnsignedByte][..],
1358 _ => &[][..],
1359 }
1360 }
1361
1362 pub fn required_webgl_version(self) -> WebGLVersion {
1363 match self {
1364 TexFormat::DepthComponent |
1365 TexFormat::Alpha |
1366 TexFormat::RGB |
1367 TexFormat::RGBA |
1368 TexFormat::Luminance |
1369 TexFormat::LuminanceAlpha |
1370 TexFormat::CompressedRgbS3tcDxt1 |
1371 TexFormat::CompressedRgbaS3tcDxt1 |
1372 TexFormat::CompressedRgbaS3tcDxt3 |
1373 TexFormat::CompressedRgbaS3tcDxt5 => WebGLVersion::WebGL1,
1374 _ => WebGLVersion::WebGL2,
1375 }
1376 }
1377
1378 pub fn usable_as_internal(self) -> bool {
1379 !self.compatible_data_types().is_empty()
1380 }
1381}
1382
1383#[derive(PartialEq)]
1384pub enum SizedDataType {
1385 Int8,
1386 Int16,
1387 Int32,
1388 Uint8,
1389 Uint16,
1390 Uint32,
1391 Float32,
1392}
1393
1394impl TexDataType {
1395 pub fn from_webgl_constant(constant: u32, version: WebGLVersion) -> Option<Self> {
1398 match (version, constant) {
1399 (WebGLVersion::WebGL2, gl::HALF_FLOAT) => Some(TexDataType::HalfFloat),
1400 (WebGLVersion::WebGL2, gl::HALF_FLOAT_OES) => None,
1401 _ => Self::from_gl_constant(constant),
1402 }
1403 }
1404
1405 pub fn sized_data_type(&self) -> SizedDataType {
1407 match self {
1408 TexDataType::Byte => SizedDataType::Int8,
1409 TexDataType::UnsignedByte => SizedDataType::Uint8,
1410 TexDataType::Short => SizedDataType::Int16,
1411 TexDataType::UnsignedShort |
1412 TexDataType::UnsignedShort4444 |
1413 TexDataType::UnsignedShort5551 |
1414 TexDataType::UnsignedShort565 => SizedDataType::Uint16,
1415 TexDataType::Int => SizedDataType::Int32,
1416 TexDataType::UnsignedInt |
1417 TexDataType::UnsignedInt10f11f11fRev |
1418 TexDataType::UnsignedInt2101010Rev |
1419 TexDataType::UnsignedInt5999Rev |
1420 TexDataType::UnsignedInt248 => SizedDataType::Uint32,
1421 TexDataType::HalfFloat => SizedDataType::Uint16,
1422 TexDataType::Float | TexDataType::Float32UnsignedInt248Rev => SizedDataType::Float32,
1423 }
1424 }
1425
1426 pub fn element_size(&self) -> u32 {
1428 use self::*;
1429 match *self {
1430 TexDataType::Byte | TexDataType::UnsignedByte => 1,
1431 TexDataType::Short |
1432 TexDataType::UnsignedShort |
1433 TexDataType::UnsignedShort4444 |
1434 TexDataType::UnsignedShort5551 |
1435 TexDataType::UnsignedShort565 => 2,
1436 TexDataType::Int |
1437 TexDataType::UnsignedInt |
1438 TexDataType::UnsignedInt10f11f11fRev |
1439 TexDataType::UnsignedInt2101010Rev |
1440 TexDataType::UnsignedInt5999Rev => 4,
1441 TexDataType::UnsignedInt248 => 4,
1442 TexDataType::Float => 4,
1443 TexDataType::HalfFloat => 2,
1444 TexDataType::Float32UnsignedInt248Rev => 4,
1445 }
1446 }
1447
1448 pub fn components_per_element(&self) -> u32 {
1451 match *self {
1452 TexDataType::Byte => 1,
1453 TexDataType::UnsignedByte => 1,
1454 TexDataType::Short => 1,
1455 TexDataType::UnsignedShort => 1,
1456 TexDataType::UnsignedShort565 => 3,
1457 TexDataType::UnsignedShort5551 => 4,
1458 TexDataType::UnsignedShort4444 => 4,
1459 TexDataType::Int => 1,
1460 TexDataType::UnsignedInt => 1,
1461 TexDataType::UnsignedInt10f11f11fRev => 3,
1462 TexDataType::UnsignedInt2101010Rev => 4,
1463 TexDataType::UnsignedInt5999Rev => 4,
1464 TexDataType::UnsignedInt248 => 2,
1465 TexDataType::Float => 1,
1466 TexDataType::HalfFloat => 1,
1467 TexDataType::Float32UnsignedInt248Rev => 2,
1468 }
1469 }
1470
1471 pub fn required_webgl_version(self) -> WebGLVersion {
1472 match self {
1473 TexDataType::UnsignedByte |
1474 TexDataType::UnsignedShort4444 |
1475 TexDataType::UnsignedShort5551 |
1476 TexDataType::UnsignedShort565 |
1477 TexDataType::Float |
1478 TexDataType::HalfFloat => WebGLVersion::WebGL1,
1479 _ => WebGLVersion::WebGL2,
1480 }
1481 }
1482}
1483
1484#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
1485pub enum AlphaTreatment {
1486 Premultiply,
1487 Unmultiply,
1488}
1489
1490#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
1491pub enum YAxisTreatment {
1492 AsIs,
1493 Flipped,
1494}
1495
1496#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
1497pub struct GLContextAttributes {
1498 pub alpha: bool,
1499 pub depth: bool,
1500 pub stencil: bool,
1501 pub antialias: bool,
1502 pub premultiplied_alpha: bool,
1503 pub preserve_drawing_buffer: bool,
1504}
1505
1506#[derive(Clone, Debug, Deserialize, Serialize)]
1507pub struct GLLimits {
1508 pub max_vertex_attribs: u32,
1509 pub max_tex_size: u32,
1510 pub max_3d_tex_size: u32,
1511 pub max_cube_map_tex_size: u32,
1512 pub max_combined_texture_image_units: u32,
1513 pub max_fragment_uniform_vectors: u32,
1514 pub max_renderbuffer_size: u32,
1515 pub max_texture_image_units: u32,
1516 pub max_varying_vectors: u32,
1517 pub max_vertex_texture_image_units: u32,
1518 pub max_vertex_uniform_vectors: u32,
1519 pub max_client_wait_timeout_webgl: std::time::Duration,
1520 pub max_transform_feedback_separate_attribs: u32,
1521 pub max_vertex_output_vectors: u32,
1522 pub max_fragment_input_vectors: u32,
1523 pub max_draw_buffers: u32,
1524 pub max_color_attachments: u32,
1525 pub max_uniform_buffer_bindings: u32,
1526 pub min_program_texel_offset: i32,
1527 pub max_program_texel_offset: u32,
1528 pub max_uniform_block_size: u64,
1529 pub max_combined_uniform_blocks: u32,
1530 pub max_combined_vertex_uniform_components: u64,
1531 pub max_combined_fragment_uniform_components: u64,
1532 pub max_vertex_uniform_blocks: u32,
1533 pub max_vertex_uniform_components: u32,
1534 pub max_fragment_uniform_blocks: u32,
1535 pub max_fragment_uniform_components: u32,
1536 pub max_3d_texture_size: u32,
1537 pub max_array_texture_layers: u32,
1538 pub uniform_buffer_offset_alignment: u32,
1539 pub max_element_index: u64,
1540 pub max_elements_indices: u32,
1541 pub max_elements_vertices: u32,
1542 pub max_fragment_input_components: u32,
1543 pub max_samples: u32,
1544 pub max_server_wait_timeout: std::time::Duration,
1545 pub max_texture_lod_bias: f32,
1546 pub max_varying_components: u32,
1547 pub max_vertex_output_components: u32,
1548}