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