aboutsummaryrefslogtreecommitdiffstats
path: root/components/webgpu/lib.rs
diff options
context:
space:
mode:
authorbors-servo <servo-ops@mozilla.com>2020-07-06 17:45:09 -0400
committerGitHub <noreply@github.com>2020-07-06 17:45:09 -0400
commitec9308199ebf3992ab879e56e4bca44af1ac3c61 (patch)
treed99e7c6d81673b844c058badcbcba1d10bef8d67 /components/webgpu/lib.rs
parent22a7522a045fc1a680c4e8b60ffa8aa4eaadfca9 (diff)
parent9e7e9433e4e9e7038492c32602ec0a8fe239b4fc (diff)
downloadservo-ec9308199ebf3992ab879e56e4bca44af1ac3c61.tar.gz
servo-ec9308199ebf3992ab879e56e4bca44af1ac3c61.zip
Auto merge of #27180 - kunalmohan:segfault, r=kvark
Remove segfaults in WebGPU threads <!-- Please describe your changes on the following line: --> I have also increased the number of staging buffers for presentation. Segfault occurred at 2 places- 1. RenderPipeline descriptor. 2. BufferMapAsync callback. r?@kvark --- <!-- 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 - [ ] These changes fix #___ (GitHub issue number if applicable) <!-- Either: --> - [ ] There are tests for these changes OR - [ ] These changes do not require tests because ___ <!-- 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. -->
Diffstat (limited to 'components/webgpu/lib.rs')
-rw-r--r--components/webgpu/lib.rs77
1 files changed, 41 insertions, 36 deletions
diff --git a/components/webgpu/lib.rs b/components/webgpu/lib.rs
index 5fa867901cd..c0a9d46844b 100644
--- a/components/webgpu/lib.rs
+++ b/components/webgpu/lib.rs
@@ -20,7 +20,8 @@ use servo_config::pref;
use smallvec::SmallVec;
use std::collections::HashMap;
use std::ffi::CString;
-use std::ptr::{self, NonNull};
+use std::ptr;
+use std::rc::Rc;
use std::slice;
use std::sync::{Arc, Mutex};
use std::time::{Duration, Instant};
@@ -38,6 +39,7 @@ use wgpu::{
};
const DEVICE_POLL_INTERVAL: u64 = 100;
+pub const PRESENTATION_BUFFER_COUNT: usize = 10;
#[derive(Debug, Deserialize, Serialize)]
pub enum WebGPUResponse {
@@ -145,7 +147,7 @@ pub enum WebGPURequest {
},
CreateSwapChain {
device_id: id::DeviceId,
- buffer_ids: ArrayVec<[id::BufferId; 5]>,
+ buffer_ids: ArrayVec<[id::BufferId; PRESENTATION_BUFFER_COUNT]>,
external_id: u64,
sender: IpcSender<webrender_api::ImageKey>,
image_desc: webrender_api::ImageDescriptor,
@@ -312,9 +314,9 @@ struct WGPU<'a> {
// Track invalid adapters https://gpuweb.github.io/gpuweb/#invalid
_invalid_adapters: Vec<WebGPUAdapter>,
// Buffers with pending mapping
- buffer_maps: HashMap<id::BufferId, BufferMapInfo<'a, WebGPUResponseResult>>,
+ buffer_maps: HashMap<id::BufferId, Rc<BufferMapInfo<'a, WebGPUResponseResult>>>,
// Presentation Buffers with pending mapping
- present_buffer_maps: HashMap<id::BufferId, BufferMapInfo<'a, WebGPURequest>>,
+ present_buffer_maps: HashMap<id::BufferId, Rc<BufferMapInfo<'a, WebGPURequest>>>,
webrender_api: webrender_api::RenderApi,
webrender_document: webrender_api::DocumentId,
external_images: Arc<Mutex<WebrenderExternalImageRegistry>>,
@@ -374,16 +376,15 @@ impl<'a> WGPU<'a> {
size: (map_range.end - map_range.start) as usize,
external_id: None,
};
- self.buffer_maps.insert(buffer_id, map_info);
+ self.buffer_maps.insert(buffer_id, Rc::new(map_info));
unsafe extern "C" fn callback(
status: BufferMapAsyncStatus,
userdata: *mut u8,
) {
- let nonnull_info =
- NonNull::new(userdata as *mut BufferMapInfo<WebGPUResponseResult>)
- .unwrap();
- let info = nonnull_info.as_ref();
+ let info = Rc::from_raw(
+ userdata as *const BufferMapInfo<WebGPUResponseResult>,
+ );
match status {
BufferMapAsyncStatus::Success => {
let global = &info.global;
@@ -406,7 +407,7 @@ impl<'a> WGPU<'a> {
host: host_map,
callback,
user_data: convert_to_pointer(
- self.buffer_maps.get(&buffer_id).unwrap(),
+ self.buffer_maps.get(&buffer_id).unwrap().clone(),
),
};
let global = &self.global;
@@ -579,6 +580,19 @@ impl<'a> WGPU<'a> {
},
None => None,
};
+
+ let vert_buffers = vertex_state
+ .1
+ .iter()
+ .map(|&(array_stride, step_mode, ref attributes)| {
+ wgpu_core::pipeline::VertexBufferLayoutDescriptor {
+ array_stride,
+ step_mode,
+ attributes_length: attributes.len(),
+ attributes: attributes.as_ptr(),
+ }
+ })
+ .collect::<Vec<_>>();
let descriptor = wgpu_core::pipeline::RenderPipelineDescriptor {
layout: pipeline_layout_id,
vertex_stage: wgpu_core::pipeline::ProgrammableStageDescriptor {
@@ -598,19 +612,7 @@ impl<'a> WGPU<'a> {
vertex_state: wgpu_core::pipeline::VertexStateDescriptor {
index_format: vertex_state.0,
vertex_buffers_length: vertex_state.1.len(),
- vertex_buffers: vertex_state
- .1
- .iter()
- .map(|buffer| {
- wgpu_core::pipeline::VertexBufferLayoutDescriptor {
- array_stride: buffer.0,
- step_mode: buffer.1,
- attributes_length: buffer.2.len(),
- attributes: buffer.2.as_ptr(),
- }
- })
- .collect::<Vec<_>>()
- .as_ptr(),
+ vertex_buffers: vert_buffers.as_ptr(),
},
sample_count,
sample_mask,
@@ -667,8 +669,12 @@ impl<'a> WGPU<'a> {
data: vec![255; (buffer_stride * height as u32) as usize],
size: Size2D::new(width, height),
unassigned_buffer_ids: buffer_ids,
- available_buffer_ids: ArrayVec::<[id::BufferId; 5]>::new(),
- queued_buffer_ids: ArrayVec::<[id::BufferId; 5]>::new(),
+ available_buffer_ids: ArrayVec::<
+ [id::BufferId; PRESENTATION_BUFFER_COUNT],
+ >::new(),
+ queued_buffer_ids: ArrayVec::<
+ [id::BufferId; PRESENTATION_BUFFER_COUNT],
+ >::new(),
buffer_stride,
image_key,
image_desc,
@@ -952,15 +958,14 @@ impl<'a> WGPU<'a> {
size: buffer_size as usize,
external_id: Some(external_id),
};
- self.present_buffer_maps.insert(buffer_id, map_info);
+ self.present_buffer_maps
+ .insert(buffer_id, Rc::new(map_info));
unsafe extern "C" fn callback(
status: BufferMapAsyncStatus,
userdata: *mut u8,
) {
- let nonnull_info =
- NonNull::new(userdata as *mut BufferMapInfo<WebGPURequest>)
- .unwrap();
- let info = nonnull_info.as_ref();
+ let info =
+ Rc::from_raw(userdata as *const BufferMapInfo<WebGPURequest>);
match status {
BufferMapAsyncStatus::Success => {
if let Err(e) =
@@ -980,7 +985,7 @@ impl<'a> WGPU<'a> {
host: HostMap::Read,
callback,
user_data: convert_to_pointer(
- self.present_buffer_maps.get(&buffer_id).unwrap(),
+ self.present_buffer_maps.get(&buffer_id).unwrap().clone(),
),
};
gfx_select!(buffer_id => global.buffer_map_async(buffer_id, 0..buffer_size, map_op));
@@ -1072,8 +1077,8 @@ impl<'a> WGPU<'a> {
}
}
-fn convert_to_pointer<T: Sized>(obj: &T) -> *mut u8 {
- (obj as *const T) as *mut u8
+fn convert_to_pointer<T: Sized>(obj: Rc<T>) -> *mut u8 {
+ Rc::into_raw(obj) as *mut u8
}
macro_rules! webgpu_resource {
@@ -1150,9 +1155,9 @@ pub struct PresentationData {
queue_id: id::QueueId,
pub data: Vec<u8>,
pub size: Size2D<i32>,
- unassigned_buffer_ids: ArrayVec<[id::BufferId; 5]>,
- available_buffer_ids: ArrayVec<[id::BufferId; 5]>,
- queued_buffer_ids: ArrayVec<[id::BufferId; 5]>,
+ unassigned_buffer_ids: ArrayVec<[id::BufferId; PRESENTATION_BUFFER_COUNT]>,
+ available_buffer_ids: ArrayVec<[id::BufferId; PRESENTATION_BUFFER_COUNT]>,
+ queued_buffer_ids: ArrayVec<[id::BufferId; PRESENTATION_BUFFER_COUNT]>,
buffer_stride: u32,
image_key: webrender_api::ImageKey,
image_desc: webrender_api::ImageDescriptor,