mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-22 09:45:41 +00:00
servo: Use a better protocol between renderer and osmain
Source-Repo: https://github.com/servo/servo Source-Revision: 09694fe58fd666bbea908337c07c6f9991acb4bb
This commit is contained in:
parent
e252fca5f5
commit
079867a7f6
@ -4,26 +4,25 @@ import comm::*;
|
||||
import layout::display_list::*;
|
||||
|
||||
enum msg {
|
||||
draw(display_list),
|
||||
render(display_list),
|
||||
exit(comm::chan<()>)
|
||||
}
|
||||
|
||||
fn renderer(osmain: chan<osmain::msg>) -> chan<msg> {
|
||||
task::spawn_listener::<msg> {|po|
|
||||
listen {|draw_target_ch|
|
||||
osmain.send(osmain::get_draw_target(draw_target_ch));
|
||||
let draw_target = draw_target_ch.recv();
|
||||
#debug("renderer: beginning rendering loop");
|
||||
osmain.send(osmain::begin_drawing(draw_target_ch));
|
||||
|
||||
loop {
|
||||
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);
|
||||
|
||||
listen {|draw_ch|
|
||||
osmain.send(osmain::draw(draw_ch));
|
||||
draw_ch.recv();
|
||||
}
|
||||
#debug("renderer: returning surface");
|
||||
osmain.send(osmain::draw(draw_target_ch, draw_target));
|
||||
}
|
||||
exit(response_ch) {
|
||||
response_ch.send(());
|
||||
|
@ -33,7 +33,7 @@ fn layout(renderer: chan<renderer::msg>) -> chan<msg> {
|
||||
let box = layout_dom(dom);
|
||||
let dlist = build_display_list(box);
|
||||
|
||||
send(renderer, gfx::renderer::draw(dlist));
|
||||
send(renderer, gfx::renderer::render(dlist));
|
||||
}
|
||||
exit {
|
||||
break;
|
||||
@ -54,18 +54,18 @@ fn build_display_list(_box: @base::box) -> display_list::display_list {
|
||||
display_item({
|
||||
item_type: solid_color,
|
||||
bounds: geom::box(
|
||||
int_to_au(r.next() as int % 800),
|
||||
int_to_au(r.next() as int % 600),
|
||||
int_to_au(100),
|
||||
int_to_au(100))
|
||||
int_to_au(r.next() as int % 800 - 100),
|
||||
int_to_au(r.next() as int % 600 - 100),
|
||||
int_to_au(200),
|
||||
int_to_au(200))
|
||||
}),
|
||||
display_item({
|
||||
item_type: solid_color,
|
||||
bounds: geom::box(
|
||||
int_to_au(100),
|
||||
int_to_au(100),
|
||||
int_to_au(100),
|
||||
int_to_au(100))
|
||||
int_to_au(r.next() as int % 800 - 100),
|
||||
int_to_au(r.next() as int % 600 - 100),
|
||||
int_to_au(200),
|
||||
int_to_au(200))
|
||||
})
|
||||
]
|
||||
}
|
@ -2,9 +2,9 @@ import comm::*;
|
||||
import azure::cairo::cairo_surface_t;
|
||||
|
||||
enum msg {
|
||||
get_draw_target(chan<AzDrawTargetRef>),
|
||||
begin_drawing(chan<AzDrawTargetRef>),
|
||||
draw(chan<AzDrawTargetRef>, AzDrawTargetRef),
|
||||
add_key_handler(chan<()>),
|
||||
draw(chan<()>),
|
||||
exit
|
||||
}
|
||||
|
||||
@ -31,7 +31,7 @@ fn mainloop(po: port<msg>) {
|
||||
[sdl::video::doublebuf]);
|
||||
assert !ptr::is_null(screen);
|
||||
|
||||
let surface = mk_surface();
|
||||
let surfaces = surface_set();
|
||||
|
||||
loop {
|
||||
sdl::event::poll_event {|event|
|
||||
@ -51,37 +51,85 @@ fn mainloop(po: port<msg>) {
|
||||
add_key_handler(key_ch) {
|
||||
key_handlers += [key_ch];
|
||||
}
|
||||
get_draw_target(response_ch) {
|
||||
response_ch.send(copy(surface.az_target));
|
||||
begin_drawing(sender) {
|
||||
lend_surface(surfaces, sender);
|
||||
}
|
||||
draw(response_ch) {
|
||||
sdl::video::unlock_surface(surface.sdl_surf);
|
||||
sdl::video::blit_surface(surface.sdl_surf, ptr::null(),
|
||||
draw(sender, dt) {
|
||||
return_surface(surfaces, dt);
|
||||
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());
|
||||
sdl::video::lock_surface(surface.sdl_surf);
|
||||
sdl::video::lock_surface(sdl_surf);
|
||||
sdl::video::flip(screen);
|
||||
response_ch.send(());
|
||||
}
|
||||
exit { break; }
|
||||
}
|
||||
}
|
||||
}
|
||||
destroy_surface(surface);
|
||||
destroy_surface(surfaces.s1.surf);
|
||||
destroy_surface(surfaces.s2.surf);
|
||||
sdl::quit();
|
||||
}
|
||||
|
||||
#[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)
|
||||
type surface_set = {
|
||||
mut s1: {
|
||||
surf: surface,
|
||||
have: bool
|
||||
},
|
||||
mut s2: {
|
||||
surf: surface,
|
||||
have: bool
|
||||
}
|
||||
};
|
||||
task::set_opts(builder, opts);
|
||||
ret task::run_listener(builder, f);
|
||||
|
||||
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
|
||||
};
|
||||
// But we (hopefully) have another!
|
||||
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 = {
|
||||
@ -129,6 +177,20 @@ fn destroy_surface(surface: surface) {
|
||||
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")]
|
||||
mod platform {
|
||||
fn runmain(f: fn()) {
|
||||
|
Loading…
Reference in New Issue
Block a user