Skip to content

Commit

Permalink
[css-properties-values-api] Invalidate paint worklet on registration.
Browse files Browse the repository at this point in the history
Due to how initial values of registered custom properties used to be
handled, the style diff function for custom paint could not discover that
the computed value for some property changed due to a new property
registration.

This meant that, if you used the property '--x' in your paint worklet
(without applying '--x' on any element in the document), and _then_
registered the property '--x' (giving it an initial value), the worklet
would not repaint even though the computed value of --x changed from
"nothing" to the registered initial value.

Now that initial values are returned from ::GetRegisteredVariable, simply
compare those values when diffing for custom paint invalidation.

Note that the second test in this CL is already passing before this CL,
but I'm including it anyway since that case is also mentioned in the bug.

R=ikilpatrick@chromium.org

Bug: 657706
Change-Id: I2b7707d48d73693a70b100fe1121bd7f977b4db1
Reviewed-on: https://chromium-review.googlesource.com/c/1309788
Commit-Queue: Anders Ruud <andruud@chromium.org>
Reviewed-by: Ian Kilpatrick <ikilpatrick@chromium.org>
Cr-Commit-Position: refs/heads/master@{#604607}
  • Loading branch information
andruud authored and foolip committed Nov 2, 2018
1 parent ff0b6d8 commit 2a56736
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 6 deletions.
17 changes: 11 additions & 6 deletions common/worklet-reftest.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ function importWorklet(worklet, code) {
return worklet.addModule(url);
}

async function animationFrames(frames) {
for (let i = 0; i < frames; i++)
await new Promise(requestAnimationFrame);
}

async function workletPainted() {
await animationFrames(2);
}

// To make sure that we take the snapshot at the right time, we do double
// requestAnimationFrame. In the second frame, we take a screenshot, that makes
// sure that we already have a full frame.
Expand All @@ -24,10 +33,6 @@ async function importWorkletAndTerminateTestAfterAsyncPaint(worklet, code) {
}

await importWorklet(worklet, code);

requestAnimationFrame(function() {
requestAnimationFrame(function() {
takeScreenshot();
});
});
await workletPainted();
takeScreenshot();
}
49 changes: 49 additions & 0 deletions css/css-paint-api/registered-property-invalidation-001.https.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<!DOCTYPE html>
<html class="reftest-wait">
<title>Registering a property causes invalidation for initial value</title>
<link rel="help" href="https://www.w3.org/TR/css-paint-api-1/#examples">
<link rel="match" href="parse-input-arguments-ref.html">
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<body>
<style>
#target {
background: paint(geometry);
width: 100px;
height: 100px;
}
</style>
<div id="target"></div>
<script id="code" type="text/worklet">
registerPaint('geometry', class {
static get inputProperties() { return ['--color']; }
paint(ctx, geom, styleMap) {
ctx.strokeStyle = styleMap.get('--color').toString();
ctx.lineWidth = 4;
ctx.strokeRect(0, 0, geom.width, geom.height);
}
});
</script>

<script>
async function test() {
getComputedStyle(target);
let code = document.getElementById('code').textContent;
await importWorklet(CSS.paintWorklet, code);
await workletPainted();
CSS.registerProperty({
name: '--color',
syntax: '<color>',
initialValue: 'green',
inherits: false
});
await workletPainted();
takeScreenshot();
}

test();
</script>
</body>
</html>


52 changes: 52 additions & 0 deletions css/css-paint-api/registered-property-invalidation-002.https.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<!DOCTYPE html>
<html class="reftest-wait">
<title>Registering a property causes invalidation for applied value</title>
<link rel="help" href="https://www.w3.org/TR/css-paint-api-1/#examples">
<link rel="match" href="parse-input-arguments-ref.html">
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<body>
<style>
#target {
background: paint(geometry);
width: 100px;
height: 100px;
--length: 100px;
}
</style>
<div id="target"></div>
<script id="code" type="text/worklet">
registerPaint('geometry', class {
static get inputProperties() { return ['--length']; }
paint(ctx, geom, styleMap) {
let value = styleMap.get('--length');
let pass = value.value === 100 && value.unit === 'px';
ctx.strokeStyle = pass ? 'green' : 'red';
ctx.lineWidth = 4;
ctx.strokeRect(0, 0, geom.width, geom.height);
}
});
</script>

<script>
async function test() {
getComputedStyle(target);
let code = document.getElementById('code').textContent;
await importWorklet(CSS.paintWorklet, code);
await workletPainted();
CSS.registerProperty({
name: '--length',
syntax: '<length>',
initialValue: '0px',
inherits: false
});
await workletPainted();
takeScreenshot();
}

test();
</script>
</body>
</html>


0 comments on commit 2a56736

Please sign in to comment.