Skip to content

libservo: Add a WebView::take_screenshot() API and use it for reftests#39583

Merged
mrobinson merged 1 commit intoservo:mainfrom
mrobinson:add-a-take-screenshot-api
Sep 30, 2025
Merged

libservo: Add a WebView::take_screenshot() API and use it for reftests#39583
mrobinson merged 1 commit intoservo:mainfrom
mrobinson:add-a-take-screenshot-api

Conversation

@mrobinson
Copy link
Copy Markdown
Member

@mrobinson mrobinson commented Sep 30, 2025

This change adds a new API to the WebView for capturing screenshots.
This makes it possible to:

  • use the reftest waiting infrastructure via the API
    easily.
  • take more than a single screenshot in one Servo run.
  • take screenshots, but still paint the WebView normally prior
    to the moment that the screenshot is ready, instead of preventing
    all non-screenshot-ready paints while taking a screenshot.

In addition, the previous infrastructure, the wait_for_stable_image
option is removed completely.

Testing: This change is tested by the passing of the WPT tests,
as they commonly use the screenshot feature.

@mrobinson mrobinson added the T-linux-wpt Do a try run of the WPT label Sep 30, 2025
@github-actions github-actions bot removed the T-linux-wpt Do a try run of the WPT label Sep 30, 2025
@github-actions
Copy link
Copy Markdown

🔨 Triggering try run (#18121131681) for Linux (WPT)

@yezhizhen yezhizhen self-requested a review September 30, 2025 06:50
self.set_needs_repaint(RepaintReason::ReadyForScreenshot);
}
CompositorMsg::NewWebRenderFrameReady(..) => {
unreachable!("New WebRender frames should be handled in the caller.");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we add a comment in handle_messages() explaining why we set these messages aside, and maybe s/the caller/handle_messages()/ here?

Comment on lines +1073 to 1076
let img = self
.compositor
.borrow_mut()
.render_to_shared_memory(webview_id, page_rect);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we can do something similar here and completely remove render_to_shared_memory. This is also taking webview screenshot if page_rect == None.

If provided, it takes the screenshot of the rectangle.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep! That's will be the next change in the series.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! render_to_shared_memory is used as for WebDriver screenshot test, and should provide test coverage for the change.

@github-actions
Copy link
Copy Markdown

Test results for linux-wpt from try job (#18121131681):

Flaky unexpected result (29)
  • OK /FileAPI/url/url-with-fetch.any.worker.html (#21517)
    • FAIL [expected PASS] subtest: Revoke blob URL after calling fetch, fetch should succeed

      promise_test: Unhandled rejection with value: object "TypeError: Network error occurred"
      

  • OK /IndexedDB/idbfactory_open.any.html
    • FAIL [expected PASS] subtest: Calling open() with version argument 1.5 should not throw.

      assert_equals: version expected 1 but got 9007199254740991
      

  • FAIL [expected PASS] /_mozilla/gfx-rs-gecko/descriptor-ranges.html (#23258)
  • TIMEOUT [expected PASS] /_mozilla/shadow-dom/move-element-with-ua-shadow-tree-crash.html (#39473)
  • OK /_webgl/conformance/textures/misc/texture-upload-size.html (#21770)
    • FAIL [expected PASS] subtest: WebGL test #53

      assert_true: Texture was smaller than the expected size 2x2 expected true got false
      

    • FAIL [expected PASS] subtest: WebGL test #55

      assert_true: getError expected: INVALID_VALUE. Was NO_ERROR : when calling texSubImage2D with the same texture upload with offset 1, 1 expected true got false
      

    • FAIL [expected PASS] subtest: WebGL test #57

      assert_true: Texture was smaller than the expected size 2x2 expected true got false
      

    • FAIL [expected PASS] subtest: WebGL test #59

      assert_true: getError expected: INVALID_VALUE. Was NO_ERROR : when calling texSubImage2D with the same texture upload with offset 1, 1 expected true got false
      

    • PASS [expected FAIL] subtest: WebGL test #61
    • PASS [expected FAIL] subtest: WebGL test #63
    • PASS [expected FAIL] subtest: WebGL test #65
    • PASS [expected FAIL] subtest: WebGL test #67
    • FAIL [expected PASS] subtest: WebGL test #69

      assert_true: Texture was smaller than the expected size 2x2 expected true got false
      

    • FAIL [expected PASS] subtest: WebGL test #71

      assert_true: getError expected: INVALID_VALUE. Was NO_ERROR : when calling texSubImage2D with the same texture upload with offset 1, 1 expected true got false
      

    • And 2 more unexpected results...
  • FAIL [expected PASS] /css/WOFF2/metadatadisplay-encoding-002.xht
  • FAIL [expected PASS] /css/WOFF2/metadatadisplay-schema-license-010.xht
  • FAIL [expected PASS] /css/WOFF2/metadatadisplay-schema-trademark-016.xht
  • FAIL [expected PASS] /css/WOFF2/metadatadisplay-well-formed-004.xht
  • OK /css/css-cascade/layer-font-face-override.html (#35935)
    • FAIL [expected PASS] subtest: @font-face override update with appended sheet 1

      assert_equals: expected "80px" but got "38.3166666666667px"
      

    • FAIL [expected PASS] subtest: @font-face override update with appended sheet 2

      assert_equals: expected "80px" but got "38.3166666666667px"
      

  • FAIL [expected PASS] /css/css-fonts/font-face-local-not-family.html
  • PASS [expected FAIL] /css/css-fonts/font-palette-9.html
  • OK /css/css-text/i18n/zh/css-text-line-break-zh-po-strict.html
    • FAIL [expected PASS] subtest: FE6A SMALL PERCENT SIGN may NOT appear at line start if zh and strict

      assert_approx_equals: expected 80 +/- 1 but got 87
      

  • OK /fetch/metadata/generated/css-font-face.sub.tentative.html (#34624)
    • PASS [expected FAIL] subtest: sec-fetch-storage-access - Not sent to non-trustworthy cross-site destination
  • OK /html/browsers/browsing-the-web/navigating-across-documents/replace-before-load/a-click.html (#28697)
    • PASS [expected FAIL] subtest: aElement.click() before the load event must NOT replace
  • OK /html/browsers/history/the-history-interface/traverse_the_history_4.html (#21383)
    • PASS [expected FAIL] subtest: Multiple history traversals, last would be aborted
  • TIMEOUT [expected OK] /html/interaction/focus/the-autofocus-attribute/document-with-fragment-empty.html (#28259)
    • TIMEOUT [expected FAIL] subtest: Autofocus elements in top-level browsing context's documents with empty fragments should work.

      Test timed out
      

  • OK [expected CRASH] /html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html (#22647)
  • TIMEOUT [expected CRASH] /html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-3.html (#24057)
  • CRASH [expected OK] /html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html (#22154)
  • TIMEOUT [expected OK] /html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-3.html (#24066)
    • NOTRUN [expected FAIL] subtest: Check that popups from a sandboxed iframe do not escape the sandbox
  • OK /html/semantics/forms/form-submission-0/form-submit-iframe-then-location-navigate.html (#29634)
    • PASS [expected FAIL] subtest: Verifies that location navigations take precedence when following form submissions.
  • OK /html/semantics/forms/historical.html (#28568)
    • FAIL [expected PASS] subtest: <input name=isindex> should not be supported

      assert_regexp_match: expected object "/\?isindex=x$/" but got "about:blank"
      

  • TIMEOUT [expected CRASH] /html/webappapis/dynamic-markup-insertion/opening-the-input-stream/ignore-opens-during-unload.window.html (#21444)
  • OK /preload/prefetch-document.html (#37210)
    • FAIL [expected PASS] subtest: different-site document prefetch with 'as=document' should not be consumed

      assert_equals: expected 2 but got 1
      

  • ERROR /service-workers/idlharness.https.any.html (#36250)
    • PASS [expected TIMEOUT] subtest: ServiceWorkerContainer interface: operation register((TrustedScriptURL or USVString), optional RegistrationOptions)
    • PASS [expected TIMEOUT] subtest: NavigationPreloadManager interface: operation enable()
    • PASS [expected TIMEOUT] subtest: NavigationPreloadManager interface: operation disable()
    • PASS [expected TIMEOUT] subtest: NavigationPreloadManager interface: operation setHeaderValue(ByteString)
    • PASS [expected TIMEOUT] subtest: NavigationPreloadManager interface: operation getState()
  • FAIL [expected PASS] /shadow-dom/shadow-style-invalidation-vw-units.html (#38468)
  • OK /webdriver/tests/classic/find_elements_from_element/user_prompts.py
    • FAIL [expected PASS] subtest: test_accept[alert-None]

      webdriver.error.NoSuchElementException: no such element (404)
      

  • OK /webdriver/tests/classic/get_element_attribute/user_prompts.py
    • FAIL [expected PASS] subtest: test_accept[alert-None]

      webdriver.error.NoSuchElementException: no such element (404)
      

Stable unexpected results that are known to be intermittent (33)
  • OK /IndexedDB/idbcursor-continuePrimaryKey-exceptions.any.worker.html (#39277)
    • FAIL [expected PASS] subtest: IDBCursor continuePrimaryKey() on object store cursor

      assert_throws_dom: continuePrimaryKey() should throw if source is not an index function "function() {
              cursor.continuePrimaryKey(2, 2);
            }" threw object "TypeError: cursor.continuePrimaryKey is not a function" that is not a DOMException InvalidAccessError: property "code" is equal to undefined, expected 15
      

  • OK /IndexedDB/idbobjectstore_get.any.html (#38942)
    • PASS [expected FAIL] subtest: Attempts to retrieve a record that doesn't exist
  • OK /IndexedDB/idbobjectstore_getAll.any.html (#39276)
    • PASS [expected FAIL] subtest: Get all values with transaction.commit()
  • OK /IndexedDB/idbobjectstore_getAll.any.worker.html (#39400)
    • PASS [expected FAIL] subtest: Get all values with transaction.commit()
  • OK /IndexedDB/key-conversion-exceptions.any.html (#39305)
    • FAIL [expected PASS] subtest: IDBCursor continue() method with throwing/invalid keys

      assert_throws_exactly: key conversion with throwing getter should rethrow function "() => {
            receiver[method](key);
          }" threw object "TypeError: receiver[method] is not a function" but we expected it to throw object "getter: throwing from getter"
      

  • OK /IndexedDB/key-conversion-exceptions.any.worker.html (#39284)
    • FAIL [expected PASS] subtest: IDBCursor continue() method with throwing/invalid keys

      assert_throws_exactly: key conversion with throwing getter should rethrow function "() => {
            receiver[method](key);
          }" threw object "TypeError: receiver[method] is not a function" but we expected it to throw object "getter: throwing from getter"
      

  • FAIL [expected PASS] /_mozilla/css/iframe/hide_and_show.html (#15265)
  • FAIL [expected PASS] /_mozilla/css/stacked_layers.html (#39548)
  • FAIL [expected PASS] /_mozilla/mozilla/sslfail.html (#10760)
  • TIMEOUT [expected OK] /_mozilla/mozilla/window_resize_event.html (#36741)
    • TIMEOUT [expected PASS] subtest: Popup onresize event fires after resizeTo

      Test timed out
      

  • OK /_webgl/conformance/rendering/texture-switch-performance.html (#23384)
    • FAIL [expected PASS] subtest: WebGL test #0

      assert_true: Texture switching significantly hurt performance - achieved 67 frames in 2.027 seconds (0.39 times baseline performance) expected true got false
      

  • OK /_webgl/conformance2/rendering/texture-switch-performance.html (#23384)
    • FAIL [expected PASS] subtest: WebGL test #0

      assert_true: Texture switching significantly hurt performance - achieved 99 frames in 2.008 seconds (0.58 times baseline performance) expected true got false
      

  • OK /css/css-fonts/generic-family-keywords-003.html (#38994)
    • PASS [expected FAIL] subtest: @font-face matching for quoted and unquoted serif (drawing text in a canvas)
  • TIMEOUT [expected FAIL] /dom/xslt/large-cdata.html (#38029)
  • TIMEOUT [expected OK] /fetch/api/redirect/redirect-keepalive.https.any.html (#32153)
    • TIMEOUT [expected PASS] subtest: [keepalive][iframe][load] mixed content redirect; setting up

      Test timed out
      

  • ERROR [expected TIMEOUT] /fetch/fetch-later/quota/same-origin-iframe/max-payload.https.window.html (#35210)
  • OK /fetch/metadata/generated/css-font-face.https.sub.tentative.html (#32732)
    • PASS [expected FAIL] subtest: sec-fetch-storage-access - Cross-site
    • PASS [expected FAIL] subtest: sec-fetch-storage-access - Same site
  • OK /html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/iframe-nosrc.html (#34819)
    • PASS [expected FAIL] subtest: link click
  • OK /html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/iframe-src-aboutblank-navigate-immediately.html (#29048)
    • FAIL [expected PASS] subtest: Navigating to a different document with location.assign

      assert_equals: expected "http://web-platform.test:8000/common/blank.html?1" but got "about:blank"
      

  • OK /html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-cross-origin.sub.window.html (#29056)
    • FAIL [expected PASS] subtest: Cross-origin navigation started from unload handler must be ignored

      promise_test: Unhandled rejection with value: object "SecurityError: The operation is insecure."
      

  • OK /html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-same-origin.window.html (#29049)
    • PASS [expected FAIL] subtest: Same-origin navigation started from unload handler must be ignored
  • TIMEOUT [expected OK] /html/interaction/focus/the-autofocus-attribute/document-with-fragment-nonexistent.html (#28259)
    • TIMEOUT [expected FAIL] subtest: Autofocus elements in top-level browsing context's documents with non-existent fragments should work.

      Test timed out
      

  • CRASH [expected OK] /html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-2.html (#22667)
  • OK [expected CRASH] /html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html (#24066)
  • OK /html/semantics/forms/form-submission-0/text-plain.window.html (#28687)
    • PASS [expected FAIL] subtest: text/plain: Basic test (normal form)
    • PASS [expected FAIL] subtest: text/plain: Basic File test (formdata event)
    • PASS [expected FAIL] subtest: text/plain: 0x00 in filename (formdata event)
  • OK /html/semantics/forms/form-submission-0/urlencoded2.window.html (#28687)
    • FAIL [expected PASS] subtest: application/x-www-form-urlencoded: Basic test (normal form)

      assert_equals: expected "basic=test" but got ""
      

  • OK /preload/preload-error.sub.html (#37177)
    • PASS [expected FAIL] subtest: success (fetch): main
  • OK /preload/preload-invalid-resources.html (#39091)
    • PASS [expected FAIL] subtest: Preloading an invalid image (missing) should preload and not re-fetch
  • TIMEOUT /preload/preload-resource-match.https.html (#38088)
    • PASS [expected TIMEOUT] subtest: Loading module (use-credentials) with link (anonymous) should discard the preloaded response
    • PASS [expected NOTRUN] subtest: Loading module (use-credentials) with link (use-credentials) should reuse the preloaded response
    • PASS [expected NOTRUN] subtest: Loading style (same-origin) with link (same-origin) should reuse the preloaded response
    • PASS [expected NOTRUN] subtest: Loading style (no-cors) with link (no-cors) should reuse the preloaded response
    • PASS [expected NOTRUN] subtest: Loading style (no-cors) with link (anonymous) should discard the preloaded response
    • PASS [expected NOTRUN] subtest: Loading style (no-cors) with link (use-credentials) should discard the preloaded response
    • PASS [expected NOTRUN] subtest: Loading style (anonymous) with link (no-cors) should discard the preloaded response
    • PASS [expected NOTRUN] subtest: Loading style (anonymous) with link (anonymous) should reuse the preloaded response
    • PASS [expected NOTRUN] subtest: Loading style (anonymous) with link (use-credentials) should discard the preloaded response
    • PASS [expected NOTRUN] subtest: Loading style (use-credentials) with link (no-cors) should discard the preloaded response
    • And 1 more unexpected results...
  • OK /trusted-types/trusted-types-navigation.html?01-05 (#38975)
    • PASS [expected FAIL] subtest: Navigate a frame via anchor with javascript:-urls in enforcing mode.
  • OK /trusted-types/trusted-types-navigation.html?26-30 (#38807)
    • FAIL [expected PASS] subtest: Navigate a window via form-submission with javascript:-urls in report-only mode.

      promise_test: Unhandled rejection with value: "Unexpected message received: \"No securitypolicyviolation reported!\""
      

  • TIMEOUT [expected OK] /webdriver/tests/classic/perform_actions/navigation.py (#38822)
  • OK [expected ERROR] /workers/baseurl/alpha/sharedworker-in-worker.html (#21315)

@github-actions
Copy link
Copy Markdown

✨ Try run (#18121131681) succeeded.

@mrobinson mrobinson force-pushed the add-a-take-screenshot-api branch from c1b2f31 to a6d1f8a Compare September 30, 2025 08:57
@mrobinson mrobinson marked this pull request as ready for review September 30, 2025 08:57
@servo-highfive servo-highfive added the S-awaiting-review There is new code that needs to be reviewed. label Sep 30, 2025
@mrobinson mrobinson force-pushed the add-a-take-screenshot-api branch from a6d1f8a to 134a7d5 Compare September 30, 2025 08:58
@mrobinson mrobinson enabled auto-merge September 30, 2025 08:58
@mrobinson mrobinson added this pull request to the merge queue Sep 30, 2025
@servo-highfive servo-highfive added the S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. label Sep 30, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Sep 30, 2025
@servo-highfive servo-highfive added S-tests-failed The changes caused existing tests to fail. and removed S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. labels Sep 30, 2025
@mrobinson mrobinson force-pushed the add-a-take-screenshot-api branch from 134a7d5 to f072b4e Compare September 30, 2025 10:21
@mrobinson mrobinson requested a review from jschwe as a code owner September 30, 2025 10:21
@servo-highfive servo-highfive removed the S-tests-failed The changes caused existing tests to fail. label Sep 30, 2025
@mrobinson mrobinson added T-android Do a try run on Android T-ohos Do a try run on OpenHarmony labels Sep 30, 2025
@github-actions github-actions bot removed the T-android Do a try run on Android label Sep 30, 2025
@github-actions
Copy link
Copy Markdown

🔨 Triggering try run (#18126654002) for Android

@github-actions github-actions bot removed the T-ohos Do a try run on OpenHarmony label Sep 30, 2025
@github-actions
Copy link
Copy Markdown

🔨 Triggering try run (#18126655985) for OpenHarmony

@github-actions
Copy link
Copy Markdown

⚠️ Try run (#18126655985) failed.

@github-actions
Copy link
Copy Markdown

⚠️ Try run (#18126654002) failed.

This change adds a new API to the `WebView` for capturing screenshots.
This makes it:

 - Possible to use the reftest waiting infrastructure via the API
   easily.
 - Possible to take more than a single screenshot in one Servo run.

In addition, the previous infrastructure, the `wait_for_stable_image`
option is removed completely.

Co-authored-by: Delan Azabani <[email protected]>
Signed-off-by: Martin Robinson <[email protected]>
@mrobinson mrobinson force-pushed the add-a-take-screenshot-api branch from f072b4e to fd12589 Compare September 30, 2025 10:56
@mrobinson mrobinson added T-android Do a try run on Android T-ohos Do a try run on OpenHarmony labels Sep 30, 2025
@github-actions github-actions bot removed T-android Do a try run on Android T-ohos Do a try run on OpenHarmony labels Sep 30, 2025
@github-actions
Copy link
Copy Markdown

🔨 Triggering try run (#18127549061) for Android, OpenHarmony

@github-actions
Copy link
Copy Markdown

🐰 Bencher Report

Branch39583/PR
TestbedHUAWEI Mate 60 Pro

⚠️ WARNING: No Threshold found!

Without a Threshold, no Alerts will ever be generated.

Click here to create a new Threshold
For more information, see the Threshold documentation.
To only post results if a Threshold exists, set the --ci-only-thresholds flag.

Click to view all benchmark results
BenchmarkDataMeasure (units) x 1e3Latencymilliseconds (ms)MemoryBytesscoreMeasure (units)
release/E2E/file:///parse_from_string.html/📈 view plot
⚠️ NO THRESHOLD
2.05 units x 1e3
release/E2E/https://www.google.com/JS/gc-heap/admin📈 view plot
⚠️ NO THRESHOLD
26,752.00
release/E2E/https://www.google.com/JS/gc-heap/decommitted📈 view plot
⚠️ NO THRESHOLD
409,600.00
release/E2E/https://www.google.com/JS/gc-heap/unused📈 view plot
⚠️ NO THRESHOLD
139,832.00
release/E2E/https://www.google.com/JS/gc-heap/used📈 view plot
⚠️ NO THRESHOLD
472,392.00
release/E2E/https://www.google.com/JS/malloc-heap📈 view plot
⚠️ NO THRESHOLD
5,050,803.00
release/E2E/https://www.google.com/JS/non-heap📈 view plot
⚠️ NO THRESHOLD
262,144.00
release/E2E/https://www.google.com/LayoutThread/box-tree📈 view plot
⚠️ NO THRESHOLD
107,632.00
release/E2E/https://www.google.com/LayoutThread/display-list📈 view plot
⚠️ NO THRESHOLD
0.00
release/E2E/https://www.google.com/LayoutThread/font-context📈 view plot
⚠️ NO THRESHOLD
8,616.00
release/E2E/https://www.google.com/LayoutThread/fragment-tree📈 view plot
⚠️ NO THRESHOLD
112.00
release/E2E/https://www.google.com/LayoutThread/stacking-context-tree📈 view plot
⚠️ NO THRESHOLD
14,080.00
release/E2E/https://www.google.com/LayoutThread/stylist📈 view plot
⚠️ NO THRESHOLD
5,104.00
release/E2E/https://www.google.com/Load📈 view plot
⚠️ NO THRESHOLD
719.74 ms
release/E2E/https://www.google.com/Resident📈 view plot
⚠️ NO THRESHOLD
182,742,220.00
release/E2E/https://www.google.com/image-cache📈 view plot
⚠️ NO THRESHOLD
35,760.00
release/E2E/https://www.google.com/resident-smaps📈 view plot
⚠️ NO THRESHOLD
185,483,264.00
release/E2E/https://www.servo.org/Load📈 view plot
⚠️ NO THRESHOLD
909.37 ms
release/E2E/https://www.servo.org/Resident📈 view plot
⚠️ NO THRESHOLD
263,510,425.00
release/E2E/https://www.servo.org/resident-smaps📈 view plot
⚠️ NO THRESHOLD
264,702,361.00
release/Speedometer/Charts-observable-plot📈 view plot
⚠️ NO THRESHOLD
795.25 ms
release/Speedometer/Charts-observable-plot/Dotted📈 view plot
⚠️ NO THRESHOLD
98.33 ms
release/Speedometer/Charts-observable-plot/Dotted/Async📈 view plot
⚠️ NO THRESHOLD
9.70 ms
release/Speedometer/Charts-observable-plot/Dotted/Sync📈 view plot
⚠️ NO THRESHOLD
88.63 ms
release/Speedometer/Charts-observable-plot/Stacked by 20📈 view plot
⚠️ NO THRESHOLD
391.90 ms
release/Speedometer/Charts-observable-plot/Stacked by 20/Async📈 view plot
⚠️ NO THRESHOLD
16.76 ms
release/Speedometer/Charts-observable-plot/Stacked by 20/Sync📈 view plot
⚠️ NO THRESHOLD
375.14 ms
release/Speedometer/Charts-observable-plot/Stacked by 6📈 view plot
⚠️ NO THRESHOLD
305.03 ms
release/Speedometer/Charts-observable-plot/Stacked by 6/Async📈 view plot
⚠️ NO THRESHOLD
8.22 ms
release/Speedometer/Charts-observable-plot/Stacked by 6/Sync📈 view plot
⚠️ NO THRESHOLD
296.80 ms
release/Speedometer/Geomean📈 view plot
⚠️ NO THRESHOLD
695.87 ms
release/Speedometer/Iteration-0-Total📈 view plot
⚠️ NO THRESHOLD
905.74 ms
release/Speedometer/Iteration-1-Total📈 view plot
⚠️ NO THRESHOLD
879.21 ms
release/Speedometer/Iteration-2-Total📈 view plot
⚠️ NO THRESHOLD
873.40 ms
release/Speedometer/Iteration-3-Total📈 view plot
⚠️ NO THRESHOLD
1,089.87 ms
release/Speedometer/Iteration-4-Total📈 view plot
⚠️ NO THRESHOLD
1,133.33 ms
release/Speedometer/Iteration-5-Total📈 view plot
⚠️ NO THRESHOLD
912.69 ms
release/Speedometer/Iteration-6-Total📈 view plot
⚠️ NO THRESHOLD
874.90 ms
release/Speedometer/Iteration-7-Total📈 view plot
⚠️ NO THRESHOLD
912.50 ms
release/Speedometer/Iteration-8-Total📈 view plot
⚠️ NO THRESHOLD
1,134.47 ms
release/Speedometer/Iteration-9-Total📈 view plot
⚠️ NO THRESHOLD
1,132.14 ms
release/Speedometer/Score📈 view plot
⚠️ NO THRESHOLD
1.45 units
release/Speedometer/TodoMVC-Angular📈 view plot
⚠️ NO THRESHOLD
953.27 ms
release/Speedometer/TodoMVC-Angular/Adding100Items📈 view plot
⚠️ NO THRESHOLD
457.19 ms
release/Speedometer/TodoMVC-Angular/Adding100Items/Async📈 view plot
⚠️ NO THRESHOLD
29.75 ms
release/Speedometer/TodoMVC-Angular/Adding100Items/Sync📈 view plot
⚠️ NO THRESHOLD
427.44 ms
release/Speedometer/TodoMVC-Angular/CompletingAllItems📈 view plot
⚠️ NO THRESHOLD
305.84 ms
release/Speedometer/TodoMVC-Angular/CompletingAllItems/Async📈 view plot
⚠️ NO THRESHOLD
34.93 ms
release/Speedometer/TodoMVC-Angular/CompletingAllItems/Sync📈 view plot
⚠️ NO THRESHOLD
270.91 ms
release/Speedometer/TodoMVC-Angular/DeletingAllItems📈 view plot
⚠️ NO THRESHOLD
190.24 ms
release/Speedometer/TodoMVC-Angular/DeletingAllItems/Async📈 view plot
⚠️ NO THRESHOLD
6.25 ms
release/Speedometer/TodoMVC-Angular/DeletingAllItems/Sync📈 view plot
⚠️ NO THRESHOLD
183.99 ms
release/Speedometer/TodoMVC-JavaScript-ES5📈 view plot
⚠️ NO THRESHOLD
1,587.24 ms
release/Speedometer/TodoMVC-JavaScript-ES5/Adding100Items📈 view plot
⚠️ NO THRESHOLD
1,305.07 ms
release/Speedometer/TodoMVC-JavaScript-ES5/Adding100Items/Async📈 view plot
⚠️ NO THRESHOLD
53.38 ms
release/Speedometer/TodoMVC-JavaScript-ES5/Adding100Items/Sync📈 view plot
⚠️ NO THRESHOLD
1,251.69 ms
release/Speedometer/TodoMVC-JavaScript-ES5/CompletingAllItems📈 view plot
⚠️ NO THRESHOLD
177.57 ms
release/Speedometer/TodoMVC-JavaScript-ES5/CompletingAllItems/Async📈 view plot
⚠️ NO THRESHOLD
31.83 ms
release/Speedometer/TodoMVC-JavaScript-ES5/CompletingAllItems/Sync📈 view plot
⚠️ NO THRESHOLD
145.74 ms
release/Speedometer/TodoMVC-JavaScript-ES5/DeletingAllItems📈 view plot
⚠️ NO THRESHOLD
104.59 ms
release/Speedometer/TodoMVC-JavaScript-ES5/DeletingAllItems/Async📈 view plot
⚠️ NO THRESHOLD
7.02 ms
release/Speedometer/TodoMVC-JavaScript-ES5/DeletingAllItems/Sync📈 view plot
⚠️ NO THRESHOLD
97.58 ms
release/Speedometer/TodoMVC-JavaScript-ES6-Webpack📈 view plot
⚠️ NO THRESHOLD
2,310.72 ms
release/Speedometer/TodoMVC-JavaScript-ES6-Webpack/Adding100Items📈 view plot
⚠️ NO THRESHOLD
1,891.10 ms
release/Speedometer/TodoMVC-JavaScript-ES6-Webpack/Adding100Items/Async📈 view plot
⚠️ NO THRESHOLD
36.50 ms
release/Speedometer/TodoMVC-JavaScript-ES6-Webpack/Adding100Items/Sync📈 view plot
⚠️ NO THRESHOLD
1,854.60 ms
release/Speedometer/TodoMVC-JavaScript-ES6-Webpack/CompletingAllItems📈 view plot
⚠️ NO THRESHOLD
263.72 ms
release/Speedometer/TodoMVC-JavaScript-ES6-Webpack/CompletingAllItems/Async📈 view plot
⚠️ NO THRESHOLD
37.68 ms
release/Speedometer/TodoMVC-JavaScript-ES6-Webpack/CompletingAllItems/Sync📈 view plot
⚠️ NO THRESHOLD
226.04 ms
release/Speedometer/TodoMVC-JavaScript-ES6-Webpack/DeletingAllItems📈 view plot
⚠️ NO THRESHOLD
155.90 ms
release/Speedometer/TodoMVC-JavaScript-ES6-Webpack/DeletingAllItems/Async📈 view plot
⚠️ NO THRESHOLD
7.30 ms
release/Speedometer/TodoMVC-JavaScript-ES6-Webpack/DeletingAllItems/Sync📈 view plot
⚠️ NO THRESHOLD
148.59 ms
release/Speedometer/TodoMVC-Preact📈 view plot
⚠️ NO THRESHOLD
159.33 ms
release/Speedometer/TodoMVC-Preact/Adding100Items📈 view plot
⚠️ NO THRESHOLD
80.28 ms
release/Speedometer/TodoMVC-Preact/Adding100Items/Async📈 view plot
⚠️ NO THRESHOLD
72.69 ms
release/Speedometer/TodoMVC-Preact/Adding100Items/Sync📈 view plot
⚠️ NO THRESHOLD
7.59 ms
release/Speedometer/TodoMVC-Preact/CompletingAllItems📈 view plot
⚠️ NO THRESHOLD
63.09 ms
release/Speedometer/TodoMVC-Preact/CompletingAllItems/Async📈 view plot
⚠️ NO THRESHOLD
50.76 ms
release/Speedometer/TodoMVC-Preact/CompletingAllItems/Sync📈 view plot
⚠️ NO THRESHOLD
12.34 ms
release/Speedometer/TodoMVC-Preact/DeletingAllItems📈 view plot
⚠️ NO THRESHOLD
15.97 ms
release/Speedometer/TodoMVC-Preact/DeletingAllItems/Async📈 view plot
⚠️ NO THRESHOLD
9.83 ms
release/Speedometer/TodoMVC-Preact/DeletingAllItems/Sync📈 view plot
⚠️ NO THRESHOLD
6.13 ms
release/Speedometer/TodoMVC-React📈 view plot
⚠️ NO THRESHOLD
864.83 ms
release/Speedometer/TodoMVC-React-Redux📈 view plot
⚠️ NO THRESHOLD
1,072.15 ms
release/Speedometer/TodoMVC-React-Redux/Adding100Items📈 view plot
⚠️ NO THRESHOLD
351.10 ms
release/Speedometer/TodoMVC-React-Redux/Adding100Items/Async📈 view plot
⚠️ NO THRESHOLD
37.90 ms
release/Speedometer/TodoMVC-React-Redux/Adding100Items/Sync📈 view plot
⚠️ NO THRESHOLD
313.20 ms
release/Speedometer/TodoMVC-React-Redux/CompletingAllItems📈 view plot
⚠️ NO THRESHOLD
472.35 ms
release/Speedometer/TodoMVC-React-Redux/CompletingAllItems/Async📈 view plot
⚠️ NO THRESHOLD
39.07 ms
release/Speedometer/TodoMVC-React-Redux/CompletingAllItems/Sync📈 view plot
⚠️ NO THRESHOLD
433.28 ms
release/Speedometer/TodoMVC-React-Redux/DeletingAllItems📈 view plot
⚠️ NO THRESHOLD
248.70 ms
release/Speedometer/TodoMVC-React-Redux/DeletingAllItems/Async📈 view plot
⚠️ NO THRESHOLD
7.84 ms
release/Speedometer/TodoMVC-React-Redux/DeletingAllItems/Sync📈 view plot
⚠️ NO THRESHOLD
240.86 ms
release/Speedometer/TodoMVC-React/Adding100Items📈 view plot
⚠️ NO THRESHOLD
308.07 ms
release/Speedometer/TodoMVC-React/Adding100Items/Async📈 view plot
⚠️ NO THRESHOLD
39.49 ms
release/Speedometer/TodoMVC-React/Adding100Items/Sync📈 view plot
⚠️ NO THRESHOLD
268.58 ms
release/Speedometer/TodoMVC-React/CompletingAllItems📈 view plot
⚠️ NO THRESHOLD
355.10 ms
release/Speedometer/TodoMVC-React/CompletingAllItems/Async📈 view plot
⚠️ NO THRESHOLD
34.60 ms
release/Speedometer/TodoMVC-React/CompletingAllItems/Sync📈 view plot
⚠️ NO THRESHOLD
320.50 ms
release/Speedometer/TodoMVC-React/DeletingAllItems📈 view plot
⚠️ NO THRESHOLD
201.66 ms
release/Speedometer/TodoMVC-React/DeletingAllItems/Async📈 view plot
⚠️ NO THRESHOLD
7.05 ms
release/Speedometer/TodoMVC-React/DeletingAllItems/Sync📈 view plot
⚠️ NO THRESHOLD
194.61 ms
release/Speedometer/TodoMVC-Svelte📈 view plot
⚠️ NO THRESHOLD
135.79 ms
release/Speedometer/TodoMVC-Svelte/Adding100Items📈 view plot
⚠️ NO THRESHOLD
75.25 ms
release/Speedometer/TodoMVC-Svelte/Adding100Items/Async📈 view plot
⚠️ NO THRESHOLD
58.83 ms
release/Speedometer/TodoMVC-Svelte/Adding100Items/Sync📈 view plot
⚠️ NO THRESHOLD
16.41 ms
release/Speedometer/TodoMVC-Svelte/CompletingAllItems📈 view plot
⚠️ NO THRESHOLD
44.94 ms
release/Speedometer/TodoMVC-Svelte/CompletingAllItems/Async📈 view plot
⚠️ NO THRESHOLD
35.37 ms
release/Speedometer/TodoMVC-Svelte/CompletingAllItems/Sync📈 view plot
⚠️ NO THRESHOLD
9.56 ms
release/Speedometer/TodoMVC-Svelte/DeletingAllItems📈 view plot
⚠️ NO THRESHOLD
15.61 ms
release/Speedometer/TodoMVC-Svelte/DeletingAllItems/Async📈 view plot
⚠️ NO THRESHOLD
10.83 ms
release/Speedometer/TodoMVC-Svelte/DeletingAllItems/Sync📈 view plot
⚠️ NO THRESHOLD
4.78 ms
🐰 View full continuous benchmarking report in Bencher

@github-actions
Copy link
Copy Markdown

✨ Try run (#18127549061) succeeded.

@mrobinson mrobinson enabled auto-merge September 30, 2025 11:33
@mrobinson mrobinson added this pull request to the merge queue Sep 30, 2025
@servo-highfive servo-highfive added the S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. label Sep 30, 2025
Merged via the queue into servo:main with commit 6ffc0cd Sep 30, 2025
50 checks passed
@mrobinson mrobinson deleted the add-a-take-screenshot-api branch September 30, 2025 12:10
@servo-highfive servo-highfive removed the S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. label Sep 30, 2025
delan added a commit that referenced this pull request Oct 6, 2025
…sts (#39583) (bencher)

{"fail_fast": false, "matrix": [{"name": "Linux (Bencher)", "workflow": "linux", "wpt": false, "profile": "release", "unit_tests": false, "build_libservo": false, "bencher": true, "build_args": "", "wpt_args": "", "number_of_wpt_chunks": 20}, {"name": "MacOS (Bencher)", "workflow": "macos", "wpt": false, "profile": "release", "unit_tests": false, "build_libservo": false, "bencher": true, "build_args": "", "wpt_args": "", "number_of_wpt_chunks": 20}, {"name": "Windows (Bencher)", "workflow": "windows", "wpt": false, "profile": "release", "unit_tests": false, "build_libservo": false, "bencher": true, "build_args": "", "wpt_args": "", "number_of_wpt_chunks": 20}, {"name": "Android (Bencher)", "workflow": "android", "wpt": false, "profile": "release", "unit_tests": false, "build_libservo": false, "bencher": true, "build_args": "", "wpt_args": "", "number_of_wpt_chunks": 20}, {"name": "OpenHarmony (Bencher)", "workflow": "ohos", "wpt": false, "profile": "release", "unit_tests": false, "build_libservo": false, "bencher": true, "build_args": "", "wpt_args": "", "number_of_wpt_chunks": 20}]}
mrobinson added a commit to mrobinson/servo that referenced this pull request Oct 6, 2025
When processing new WebRender frames after handling messages in the
compositor, only do that when we actually receive
`NewWebRenderFrameReady` messages. This isn't an issue unless there are
active animations. When there are, every spin of the event loop was
triggering a repaint.

Signed-off-by: Martin Robinson <[email protected]>
Co-authored-by: Delan Azabani <[email protected]>
github-merge-queue bot pushed a commit that referenced this pull request Oct 6, 2025
When processing new WebRender frames after handling messages in the
compositor, only do that when we actually receive
`NewWebRenderFrameReady` messages. This isn't an issue unless there are
active animations. When there are, every spin of the event loop was
triggering a repaint.

Testing: This should fix the performance regression on the Speedometer
Bencher
benchmarks.
Fixes: #39641

Signed-off-by: Martin Robinson <[email protected]>
Co-authored-by: Delan Azabani <[email protected]>
mrobinson added a commit to mrobinson/servo that referenced this pull request Oct 17, 2025
…ts.ready`

This fixes a regression (likely from servo#39583) that made the result of many font loading
tests intermittent. The issues here is that the count of fonts loading
is decremented synchronously in the `FontContext`, but the notification
to the `ScriptThread` happens asynchronously. In between the time the
decrement happens and the `ScriptThread` is notified, a rendering update
could happen which could mark a screenshot as ready to take too soon.

The solution here is to wait until the `fonts.ready` promise is
resolved, which is guaranteed to fire after all fonts have loaded. In
addition, a rendering update is queued after this happens. This means
that the screenshot will wait until that final rendering update to be
ready.

This should remove the flakiness of font load tests.

Signed-off-by: Martin Robinson <[email protected]>
mrobinson added a commit to mrobinson/servo that referenced this pull request Oct 17, 2025
…ts.ready`

This fixes a regression (likely from servo#39583) that made the result of many font loading
tests intermittent. The issues here is that the count of fonts loading
is decremented synchronously in the `FontContext`, but the notification
to the `ScriptThread` happens asynchronously. In between the time the
decrement happens and the `ScriptThread` is notified, a rendering update
could happen which could mark a screenshot as ready to take too soon.

The solution here is to wait until the `fonts.ready` promise is
resolved, which is guaranteed to fire after all fonts have loaded. In
addition, a rendering update is queued after this happens. This means
that the screenshot will wait until that final rendering update to be
ready.

This should remove the flakiness of font load tests.

Signed-off-by: Martin Robinson <[email protected]>
github-merge-queue bot pushed a commit that referenced this pull request Oct 17, 2025
…ts.ready` (#39963)

This fixes a regression (likely from #39583) that made the result of
many font loading
tests intermittent. The issues here is that the count of fonts loading
is decremented synchronously in the `FontContext`, but the notification
to the `ScriptThread` happens asynchronously. In between the time the
decrement happens and the `ScriptThread` is notified, a rendering update
could happen which could mark a screenshot as ready to take too soon.

The solution here is to wait until the `fonts.ready` promise is
resolved, which is guaranteed to fire after all fonts have loaded. In
addition, a rendering update is queued after this happens. This means
that the screenshot will wait until that final rendering update to be
ready.

This should remove the flakiness of font load tests.

Testing: This should fix many flaky tests.
Fixes: #39953.
Fixes: #39951.
Fixes #38956.
Fixes #39408.
Fixes #39429.
Fixes #39592.
Fixes #39636.
Fixes #39650.
Fixes #39666.
Fixes #39667.
Fixes #39706.
Fixes #39750.
Fixes #39801.
Fixes #39853.
Fixes #39881.
Fixes #39950.

Signed-off-by: Martin Robinson <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-awaiting-review There is new code that needs to be reviewed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants