gfx: Take advantage of Apple extensions to DMA layers on the Mac.

We have 60 FPS window resizing now.
This commit is contained in:
Patrick Walton 2012-10-18 21:09:30 -07:00
parent ac9764d3ef
commit 4f79822628
7 changed files with 34 additions and 15 deletions

@ -1 +1 @@
Subproject commit 8b179c7470984e5544ee3b8c47f654f7c897f88e
Subproject commit 90a617d9139b505b0fb03838a62a41887d658904

@ -1 +1 @@
Subproject commit 18beb006b719100421c24c634386df15f7fbf6bd
Subproject commit bb99acf0c7351b5e086fbd9e225d64fec3ea7e39

View file

@ -9,7 +9,11 @@ struct LayerBuffer {
cairo_surface: ImageSurface,
draw_target: DrawTarget,
size: Size2D<uint>
size: Size2D<uint>,
// NB: stride is in pixels, like OpenGL GL_UNPACK_ROW_LENGTH.
stride: uint
}
/**

View file

@ -54,7 +54,8 @@ pub fn PngCompositor(output: Chan<~[u8]>) -> PngCompositor {
let layer_buffer = LayerBuffer {
cairo_surface: cairo_surface.clone(),
draw_target: move draw_target,
size: Size2D(800u, 600u)
size: Size2D(800u, 600u),
stride: 800
};
let layer_buffer = Cell(move layer_buffer);

View file

@ -22,14 +22,24 @@ pub fn render_layers(layer: &RenderLayer,
let mut buffer = move buffer;
if buffer.size != layer.size {
// Create a new buffer.
// Round the width up the nearest 32 pixels for DMA on the Mac.
let mut stride = layer.size.width;
if stride % 32 != 0 {
stride = (stride & !(32 - 1)) + 32;
}
assert stride % 32 == 0;
assert stride >= layer.size.width;
let cairo_surface = ImageSurface(CAIRO_FORMAT_RGB24,
layer.size.width as c_int,
stride as c_int,
layer.size.height as c_int);
let draw_target = DrawTarget(&cairo_surface);
buffer = LayerBuffer {
cairo_surface: move cairo_surface,
draw_target: move draw_target,
size: copy layer.size
size: copy layer.size,
stride: stride
};
}

View file

@ -84,7 +84,8 @@ impl<C: Compositor Send> Renderer<C> {
let layer_buffer = layer_buffer_cell.take();
let layer_buffer_channel = layer_buffer_channel_cell.take();
let layer_buffer = for render_layers(&render_layer, move layer_buffer) |render_layer, layer_buffer| {
let layer_buffer = for render_layers(&render_layer, move layer_buffer)
|render_layer, layer_buffer| {
let ctx = RenderContext {
canvas: layer_buffer,
font_cache: self.font_cache

View file

@ -56,13 +56,13 @@ fn OSMain(dom_event_chan: pipes::SharedChan<Event>) -> OSMain {
/// Cairo surface wrapping to work with layers
struct CairoSurfaceImageData {
cairo_surface: ImageSurface
cairo_surface: ImageSurface,
size: Size2D<uint>
}
impl CairoSurfaceImageData : layers::layers::ImageData {
fn size() -> Size2D<uint> {
Size2D(self.cairo_surface.width() as uint, self.cairo_surface.height() as uint)
}
fn size() -> Size2D<uint> { self.size }
fn stride() -> uint { self.cairo_surface.width() as uint }
fn format() -> layers::layers::Format { layers::layers::ARGB32Format }
fn with_data(f: layers::layers::WithDataFn) { f(self.cairo_surface.data()) }
}
@ -92,7 +92,7 @@ fn mainloop(mode: Mode, po: comm::Port<Msg>, dom_event_chan: pipes::SharedChan<E
let context = layers::rendergl::init_render_context();
let image_data = @layers::layers::BasicImageData::new(
Size2D(0u, 0u), layers::layers::RGB24Format, ~[]);
Size2D(0u, 0u), 0, layers::layers::RGB24Format, ~[]);
let image = @layers::layers::Image::new(image_data as @layers::layers::ImageData);
let image_layer = @layers::layers::ImageLayer(image);
let original_layer_transform = image_layer.common.transform;
@ -130,7 +130,8 @@ fn mainloop(mode: Mode, po: comm::Port<Msg>, dom_event_chan: pipes::SharedChan<E
let height = surfaces.front.layer_buffer.size.height as uint;
let image_data = @CairoSurfaceImageData {
cairo_surface: surfaces.front.layer_buffer.cairo_surface.clone()
cairo_surface: surfaces.front.layer_buffer.cairo_surface.clone(),
size: Size2D(width, height)
};
let image = @layers::layers::Image::new(
image_data as @layers::layers::ImageData);
@ -217,7 +218,8 @@ fn lend_surface(surfaces: &SurfaceSet, receiver: pipes::Chan<LayerBuffer>) {
let layer_buffer = LayerBuffer {
cairo_surface: surfaces.front.layer_buffer.cairo_surface.clone(),
draw_target: azure_hl::clone_mutable_draw_target(draw_target_ref),
size: copy surfaces.front.layer_buffer.size
size: copy surfaces.front.layer_buffer.size,
stride: surfaces.front.layer_buffer.stride
};
#debug("osmain: lending surface %?", layer_buffer);
receiver.send(move layer_buffer);
@ -256,7 +258,8 @@ fn Surface() -> Surface {
let layer_buffer = LayerBuffer {
cairo_surface: move cairo_surface,
draw_target: move draw_target,
size: Size2D(800u, 600u)
size: Size2D(800u, 600u),
stride: 800
};
Surface { layer_buffer: move layer_buffer, have: true }
}