mirror of
https://github.com/servo/servo.git
synced 2025-07-23 15:23:42 +01:00
Use a better protocol between renderer and osmain
This commit is contained in:
parent
04575529ad
commit
09694fe58f
3 changed files with 103 additions and 42 deletions
|
@ -4,26 +4,25 @@ import comm::*;
|
||||||
import layout::display_list::*;
|
import layout::display_list::*;
|
||||||
|
|
||||||
enum msg {
|
enum msg {
|
||||||
draw(display_list),
|
render(display_list),
|
||||||
exit(comm::chan<()>)
|
exit(comm::chan<()>)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn renderer(osmain: chan<osmain::msg>) -> chan<msg> {
|
fn renderer(osmain: chan<osmain::msg>) -> chan<msg> {
|
||||||
task::spawn_listener::<msg> {|po|
|
task::spawn_listener::<msg> {|po|
|
||||||
listen {|draw_target_ch|
|
listen {|draw_target_ch|
|
||||||
osmain.send(osmain::get_draw_target(draw_target_ch));
|
#debug("renderer: beginning rendering loop");
|
||||||
let draw_target = draw_target_ch.recv();
|
osmain.send(osmain::begin_drawing(draw_target_ch));
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
alt po.recv() {
|
alt po.recv() {
|
||||||
draw(display_list) {
|
render(display_list) {
|
||||||
|
#debug("renderer: got render request");
|
||||||
|
let draw_target = draw_target_ch.recv();
|
||||||
|
#debug("renderer: rendering");
|
||||||
draw_display_list(draw_target, display_list);
|
draw_display_list(draw_target, display_list);
|
||||||
|
#debug("renderer: returning surface");
|
||||||
listen {|draw_ch|
|
osmain.send(osmain::draw(draw_target_ch, draw_target));
|
||||||
osmain.send(osmain::draw(draw_ch));
|
|
||||||
draw_ch.recv();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
exit(response_ch) {
|
exit(response_ch) {
|
||||||
response_ch.send(());
|
response_ch.send(());
|
||||||
|
|
|
@ -33,7 +33,7 @@ fn layout(renderer: chan<renderer::msg>) -> chan<msg> {
|
||||||
let box = layout_dom(dom);
|
let box = layout_dom(dom);
|
||||||
let dlist = build_display_list(box);
|
let dlist = build_display_list(box);
|
||||||
|
|
||||||
send(renderer, gfx::renderer::draw(dlist));
|
send(renderer, gfx::renderer::render(dlist));
|
||||||
}
|
}
|
||||||
exit {
|
exit {
|
||||||
break;
|
break;
|
||||||
|
@ -54,18 +54,18 @@ fn build_display_list(_box: @base::box) -> display_list::display_list {
|
||||||
display_item({
|
display_item({
|
||||||
item_type: solid_color,
|
item_type: solid_color,
|
||||||
bounds: geom::box(
|
bounds: geom::box(
|
||||||
int_to_au(r.next() as int % 800),
|
int_to_au(r.next() as int % 800 - 100),
|
||||||
int_to_au(r.next() as int % 600),
|
int_to_au(r.next() as int % 600 - 100),
|
||||||
int_to_au(100),
|
int_to_au(200),
|
||||||
int_to_au(100))
|
int_to_au(200))
|
||||||
}),
|
}),
|
||||||
display_item({
|
display_item({
|
||||||
item_type: solid_color,
|
item_type: solid_color,
|
||||||
bounds: geom::box(
|
bounds: geom::box(
|
||||||
int_to_au(100),
|
int_to_au(r.next() as int % 800 - 100),
|
||||||
int_to_au(100),
|
int_to_au(r.next() as int % 600 - 100),
|
||||||
int_to_au(100),
|
int_to_au(200),
|
||||||
int_to_au(100))
|
int_to_au(200))
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -2,9 +2,9 @@ import comm::*;
|
||||||
import azure::cairo::cairo_surface_t;
|
import azure::cairo::cairo_surface_t;
|
||||||
|
|
||||||
enum msg {
|
enum msg {
|
||||||
get_draw_target(chan<AzDrawTargetRef>),
|
begin_drawing(chan<AzDrawTargetRef>),
|
||||||
|
draw(chan<AzDrawTargetRef>, AzDrawTargetRef),
|
||||||
add_key_handler(chan<()>),
|
add_key_handler(chan<()>),
|
||||||
draw(chan<()>),
|
|
||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ fn mainloop(po: port<msg>) {
|
||||||
[sdl::video::doublebuf]);
|
[sdl::video::doublebuf]);
|
||||||
assert !ptr::is_null(screen);
|
assert !ptr::is_null(screen);
|
||||||
|
|
||||||
let surface = mk_surface();
|
let surfaces = surface_set();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
sdl::event::poll_event {|event|
|
sdl::event::poll_event {|event|
|
||||||
|
@ -51,37 +51,85 @@ fn mainloop(po: port<msg>) {
|
||||||
add_key_handler(key_ch) {
|
add_key_handler(key_ch) {
|
||||||
key_handlers += [key_ch];
|
key_handlers += [key_ch];
|
||||||
}
|
}
|
||||||
get_draw_target(response_ch) {
|
begin_drawing(sender) {
|
||||||
response_ch.send(copy(surface.az_target));
|
lend_surface(surfaces, sender);
|
||||||
}
|
}
|
||||||
draw(response_ch) {
|
draw(sender, dt) {
|
||||||
sdl::video::unlock_surface(surface.sdl_surf);
|
return_surface(surfaces, dt);
|
||||||
sdl::video::blit_surface(surface.sdl_surf, ptr::null(),
|
lend_surface(surfaces, sender);
|
||||||
|
|
||||||
|
#debug("osmain: drawing to screen");
|
||||||
|
assert surfaces.s1.surf.az_target == dt;
|
||||||
|
let sdl_surf = surfaces.s1.surf.sdl_surf;
|
||||||
|
|
||||||
|
sdl::video::unlock_surface(sdl_surf);
|
||||||
|
sdl::video::blit_surface(sdl_surf, ptr::null(),
|
||||||
screen, ptr::null());
|
screen, ptr::null());
|
||||||
sdl::video::lock_surface(surface.sdl_surf);
|
sdl::video::lock_surface(sdl_surf);
|
||||||
sdl::video::flip(screen);
|
sdl::video::flip(screen);
|
||||||
response_ch.send(());
|
|
||||||
}
|
}
|
||||||
exit { break; }
|
exit { break; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
destroy_surface(surface);
|
destroy_surface(surfaces.s1.surf);
|
||||||
|
destroy_surface(surfaces.s2.surf);
|
||||||
sdl::quit();
|
sdl::quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc = "A function for spawning into the platform's main thread"]
|
type surface_set = {
|
||||||
fn on_osmain<T: send>(f: fn~(comm::port<T>)) -> comm::chan<T> {
|
mut s1: {
|
||||||
let builder = task::builder();
|
surf: surface,
|
||||||
let opts = {
|
have: bool
|
||||||
sched: some({
|
},
|
||||||
mode: task::osmain,
|
mut s2: {
|
||||||
native_stack_size: none
|
surf: surface,
|
||||||
})
|
have: bool
|
||||||
with task::get_opts(builder)
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fn lend_surface(surfaces: surface_set, recvr: chan<AzDrawTargetRef>) {
|
||||||
|
// We are in a position to lend out the surface?
|
||||||
|
assert surfaces.s1.have;
|
||||||
|
// Ok then take it
|
||||||
|
let dt1 = surfaces.s1.surf.az_target;
|
||||||
|
#debug("osmain: lending surface %?", dt1);
|
||||||
|
recvr.send(dt1);
|
||||||
|
// Now we don't have it
|
||||||
|
surfaces.s1 = {
|
||||||
|
have: false
|
||||||
|
with surfaces.s1
|
||||||
};
|
};
|
||||||
task::set_opts(builder, opts);
|
// But we (hopefully) have another!
|
||||||
ret task::run_listener(builder, f);
|
surfaces.s1 <-> surfaces.s2;
|
||||||
|
// Let's look
|
||||||
|
assert surfaces.s1.have;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn return_surface(surfaces: surface_set, dt: AzDrawTargetRef) {
|
||||||
|
#debug("osmain: returning surface %?", dt);
|
||||||
|
// We have room for a return
|
||||||
|
assert surfaces.s1.have;
|
||||||
|
assert !surfaces.s2.have;
|
||||||
|
assert surfaces.s2.surf.az_target == dt;
|
||||||
|
// Now we have it again
|
||||||
|
surfaces.s2 = {
|
||||||
|
have: true
|
||||||
|
with surfaces.s2
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn surface_set() -> surface_set {
|
||||||
|
{
|
||||||
|
mut s1: {
|
||||||
|
surf: mk_surface(),
|
||||||
|
have: true
|
||||||
|
},
|
||||||
|
mut s2: {
|
||||||
|
surf: mk_surface(),
|
||||||
|
have: true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type surface = {
|
type surface = {
|
||||||
|
@ -129,6 +177,20 @@ fn destroy_surface(surface: surface) {
|
||||||
sdl::video::free_surface(surface.sdl_surf);
|
sdl::video::free_surface(surface.sdl_surf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[doc = "A function for spawning into the platform's main thread"]
|
||||||
|
fn on_osmain<T: send>(f: fn~(comm::port<T>)) -> comm::chan<T> {
|
||||||
|
let builder = task::builder();
|
||||||
|
let opts = {
|
||||||
|
sched: some({
|
||||||
|
mode: task::osmain,
|
||||||
|
native_stack_size: none
|
||||||
|
})
|
||||||
|
with task::get_opts(builder)
|
||||||
|
};
|
||||||
|
task::set_opts(builder, opts);
|
||||||
|
ret task::run_listener(builder, f);
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
mod platform {
|
mod platform {
|
||||||
fn runmain(f: fn()) {
|
fn runmain(f: fn()) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue