mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
auto merge of #466 : pcwalton/servo/phantom-type, r=pcwalton
See the explanation on the commit for more detail. r? @metajack
This commit is contained in:
commit
90b01df4c3
286 changed files with 483 additions and 487 deletions
54
Makefile.in
54
Makefile.in
|
@ -171,35 +171,35 @@ $(eval $(call DEF_SUBMODULE_RULES,$(submodule))))
|
|||
|
||||
DONE_SUBMODULES = $(foreach submodule,$(SUBMODULES),$(DONE_$(submodule)))
|
||||
|
||||
RFLAGS_servo_util = $(strip $(CFG_RUSTC_FLAGS)) $(addprefix -L $(B)src/,$(DEPS_SUBMODULES))
|
||||
SRC_servo_util = $(call rwildcard,$(S)src/components/servo-util/,*.rs)
|
||||
CRATE_servo_util = $(S)src/components/servo-util/servo_util.rc
|
||||
DONE_servo_util = $(B)src/components/servo-util/libservoutil.dummy
|
||||
RFLAGS_util = $(strip $(CFG_RUSTC_FLAGS)) $(addprefix -L $(B)src/,$(DEPS_SUBMODULES))
|
||||
SRC_util = $(call rwildcard,$(S)src/components/util/,*.rs)
|
||||
CRATE_util = $(S)src/components/util/util.rc
|
||||
DONE_util = $(B)src/components/util/libutil.dummy
|
||||
|
||||
DEPS_servo_util = $(CRATE_servo_util) $(SRC_servo_util) $(DONE_SUBMODULES)
|
||||
DEPS_util = $(CRATE_util) $(SRC_util) $(DONE_SUBMODULES)
|
||||
|
||||
RFLAGS_servo_net = $(strip $(CFG_RUSTC_FLAGS)) $(addprefix -L $(B)src/,$(DEPS_SUBMODULES)) -L $(B)src/components/servo-util
|
||||
SRC_servo_net = $(call rwildcard,$(S)src/components/servo-net/,*.rs)
|
||||
CRATE_servo_net = $(S)src/components/servo-net/servo_net.rc
|
||||
DONE_servo_net = $(B)src/components/servo-net/libservonet.dummy
|
||||
RFLAGS_net = $(strip $(CFG_RUSTC_FLAGS)) $(addprefix -L $(B)src/,$(DEPS_SUBMODULES)) -L $(B)src/components/util
|
||||
SRC_net = $(call rwildcard,$(S)src/components/net/,*.rs)
|
||||
CRATE_net = $(S)src/components/net/net.rc
|
||||
DONE_net = $(B)src/components/net/libnet.dummy
|
||||
|
||||
DEPS_servo_net = $(CRATE_servo_net) $(SRC_servo_net) $(DONE_SUBMODULES) $(DONE_servo_util)
|
||||
DEPS_net = $(CRATE_net) $(SRC_net) $(DONE_SUBMODULES) $(DONE_util)
|
||||
|
||||
RFLAGS_servo_gfx = $(strip $(CFG_RUSTC_FLAGS)) $(addprefix -L $(B)src/,$(DEPS_SUBMODULES)) -L $(B)src/components/servo-util -L $(B)src/components/servo-net
|
||||
SRC_servo_gfx = $(call rwildcard,$(S)src/components/servo-gfx/,*.rs)
|
||||
CRATE_servo_gfx = $(S)src/components/servo-gfx/servo_gfx.rc
|
||||
DONE_servo_gfx = $(B)src/components/servo-gfx/libservogfx.dummy
|
||||
RFLAGS_gfx = $(strip $(CFG_RUSTC_FLAGS)) $(addprefix -L $(B)src/,$(DEPS_SUBMODULES)) -L $(B)src/components/util -L $(B)src/components/net
|
||||
SRC_gfx = $(call rwildcard,$(S)src/components/gfx/,*.rs)
|
||||
CRATE_gfx = $(S)src/components/gfx/gfx.rc
|
||||
DONE_gfx = $(B)src/components/gfx/libgfx.dummy
|
||||
|
||||
DEPS_servo_gfx = $(CRATE_servo_gfx) $(SRC_servo_gfx) $(DONE_SUBMODULES) $(DONE_servo_util) $(DONE_servo_net)
|
||||
DEPS_gfx = $(CRATE_gfx) $(SRC_gfx) $(DONE_SUBMODULES) $(DONE_util) $(DONE_net)
|
||||
|
||||
RFLAGS_servo = $(strip $(CFG_RUSTC_FLAGS)) $(addprefix -L $(B)src/,$(DEPS_SUBMODULES)) -L $(B)src/components/servo-gfx -L $(B)src/components/servo-util -L $(B)src/components/servo-net
|
||||
RFLAGS_servo = $(strip $(CFG_RUSTC_FLAGS)) $(addprefix -L $(B)src/,$(DEPS_SUBMODULES)) -L $(B)src/components/gfx -L $(B)src/components/util -L $(B)src/components/net
|
||||
|
||||
WEBIDL_servo = $(call rwildcard,$(S)src/components/servo/,*.webidl)
|
||||
WEBIDL_servo = $(call rwildcard,$(S)src/components/main/,*.webidl)
|
||||
AUTOGEN_SRC_servo = $(patsubst %.webidl, %Binding.rs, $(WEBIDL_servo))
|
||||
SRC_servo = $(call rwildcard,$(S)src/components/servo/,*.rs) $(AUTOGEN_SRC_servo)
|
||||
CRATE_servo = $(S)src/components/servo/servo.rc
|
||||
SRC_servo = $(call rwildcard,$(S)src/components/main/,*.rs) $(AUTOGEN_SRC_servo)
|
||||
CRATE_servo = $(S)src/components/main/servo.rc
|
||||
|
||||
DEPS_servo = $(CRATE_servo) $(SRC_servo) $(DONE_SUBMODULES) $(DONE_servo_util) $(DONE_servo_gfx) $(DONE_servo_net)
|
||||
DEPS_servo = $(CRATE_servo) $(SRC_servo) $(DONE_SUBMODULES) $(DONE_util) $(DONE_gfx) $(DONE_net)
|
||||
|
||||
# rules that depend on having correct meta-target vars (DEPS_CLEAN, DEPS_servo, etc)
|
||||
include $(S)mk/check.mk
|
||||
|
@ -211,16 +211,16 @@ all: servo package
|
|||
|
||||
# Servo helper libraries
|
||||
|
||||
$(DONE_servo_util): $(DEPS_servo_util)
|
||||
$(RUSTC) $(RFLAGS_servo_util) -o $@ $< && touch $@
|
||||
$(DONE_util): $(DEPS_util)
|
||||
$(RUSTC) $(RFLAGS_util) -o $@ $< && touch $@
|
||||
|
||||
$(DONE_servo_net): $(DEPS_servo_net)
|
||||
$(RUSTC) $(RFLAGS_servo_net) -o $@ $< && touch $@
|
||||
$(DONE_net): $(DEPS_net)
|
||||
$(RUSTC) $(RFLAGS_net) -o $@ $< && touch $@
|
||||
|
||||
$(DONE_servo_gfx): $(DEPS_servo_gfx)
|
||||
$(RUSTC) $(RFLAGS_servo_gfx) -o $@ $< && touch $@
|
||||
$(DONE_gfx): $(DEPS_gfx)
|
||||
$(RUSTC) $(RFLAGS_gfx) -o $@ $< && touch $@
|
||||
|
||||
BINDINGS_SRC = $(S)/src/components/servo/dom/bindings/codegen
|
||||
BINDINGS_SRC = $(S)/src/components/main/dom/bindings/codegen
|
||||
|
||||
CACHE_DIR = $(BINDINGS_SRC)/_cache
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# The Servo Parallel Browser Project
|
||||
zRThe Servo Parallel Browser Project
|
||||
|
||||
Servo is a prototype web browser engine written in the [Rust](https://github.com/mozilla/rust)
|
||||
language. It is currently developed on 64bit OS X and 64bit Linux.
|
||||
|
@ -36,7 +36,7 @@ cd servo
|
|||
mkdir -p build && cd build
|
||||
../configure
|
||||
make && make check
|
||||
./servo ../src/test/about-mozilla.html
|
||||
./servo ../src/test/html/about-mozilla.html
|
||||
```
|
||||
|
||||
[issue]: https://github.com/mxcl/homebrew/issues/5117
|
||||
|
|
9
configure
vendored
9
configure
vendored
|
@ -449,10 +449,11 @@ do
|
|||
make_dir ${CFG_BUILD_DIR}src/${i}
|
||||
done
|
||||
|
||||
make_dir ${CFG_BUILD_DIR}src/components/servo-util
|
||||
make_dir ${CFG_BUILD_DIR}src/components/servo-net
|
||||
make_dir ${CFG_BUILD_DIR}src/components/servo-gfx
|
||||
make_dir src/test/ref
|
||||
make_dir ${CFG_BUILD_DIR}src/components/util
|
||||
make_dir ${CFG_BUILD_DIR}src/components/net
|
||||
make_dir ${CFG_BUILD_DIR}src/components/gfx
|
||||
make_dir ${CFG_BUILD_DIR}src/components/main
|
||||
make_dir src/test/html/ref
|
||||
make_dir src/compiler/rust
|
||||
|
||||
# TODO: don't run configure on submodules unless necessary. For an example,
|
||||
|
|
|
@ -20,10 +20,10 @@ $(eval $(call DEF_SUBMODULE_TEST_RULES,$(submodule))))
|
|||
servo-test: $(DEPS_servo)
|
||||
$(RUSTC) $(RFLAGS_servo) --test -o $@ $<
|
||||
|
||||
reftest: $(S)src/reftest/reftest.rs servo
|
||||
reftest: $(S)src/test/harness/reftest/reftest.rs servo
|
||||
$(RUSTC) $(RFLAGS_servo) -o $@ $< -L .
|
||||
|
||||
contenttest: $(S)src/contenttest/contenttest.rs servo
|
||||
contenttest: $(S)src/test/harness/contenttest/contenttest.rs servo
|
||||
$(RUSTC) $(RFLAGS_servo) -o $@ $< -L .
|
||||
|
||||
DEPS_CHECK_TARGETS_ALL = $(addprefix check-,$(DEPS_CHECK_ALL))
|
||||
|
@ -39,7 +39,7 @@ check-servo: servo-test
|
|||
./servo-test $(TESTNAME)
|
||||
|
||||
check-ref: reftest
|
||||
./reftest --source-dir=$(S)/src/test/ref --work-dir=src/test/ref $(TESTNAME)
|
||||
./reftest --source-dir=$(S)/src/test/html/ref --work-dir=src/test/html/ref $(TESTNAME)
|
||||
|
||||
check-content: contenttest
|
||||
./contenttest --source-dir=$(S)/src/test/content $(TESTNAME)
|
||||
|
|
14
mk/clean.mk
14
mk/clean.mk
|
@ -25,14 +25,14 @@ clean-fast: $(DEPS_CLEAN_TARGETS_FAST) clean-servo
|
|||
$(Q)echo "Cleaning targets:"
|
||||
$(Q)echo "$(filter-out $(SLOW_BUILDS),$(DEPS_CLEAN_ALL))"
|
||||
|
||||
clean-servo-util:
|
||||
cd $(B)/src/components/servo-util/ && rm -rf libservo_util*.dylib $(DONE_servo_util)
|
||||
clean-util:
|
||||
cd $(B)/src/components/util/ && rm -rf libservo_util*.dylib $(DONE_servo_util)
|
||||
|
||||
clean-servo-net:
|
||||
cd $(B)/src/components/servo-net/ && rm -rf libservo_net*.dylib $(DONE_servo_net)
|
||||
clean-net:
|
||||
cd $(B)/src/components/net/ && rm -rf libservo_net*.dylib $(DONE_servo_net)
|
||||
|
||||
clean-servo-gfx:
|
||||
cd $(B)/src/components/servo-gfx/ && rm -rf libservo_gfx*.dylib $(DONE_servo_gfx)
|
||||
clean-gfx:
|
||||
cd $(B)/src/components/gfx/ && rm -rf libservo_gfx*.dylib $(DONE_servo_gfx)
|
||||
|
||||
clean-servo: clean-servo-gfx clean-servo-util clean-servo-net
|
||||
clean-servo: clean-gfx clean-util clean-net
|
||||
rm -f servo servo-test
|
||||
|
|
|
@ -3,12 +3,10 @@ crate or library.
|
|||
|
||||
## Servo components
|
||||
|
||||
* `components/contenttest`: JavaScript test runner.
|
||||
* `components/reftest`: Reference (layout) test runner.
|
||||
* `components/servo`: The top-level Servo crate. Contains compositing, DOM, layout, and script.
|
||||
* `components/servo-gfx`: Graphics rendering, fonts, and text shaping.
|
||||
* `components/servo-net`: Networking, caching, image decoding.
|
||||
* `components/servo-util`: Various utility functions used by other Servo components.
|
||||
* `components/gfx`: Graphics rendering, fonts, and text shaping.
|
||||
* `components/main`: The top-level Servo crate. Contains compositing, DOM, layout, and script.
|
||||
* `components/net`: Networking, caching, image decoding.
|
||||
* `components/util`: Various utility functions used by other Servo components.
|
||||
|
||||
## The Rust compiler
|
||||
|
||||
|
@ -60,9 +58,14 @@ they are designed to be useful in other Rust projects.
|
|||
* `platform/macos/rust-core-text`: Bindings to Core Text.
|
||||
* `platform/macos/rust-io-surface`: Bindings to the `IOSurface` library.
|
||||
|
||||
## Tests
|
||||
|
||||
* `test/harness/contenttest`: JavaScript test runner.
|
||||
* `test/harness/reftest`: Reference (layout) test runner.
|
||||
* `test/html`: Test cases.
|
||||
|
||||
## Miscellaneous
|
||||
|
||||
* `etc`: Various scripts and files that don't belong anywhere else.
|
||||
* `etc/patches`: Patches for upstream libraries.
|
||||
* `test`: Test cases.
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ pub struct LayerBufferSet {
|
|||
/// The interface used to by the renderer to acquire draw targets for each rendered frame and
|
||||
/// submit them to be drawn to the display.
|
||||
pub trait Compositor {
|
||||
fn begin_drawing(&self, next_dt: comm::Chan<LayerBufferSet>);
|
||||
fn draw(&self, next_dt: comm::Chan<LayerBufferSet>, draw_me: LayerBufferSet);
|
||||
fn paint(&self, layer_buffer_set: LayerBufferSet);
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
* 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/. */
|
||||
|
||||
#[link(name = "servo_gfx",
|
||||
#[link(name = "gfx",
|
||||
vers = "0.1",
|
||||
uuid = "0106bb54-6ea9-45bf-a39e-a738621f15e5",
|
||||
url = "http://servo.org/")];
|
||||
|
@ -13,8 +13,8 @@ extern mod geom;
|
|||
extern mod http_client;
|
||||
extern mod stb_image;
|
||||
extern mod std;
|
||||
extern mod servo_net;
|
||||
extern mod servo_util (name = "servo_util");
|
||||
extern mod servo_net (name = "net");
|
||||
extern mod servo_util (name = "util");
|
||||
|
||||
// Eventually we would like the shaper to be pluggable, as many operating systems have their own
|
||||
// shapers. For now, however, this is a hard dependency.
|
|
@ -134,6 +134,8 @@ pub fn render_layers(layer_ref: *RenderLayer,
|
|||
}
|
||||
}
|
||||
|
||||
return LayerBufferSet { buffers: new_buffers };
|
||||
LayerBufferSet {
|
||||
buffers: new_buffers,
|
||||
}
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
// The task that handles all rendering/painting.
|
||||
|
||||
use azure::AzFloat;
|
||||
use compositor::{Compositor, LayerBufferSet};
|
||||
use compositor::Compositor;
|
||||
use font_context::FontContext;
|
||||
use geom::matrix2d::Matrix2D;
|
||||
use opts::Opts;
|
||||
|
@ -13,67 +13,81 @@ use render_context::RenderContext;
|
|||
use render_layers::{RenderLayer, render_layers};
|
||||
|
||||
use core::cell::Cell;
|
||||
use core::comm::{Port, SharedChan};
|
||||
use core::comm::{Chan, Port, SharedChan};
|
||||
use core::task::SingleThreaded;
|
||||
use std::task_pool::TaskPool;
|
||||
use servo_net::util::spawn_listener;
|
||||
|
||||
use servo_util::time;
|
||||
use servo_util::time::time;
|
||||
use servo_util::time::profile;
|
||||
use servo_util::time::ProfilerChan;
|
||||
use servo_util::time::profile;
|
||||
use servo_util::time::time;
|
||||
use servo_util::time;
|
||||
|
||||
pub enum Msg {
|
||||
RenderMsg(RenderLayer),
|
||||
ExitMsg(comm::Chan<()>)
|
||||
ExitMsg(Chan<()>),
|
||||
}
|
||||
|
||||
pub type RenderTask = SharedChan<Msg>;
|
||||
#[deriving(Clone)]
|
||||
pub struct RenderTask {
|
||||
channel: SharedChan<Msg>,
|
||||
}
|
||||
|
||||
pub fn RenderTask<C:Compositor + Owned>(compositor: C,
|
||||
opts: Opts,
|
||||
prof_chan: ProfilerChan) -> RenderTask {
|
||||
let compositor_cell = Cell(compositor);
|
||||
let opts_cell = Cell(opts);
|
||||
let render_task = do spawn_listener |po: Port<Msg>| {
|
||||
let (layer_buffer_set_port, layer_buffer_channel) = comm::stream();
|
||||
impl RenderTask {
|
||||
pub fn new<C:Compositor + Owned>(compositor: C,
|
||||
opts: Opts,
|
||||
profiler_chan: ProfilerChan)
|
||||
-> RenderTask {
|
||||
let compositor_cell = Cell(compositor);
|
||||
let opts_cell = Cell(opts);
|
||||
let (port, chan) = comm::stream();
|
||||
let port = Cell(port);
|
||||
|
||||
let compositor = compositor_cell.take();
|
||||
compositor.begin_drawing(layer_buffer_channel);
|
||||
do spawn {
|
||||
let compositor = compositor_cell.take();
|
||||
|
||||
// FIXME: Annoying three-cell dance here. We need one-shot closures.
|
||||
let opts = opts_cell.with_ref(|o| copy *o);
|
||||
let n_threads = opts.n_render_threads;
|
||||
let new_opts_cell = Cell(opts);
|
||||
let prof_chan2 = prof_chan.clone();
|
||||
// FIXME: Annoying three-cell dance here. We need one-shot closures.
|
||||
let opts = opts_cell.with_ref(|o| copy *o);
|
||||
let n_threads = opts.n_render_threads;
|
||||
let new_opts_cell = Cell(opts);
|
||||
|
||||
let thread_pool = do TaskPool::new(n_threads, Some(SingleThreaded)) {
|
||||
let opts_cell = Cell(new_opts_cell.with_ref(|o| copy *o));
|
||||
let prof_chan = prof_chan2.clone();
|
||||
let f: ~fn(uint) -> ThreadRenderContext = |thread_index| {
|
||||
ThreadRenderContext {
|
||||
thread_index: thread_index,
|
||||
font_ctx: @mut FontContext::new(opts_cell.with_ref(|o| o.render_backend),
|
||||
false,
|
||||
prof_chan.clone()),
|
||||
opts: opts_cell.with_ref(|o| copy *o),
|
||||
}
|
||||
let profiler_chan = profiler_chan.clone();
|
||||
let profiler_chan_copy = profiler_chan.clone();
|
||||
|
||||
let thread_pool = do TaskPool::new(n_threads, Some(SingleThreaded)) {
|
||||
let opts_cell = Cell(new_opts_cell.with_ref(|o| copy *o));
|
||||
let profiler_chan = Cell(profiler_chan.clone());
|
||||
|
||||
let f: ~fn(uint) -> ThreadRenderContext = |thread_index| {
|
||||
let opts = opts_cell.with_ref(|opts| copy *opts);
|
||||
|
||||
ThreadRenderContext {
|
||||
thread_index: thread_index,
|
||||
font_ctx: @mut FontContext::new(opts.render_backend,
|
||||
false,
|
||||
profiler_chan.take()),
|
||||
opts: opts,
|
||||
}
|
||||
};
|
||||
f
|
||||
};
|
||||
f
|
||||
};
|
||||
|
||||
// FIXME: rust/#5967
|
||||
let mut r = Renderer {
|
||||
port: po,
|
||||
compositor: compositor,
|
||||
layer_buffer_set_port: Cell(layer_buffer_set_port),
|
||||
thread_pool: thread_pool,
|
||||
opts: opts_cell.take(),
|
||||
prof_chan: prof_chan.clone()
|
||||
};
|
||||
r.start();
|
||||
};
|
||||
SharedChan::new(render_task)
|
||||
// FIXME: rust/#5967
|
||||
let mut renderer = Renderer {
|
||||
port: port.take(),
|
||||
compositor: compositor,
|
||||
thread_pool: thread_pool,
|
||||
opts: opts_cell.take(),
|
||||
profiler_chan: profiler_chan_copy,
|
||||
};
|
||||
|
||||
renderer.start();
|
||||
}
|
||||
|
||||
RenderTask {
|
||||
channel: SharedChan::new(chan),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Data that needs to be kept around for each render thread.
|
||||
|
@ -86,10 +100,11 @@ priv struct ThreadRenderContext {
|
|||
priv struct Renderer<C> {
|
||||
port: Port<Msg>,
|
||||
compositor: C,
|
||||
layer_buffer_set_port: Cell<comm::Port<LayerBufferSet>>,
|
||||
thread_pool: TaskPool<ThreadRenderContext>,
|
||||
opts: Opts,
|
||||
prof_chan: ProfilerChan,
|
||||
|
||||
/// A channel to the profiler.
|
||||
profiler_chan: ProfilerChan,
|
||||
}
|
||||
|
||||
impl<C: Compositor + Owned> Renderer<C> {
|
||||
|
@ -108,26 +123,13 @@ impl<C: Compositor + Owned> Renderer<C> {
|
|||
}
|
||||
|
||||
fn render(&mut self, render_layer: RenderLayer) {
|
||||
debug!("renderer: got render request");
|
||||
|
||||
let layer_buffer_set_port = self.layer_buffer_set_port.take();
|
||||
|
||||
if !layer_buffer_set_port.peek() {
|
||||
warn!("renderer: waiting on layer buffer");
|
||||
}
|
||||
|
||||
let (new_layer_buffer_set_port, layer_buffer_set_channel) = comm::stream();
|
||||
self.layer_buffer_set_port.put_back(new_layer_buffer_set_port);
|
||||
|
||||
let layer_buffer_set_channel_cell = Cell(layer_buffer_set_channel);
|
||||
|
||||
debug!("renderer: rendering");
|
||||
|
||||
do profile(time::RenderingCategory, self.prof_chan.clone()) {
|
||||
let layer_buffer_set_channel = layer_buffer_set_channel_cell.take();
|
||||
|
||||
let layer_buffer_set = do render_layers(&render_layer, &self.opts, self.prof_chan.clone())
|
||||
|render_layer_ref, layer_buffer, buffer_chan| {
|
||||
do time("rendering") {
|
||||
let layer_buffer_set = do render_layers(&render_layer,
|
||||
&self.opts,
|
||||
self.profiler_chan.clone()) |render_layer_ref,
|
||||
layer_buffer,
|
||||
buffer_chan| {
|
||||
let layer_buffer_cell = Cell(layer_buffer);
|
||||
do self.thread_pool.execute |thread_render_context| {
|
||||
do layer_buffer_cell.with_ref |layer_buffer| {
|
||||
|
@ -160,7 +162,8 @@ impl<C: Compositor + Owned> Renderer<C> {
|
|||
};
|
||||
|
||||
debug!("renderer: returning surface");
|
||||
self.compositor.draw(layer_buffer_set_channel, layer_buffer_set);
|
||||
self.compositor.paint(layer_buffer_set);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,16 +7,14 @@ use platform::{Application, Window};
|
|||
use scripting::script_task::{LoadMsg, ScriptMsg};
|
||||
use windowing::{ApplicationMethods, WindowMethods};
|
||||
|
||||
use azure::azure_hl::{BackendType, B8G8R8A8, DataSourceSurface, DrawTarget, SourceSurfaceMethods};
|
||||
use azure::azure_hl::{DataSourceSurface, DrawTarget, SourceSurfaceMethods};
|
||||
use core::cell::Cell;
|
||||
use core::comm::{Chan, SharedChan, Port};
|
||||
use core::util;
|
||||
use geom::matrix::identity;
|
||||
use geom::point::Point2D;
|
||||
use geom::rect::Rect;
|
||||
use geom::size::Size2D;
|
||||
use gfx::compositor::{Compositor, LayerBuffer, LayerBufferSet};
|
||||
use gfx::opts::Opts;
|
||||
use gfx::compositor::{Compositor, LayerBufferSet};
|
||||
use layers::layers::{ARGB32Format, BasicImageData, ContainerLayer, ContainerLayerKind, Format};
|
||||
use layers::layers::{Image, ImageData, ImageLayer, ImageLayerKind, RGB24Format, WithDataFn};
|
||||
use layers::rendergl;
|
||||
|
@ -29,33 +27,39 @@ mod resize_rate_limiter;
|
|||
|
||||
/// The implementation of the layers-based compositor.
|
||||
#[deriving(Clone)]
|
||||
pub struct CompositorImpl {
|
||||
chan: SharedChan<Msg>
|
||||
pub struct CompositorTask {
|
||||
/// A channel on which messages can be sent to the compositor.
|
||||
chan: SharedChan<Msg>,
|
||||
}
|
||||
|
||||
impl CompositorImpl {
|
||||
/// Creates a new compositor instance.
|
||||
impl CompositorTask {
|
||||
/// Starts the compositor. Returns an interface that can be used to communicate with the
|
||||
/// compositor and a port which allows notification when the compositor shuts down.
|
||||
pub fn new(script_chan: SharedChan<ScriptMsg>,
|
||||
opts: Opts,
|
||||
prof_chan: ProfilerChan)
|
||||
-> CompositorImpl {
|
||||
profiler_chan: ProfilerChan)
|
||||
-> (CompositorTask, Port<()>) {
|
||||
let script_chan = Cell(script_chan);
|
||||
let (shutdown_port, shutdown_chan) = stream();
|
||||
let shutdown_chan = Cell(shutdown_chan);
|
||||
|
||||
let chan: Chan<Msg> = do on_osmain |port| {
|
||||
debug!("preparing to enter main loop");
|
||||
run_main_loop(port, script_chan.take(), &opts, prof_chan.clone());
|
||||
run_main_loop(port,
|
||||
script_chan.take(),
|
||||
shutdown_chan.take(),
|
||||
profiler_chan.clone());
|
||||
};
|
||||
|
||||
CompositorImpl {
|
||||
chan: SharedChan::new(chan)
|
||||
}
|
||||
let task = CompositorTask {
|
||||
chan: SharedChan::new(chan),
|
||||
};
|
||||
(task, shutdown_port)
|
||||
}
|
||||
}
|
||||
|
||||
/// Messages to the compositor.
|
||||
pub enum Msg {
|
||||
BeginDrawing(Chan<LayerBufferSet>),
|
||||
Draw(Chan<LayerBufferSet>, LayerBufferSet),
|
||||
AddKeyHandler(Chan<()>),
|
||||
Paint(LayerBufferSet),
|
||||
Exit
|
||||
}
|
||||
|
||||
|
@ -84,18 +88,19 @@ impl ImageData for AzureDrawTargetImageData {
|
|||
}
|
||||
}
|
||||
|
||||
fn run_main_loop(po: Port<Msg>, script_chan: SharedChan<ScriptMsg>, opts: &Opts, prof_chan:ProfilerChan) {
|
||||
fn run_main_loop(port: Port<Msg>,
|
||||
script_chan: SharedChan<ScriptMsg>,
|
||||
shutdown_chan: Chan<()>,
|
||||
profiler_chan: ProfilerChan) {
|
||||
let app: Application = ApplicationMethods::new();
|
||||
let window: @mut Window = WindowMethods::new(&app);
|
||||
let resize_rate_limiter = @mut ResizeRateLimiter(script_chan.clone());
|
||||
|
||||
let surfaces = @mut SurfaceSet::new(opts.render_backend);
|
||||
let context = rendergl::init_render_context();
|
||||
|
||||
// Create an initial layer tree.
|
||||
//
|
||||
// TODO: There should be no initial layer tree until the renderer creates one from the display
|
||||
// list. This is only here because we don't have that logic in the renderer yet.
|
||||
let context = rendergl::init_render_context();
|
||||
let root_layer = @mut ContainerLayer();
|
||||
let original_layer_transform;
|
||||
{
|
||||
|
@ -108,7 +113,6 @@ fn run_main_loop(po: Port<Msg>, script_chan: SharedChan<ScriptMsg>, opts: &Opts,
|
|||
}
|
||||
|
||||
let scene = @mut Scene(ContainerLayerKind(root_layer), Size2D(800.0, 600.0), identity());
|
||||
let key_handlers: @mut ~[Chan<()>] = @mut ~[];
|
||||
let done = @mut false;
|
||||
|
||||
// FIXME: This should not be a separate offset applied after the fact but rather should be
|
||||
|
@ -121,24 +125,19 @@ fn run_main_loop(po: Port<Msg>, script_chan: SharedChan<ScriptMsg>, opts: &Opts,
|
|||
resize_rate_limiter.check_resize_response();
|
||||
|
||||
// Handle messages
|
||||
while po.peek() {
|
||||
match po.recv() {
|
||||
AddKeyHandler(key_ch) => key_handlers.push(key_ch),
|
||||
BeginDrawing(sender) => surfaces.lend(sender),
|
||||
while port.peek() {
|
||||
match port.recv() {
|
||||
Exit => *done = true,
|
||||
|
||||
Draw(sender, draw_target) => {
|
||||
Paint(new_layer_buffer_set) => {
|
||||
debug!("osmain: received new frame");
|
||||
|
||||
// Perform a buffer swap.
|
||||
surfaces.put_back(draw_target);
|
||||
surfaces.lend(sender);
|
||||
let mut new_layer_buffer_set = new_layer_buffer_set;
|
||||
|
||||
// Iterate over the children of the container layer.
|
||||
let mut current_layer_child = root_layer.first_child;
|
||||
|
||||
// Replace the image layer data with the buffer data.
|
||||
let buffers = util::replace(&mut surfaces.front.layer_buffer_set.buffers, ~[]);
|
||||
let buffers = util::replace(&mut new_layer_buffer_set.buffers, ~[]);
|
||||
for buffers.each |buffer| {
|
||||
let width = buffer.rect.size.width as uint;
|
||||
let height = buffer.rect.size.height as uint;
|
||||
|
@ -183,14 +182,15 @@ fn run_main_loop(po: Port<Msg>, script_chan: SharedChan<ScriptMsg>, opts: &Opts,
|
|||
image_layer.common.set_transform(transform)
|
||||
}
|
||||
|
||||
surfaces.front.layer_buffer_set.buffers = buffers
|
||||
// TODO: Recycle the old buffers; send them back to the renderer to reuse if
|
||||
// it wishes.
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
do window.set_composite_callback {
|
||||
do profile(time::CompositingCategory, prof_chan.clone()) {
|
||||
do profile(time::CompositingCategory, profiler_chan.clone()) {
|
||||
debug!("compositor: compositing");
|
||||
// Adjust the layer dimensions as necessary to correspond to the size of the window.
|
||||
scene.size = window.size();
|
||||
|
@ -216,7 +216,7 @@ fn run_main_loop(po: Port<Msg>, script_chan: SharedChan<ScriptMsg>, opts: &Opts,
|
|||
|
||||
// When the user scrolls, move the layer around.
|
||||
do window.set_scroll_callback |delta| {
|
||||
// FIXME: Can't use `+=` due to a Rust bug.
|
||||
// FIXME (Rust #2528): Can't use `+=`.
|
||||
let world_offset_copy = *world_offset;
|
||||
*world_offset = world_offset_copy + delta;
|
||||
|
||||
|
@ -235,104 +235,28 @@ fn run_main_loop(po: Port<Msg>, script_chan: SharedChan<ScriptMsg>, opts: &Opts,
|
|||
// Check for messages coming from the windowing system.
|
||||
window.check_loop();
|
||||
}
|
||||
|
||||
shutdown_chan.send(())
|
||||
}
|
||||
|
||||
/// Implementation of the abstract `Compositor` interface.
|
||||
impl Compositor for CompositorImpl {
|
||||
fn begin_drawing(&self, next_dt: Chan<LayerBufferSet>) {
|
||||
self.chan.send(BeginDrawing(next_dt))
|
||||
}
|
||||
fn draw(&self, next_dt: Chan<LayerBufferSet>, draw_me: LayerBufferSet) {
|
||||
self.chan.send(Draw(next_dt, draw_me))
|
||||
}
|
||||
}
|
||||
|
||||
struct SurfaceSet {
|
||||
front: Surface,
|
||||
back: Surface,
|
||||
}
|
||||
|
||||
impl SurfaceSet {
|
||||
/// Creates a new surface set.
|
||||
fn new(backend: BackendType) -> SurfaceSet {
|
||||
SurfaceSet {
|
||||
front: Surface::new(backend),
|
||||
back: Surface::new(backend),
|
||||
}
|
||||
}
|
||||
|
||||
fn lend(&mut self, receiver: Chan<LayerBufferSet>) {
|
||||
// We are in a position to lend out the surface?
|
||||
assert!(self.front.have);
|
||||
// Ok then take it
|
||||
let old_layer_buffers = util::replace(&mut self.front.layer_buffer_set.buffers, ~[]);
|
||||
let new_layer_buffers = do old_layer_buffers.map |layer_buffer| {
|
||||
let draw_target_ref = &layer_buffer.draw_target;
|
||||
let layer_buffer = LayerBuffer {
|
||||
draw_target: draw_target_ref.clone(),
|
||||
rect: copy layer_buffer.rect,
|
||||
stride: layer_buffer.stride
|
||||
};
|
||||
debug!("osmain: lending surface %?", layer_buffer);
|
||||
layer_buffer
|
||||
};
|
||||
self.front.layer_buffer_set.buffers = old_layer_buffers;
|
||||
|
||||
let new_layer_buffer_set = LayerBufferSet { buffers: new_layer_buffers };
|
||||
receiver.send(new_layer_buffer_set);
|
||||
// Now we don't have it
|
||||
self.front.have = false;
|
||||
// But we (hopefully) have another!
|
||||
util::swap(&mut self.front, &mut self.back);
|
||||
// Let's look
|
||||
assert!(self.front.have);
|
||||
}
|
||||
|
||||
fn put_back(&mut self, layer_buffer_set: LayerBufferSet) {
|
||||
// We have room for a return
|
||||
assert!(self.front.have);
|
||||
assert!(!self.back.have);
|
||||
|
||||
self.back.layer_buffer_set = layer_buffer_set;
|
||||
|
||||
// Now we have it again
|
||||
self.back.have = true;
|
||||
}
|
||||
}
|
||||
|
||||
struct Surface {
|
||||
layer_buffer_set: LayerBufferSet,
|
||||
have: bool,
|
||||
}
|
||||
|
||||
impl Surface {
|
||||
fn new(backend: BackendType) -> Surface {
|
||||
let layer_buffer = LayerBuffer {
|
||||
draw_target: DrawTarget::new(backend, Size2D(800, 600), B8G8R8A8),
|
||||
rect: Rect(Point2D(0u, 0u), Size2D(800u, 600u)),
|
||||
stride: 800 * 4
|
||||
};
|
||||
let layer_buffer_set = LayerBufferSet {
|
||||
buffers: ~[ layer_buffer ]
|
||||
};
|
||||
Surface {
|
||||
layer_buffer_set: layer_buffer_set,
|
||||
have: true
|
||||
}
|
||||
impl Compositor for CompositorTask {
|
||||
fn paint(&self, layer_buffer_set: LayerBufferSet) {
|
||||
self.chan.send(Paint(layer_buffer_set))
|
||||
}
|
||||
}
|
||||
|
||||
/// A function for spawning into the platform's main thread.
|
||||
fn on_osmain<T: Owned>(f: ~fn(po: Port<T>)) -> Chan<T> {
|
||||
let (setup_po, setup_ch) = comm::stream();
|
||||
fn on_osmain<T: Owned>(f: ~fn(port: Port<T>)) -> Chan<T> {
|
||||
let (setup_port, setup_chan) = comm::stream();
|
||||
// FIXME: rust#6399
|
||||
let mut main_task = task::task();
|
||||
main_task.sched_mode(task::PlatformThread);
|
||||
do main_task.spawn {
|
||||
let (po, ch) = comm::stream();
|
||||
setup_ch.send(ch);
|
||||
f(po);
|
||||
let (port, chan) = comm::stream();
|
||||
setup_chan.send(chan);
|
||||
f(port);
|
||||
}
|
||||
setup_po.recv()
|
||||
setup_port.recv()
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
use css::node_util::NodeUtil;
|
||||
use css::select_handler::NodeSelectHandler;
|
||||
use dom::node::AbstractNode;
|
||||
use dom::node::{AbstractNode, LayoutView};
|
||||
use newcss::complete::CompleteSelectResults;
|
||||
use newcss::select::{SelectCtx, SelectResults};
|
||||
|
||||
|
@ -16,7 +16,7 @@ pub trait MatchMethods {
|
|||
fn restyle_subtree(&self, select_ctx: &SelectCtx);
|
||||
}
|
||||
|
||||
impl MatchMethods for AbstractNode {
|
||||
impl MatchMethods for AbstractNode<LayoutView> {
|
||||
/**
|
||||
* Performs CSS selector matching on a subtree.
|
||||
*
|
||||
|
@ -40,7 +40,8 @@ impl MatchMethods for AbstractNode {
|
|||
}
|
||||
}
|
||||
|
||||
fn compose_results(node: AbstractNode, results: SelectResults) -> CompleteSelectResults {
|
||||
fn compose_results(node: AbstractNode<LayoutView>, results: SelectResults)
|
||||
-> CompleteSelectResults {
|
||||
match find_parent_element_node(node) {
|
||||
None => CompleteSelectResults::new_root(results),
|
||||
Some(parent_node) => {
|
||||
|
@ -50,7 +51,7 @@ fn compose_results(node: AbstractNode, results: SelectResults) -> CompleteSelect
|
|||
}
|
||||
}
|
||||
|
||||
fn find_parent_element_node(node: AbstractNode) -> Option<AbstractNode> {
|
||||
fn find_parent_element_node(node: AbstractNode<LayoutView>) -> Option<AbstractNode<LayoutView>> {
|
||||
match node.parent_node() {
|
||||
Some(parent) if parent.is_element() => Some(parent),
|
||||
Some(parent) => find_parent_element_node(parent),
|
|
@ -5,7 +5,8 @@
|
|||
// Style retrieval from DOM elements.
|
||||
|
||||
use css::node_util::NodeUtil;
|
||||
use dom::node::AbstractNode;
|
||||
use dom::node::{AbstractNode, LayoutView};
|
||||
|
||||
use newcss::complete::CompleteStyle;
|
||||
|
||||
/// Node mixin providing `style` method that returns a `NodeStyle`
|
||||
|
@ -13,7 +14,7 @@ pub trait StyledNode {
|
|||
fn style(&self) -> CompleteStyle;
|
||||
}
|
||||
|
||||
impl StyledNode for AbstractNode {
|
||||
impl StyledNode for AbstractNode<LayoutView> {
|
||||
fn style(&self) -> CompleteStyle {
|
||||
assert!(self.is_element()); // Only elements can have styles
|
||||
let results = self.get_css_select_results();
|
|
@ -2,17 +2,18 @@
|
|||
* 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 dom::node::AbstractNode;
|
||||
use newcss::complete::CompleteSelectResults;
|
||||
use dom::node::{AbstractNode, LayoutView};
|
||||
use layout::aux::LayoutAuxMethods;
|
||||
|
||||
use core::cast::transmute;
|
||||
use newcss::complete::CompleteSelectResults;
|
||||
|
||||
pub trait NodeUtil<'self> {
|
||||
fn get_css_select_results(self) -> &'self CompleteSelectResults;
|
||||
fn set_css_select_results(self, decl: CompleteSelectResults);
|
||||
}
|
||||
|
||||
impl<'self> NodeUtil<'self> for AbstractNode {
|
||||
impl<'self> NodeUtil<'self> for AbstractNode<LayoutView> {
|
||||
/**
|
||||
* Provides the computed style for the given node. If CSS selector
|
||||
* Returns the style results for the given node. If CSS selector
|
|
@ -5,15 +5,15 @@
|
|||
//! CSS library requires that DOM nodes be convertable to *c_void through this trait
|
||||
extern mod netsurfcss;
|
||||
|
||||
use dom::node::AbstractNode;
|
||||
use dom::node::{AbstractNode, LayoutView};
|
||||
|
||||
use core::cast;
|
||||
|
||||
// FIXME: Rust #3908. rust-css can't reexport VoidPtrLike
|
||||
use css::node_void_ptr::netsurfcss::util::VoidPtrLike;
|
||||
|
||||
impl VoidPtrLike for AbstractNode {
|
||||
fn from_void_ptr(node: *libc::c_void) -> AbstractNode {
|
||||
impl VoidPtrLike for AbstractNode<LayoutView> {
|
||||
fn from_void_ptr(node: *libc::c_void) -> AbstractNode<LayoutView> {
|
||||
assert!(node.is_not_null());
|
||||
unsafe {
|
||||
cast::transmute(node)
|
|
@ -6,16 +6,16 @@
|
|||
/// Implementation of the callbacks that the CSS selector engine uses to query the DOM.
|
||||
///
|
||||
|
||||
use dom::node::AbstractNode;
|
||||
use dom::node::{AbstractNode, LayoutView};
|
||||
use newcss::select::SelectHandler;
|
||||
|
||||
use core::str::eq_slice;
|
||||
|
||||
pub struct NodeSelectHandler {
|
||||
node: AbstractNode
|
||||
node: AbstractNode<LayoutView>,
|
||||
}
|
||||
|
||||
fn with_node_name<R>(node: AbstractNode, f: &fn(&str) -> R) -> R {
|
||||
fn with_node_name<R>(node: AbstractNode<LayoutView>, f: &fn(&str) -> R) -> R {
|
||||
if !node.is_element() {
|
||||
fail!(~"attempting to style non-element node");
|
||||
}
|
||||
|
@ -24,12 +24,13 @@ fn with_node_name<R>(node: AbstractNode, f: &fn(&str) -> R) -> R {
|
|||
}
|
||||
}
|
||||
|
||||
impl SelectHandler<AbstractNode> for NodeSelectHandler {
|
||||
fn with_node_name<R>(&self, node: &AbstractNode, f: &fn(&str) -> R) -> R {
|
||||
impl SelectHandler<AbstractNode<LayoutView>> for NodeSelectHandler {
|
||||
fn with_node_name<R>(&self, node: &AbstractNode<LayoutView>, f: &fn(&str) -> R) -> R {
|
||||
with_node_name(*node, f)
|
||||
}
|
||||
|
||||
fn named_parent_node(&self, node: &AbstractNode, name: &str) -> Option<AbstractNode> {
|
||||
fn named_parent_node(&self, node: &AbstractNode<LayoutView>, name: &str)
|
||||
-> Option<AbstractNode<LayoutView>> {
|
||||
match node.parent_node() {
|
||||
Some(parent) => {
|
||||
do with_node_name(parent) |node_name| {
|
||||
|
@ -44,12 +45,13 @@ impl SelectHandler<AbstractNode> for NodeSelectHandler {
|
|||
}
|
||||
}
|
||||
|
||||
fn parent_node(&self, node: &AbstractNode) -> Option<AbstractNode> {
|
||||
fn parent_node(&self, node: &AbstractNode<LayoutView>) -> Option<AbstractNode<LayoutView>> {
|
||||
node.parent_node()
|
||||
}
|
||||
|
||||
// TODO: Use a Bloom filter.
|
||||
fn named_ancestor_node(&self, node: &AbstractNode, name: &str) -> Option<AbstractNode> {
|
||||
fn named_ancestor_node(&self, node: &AbstractNode<LayoutView>, name: &str)
|
||||
-> Option<AbstractNode<LayoutView>> {
|
||||
let mut node = *node;
|
||||
loop {
|
||||
let parent = node.parent_node();
|
||||
|
@ -71,11 +73,11 @@ impl SelectHandler<AbstractNode> for NodeSelectHandler {
|
|||
}
|
||||
}
|
||||
|
||||
fn node_is_root(&self, node: &AbstractNode) -> bool {
|
||||
fn node_is_root(&self, node: &AbstractNode<LayoutView>) -> bool {
|
||||
self.parent_node(node).is_none()
|
||||
}
|
||||
|
||||
fn with_node_id<R>(&self, node: &AbstractNode, f: &fn(Option<&str>) -> R) -> R {
|
||||
fn with_node_id<R>(&self, node: &AbstractNode<LayoutView>, f: &fn(Option<&str>) -> R) -> R {
|
||||
if !node.is_element() {
|
||||
fail!(~"attempting to style non-element node");
|
||||
}
|
||||
|
@ -84,7 +86,7 @@ impl SelectHandler<AbstractNode> for NodeSelectHandler {
|
|||
}
|
||||
}
|
||||
|
||||
fn node_has_id(&self, node: &AbstractNode, id: &str) -> bool {
|
||||
fn node_has_id(&self, node: &AbstractNode<LayoutView>, id: &str) -> bool {
|
||||
if !node.is_element() {
|
||||
fail!(~"attempting to style non-element node");
|
||||
}
|
|
@ -513,7 +513,7 @@ addExternalIface('CSSValue')
|
|||
addExternalIface('Document', nativeType='Document', pointerType='@mut ')
|
||||
addExternalIface('DOMStringList', nativeType='nsDOMStringList',
|
||||
headerFile='nsDOMLists.h')
|
||||
addExternalIface('Element', nativeType='AbstractNode', pointerType='')
|
||||
addExternalIface('Element', nativeType='AbstractNode<ScriptView>', pointerType='')
|
||||
addExternalIface('File')
|
||||
addExternalIface('HitRegionOptions', nativeType='nsISupports')
|
||||
addExternalIface('HTMLElement')
|
|
@ -4149,6 +4149,7 @@ class CGBindingRoot(CGThing):
|
|||
'dom::eventtarget::*', #XXXjdm
|
||||
'scripting::script_task::task_from_context',
|
||||
'dom::bindings::utils::EnumEntry',
|
||||
'dom::node::ScriptView',
|
||||
],
|
||||
[],
|
||||
curr)
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue