Backed out 6 changesets (bug 1510030) for webrender bustages CLOSED TREE

Backed out changeset 28a2fba71977 (bug 1510030)
Backed out changeset 1700b3a416cd (bug 1510030)
Backed out changeset 087518046b0c (bug 1510030)
Backed out changeset 6b3af91a7ce6 (bug 1510030)
Backed out changeset 737f4bc3afd3 (bug 1510030)
Backed out changeset 921116ca67a5 (bug 1510030)
This commit is contained in:
Bogdan Tara 2020-02-27 04:45:04 +02:00
Родитель ee2bc06eb8
Коммит a6ca41945c
25 изменённых файлов: 203 добавлений и 625 удалений

Просмотреть файл

@ -1898,6 +1898,17 @@ KeyframeEffect::MatchForCompositor KeyframeEffect::IsMatchForCompositor(
if (!StaticPrefs::gfx_omta_background_color()) {
return KeyframeEffect::MatchForCompositor::No;
}
if (nsIContent* content = aFrame->GetContent()) {
RefPtr<layers::LayerManager> layerManager =
nsContentUtils::LayerManagerForContent(content);
if (layerManager &&
layerManager->GetBackendType() == layers::LayersBackend::LAYERS_WR) {
// Bug 1510030: We don't yet support background-color animations on the
// compositor for WebRender.
return KeyframeEffect::MatchForCompositor::No;
}
}
}
return mAnimation->IsPlaying() ? KeyframeEffect::MatchForCompositor::Yes

Просмотреть файл

@ -51,6 +51,8 @@ div {
animation is running on the compositor or not **/
const omtaEnabled = isOMTAEnabled();
const isWebRender =
SpecialPowers.DOMWindowUtils.layerManagerType == 'WebRender';
function assert_animation_is_running_on_compositor(animation, desc) {
assert_equals(animation.isRunningOnCompositor, omtaEnabled,
@ -1027,8 +1029,14 @@ promise_test(async t => {
await waitForAnimationReadyToRestyle(animation);
await waitForPaints();
assert_animation_is_running_on_compositor(animation,
'background-color animation should be running on the compositor');
if (!isWebRender) {
assert_animation_is_running_on_compositor(animation,
'background-color animation should be running on the compositor');
} else {
assert_animation_is_not_running_on_compositor(animation,
'background-color animation is not yet able to run on the compositor ' +
'on WebRender');
}
}, 'background-color animation runs on the compositor');
promise_test(async t => {
@ -1039,8 +1047,14 @@ promise_test(async t => {
await waitForAnimationReadyToRestyle(animation);
await waitForPaints();
assert_animation_is_running_on_compositor(animation,
'background-color animation should be running on the compositor');
if (!isWebRender) {
assert_animation_is_running_on_compositor(animation,
'background-color animation should be running on the compositor');
} else {
assert_animation_is_not_running_on_compositor(animation,
'background-color animation is not yet able to run on the compositor ' +
'on WebRender');
}
// Add a red opaque background image covering the background color animation.
div.style.backgroundImage =

Просмотреть файл

@ -615,12 +615,6 @@ bool AnimationHelper::SampleAnimations(CompositorAnimationStorage* aStorage,
// Store the AnimatedValue
switch (lastPropertyAnimationGroup.mProperty) {
case eCSSProperty_background_color: {
aStorage->SetAnimatedValue(
iter.Key(), Servo_AnimationValue_GetColor(animationValues[0],
NS_RGBA(0, 0, 0, 0)));
break;
}
case eCSSProperty_opacity: {
MOZ_ASSERT(animationValues.Length() == 1);
aStorage->SetAnimatedValue(

Просмотреть файл

@ -2279,8 +2279,7 @@ bool WebRenderBridgeParent::AdvanceAnimations() {
bool WebRenderBridgeParent::SampleAnimations(
wr::RenderRootArray<nsTArray<wr::WrOpacityProperty>>& aOpacityArrays,
wr::RenderRootArray<nsTArray<wr::WrTransformProperty>>& aTransformArrays,
wr::RenderRootArray<nsTArray<wr::WrColorProperty>>& aColorArrays) {
wr::RenderRootArray<nsTArray<wr::WrTransformProperty>>& aTransformArrays) {
const bool isAnimating = AdvanceAnimations();
// return the animated data if has
@ -2291,16 +2290,12 @@ bool WebRenderBridgeParent::SampleAnimations(
wr::RenderRoot renderRoot = mAnimStorage->AnimationRenderRoot(iter.Key());
auto& transformArray = aTransformArrays[renderRoot];
auto& opacityArray = aOpacityArrays[renderRoot];
auto& colorArray = aColorArrays[renderRoot];
if (value->Is<AnimationTransform>()) {
transformArray.AppendElement(wr::ToWrTransformProperty(
iter.Key(), value->Transform().mTransformInDevSpace));
} else if (value->Is<float>()) {
opacityArray.AppendElement(
wr::ToWrOpacityProperty(iter.Key(), value->Opacity()));
} else if (value->Is<nscolor>()) {
colorArray.AppendElement(wr::ToWrColorProperty(
iter.Key(), gfx::Color::FromABGR(value->Color())));
}
}
}
@ -2430,9 +2425,8 @@ void WebRenderBridgeParent::MaybeGenerateFrame(VsyncId aId,
wr::RenderRootArray<nsTArray<wr::WrOpacityProperty>> opacityArrays;
wr::RenderRootArray<nsTArray<wr::WrTransformProperty>> transformArrays;
wr::RenderRootArray<nsTArray<wr::WrColorProperty>> colorArrays;
if (SampleAnimations(opacityArrays, transformArrays, colorArrays)) {
if (SampleAnimations(opacityArrays, transformArrays)) {
// TODO we should have a better way of assessing whether we need a content
// or a chrome frame generation.
ScheduleGenerateFrameAllRenderRoots();
@ -2445,8 +2439,7 @@ void WebRenderBridgeParent::MaybeGenerateFrame(VsyncId aId,
}
auto renderRoot = api->GetRenderRoot();
fastTxns[renderRoot]->UpdateDynamicProperties(opacityArrays[renderRoot],
transformArrays[renderRoot],
colorArrays[renderRoot]);
transformArrays[renderRoot]);
}
SetAPZSampleTime();

Просмотреть файл

@ -427,8 +427,7 @@ class WebRenderBridgeParent final
bool AdvanceAnimations();
bool SampleAnimations(
wr::RenderRootArray<nsTArray<wr::WrOpacityProperty>>& aOpacityArrays,
wr::RenderRootArray<nsTArray<wr::WrTransformProperty>>& aTransformArrays,
wr::RenderRootArray<nsTArray<wr::WrColorProperty>>& aColorArrays);
wr::RenderRootArray<nsTArray<wr::WrTransformProperty>>& aTransformArrays);
CompositorBridgeParent* GetRootCompositorBridgeParent() const;

Просмотреть файл

@ -216,15 +216,12 @@ void TransactionBuilder::InvalidateRenderedFrame() {
void TransactionBuilder::UpdateDynamicProperties(
const nsTArray<wr::WrOpacityProperty>& aOpacityArray,
const nsTArray<wr::WrTransformProperty>& aTransformArray,
const nsTArray<wr::WrColorProperty>& aColorArray) {
const nsTArray<wr::WrTransformProperty>& aTransformArray) {
wr_transaction_update_dynamic_properties(
mTxn, aOpacityArray.IsEmpty() ? nullptr : aOpacityArray.Elements(),
aOpacityArray.Length(),
aTransformArray.IsEmpty() ? nullptr : aTransformArray.Elements(),
aTransformArray.Length(),
aColorArray.IsEmpty() ? nullptr : aColorArray.Elements(),
aColorArray.Length());
aTransformArray.Length());
}
bool TransactionBuilder::IsEmpty() const {
@ -1142,20 +1139,6 @@ void DisplayListBuilder::PushHitTest(const wr::LayoutRect& aBounds,
&mCurrentSpaceAndClipChain);
}
void DisplayListBuilder::PushRectWithAnimation(
const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip,
bool aIsBackfaceVisible, const wr::ColorF& aColor,
const WrAnimationProperty* aAnimation) {
wr::LayoutRect clip = MergeClipLeaf(aClip);
WRDL_LOG("PushRectWithAnimation b=%s cl=%s c=%s\n", mWrState,
Stringify(aBounds).c_str(), Stringify(clip).c_str(),
Stringify(aColor).c_str());
wr_dp_push_rect_with_animation(mWrState, aBounds, clip, aIsBackfaceVisible,
&mCurrentSpaceAndClipChain, aColor,
aAnimation);
}
void DisplayListBuilder::PushClearRect(const wr::LayoutRect& aBounds) {
wr::LayoutRect clip = MergeClipLeaf(aBounds);
WRDL_LOG("PushClearRect b=%s c=%s\n", mWrState, Stringify(aBounds).c_str(),

Просмотреть файл

@ -106,8 +106,7 @@ class TransactionBuilder final {
void UpdateDynamicProperties(
const nsTArray<wr::WrOpacityProperty>& aOpacityArray,
const nsTArray<wr::WrTransformProperty>& aTransformArray,
const nsTArray<wr::WrColorProperty>& aColorArray);
const nsTArray<wr::WrTransformProperty>& aTransformArray);
void SetDocumentView(const LayoutDeviceIntRect& aDocRect);
@ -463,10 +462,6 @@ class DisplayListBuilder final {
void PushRect(const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip,
bool aIsBackfaceVisible, const wr::ColorF& aColor);
void PushRectWithAnimation(const wr::LayoutRect& aBounds,
const wr::LayoutRect& aClip,
bool aIsBackfaceVisible, const wr::ColorF& aColor,
const WrAnimationProperty* aAnimation);
void PushRoundedRect(const wr::LayoutRect& aBounds,
const wr::LayoutRect& aClip, bool aIsBackfaceVisible,
const wr::ColorF& aColor);

Просмотреть файл

@ -644,14 +644,6 @@ static inline wr::WrOpacityProperty ToWrOpacityProperty(uint64_t id,
return prop;
}
static inline wr::WrColorProperty ToWrColorProperty(uint64_t id,
const gfx::Color& color) {
wr::WrColorProperty prop;
prop.id = id;
prop.color = ToColorF(color);
return prop;
}
// Whenever possible, use wr::ExternalImageId instead of manipulating uint64_t.
inline uint64_t AsUint64(const ExternalImageId& aId) {
return static_cast<uint64_t>(aId._0);

Просмотреть файл

@ -433,11 +433,9 @@ pub struct WrFilterData {
}
#[repr(u32)]
#[derive(Debug)]
pub enum WrAnimationType {
Transform = 0,
Opacity = 1,
BackgroundColor = 2,
}
#[repr(C)]
@ -461,13 +459,6 @@ pub struct WrOpacityProperty {
pub opacity: f32,
}
#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub struct WrColorProperty {
pub id: u64,
pub color: ColorF,
}
/// cbindgen:field-names=[mHandle]
/// cbindgen:derive-lt=true
/// cbindgen:derive-lte=true
@ -1714,13 +1705,10 @@ pub extern "C" fn wr_transaction_update_dynamic_properties(
opacity_count: usize,
transform_array: *const WrTransformProperty,
transform_count: usize,
color_array: *const WrColorProperty,
color_count: usize,
) {
let mut properties = DynamicProperties {
transforms: Vec::with_capacity(transform_count),
floats: Vec::with_capacity(opacity_count),
colors: Vec::with_capacity(color_count),
};
if transform_count > 0 {
@ -1750,19 +1738,6 @@ pub extern "C" fn wr_transaction_update_dynamic_properties(
}
}
if color_count > 0 {
let color_slice = unsafe { make_slice(color_array, color_count) };
properties.colors.reserve(color_slice.len());
for element in color_slice.iter() {
let prop = PropertyValue {
key: PropertyBindingKey::new(element.id),
value: element.color,
};
properties.colors.push(prop);
}
}
txn.update_dynamic_properties(properties);
}
@ -2406,7 +2381,6 @@ pub extern "C" fn wr_dp_push_stacking_context(
// Same as above opacity case.
transform_ref.cloned().unwrap_or(LayoutTransform::identity())));
},
_ => unreachable!("{:?} should not create a stacking context", anim.effect_type),
}
}
@ -2639,29 +2613,6 @@ fn prim_flags(
}
}
fn common_item_properties_for_rect(
state: &mut WrState,
rect: LayoutRect,
clip: LayoutRect,
is_backface_visible: bool,
parent: &WrSpaceAndClipChain
) -> CommonItemProperties {
let space_and_clip = parent.to_webrender(state.pipeline_id);
let clip_rect = clip.intersection(&rect);
CommonItemProperties {
// NB: the damp-e10s talos-test will frequently crash on startup if we
// early-return here for empty rects. I couldn't figure out why, but
// it's pretty harmless to feed these through, so, uh, we do?
clip_rect: clip_rect.unwrap_or(LayoutRect::zero()),
clip_id: space_and_clip.clip_id,
spatial_id: space_and_clip.spatial_id,
flags: prim_flags(is_backface_visible),
hit_info: state.current_tag,
item_key: state.current_item_key,
}
}
#[no_mangle]
pub extern "C" fn wr_dp_push_rect(state: &mut WrState,
rect: LayoutRect,
@ -2671,13 +2622,20 @@ pub extern "C" fn wr_dp_push_rect(state: &mut WrState,
color: ColorF) {
debug_assert!(unsafe { !is_in_render_thread() });
let prim_info = common_item_properties_for_rect(
state,
rect,
clip,
is_backface_visible,
parent,
);
let space_and_clip = parent.to_webrender(state.pipeline_id);
let clip_rect = clip.intersection(&rect);
let prim_info = CommonItemProperties {
// NB: the damp-e10s talos-test will frequently crash on startup if we
// early-return here for empty rects. I couldn't figure out why, but
// it's pretty harmless to feed these through, so, uh, we do?
clip_rect: clip_rect.unwrap_or(LayoutRect::zero()),
clip_id: space_and_clip.clip_id,
spatial_id: space_and_clip.spatial_id,
flags: prim_flags(is_backface_visible),
hit_info: state.current_tag,
item_key: state.current_item_key,
};
state.frame_builder.dl_builder.push_rect(
&prim_info,
@ -2685,40 +2643,6 @@ pub extern "C" fn wr_dp_push_rect(state: &mut WrState,
);
}
#[no_mangle]
pub extern "C" fn wr_dp_push_rect_with_animation(
state: &mut WrState,
rect: LayoutRect,
clip: LayoutRect,
is_backface_visible: bool,
parent: &WrSpaceAndClipChain,
color: ColorF,
animation: *const WrAnimationProperty) {
debug_assert!(unsafe { !is_in_render_thread() });
let prim_info = common_item_properties_for_rect(
state,
rect,
clip,
is_backface_visible,
parent,
);
let anim = unsafe { animation.as_ref() };
if let Some(anim) = anim {
debug_assert!(anim.id > 0);
match anim.effect_type {
WrAnimationType::BackgroundColor => {
state.frame_builder.dl_builder.push_rect_with_animation(
&prim_info,
PropertyBinding::Binding(PropertyBindingKey::new(anim.id), color),
)
},
_ => unreachable!("Didn't expect {:?} animation", anim.effect_type),
}
}
}
#[no_mangle]
pub extern "C" fn wr_dp_push_rect_with_parent_clip(
state: &mut WrState,

Просмотреть файл

@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use api::{BorderRadius, BoxShadowClipMode, ClipMode, ColorF, PrimitiveKeyKind};
use api::PropertyBinding;
use api::MAX_BLUR_RADIUS;
use api::units::*;
use crate::clip::{ClipItemKey, ClipItemKeyKind};
@ -164,7 +163,7 @@ impl<'a> SceneBuilder<'a> {
&LayoutPrimitiveInfo::with_clip_rect(final_prim_rect, prim_info.clip_rect),
clips,
PrimitiveKeyKind::Rectangle {
color: PropertyBinding::Value(color.into()),
color: color.into(),
},
);
} else {
@ -190,7 +189,7 @@ impl<'a> SceneBuilder<'a> {
// Draw the box-shadow as a solid rect, using a box-shadow
// clip mask item.
let prim = PrimitiveKeyKind::Rectangle {
color: PropertyBinding::Value(color.into()),
color: color.into(),
};
// Create the box-shadow clip item.

Просмотреть файл

@ -96,7 +96,7 @@
use api::{MixBlendMode, PipelineId, PremultipliedColorF, FilterPrimitiveKind};
use api::{PropertyBinding, PropertyBindingId, FilterPrimitive, FontRenderMode};
use api::{DebugFlags, RasterSpace, ImageKey, ColorF, ColorU, PrimitiveFlags};
use api::{DebugFlags, RasterSpace, ImageKey, ColorF, PrimitiveFlags};
use api::units::*;
use crate::box_shadow::{BLUR_SAMPLE_SCALE};
use crate::clip::{ClipStore, ClipChainInstance, ClipDataHandle, ClipChainId};
@ -120,7 +120,6 @@ use crate::prim_store::{SpaceMapper, PrimitiveVisibilityMask, PointKey, Primitiv
use crate::prim_store::{SpaceSnapper, PictureIndex, PrimitiveInstance, PrimitiveInstanceKind};
use crate::prim_store::{get_raster_rects, PrimitiveScratchBuffer, RectangleKey};
use crate::prim_store::{OpacityBindingStorage, ImageInstanceStorage, OpacityBindingIndex};
use crate::prim_store::{ColorBindingStorage, ColorBindingIndex};
use crate::print_tree::{PrintTree, PrintTreePrinter};
use crate::render_backend::DataStores;
use crate::render_task_graph::RenderTaskId;
@ -265,8 +264,6 @@ pub struct PictureCacheState {
spatial_nodes: FastHashMap<SpatialNodeIndex, SpatialNodeDependency>,
/// State of opacity bindings from previous frame
opacity_bindings: FastHashMap<PropertyBindingId, OpacityBindingInfo>,
/// State of color bindings from previous frame
color_bindings: FastHashMap<PropertyBindingId, ColorBindingInfo>,
/// The current transform of the picture cache root spatial node
root_transform: TransformKey,
/// The current tile size in device pixels
@ -281,7 +278,6 @@ pub struct PictureCacheState {
pub struct PictureCacheRecycledAllocations {
old_opacity_bindings: FastHashMap<PropertyBindingId, OpacityBindingInfo>,
old_color_bindings: FastHashMap<PropertyBindingId, ColorBindingInfo>,
compare_cache: FastHashMap<PrimitiveComparisonKey, PrimitiveCompareResult>,
}
@ -405,39 +401,33 @@ fn clampf(value: f32, low: f32, high: f32) -> f32 {
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct PrimitiveDependencyIndex(pub u32);
/// Information about the state of a binding.
/// Information about the state of an opacity binding.
#[derive(Debug)]
pub struct BindingInfo<T> {
pub struct OpacityBindingInfo {
/// The current value retrieved from dynamic scene properties.
value: T,
value: f32,
/// True if it was changed (or is new) since the last frame build.
changed: bool,
}
/// Information stored in a tile descriptor for a binding.
/// Information stored in a tile descriptor for an opacity binding.
#[derive(Debug, PartialEq, Clone, Copy)]
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub enum Binding<T> {
Value(T),
pub enum OpacityBinding {
Value(f32),
Binding(PropertyBindingId),
}
impl<T> From<PropertyBinding<T>> for Binding<T> {
fn from(binding: PropertyBinding<T>) -> Binding<T> {
impl From<PropertyBinding<f32>> for OpacityBinding {
fn from(binding: PropertyBinding<f32>) -> OpacityBinding {
match binding {
PropertyBinding::Binding(key, _) => Binding::Binding(key.id),
PropertyBinding::Value(value) => Binding::Value(value),
PropertyBinding::Binding(key, _) => OpacityBinding::Binding(key.id),
PropertyBinding::Value(value) => OpacityBinding::Value(value),
}
}
}
pub type OpacityBinding = Binding<f32>;
pub type OpacityBindingInfo = BindingInfo<f32>;
pub type ColorBinding = Binding<ColorU>;
pub type ColorBindingInfo = BindingInfo<ColorU>;
/// Information about the state of a spatial node value
#[derive(Debug)]
pub struct SpatialNodeDependency {
@ -486,9 +476,6 @@ struct TilePostUpdateContext<'a> {
/// Information about opacity bindings from the picture cache.
opacity_bindings: &'a FastHashMap<PropertyBindingId, OpacityBindingInfo>,
/// Information about color bindings from the picture cache.
color_bindings: &'a FastHashMap<PropertyBindingId, ColorBindingInfo>,
/// Current size in device pixels of tiles for this cache
current_tile_size: DeviceIntSize,
@ -528,9 +515,6 @@ struct PrimitiveDependencyInfo {
/// Opacity bindings this primitive depends on.
opacity_bindings: SmallVec<[OpacityBinding; 4]>,
/// Color binding this primitive depends on.
color_binding: Option<ColorBinding>,
/// Clips that this primitive depends on.
clips: SmallVec<[ItemUid; 8]>,
@ -553,7 +537,6 @@ impl PrimitiveDependencyInfo {
prim_origin,
images: SmallVec::new(),
opacity_bindings: SmallVec::new(),
color_binding: None,
clip_by_tile: false,
prim_clip_rect,
clips: SmallVec::new(),
@ -705,8 +688,6 @@ pub enum PrimitiveCompareResult {
Image,
/// The value of an opacity binding changed
OpacityBinding,
/// The value of a color binding changed
ColorBinding,
}
/// A more detailed version of PrimitiveCompareResult used when
@ -737,11 +718,7 @@ pub enum PrimitiveCompareResultDetail {
/// The value of an opacity binding changed
OpacityBinding {
detail: CompareHelperResult<OpacityBinding>,
},
/// The value of a color binding changed
ColorBinding {
detail: CompareHelperResult<ColorBinding>,
},
}
}
/// Debugging information about why a tile was invalidated
@ -909,7 +886,6 @@ impl Tile {
state.resource_cache,
ctx.spatial_nodes,
ctx.opacity_bindings,
ctx.color_bindings,
);
let mut dirty_rect = PictureRect::zero();
@ -1078,12 +1054,6 @@ impl Tile {
// Include any transforms that this primitive depends on.
self.current_descriptor.transforms.extend_from_slice(&info.spatial_nodes);
// Include any color bindings this primitive depends on.
if info.color_binding.is_some() {
self.current_descriptor.color_bindings.insert(
self.current_descriptor.color_bindings.len(), info.color_binding.unwrap());
}
// TODO(gw): The origin of background rects produced by APZ changes
// in Gecko during scrolling. Consider investigating this so the
// hack / workaround below is not required.
@ -1136,7 +1106,6 @@ impl Tile {
clip_dep_count: info.clips.len() as u8,
image_dep_count: info.images.len() as u8,
opacity_binding_dep_count: info.opacity_bindings.len() as u8,
color_binding_dep_count: if info.color_binding.is_some() { 1 } else { 0 } as u8,
});
// Add this primitive to the dirty rect quadtree.
@ -1348,7 +1317,6 @@ pub struct PrimitiveDescriptor {
image_dep_count: u8,
opacity_binding_dep_count: u8,
clip_dep_count: u8,
color_binding_dep_count: u8,
}
impl PartialEq for PrimitiveDescriptor {
@ -1499,10 +1467,6 @@ pub struct TileDescriptor {
/// Picture space rect that contains valid pixels region of this tile.
local_valid_rect: PictureRect,
/// List of the effects of color that we care about
/// tracking for this tile.
color_bindings: Vec<ColorBinding>,
}
impl TileDescriptor {
@ -1514,7 +1478,6 @@ impl TileDescriptor {
images: Vec::new(),
transforms: Vec::new(),
local_valid_rect: PictureRect::zero(),
color_bindings: Vec::new(),
}
}
@ -1532,12 +1495,11 @@ impl TileDescriptor {
prim.prim_clip_rect.w,
prim.prim_clip_rect.h,
));
pt.add_item(format!("deps: t={} i={} o={} c={} color={}",
pt.add_item(format!("deps: t={} i={} o={} c={}",
prim.transform_dep_count,
prim.image_dep_count,
prim.opacity_binding_dep_count,
prim.clip_dep_count,
prim.color_binding_dep_count,
));
pt.end_level();
}
@ -1580,15 +1542,6 @@ impl TileDescriptor {
pt.end_level();
}
if !self.color_bindings.is_empty() {
pt.new_level("color_bindings".to_string());
for color_binding in &self.color_bindings {
pt.new_level(format!("binding={:?}", color_binding));
pt.end_level();
}
pt.end_level();
}
pt.end_level();
}
@ -1601,7 +1554,6 @@ impl TileDescriptor {
self.images.clear();
self.transforms.clear();
self.local_valid_rect = PictureRect::zero();
self.color_bindings.clear();
}
}
@ -2074,11 +2026,6 @@ pub struct TileCacheInstance {
/// calculate invalid relative transforms when building the spatial
/// nodes hash above.
used_spatial_nodes: FastHashSet<SpatialNodeIndex>,
/// List of color bindings, with some extra information
/// about whether they changed since last frame.
color_bindings: FastHashMap<PropertyBindingId, ColorBindingInfo>,
/// Switch back and forth between old and new bindings hashmaps to avoid re-allocating.
old_color_bindings: FastHashMap<PropertyBindingId, ColorBindingInfo>,
/// The current dirty region tracker for this picture.
pub dirty_region: DirtyRegion,
/// Current size of tiles in picture units.
@ -2167,8 +2114,6 @@ impl TileCacheInstance {
spatial_nodes: FastHashMap::default(),
old_spatial_nodes: FastHashMap::default(),
used_spatial_nodes: FastHashSet::default(),
color_bindings: FastHashMap::default(),
old_color_bindings: FastHashMap::default(),
dirty_region: DirtyRegion::new(),
tile_size: PictureSize::zero(),
tile_rect: TileRect::zero(),
@ -2230,7 +2175,7 @@ impl TileCacheInstance {
(p0, p1)
}
/// Update transforms, opacity, color bindings and tile rects.
/// Update transforms, opacity bindings and tile rects.
pub fn pre_update(
&mut self,
pic_rect: PictureRect,
@ -2312,7 +2257,6 @@ impl TileCacheInstance {
self.root_transform = prev_state.root_transform;
self.spatial_nodes = prev_state.spatial_nodes;
self.opacity_bindings = prev_state.opacity_bindings;
self.color_bindings = prev_state.color_bindings;
self.current_tile_size = prev_state.current_tile_size;
self.native_surface_id = prev_state.native_surface_id;
self.is_opaque = prev_state.is_opaque;
@ -2336,11 +2280,6 @@ impl TileCacheInstance {
&mut self.old_opacity_bindings,
prev_state.allocations.old_opacity_bindings,
);
recycle_map(
self.color_bindings.len(),
&mut self.old_color_bindings,
prev_state.allocations.old_color_bindings,
);
recycle_map(
prev_state.allocations.compare_cache.len(),
&mut self.compare_cache,
@ -2441,23 +2380,6 @@ impl TileCacheInstance {
});
}
// Do a hacky diff of color binding values from the last frame. This is
// used later on during tile invalidation tests.
let current_properties = frame_context.scene_properties.color_properties();
mem::swap(&mut self.color_bindings, &mut self.old_color_bindings);
self.color_bindings.clear();
for (id, value) in current_properties {
let changed = match self.old_color_bindings.get(id) {
Some(old_property) => old_property.value != (*value).into(),
None => true,
};
self.color_bindings.insert(*id, ColorBindingInfo {
value: (*value).into(),
changed,
});
}
let world_tile_size = WorldSize::new(
self.current_tile_size.width as f32 / frame_context.global_device_pixel_scale.0,
self.current_tile_size.height as f32 / frame_context.global_device_pixel_scale.0,
@ -2617,7 +2539,6 @@ impl TileCacheInstance {
pictures: &[PicturePrimitive],
resource_cache: &ResourceCache,
opacity_binding_store: &OpacityBindingStorage,
color_bindings: &ColorBindingStorage,
image_instances: &ImageInstanceStorage,
surface_stack: &[SurfaceIndex],
composite_state: &CompositeState,
@ -2754,15 +2675,13 @@ impl TileCacheInstance {
prim_info.opacity_bindings.push(binding.into());
}
}
PrimitiveInstanceKind::Rectangle { data_handle, opacity_binding_index, color_binding_index, .. } => {
PrimitiveInstanceKind::Rectangle { data_handle, opacity_binding_index, .. } => {
if opacity_binding_index == OpacityBindingIndex::INVALID {
// Rectangles can only form a backdrop candidate if they are known opaque.
// TODO(gw): We could resolve the opacity binding here, but the common
// case for background rects is that they don't have animated opacity.
let color = match data_stores.prim[data_handle].kind {
PrimitiveTemplateKind::Rectangle { color, .. } => {
frame_context.scene_properties.resolve_color(&color)
}
PrimitiveTemplateKind::Rectangle { color, .. } => color,
_ => unreachable!(),
};
if color.a >= 1.0 {
@ -2775,10 +2694,6 @@ impl TileCacheInstance {
}
}
if color_binding_index != ColorBindingIndex::INVALID {
prim_info.color_binding = Some(color_bindings[color_binding_index].into());
}
prim_info.clip_by_tile = true;
}
PrimitiveInstanceKind::Image { data_handle, image_instance_index, .. } => {
@ -3180,7 +3095,6 @@ impl TileCacheInstance {
backdrop: self.backdrop,
spatial_nodes: &self.spatial_nodes,
opacity_bindings: &self.opacity_bindings,
color_bindings: &self.color_bindings,
current_tile_size: self.current_tile_size,
local_rect: self.local_rect,
};
@ -4064,14 +3978,12 @@ impl PicturePrimitive {
tiles: tile_cache.tiles,
spatial_nodes: tile_cache.spatial_nodes,
opacity_bindings: tile_cache.opacity_bindings,
color_bindings: tile_cache.color_bindings,
root_transform: tile_cache.root_transform,
current_tile_size: tile_cache.current_tile_size,
native_surface_id: tile_cache.native_surface_id.take(),
is_opaque: tile_cache.is_opaque,
allocations: PictureCacheRecycledAllocations {
old_opacity_bindings: tile_cache.old_opacity_bindings,
old_color_bindings: tile_cache.old_color_bindings,
compare_cache: tile_cache.compare_cache,
},
},
@ -5626,11 +5538,9 @@ struct PrimitiveComparer<'a> {
transform_comparer: CompareHelper<'a, SpatialNodeIndex>,
image_comparer: CompareHelper<'a, ImageDependency>,
opacity_comparer: CompareHelper<'a, OpacityBinding>,
color_comparer: CompareHelper<'a, ColorBinding>,
resource_cache: &'a ResourceCache,
spatial_nodes: &'a FastHashMap<SpatialNodeIndex, SpatialNodeDependency>,
opacity_bindings: &'a FastHashMap<PropertyBindingId, OpacityBindingInfo>,
color_bindings: &'a FastHashMap<PropertyBindingId, ColorBindingInfo>,
}
impl<'a> PrimitiveComparer<'a> {
@ -5640,7 +5550,6 @@ impl<'a> PrimitiveComparer<'a> {
resource_cache: &'a ResourceCache,
spatial_nodes: &'a FastHashMap<SpatialNodeIndex, SpatialNodeDependency>,
opacity_bindings: &'a FastHashMap<PropertyBindingId, OpacityBindingInfo>,
color_bindings: &'a FastHashMap<PropertyBindingId, ColorBindingInfo>,
) -> Self {
let clip_comparer = CompareHelper::new(
&prev.clips,
@ -5662,21 +5571,14 @@ impl<'a> PrimitiveComparer<'a> {
&curr.opacity_bindings,
);
let color_comparer = CompareHelper::new(
&prev.color_bindings,
&curr.color_bindings,
);
PrimitiveComparer {
clip_comparer,
transform_comparer,
image_comparer,
opacity_comparer,
color_comparer,
resource_cache,
spatial_nodes,
opacity_bindings,
color_bindings,
}
}
@ -5685,7 +5587,6 @@ impl<'a> PrimitiveComparer<'a> {
self.transform_comparer.reset();
self.image_comparer.reset();
self.opacity_comparer.reset();
self.color_comparer.reset();
}
fn advance_prev(&mut self, prim: &PrimitiveDescriptor) {
@ -5693,7 +5594,6 @@ impl<'a> PrimitiveComparer<'a> {
self.transform_comparer.advance_prev(prim.transform_dep_count);
self.image_comparer.advance_prev(prim.image_dep_count);
self.opacity_comparer.advance_prev(prim.opacity_binding_dep_count);
self.color_comparer.advance_prev(prim.color_binding_dep_count);
}
fn advance_curr(&mut self, prim: &PrimitiveDescriptor) {
@ -5701,7 +5601,6 @@ impl<'a> PrimitiveComparer<'a> {
self.transform_comparer.advance_curr(prim.transform_dep_count);
self.image_comparer.advance_curr(prim.image_dep_count);
self.opacity_comparer.advance_curr(prim.opacity_binding_dep_count);
self.color_comparer.advance_curr(prim.color_binding_dep_count);
}
/// Check if two primitive descriptors are the same.
@ -5714,7 +5613,6 @@ impl<'a> PrimitiveComparer<'a> {
let resource_cache = self.resource_cache;
let spatial_nodes = self.spatial_nodes;
let opacity_bindings = self.opacity_bindings;
let color_bindings = self.color_bindings;
// Check equality of the PrimitiveDescriptor
if prev != curr {
@ -5794,30 +5692,6 @@ impl<'a> PrimitiveComparer<'a> {
return PrimitiveCompareResult::OpacityBinding;
}
// Check if any of the color bindings this prim has are different.
let mut bind_result = CompareHelperResult::Equal;
if !self.color_comparer.is_same(
prev.color_binding_dep_count,
curr.color_binding_dep_count,
|curr| {
if let ColorBinding::Binding(id) = curr {
if color_bindings
.get(id)
.map_or(true, |info| info.changed) {
return true;
}
}
true
},
if opt_detail.is_some() { Some(&mut bind_result) } else { None },
) {
if let Some(detail) = opt_detail {
*detail = PrimitiveCompareResultDetail::ColorBinding{ detail: bind_result };
}
return PrimitiveCompareResult::ColorBinding;
}
PrimitiveCompareResult::Equal
}
}

Просмотреть файл

@ -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/. */
use api::{BorderRadius, ClipMode, ColorF, ColorU};
use api::{BorderRadius, ClipMode, ColorF};
use api::{ImageRendering, RepeatMode, PrimitiveFlags};
use api::{PremultipliedColorF, PropertyBinding, Shadow, GradientStop};
use api::{BoxShadowClipMode, LineStyle, LineOrientation, BorderStyle};
@ -720,7 +720,7 @@ impl intern::InternDebug for PrimitiveKey {}
#[derive(MallocSizeOf)]
pub enum PrimitiveTemplateKind {
Rectangle {
color: PropertyBinding<ColorF>,
color: ColorF,
},
Clear,
}
@ -812,8 +812,7 @@ impl PrimitiveTemplateKind {
/// Write any GPU blocks for the primitive template to the given request object.
fn write_prim_gpu_blocks(
&self,
request: &mut GpuDataRequest,
scene_properties: &SceneProperties,
request: &mut GpuDataRequest
) {
match *self {
PrimitiveTemplateKind::Clear => {
@ -821,7 +820,7 @@ impl PrimitiveTemplateKind {
request.push(PremultipliedColorF::BLACK);
}
PrimitiveTemplateKind::Rectangle { ref color, .. } => {
request.push(scene_properties.resolve_color(color).premultiplied())
request.push(color.premultiplied());
}
}
}
@ -835,10 +834,9 @@ impl PrimitiveTemplate {
pub fn update(
&mut self,
frame_state: &mut FrameBuildingState,
scene_properties: &SceneProperties,
) {
if let Some(mut request) = frame_state.gpu_cache.request(&mut self.common.gpu_cache_handle) {
self.kind.write_prim_gpu_blocks(&mut request, scene_properties);
self.kind.write_prim_gpu_blocks(&mut request);
}
self.opacity = match self.kind {
@ -846,7 +844,7 @@ impl PrimitiveTemplate {
PrimitiveOpacity::translucent()
}
PrimitiveTemplateKind::Rectangle { ref color, .. } => {
PrimitiveOpacity::from_alpha(scene_properties.resolve_color(color).a)
PrimitiveOpacity::from_alpha(color.a)
}
};
}
@ -875,7 +873,7 @@ impl InternablePrimitive for PrimitiveKeyKind {
fn make_instance_kind(
key: PrimitiveKey,
data_handle: PrimitiveDataHandle,
prim_store: &mut PrimitiveStore,
_: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
match key.kind {
@ -884,18 +882,11 @@ impl InternablePrimitive for PrimitiveKeyKind {
data_handle
}
}
PrimitiveKeyKind::Rectangle { color, .. } => {
let color_binding_index = match color {
PropertyBinding::Binding(..) => {
prim_store.color_bindings.push(color)
}
PropertyBinding::Value(..) => ColorBindingIndex::INVALID,
};
PrimitiveKeyKind::Rectangle { .. } => {
PrimitiveInstanceKind::Rectangle {
data_handle,
opacity_binding_index: OpacityBindingIndex::INVALID,
segment_instance_index: SegmentInstanceIndex::INVALID,
color_binding_index,
}
}
}
@ -927,7 +918,8 @@ impl OpacityBinding {
}
// Resolve the current value of each opacity binding, and
// store that as a single combined opacity.
// store that as a single combined opacity. Returns true
// if the opacity value changed from last time.
pub fn update(&mut self, scene_properties: &SceneProperties) {
let mut new_opacity = 1.0;
@ -1335,10 +1327,7 @@ impl IsVisible for PrimitiveKeyKind {
true
}
PrimitiveKeyKind::Rectangle { ref color, .. } => {
match *color {
PropertyBinding::Value(value) => value.a > 0,
PropertyBinding::Binding(..) => true,
}
color.a > 0
}
}
}
@ -1355,7 +1344,7 @@ impl CreateShadow for PrimitiveKeyKind {
match *self {
PrimitiveKeyKind::Rectangle { .. } => {
PrimitiveKeyKind::Rectangle {
color: PropertyBinding::Value(shadow.color.into()),
color: shadow.color.into(),
}
}
PrimitiveKeyKind::Clear => {
@ -1416,7 +1405,6 @@ pub enum PrimitiveInstanceKind {
data_handle: PrimitiveDataHandle,
opacity_binding_index: OpacityBindingIndex,
segment_instance_index: SegmentInstanceIndex,
color_binding_index: ColorBindingIndex,
},
YuvImage {
/// Handle to the common interned data for this primitive.
@ -1673,8 +1661,6 @@ pub type TextRunIndex = storage::Index<TextRunPrimitive>;
pub type TextRunStorage = storage::Storage<TextRunPrimitive>;
pub type OpacityBindingIndex = storage::Index<OpacityBinding>;
pub type OpacityBindingStorage = storage::Storage<OpacityBinding>;
pub type ColorBindingIndex = storage::Index<PropertyBinding<ColorU>>;
pub type ColorBindingStorage = storage::Storage<PropertyBinding<ColorU>>;
pub type BorderHandleStorage = storage::Storage<RenderTaskCacheEntryHandle>;
pub type SegmentStorage = storage::Storage<BrushSegment>;
pub type SegmentsRange = storage::Range<BrushSegment>;
@ -1814,7 +1800,6 @@ pub struct PrimitiveStoreStats {
opacity_binding_count: usize,
image_count: usize,
linear_gradient_count: usize,
color_binding_count: usize,
}
impl PrimitiveStoreStats {
@ -1825,7 +1810,6 @@ impl PrimitiveStoreStats {
opacity_binding_count: 0,
image_count: 0,
linear_gradient_count: 0,
color_binding_count: 0,
}
}
}
@ -1843,8 +1827,6 @@ pub struct PrimitiveStore {
/// List of animated opacity bindings for a primitive.
pub opacity_bindings: OpacityBindingStorage,
/// animated color bindings for this primitive.
pub color_bindings: ColorBindingStorage,
}
impl PrimitiveStore {
@ -1854,7 +1836,6 @@ impl PrimitiveStore {
text_runs: TextRunStorage::new(stats.text_run_count),
images: ImageInstanceStorage::new(stats.image_count),
opacity_bindings: OpacityBindingStorage::new(stats.opacity_binding_count),
color_bindings: ColorBindingStorage::new(stats.color_binding_count),
linear_gradients: LinearGradientStorage::new(stats.linear_gradient_count),
}
}
@ -1866,7 +1847,6 @@ impl PrimitiveStore {
image_count: self.images.len(),
opacity_binding_count: self.opacity_bindings.len(),
linear_gradient_count: self.linear_gradients.len(),
color_binding_count: self.color_bindings.len(),
}
}
@ -2171,7 +2151,6 @@ impl PrimitiveStore {
&self.pictures,
frame_state.resource_cache,
&self.opacity_bindings,
&self.color_bindings,
&self.images,
&frame_state.surface_stack,
&frame_state.composite_state,
@ -2678,7 +2657,7 @@ impl PrimitiveStore {
self.pictures[pic_index.0].requested_composite_mode = None;
}
fn prepare_prim_for_render(
pub fn prepare_prim_for_render(
&mut self,
prim_instance: &mut PrimitiveInstance,
prim_spatial_node_index: SpatialNodeIndex,
@ -2997,7 +2976,7 @@ impl PrimitiveStore {
// Update the template this instane references, which may refresh the GPU
// cache with any shared template data.
prim_data.update(frame_state, frame_context.scene_properties);
prim_data.update(frame_state);
}
PrimitiveInstanceKind::NormalBorder { data_handle, ref mut cache_handles, .. } => {
let prim_data = &mut data_stores.normal_border[*data_handle];
@ -3087,37 +3066,13 @@ impl PrimitiveStore {
// cache with any shared template data.
prim_data.kind.update(&mut prim_data.common, frame_state);
}
PrimitiveInstanceKind::Rectangle { data_handle, segment_instance_index, opacity_binding_index, color_binding_index, .. } => {
PrimitiveInstanceKind::Rectangle { data_handle, segment_instance_index, opacity_binding_index, .. } => {
let prim_data = &mut data_stores.prim[*data_handle];
prim_data.common.may_need_repetition = false;
if *color_binding_index != ColorBindingIndex::INVALID {
match self.color_bindings[*color_binding_index] {
PropertyBinding::Binding(..) => {
// We explicitly invalidate the gpu cache
// if the color is animating.
let gpu_cache_handle =
if *segment_instance_index == SegmentInstanceIndex::INVALID {
None
} else if *segment_instance_index == SegmentInstanceIndex::UNUSED {
Some(&prim_data.common.gpu_cache_handle)
} else {
Some(&scratch.segment_instances[*segment_instance_index].gpu_cache_handle)
};
if let Some(gpu_cache_handle) = gpu_cache_handle {
frame_state.gpu_cache.invalidate(gpu_cache_handle);
}
}
PropertyBinding::Value(..) => {},
}
}
// Update the template this instane references, which may refresh the GPU
// cache with any shared template data.
prim_data.update(
frame_state,
frame_context.scene_properties,
);
prim_data.update(frame_state);
update_opacity_binding(
&mut self.opacity_bindings,
@ -3133,7 +3088,6 @@ impl PrimitiveStore {
|request| {
prim_data.kind.write_prim_gpu_blocks(
request,
frame_context.scene_properties,
);
}
);
@ -4352,10 +4306,13 @@ fn update_opacity_binding(
opacity_bindings: &mut OpacityBindingStorage,
opacity_binding_index: OpacityBindingIndex,
scene_properties: &SceneProperties,
) {
if opacity_binding_index != OpacityBindingIndex::INVALID {
) -> f32 {
if opacity_binding_index == OpacityBindingIndex::INVALID {
1.0
} else {
let binding = &mut opacity_bindings[opacity_binding_index];
binding.update(scene_properties);
binding.current
}
}

Просмотреть файл

@ -22,7 +22,6 @@ use std::sync::Arc;
pub struct SceneProperties {
transform_properties: FastHashMap<PropertyBindingId, LayoutTransform>,
float_properties: FastHashMap<PropertyBindingId, f32>,
color_properties: FastHashMap<PropertyBindingId, ColorF>,
current_properties: DynamicProperties,
pending_properties: Option<DynamicProperties>,
}
@ -32,7 +31,6 @@ impl SceneProperties {
SceneProperties {
transform_properties: FastHashMap::default(),
float_properties: FastHashMap::default(),
color_properties: FastHashMap::default(),
current_properties: DynamicProperties::default(),
pending_properties: None,
}
@ -80,11 +78,6 @@ impl SceneProperties {
.insert(property.key.id, property.value);
}
for property in &pending_properties.colors {
self.color_properties
.insert(property.key.id, property.value);
}
self.current_properties = pending_properties.clone();
properties_changed = true;
}
@ -128,27 +121,6 @@ impl SceneProperties {
pub fn float_properties(&self) -> &FastHashMap<PropertyBindingId, f32> {
&self.float_properties
}
/// Get the current value for a color property.
pub fn resolve_color(
&self,
property: &PropertyBinding<ColorF>
) -> ColorF {
match *property {
PropertyBinding::Value(value) => value,
PropertyBinding::Binding(ref key, v) => {
self.color_properties
.get(&key.id)
.cloned()
.unwrap_or(v)
}
}
}
pub fn color_properties(&self) -> &FastHashMap<PropertyBindingId, ColorF> {
&self.color_properties
}
}
/// A representation of the layout within the display port for a given document or iframe.

Просмотреть файл

@ -1214,7 +1214,7 @@ impl<'a> SceneBuilder<'a> {
self.add_solid_rectangle(
clip_and_scroll,
&layout,
PropertyBinding::Value(ColorF::TRANSPARENT),
ColorF::TRANSPARENT,
);
}
DisplayItem::ClearRectangle(ref info) => {
@ -2749,19 +2749,13 @@ impl<'a> SceneBuilder<'a> {
&mut self,
clip_and_scroll: ScrollNodeAndClipChain,
info: &LayoutPrimitiveInfo,
color: PropertyBinding<ColorF>,
color: ColorF,
) {
match color {
PropertyBinding::Value(value) => {
if value.a == 0.0 {
// Don't add transparent rectangles to the draw list,
// but do consider them for hit testing. This allows
// specifying invisible hit testing areas.
self.add_primitive_to_hit_testing_list(info, clip_and_scroll);
return;
}
},
PropertyBinding::Binding(..) => {},
if color.a == 0.0 {
// Don't add transparent rectangles to the draw list, but do consider them for hit
// testing. This allows specifying invisible hit testing areas.
self.add_primitive_to_hit_testing_list(info, clip_and_scroll);
return;
}
self.add_primitive(

Просмотреть файл

@ -1154,7 +1154,7 @@ pub enum PrimitiveKeyKind {
///
Rectangle {
///
color: PropertyBinding<ColorU>,
color: ColorU,
},
}
@ -1821,7 +1821,7 @@ impl PropertyBindingId {
/// A unique key that is used for connecting animated property
/// values to bindings in the display list.
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
#[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Serialize, PeekPoke)]
pub struct PropertyBindingKey<T> {
///
pub id: PropertyBindingId,
@ -1853,7 +1853,7 @@ impl<T> PropertyBindingKey<T> {
/// used for the case where the animation is still in-delay phase
/// (i.e. the animation doesn't produce any animation values).
#[repr(C)]
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize, PeekPoke)]
pub enum PropertyBinding<T> {
/// Non-animated value.
Value(T),
@ -1873,46 +1873,6 @@ impl<T> From<T> for PropertyBinding<T> {
}
}
impl From<PropertyBindingKey<ColorF>> for PropertyBindingKey<ColorU> {
fn from(key: PropertyBindingKey<ColorF>) -> PropertyBindingKey<ColorU> {
PropertyBindingKey {
id: key.id.clone(),
_phantom: PhantomData,
}
}
}
impl From<PropertyBindingKey<ColorU>> for PropertyBindingKey<ColorF> {
fn from(key: PropertyBindingKey<ColorU>) -> PropertyBindingKey<ColorF> {
PropertyBindingKey {
id: key.id.clone(),
_phantom: PhantomData,
}
}
}
impl From<PropertyBinding<ColorF>> for PropertyBinding<ColorU> {
fn from(value: PropertyBinding<ColorF>) -> PropertyBinding<ColorU> {
match value {
PropertyBinding::Value(value) => PropertyBinding::Value(value.into()),
PropertyBinding::Binding(k, v) => {
PropertyBinding::Binding(k.into(), v.into())
}
}
}
}
impl From<PropertyBinding<ColorU>> for PropertyBinding<ColorF> {
fn from(value: PropertyBinding<ColorU>) -> PropertyBinding<ColorF> {
match value {
PropertyBinding::Value(value) => PropertyBinding::Value(value.into()),
PropertyBinding::Binding(k, v) => {
PropertyBinding::Binding(k.into(), v.into())
}
}
}
}
/// The current value of an animated property. This is
/// supplied by the calling code.
#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq)]
@ -1930,10 +1890,8 @@ pub struct PropertyValue<T> {
pub struct DynamicProperties {
///
pub transforms: Vec<PropertyValue<LayoutTransform>>,
/// opacity
///
pub floats: Vec<PropertyValue<f32>>,
/// background color
pub colors: Vec<PropertyValue<ColorF>>,
}
/// A handler to integrate WebRender with the thread that contains the `Renderer`.

Просмотреть файл

@ -299,11 +299,11 @@ pub struct ScrollFrameDisplayItem {
pub external_scroll_offset: LayoutVector2D,
}
/// A solid or an animating color to draw (may not actually be a rectangle due to complex clips)
/// A solid color to draw (may not actually be a rectangle due to complex clips)
#[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Serialize, PeekPoke)]
pub struct RectangleDisplayItem {
pub common: CommonItemProperties,
pub color: PropertyBinding<ColorF>,
pub color: ColorF,
}
/// Clears all colors from the area, making it possible to cut holes in the window.

Просмотреть файл

@ -1116,19 +1116,7 @@ impl DisplayListBuilder {
) {
let item = di::DisplayItem::Rectangle(di::RectangleDisplayItem {
common: *common,
color: PropertyBinding::Value(color),
});
self.push_item(&item);
}
pub fn push_rect_with_animation(
&mut self,
common: &di::CommonItemProperties,
color: PropertyBinding<ColorF>,
) {
let item = di::DisplayItem::Rectangle(di::RectangleDisplayItem {
common: *common,
color,
color
});
self.push_item(&item);
}

Просмотреть файл

@ -14,7 +14,6 @@ use webrender::api::units::{LayoutSize, LayoutTransform};
pub struct SceneProperties {
transform_properties: HashMap<PropertyBindingId, LayoutTransform>,
float_properties: HashMap<PropertyBindingId, f32>,
color_properties: HashMap<PropertyBindingId, ColorF>,
}
impl SceneProperties {
@ -22,7 +21,6 @@ impl SceneProperties {
pub fn set_properties(&mut self, properties: &DynamicProperties) {
self.transform_properties.clear();
self.float_properties.clear();
self.color_properties.clear();
for property in &properties.transforms {
self.transform_properties
@ -33,11 +31,6 @@ impl SceneProperties {
self.float_properties
.insert(property.key.id, property.value);
}
for property in &properties.colors {
self.color_properties
.insert(property.key.id, property.value);
}
}
/// Get the current value for a transform property.
@ -64,17 +57,6 @@ impl SceneProperties {
.unwrap_or(v),
}
}
/// Get the current value for a color property.
pub fn resolve_color(&self, property: &PropertyBinding<ColorF>) -> ColorF {
match *property {
PropertyBinding::Value(value) => value,
PropertyBinding::Binding(ref key, v) => self.color_properties
.get(&key.id)
.cloned()
.unwrap_or(v),
}
}
}
/// A representation of the layout within the display port for a given document or iframe.

Просмотреть файл

@ -1002,13 +1002,7 @@ impl YamlFrameWriter {
DisplayItem::Rectangle(item) => {
str_node(&mut v, "type", "rect");
common_node(&mut v, clip_id_mapper, &item.common);
let key_label = match item.color {
PropertyBinding::Value(..) => "color",
PropertyBinding::Binding(..) => "animating-color",
};
color_node(&mut v, key_label,
scene.properties.resolve_color(&item.color));
color_node(&mut v, "color", item.color);
}
DisplayItem::HitTest(item) => {
str_node(&mut v, "type", "hit-test");

Просмотреть файл

@ -5141,28 +5141,12 @@ bool nsDisplayBackgroundColor::CreateWebRenderCommands(
return false;
}
uint64_t animationsId = 0;
// We don't support background-color animations on table elements yet.
if (GetType() == DisplayItemType::TYPE_BACKGROUND_COLOR) {
animationsId = AddAnimationsForWebRender(
this, aManager, aDisplayListBuilder, aBuilder.GetRenderRoot());
}
LayoutDeviceRect bounds = LayoutDeviceRect::FromAppUnits(
mBackgroundRect, mFrame->PresContext()->AppUnitsPerDevPixel());
wr::LayoutRect r = wr::ToLayoutRect(bounds);
if (animationsId) {
wr::WrAnimationProperty prop{
wr::WrAnimationType::BackgroundColor,
animationsId,
};
aBuilder.PushRectWithAnimation(r, r, !BackfaceIsHidden(),
wr::ToColorF(ToDeviceColor(mColor)), &prop);
} else {
aBuilder.PushRect(r, r, !BackfaceIsHidden(),
wr::ToColorF(ToDeviceColor(mColor)));
}
aBuilder.PushRect(r, r, !BackfaceIsHidden(),
wr::ToColorF(ToDeviceColor(mColor)));
return true;
}
@ -8362,7 +8346,9 @@ bool nsDisplayTransform::CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder) {
bool nsDisplayBackgroundColor::CanUseAsyncAnimations(
nsDisplayListBuilder* aBuilder) {
return StaticPrefs::gfx_omta_background_color();
LayerManager* layerManager = aBuilder->GetWidgetLayerManager();
return layerManager &&
layerManager->GetBackendType() != layers::LayersBackend::LAYERS_WR;
}
/* static */

Просмотреть файл

@ -1,9 +0,0 @@
<!DOCTYPE HTML>
<style>
#target {
width: 100px;
height: 100px;
background-color: green;
}
</style>
<div id="target"></div>

Просмотреть файл

@ -1,23 +0,0 @@
<!DOCTYPE HTML>
<html class="reftest-wait reftest-no-flush">
<style>
@keyframes anim {
from { background-color: green; }
to { background-color: red; }
}
#target {
width: 100px;
height: 100px;
background-color: black;
}
</style>
<div id="target"></div>
<script>
document.addEventListener("MozReftestInvalidate", () => {
target.style.animation = "anim 100s step-end reverse";
target.addEventListener("animationstart", () => {
document.documentElement.classList.remove("reftest-wait");
});
});
</script>
</html>

Просмотреть файл

@ -82,4 +82,3 @@ pref(layout.css.marker.restricted,false) == marker-reframe-and-animation-starts-
== opacity-animation-in-delay.html about:blank
== transform-animation-in-delay.html transform-animation-in-delay-ref.html
== containing-block-on-visibility-hidden.html containing-block-on-visibility-hidden-ref.html
== background-color.html background-color-ref.html

Просмотреть файл

@ -1,4 +1,4 @@
pref(gfx.omta.background-color,true) fuzzy(0-1,0-10000) == background-color-with-opacity.html background-color-with-opacity-ref.html
pref(gfx.omta.background-color,true) fuzzy-if((OSX&&!webrender)||(/^Windows\x20NT\x206\.1/.test(http.oscpu)&&!gpuProcess&&layersGPUAccelerated),1-1,10000-10000) == background-color-with-opacity.html background-color-with-opacity-ref.html
== transitions-inline-already-wrapped-1.html transitions-inline-ref.html
== transitions-inline-already-wrapped-2.html transitions-inline-ref.html
== transitions-inline-rewrap-1.html transitions-inline-ref.html

Просмотреть файл

@ -2396,125 +2396,127 @@ addAsyncAnimTest(async function() {
done_div();
});
// Normal background-color animation.
addAsyncAnimTest(async function() {
new_div("background-color: rgb(255, 0, 0); " +
"transition: background-color 10s linear");
await waitForPaintsFlushed();
if (SpecialPowers.DOMWindowUtils.layerManagerType != 'WebRender') {
// Normal background-color animation.
addAsyncAnimTest(async function() {
new_div("background-color: rgb(255, 0, 0); " +
"transition: background-color 10s linear");
await waitForPaintsFlushed();
gDiv.style.backgroundColor = "rgb(0, 255, 0)";
await waitForPaintsFlushed();
gDiv.style.backgroundColor = "rgb(0, 255, 0)";
await waitForPaintsFlushed();
omta_is("background-color", "rgb(255, 0, 0)", RunningOn.Compositor,
"background-color transition runs on compositor thread");
omta_is("background-color", "rgb(255, 0, 0)", RunningOn.Compositor,
"background-color transition runs on compositor thread");
advance_clock(5000);
omta_is("background-color", "rgb(128, 128, 0)", RunningOn.Compositor,
"background-color on compositor at 5s");
advance_clock(5000);
omta_is("background-color", "rgb(128, 128, 0)", RunningOn.Compositor,
"background-color on compositor at 5s");
done_div();
});
done_div();
});
// background-color animation with currentColor.
addAsyncAnimTest(async function() {
new_div("color: rgb(255, 0, 0); " +
"background-color: currentColor; " +
"transition: background-color 10s linear");
await waitForPaintsFlushed();
// background-color animation with currentColor.
addAsyncAnimTest(async function() {
new_div("color: rgb(255, 0, 0); " +
"background-color: currentColor; " +
"transition: background-color 10s linear");
await waitForPaintsFlushed();
gDiv.style.backgroundColor = "rgb(0, 255, 0)";
await waitForPaintsFlushed();
gDiv.style.backgroundColor = "rgb(0, 255, 0)";
await waitForPaintsFlushed();
omta_is("background-color", "rgb(255, 0, 0)", RunningOn.Compositor,
"background-color transition starting with current-color runs on " +
"compositor thread");
omta_is("background-color", "rgb(255, 0, 0)", RunningOn.Compositor,
"background-color transition starting with current-color runs on " +
"compositor thread");
advance_clock(5000);
omta_is("background-color", "rgb(128, 128, 0)", RunningOn.Compositor,
"background-color on compositor at 5s");
advance_clock(5000);
omta_is("background-color", "rgb(128, 128, 0)", RunningOn.Compositor,
"background-color on compositor at 5s");
done_div();
});
done_div();
});
// Tests that a background-color animation from inherited currentColor to
// a normal color on the compositor is updated when the parent color is
// changed.
addAsyncAnimTest(async function() {
new_div("");
const parent = document.createElement("div");
gDiv.parentNode.insertBefore(parent, gDiv);
parent.style.color = "rgb(255, 0, 0)";
parent.appendChild(gDiv);
// Tests that a background-color animation from inherited currentColor to
// a normal color on the compositor is updated when the parent color is
// changed.
addAsyncAnimTest(async function() {
new_div("");
const parent = document.createElement("div");
gDiv.parentNode.insertBefore(parent, gDiv);
parent.style.color = "rgb(255, 0, 0)";
parent.appendChild(gDiv);
gDiv.animate({ backgroundColor: [ "currentColor", "rgb(0, 255, 0)" ] }, 1000);
gDiv.animate({ backgroundColor: [ "currentColor", "rgb(0, 255, 0)" ] }, 1000);
await waitForPaintsFlushed();
await waitForPaintsFlushed();
omta_is("background-color", "rgb(255, 0, 0)", RunningOn.Compositor,
"background-color animation starting with current-color runs on " +
"compositor thread");
omta_is("background-color", "rgb(255, 0, 0)", RunningOn.Compositor,
"background-color animation starting with current-color runs on " +
"compositor thread");
advance_clock(500);
advance_clock(500);
omta_is("background-color", "rgb(128, 128, 0)", RunningOn.Compositor,
"background-color on compositor at 5s");
omta_is("background-color", "rgb(128, 128, 0)", RunningOn.Compositor,
"background-color on compositor at 5s");
// Change the parent's color in the middle of the animation.
parent.style.color = "rgb(0, 0, 255)";
await waitForPaintsFlushed();
// Change the parent's color in the middle of the animation.
parent.style.color = "rgb(0, 0, 255)";
await waitForPaintsFlushed();
omta_is("background-color", "rgb(0, 128, 128)", RunningOn.Compositor,
"background-color on compositor is reflected by the parent's " +
"color change");
omta_is("background-color", "rgb(0, 128, 128)", RunningOn.Compositor,
"background-color on compositor is reflected by the parent's " +
"color change");
done_div();
parent.remove();
});
done_div();
parent.remove();
});
// Tests that a background-color animation from currentColor to a normal color
// on <a> element is updated when the link is visited.
addAsyncAnimTest(async function() {
if (isGeckoView()) {
todo(false, "no global history on GeckoView; can't run test");
return;
}
// Tests that a background-color animation from currentColor to a normal color
// on <a> element is updated when the link is visited.
addAsyncAnimTest(async function() {
if (isGeckoView()) {
todo(false, "no global history on GeckoView; can't run test");
return;
}
[ gDiv ] = new_element("a", "display: block");
gDiv.setAttribute("href", "not-exist.html");
gDiv.classList.add("visited");
[ gDiv ] = new_element("a", "display: block");
gDiv.setAttribute("href", "not-exist.html");
gDiv.classList.add("visited");
const extraStyle = document.createElement('style');
document.head.appendChild(extraStyle);
extraStyle.sheet.insertRule(".visited:visited { color: rgb(0, 0, 255); }", 0);
extraStyle.sheet.insertRule(".visited:link { color: rgb(255, 0, 0); }", 1);
const extraStyle = document.createElement('style');
document.head.appendChild(extraStyle);
extraStyle.sheet.insertRule(".visited:visited { color: rgb(0, 0, 255); }", 0);
extraStyle.sheet.insertRule(".visited:link { color: rgb(255, 0, 0); }", 1);
gDiv.animate({ backgroundColor: [ "currentColor", "rgb(0, 255, 0)" ] }, 1000);
await waitForPaintsFlushed();
gDiv.animate({ backgroundColor: [ "currentColor", "rgb(0, 255, 0)" ] }, 1000);
await waitForPaintsFlushed();
omta_is("background-color", "rgb(255, 0, 0)", RunningOn.Compositor,
"background-color animation starting with current-color runs on " +
"compositor thread");
omta_is("background-color", "rgb(255, 0, 0)", RunningOn.Compositor,
"background-color animation starting with current-color runs on " +
"compositor thread");
advance_clock(500);
advance_clock(500);
omta_is("background-color", "rgb(128, 128, 0)", RunningOn.Compositor,
"background-color on compositor at 5s");
omta_is("background-color", "rgb(128, 128, 0)", RunningOn.Compositor,
"background-color on compositor at 5s");
gDiv.setAttribute("href", window.top.location.href);
await waitForVisitedLinkColoring(gDiv, "color", "rgb(0, 0, 255)");
await waitForPaintsFlushed();
gDiv.setAttribute("href", window.top.location.href);
await waitForVisitedLinkColoring(gDiv, "color", "rgb(0, 0, 255)");
await waitForPaintsFlushed();
// `omta_is` checks that the result on the compositor equals to the value by
// getComputedValue() but getComputedValue lies for visited link values so
// we use getOMTAStyle directly instead.
is(SpecialPowers.DOMWindowUtils.getOMTAStyle(gDiv, "background-color"),
"rgb(0, 128, 128)",
"background-color on <a> element after the link is visited");
// `omta_is` checks that the result on the compositor equals to the value by
// getComputedValue() but getComputedValue lies for visited link values so
// we use getOMTAStyle directly instead.
is(SpecialPowers.DOMWindowUtils.getOMTAStyle(gDiv, "background-color"),
"rgb(0, 128, 128)",
"background-color on <a> element after the link is visited");
extraStyle.remove();
done_element();
gDiv = null;
});
extraStyle.remove();
done_element();
gDiv = null;
});
}
// Normal translate animation.
addAsyncAnimTest(async function() {