Skip to content

Commit

Permalink
Auto merge of #17364 - asajeffrey:script-paint-worklets-properties, r…
Browse files Browse the repository at this point in the history
…=jdm

Implement paint worklet properties

<!-- Please describe your changes on the following line: -->

This is the final PR to get basic paint worklet support. It adds support for paint worklet properties (https://drafts.css-houdini.org/css-paint-api/#paint-definition-input-properties). When a paint worklet is registered, it specifies a list of CSS properties, and is provided with their computed values when it is invoked.

This is a dependent PR:
* "Implemented paint worklets invoking worklet scripts" is #17239.
* "Implemented paint worklets rendering contexts" is #17326.

There should be tests added for this, hopefully the existing wpt houdini tests.

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes fix #16839
- [x] There are tests for these changes

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/17364)
<!-- Reviewable:end -->
  • Loading branch information
bors-servo committed Jul 11, 2017
2 parents 6320702 + ef033b8 commit bc44246
Show file tree
Hide file tree
Showing 29 changed files with 353 additions and 118 deletions.
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions components/layout/Cargo.toml
Expand Up @@ -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"}
Expand Down
16 changes: 13 additions & 3 deletions components/layout/context.rs
Expand Up @@ -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;
Expand All @@ -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));

Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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>,
}
17 changes: 12 additions & 5 deletions components/layout/display_list_builder.rs
Expand Up @@ -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)))
.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() {
Expand Down
1 change: 1 addition & 0 deletions components/layout/lib.rs
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions components/layout_thread/Cargo.toml
Expand Up @@ -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"}
Expand Down
29 changes: 21 additions & 8 deletions components/layout_thread/lib.rs
Expand Up @@ -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;
Expand All @@ -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};
Expand Down Expand Up @@ -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;
Expand All @@ -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};
Expand All @@ -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 {
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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(),
}
}

Expand Down Expand Up @@ -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);
Expand Down
46 changes: 46 additions & 0 deletions components/script/dom/cssstylevalue.rs
@@ -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()
}
}
2 changes: 2 additions & 0 deletions components/script/dom/mod.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit bc44246

Please sign in to comment.