Skip to content

Commit 3cf4b78

Browse files
committed
Implement GLContextDispatcher trait for NativeGLContexts, r=emilio
1 parent 6882420 commit 3cf4b78

File tree

5 files changed

+62
-16
lines changed

5 files changed

+62
-16
lines changed

webrender/src/internal_types.rs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use fnv::FnvHasher;
99
use freelist::{FreeListItem, FreeListItemId};
1010
use num_traits::Zero;
1111
use offscreen_gl_context::{NativeGLContext, NativeGLContextHandle};
12-
use offscreen_gl_context::{GLContext, NativeGLContextMethods};
12+
use offscreen_gl_context::{GLContext, NativeGLContextMethods, GLContextDispatcher};
1313
use offscreen_gl_context::{OSMesaContext, OSMesaContextHandle};
1414
use offscreen_gl_context::{ColorAttachmentType, GLContextAttributes, GLLimits};
1515
use profiler::BackendProfileCounters;
@@ -42,20 +42,23 @@ impl GLContextHandleWrapper {
4242

4343
pub fn new_context(&self,
4444
size: Size2D<i32>,
45-
attributes: GLContextAttributes) -> Result<GLContextWrapper, &'static str> {
45+
attributes: GLContextAttributes,
46+
dispatcher: Option<Box<GLContextDispatcher>>) -> Result<GLContextWrapper, &'static str> {
4647
match *self {
4748
GLContextHandleWrapper::Native(ref handle) => {
48-
let ctx = GLContext::<NativeGLContext>::new(size,
49-
attributes,
50-
ColorAttachmentType::Texture,
51-
Some(handle));
49+
let ctx = GLContext::<NativeGLContext>::new_shared_with_dispatcher(size,
50+
attributes,
51+
ColorAttachmentType::Texture,
52+
Some(handle),
53+
dispatcher);
5254
ctx.map(GLContextWrapper::Native)
5355
}
5456
GLContextHandleWrapper::OSMesa(ref handle) => {
55-
let ctx = GLContext::<OSMesaContext>::new(size,
56-
attributes,
57-
ColorAttachmentType::Texture,
58-
Some(handle));
57+
let ctx = GLContext::<OSMesaContext>::new_shared_with_dispatcher(size,
58+
attributes,
59+
ColorAttachmentType::Texture,
60+
Some(handle),
61+
dispatcher);
5962
ctx.map(GLContextWrapper::OSMesa)
6063
}
6164
}

webrender/src/render_backend.rs

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@ use std::sync::{Arc, Mutex};
1616
use std::sync::mpsc::Sender;
1717
use texture_cache::TextureCache;
1818
use webrender_traits::{ApiMsg, AuxiliaryLists, BuiltDisplayList, IdNamespace};
19-
use webrender_traits::{RenderNotifier, WebGLContextId};
19+
use webrender_traits::{RenderNotifier, WebGLContextId, RenderDispatcher};
2020
use batch::new_id;
2121
use device::TextureId;
2222
use record;
2323
use tiling::FrameBuilderConfig;
2424
use gleam::gl;
25+
use offscreen_gl_context::GLContextDispatcher;
2526

2627
pub struct RenderBackend {
2728
api_rx: IpcReceiver<ApiMsg>,
@@ -42,6 +43,7 @@ pub struct RenderBackend {
4243
webgl_contexts: HashMap<WebGLContextId, GLContextWrapper>,
4344
current_bound_webgl_context_id: Option<WebGLContextId>,
4445
enable_recording: bool,
46+
main_thread_dispatcher: Arc<Mutex<Option<Box<RenderDispatcher>>>>
4547
}
4648

4749
impl RenderBackend {
@@ -56,7 +58,8 @@ impl RenderBackend {
5658
webrender_context_handle: Option<GLContextHandleWrapper>,
5759
config: FrameBuilderConfig,
5860
debug: bool,
59-
enable_recording:bool) -> RenderBackend {
61+
enable_recording:bool,
62+
main_thread_dispatcher: Arc<Mutex<Option<Box<RenderDispatcher>>>>) -> RenderBackend {
6063
let resource_cache = ResourceCache::new(texture_cache,
6164
device_pixel_ratio,
6265
enable_aa);
@@ -76,6 +79,7 @@ impl RenderBackend {
7679
webgl_contexts: HashMap::new(),
7780
current_bound_webgl_context_id: None,
7881
enable_recording:enable_recording,
82+
main_thread_dispatcher: main_thread_dispatcher
7983
}
8084
}
8185

@@ -261,7 +265,16 @@ impl RenderBackend {
261265
}
262266
ApiMsg::RequestWebGLContext(size, attributes, tx) => {
263267
if let Some(ref wrapper) = self.webrender_context_handle {
264-
let result = wrapper.new_context(size, attributes);
268+
let dispatcher: Option<Box<GLContextDispatcher>>;
269+
if cfg!(target_os = "windows") {
270+
dispatcher = Some(Box::new(WebRenderGLDispatcher {
271+
dispatcher: self.main_thread_dispatcher.clone()
272+
}));
273+
} else {
274+
dispatcher = None;
275+
}
276+
277+
let result = wrapper.new_context(size, attributes, dispatcher);
265278

266279
match result {
267280
Ok(ctx) => {
@@ -417,3 +430,14 @@ impl RenderBackend {
417430
}
418431
}
419432

433+
struct WebRenderGLDispatcher {
434+
dispatcher: Arc<Mutex<Option<Box<RenderDispatcher>>>>
435+
}
436+
437+
impl GLContextDispatcher for WebRenderGLDispatcher {
438+
fn dispatch(&self, f: Box<Fn() + Send>) {
439+
let mut dispatcher = self.dispatcher.lock();
440+
dispatcher.as_mut().unwrap().as_mut().unwrap().dispatch(f);
441+
}
442+
}
443+

webrender/src/renderer.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ use texture_cache::{BorderType, TextureCache, TextureInsertOp};
3838
use tiling::{self, Frame, FrameBuilderConfig, GLYPHS_PER_TEXT_RUN, PrimitiveBatchData};
3939
use tiling::{TransformedRectKind, RenderTarget, ClearTile};
4040
use time::precise_time_ns;
41-
use webrender_traits::{ColorF, Epoch, PipelineId, RenderNotifier};
41+
use webrender_traits::{ColorF, Epoch, PipelineId, RenderNotifier, RenderDispatcher};
4242
use webrender_traits::{ImageFormat, RenderApiSender, RendererKind};
4343

4444
pub const BLUR_INFLATION_FACTOR: u32 = 3;
@@ -354,6 +354,7 @@ pub struct Renderer {
354354
layer_texture: VertexDataTexture,
355355
render_task_texture: VertexDataTexture,
356356
pipeline_epoch_map: HashMap<PipelineId, Epoch, BuildHasherDefault<FnvHasher>>,
357+
main_thread_dispatcher: Arc<Mutex<Option<Box<RenderDispatcher>>>>
357358
}
358359

359360
impl Renderer {
@@ -572,7 +573,9 @@ impl Renderer {
572573

573574
device.end_frame();
574575

576+
let main_thread_dispatcher = Arc::new(Mutex::new(None));
575577
let backend_notifier = notifier.clone();
578+
let backend_main_thread_dispatcher = main_thread_dispatcher.clone();
576579

577580
// We need a reference to the webrender context from the render backend in order to share
578581
// texture ids
@@ -599,7 +602,8 @@ impl Renderer {
599602
context_handle,
600603
config,
601604
debug,
602-
enable_recording);
605+
enable_recording,
606+
backend_main_thread_dispatcher);
603607
backend.run();
604608
});
605609

@@ -647,6 +651,7 @@ impl Renderer {
647651
layer_texture: layer_texture,
648652
render_task_texture: render_task_texture,
649653
pipeline_epoch_map: HashMap::with_hasher(Default::default()),
654+
main_thread_dispatcher: main_thread_dispatcher
650655
};
651656

652657
renderer.update_uniform_locations();
@@ -683,6 +688,15 @@ impl Renderer {
683688
*notifier_arc = Some(notifier);
684689
}
685690

691+
/// Sets the new MainThreadDispatcher.
692+
///
693+
/// Used to dispatch functions to the main thread's event loop.
694+
/// Required to allow GLContext sharing in some implementations like WGL.
695+
pub fn set_main_thread_dispatcher(&self, dispatcher: Box<RenderDispatcher>) {
696+
let mut dispatcher_arc = self.main_thread_dispatcher.lock().unwrap();
697+
*dispatcher_arc = Some(dispatcher);
698+
}
699+
686700
/// Returns the Epoch of the current frame in a pipeline.
687701
pub fn current_epoch(&self, pipeline_id: PipelineId) -> Option<Epoch> {
688702
self.pipeline_epoch_map.get(&pipeline_id).map(|epoch| *epoch)

webrender_traits/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ byteorder = "0.5"
1717
euclid = "0.10"
1818
gleam = "0.2.22"
1919
heapsize = "0.3.6"
20-
offscreen_gl_context = {version = "0.4.0", features = ["serde_serialization"]}
20+
offscreen_gl_context = {version = "0.4.5", features = ["serde_serialization"]}
2121
serde = "0.8"
2222
serde_derive = {version = "0.8", optional = true}
2323
ipc-channel = "0.5.0"

webrender_traits/src/types.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,11 @@ pub trait RenderNotifier: Send {
369369
fn pipeline_size_changed(&mut self, pipeline_id: PipelineId, size: Option<Size2D<f32>>);
370370
}
371371

372+
// Trait to allow dispatching functions to a specific thread or event loop.
373+
pub trait RenderDispatcher: Send {
374+
fn dispatch(&self, Box<Fn() + Send>);
375+
}
376+
372377
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
373378
pub struct ResourceId(pub u32);
374379

0 commit comments

Comments
 (0)