Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement paint worklet properties #17364

Merged
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Implemented paint worklet properties.

  • Loading branch information
asajeffrey committed Jul 11, 2017
commit ef033b8362b143f3671863313bcd792c4bf17f45

Some generated files are not rendered by default. Learn more.

@@ -34,6 +34,7 @@ script_layout_interface = {path = "../script_layout_interface"}
script_traits = {path = "../script_traits"}
selectors = { path = "../selectors" }
serde = "1.0"
servo_atoms = {path = "../atoms"}
servo_geometry = {path = "../geometry"}
serde_json = "1.0"
servo_config = {path = "../config"}
@@ -4,6 +4,7 @@

//! Data needed by the layout thread.

use fnv::FnvHashMap;
use fnv::FnvHasher;
use gfx::display_list::{WebRenderImageInfo, OpaqueNode};
use gfx::font_cache_thread::FontCacheThread;
@@ -15,15 +16,17 @@ use net_traits::image_cache::{ImageOrMetadataAvailable, UsePlaceholder};
use opaque_node::OpaqueNodeMethods;
use parking_lot::RwLock;
use script_layout_interface::{PendingImage, PendingImageState};
use script_traits::PaintWorkletExecutor;
use script_traits::Painter;
use script_traits::UntrustedNodeAddress;
use servo_atoms::Atom;
use servo_url::ServoUrl;
use std::cell::{RefCell, RefMut};
use std::collections::HashMap;
use std::hash::BuildHasherDefault;
use std::sync::{Arc, Mutex};
use std::thread;
use style::context::SharedStyleContext;
use style::properties::PropertyId;

thread_local!(static FONT_CONTEXT_KEY: RefCell<Option<FontContext>> = RefCell::new(None));

@@ -69,8 +72,8 @@ pub struct LayoutContext<'a> {
WebRenderImageInfo,
BuildHasherDefault<FnvHasher>>>>,

/// The executor for worklets
pub paint_worklet_executor: Option<Arc<PaintWorkletExecutor>>,
/// Paint worklets
pub registered_painters: Arc<RwLock<FnvHashMap<Atom, RegisteredPainter>>>,

/// A list of in-progress image loads to be shared with the script thread.
/// A None value means that this layout was not initiated by the script thread.
@@ -175,3 +178,10 @@ impl<'a> LayoutContext<'a> {
}
}
}

/// A registered paint worklet.
pub struct RegisteredPainter {
pub name: Atom,
pub properties: FnvHashMap<Atom, PropertyId>,
pub painter: Arc<Painter>,
}
@@ -1165,17 +1165,24 @@ impl FragmentDisplayListBuilding for Fragment {
let size = unbordered_box.size.to_physical(style.writing_mode);
let name = paint_worklet.name.clone();

// If the script thread has not added any paint worklet modules, there is nothing to do!
let executor = match state.layout_context.paint_worklet_executor {
Some(ref executor) => executor,
None => return debug!("Worklet {} called before any paint modules are added.", name),
// Get the painter, and the computed values for its properties.
let (properties, painter) = match state.layout_context.registered_painters.read().get(&name) {
Some(registered_painter) => (
registered_painter.properties
.iter()
.filter_map(|(name, id)| id.as_shorthand().err().map(|id| (name, id)))

This comment has been minimized.

Copy link
@jdm

jdm Jul 11, 2017

Member

Didn't we already filter them when registering?

This comment has been minimized.

Copy link
@asajeffrey

asajeffrey Jul 11, 2017

Author Member

Yes, but very annoyingly shorthand property ids have a lifetime, so we can't store them in the properties map.

.map(|(name, id)| (name.clone(), style.computed_value_to_string(id)))
.collect(),
registered_painter.painter.clone()
),
None => return debug!("Worklet {} called before registration.", name),
};

// TODO: add a one-place cache to avoid drawing the paint image every time.
// https://github.com/servo/servo/issues/17369
debug!("Drawing a paint image {}({},{}).", name, size.width.to_px(), size.height.to_px());
let (sender, receiver) = ipc::channel().unwrap();
executor.draw_a_paint_image(name, size, sender);
painter.draw_a_paint_image(size, properties, sender);

// TODO: timeout
let webrender_image = match receiver.recv() {
@@ -37,6 +37,7 @@ extern crate script_layout_interface;
extern crate script_traits;
#[macro_use] extern crate serde;
extern crate serde_json;
extern crate servo_atoms;
extern crate servo_config;
extern crate servo_geometry;
extern crate servo_url;
@@ -31,6 +31,7 @@ script_layout_interface = {path = "../script_layout_interface"}
script_traits = {path = "../script_traits"}
selectors = { path = "../selectors" }
serde_json = "1.0"
servo_atoms = {path = "../atoms"}
servo_config = {path = "../config"}
servo_geometry = {path = "../geometry"}
servo_url = {path = "../url"}
@@ -33,6 +33,7 @@ extern crate script_layout_interface;
extern crate script_traits;
extern crate selectors;
extern crate serde_json;
extern crate servo_atoms;
extern crate servo_config;
extern crate servo_geometry;
extern crate servo_url;
@@ -53,6 +54,7 @@ use ipc_channel::router::ROUTER;
use layout::animation;
use layout::construct::ConstructionResult;
use layout::context::LayoutContext;
use layout::context::RegisteredPainter;
use layout::context::heap_size_of_persistent_local_context;
use layout::display_list_builder::ToGfxColor;
use layout::flow::{self, Flow, ImmutableFlowUtils, MutableFlowUtils, MutableOwnedFlowUtils};
@@ -87,8 +89,8 @@ use script_layout_interface::rpc::TextIndexResponse;
use script_layout_interface::wrapper_traits::LayoutNode;
use script_traits::{ConstellationControlMsg, LayoutControlMsg, LayoutMsg as ConstellationMsg};
use script_traits::{ScrollState, UntrustedNodeAddress};
use script_traits::PaintWorkletExecutor;
use selectors::Element;
use servo_atoms::Atom;
use servo_config::opts;
use servo_config::prefs::PREFS;
use servo_config::resource_files::read_resource_file;
@@ -114,6 +116,7 @@ use style::error_reporting::{NullReporter, RustLogReporter};
use style::invalidation::element::restyle_hints::RestyleHint;
use style::logical_geometry::LogicalPoint;
use style::media_queries::{Device, MediaList, MediaType};
use style::properties::PropertyId;
use style::selector_parser::SnapshotMap;
use style::servo::restyle_damage::{REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, REPOSITION, STORE_OVERFLOW};
use style::shared_lock::{SharedRwLock, SharedRwLockReadGuard, StylesheetGuards};
@@ -123,6 +126,7 @@ use style::stylist::{ExtraStyleData, Stylist};
use style::thread_state;
use style::timer::Timer;
use style::traversal::{DomTraversal, TraversalDriver, TraversalFlags};
use style::values::CompactCowStr;

/// Information needed by the layout thread.
pub struct LayoutThread {
@@ -223,7 +227,7 @@ pub struct LayoutThread {
WebRenderImageInfo>>>,
/// The executor for paint worklets.
/// Will be None if the script thread hasn't added any paint worklet modules.
paint_worklet_executor: Option<Arc<PaintWorkletExecutor>>,
registered_painters: Arc<RwLock<FnvHashMap<Atom, RegisteredPainter>>>,

/// Webrender interface.
webrender_api: webrender_traits::RenderApi,
@@ -491,7 +495,7 @@ impl LayoutThread {
constellation_chan: constellation_chan.clone(),
time_profiler_chan: time_profiler_chan,
mem_profiler_chan: mem_profiler_chan,
paint_worklet_executor: None,
registered_painters: Arc::new(RwLock::new(FnvHashMap::default())),
image_cache: image_cache.clone(),
font_cache_thread: font_cache_thread,
first_reflow: Cell::new(true),
@@ -584,7 +588,7 @@ impl LayoutThread {
webrender_image_cache: self.webrender_image_cache.clone(),
pending_images: if script_initiated_layout { Some(Mutex::new(vec![])) } else { None },
newly_transitioning_nodes: if script_initiated_layout { Some(Mutex::new(vec![])) } else { None },
paint_worklet_executor: self.paint_worklet_executor.clone(),
registered_painters: self.registered_painters.clone(),
}
}

@@ -700,10 +704,19 @@ impl LayoutThread {
Msg::SetFinalUrl(final_url) => {
self.url = final_url;
},
Msg::SetPaintWorkletExecutor(executor) => {
debug!("Setting the paint worklet executor");
debug_assert!(self.paint_worklet_executor.is_none());
self.paint_worklet_executor = Some(executor);
Msg::RegisterPaint(name, mut properties, painter) => {
debug!("Registering the painter");
let properties = properties.drain(..)
.filter_map(|name| PropertyId::parse(CompactCowStr::from(&*name)).ok().map(|id| (name.clone(), id)))
.filter(|&(_, ref id)| id.as_shorthand().is_err())
.collect();
let registered_painter = RegisteredPainter {
name: name.clone(),
properties: properties,
painter: painter,
};
self.registered_painters.write()
.insert(name, registered_painter);
},
Msg::PrepareToExit(response_chan) => {
self.prepare_to_exit(response_chan);
@@ -0,0 +1,46 @@
/* 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 dom::bindings::codegen::Bindings::CSSStyleValueBinding::CSSStyleValueMethods;
use dom::bindings::codegen::Bindings::CSSStyleValueBinding::Wrap;
use dom::bindings::js::Root;
use dom::bindings::reflector::Reflector;
use dom::bindings::reflector::reflect_dom_object;
use dom::bindings::str::DOMString;
use dom::globalscope::GlobalScope;
use dom_struct::dom_struct;

#[dom_struct]
pub struct CSSStyleValue {
reflector: Reflector,
value: String,
}

impl CSSStyleValue {
fn new_inherited(value: String) -> CSSStyleValue {
CSSStyleValue {
reflector: Reflector::new(),
value: value,
}
}

pub fn new(global: &GlobalScope, value: String) -> Root<CSSStyleValue> {
reflect_dom_object(box CSSStyleValue::new_inherited(value), global, Wrap)
}
}

impl CSSStyleValueMethods for CSSStyleValue {
/// https://drafts.css-houdini.org/css-typed-om-1/#CSSStyleValue-stringification-behavior
fn Stringifier(&self) -> DOMString {
DOMString::from(&*self.value)
}

/// This attribute is no longer part of the `CSSStyleValue` interface,
/// but is still used in some examples.
/// https://github.com/GoogleChrome/houdini-samples/issues/16
// check-tidy: no specs after this line
fn CssText(&self) -> DOMString {
self.Stringifier()
}
}
@@ -253,6 +253,7 @@ pub mod cssrulelist;
pub mod cssstyledeclaration;
pub mod cssstylerule;
pub mod cssstylesheet;
pub mod cssstylevalue;
pub mod csssupportsrule;
pub mod cssviewportrule;
pub mod customelementregistry;
@@ -418,6 +419,7 @@ pub mod serviceworkerregistration;
pub mod servoparser;
pub mod storage;
pub mod storageevent;
pub mod stylepropertymapreadonly;
pub mod stylesheet;
pub mod stylesheetlist;
pub mod svgelement;
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.