mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Auto merge of #27448 - asajeffrey:script-webgl-texture-ownership, r=jdm
Don't delete GL textures created by WebXR <!-- Please describe your changes on the following line: --> Currently WebGL assumes it owns any WebGLTexture, and deletes the backing GL texture when the object is GC'd. This isn't valid for textures created by a webxr layer manager, which can result in textures being used after they're deleted. --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix #27427 - [x] These changes do not require tests because we don't reftest webxr <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
This commit is contained in:
commit
5831ab8221
2 changed files with 38 additions and 4 deletions
|
@ -29,6 +29,14 @@ pub enum TexParameterValue {
|
|||
Bool(bool),
|
||||
}
|
||||
|
||||
// Textures generated for WebXR are owned by the WebXR device, not by the WebGL thread
|
||||
// so the GL texture should not be deleted when the texture is garbage collected.
|
||||
#[derive(Clone, Copy, Debug, Eq, JSTraceable, MallocSizeOf, PartialEq)]
|
||||
enum WebGLTextureOwner {
|
||||
WebGL,
|
||||
WebXR,
|
||||
}
|
||||
|
||||
const MAX_LEVEL_COUNT: usize = 31;
|
||||
const MAX_FACE_COUNT: usize = 6;
|
||||
|
||||
|
@ -41,6 +49,7 @@ pub struct WebGLTexture {
|
|||
/// The target to which this texture was bound the first time
|
||||
target: Cell<Option<u32>>,
|
||||
is_deleted: Cell<bool>,
|
||||
owner: WebGLTextureOwner,
|
||||
/// Stores information about mipmap levels and cubemap faces.
|
||||
#[ignore_malloc_size_of = "Arrays are cumbersome"]
|
||||
image_info_array: DomRefCell<[Option<ImageInfo>; MAX_LEVEL_COUNT * MAX_FACE_COUNT]>,
|
||||
|
@ -59,12 +68,17 @@ pub struct WebGLTexture {
|
|||
}
|
||||
|
||||
impl WebGLTexture {
|
||||
fn new_inherited(context: &WebGLRenderingContext, id: WebGLTextureId) -> Self {
|
||||
fn new_inherited(
|
||||
context: &WebGLRenderingContext,
|
||||
id: WebGLTextureId,
|
||||
owner: WebGLTextureOwner,
|
||||
) -> Self {
|
||||
Self {
|
||||
webgl_object: WebGLObject::new_inherited(context),
|
||||
id: id,
|
||||
target: Cell::new(None),
|
||||
is_deleted: Cell::new(false),
|
||||
owner: owner,
|
||||
immutable_levels: Cell::new(None),
|
||||
face_count: Cell::new(0),
|
||||
base_mipmap_level: 0,
|
||||
|
@ -87,7 +101,22 @@ impl WebGLTexture {
|
|||
|
||||
pub fn new(context: &WebGLRenderingContext, id: WebGLTextureId) -> DomRoot<Self> {
|
||||
reflect_dom_object(
|
||||
Box::new(WebGLTexture::new_inherited(context, id)),
|
||||
Box::new(WebGLTexture::new_inherited(
|
||||
context,
|
||||
id,
|
||||
WebGLTextureOwner::WebGL,
|
||||
)),
|
||||
&*context.global(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn new_webxr(context: &WebGLRenderingContext, id: WebGLTextureId) -> DomRoot<Self> {
|
||||
reflect_dom_object(
|
||||
Box::new(WebGLTexture::new_inherited(
|
||||
context,
|
||||
id,
|
||||
WebGLTextureOwner::WebXR,
|
||||
)),
|
||||
&*context.global(),
|
||||
)
|
||||
}
|
||||
|
@ -216,6 +245,11 @@ impl WebGLTexture {
|
|||
let _ = fb.detach_texture(self);
|
||||
}
|
||||
|
||||
// We don't delete textures owned by WebXR
|
||||
if self.owner == WebGLTextureOwner::WebXR {
|
||||
return;
|
||||
}
|
||||
|
||||
let cmd = WebGLCommand::DeleteTexture(self.id);
|
||||
match operation_fallibility {
|
||||
Operation::Fallible => context.send_command_ignored(cmd),
|
||||
|
|
|
@ -229,7 +229,7 @@ impl XRWebGLLayer {
|
|||
// TODO: Cache this texture
|
||||
let color_texture_id =
|
||||
WebGLTextureId::maybe_new(sub_images.sub_image.as_ref()?.color_texture)?;
|
||||
let color_texture = WebGLTexture::new(context, color_texture_id);
|
||||
let color_texture = WebGLTexture::new_webxr(context, color_texture_id);
|
||||
let target = self.texture_target();
|
||||
|
||||
// Save the current bindings
|
||||
|
@ -263,7 +263,7 @@ impl XRWebGLLayer {
|
|||
if let Some(id) = sub_images.sub_image.as_ref()?.depth_stencil_texture {
|
||||
// TODO: Cache this texture
|
||||
let depth_stencil_texture_id = WebGLTextureId::maybe_new(id)?;
|
||||
let depth_stencil_texture = WebGLTexture::new(context, depth_stencil_texture_id);
|
||||
let depth_stencil_texture = WebGLTexture::new_webxr(context, depth_stencil_texture_id);
|
||||
framebuffer
|
||||
.texture2d_even_if_opaque(
|
||||
constants::DEPTH_STENCIL_ATTACHMENT,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue