Bug 1914735 - Track color-scheme dependencies for non-inherited rule cache. r=firefox-style-system-reviewers,boris

Differential Revision: https://phabricator.services.mozilla.com/D220134
This commit is contained in:
Emilio Cobos Álvarez 2024-09-04 16:56:38 +00:00
Родитель 250e3875ed
Коммит cbd27def34
4 изменённых файлов: 66 добавлений и 1 удалений

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

@ -11,6 +11,7 @@ use crate::rule_tree::StrongRuleNode;
use crate::selector_parser::PseudoElement;
use crate::shared_lock::StylesheetGuards;
use crate::values::computed::{NonNegativeLength, Zoom};
use crate::values::specified::color::ColorSchemeFlags;
use fxhash::FxHashMap;
use servo_arc::Arc;
use smallvec::SmallVec;
@ -22,6 +23,7 @@ pub struct RuleCacheConditions {
font_size: Option<NonNegativeLength>,
line_height: Option<NonNegativeLength>,
writing_mode: Option<WritingMode>,
color_scheme: Option<ColorSchemeFlags>,
}
impl RuleCacheConditions {
@ -37,6 +39,12 @@ impl RuleCacheConditions {
self.line_height = Some(line_height);
}
/// Sets the style as depending in the color-scheme property value.
pub fn set_color_scheme_dependency(&mut self, color_scheme: ColorSchemeFlags) {
debug_assert!(self.color_scheme.map_or(true, |cs| cs == color_scheme));
self.color_scheme = Some(color_scheme);
}
/// Sets the style as uncacheable.
pub fn set_uncacheable(&mut self) {
self.uncacheable = true;
@ -58,6 +66,7 @@ impl RuleCacheConditions {
struct CachedConditions {
font_size: Option<NonNegativeLength>,
line_height: Option<NonNegativeLength>,
color_scheme: Option<ColorSchemeFlags>,
writing_mode: Option<WritingMode>,
zoom: Zoom,
}
@ -85,6 +94,12 @@ impl CachedConditions {
}
}
if let Some(cs) = self.color_scheme {
if style.get_inherited_ui().clone_color_scheme().bits != cs {
return false;
}
}
if let Some(wm) = self.writing_mode {
if style.writing_mode != wm {
return false;
@ -208,6 +223,7 @@ impl RuleCache {
writing_mode: conditions.writing_mode,
font_size: conditions.font_size,
line_height: conditions.line_height,
color_scheme: conditions.color_scheme,
zoom: style.effective_zoom,
};
self.map

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

@ -141,6 +141,9 @@ impl LightDark {
fn compute(&self, cx: &Context) -> ComputedColor {
let style_color_scheme = cx.style().get_inherited_ui().clone_color_scheme();
let dark = cx.device().is_dark_color_scheme(&style_color_scheme);
if cx.for_non_inherited_property {
cx.rule_cache_conditions.borrow_mut().set_color_scheme_dependency(style_color_scheme.bits);
}
let used = if dark { &self.dark } else { &self.light };
used.to_computed_value(cx)
}
@ -421,6 +424,9 @@ impl SystemColor {
// TODO: We should avoid cloning here most likely, though it's cheap-ish.
let style_color_scheme = cx.style().get_inherited_ui().clone_color_scheme();
let color = cx.device().system_nscolor(*self, &style_color_scheme);
if cx.for_non_inherited_property {
cx.rule_cache_conditions.borrow_mut().set_color_scheme_dependency(style_color_scheme.bits);
}
if color == bindings::NS_SAME_AS_FOREGROUND_COLOR {
return ComputedColor::currentcolor();
}
@ -930,7 +936,7 @@ bitflags! {
pub struct ColorScheme {
#[ignore_malloc_size_of = "Arc"]
idents: crate::ArcSlice<CustomIdent>,
bits: ColorSchemeFlags,
pub bits: ColorSchemeFlags,
}
impl ColorScheme {

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

@ -0,0 +1,22 @@
<!doctype html>
<meta charset="utf-8">
<title>CSS Test Reference</title>
<style>
.dark {
color-scheme: dark;
background-color: Canvas;
color: CanvasText;
border: 2px solid purple;
}
.light {
background-color: white;
color: black;
border: 2px solid blue;
}
</style>
<div class="light">
Always light
</div>
<div class="dark">
Always dark
</div>

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

@ -0,0 +1,21 @@
<!doctype html>
<meta charset="utf-8">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1914735">
<link rel="author" href="mailto:kizmarh@gmail.com" title="Roman Komarov">
<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
<link rel="author" href="https://mozilla.org" title="Mozilla">
<link rel="match" href="color-scheme-rule-cache-ref.html">
<title>Dependencies from color-scheme to non-inherited properties</title>
<style>
div {
background-color: Canvas;
color: CanvasText;
border: 2px solid light-dark(blue, purple);
}
</style>
<div style="color-scheme: light">
Always light
</div>
<div style="color-scheme: dark">
Always dark
</div>