mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Add support for some more WebGL2 renderbuffer functions
Adds support for the following WebGL2 calls: - `RenderbufferStorageMultisample` - `GetInternalFormativ` See: https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.5
This commit is contained in:
parent
13a349603d
commit
5eaa9ef8cb
16 changed files with 256 additions and 74 deletions
|
@ -42,7 +42,8 @@ use crate::js::conversions::ToJSValConvertible;
|
|||
use crate::script_runtime::JSContext;
|
||||
use canvas_traits::webgl::WebGLError::*;
|
||||
use canvas_traits::webgl::{
|
||||
webgl_channel, GLContextAttributes, WebGLCommand, WebGLResult, WebGLVersion,
|
||||
webgl_channel, GLContextAttributes, InternalFormatParameter, WebGLCommand, WebGLResult,
|
||||
WebGLVersion,
|
||||
};
|
||||
use dom_struct::dom_struct;
|
||||
use euclid::default::{Point2D, Rect, Size2D};
|
||||
|
@ -51,7 +52,7 @@ use js::jsapi::{JSObject, Type};
|
|||
use js::jsval::{BooleanValue, DoubleValue, Int32Value, UInt32Value};
|
||||
use js::jsval::{JSVal, NullValue, ObjectValue, UndefinedValue};
|
||||
use js::rust::CustomAutoRooterGuard;
|
||||
use js::typedarray::{ArrayBufferView, CreateWith, Float32, Uint32, Uint32Array};
|
||||
use js::typedarray::{ArrayBufferView, CreateWith, Float32, Int32Array, Uint32, Uint32Array};
|
||||
use script_layout_interface::HTMLCanvasDataSource;
|
||||
use std::cell::Cell;
|
||||
use std::cmp;
|
||||
|
@ -3753,6 +3754,60 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
|
|||
None => self.base.webgl_error(InvalidOperation),
|
||||
}
|
||||
}
|
||||
|
||||
/// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.5
|
||||
#[allow(unsafe_code)]
|
||||
fn GetInternalformatParameter(
|
||||
&self,
|
||||
cx: JSContext,
|
||||
target: u32,
|
||||
internal_format: u32,
|
||||
pname: u32,
|
||||
) -> JSVal {
|
||||
if target != constants::RENDERBUFFER {
|
||||
self.base.webgl_error(InvalidEnum);
|
||||
return NullValue();
|
||||
}
|
||||
|
||||
match handle_potential_webgl_error!(
|
||||
self.base,
|
||||
InternalFormatParameter::from_u32(pname),
|
||||
return NullValue()
|
||||
) {
|
||||
InternalFormatParameter::IntVec(param) => unsafe {
|
||||
let (sender, receiver) = webgl_channel().unwrap();
|
||||
self.base
|
||||
.send_command(WebGLCommand::GetInternalFormatIntVec(
|
||||
target,
|
||||
internal_format,
|
||||
param,
|
||||
sender,
|
||||
));
|
||||
|
||||
rooted!(in(*cx) let mut rval = ptr::null_mut::<JSObject>());
|
||||
let _ = Int32Array::create(
|
||||
*cx,
|
||||
CreateWith::Slice(&receiver.recv().unwrap()),
|
||||
rval.handle_mut(),
|
||||
)
|
||||
.unwrap();
|
||||
ObjectValue(rval.get())
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.5
|
||||
fn RenderbufferStorageMultisample(
|
||||
&self,
|
||||
target: u32,
|
||||
samples: i32,
|
||||
internal_format: u32,
|
||||
width: i32,
|
||||
height: i32,
|
||||
) {
|
||||
self.base
|
||||
.renderbuffer_storage(target, samples, internal_format, width, height)
|
||||
}
|
||||
}
|
||||
|
||||
impl LayoutCanvasWebGLRenderingContextHelpers for LayoutDom<WebGL2RenderingContext> {
|
||||
|
|
|
@ -14,7 +14,8 @@ use crate::dom::webglframebuffer::WebGLFramebuffer;
|
|||
use crate::dom::webglobject::WebGLObject;
|
||||
use crate::dom::webglrenderingcontext::WebGLRenderingContext;
|
||||
use canvas_traits::webgl::{
|
||||
webgl_channel, GlType, WebGLCommand, WebGLError, WebGLRenderbufferId, WebGLResult, WebGLVersion,
|
||||
webgl_channel, GlType, InternalFormatIntVec, WebGLCommand, WebGLError, WebGLRenderbufferId,
|
||||
WebGLResult, WebGLVersion,
|
||||
};
|
||||
use dom_struct::dom_struct;
|
||||
use std::cell::Cell;
|
||||
|
@ -133,11 +134,13 @@ impl WebGLRenderbuffer {
|
|||
pub fn storage(
|
||||
&self,
|
||||
api_type: GlType,
|
||||
sample_count: i32,
|
||||
internal_format: u32,
|
||||
width: i32,
|
||||
height: i32,
|
||||
) -> WebGLResult<()> {
|
||||
let is_gles = api_type == GlType::Gles;
|
||||
let webgl_version = self.upcast().context().webgl_version();
|
||||
|
||||
// Validate the internal_format, and save it for completeness
|
||||
// validation.
|
||||
|
@ -173,7 +176,7 @@ impl WebGLRenderbuffer {
|
|||
constants::DEPTH_COMPONENT24 |
|
||||
constants::DEPTH_COMPONENT32F |
|
||||
constants::DEPTH24_STENCIL8 |
|
||||
constants::DEPTH32F_STENCIL8 => match self.upcast().context().webgl_version() {
|
||||
constants::DEPTH32F_STENCIL8 => match webgl_version {
|
||||
WebGLVersion::WebGL1 => return Err(WebGLError::InvalidEnum),
|
||||
_ => internal_format,
|
||||
},
|
||||
|
@ -221,6 +224,22 @@ impl WebGLRenderbuffer {
|
|||
_ => return Err(WebGLError::InvalidEnum),
|
||||
};
|
||||
|
||||
if webgl_version != WebGLVersion::WebGL1 {
|
||||
let (sender, receiver) = webgl_channel().unwrap();
|
||||
self.upcast::<WebGLObject>().context().send_command(
|
||||
WebGLCommand::GetInternalFormatIntVec(
|
||||
constants::RENDERBUFFER,
|
||||
internal_format,
|
||||
InternalFormatIntVec::Samples,
|
||||
sender,
|
||||
),
|
||||
);
|
||||
let samples = receiver.recv().unwrap();
|
||||
if sample_count < 0 || sample_count as usize > samples.len() {
|
||||
return Err(WebGLError::InvalidOperation);
|
||||
}
|
||||
}
|
||||
|
||||
self.internal_format.set(Some(internal_format));
|
||||
self.is_initialized.set(false);
|
||||
|
||||
|
@ -228,17 +247,24 @@ impl WebGLRenderbuffer {
|
|||
fb.update_status();
|
||||
}
|
||||
|
||||
self.upcast::<WebGLObject>()
|
||||
.context()
|
||||
.send_command(WebGLCommand::RenderbufferStorage(
|
||||
let command = match sample_count {
|
||||
0 => WebGLCommand::RenderbufferStorage(
|
||||
constants::RENDERBUFFER,
|
||||
actual_format,
|
||||
width,
|
||||
height,
|
||||
));
|
||||
),
|
||||
_ => WebGLCommand::RenderbufferStorageMultisample(
|
||||
constants::RENDERBUFFER,
|
||||
sample_count,
|
||||
actual_format,
|
||||
width,
|
||||
height,
|
||||
),
|
||||
};
|
||||
self.upcast::<WebGLObject>().context().send_command(command);
|
||||
|
||||
self.size.set(Some((width, height)));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -1476,6 +1476,40 @@ impl WebGLRenderingContext {
|
|||
}
|
||||
slot.set(framebuffer);
|
||||
}
|
||||
|
||||
pub fn renderbuffer_storage(
|
||||
&self,
|
||||
target: u32,
|
||||
samples: i32,
|
||||
internal_format: u32,
|
||||
width: i32,
|
||||
height: i32,
|
||||
) {
|
||||
if target != constants::RENDERBUFFER {
|
||||
return self.webgl_error(InvalidEnum);
|
||||
}
|
||||
|
||||
let max = self.limits.max_renderbuffer_size;
|
||||
|
||||
if samples < 0 || width < 0 || width as u32 > max || height < 0 || height as u32 > max {
|
||||
return self.webgl_error(InvalidValue);
|
||||
}
|
||||
|
||||
let rb = handle_potential_webgl_error!(
|
||||
self,
|
||||
self.bound_renderbuffer.get().ok_or(InvalidOperation),
|
||||
return
|
||||
);
|
||||
handle_potential_webgl_error!(
|
||||
self,
|
||||
rb.storage(self.api_type, samples, internal_format, width, height)
|
||||
);
|
||||
if let Some(fb) = self.bound_draw_framebuffer.get() {
|
||||
fb.invalidate_renderbuffer(&*rb);
|
||||
}
|
||||
|
||||
// FIXME: https://github.com/servo/servo/issues/13710
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "webgl_backtrace"))]
|
||||
|
@ -4336,30 +4370,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
|||
|
||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.7
|
||||
fn RenderbufferStorage(&self, target: u32, internal_format: u32, width: i32, height: i32) {
|
||||
if target != constants::RENDERBUFFER {
|
||||
return self.webgl_error(InvalidEnum);
|
||||
}
|
||||
|
||||
let max = self.limits.max_renderbuffer_size;
|
||||
|
||||
if width < 0 || width as u32 > max || height < 0 || height as u32 > max {
|
||||
return self.webgl_error(InvalidValue);
|
||||
}
|
||||
|
||||
let rb = handle_potential_webgl_error!(
|
||||
self,
|
||||
self.bound_renderbuffer.get().ok_or(InvalidOperation),
|
||||
return
|
||||
);
|
||||
handle_potential_webgl_error!(
|
||||
self,
|
||||
rb.storage(self.api_type, internal_format, width, height)
|
||||
);
|
||||
if let Some(fb) = self.bound_draw_framebuffer.get() {
|
||||
fb.invalidate_renderbuffer(&*rb);
|
||||
}
|
||||
|
||||
// FIXME: https://github.com/servo/servo/issues/13710
|
||||
self.renderbuffer_storage(target, 0, internal_format, width, height)
|
||||
}
|
||||
|
||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6
|
||||
|
|
|
@ -316,9 +316,9 @@ interface mixin WebGL2RenderingContextBase
|
|||
// void readBuffer(GLenum src);
|
||||
|
||||
/* Renderbuffer objects */
|
||||
// any getInternalformatParameter(GLenum target, GLenum internalformat, GLenum pname);
|
||||
// void renderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat,
|
||||
// GLsizei width, GLsizei height);
|
||||
any getInternalformatParameter(GLenum target, GLenum internalformat, GLenum pname);
|
||||
void renderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat,
|
||||
GLsizei width, GLsizei height);
|
||||
|
||||
/* Texture objects */
|
||||
// void texStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue