servo: Merge #6125 - Renderrenderrenderrender: Now for embedding! (from zmike:renderrenderrenderrender); r=larsbergstrom
authorMike Blumenkrantz <zmike@osg.samsung.com>
Sun, 24 May 2015 19:26:00 -0500
changeset 383072 70a005a50b69d1b654db6f3084e3f6002ea0e762
parent 383071 e2687fb0ec2e97a0e9e64c0591a07e3d3bca922c
child 383073 bb860b74e3b56275980aebf6d542f09fd60b6abf
push id7198
push userjlorenzo@mozilla.com
push dateTue, 18 Apr 2017 12:07:49 +0000
treeherdermozilla-beta@d57aa49c3948 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslarsbergstrom
servo: Merge #6125 - Renderrenderrenderrender: Now for embedding! (from zmike:renderrenderrenderrender); r=larsbergstrom A collection of commits which improves embedding integration and rendering. @larsbergstrom Source-Repo: https://github.com/servo/servo Source-Revision: 4a95bce9f260b183660dab44ef3044618be6840c
servo/components/compositing/compositor.rs
servo/components/compositing/windowing.rs
servo/components/servo/Cargo.lock
servo/ports/cef/Cargo.lock
servo/ports/cef/browser.rs
servo/ports/cef/browser_host.rs
servo/ports/cef/core.rs
servo/ports/cef/interfaces/cef_browser.rs
servo/ports/cef/interfaces/cef_render_handler.rs
servo/ports/cef/lib.rs
servo/ports/cef/macros.rs
servo/ports/cef/render_handler.rs
servo/ports/cef/window.rs
servo/ports/glutin/Cargo.toml
servo/ports/glutin/lib.rs
servo/ports/glutin/window.rs
servo/ports/gonk/Cargo.lock
servo/ports/gonk/src/window.rs
--- a/servo/components/compositing/compositor.rs
+++ b/servo/components/compositing/compositor.rs
@@ -1283,33 +1283,35 @@ impl<Window: WindowMethods> IOCompositor
         }
     }
 
     fn composite(&mut self) {
         let target = self.composite_target;
         self.composite_specific_target(target);
     }
 
-    fn composite_specific_target(&mut self, target: CompositeTarget) -> Option<png::Image> {
-        if !self.window.prepare_for_composite() {
+    pub fn composite_specific_target(&mut self, target: CompositeTarget) -> Option<png::Image> {
+        if !self.context.is_some() {
+            return None
+        }
+        let (width, height) =
+            (self.window_size.width.get() as usize, self.window_size.height.get() as usize);
+        if !self.window.prepare_for_composite(width, height) {
             return None
         }
 
         match target {
             CompositeTarget::WindowAndPng | CompositeTarget::PngFile => {
                 if !self.is_ready_to_paint_image_output() {
                     return None
                 }
             },
             _ => {}
         }
 
-        let (width, height) =
-            (self.window_size.width.get() as usize, self.window_size.height.get() as usize);
-
         let (framebuffer_ids, texture_ids) = match target {
             CompositeTarget::Window => (vec!(), vec!()),
             _ => initialize_png(width, height)
         };
 
         profile(ProfilerCategory::Compositing, None, self.time_profiler_chan.clone(), || {
             debug!("compositor: compositing");
             // Adjust the layer dimensions as necessary to correspond to the size of the window.
--- a/servo/components/compositing/windowing.rs
+++ b/servo/components/compositing/windowing.rs
@@ -118,16 +118,16 @@ pub trait WindowMethods {
     /// This is part of the windowing system because its implementation often involves OS-specific
     /// magic to wake the up window's event loop.
     fn create_compositor_channel(_: &Option<Rc<Self>>)
                                  -> (Box<CompositorProxy+Send>, Box<CompositorReceiver>);
 
     /// Requests that the window system prepare a composite. Typically this will involve making
     /// some type of platform-specific graphics context current. Returns true if the composite may
     /// proceed and false if it should not.
-    fn prepare_for_composite(&self) -> bool;
+    fn prepare_for_composite(&self, width: usize, height: usize) -> bool;
 
     /// Sets the cursor to be used in the window.
     fn set_cursor(&self, cursor: Cursor);
 
     /// Process a key event.
     fn handle_key(&self, key: Key, mods: KeyModifiers);
 }
--- a/servo/components/servo/Cargo.lock
+++ b/servo/components/servo/Cargo.lock
@@ -438,34 +438,34 @@ dependencies = [
  "gl_generator 0.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "khronos_api 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "glutin"
 version = "0.0.26"
-source = "git+https://github.com/servo/glutin?branch=servo#ec7a5e40c1cc7b8176eb1e1f7bf70c8a19559400"
+source = "git+https://github.com/servo/glutin?branch=servo#e888dc79471f062ae0b5fae0ba9e0f01ac96048e"
 dependencies = [
  "android_glue 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "gdi32-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "gl_common 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "gl_generator 0.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "glutin_cocoa 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "glutin_core_foundation 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "glutin_core_graphics 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "kernel32-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "khronos_api 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "objc 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "osmesa-sys 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "user32-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
- "x11 0.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
+ "x11 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "glutin_app"
 version = "0.0.1"
 dependencies = [
  "bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "cgl 0.0.1 (git+https://github.com/servo/rust-cgl)",
@@ -476,16 +476,17 @@ dependencies = [
  "glutin 0.0.26 (git+https://github.com/servo/glutin?branch=servo)",
  "layers 0.1.0 (git+https://github.com/servo/rust-layers)",
  "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "msg 0.0.1",
  "script_traits 0.0.1",
  "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
  "util 0.0.1",
+ "x11 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "glutin_cocoa"
 version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -611,31 +612,31 @@ dependencies = [
 [[package]]
 name = "khronos_api"
 version = "0.0.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "layers"
 version = "0.1.0"
-source = "git+https://github.com/servo/rust-layers#ff65707d621498949ed428077da7e42a9f9d2745"
+source = "git+https://github.com/servo/rust-layers#cfc29e48a11f0c1e5390a049850c3ba10f23e0ad"
 dependencies = [
  "azure 0.1.0 (git+https://github.com/servo/rust-azure)",
  "cgl 0.0.1 (git+https://github.com/servo/rust-cgl)",
  "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)",
  "egl 0.1.0 (git+https://github.com/servo/rust-egl)",
  "geom 0.1.0 (git+https://github.com/servo/rust-geom)",
  "gleam 0.0.1 (git+https://github.com/servo/gleam)",
  "glx 0.0.1 (git+https://github.com/servo/rust-glx)",
  "io_surface 0.1.0 (git+https://github.com/servo/rust-io-surface)",
  "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "skia 0.0.20130412 (git+https://github.com/servo/skia)",
- "xlib 0.1.0 (git+https://github.com/servo/rust-xlib)",
+ "x11 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "layout"
 version = "0.0.1"
 dependencies = [
  "azure 0.1.0 (git+https://github.com/servo/rust-azure)",
  "bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -838,27 +839,27 @@ source = "registry+https://github.com/ru
 dependencies = [
  "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "malloc_buf 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "offscreen_gl_context"
 version = "0.0.1"
-source = "git+https://github.com/ecoal95/rust-offscreen-rendering-context#97eacf34b72f69b10130a0de016529e98ee32f04"
+source = "git+https://github.com/ecoal95/rust-offscreen-rendering-context#99cee719a811f28e70fe33fa71137663ac210487"
 dependencies = [
  "cgl 0.0.1 (git+https://github.com/servo/rust-cgl)",
  "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)",
  "geom 0.1.0 (git+https://github.com/servo/rust-geom)",
  "gleam 0.0.1 (git+https://github.com/servo/gleam)",
  "glx 0.0.1 (git+https://github.com/servo/rust-glx)",
  "layers 0.1.0 (git+https://github.com/servo/rust-layers)",
  "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "xlib 0.1.0 (git+https://github.com/servo/rust-xlib)",
+ "x11 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "openssl"
 version = "0.6.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1324,20 +1325,21 @@ name = "winapi"
 version = "0.1.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "x11"
-version = "0.0.33"
+version = "1.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pkg-config 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "xlib"
 version = "0.1.0"
 source = "git+https://github.com/servo/rust-xlib#1a0f3d48fbebf96e2d1bf83ac71309b27f49e0c7"
 dependencies = [
  "bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
--- a/servo/ports/cef/Cargo.lock
+++ b/servo/ports/cef/Cargo.lock
@@ -24,17 +24,17 @@ dependencies = [
  "png 0.1.0 (git+https://github.com/servo/rust-png)",
  "script 0.0.1",
  "script_traits 0.0.1",
  "servo 0.0.1",
  "stb_image 0.1.0 (git+https://github.com/servo/rust-stb-image)",
  "style 0.0.1",
  "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
  "util 0.0.1",
- "x11 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "x11 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "android_glue"
 version = "0.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -440,34 +440,34 @@ dependencies = [
  "gl_generator 0.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "khronos_api 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "glutin"
 version = "0.0.26"
-source = "git+https://github.com/servo/glutin?branch=servo#ec7a5e40c1cc7b8176eb1e1f7bf70c8a19559400"
+source = "git+https://github.com/servo/glutin?branch=servo#e888dc79471f062ae0b5fae0ba9e0f01ac96048e"
 dependencies = [
  "android_glue 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "gdi32-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "gl_common 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "gl_generator 0.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "glutin_cocoa 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "glutin_core_foundation 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "glutin_core_graphics 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "kernel32-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "khronos_api 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "objc 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "osmesa-sys 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "user32-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
- "x11 0.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
+ "x11 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "glutin_app"
 version = "0.0.1"
 dependencies = [
  "bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "cgl 0.0.1 (git+https://github.com/servo/rust-cgl)",
@@ -478,16 +478,17 @@ dependencies = [
  "glutin 0.0.26 (git+https://github.com/servo/glutin?branch=servo)",
  "layers 0.1.0 (git+https://github.com/servo/rust-layers)",
  "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "msg 0.0.1",
  "script_traits 0.0.1",
  "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
  "util 0.0.1",
+ "x11 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "glutin_cocoa"
 version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -613,31 +614,31 @@ dependencies = [
 [[package]]
 name = "khronos_api"
 version = "0.0.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "layers"
 version = "0.1.0"
-source = "git+https://github.com/servo/rust-layers#ff65707d621498949ed428077da7e42a9f9d2745"
+source = "git+https://github.com/servo/rust-layers#cfc29e48a11f0c1e5390a049850c3ba10f23e0ad"
 dependencies = [
  "azure 0.1.0 (git+https://github.com/servo/rust-azure)",
  "cgl 0.0.1 (git+https://github.com/servo/rust-cgl)",
  "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)",
  "egl 0.1.0 (git+https://github.com/servo/rust-egl)",
  "geom 0.1.0 (git+https://github.com/servo/rust-geom)",
  "gleam 0.0.1 (git+https://github.com/servo/gleam)",
  "glx 0.0.1 (git+https://github.com/servo/rust-glx)",
  "io_surface 0.1.0 (git+https://github.com/servo/rust-io-surface)",
  "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "skia 0.0.20130412 (git+https://github.com/servo/skia)",
- "xlib 0.1.0 (git+https://github.com/servo/rust-xlib)",
+ "x11 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "layout"
 version = "0.0.1"
 dependencies = [
  "azure 0.1.0 (git+https://github.com/servo/rust-azure)",
  "bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -828,27 +829,27 @@ source = "registry+https://github.com/ru
 dependencies = [
  "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "malloc_buf 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "offscreen_gl_context"
 version = "0.0.1"
-source = "git+https://github.com/ecoal95/rust-offscreen-rendering-context#97eacf34b72f69b10130a0de016529e98ee32f04"
+source = "git+https://github.com/ecoal95/rust-offscreen-rendering-context#99cee719a811f28e70fe33fa71137663ac210487"
 dependencies = [
  "cgl 0.0.1 (git+https://github.com/servo/rust-cgl)",
  "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)",
  "geom 0.1.0 (git+https://github.com/servo/rust-geom)",
  "gleam 0.0.1 (git+https://github.com/servo/gleam)",
  "glx 0.0.1 (git+https://github.com/servo/rust-glx)",
  "layers 0.1.0 (git+https://github.com/servo/rust-layers)",
  "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "xlib 0.1.0 (git+https://github.com/servo/rust-xlib)",
+ "x11 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "openssl"
 version = "0.6.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1309,25 +1310,17 @@ name = "winapi"
 version = "0.1.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "x11"
-version = "0.0.33"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "x11"
-version = "1.0.0"
+version = "1.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "xlib"
--- a/servo/ports/cef/browser.rs
+++ b/servo/ports/cef/browser.rs
@@ -13,16 +13,17 @@ use types::{cef_browser_settings_t, cef_
 use window;
 use wrappers::CefWrap;
 
 use compositing::windowing::{WindowNavigateMsg, WindowEvent};
 use glutin_app;
 use libc::c_int;
 use std::cell::{Cell, RefCell, BorrowState};
 use std::ptr;
+use std::rc::Rc;
 use std::sync::atomic::{AtomicIsize, Ordering};
 
 thread_local!(pub static ID_COUNTER: AtomicIsize = AtomicIsize::new(0));
 thread_local!(pub static BROWSERS: RefCell<Vec<CefBrowser>> = RefCell::new(vec!()));
 
 pub enum ServoBrowser {
     Invalid,
     OnScreen(Browser),
@@ -82,49 +83,56 @@ cef_class_impl! {
 
 pub struct ServoCefBrowser {
     /// A reference to the browser's primary frame.
     pub frame: CefFrame,
     /// A reference to the browser's host.
     pub host: CefBrowserHost,
     /// A reference to the browser client.
     pub client: CefClient,
+    /// the glutin window when using windowed rendering
+    pub window: Option<Rc<glutin_app::window::Window>>,
     /// Whether the on-created callback has fired yet.
     pub callback_executed: Cell<bool>,
     /// the display system window handle: only to be used with host.get_window_handle()
     window_handle: cef_window_handle_t,
 
     id: isize,
     servo_browser: RefCell<ServoBrowser>,
     message_queue: RefCell<Vec<WindowEvent>>,
 }
 
 impl ServoCefBrowser {
     pub fn new(window_info: &cef_window_info_t, client: CefClient) -> ServoCefBrowser {
         let frame = ServoCefFrame::new().as_cef_interface();
         let host = ServoCefBrowserHost::new(client.clone()).as_cef_interface();
         let mut window_handle: cef_window_handle_t = get_null_window_handle();
+        let mut glutin_window: Option<Rc<glutin_app::window::Window>> = None;
 
         let servo_browser = if window_info.windowless_rendering_enabled == 0 {
-            let glutin_window = glutin_app::create_window(window_info.parent_window as glutin_app::WindowID);
-            let servo_browser = Browser::new(Some(glutin_window.clone()));
-            window_handle = glutin_window.platform_window() as cef_window_handle_t;
+            glutin_window = Some(glutin_app::create_window(window_info.parent_window as glutin_app::WindowID));
+            let servo_browser = Browser::new(glutin_window.clone());
+            window_handle = match glutin_window {
+                Some(ref win) => win.platform_window() as cef_window_handle_t,
+                None => get_null_window_handle()
+            };
             ServoBrowser::OnScreen(servo_browser)
         } else {
             ServoBrowser::Invalid
         };
 
         let id = ID_COUNTER.with(|counter| {
             counter.fetch_add(1, Ordering::SeqCst)
         });
 
         ServoCefBrowser {
             frame: frame,
             host: host,
             client: client,
+            window: glutin_window,
             callback_executed: Cell::new(false),
             servo_browser: RefCell::new(servo_browser),
             message_queue: RefCell::new(vec!()),
             id: id,
             window_handle: window_handle,
         }
     }
 }
@@ -134,19 +142,19 @@ pub trait ServoCefBrowserExtensions {
     fn send_window_event(&self, event: WindowEvent);
     fn get_title_for_main_frame(&self);
     fn pinch_zoom_level(&self) -> f32;
 }
 
 impl ServoCefBrowserExtensions for CefBrowser {
     fn init(&self, window_info: &cef_window_info_t) {
         if window_info.windowless_rendering_enabled != 0 {
-            let window = window::Window::new();
+            let window = window::Window::new(window_info.width, window_info.height);
+            window.set_browser(self.clone());
             let servo_browser = Browser::new(Some(window.clone()));
-            window.set_browser(self.clone());
             *self.downcast().servo_browser.borrow_mut() = ServoBrowser::OffScreen(servo_browser);
         }
 
         self.downcast().host.set_browser((*self).clone());
         self.downcast().frame.set_browser((*self).clone());
         if window_info.windowless_rendering_enabled == 0 {
             self.downcast().host.initialize_compositing();
         }
@@ -193,17 +201,26 @@ pub fn get_null_window_handle() -> cef_w
 }
 
 pub fn update() {
     BROWSERS.with(|browsers| {
         for browser in browsers.borrow().iter() {
             if browser.downcast().callback_executed.get() == false {
                 browser_callback_after_created(browser.clone());
             }
-            browser.send_window_event(WindowEvent::Idle);
+            let mut events = match browser.downcast().window {
+                Some(ref win) => win.wait_events(),
+                None => vec![WindowEvent::Idle]
+            };
+            loop {
+               match events.pop() {
+                   Some(event) => browser.send_window_event(event),
+                   None => break
+               }
+            }
         }
     });
 }
 
 pub fn close(browser: CefBrowser) {
     BROWSERS.with(|browsers| {
         let mut browsers = browsers.borrow_mut();
         browsers.iter()
@@ -233,19 +250,19 @@ fn browser_host_create(window_info: &cef
                        url: *const cef_string_t,
                        callback_executed: bool)
                        -> CefBrowser {
     let browser = ServoCefBrowser::new(window_info, client).as_cef_interface();
     browser.init(window_info);
     if callback_executed {
         browser_callback_after_created(browser.clone());
     }
-    if url != ptr::null() {
-       unsafe { browser.downcast().frame.load_url(CefWrap::to_rust(url)); }
-    }
+    //if url != ptr::null() {
+       //unsafe { browser.downcast().frame.load_url(CefWrap::to_rust(url)); }
+    //}
     BROWSERS.with(|browsers| {
         browsers.borrow_mut().push(browser.clone());
     });
     browser
 }
 
 cef_static_method_impls! {
     fn cef_browser_host_create_browser(window_info: *const cef_window_info_t,
--- a/servo/ports/cef/browser_host.rs
+++ b/servo/ports/cef/browser_host.rs
@@ -2,47 +2,60 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 use eutil::Downcast;
 use interfaces::{CefBrowser, CefBrowserHost, CefClient, cef_browser_t, cef_browser_host_t, cef_client_t};
 use types::{cef_mouse_button_type_t, cef_mouse_event, cef_rect_t, cef_key_event, cef_window_handle_t};
 use types::cef_key_event_type_t::{KEYEVENT_CHAR, KEYEVENT_KEYDOWN, KEYEVENT_KEYUP, KEYEVENT_RAWKEYDOWN};
 use browser::{self, ServoCefBrowserExtensions};
+use wrappers::CefWrap;
 
 use compositing::windowing::{WindowEvent, MouseWindowEvent};
 use geom::point::TypedPoint2D;
 use geom::size::TypedSize2D;
 use libc::{c_double, c_int};
 use msg::constellation_msg::{self, KeyModifiers, KeyState};
 use script_traits::MouseButton;
-use std::cell::RefCell;
+use std::cell::{Cell, RefCell};
 
 pub struct ServoCefBrowserHost {
     /// A reference to the browser.
     pub browser: RefCell<Option<CefBrowser>>,
     /// A reference to the client.
     pub client: CefClient,
+    /// flag for return value of prepare_for_composite
+    pub composite_ok: Cell<bool>,
 }
 
 full_cef_class_impl! {
     ServoCefBrowserHost : CefBrowserHost, cef_browser_host_t {
         fn get_client(&this,) -> *mut cef_client_t {{
             this.downcast().client.clone()
         }}
         fn get_browser(&this,) -> *mut cef_browser_t {{
             let browser = this.downcast().browser.borrow_mut();
             browser.clone().unwrap()
         }}
 
         fn was_resized(&this,) -> () {{
             let mut rect = cef_rect_t::zero();
-            this.get_client()
-                .get_render_handler()
-                .get_backing_rect(this.downcast().browser.borrow().clone().unwrap(), &mut rect);
+            if cfg!(target_os="macos") {
+                if check_ptr_exist!(this.get_client(), get_render_handler) &&
+                   check_ptr_exist!(this.get_client().get_render_handler(), get_backing_rect) {
+                    this.get_client()
+                        .get_render_handler()
+                        .get_backing_rect(this.downcast().browser.borrow().clone().unwrap(), &mut rect);
+                }
+            } else if check_ptr_exist!(this.get_client(), get_render_handler) &&
+               check_ptr_exist!(this.get_client().get_render_handler(), get_view_rect) {
+                this.get_client()
+                    .get_render_handler()
+                    .get_view_rect(this.downcast().browser.borrow().clone().unwrap(), &mut rect);
+               }
             let size = TypedSize2D(rect.width as u32, rect.height as u32);
             this.downcast().send_window_event(WindowEvent::Resize(size));
         }}
 
         fn close_browser(&this, _force: c_int [c_int],) -> () {{
             browser::close(this.downcast().browser.borrow_mut().take().unwrap());
         }}
 
@@ -160,29 +173,36 @@ full_cef_class_impl! {
             let old_zoom_level = this.get_zoom_level();
             this.downcast().send_window_event(WindowEvent::PinchZoom((new_zoom_level / old_zoom_level) as f32))
         }}
 
         fn initialize_compositing(&this,) -> () {{
             this.downcast().send_window_event(WindowEvent::InitializeCompositing);
         }}
 
+        fn composite(&this,) -> () {{
+            this.downcast().composite_ok.set(true);
+            this.downcast().send_window_event(WindowEvent::Refresh);
+            this.downcast().composite_ok.set(false);
+        }}
+
         fn get_window_handle(&this,) -> cef_window_handle_t {{
             let t = this.downcast();
             let browser = t.browser.borrow();
             browser::get_window(&browser.as_ref().unwrap()) as cef_window_handle_t
         }}
     }
 }
 
 impl ServoCefBrowserHost {
     pub fn new(client: CefClient) -> ServoCefBrowserHost {
         ServoCefBrowserHost {
             browser: RefCell::new(None),
             client: client,
+            composite_ok: Cell::new(false),
         }
     }
 
     fn send_window_event(&self, event: WindowEvent) {
         self.browser.borrow_mut().as_mut().unwrap().send_window_event(event);
     }
 
     fn pinch_zoom_level(&self) -> f32 {
--- a/servo/ports/cef/core.rs
+++ b/servo/ports/cef/core.rs
@@ -1,25 +1,27 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 use command_line::command_line_init;
 use interfaces::cef_app_t;
 use types::{cef_main_args_t, cef_settings_t};
+use window::init_window;
 
 use libc::{c_char, c_int, c_void};
 use util::opts;
 use std::ffi;
 use std::str;
 use browser;
+use std_url::Url;
 
 const MAX_RENDERING_THREADS: usize = 128;
 
-//static HOME_URL: &'static str = "http://s27.postimg.org/vqbtrolyr/servo.jpg";
+static HOME_URL: &'static str = "http://s27.postimg.org/vqbtrolyr/servo.jpg";
 
 static CEF_API_HASH_UNIVERSAL: &'static [u8] = b"8efd129f4afc344bd04b2feb7f73a149b6c4e27f\0";
 #[cfg(target_os="windows")]
 static CEF_API_HASH_PLATFORM: &'static [u8] = b"5c7f3e50ff5265985d11dc1a466513e25748bedd\0";
 #[cfg(target_os="macos")]
 static CEF_API_HASH_PLATFORM: &'static [u8] = b"6813214accbf2ebfb6bdcf8d00654650b251bf3d\0";
 #[cfg(target_os="linux")]
 static CEF_API_HASH_PLATFORM: &'static [u8] = b"2bc564c3871965ef3a2531b528bda3e17fa17a6d\0";
@@ -60,18 +62,23 @@ pub extern "C" fn cef_initialize(args: *
 
     let mut temp_opts = opts::default_opts();
     temp_opts.paint_threads = rendering_threads;
     temp_opts.layout_threads = rendering_threads;
     temp_opts.headless = false;
     temp_opts.hard_fail = false;
     temp_opts.enable_text_antialiasing = true;
     temp_opts.resources_path = None;
+    temp_opts.url = Url::parse(HOME_URL).unwrap();
     opts::set(temp_opts);
 
+    if unsafe { (*settings).windowless_rendering_enabled != 0 } {
+        init_window();
+    }
+
     return 1
 }
 
 #[no_mangle]
 pub extern "C" fn cef_shutdown() {
 }
 
 #[no_mangle]
--- a/servo/ports/cef/interfaces/cef_browser.rs
+++ b/servo/ports/cef/interfaces/cef_browser.rs
@@ -1316,16 +1316,23 @@ pub struct _cef_browser_host_t {
   // drag operation. If the web view is both the drag source and the drag target
   // then all DragTarget* functions should be called before DragSource* mthods.
   // This function is only used when window rendering is disabled.
   //
   pub drag_source_system_drag_ended: Option<extern "C" fn(
       this: *mut cef_browser_host_t) -> ()>,
 
   //
+  // Instructs the browser to perform an accelerated composite. The appropriate
+  // Direct3D or OpenGL state must have been set up before calling this
+  // function.
+  //
+  pub composite: Option<extern "C" fn(this: *mut cef_browser_host_t) -> ()>,
+
+  //
   // Instructs the browser to initialize accelerated compositing. The
   // appropriate Direct3D or OpenGL state must have been set up before calling
   // this function.
   //
   pub initialize_compositing: Option<extern "C" fn(
       this: *mut cef_browser_host_t) -> ()>,
 
   //
@@ -2210,16 +2217,33 @@ impl CefBrowserHost {
     unsafe {
       CefWrap::to_rust(
         ((*self.c_object).drag_source_system_drag_ended.unwrap())(
           self.c_object))
     }
   }
 
   //
+  // Instructs the browser to perform an accelerated composite. The appropriate
+  // Direct3D or OpenGL state must have been set up before calling this
+  // function.
+  //
+  pub fn composite(&self) -> () {
+    if self.c_object.is_null() ||
+       self.c_object as usize == mem::POST_DROP_USIZE {
+      panic!("called a CEF method on a null object")
+    }
+    unsafe {
+      CefWrap::to_rust(
+        ((*self.c_object).composite.unwrap())(
+          self.c_object))
+    }
+  }
+
+  //
   // Instructs the browser to initialize accelerated compositing. The
   // appropriate Direct3D or OpenGL state must have been set up before calling
   // this function.
   //
   pub fn initialize_compositing(&self) -> () {
     if self.c_object.is_null() ||
        self.c_object as usize == mem::POST_DROP_USIZE {
       panic!("called a CEF method on a null object")
--- a/servo/ports/cef/interfaces/cef_render_handler.rs
+++ b/servo/ports/cef/interfaces/cef_render_handler.rs
@@ -170,17 +170,17 @@ pub struct _cef_render_handler_t {
   pub on_scroll_offset_changed: Option<extern "C" fn(
       this: *mut cef_render_handler_t, browser: *mut interfaces::cef_browser_t,
       x: libc::c_double, y: libc::c_double) -> ()>,
 
   //
   // Called to retrieve the backing size of the view rectangle which is relative
   // to screen coordinates. On HiDPI displays, the backing size can differ from
   // the view size as returned by |GetViewRect|. Return true (1) if the
-  // rectangle was provided.
+  // rectangle was provided. Only used on Mac OS.
   //
   pub get_backing_rect: Option<extern "C" fn(this: *mut cef_render_handler_t,
       browser: *mut interfaces::cef_browser_t,
       rect: *mut types::cef_rect_t) -> libc::c_int>,
 
   //
   // Called when an element should be presented (e.g. double buffers should page
   // flip). This is called only during accelerated compositing.
@@ -522,17 +522,17 @@ impl CefRenderHandler {
           CefWrap::to_c(y)))
     }
   }
 
   //
   // Called to retrieve the backing size of the view rectangle which is relative
   // to screen coordinates. On HiDPI displays, the backing size can differ from
   // the view size as returned by |GetViewRect|. Return true (1) if the
-  // rectangle was provided.
+  // rectangle was provided. Only used on Mac OS.
   //
   pub fn get_backing_rect(&self, browser: interfaces::CefBrowser,
       rect: &mut types::cef_rect_t) -> libc::c_int {
     if self.c_object.is_null() ||
        self.c_object as usize == mem::POST_DROP_USIZE {
       panic!("called a CEF method on a null object")
     }
     unsafe {
--- a/servo/ports/cef/lib.rs
+++ b/servo/ports/cef/lib.rs
@@ -53,16 +53,17 @@ extern crate cocoa;
 extern crate core_foundation;
 #[cfg(target_os="macos")]
 extern crate core_graphics;
 #[cfg(target_os="macos")]
 extern crate core_text;
 #[cfg(target_os="macos")]
 #[macro_use]
 extern crate objc;
+#[cfg(target_os="linux")] extern crate x11;
 
 // Must come first.
 pub mod macros;
 
 pub mod browser;
 pub mod browser_host;
 pub mod command_line;
 pub mod cookie;
--- a/servo/ports/cef/macros.rs
+++ b/servo/ports/cef/macros.rs
@@ -1,14 +1,21 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #![macro_use]
 
+
+macro_rules! check_ptr_exist {
+    ($var:expr, $member:ident) => (
+        unsafe { (*CefWrap::to_c($var)).$member.is_some() }
+    );
+}
+
 // Provides the implementation of a CEF class. An example follows:
 //
 //    struct ServoCefThing {
 //        ...
 //    }
 //
 //    cef_class_impl! {
 //        ServoCefThing : CefThing, cef_thing_t {
--- a/servo/ports/cef/render_handler.rs
+++ b/servo/ports/cef/render_handler.rs
@@ -3,17 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 use interfaces::{CefBrowser, CefRenderHandler};
 use types::cef_paint_element_type_t::PET_VIEW;
 
 use std::ptr;
 
 pub trait CefRenderHandlerExtensions {
-    fn paint(&self, browser: CefBrowser);
+    fn paint(&self, browser: CefBrowser, width: usize, height: usize);
 }
 
 impl CefRenderHandlerExtensions for CefRenderHandler {
-    fn paint(&self, browser: CefBrowser) {
-        self.on_paint(browser, PET_VIEW, 0, ptr::null(), &mut (), 0, 0)
+    fn paint(&self, browser: CefBrowser, width: usize, height: usize) {
+        self.on_paint(browser, PET_VIEW, 0, ptr::null(), &mut (), width as i32, height as i32)
     }
 }
 
--- a/servo/ports/cef/window.rs
+++ b/servo/ports/cef/window.rs
@@ -7,46 +7,49 @@
 //! This is used for off-screen rendering mode only; on-screen windows (the default embedding mode)
 //! are managed by a platform toolkit (Glutin).
 
 use eutil::Downcast;
 use interfaces::CefBrowser;
 use render_handler::CefRenderHandlerExtensions;
 use rustc_unicode::str::Utf16Encoder;
 use types::{cef_cursor_handle_t, cef_cursor_type_t, cef_rect_t};
+use wrappers::CefWrap;
 
 use compositing::compositor_task::{self, CompositorProxy, CompositorReceiver};
 use compositing::windowing::{WindowEvent, WindowMethods};
 use geom::scale_factor::ScaleFactor;
 use geom::size::TypedSize2D;
 use gleam::gl;
 use layers::geometry::DevicePixel;
 use layers::platform::surface::NativeGraphicsMetadata;
-use libc::{c_char, c_void};
+use libc::{c_char, c_int, c_void};
 use msg::constellation_msg::{Key, KeyModifiers};
 use std::ptr;
 use std_url::Url;
 use util::cursor::Cursor;
 use util::geometry::ScreenPx;
 use std::cell::RefCell;
 use std::ffi::CString;
 use std::rc::Rc;
 use std::sync::mpsc::{Sender, channel};
 #[cfg(target_os="linux")]
 extern crate x11;
 #[cfg(target_os="linux")]
-use self::x11::xlib::XOpenDisplay;
+use self::x11::xlib::{XInitThreads,XOpenDisplay};
+
+#[cfg(target_os="linux")]
+pub static mut DISPLAY: *mut c_void = 0 as *mut c_void;
 
 /// The type of an off-screen window.
 #[allow(raw_pointer_derive)]
 #[derive(Clone)]
 pub struct Window {
     cef_browser: RefCell<Option<CefBrowser>>,
-#[cfg(target_os="linux")]
-    display: *mut c_void,
+    size: TypedSize2D<DevicePixel,u32>
 }
 
 #[cfg(target_os="macos")]
 fn load_gl() {
     const RTLD_DEFAULT: *mut c_void = (-2) as *mut c_void;
 
     extern {
         fn dlsym(handle: *mut c_void, symbol: *const c_char) -> *mut c_void;
@@ -71,31 +74,22 @@ fn load_gl() {
             let c_str = CString::new(s).unwrap();
             glXGetProcAddress(c_str.as_ptr()) as *const c_void
         }
     });
 }
 
 impl Window {
     /// Creates a new window.
-#[cfg(target_os="linux")]
-    pub fn new() -> Rc<Window> {
+    pub fn new(width: u32, height: u32) -> Rc<Window> {
         load_gl();
 
         Rc::new(Window {
             cef_browser: RefCell::new(None),
-            display: unsafe { XOpenDisplay(ptr::null()) as *mut c_void },
-        })
-    }
-#[cfg(not(target_os="linux"))]
-    pub fn new() -> Rc<Window> {
-        load_gl();
-
-        Rc::new(Window {
-            cef_browser: RefCell::new(None),
+            size: TypedSize2D(width, height)
         })
     }
 
     /// Sets the current browser.
     pub fn set_browser(&self, browser: CefBrowser) {
         *self.cef_browser.borrow_mut() = Some(browser)
     }
 
@@ -170,24 +164,46 @@ impl Window {
         0
     }
 }
 
 impl WindowMethods for Window {
     fn framebuffer_size(&self) -> TypedSize2D<DevicePixel,u32> {
         let browser = self.cef_browser.borrow();
         match *browser {
-            None => TypedSize2D(400, 300),
+            None => self.size,
             Some(ref browser) => {
-                let mut rect = cef_rect_t::zero();
-                browser.get_host()
-                       .get_client()
-                       .get_render_handler()
-                       .get_backing_rect((*browser).clone(), &mut rect);
-                TypedSize2D(rect.width as u32, rect.height as u32)
+                if browser.downcast().callback_executed.get() != true {
+                    self.size
+                } else {
+                    let mut rect = cef_rect_t::zero();
+                    rect.width = self.size.width.get() as i32;
+                    rect.height = self.size.height.get() as i32;
+                    if cfg!(target_os="macos") {
+                        // osx relies on virtual pixel scaling to provide sizes different from actual
+                        // pixel size on screen. other platforms are just 1.0 unless the desktop/toolkit says otherwise
+                        if check_ptr_exist!(browser.get_host().get_client(), get_render_handler) &&
+                           check_ptr_exist!(browser.get_host().get_client().get_render_handler(), get_backing_rect) {
+                            browser.get_host()
+                                   .get_client()
+                                   .get_render_handler()
+                                   .get_backing_rect((*browser).clone(), &mut rect);
+                        }
+                    } else {
+                        if check_ptr_exist!(browser.get_host().get_client(), get_render_handler) &&
+                           check_ptr_exist!(browser.get_host().get_client().get_render_handler(), get_view_rect) {
+                            browser.get_host()
+                                   .get_client()
+                                   .get_render_handler()
+                                   .get_view_rect((*browser).clone(), &mut rect);
+                        }
+                    }
+
+                    TypedSize2D(rect.width as u32, rect.height as u32)
+                }
             }
         }
     }
 
     fn size(&self) -> TypedSize2D<ScreenPx,f32> {
         let browser = self.cef_browser.borrow();
         match *browser {
             None => TypedSize2D(400.0, 300.0),
@@ -202,38 +218,53 @@ impl WindowMethods for Window {
         }
     }
 
     fn present(&self) {
         let browser = self.cef_browser.borrow();
         match *browser {
             None => {}
             Some(ref browser) => {
-                browser.get_host().get_client().get_render_handler().on_present(browser.clone());
+                if check_ptr_exist!(browser.get_host().get_client(), get_render_handler) &&
+                   check_ptr_exist!(browser.get_host().get_client().get_render_handler(), on_present) {
+                    browser.get_host().get_client().get_render_handler().on_present(browser.clone());
+                   }
             }
         }
     }
 
     fn hidpi_factor(&self) -> ScaleFactor<ScreenPx,DevicePixel,f32> {
-        let browser = self.cef_browser.borrow();
-        match *browser {
-            None => ScaleFactor::new(1.0),
-            Some(ref browser) => {
-                let mut view_rect = cef_rect_t::zero();
-                browser.get_host()
-                       .get_client()
-                       .get_render_handler()
-                       .get_view_rect((*browser).clone(), &mut view_rect);
-                let mut backing_rect = cef_rect_t::zero();
-                browser.get_host()
-                       .get_client()
-                       .get_render_handler()
-                       .get_backing_rect((*browser).clone(), &mut backing_rect);
-                ScaleFactor::new(backing_rect.width as f32 / view_rect.width as f32)
+        if cfg!(target_os="macos") {
+            let browser = self.cef_browser.borrow();
+            match *browser {
+                None => ScaleFactor::new(1.0),
+                Some(ref browser) => {
+                    let mut view_rect = cef_rect_t::zero();
+                    if check_ptr_exist!(browser.get_host().get_client(), get_render_handler) &&
+                       check_ptr_exist!(browser.get_host().get_client().get_render_handler(), get_view_rect) {
+                        browser.get_host()
+                               .get_client()
+                               .get_render_handler()
+                               .get_view_rect((*browser).clone(), &mut view_rect);
+                    }
+                    let mut backing_rect = cef_rect_t::zero();
+                    if check_ptr_exist!(browser.get_host().get_client(), get_render_handler) &&
+                       check_ptr_exist!(browser.get_host().get_client().get_render_handler(), get_backing_rect) {
+                        browser.get_host()
+                               .get_client()
+                               .get_render_handler()
+                               .get_backing_rect((*browser).clone(), &mut backing_rect);
+                    }
+                    ScaleFactor::new(backing_rect.width as f32 / view_rect.width as f32)
+                }
             }
+        } else {
+            // FIXME(zmike)
+            // need to figure out a method for actually getting the scale factor instead of this nonsense
+            ScaleFactor::new(1.0 as f32)
         }
     }
 
     #[cfg(target_os="macos")]
     fn native_metadata(&self) -> NativeGraphicsMetadata {
         use cgl::{CGLGetCurrentContext, CGLGetPixelFormat};
 
         // FIXME(pcwalton)
@@ -241,52 +272,67 @@ impl WindowMethods for Window {
             NativeGraphicsMetadata {
                 pixel_format: CGLGetPixelFormat(CGLGetCurrentContext()),
             }
         }
     }
 
     #[cfg(target_os="linux")]
     fn native_metadata(&self) -> NativeGraphicsMetadata {
-       NativeGraphicsMetadata {
-           display: self.display,
-       }
+        use x11::xlib;
+        unsafe {
+            NativeGraphicsMetadata {
+                display: DISPLAY as *mut xlib::Display,
+            }
+        }
     }
 
     fn create_compositor_channel(_: &Option<Rc<Window>>)
                                  -> (Box<CompositorProxy+Send>, Box<CompositorReceiver>) {
         let (sender, receiver) = channel();
         (box CefCompositorProxy {
              sender: sender,
          } as Box<CompositorProxy+Send>,
          box receiver as Box<CompositorReceiver>)
     }
 
-    fn prepare_for_composite(&self) -> bool {
+    fn prepare_for_composite(&self, width: usize, height: usize) -> bool {
         let browser = self.cef_browser.borrow();
         match *browser {
-            None => {}
+            None => {
+                panic!("No browser?!?");
+            }
             Some(ref browser) => {
-                browser.get_host().get_client().get_render_handler().paint(browser.clone());
+                if browser.downcast().host.downcast().composite_ok.get() == true {
+                    true
+                } else {
+                    if check_ptr_exist!(browser.get_host().get_client(), get_render_handler) &&
+                       check_ptr_exist!(browser.get_host().get_client().get_render_handler(), on_paint) {
+                        browser.get_host().get_client().get_render_handler().paint(browser.clone(), width, height);
+                    }
+                    false
+                }
             }
         }
-        true
     }
 
     fn load_end(&self) {
         // FIXME(pcwalton): The status code 200 is a lie.
         let browser = self.cef_browser.borrow();
         let browser = match *browser {
             None => return,
             Some(ref browser) => browser,
         };
-        browser.get_host()
-               .get_client()
-               .get_load_handler()
-               .on_load_end((*browser).clone(), browser.get_main_frame(), 200);
+        if check_ptr_exist!(browser.get_host().get_client(), get_load_handler) &&
+           check_ptr_exist!(browser.get_host().get_client().get_load_handler(), on_load_end) {
+            browser.get_host()
+                   .get_client()
+                   .get_load_handler()
+                   .on_load_end((*browser).clone(), browser.get_main_frame(), 200);
+        }
     }
 
     fn set_page_title(&self, string: Option<String>) {
         let browser = self.cef_browser.borrow();
         let browser = match *browser {
             None => return,
             Some(ref browser) => browser,
         };
@@ -327,21 +373,24 @@ impl WindowMethods for Window {
     fn set_cursor(&self, cursor: Cursor) {
         use types::{CefCursorInfo,cef_point_t,cef_size_t};
         let browser = self.cef_browser.borrow();
         match *browser {
             None => {}
             Some(ref browser) => {
                 let cursor_handle = self.cursor_handle_for_cursor(cursor);
                 let info = CefCursorInfo { hotspot: cef_point_t {x: 0, y: 0}, image_scale_factor: 0.0, buffer: 0 as *mut isize, size: cef_size_t { width: 0, height: 0 } };
-                browser.get_host()
-                       .get_client()
-                       .get_render_handler()
-                       .on_cursor_change(browser.clone(), cursor_handle,
-                         self.cursor_type_for_cursor(cursor), &info)
+                if check_ptr_exist!(browser.get_host().get_client(), get_render_handler) &&
+                   check_ptr_exist!(browser.get_host().get_client().get_render_handler(), on_cursor_change) {
+                    browser.get_host()
+                           .get_client()
+                           .get_render_handler()
+                           .on_cursor_change(browser.clone(), cursor_handle,
+                             self.cursor_type_for_cursor(cursor), &info)
+                   }
             }
         }
     }
 }
 
 struct CefCompositorProxy {
     sender: Sender<compositor_task::Msg>,
 }
@@ -373,19 +422,38 @@ impl CompositorProxy for CefCompositorPr
                 0);
             NSApp().postEvent_atStart_(event, 0);
             pool.drain();
         }
     }
 
     #[cfg(target_os="linux")]
     fn send(&mut self, msg: compositor_task::Msg) {
-        // FIXME(pcwalton): Kick the GTK event loop awake?
         self.sender.send(msg).unwrap();
     }
 
     fn clone_compositor_proxy(&self) -> Box<CompositorProxy+Send> {
         box CefCompositorProxy {
             sender: self.sender.clone(),
         } as Box<CompositorProxy+Send>
     }
 }
 
+#[cfg(target_os="linux")]
+pub fn init_window() {
+    unsafe {
+        assert!(XInitThreads() != 0);
+        DISPLAY = XOpenDisplay(ptr::null()) as *mut c_void;
+    }
+}
+#[cfg(not(target_os="linux"))]
+pub fn init_window() {}
+
+#[cfg(target_os="linux")]
+#[no_mangle]
+pub extern "C" fn cef_get_xdisplay() -> *mut c_void {
+    unsafe { DISPLAY }
+}
+#[cfg(not(target_os="linux"))]
+#[no_mangle]
+pub extern "C" fn cef_get_xdisplay() -> *mut c_void {
+    ptr::null_mut()
+}
--- a/servo/ports/glutin/Cargo.toml
+++ b/servo/ports/glutin/Cargo.toml
@@ -42,8 +42,9 @@ git = "https://github.com/servo/rust-cgl
 [dependencies.egl]
 git = "https://github.com/servo/rust-egl"
 
 [dependencies]
 time = "0.1.12"
 bitflags = "*"
 libc = "*"
 url = "*"
+x11 = "*"
--- a/servo/ports/glutin/lib.rs
+++ b/servo/ports/glutin/lib.rs
@@ -16,16 +16,17 @@ extern crate glutin;
 extern crate layers;
 extern crate libc;
 extern crate msg;
 #[cfg(feature = "window")] extern crate script_traits;
 extern crate time;
 extern crate util;
 extern crate egl;
 extern crate url;
+#[cfg(target_os="linux")] extern crate x11;
 
 use compositing::windowing::WindowEvent;
 use geom::scale_factor::ScaleFactor;
 use std::rc::Rc;
 use window::Window;
 use util::opts;
 
 pub mod window;
--- a/servo/ports/glutin/window.rs
+++ b/servo/ports/glutin/window.rs
@@ -547,24 +547,25 @@ impl WindowMethods for Window {
             Cursor::RowResizeCursor => MouseCursor::RowResize,
             Cursor::AllScrollCursor => MouseCursor::AllScroll,
             Cursor::ZoomInCursor => MouseCursor::ZoomIn,
             Cursor::ZoomOutCursor => MouseCursor::ZoomOut,
         };
         self.window.set_cursor(glutin_cursor);
     }
 
-    fn prepare_for_composite(&self) -> bool {
+    fn prepare_for_composite(&self, _width: usize, _height: usize) -> bool {
         true
     }
 
     #[cfg(target_os="linux")]
     fn native_metadata(&self) -> NativeGraphicsMetadata {
+        use x11::xlib;
         NativeGraphicsMetadata {
-            display: unsafe { self.window.platform_display() }
+            display: unsafe { self.window.platform_display() as *mut xlib::Display }
         }
     }
 
     #[cfg(target_os="macos")]
     fn native_metadata(&self) -> NativeGraphicsMetadata {
         use cgl::{CGLGetCurrentContext, CGLGetPixelFormat};
         unsafe {
             NativeGraphicsMetadata {
@@ -686,17 +687,17 @@ impl WindowMethods for Window {
     }
 
     fn load_end(&self) {
     }
 
     fn set_cursor(&self, _: Cursor) {
     }
 
-    fn prepare_for_composite(&self) -> bool {
+    fn prepare_for_composite(&self, _width: usize, _height: usize) -> bool {
         true
     }
 
     #[cfg(target_os="linux")]
     fn native_metadata(&self) -> NativeGraphicsMetadata {
         NativeGraphicsMetadata {
             display: ptr::null_mut()
         }
--- a/servo/ports/gonk/Cargo.lock
+++ b/servo/ports/gonk/Cargo.lock
@@ -522,31 +522,31 @@ dependencies = [
 [[package]]
 name = "khronos_api"
 version = "0.0.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "layers"
 version = "0.1.0"
-source = "git+https://github.com/servo/rust-layers#ff65707d621498949ed428077da7e42a9f9d2745"
+source = "git+https://github.com/servo/rust-layers#cfc29e48a11f0c1e5390a049850c3ba10f23e0ad"
 dependencies = [
  "azure 0.1.0 (git+https://github.com/servo/rust-azure)",
  "cgl 0.0.1 (git+https://github.com/servo/rust-cgl)",
  "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)",
  "egl 0.1.0 (git+https://github.com/servo/rust-egl)",
  "geom 0.1.0 (git+https://github.com/servo/rust-geom)",
  "gleam 0.0.1 (git+https://github.com/servo/gleam)",
  "glx 0.0.1 (git+https://github.com/servo/rust-glx)",
  "io_surface 0.1.0 (git+https://github.com/servo/rust-io-surface)",
  "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "skia 0.0.20130412 (git+https://github.com/servo/skia)",
- "xlib 0.1.0 (git+https://github.com/servo/rust-xlib)",
+ "x11 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "layout"
 version = "0.0.1"
 dependencies = [
  "azure 0.1.0 (git+https://github.com/servo/rust-azure)",
  "bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -720,27 +720,27 @@ version = "0.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "offscreen_gl_context"
 version = "0.0.1"
-source = "git+https://github.com/ecoal95/rust-offscreen-rendering-context#97eacf34b72f69b10130a0de016529e98ee32f04"
+source = "git+https://github.com/ecoal95/rust-offscreen-rendering-context#99cee719a811f28e70fe33fa71137663ac210487"
 dependencies = [
  "cgl 0.0.1 (git+https://github.com/servo/rust-cgl)",
  "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)",
  "geom 0.1.0 (git+https://github.com/servo/rust-geom)",
  "gleam 0.0.1 (git+https://github.com/servo/gleam)",
  "glx 0.0.1 (git+https://github.com/servo/rust-glx)",
  "layers 0.1.0 (git+https://github.com/servo/rust-layers)",
  "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "xlib 0.1.0 (git+https://github.com/servo/rust-xlib)",
+ "x11 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "openssl"
 version = "0.6.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1173,16 +1173,25 @@ dependencies = [
 name = "winapi"
 version = "0.1.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "x11"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pkg-config 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "xlib"
 version = "0.1.0"
 source = "git+https://github.com/servo/rust-xlib#1a0f3d48fbebf96e2d1bf83ac71309b27f49e0c7"
 dependencies = [
  "bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
--- a/servo/ports/gonk/src/window.rs
+++ b/servo/ports/gonk/src/window.rs
@@ -826,17 +826,17 @@ impl WindowMethods for Window {
              event_sender: window.as_ref().unwrap().event_send.clone(),
          } as Box<CompositorProxy+Send>,
          box receiver as Box<CompositorReceiver>)
     }
 
     fn set_cursor(&self, _: Cursor) {
     }
 
-    fn prepare_for_composite(&self) -> bool {
+    fn prepare_for_composite(&self, _width: usize, _height: usize) -> bool {
         true
     }
 }
 
 struct GonkCompositorProxy {
     sender: Sender<compositor_task::Msg>,
     event_sender: Sender<WindowEvent>,
 }