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