зеркало из https://github.com/mozilla/gecko-dev.git
servo: Use the high-level Cairo API in the compositor. Also modernize the style a bit.
Source-Repo: https://github.com/servo/servo Source-Revision: 39119adb6728499bfd68363c024264c7bd85cc61
This commit is contained in:
Родитель
d9219b69f3
Коммит
612e99c54c
|
@ -69,7 +69,9 @@ fn PngSink(output: chan<~[u8]>) -> PngSink {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_draw(sender: pipes::chan<AzDrawTargetRef>, dt: AzDrawTargetRef, output: chan<~[u8]>,
|
fn do_draw(sender: pipes::chan<AzDrawTargetRef>,
|
||||||
|
dt: AzDrawTargetRef,
|
||||||
|
output: chan<~[u8]>,
|
||||||
cairo_surface: ImageSurface) {
|
cairo_surface: ImageSurface) {
|
||||||
let buffer = io::mem_buffer();
|
let buffer = io::mem_buffer();
|
||||||
cairo_surface.write_to_png_stream(&buffer);
|
cairo_surface.write_to_png_stream(&buffer);
|
||||||
|
|
|
@ -39,12 +39,13 @@ trait Sink {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn Renderer<S: Sink send copy>(sink: S) -> comm::chan<Msg> {
|
fn Renderer<S: Sink send copy>(sink: S) -> comm::chan<Msg> {
|
||||||
task::spawn_listener::<Msg>(|po| {
|
do task::spawn_listener |po: comm::port<Msg>| {
|
||||||
let (draw_target_ch, draw_target_po) = pipes::stream();
|
let (draw_target_ch, draw_target_po) = pipes::stream();
|
||||||
let mut draw_target_ch = draw_target_ch;
|
let mut draw_target_ch = draw_target_ch;
|
||||||
let mut draw_target_po = draw_target_po;
|
let mut draw_target_po = draw_target_po;
|
||||||
|
|
||||||
#debug("renderer: beginning rendering loop");
|
debug!("renderer: beginning rendering loop");
|
||||||
|
|
||||||
sink.begin_drawing(draw_target_ch);
|
sink.begin_drawing(draw_target_ch);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
@ -60,8 +61,10 @@ fn Renderer<S: Sink send copy>(sink: S) -> comm::chan<Msg> {
|
||||||
let mut draw_target_ch = none;
|
let mut draw_target_ch = none;
|
||||||
draw_target_ch_ <-> draw_target_ch;
|
draw_target_ch_ <-> draw_target_ch;
|
||||||
let draw_target_ch = option::unwrap(draw_target_ch);
|
let draw_target_ch = option::unwrap(draw_target_ch);
|
||||||
|
|
||||||
clear(draw_target);
|
clear(draw_target);
|
||||||
draw_display_list(draw_target, display_list);
|
draw_display_list(draw_target, display_list);
|
||||||
|
|
||||||
#debug("renderer: returning surface");
|
#debug("renderer: returning surface");
|
||||||
sink.draw(draw_target_ch, draw_target);
|
sink.draw(draw_target_ch, draw_target);
|
||||||
}
|
}
|
||||||
|
@ -72,7 +75,7 @@ fn Renderer<S: Sink send copy>(sink: S) -> comm::chan<Msg> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trait to_float {
|
trait to_float {
|
||||||
|
|
|
@ -2,9 +2,11 @@ export OSMain;
|
||||||
export Msg, BeginDrawing, Draw, AddKeyHandler, Exit;
|
export Msg, BeginDrawing, Draw, AddKeyHandler, Exit;
|
||||||
|
|
||||||
import azure::*;
|
import azure::*;
|
||||||
|
import azure::azure_hl::DrawTarget;
|
||||||
import azure::bindgen::*;
|
import azure::bindgen::*;
|
||||||
import azure::cairo;
|
import azure::cairo;
|
||||||
import azure::cairo::bindgen::*;
|
import azure::cairo::bindgen::*;
|
||||||
|
import azure::cairo_hl::ImageSurface;
|
||||||
import comm::*;
|
import comm::*;
|
||||||
import dvec::dvec;
|
import dvec::dvec;
|
||||||
import azure::cairo::cairo_surface_t;
|
import azure::cairo::cairo_surface_t;
|
||||||
|
@ -49,7 +51,7 @@ fn mainloop(po: port<Msg>) {
|
||||||
unsafe { let y <- *ptr::addr_of(x); y }]
|
unsafe { let y <- *ptr::addr_of(x); y }]
|
||||||
];
|
];
|
||||||
|
|
||||||
let surfaces = @surface_set();
|
let surfaces = @SurfaceSet();
|
||||||
|
|
||||||
let window = glut::create_window(~"Servo");
|
let window = glut::create_window(~"Servo");
|
||||||
glut::reshape_window(window, 800, 600);
|
glut::reshape_window(window, 800, 600);
|
||||||
|
@ -79,14 +81,8 @@ fn mainloop(po: port<Msg>) {
|
||||||
return_surface(*surfaces, dt);
|
return_surface(*surfaces, dt);
|
||||||
lend_surface(*surfaces, sender);
|
lend_surface(*surfaces, sender);
|
||||||
|
|
||||||
let mut image_data;
|
let buffer = surfaces.front.cairo_surface.data();
|
||||||
unsafe {
|
let image = @layers::layers::Image(800, 600, layers::layers::ARGB32Format, buffer);
|
||||||
let buffer = cairo_image_surface_get_data(surfaces.s1.surf.cairo_surf);
|
|
||||||
image_data = vec::unsafe::from_buf(buffer, 800 * 600 * 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
let image =
|
|
||||||
@layers::layers::Image(800, 600, layers::layers::ARGB32Format, image_data);
|
|
||||||
image_layer.set_image(image);
|
image_layer.set_image(image);
|
||||||
}
|
}
|
||||||
exit => {
|
exit => {
|
||||||
|
@ -122,9 +118,6 @@ fn mainloop(po: port<Msg>) {
|
||||||
#debug("osmain: running GLUT check loop");
|
#debug("osmain: running GLUT check loop");
|
||||||
glut::check_loop();
|
glut::check_loop();
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy_surface(surfaces.s1.surf);
|
|
||||||
destroy_surface(surfaces.s2.surf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc = "
|
#[doc = "
|
||||||
|
@ -143,83 +136,53 @@ impl OSMain : Sink {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type surface_set = {
|
struct SurfaceSet {
|
||||||
mut s1: {
|
mut front: Surface;
|
||||||
surf: surface,
|
mut back: Surface;
|
||||||
have: bool
|
}
|
||||||
},
|
|
||||||
mut s2: {
|
|
||||||
surf: surface,
|
|
||||||
have: bool
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
fn lend_surface(surfaces: surface_set, recvr: pipes::chan<AzDrawTargetRef>) {
|
fn lend_surface(surfaces: SurfaceSet, receiver: pipes::chan<AzDrawTargetRef>) {
|
||||||
// We are in a position to lend out the surface?
|
// We are in a position to lend out the surface?
|
||||||
assert surfaces.s1.have;
|
assert surfaces.front.have;
|
||||||
// Ok then take it
|
// Ok then take it
|
||||||
let dt1 = surfaces.s1.surf.az_target;
|
let draw_target = surfaces.front.draw_target.azure_draw_target;
|
||||||
#debug("osmain: lending surface %?", dt1);
|
#debug("osmain: lending surface %?", draw_target);
|
||||||
recvr.send(dt1);
|
receiver.send(draw_target);
|
||||||
// Now we don't have it
|
// Now we don't have it
|
||||||
surfaces.s1 = {
|
surfaces.front.have = false;
|
||||||
have: false
|
|
||||||
with surfaces.s1
|
|
||||||
};
|
|
||||||
// But we (hopefully) have another!
|
// But we (hopefully) have another!
|
||||||
surfaces.s1 <-> surfaces.s2;
|
surfaces.front <-> surfaces.back;
|
||||||
// Let's look
|
// Let's look
|
||||||
assert surfaces.s1.have;
|
assert surfaces.front.have;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn return_surface(surfaces: surface_set, dt: AzDrawTargetRef) {
|
fn return_surface(surfaces: SurfaceSet, draw_target: AzDrawTargetRef) {
|
||||||
#debug("osmain: returning surface %?", dt);
|
#debug("osmain: returning surface %?", draw_target);
|
||||||
// We have room for a return
|
// We have room for a return
|
||||||
assert surfaces.s1.have;
|
assert surfaces.front.have;
|
||||||
assert !surfaces.s2.have;
|
assert !surfaces.back.have;
|
||||||
assert surfaces.s2.surf.az_target == dt;
|
|
||||||
|
// FIXME: This is incompatible with page resizing.
|
||||||
|
assert surfaces.back.draw_target.azure_draw_target == draw_target;
|
||||||
|
|
||||||
// Now we have it again
|
// Now we have it again
|
||||||
surfaces.s2 = {
|
surfaces.back.have = true;
|
||||||
have: true
|
|
||||||
with surfaces.s2
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn surface_set() -> surface_set {
|
fn SurfaceSet() -> SurfaceSet {
|
||||||
{
|
SurfaceSet { front: Surface(), back: Surface() }
|
||||||
mut s1: {
|
|
||||||
surf: mk_surface(),
|
|
||||||
have: true
|
|
||||||
},
|
|
||||||
mut s2: {
|
|
||||||
surf: mk_surface(),
|
|
||||||
have: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type surface = {
|
struct Surface {
|
||||||
cairo_surf: *cairo_surface_t,
|
cairo_surface: ImageSurface;
|
||||||
az_target: AzDrawTargetRef
|
draw_target: DrawTarget;
|
||||||
};
|
mut have: bool;
|
||||||
|
|
||||||
fn mk_surface() -> surface {
|
|
||||||
let cairo_surf = cairo_image_surface_create(cairo::CAIRO_FORMAT_RGB24, 800, 600);
|
|
||||||
|
|
||||||
assert !ptr::is_null(cairo_surf);
|
|
||||||
|
|
||||||
let azure_target = AzCreateDrawTargetForCairoSurface(cairo_surf);
|
|
||||||
assert !ptr::is_null(azure_target);
|
|
||||||
|
|
||||||
{
|
|
||||||
cairo_surf: cairo_surf,
|
|
||||||
az_target: azure_target
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn destroy_surface(+surface: surface) {
|
fn Surface() -> Surface {
|
||||||
AzReleaseDrawTarget(surface.az_target);
|
let cairo_surface = ImageSurface(cairo::CAIRO_FORMAT_RGB24, 800, 600);
|
||||||
cairo_surface_destroy(surface.cairo_surf);
|
let draw_target = DrawTarget(cairo_surface);
|
||||||
|
Surface { cairo_surface: cairo_surface, draw_target: draw_target, have: true }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc = "A function for spawning into the platform's main thread"]
|
#[doc = "A function for spawning into the platform's main thread"]
|
||||||
|
|
Загрузка…
Ссылка в новой задаче