use deno_core::op2;
use deno_core::OpState;
#[cfg(feature = "webgl-render")]
use crate::canvas::webgl_render::WebGLContext;
#[cfg(feature = "webgl-render")]
use std::collections::HashMap;
pub struct WebGLState {
#[cfg(feature = "webgl-render")]
contexts: HashMap<i32, WebGLContext>,
#[cfg(feature = "webgl-render")]
next_id: i32,
available: bool,
}
impl Default for WebGLState {
fn default() -> Self {
Self::new()
}
}
impl WebGLState {
pub fn new() -> Self {
Self {
#[cfg(feature = "webgl-render")]
contexts: HashMap::new(),
#[cfg(feature = "webgl-render")]
next_id: 1,
available: cfg!(feature = "webgl-render"),
}
}
}
#[op2(fast)]
pub fn op_webgl_available(state: &mut OpState) -> bool {
let state = state.borrow::<WebGLState>();
state.available
}
#[op2(fast)]
#[smi]
pub fn op_webgl_create_context(
_state: &mut OpState,
#[smi] _width: i32,
#[smi] _height: i32,
#[bigint] _canvas_seed: u64,
) -> i32 {
let _state = _state.borrow_mut::<WebGLState>();
#[cfg(feature = "webgl-render")]
{
if let Some(ctx) = WebGLContext::new(_width as u32, _height as u32, _canvas_seed) {
let id = _state.next_id;
_state.next_id += 1;
_state.contexts.insert(id, ctx);
return id;
}
}
-1
}
#[op2(fast)]
#[smi]
pub fn op_webgl_create_shader(
_state: &mut OpState,
#[smi] _ctx_id: i32,
#[smi] _shader_type: u32,
) -> i32 {
let _state = _state.borrow_mut::<WebGLState>();
#[cfg(feature = "webgl-render")]
if let Some(ctx) = _state.contexts.get_mut(&_ctx_id) {
return ctx.create_shader(_shader_type) as i32;
}
0
}
#[op2(fast)]
pub fn op_webgl_shader_source(
_state: &mut OpState,
#[smi] _ctx_id: i32,
#[smi] _shader_id: i32,
#[string] _source: &str,
) {
let _state = _state.borrow_mut::<WebGLState>();
#[cfg(feature = "webgl-render")]
if let Some(ctx) = _state.contexts.get_mut(&_ctx_id) {
ctx.shader_source(_shader_id as u32, _source);
}
}
#[op2(fast)]
pub fn op_webgl_compile_shader(_state: &mut OpState, #[smi] _ctx_id: i32, #[smi] _shader_id: i32) {
let _state = _state.borrow_mut::<WebGLState>();
#[cfg(feature = "webgl-render")]
if let Some(ctx) = _state.contexts.get_mut(&_ctx_id) {
ctx.compile_shader(_shader_id as u32);
}
}
#[op2(fast)]
#[smi]
pub fn op_webgl_get_shader_parameter(
_state: &mut OpState,
#[smi] _ctx_id: i32,
#[smi] _shader_id: i32,
#[smi] _pname: u32,
) -> i32 {
let _state = _state.borrow::<WebGLState>();
#[cfg(feature = "webgl-render")]
if let Some(ctx) = _state.contexts.get(&_ctx_id) {
return ctx.get_shader_parameter(_shader_id as u32, _pname);
}
1 }
#[op2(fast)]
#[smi]
pub fn op_webgl_create_program(_state: &mut OpState, #[smi] _ctx_id: i32) -> i32 {
let _state = _state.borrow_mut::<WebGLState>();
#[cfg(feature = "webgl-render")]
if let Some(ctx) = _state.contexts.get_mut(&_ctx_id) {
return ctx.create_program() as i32;
}
0
}
#[op2(fast)]
pub fn op_webgl_attach_shader(
_state: &mut OpState,
#[smi] _ctx_id: i32,
#[smi] _program_id: i32,
#[smi] _shader_id: i32,
) {
let _state = _state.borrow::<WebGLState>();
#[cfg(feature = "webgl-render")]
if let Some(ctx) = _state.contexts.get(&_ctx_id) {
ctx.attach_shader(_program_id as u32, _shader_id as u32);
}
}
#[op2(fast)]
pub fn op_webgl_link_program(_state: &mut OpState, #[smi] _ctx_id: i32, #[smi] _program_id: i32) {
let _state = _state.borrow::<WebGLState>();
#[cfg(feature = "webgl-render")]
if let Some(ctx) = _state.contexts.get(&_ctx_id) {
ctx.link_program(_program_id as u32);
}
}
#[op2(fast)]
pub fn op_webgl_use_program(_state: &mut OpState, #[smi] _ctx_id: i32, #[smi] _program_id: i32) {
let _state = _state.borrow::<WebGLState>();
#[cfg(feature = "webgl-render")]
if let Some(ctx) = _state.contexts.get(&_ctx_id) {
ctx.use_program(_program_id as u32);
}
}
#[op2(fast)]
#[smi]
pub fn op_webgl_create_buffer(_state: &mut OpState, #[smi] _ctx_id: i32) -> i32 {
let _state = _state.borrow_mut::<WebGLState>();
#[cfg(feature = "webgl-render")]
if let Some(ctx) = _state.contexts.get_mut(&_ctx_id) {
return ctx.create_buffer() as i32;
}
0
}
#[op2(fast)]
pub fn op_webgl_bind_buffer(
_state: &mut OpState,
#[smi] _ctx_id: i32,
#[smi] _target: u32,
#[smi] _buffer_id: i32,
) {
let _state = _state.borrow::<WebGLState>();
#[cfg(feature = "webgl-render")]
if let Some(ctx) = _state.contexts.get(&_ctx_id) {
ctx.bind_buffer(_target, _buffer_id as u32);
}
}
#[op2(fast)]
pub fn op_webgl_draw_arrays(
_state: &mut OpState,
#[smi] _ctx_id: i32,
#[smi] _mode: u32,
#[smi] _first: i32,
#[smi] _count: i32,
) {
let _state = _state.borrow::<WebGLState>();
#[cfg(feature = "webgl-render")]
if let Some(ctx) = _state.contexts.get(&_ctx_id) {
ctx.draw_arrays(_mode, _first, _count);
}
}
#[op2(fast)]
pub fn op_webgl_clear_color(
_state: &mut OpState,
#[smi] _ctx_id: i32,
_r: f64,
_g: f64,
_b: f64,
_a: f64,
) {
let _state = _state.borrow::<WebGLState>();
#[cfg(feature = "webgl-render")]
if let Some(ctx) = _state.contexts.get(&_ctx_id) {
ctx.clear_color(_r as f32, _g as f32, _b as f32, _a as f32);
}
}
#[op2(fast)]
pub fn op_webgl_clear(_state: &mut OpState, #[smi] _ctx_id: i32, #[smi] _mask: u32) {
let _state = _state.borrow::<WebGLState>();
#[cfg(feature = "webgl-render")]
if let Some(ctx) = _state.contexts.get(&_ctx_id) {
ctx.clear(_mask);
}
}
#[op2(fast)]
pub fn op_webgl_viewport(
_state: &mut OpState,
#[smi] _ctx_id: i32,
#[smi] _x: i32,
#[smi] _y: i32,
#[smi] _w: i32,
#[smi] _h: i32,
) {
let _state = _state.borrow::<WebGLState>();
#[cfg(feature = "webgl-render")]
if let Some(ctx) = _state.contexts.get(&_ctx_id) {
ctx.viewport(_x, _y, _w, _h);
}
}
#[op2]
#[serde]
pub fn op_webgl_read_pixels(
_state: &mut OpState,
#[smi] _ctx_id: i32,
#[smi] _x: i32,
#[smi] _y: i32,
#[smi] _w: i32,
#[smi] _h: i32,
#[smi] _format: u32,
#[smi] _type: u32,
) -> Vec<u8> {
let _state = _state.borrow::<WebGLState>();
#[cfg(feature = "webgl-render")]
if let Some(ctx) = _state.contexts.get(&_ctx_id) {
return ctx.read_pixels(_x, _y, _w, _h, _format, _type);
}
vec![]
}
#[op2(fast)]
pub fn op_webgl_enable(_state: &mut OpState, #[smi] _ctx_id: i32, #[smi] _cap: u32) {
let _state = _state.borrow::<WebGLState>();
#[cfg(feature = "webgl-render")]
if let Some(ctx) = _state.contexts.get(&_ctx_id) {
ctx.enable(_cap);
}
}
#[op2(fast)]
pub fn op_webgl_disable(_state: &mut OpState, #[smi] _ctx_id: i32, #[smi] _cap: u32) {
let _state = _state.borrow::<WebGLState>();
#[cfg(feature = "webgl-render")]
if let Some(ctx) = _state.contexts.get(&_ctx_id) {
ctx.disable(_cap);
}
}
#[op2(fast)]
#[smi]
pub fn op_webgl_get_error(_state: &mut OpState, #[smi] _ctx_id: i32) -> u32 {
let _state = _state.borrow::<WebGLState>();
#[cfg(feature = "webgl-render")]
if let Some(ctx) = _state.contexts.get(&_ctx_id) {
return ctx.get_error();
}
0 }
deno_core::extension!(
webgl_extension,
ops = [
op_webgl_available,
op_webgl_create_context,
op_webgl_create_shader,
op_webgl_shader_source,
op_webgl_compile_shader,
op_webgl_get_shader_parameter,
op_webgl_create_program,
op_webgl_attach_shader,
op_webgl_link_program,
op_webgl_use_program,
op_webgl_create_buffer,
op_webgl_bind_buffer,
op_webgl_draw_arrays,
op_webgl_clear_color,
op_webgl_clear,
op_webgl_viewport,
op_webgl_read_pixels,
op_webgl_enable,
op_webgl_disable,
op_webgl_get_error,
],
);