aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2012-05-03 22:09:47 -0700
committerBrian Anderson <banderson@mozilla.com>2012-05-03 22:09:47 -0700
commit09694fe58fd666bbea908337c07c6f9991acb4bb (patch)
treefdb868b25859942c2a1900bc944528a9129de92e /src
parent04575529ade33e2a16e9ac4b3161484ed81f9448 (diff)
downloadservo-09694fe58fd666bbea908337c07c6f9991acb4bb.tar.gz
servo-09694fe58fd666bbea908337c07c6f9991acb4bb.zip
Use a better protocol between renderer and osmain
Diffstat (limited to 'src')
-rw-r--r--src/servo/gfx/renderer.rs21
-rw-r--r--src/servo/layout/layout.rs18
-rw-r--r--src/servo/platform/osmain.rs106
3 files changed, 103 insertions, 42 deletions
diff --git a/src/servo/gfx/renderer.rs b/src/servo/gfx/renderer.rs
index 34a42aec65b..3fe50ee6c7a 100644
--- a/src/servo/gfx/renderer.rs
+++ b/src/servo/gfx/renderer.rs
@@ -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(());
diff --git a/src/servo/layout/layout.rs b/src/servo/layout/layout.rs
index 0c81ec6b379..788c1357c26 100644
--- a/src/servo/layout/layout.rs
+++ b/src/servo/layout/layout.rs
@@ -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))
})
]
} \ No newline at end of file
diff --git a/src/servo/platform/osmain.rs b/src/servo/platform/osmain.rs
index 9c7363175d6..29fad044278 100644
--- a/src/servo/platform/osmain.rs
+++ b/src/servo/platform/osmain.rs
@@ -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
+ }
+};
+
+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
};
- task::set_opts(builder, opts);
- ret task::run_listener(builder, f);
+}
+
+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()) {