1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 use euclid::Size2D; 6 use nonzero::NonZero; 7 use offscreen_gl_context::{GLContextAttributes, GLLimits}; 8 use std::fmt; 9 use webrender_api::{DocumentId, ImageKey, PipelineId}; 10 11 /// Sender type used in WebGLCommands. 12 pub use ::webgl_channel::WebGLSender; 13 /// Receiver type used in WebGLCommands. 14 pub use ::webgl_channel::WebGLReceiver; 15 /// Result type for send()/recv() calls in in WebGLCommands. 16 pub use ::webgl_channel::WebGLSendResult; 17 /// Helper function that creates a WebGL channel (WebGLSender, WebGLReceiver) to be used in WebGLCommands. 18 pub use ::webgl_channel::webgl_channel; 19 /// Entry point type used in a Script Pipeline to get the WebGLChan to be used in that thread. 20 pub use ::webgl_channel::WebGLPipeline; 21 /// Entry point channel type used for sending WebGLMsg messages to the WebGL renderer. 22 pub use ::webgl_channel::WebGLChan; 23 24 /// WebGL Message API 25 #[derive(Clone, Deserialize, Serialize)] 26 pub enum WebGLMsg { 27 /// Creates a new WebGLContext. 28 CreateContext(WebGLVersion, Size2D<i32>, GLContextAttributes, 29 WebGLSender<Result<(WebGLCreateContextResult), String>>), 30 /// Resizes a WebGLContext. 31 ResizeContext(WebGLContextId, Size2D<i32>, WebGLSender<Result<(), String>>), 32 /// Drops a WebGLContext. 33 RemoveContext(WebGLContextId), 34 /// Runs a WebGLCommand in a specific WebGLContext. 35 WebGLCommand(WebGLContextId, WebGLCommand), 36 /// Runs a WebVRCommand in a specific WebGLContext. 37 WebVRCommand(WebGLContextId, WebVRCommand), 38 /// Locks a specific WebGLContext. Lock messages are used for a correct synchronization 39 /// with WebRender external image API. 40 /// WR locks a external texture when it wants to use the shared texture contents. 41 /// The WR client should not change the shared texture content until the Unlock call. 42 /// Currently OpenGL Sync Objects are used to implement the synchronization mechanism. 43 Lock(WebGLContextId, WebGLSender<(u32, Size2D<i32>, usize)>), 44 /// Unlocks a specific WebGLContext. Unlock messages are used for a correct synchronization 45 /// with WebRender external image API. 46 /// The WR unlocks a context when it finished reading the shared texture contents. 47 /// Unlock messages are always sent after a Lock message. 48 Unlock(WebGLContextId), 49 /// Creates or updates the image keys required for WebRender. 50 UpdateWebRenderImage(WebGLContextId, WebGLSender<ImageKey>), 51 /// Commands used for the DOMToTexture feature. 52 DOMToTextureCommand(DOMToTextureCommand), 53 /// Frees all resources and closes the thread. 54 Exit, 55 } 56 57 /// Contains the WebGLCommand sender and information about a WebGLContext 58 #[derive(Clone, Deserialize, Serialize)] 59 pub struct WebGLCreateContextResult { 60 /// Sender instance to send commands to the specific WebGLContext 61 pub sender: WebGLMsgSender, 62 /// Information about the internal GL Context. 63 pub limits: GLLimits, 64 /// How the WebGLContext is shared with WebRender. 65 pub share_mode: WebGLContextShareMode, 66 /// The GLSL version supported by the context. 67 pub glsl_version: WebGLSLVersion 68 } 69 70 #[derive(Clone, Copy, Deserialize, MallocSizeOf, Serialize)] 71 pub enum WebGLContextShareMode { 72 /// Fast: a shared texture_id is used in WebRender. 73 SharedTexture, 74 /// Slow: glReadPixels is used to send pixels to WebRender each frame. 75 Readback, 76 } 77 78 /// Defines the WebGL version 79 #[derive(Clone, Copy, Deserialize, Eq, MallocSizeOf, PartialEq, Serialize)] 80 pub enum WebGLVersion { 81 /// https://www.khronos.org/registry/webgl/specs/1.0.2/ 82 /// Conforms closely to the OpenGL ES 2.0 API 83 WebGL1, 84 /// https://www.khronos.org/registry/webgl/specs/latest/2.0/ 85 /// Conforms closely to the OpenGL ES 3.0 API 86 WebGL2, 87 } 88 89 /// Defines the GLSL version supported by the WebGL backend contexts. 90 #[derive(Clone, Copy, Deserialize, Eq, MallocSizeOf, PartialEq, Serialize)] 91 pub struct WebGLSLVersion { 92 /// Major GLSL version 93 pub major: u32, 94 /// Minor GLSL version 95 pub minor: u32, 96 } 97 98 /// Helper struct to send WebGLCommands to a specific WebGLContext. 99 #[derive(Clone, Deserialize, MallocSizeOf, Serialize)] 100 pub struct WebGLMsgSender { 101 ctx_id: WebGLContextId, 102 #[ignore_malloc_size_of = "channels are hard"] 103 sender: WebGLChan, 104 } 105 106 impl WebGLMsgSender { new(id: WebGLContextId, sender: WebGLChan) -> Self107 pub fn new(id: WebGLContextId, sender: WebGLChan) -> Self { 108 WebGLMsgSender { 109 ctx_id: id, 110 sender: sender, 111 } 112 } 113 114 /// Returns the WebGLContextId associated to this sender context_id(&self) -> WebGLContextId115 pub fn context_id(&self) -> WebGLContextId { 116 self.ctx_id 117 } 118 119 /// Send a WebGLCommand message 120 #[inline] send(&self, command: WebGLCommand) -> WebGLSendResult121 pub fn send(&self, command: WebGLCommand) -> WebGLSendResult { 122 self.sender.send(WebGLMsg::WebGLCommand(self.ctx_id, command)) 123 } 124 125 /// Send a WebVRCommand message 126 #[inline] send_vr(&self, command: WebVRCommand) -> WebGLSendResult127 pub fn send_vr(&self, command: WebVRCommand) -> WebGLSendResult { 128 self.sender.send(WebGLMsg::WebVRCommand(self.ctx_id, command)) 129 } 130 131 /// Send a resize message 132 #[inline] send_resize(&self, size: Size2D<i32>, sender: WebGLSender<Result<(), String>>) -> WebGLSendResult133 pub fn send_resize(&self, 134 size: Size2D<i32>, 135 sender: WebGLSender<Result<(), String>>) 136 -> WebGLSendResult { 137 self.sender.send(WebGLMsg::ResizeContext(self.ctx_id, size, sender)) 138 } 139 140 #[inline] send_remove(&self) -> WebGLSendResult141 pub fn send_remove(&self) -> WebGLSendResult { 142 self.sender.send(WebGLMsg::RemoveContext(self.ctx_id)) 143 } 144 145 #[inline] send_update_wr_image(&self, sender: WebGLSender<ImageKey>) -> WebGLSendResult146 pub fn send_update_wr_image(&self, sender: WebGLSender<ImageKey>) -> WebGLSendResult { 147 self.sender.send(WebGLMsg::UpdateWebRenderImage(self.ctx_id, sender)) 148 } 149 send_dom_to_texture(&self, command: DOMToTextureCommand) -> WebGLSendResult150 pub fn send_dom_to_texture(&self, command: DOMToTextureCommand) -> WebGLSendResult { 151 self.sender.send(WebGLMsg::DOMToTextureCommand(command)) 152 } 153 } 154 155 /// WebGL Commands for a specific WebGLContext 156 #[derive(Clone, Deserialize, Serialize)] 157 pub enum WebGLCommand { 158 GetContextAttributes(WebGLSender<GLContextAttributes>), 159 ActiveTexture(u32), 160 BlendColor(f32, f32, f32, f32), 161 BlendEquation(u32), 162 BlendEquationSeparate(u32, u32), 163 BlendFunc(u32, u32), 164 BlendFuncSeparate(u32, u32, u32, u32), 165 AttachShader(WebGLProgramId, WebGLShaderId), 166 DetachShader(WebGLProgramId, WebGLShaderId), 167 BindAttribLocation(WebGLProgramId, u32, String), 168 BufferData(u32, Vec<u8>, u32), 169 BufferSubData(u32, isize, Vec<u8>), 170 Clear(u32), 171 ClearColor(f32, f32, f32, f32), 172 ClearDepth(f64), 173 ClearStencil(i32), 174 ColorMask(bool, bool, bool, bool), 175 CullFace(u32), 176 FrontFace(u32), 177 DepthFunc(u32), 178 DepthMask(bool), 179 DepthRange(f64, f64), 180 Enable(u32), 181 Disable(u32), 182 CompileShader(WebGLShaderId, String), 183 CopyTexImage2D(u32, i32, u32, i32, i32, i32, i32, i32), 184 CopyTexSubImage2D(u32, i32, i32, i32, i32, i32, i32, i32), 185 CreateBuffer(WebGLSender<Option<WebGLBufferId>>), 186 CreateFramebuffer(WebGLSender<Option<WebGLFramebufferId>>), 187 CreateRenderbuffer(WebGLSender<Option<WebGLRenderbufferId>>), 188 CreateTexture(WebGLSender<Option<WebGLTextureId>>), 189 CreateProgram(WebGLSender<Option<WebGLProgramId>>), 190 CreateShader(u32, WebGLSender<Option<WebGLShaderId>>), 191 DeleteBuffer(WebGLBufferId), 192 DeleteFramebuffer(WebGLFramebufferId), 193 DeleteRenderbuffer(WebGLRenderbufferId), 194 DeleteTexture(WebGLTextureId), 195 DeleteProgram(WebGLProgramId), 196 DeleteShader(WebGLShaderId), 197 BindBuffer(u32, Option<WebGLBufferId>), 198 BindFramebuffer(u32, WebGLFramebufferBindingRequest), 199 BindRenderbuffer(u32, Option<WebGLRenderbufferId>), 200 BindTexture(u32, Option<WebGLTextureId>), 201 DisableVertexAttribArray(u32), 202 DrawArrays(u32, i32, i32), 203 DrawElements(u32, i32, u32, i64), 204 EnableVertexAttribArray(u32), 205 FramebufferRenderbuffer(u32, u32, u32, Option<WebGLRenderbufferId>), 206 FramebufferTexture2D(u32, u32, u32, Option<WebGLTextureId>, i32), 207 GetBufferParameter(u32, u32, WebGLSender<WebGLResult<WebGLParameter>>), 208 GetExtensions(WebGLSender<String>), 209 GetParameter(u32, WebGLSender<WebGLResult<WebGLParameter>>), 210 GetTexParameter(u32, u32, WebGLSender<WebGLResult<WebGLParameter>>), 211 GetProgramParameter(WebGLProgramId, u32, WebGLSender<WebGLResult<WebGLParameter>>), 212 GetShaderParameter(WebGLShaderId, u32, WebGLSender<WebGLResult<WebGLParameter>>), 213 GetShaderPrecisionFormat(u32, u32, WebGLSender<WebGLResult<(i32, i32, i32)>>), 214 GetActiveAttrib(WebGLProgramId, u32, WebGLSender<WebGLResult<(i32, u32, String)>>), 215 GetActiveUniform(WebGLProgramId, u32, WebGLSender<WebGLResult<(i32, u32, String)>>), 216 GetAttribLocation(WebGLProgramId, String, WebGLSender<Option<i32>>), 217 GetUniformLocation(WebGLProgramId, String, WebGLSender<Option<i32>>), 218 GetVertexAttrib(u32, u32, WebGLSender<WebGLResult<WebGLParameter>>), 219 GetVertexAttribOffset(u32, u32, WebGLSender<WebGLResult<isize>>), 220 GetShaderInfoLog(WebGLShaderId, WebGLSender<String>), 221 GetProgramInfoLog(WebGLProgramId, WebGLSender<String>), 222 PolygonOffset(f32, f32), 223 RenderbufferStorage(u32, u32, i32, i32), 224 ReadPixels(i32, i32, i32, i32, u32, u32, WebGLSender<Vec<u8>>), 225 SampleCoverage(f32, bool), 226 Scissor(i32, i32, i32, i32), 227 StencilFunc(u32, i32, u32), 228 StencilFuncSeparate(u32, u32, i32, u32), 229 StencilMask(u32), 230 StencilMaskSeparate(u32, u32), 231 StencilOp(u32, u32, u32), 232 StencilOpSeparate(u32, u32, u32, u32), 233 Hint(u32, u32), 234 IsEnabled(u32, WebGLSender<bool>), 235 LineWidth(f32), 236 PixelStorei(u32, i32), 237 LinkProgram(WebGLProgramId), 238 Uniform1f(i32, f32), 239 Uniform1fv(i32, Vec<f32>), 240 Uniform1i(i32, i32), 241 Uniform1iv(i32, Vec<i32>), 242 Uniform2f(i32, f32, f32), 243 Uniform2fv(i32, Vec<f32>), 244 Uniform2i(i32, i32, i32), 245 Uniform2iv(i32, Vec<i32>), 246 Uniform3f(i32, f32, f32, f32), 247 Uniform3fv(i32, Vec<f32>), 248 Uniform3i(i32, i32, i32, i32), 249 Uniform3iv(i32, Vec<i32>), 250 Uniform4f(i32, f32, f32, f32, f32), 251 Uniform4fv(i32, Vec<f32>), 252 Uniform4i(i32, i32, i32, i32, i32), 253 Uniform4iv(i32, Vec<i32>), 254 UniformMatrix2fv(i32, bool, Vec<f32>), 255 UniformMatrix3fv(i32, bool, Vec<f32>), 256 UniformMatrix4fv(i32, bool, Vec<f32>), 257 UseProgram(WebGLProgramId), 258 ValidateProgram(WebGLProgramId), 259 VertexAttrib(u32, f32, f32, f32, f32), 260 VertexAttribPointer(u32, i32, u32, bool, i32, u32), 261 VertexAttribPointer2f(u32, i32, bool, i32, u32), 262 Viewport(i32, i32, i32, i32), 263 TexImage2D(u32, i32, i32, i32, i32, u32, u32, Vec<u8>), 264 TexParameteri(u32, u32, i32), 265 TexParameterf(u32, u32, f32), 266 TexSubImage2D(u32, i32, i32, i32, i32, i32, u32, u32, Vec<u8>), 267 DrawingBufferWidth(WebGLSender<i32>), 268 DrawingBufferHeight(WebGLSender<i32>), 269 Finish(WebGLSender<()>), 270 Flush, 271 GenerateMipmap(u32), 272 CreateVertexArray(WebGLSender<Option<WebGLVertexArrayId>>), 273 DeleteVertexArray(WebGLVertexArrayId), 274 BindVertexArray(Option<WebGLVertexArrayId>), 275 } 276 277 macro_rules! define_resource_id_struct { 278 ($name:ident) => { 279 #[derive(Clone, Copy, Eq, Hash, PartialEq)] 280 pub struct $name(NonZero<u32>); 281 282 impl $name { 283 #[allow(unsafe_code)] 284 #[inline] 285 pub unsafe fn new(id: u32) -> Self { 286 $name(NonZero::new_unchecked(id)) 287 } 288 289 #[inline] 290 pub fn get(self) -> u32 { 291 self.0.get() 292 } 293 } 294 295 }; 296 } 297 298 macro_rules! define_resource_id { 299 ($name:ident) => { 300 define_resource_id_struct!($name); 301 302 #[allow(unsafe_code)] 303 impl<'de> ::serde::Deserialize<'de> for $name { 304 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 305 where D: ::serde::Deserializer<'de> 306 { 307 let id = try!(u32::deserialize(deserializer)); 308 if id == 0 { 309 Err(::serde::de::Error::custom("expected a non-zero value")) 310 } else { 311 Ok(unsafe { $name::new(id) }) 312 } 313 } 314 } 315 316 impl ::serde::Serialize for $name { 317 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 318 where S: ::serde::Serializer 319 { 320 self.get().serialize(serializer) 321 } 322 } 323 324 impl ::std::fmt::Debug for $name { 325 fn fmt(&self, fmt: &mut ::std::fmt::Formatter) 326 -> Result<(), ::std::fmt::Error> { 327 fmt.debug_tuple(stringify!($name)) 328 .field(&self.get()) 329 .finish() 330 } 331 } 332 333 impl ::std::fmt::Display for $name { 334 fn fmt(&self, fmt: &mut ::std::fmt::Formatter) 335 -> Result<(), ::std::fmt::Error> { 336 write!(fmt, "{}", self.get()) 337 } 338 } 339 340 impl ::malloc_size_of::MallocSizeOf for $name { 341 fn size_of(&self, _ops: &mut ::malloc_size_of::MallocSizeOfOps) -> usize { 0 } 342 } 343 } 344 } 345 346 define_resource_id!(WebGLBufferId); 347 define_resource_id!(WebGLFramebufferId); 348 define_resource_id!(WebGLRenderbufferId); 349 define_resource_id!(WebGLTextureId); 350 define_resource_id!(WebGLProgramId); 351 define_resource_id!(WebGLShaderId); 352 define_resource_id!(WebGLVertexArrayId); 353 354 #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, Ord)] 355 #[derive(PartialEq, PartialOrd, Serialize)] 356 pub struct WebGLContextId(pub usize); 357 358 #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)] 359 pub enum WebGLError { 360 InvalidEnum, 361 InvalidFramebufferOperation, 362 InvalidOperation, 363 InvalidValue, 364 OutOfMemory, 365 ContextLost, 366 } 367 368 #[derive(Clone, Debug, Deserialize, Serialize)] 369 pub enum WebGLFramebufferBindingRequest { 370 Explicit(WebGLFramebufferId), 371 Default, 372 } 373 374 #[derive(Clone, Debug, Deserialize, Serialize)] 375 pub enum WebGLParameter { 376 Int(i32), 377 Bool(bool), 378 String(String), 379 Float(f32), 380 FloatArray(Vec<f32>), 381 Invalid, 382 } 383 384 pub type WebGLResult<T> = Result<T, WebGLError>; 385 386 #[derive(Clone, Debug, Deserialize, Serialize)] 387 pub enum WebGLShaderParameter { 388 Int(i32), 389 Bool(bool), 390 Invalid, 391 } 392 393 pub type WebVRDeviceId = u32; 394 395 // WebVR commands that must be called in the WebGL render thread. 396 #[derive(Clone, Deserialize, Serialize)] 397 pub enum WebVRCommand { 398 /// Start presenting to a VR device. 399 Create(WebVRDeviceId), 400 /// Synchronize the pose information to be used in the frame. 401 SyncPoses(WebVRDeviceId, f64, f64, WebGLSender<Result<Vec<u8>, ()>>), 402 /// Submit the frame to a VR device using the specified texture coordinates. 403 SubmitFrame(WebVRDeviceId, [f32; 4], [f32; 4]), 404 /// Stop presenting to a VR device 405 Release(WebVRDeviceId) 406 } 407 408 // Trait object that handles WebVR commands. 409 // Receives the texture id and size associated to the WebGLContext. 410 pub trait WebVRRenderHandler: Send { handle(&mut self, command: WebVRCommand, texture: Option<(u32, Size2D<i32>)>)411 fn handle(&mut self, command: WebVRCommand, texture: Option<(u32, Size2D<i32>)>); 412 } 413 414 /// WebGL commands required to implement DOMToTexture feature. 415 #[derive(Clone, Deserialize, Serialize)] 416 pub enum DOMToTextureCommand { 417 /// Attaches a HTMLIFrameElement to a WebGLTexture. 418 Attach(WebGLContextId, WebGLTextureId, DocumentId, PipelineId, Size2D<i32>), 419 /// Releases the HTMLIFrameElement to WebGLTexture attachment. 420 Detach(WebGLTextureId), 421 /// Lock message used for a correct synchronization with WebRender GL flow. 422 Lock(PipelineId, usize, WebGLSender<Option<(u32, Size2D<i32>)>>), 423 } 424 425 impl fmt::Debug for WebGLCommand { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result426 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 427 use self::WebGLCommand::*; 428 let name = match *self { 429 GetContextAttributes(..) => "GetContextAttributes", 430 ActiveTexture(..) => "ActiveTexture", 431 BlendColor(..) => "BlendColor", 432 BlendEquation(..) => "BlendEquation", 433 BlendEquationSeparate(..) => "BlendEquationSeparate", 434 BlendFunc(..) => "BlendFunc", 435 BlendFuncSeparate(..) => "BlendFuncSeparate", 436 AttachShader(..) => "AttachShader", 437 DetachShader(..) => "DetachShader", 438 BindAttribLocation(..) => "BindAttribLocation", 439 BufferData(..) => "BufferData", 440 BufferSubData(..) => "BufferSubData", 441 Clear(..) => "Clear", 442 ClearColor(..) => "ClearColor", 443 ClearDepth(..) => "ClearDepth", 444 ClearStencil(..) => "ClearStencil", 445 ColorMask(..) => "ColorMask", 446 CopyTexImage2D(..) => "CopyTexImage2D", 447 CopyTexSubImage2D(..) => "CopyTexSubImage2D", 448 CullFace(..) => "CullFace", 449 FrontFace(..) => "FrontFace", 450 DepthFunc(..) => "DepthFunc", 451 DepthMask(..) => "DepthMask", 452 DepthRange(..) => "DepthRange", 453 Enable(..) => "Enable", 454 Disable(..) => "Disable", 455 CompileShader(..) => "CompileShader", 456 CreateBuffer(..) => "CreateBuffer", 457 CreateFramebuffer(..) => "CreateFramebuffer", 458 CreateRenderbuffer(..) => "CreateRenderbuffer", 459 CreateTexture(..) => "CreateTexture", 460 CreateProgram(..) => "CreateProgram", 461 CreateShader(..) => "CreateShader", 462 DeleteBuffer(..) => "DeleteBuffer", 463 DeleteFramebuffer(..) => "DeleteFramebuffer", 464 DeleteRenderbuffer(..) => "DeleteRenderBuffer", 465 DeleteTexture(..) => "DeleteTexture", 466 DeleteProgram(..) => "DeleteProgram", 467 DeleteShader(..) => "DeleteShader", 468 BindBuffer(..) => "BindBuffer", 469 BindFramebuffer(..) => "BindFramebuffer", 470 BindRenderbuffer(..) => "BindRenderbuffer", 471 BindTexture(..) => "BindTexture", 472 DisableVertexAttribArray(..) => "DisableVertexAttribArray", 473 DrawArrays(..) => "DrawArrays", 474 DrawElements(..) => "DrawElements", 475 EnableVertexAttribArray(..) => "EnableVertexAttribArray", 476 FramebufferRenderbuffer(..) => "FramebufferRenderbuffer", 477 FramebufferTexture2D(..) => "FramebufferTexture2D", 478 GetBufferParameter(..) => "GetBufferParameter", 479 GetExtensions(..) => "GetExtensions", 480 GetParameter(..) => "GetParameter", 481 GetTexParameter(..) => "GetTexParameter", 482 GetProgramParameter(..) => "GetProgramParameter", 483 GetShaderParameter(..) => "GetShaderParameter", 484 GetShaderPrecisionFormat(..) => "GetShaderPrecisionFormat", 485 GetActiveAttrib(..) => "GetActiveAttrib", 486 GetActiveUniform(..) => "GetActiveUniform", 487 GetAttribLocation(..) => "GetAttribLocation", 488 GetUniformLocation(..) => "GetUniformLocation", 489 GetShaderInfoLog(..) => "GetShaderInfoLog", 490 GetProgramInfoLog(..) => "GetProgramInfoLog", 491 GetVertexAttrib(..) => "GetVertexAttrib", 492 GetVertexAttribOffset(..) => "GetVertexAttribOffset", 493 PolygonOffset(..) => "PolygonOffset", 494 ReadPixels(..) => "ReadPixels", 495 RenderbufferStorage(..) => "RenderbufferStorage", 496 SampleCoverage(..) => "SampleCoverage", 497 Scissor(..) => "Scissor", 498 StencilFunc(..) => "StencilFunc", 499 StencilFuncSeparate(..) => "StencilFuncSeparate", 500 StencilMask(..) => "StencilMask", 501 StencilMaskSeparate(..) => "StencilMaskSeparate", 502 StencilOp(..) => "StencilOp", 503 StencilOpSeparate(..) => "StencilOpSeparate", 504 Hint(..) => "Hint", 505 IsEnabled(..) => "IsEnabled", 506 LineWidth(..) => "LineWidth", 507 PixelStorei(..) => "PixelStorei", 508 LinkProgram(..) => "LinkProgram", 509 Uniform1f(..) => "Uniform1f", 510 Uniform1fv(..) => "Uniform1fv", 511 Uniform1i(..) => "Uniform1i", 512 Uniform1iv(..) => "Uniform1iv", 513 Uniform2f(..) => "Uniform2f", 514 Uniform2fv(..) => "Uniform2fv", 515 Uniform2i(..) => "Uniform2i", 516 Uniform2iv(..) => "Uniform2iv", 517 Uniform3f(..) => "Uniform3f", 518 Uniform3fv(..) => "Uniform3fv", 519 Uniform3i(..) => "Uniform3i", 520 Uniform3iv(..) => "Uniform3iv", 521 Uniform4f(..) => "Uniform4f", 522 Uniform4fv(..) => "Uniform4fv", 523 Uniform4i(..) => "Uniform4i", 524 Uniform4iv(..) => "Uniform4iv", 525 UniformMatrix2fv(..) => "UniformMatrix2fv", 526 UniformMatrix3fv(..) => "UniformMatrix3fv", 527 UniformMatrix4fv(..) => "UniformMatrix4fv", 528 UseProgram(..) => "UseProgram", 529 ValidateProgram(..) => "ValidateProgram", 530 VertexAttrib(..) => "VertexAttrib", 531 VertexAttribPointer2f(..) => "VertexAttribPointer2f", 532 VertexAttribPointer(..) => "VertexAttribPointer", 533 Viewport(..) => "Viewport", 534 TexImage2D(..) => "TexImage2D", 535 TexParameteri(..) => "TexParameteri", 536 TexParameterf(..) => "TexParameterf", 537 TexSubImage2D(..) => "TexSubImage2D", 538 DrawingBufferWidth(..) => "DrawingBufferWidth", 539 DrawingBufferHeight(..) => "DrawingBufferHeight", 540 Finish(..) => "Finish", 541 Flush => "Flush", 542 GenerateMipmap(..) => "GenerateMipmap", 543 CreateVertexArray(..) => "CreateVertexArray", 544 DeleteVertexArray(..) => "DeleteVertexArray", 545 BindVertexArray(..) => "BindVertexArray" 546 }; 547 548 write!(f, "CanvasWebGLMsg::{}(..)", name) 549 } 550 } 551