[webkit-changes] [WebKit/WebKit] b9e5c9: DisplayListRecorder fails to record state change b...

Kimmo Kinnunen noreply at github.com
Tue Mar 14 01:04:39 PDT 2023


  Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: b9e5c9199441501375c71988e4efca5f487905f2
      https://github.com/WebKit/WebKit/commit/b9e5c9199441501375c71988e4efca5f487905f2
  Author: Kimmo Kinnunen <kkinnunen at apple.com>
  Date:   2023-03-14 (Tue, 14 Mar 2023)

  Changed paths:
    M Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.cpp
    M Source/WebCore/rendering/BorderPainter.cpp
    M Tools/TestWebKitAPI/Tests/WebCore/DisplayListRecorderTests.cpp

  Log Message:
  -----------
  DisplayListRecorder fails to record state change before multiple commands
https://bugs.webkit.org/show_bug.cgi?id=253693
rdar://problem/106542943

Reviewed by Simon Fraser.

Problems:
1. Multiple commands that use or might use the state are missing the
   appendStateChangeItemIfNecessary() that would write the state item.
2. Recorder::clipToImageBuffer() does not maintain the state needed to
   return the correct GraphicsContext::clipBounds().

Fix 1. by applying appendStateChangeItemIfNecessary() conservatively.
This is likely not a perf problem, since all the clip commands
would anyway need some future draw command, and those would append
the state change at that point.

Fix 2. by updating the clip bounds, similar to other cases which
update the clip bounds.

The video drawing commands are not testable currently, as MediaPlayer
cannot be instantiated as a mock and VideoFrame command is not implemented.

Auxiliary problems:
The unfixed, buggy behavior of Recorder::clipToPath() would invert buggy
behavior of BorderPainter.

This would lead to passing
imported/w3c/web-platform-tests/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-button-border-block-end-color-001.html
and similar tests.

The example of the problem, test above would compare two renderings:

Reference (kind-of-widget-fallback-input-button-border-block-end-color-001-expected.html)
    <input id="button-input" type="button" value="input-button">

vs:

Test (kind-of-widget-fallback-input-button-border-block-end-color-001.html)
    <input id="button-input" type="button" value="input-button">

    const prop = "border-block-end-color";
    for (const el of elements) {
        el.style.setProperty(prop, getComputedStyle(el).getPropertyValue(prop));
    }

The BorderPainter would compare the colors of each border, and run the
fast path if all the colors match.

For the reference, the fast path was taken.

For the test, because of the BorderPainter bug, the colors would not match. The
BorderPainter would take slow path that would set up complex clip path
with antialiasing.

Because the Recorder::clipToPath would incorrectly skip setting the antialiasing
state, two corner pixels of the rounded rect would be included in the rendering.
This would match the unclipped fast path rendering of the reference.

Once the clipToPath() bug was fixed, it would show two-pixel difference due
to the clipToPath being correctly cliping antialiased path vs the reference
using the fast path, unclipped.

Fix by fixing BorderPainter to compare the border colors always without
the "semantic" bit.

This makes the test take the same fast path as the reference, and thus the
rendering is identical.

Also in a best-effort manner, fix one other color compare case to ignore
the semantic bit. It is not consistent that one code-path would ignore
the semantic bit while others would be continue using it.

* Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.cpp:
(WebCore::DisplayList::Recorder::clip):
(WebCore::DisplayList::Recorder::clipOut):
(WebCore::DisplayList::Recorder::clipPath):
(WebCore::DisplayList::Recorder::clipToImageBuffer):
(WebCore::DisplayList::Recorder::paintFrameForMedia):
(WebCore::DisplayList::Recorder::paintVideoFrame):
* Tools/TestWebKitAPI/Tests/WebCore/DisplayListRecorderTests.cpp:
(TestWebKitAPI::createTestPath):
(TestWebKitAPI::createTestImageBuffer):
(TestWebKitAPI::checkEqualState):
* Source/WebCore/rendering/BorderPainter.cpp:
 (WebCore::BorderPainter::paintSides):
 (WebCore::BorderPainter::paintTranslucentBorderSides):

Canonical link: https://commits.webkit.org/261618@main




More information about the webkit-changes mailing list