script/dom/webgl/extensions/
wrapper.rs1use js::context::JSContext;
6use js::rust::MutableHandleObject;
7use malloc_size_of::MallocSizeOf;
8use script_bindings::reflector::DomObject;
9
10use super::{WebGLExtension, WebGLExtensionSpec, WebGLExtensions};
11use crate::dom::bindings::root::MutNullableDom;
12use crate::dom::bindings::trace::JSTraceable;
13use crate::dom::webgl::webglrenderingcontext::WebGLRenderingContext;
14
15pub(crate) trait WebGLExtensionWrapper: JSTraceable + MallocSizeOf {
18 fn instance_or_init(
19 &self,
20 cx: &mut JSContext,
21 ctx: &WebGLRenderingContext,
22 ext: &WebGLExtensions,
23 rval: MutableHandleObject,
24 );
25 fn spec(&self) -> WebGLExtensionSpec;
26 fn is_supported(&self, _: &WebGLExtensions) -> bool;
27 fn is_enabled(&self) -> bool;
28 fn enable(&self, ext: &WebGLExtensions);
29 fn name(&self) -> &'static str;
30}
31
32#[cfg_attr(crown, crown::unrooted_must_root_lint::must_root)]
33#[derive(JSTraceable, MallocSizeOf)]
34pub(crate) struct TypedWebGLExtensionWrapper<T: WebGLExtension> {
35 extension: MutNullableDom<T::Extension>,
36}
37
38impl<T: WebGLExtension> TypedWebGLExtensionWrapper<T> {
41 pub(crate) fn new() -> TypedWebGLExtensionWrapper<T> {
42 TypedWebGLExtensionWrapper {
43 extension: MutNullableDom::new(None),
44 }
45 }
46}
47
48impl<T> WebGLExtensionWrapper for TypedWebGLExtensionWrapper<T>
49where
50 T: WebGLExtension + JSTraceable + MallocSizeOf + 'static,
51{
52 fn instance_or_init(
53 &self,
54 cx: &mut JSContext,
55 ctx: &WebGLRenderingContext,
56 ext: &WebGLExtensions,
57 mut rval: MutableHandleObject,
58 ) {
59 let mut enabled = true;
60 let extension = self.extension.or_init(|| {
61 enabled = false;
62 T::new(cx, ctx)
63 });
64 if !enabled {
65 self.enable(ext);
66 }
67 rval.set(extension.reflector().get_jsobject().get());
68 }
69
70 fn spec(&self) -> WebGLExtensionSpec {
71 T::spec()
72 }
73
74 fn is_supported(&self, ext: &WebGLExtensions) -> bool {
75 self.is_enabled() || T::is_supported(ext)
76 }
77
78 fn is_enabled(&self) -> bool {
79 self.extension.get().is_some()
80 }
81
82 fn enable(&self, ext: &WebGLExtensions) {
83 T::enable(ext);
84 }
85
86 fn name(&self) -> &'static str {
87 T::name()
88 }
89}