Skip to content

Implement GLContextDispatcher trait for NativeGLContexts #432

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 18, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 13 additions & 10 deletions webrender/src/internal_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use fnv::FnvHasher;
use freelist::{FreeListItem, FreeListItemId};
use num_traits::Zero;
use offscreen_gl_context::{NativeGLContext, NativeGLContextHandle};
use offscreen_gl_context::{GLContext, NativeGLContextMethods};
use offscreen_gl_context::{GLContext, NativeGLContextMethods, GLContextDispatcher};
use offscreen_gl_context::{OSMesaContext, OSMesaContextHandle};
use offscreen_gl_context::{ColorAttachmentType, GLContextAttributes, GLLimits};
use profiler::BackendProfileCounters;
Expand Down Expand Up @@ -42,20 +42,23 @@ impl GLContextHandleWrapper {

pub fn new_context(&self,
size: Size2D<i32>,
attributes: GLContextAttributes) -> Result<GLContextWrapper, &'static str> {
attributes: GLContextAttributes,
dispatcher: Option<Box<GLContextDispatcher>>) -> Result<GLContextWrapper, &'static str> {
match *self {
GLContextHandleWrapper::Native(ref handle) => {
let ctx = GLContext::<NativeGLContext>::new(size,
attributes,
ColorAttachmentType::Texture,
Some(handle));
let ctx = GLContext::<NativeGLContext>::new_shared_with_dispatcher(size,
attributes,
ColorAttachmentType::Texture,
Some(handle),
dispatcher);
ctx.map(GLContextWrapper::Native)
}
GLContextHandleWrapper::OSMesa(ref handle) => {
let ctx = GLContext::<OSMesaContext>::new(size,
attributes,
ColorAttachmentType::Texture,
Some(handle));
let ctx = GLContext::<OSMesaContext>::new_shared_with_dispatcher(size,
attributes,
ColorAttachmentType::Texture,
Some(handle),
dispatcher);
ctx.map(GLContextWrapper::OSMesa)
}
}
Expand Down
29 changes: 26 additions & 3 deletions webrender/src/render_backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@ use std::sync::{Arc, Mutex};
use std::sync::mpsc::Sender;
use texture_cache::TextureCache;
use webrender_traits::{ApiMsg, AuxiliaryLists, BuiltDisplayList, IdNamespace};
use webrender_traits::{RenderNotifier, WebGLContextId};
use webrender_traits::{RenderNotifier, WebGLContextId, RenderDispatcher};
use batch::new_id;
use device::TextureId;
use record;
use tiling::FrameBuilderConfig;
use gleam::gl;
use offscreen_gl_context::GLContextDispatcher;

pub struct RenderBackend {
api_rx: IpcReceiver<ApiMsg>,
Expand All @@ -42,6 +43,7 @@ pub struct RenderBackend {
webgl_contexts: HashMap<WebGLContextId, GLContextWrapper>,
current_bound_webgl_context_id: Option<WebGLContextId>,
enable_recording: bool,
main_thread_dispatcher: Arc<Mutex<Option<Box<RenderDispatcher>>>>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably an option of an arc is a better Idea?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used the same type pattern as the one used in RenderNotifier setter

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm... I see why you need this, but it seems unfortunate.

}

impl RenderBackend {
Expand All @@ -56,7 +58,8 @@ impl RenderBackend {
webrender_context_handle: Option<GLContextHandleWrapper>,
config: FrameBuilderConfig,
debug: bool,
enable_recording:bool) -> RenderBackend {
enable_recording:bool,
main_thread_dispatcher: Arc<Mutex<Option<Box<RenderDispatcher>>>>) -> RenderBackend {
let resource_cache = ResourceCache::new(texture_cache,
device_pixel_ratio,
enable_aa);
Expand All @@ -76,6 +79,7 @@ impl RenderBackend {
webgl_contexts: HashMap::new(),
current_bound_webgl_context_id: None,
enable_recording:enable_recording,
main_thread_dispatcher: main_thread_dispatcher
}
}

Expand Down Expand Up @@ -261,7 +265,15 @@ impl RenderBackend {
}
ApiMsg::RequestWebGLContext(size, attributes, tx) => {
if let Some(ref wrapper) = self.webrender_context_handle {
let result = wrapper.new_context(size, attributes);
let dispatcher: Option<Box<GLContextDispatcher>> = if cfg!(target_os = "windows") {
Some(Box::new(WebRenderGLDispatcher {
dispatcher: self.main_thread_dispatcher.clone()
}))
} else {
None
};

let result = wrapper.new_context(size, attributes, dispatcher);

match result {
Ok(ctx) => {
Expand Down Expand Up @@ -417,3 +429,14 @@ impl RenderBackend {
}
}

struct WebRenderGLDispatcher {
dispatcher: Arc<Mutex<Option<Box<RenderDispatcher>>>>
}

impl GLContextDispatcher for WebRenderGLDispatcher {
fn dispatch(&self, f: Box<Fn() + Send>) {
let mut dispatcher = self.dispatcher.lock();
dispatcher.as_mut().unwrap().as_mut().unwrap().dispatch(f);
}
}

19 changes: 17 additions & 2 deletions webrender/src/renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ use texture_cache::{BorderType, TextureCache, TextureInsertOp};
use tiling::{self, Frame, FrameBuilderConfig, GLYPHS_PER_TEXT_RUN, PrimitiveBatchData};
use tiling::{TransformedRectKind, RenderTarget, ClearTile};
use time::precise_time_ns;
use webrender_traits::{ColorF, Epoch, PipelineId, RenderNotifier};
use webrender_traits::{ColorF, Epoch, PipelineId, RenderNotifier, RenderDispatcher};
use webrender_traits::{ImageFormat, RenderApiSender, RendererKind};

pub const BLUR_INFLATION_FACTOR: u32 = 3;
Expand Down Expand Up @@ -362,6 +362,9 @@ pub struct Renderer {
layer_texture: VertexDataTexture,
render_task_texture: VertexDataTexture,
pipeline_epoch_map: HashMap<PipelineId, Epoch, BuildHasherDefault<FnvHasher>>,
/// Used to dispatch functions to the main thread's event loop.
/// Required to allow GLContext sharing in some implementations like WGL.
main_thread_dispatcher: Arc<Mutex<Option<Box<RenderDispatcher>>>>
}

impl Renderer {
Expand Down Expand Up @@ -580,7 +583,9 @@ impl Renderer {

device.end_frame();

let main_thread_dispatcher = Arc::new(Mutex::new(None));
let backend_notifier = notifier.clone();
let backend_main_thread_dispatcher = main_thread_dispatcher.clone();

// We need a reference to the webrender context from the render backend in order to share
// texture ids
Expand All @@ -607,7 +612,8 @@ impl Renderer {
context_handle,
config,
debug,
enable_recording);
enable_recording,
backend_main_thread_dispatcher);
backend.run();
});

Expand Down Expand Up @@ -655,6 +661,7 @@ impl Renderer {
layer_texture: layer_texture,
render_task_texture: render_task_texture,
pipeline_epoch_map: HashMap::with_hasher(Default::default()),
main_thread_dispatcher: main_thread_dispatcher
};

renderer.update_uniform_locations();
Expand Down Expand Up @@ -691,6 +698,14 @@ impl Renderer {
*notifier_arc = Some(notifier);
}

/// Sets the new MainThreadDispatcher.
///
/// Allows to dispatch functions to the main thread's event loop.
pub fn set_main_thread_dispatcher(&self, dispatcher: Box<RenderDispatcher>) {
let mut dispatcher_arc = self.main_thread_dispatcher.lock().unwrap();
*dispatcher_arc = Some(dispatcher);
}

/// Returns the Epoch of the current frame in a pipeline.
pub fn current_epoch(&self, pipeline_id: PipelineId) -> Option<Epoch> {
self.pipeline_epoch_map.get(&pipeline_id).map(|epoch| *epoch)
Expand Down
2 changes: 1 addition & 1 deletion webrender_traits/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ byteorder = "0.5"
euclid = "0.10"
gleam = "0.2.22"
heapsize = "0.3.6"
offscreen_gl_context = {version = "0.4.0", features = ["serde_serialization"]}
offscreen_gl_context = {version = "0.4.5", features = ["serde_serialization"]}
serde = "0.8"
serde_derive = {version = "0.8", optional = true}
ipc-channel = "0.5.0"
Expand Down
5 changes: 5 additions & 0 deletions webrender_traits/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,11 @@ pub trait RenderNotifier: Send {
fn pipeline_size_changed(&mut self, pipeline_id: PipelineId, size: Option<Size2D<f32>>);
}

// Trait to allow dispatching functions to a specific thread or event loop.
pub trait RenderDispatcher: Send {
fn dispatch(&self, Box<Fn() + Send>);
}

#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub struct ResourceId(pub u32);

Expand Down