Skip to content
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

Implement GLContextDispatcher trait for NativeGLContexts #432

Merged
merged 1 commit into from Oct 18, 2016
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -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;
@@ -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)
}
}
@@ -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>,
@@ -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>>>>

This comment has been minimized.

Copy link
@emilio

emilio Oct 5, 2016

Member

Probably an option of an arc is a better Idea?

This comment has been minimized.

Copy link
@MortimerGoro

MortimerGoro Oct 5, 2016

Author Contributor

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

This comment has been minimized.

Copy link
@emilio

emilio Oct 5, 2016

Member

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

}

impl RenderBackend {
@@ -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);
@@ -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
}
}

@@ -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) => {
@@ -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);
}
}

@@ -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;
@@ -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 {
@@ -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
@@ -607,7 +612,8 @@ impl Renderer {
context_handle,
config,
debug,
enable_recording);
enable_recording,
backend_main_thread_dispatcher);
backend.run();
});

@@ -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();
@@ -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)
@@ -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"
@@ -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);

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.