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