aboutsummaryrefslogtreecommitdiffstats
path: root/components/canvas/webgl_thread.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/canvas/webgl_thread.rs')
-rw-r--r--components/canvas/webgl_thread.rs78
1 files changed, 69 insertions, 9 deletions
diff --git a/components/canvas/webgl_thread.rs b/components/canvas/webgl_thread.rs
index ee1e3513939..612117c7095 100644
--- a/components/canvas/webgl_thread.rs
+++ b/components/canvas/webgl_thread.rs
@@ -13,7 +13,7 @@ use ipc_channel::ipc::{self, OpaqueIpcMessage};
use ipc_channel::router::ROUTER;
use offscreen_gl_context::{DrawBuffer, GLContext, NativeGLContextMethods};
use pixels::{self, PixelFormat};
-use sparkle::gl;
+use sparkle::gl::{self, Gl};
use std::borrow::Cow;
use std::cell::Cell;
use std::cell::RefCell;
@@ -30,6 +30,15 @@ pub use crate::webgl_mode::{ThreadMode, WebGLThreads};
struct GLContextData {
ctx: GLContextWrapper,
state: GLState,
+ use_apple_vertex_arrays: bool,
+}
+
+// rust-offscreen-rendering-context creates a legacy OpenGL context on macOS when
+// OpenGL 2 support is requested. Legacy contexts return GL errors for the vertex
+// array object functions, but support a set of APPLE extension functions that
+// provide VAO support instead.
+fn needs_apple_vertex_arrays(gl: &gl::Gl, version: WebGLVersion) -> bool {
+ cfg!(target_os = "macos") && gl.get_type() == gl::GlType::Gl && version == WebGLVersion::WebGL1
}
pub struct GLState {
@@ -316,7 +325,12 @@ impl WebGLThread {
&mut self.bound_context_id,
);
if let Some(data) = data {
- data.ctx.apply_command(command, backtrace, &mut data.state);
+ data.ctx.apply_command(
+ command,
+ data.use_apple_vertex_arrays,
+ backtrace,
+ &mut data.state,
+ );
}
}
@@ -421,11 +435,13 @@ impl WebGLThread {
.0 as usize,
);
let (size, texture_id, limits) = ctx.get_info();
+ let use_apple_vertex_arrays = needs_apple_vertex_arrays(ctx.gl(), version);
self.contexts.insert(
id,
GLContextData {
ctx,
state: Default::default(),
+ use_apple_vertex_arrays,
},
);
@@ -883,6 +899,7 @@ impl WebGLImpl {
pub fn apply<Native: NativeGLContextMethods>(
ctx: &GLContext<Native>,
state: &mut GLState,
+ use_apple_vertex_array: bool,
command: WebGLCommand,
_backtrace: WebGLCommandBacktrace,
) {
@@ -1304,11 +1321,37 @@ impl WebGLImpl {
WebGLCommand::Finish(ref sender) => Self::finish(ctx.gl(), sender),
WebGLCommand::Flush => ctx.gl().flush(),
WebGLCommand::GenerateMipmap(target) => ctx.gl().generate_mipmap(target),
- WebGLCommand::CreateVertexArray(ref chan) => Self::create_vertex_array(ctx.gl(), chan),
- WebGLCommand::DeleteVertexArray(id) => ctx.gl().delete_vertex_arrays(&[id.get()]),
- WebGLCommand::BindVertexArray(id) => ctx
- .gl()
- .bind_vertex_array(id.map_or(0, WebGLVertexArrayId::get)),
+ WebGLCommand::CreateVertexArray(ref chan) => {
+ Self::create_vertex_array(ctx.gl(), use_apple_vertex_array, chan)
+ },
+ WebGLCommand::DeleteVertexArray(id) => {
+ let gl = ctx.gl();
+ let ids = [id.get()];
+ if use_apple_vertex_array {
+ match gl {
+ Gl::Gl(gl) => unsafe {
+ gl.DeleteVertexArraysAPPLE(ids.len() as gl::GLsizei, ids.as_ptr());
+ },
+ Gl::Gles(_) => unimplemented!("No GLES on macOS"),
+ }
+ } else {
+ gl.delete_vertex_arrays(&ids)
+ }
+ },
+ WebGLCommand::BindVertexArray(id) => {
+ let gl = ctx.gl();
+ let id = id.map_or(0, WebGLVertexArrayId::get);
+ if use_apple_vertex_array {
+ match gl {
+ Gl::Gl(gl) => unsafe {
+ gl.BindVertexArrayAPPLE(id);
+ },
+ Gl::Gles(_) => unimplemented!("No GLES on macOS"),
+ }
+ } else {
+ gl.bind_vertex_array(id)
+ }
+ },
WebGLCommand::GetParameterBool(param, ref sender) => {
let mut value = [0];
unsafe {
@@ -1847,8 +1890,25 @@ impl WebGLImpl {
}
#[allow(unsafe_code)]
- fn create_vertex_array(gl: &gl::Gl, chan: &WebGLSender<Option<WebGLVertexArrayId>>) {
- let vao = gl.gen_vertex_arrays(1)[0];
+ fn create_vertex_array(
+ gl: &gl::Gl,
+ use_apple_ext: bool,
+ chan: &WebGLSender<Option<WebGLVertexArrayId>>,
+ ) {
+ let vao = if use_apple_ext {
+ match gl {
+ Gl::Gl(gl) => {
+ let mut ids = vec![0];
+ unsafe {
+ gl.GenVertexArraysAPPLE(ids.len() as gl::GLsizei, ids.as_mut_ptr());
+ }
+ ids[0]
+ },
+ Gl::Gles(_) => unimplemented!("No GLES on macOS"),
+ }
+ } else {
+ gl.gen_vertex_arrays(1)[0]
+ };
let vao = if vao == 0 {
None
} else {