Skip to content

Commit

Permalink
webrender: add selectable channel
Browse files Browse the repository at this point in the history
  • Loading branch information
harryfei committed Aug 16, 2020
1 parent c971af3 commit 8a42d93
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 51 deletions.
82 changes: 82 additions & 0 deletions rust_src/src/webrender_backend/channel.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
use std::{
ffi::CString,
sync::mpsc::{channel, Receiver, SendError, Sender, TryIter},
};

pub struct SelectableSender<T> {
inner_sender: Sender<T>,
raw_fd: i32,
}

impl<T> SelectableSender<T> {
pub fn new(inner_sender: Sender<T>, raw_fd: i32) -> Self {
Self {
inner_sender,
raw_fd,
}
}

pub fn send(&self, message: T) -> Result<(), SendError<T>> {
let ret = self.inner_sender.send(message);

// make raw_fd readable
unsafe {
libc::write(
self.raw_fd,
CString::new("0").unwrap().as_ptr() as *const libc::c_void,
2,
)
};

ret
}
}

pub struct SelectableReceiver<T> {
inner_receiver: Receiver<T>,
raw_fd: i32,
}

impl<T> SelectableReceiver<T> {
pub fn new(inner_receiver: Receiver<T>, raw_fd: i32) -> Self {
Self {
inner_receiver,
raw_fd,
}
}

pub fn get_raw_fd(&self) -> i32 {
self.raw_fd
}

pub fn poll(&self) -> TryIter<T> {
let mut buffer: [i32; 10] = Default::default();

// swallow reaable data on raw_fd
let _ = unsafe {
libc::read(
self.raw_fd,
&mut buffer[0] as *mut _ as *mut libc::c_void,
10,
)
};

self.inner_receiver.try_iter()
}
}

pub fn selectable_channel<T>() -> (SelectableSender<T>, SelectableReceiver<T>) {
let (event_tx, event_rx) = channel::<T>();

let mut pipes: [i32; 2] = [-1, -1];
unsafe {
libc::pipe(&mut pipes[0]);
libc::fcntl(pipes[0], libc::F_SETFL, libc::O_NONBLOCK);
libc::fcntl(pipes[1], libc::F_SETFL, libc::O_NONBLOCK)
};

let receiver = SelectableReceiver::<T>::new(event_rx, pipes[0]);
let sender = SelectableSender::<T>::new(event_tx, pipes[1]);

(sender, receiver)
}
2 changes: 1 addition & 1 deletion rust_src/src/webrender_backend/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub fn create_frame(
let mut output = Box::new(Output::new());
output.set_display_info(dpyinfo);

unsafe { add_keyboard_wait_descriptor(output.keyboard_fd) };
unsafe { add_keyboard_wait_descriptor(output.get_keyboard_fd()) };

// Remeber to destory the Output object when frame destoried.
let output = Box::into_raw(output);
Expand Down
1 change: 1 addition & 0 deletions rust_src/src/webrender_backend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub mod keyboard;
pub mod output;
pub mod term;

mod channel;
mod cursor;
mod draw_canvas;
mod event;
Expand Down
62 changes: 12 additions & 50 deletions rust_src/src/webrender_backend/output.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use std::{
cell::RefCell,
ffi::CString,
rc::Rc,
sync::mpsc::{channel, sync_channel, Receiver, SyncSender},
sync::mpsc::{sync_channel, SyncSender},
thread::JoinHandle,
};

Expand All @@ -27,6 +26,7 @@ use webrender::{self, api::units::*, api::*};

use crate::{lisp::ExternalPtr, remacs_sys::wr_output};

use super::channel::{selectable_channel, SelectableReceiver};
use super::display_info::DisplayInfoRef;
use super::font::FontRef;
use super::texture::TextureResourceManager;
Expand Down Expand Up @@ -61,22 +61,13 @@ pub struct Output {
event_loop_proxy: EventLoopProxy<EmacsGUIEvent>,
color_bits: u8,

pub keyboard_fd: i32,
event_rx: Receiver<GUIEvent>,
event_rx: SelectableReceiver<GUIEvent>,
}

impl Output {
pub fn new() -> Self {
let (
api,
window,
document_id,
loop_thread,
event_loop_proxy,
color_bits,
event_rx,
keyboard_fd,
) = Self::create_webrender_window();
let (api, window, document_id, loop_thread, event_loop_proxy, color_bits, event_rx) =
Self::create_webrender_window();

Self {
output: wr_output::default(),
Expand All @@ -92,7 +83,6 @@ impl Output {
window,
event_loop_proxy,
color_bits,
keyboard_fd,
event_rx,
}
}
Expand All @@ -104,18 +94,11 @@ impl Output {
JoinHandle<()>,
EventLoopProxy<EmacsGUIEvent>,
u8,
std::sync::mpsc::Receiver<GUIEvent>,
i32,
SelectableReceiver<GUIEvent>,
) {
let (webrender_tx, webrender_rx) = sync_channel(1);

let (event_tx, event_rx) = channel::<GUIEvent>();
let mut pipes: [i32; 2] = [-1, -1];
unsafe {
libc::pipe(&mut pipes[0]);
libc::fcntl(pipes[0], libc::F_SETFL, libc::O_NONBLOCK);
libc::fcntl(pipes[1], libc::F_SETFL, libc::O_NONBLOCK)
};
let (event_tx, event_rx) = selectable_channel::<GUIEvent>();

let window_loop_thread = std::thread::spawn(move || {
let events_loop = glutin::event_loop::EventLoop::new_any_thread();
Expand Down Expand Up @@ -236,14 +219,6 @@ impl Output {
current_context.swap_buffers().ok();

event_tx.send(e.to_static().unwrap()).unwrap();

unsafe {
libc::write(
pipes[1],
CString::new("0").unwrap().as_ptr() as *const libc::c_void,
2,
)
};
}

Event::WindowEvent {
Expand All @@ -263,13 +238,6 @@ impl Output {
..
} => {
event_tx.send(e.to_static().unwrap()).unwrap();
unsafe {
libc::write(
pipes[1],
CString::new("0").unwrap().as_ptr() as *const libc::c_void,
2,
)
};
}
Event::UserEvent(EmacsGUIEvent::Flush(sender)) => {
renderer.update();
Expand Down Expand Up @@ -309,7 +277,6 @@ impl Output {
event_loop_proxy,
color_bits,
event_rx,
pipes[0],
)
}

Expand Down Expand Up @@ -529,19 +496,14 @@ impl Output {
where
F: FnMut(GUIEvent),
{
let mut buffer: [i32; 10] = Default::default();

let _ = unsafe {
libc::read(
self.keyboard_fd,
&mut buffer[0] as *mut _ as *mut libc::c_void,
10,
)
};
for e in self.event_rx.try_iter() {
for e in self.event_rx.poll() {
f(e);
}
}

pub fn get_keyboard_fd(&self) -> i32 {
self.event_rx.get_raw_fd()
}
}

pub type OutputRef = ExternalPtr<Output>;
Expand Down

0 comments on commit 8a42d93

Please sign in to comment.