Skip to content

Conversation

@mrobinson
Copy link
Member

@mrobinson mrobinson commented Oct 25, 2025

Canvas expects input data to be in RGBA premultiplied format and
WebRender already supports RGBA and BGRA data as long as they are
premultiplied. Pre-multiplying up front allows:

  • Avoiding many conversions when painting images to canvas.
  • Passing the RasterImage IpcSharedMemory of the image instead of creating
    a new one with the premultiplied data every time we upload to
    WebRender. This is a big deal for animated gifs, because before every
    frame was creating a new shared memory segment.

It seems that for rasterized SVGs were were already putting
premultplied data into the RasterImage so it's quite likely SVGs were
being composited incorrectly.

Testing: This causes 8 tests to start passing and 2 tests to fail in the WebGL conformance suite.
The failures are due to the fact that premultiplying alpha is lossy when alpha is 0. In that case,
the resulting color of a blend operation might be wrong. This is typically only a problem if you
use RGBA data as RGB data, which is pretty unusual. In the case that you are blending with
RGBA the final color values will be 0 or close to 0 anyway. Gecko solves this issue by having a
cacheable surface generation API that can fetch both premulitplied and unpremulitplied data
from things like image elements. We do not have that yet, but I argue that this change
is important anyway due to the amount that it reduces memory and file descriptor usage
as well as the cost of copying image data so much in memory.

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

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

@github-actions
Copy link

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

Flaky unexpected result (20)
  • 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
      

  • TIMEOUT [expected OK] /_mozilla/mozilla/window_resize_event.html (#36741)
    • TIMEOUT [expected PASS] subtest: Popup onresize event fires after resizeTo

      Test timed out
      

  • OK /css/css-fonts/variations/font-weight-matching.html (#38577)
    • FAIL [expected PASS] subtest: Test @font-face matching for weight 470

      assert_approx_equals: @font-face should be mapped to CSSTest Weights 300. expected 90 +/- 2 but got 180
      

    • FAIL [expected PASS] subtest: Test @font-face matching for weight 500

      assert_approx_equals: @font-face should be mapped to CSSTest Weights 300. expected 90 +/- 2 but got 180
      

  • OK /custom-elements/form-associated/ElementInternals-setFormValue.html (#29174)
    • PASS [expected FAIL] subtest: Single value - name is missing
  • TIMEOUT [expected FAIL] /dom/xslt/encoding-single-chunk.html (#39983)
  • 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.href

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

  • TIMEOUT /html/browsers/history/the-history-interface/001.html (#12580)
    • FAIL [expected PASS] subtest: traversing history must also traverse hash changes

      assert_equals: (this could cause other failures later on) expected "" but got "test"
      

  • OK /html/browsers/history/the-history-interface/traverse_the_history_4.html (#21383)
    • PASS [expected FAIL] subtest: Multiple history traversals, last would be aborted
  • FAIL [expected PASS] /html/canvas/element/manual/text/canvas.2d.disconnected.html (#30063)
  • TIMEOUT /html/interaction/focus/the-autofocus-attribute/supported-elements.html (#24145)
    • FAIL [expected TIMEOUT] subtest: Element with tabindex should support autofocus

      assert_equals: expected "SPAN" but got "BODY"
      

    • PASS [expected NOTRUN] subtest: Non-HTMLElement should not support autofocus
    • TIMEOUT [expected NOTRUN] subtest: Host element with delegatesFocus should support autofocus

      Test timed out
      

  • OK /html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/allow-scripts-flag-changing-1.html (#39694)
    • PASS [expected FAIL] subtest: Meta refresh is blocked by the allow-scripts sandbox flag at its creation time, not when refresh comes due
  • OK /html/semantics/forms/form-submission-0/multipart-formdata.window.html (#28725)
    • PASS [expected FAIL] subtest: multipart/form-data: 0x00 in value (formdata event)
  • OK /html/semantics/forms/form-submission-0/text-plain.window.html (#28687)
    • PASS [expected FAIL] subtest: text/plain: Basic test (normal form)
  • OK /html/semantics/scripting-1/the-script-element/module/dynamic-import/blob-url.any.html (#33948)
    • FAIL [expected PASS] subtest: Revoking a blob URL immediately after calling import will not fail

      promise_test: Unhandled rejection with value: object "TypeError: Dynamic import failed"
      

  • OK /html/semantics/scripting-1/the-script-element/module/dynamic-import/blob-url.any.worker.html (#33909)
    • FAIL [expected PASS] subtest: Revoking a blob URL immediately after calling import will not fail

      promise_test: Unhandled rejection with value: object "TypeError: Dynamic import failed"
      

  • OK /html/webappapis/user-prompts/print-during-unload.html (#35944)
    • PASS [expected FAIL] subtest: print() during unload
  • PASS [expected FAIL] /png/apng/fcTL-blend-source-nearly-transparent.html
  • OK /preload/preload-xhr.html (#39092)
    • FAIL [expected PASS] subtest: Make an XHR request immediately after creating link rel=preload.

      assert_equals: resources/dummy.xml?token=659c7e64-54ef-49b6-a98b-b2ae71161ed9 expected 1 but got 0
      

  • OK /wasm/webapi/abort.any.html (#39966)
    • FAIL [expected PASS] subtest: instantiateStreaming() asynchronously racing with abort should succeed or reject with AbortError

      assert_equals: expected "AbortError" but got "CompileError"
      

  • OK /webdriver/tests/classic/dismiss_alert/dismiss.py (#39098)
    • FAIL [expected PASS] subtest: test_dismiss_in_popup_window

      AssertionError: no such alert (404): No user prompt is currently active.
      

Stable unexpected results that are known to be intermittent (23)
  • 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_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/mozilla/sslfail.html (#10760)
  • CRASH [expected ERROR] /_webgl/conformance2/textures/misc/tex-input-validation.html (#38890)
  • OK /css/css-fonts/generic-family-keywords-003.html (#38994)
    • FAIL [expected PASS] subtest: @font-face matching for quoted and unquoted serif (drawing text in a canvas)

      assert_equals: quoted serif matches  @font-face rule expected 125 but got 40
      

  • TIMEOUT [expected FAIL] /dom/xslt/large-cdata.html (#38029)
  • OK /fetch/metadata/generated/css-font-face.https.sub.tentative.html (#32732)
    • PASS [expected FAIL] subtest: sec-fetch-site - Same origin
    • PASS [expected FAIL] subtest: sec-fetch-dest
  • OK /fetch/metadata/generated/css-font-face.sub.tentative.html (#34624)
    • PASS [expected FAIL] subtest: sec-fetch-storage-access - Not sent to non-trustworthy same-origin destination
  • ERROR /fetch/metadata/generated/serviceworker.https.sub.html (#36247)
    • FAIL [expected PASS] subtest: sec-fetch-site - Same origin, no options - registration

      promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
      

  • OK /html/browsers/browsing-the-web/navigating-across-documents/empty-iframe-load-event.html (#29066)
    • PASS [expected FAIL] subtest: Check execution order on load handler
    • PASS [expected FAIL] subtest: Check execution order from nested timeout
  • OK /html/browsers/history/the-history-interface/traverse_the_history_5.html (#21383)
    • PASS [expected FAIL] subtest: Multiple history traversals, last would be aborted
  • OK /html/browsers/windows/embedded-opener-remove-frame.html (#23867)
    • FAIL [expected PASS] subtest: opener of discarded auxiliary browsing context

      assert_object_equals: property "get" expected function "function opener() {
          [native code]
      }" got function "function opener() {
          [native code]
      }"
      

  • OK [expected TIMEOUT] /html/interaction/focus/the-autofocus-attribute/autofocus-dialog.html (#29087)
  • TIMEOUT [expected OK] /html/semantics/embedded-content/the-iframe-element/iframe_sandbox_navigate_other_frame_popup.sub.html (#39702)
    • TIMEOUT [expected FAIL] subtest: Sandboxed iframe can not navigate other frame's popup

      Test timed out
      

  • 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 [expected CRASH] /html/semantics/forms/the-fieldset-element/disabled-003.html (#31730, #39631)
  • OK /navigation-timing/test-navigation-type-reload.html (#33334)
    • FAIL [expected PASS] subtest: Reload domComplete > Original domComplete

      assert_true: Reload domComplete > Original domComplete expected true got false
      

    • FAIL [expected PASS] subtest: Reload domContentLoadedEventEnd > Original domContentLoadedEventEnd

      assert_true: Reload domContentLoadedEventEnd > Original domContentLoadedEventEnd expected true got false
      

    • FAIL [expected PASS] subtest: Reload domContentLoadedEventStart > Original domContentLoadedEventStart

      assert_true: Reload domContentLoadedEventStart > Original domContentLoadedEventStart expected true got false
      

    • FAIL [expected PASS] subtest: Reload fetchStart > Original fetchStart

      assert_true: Reload fetchStart > Original fetchStart expected true got false
      

    • FAIL [expected PASS] subtest: Reload loadEventEnd > Original loadEventEnd

      assert_true: Reload loadEventEnd > Original loadEventEnd expected true got false
      

    • FAIL [expected PASS] subtest: Reload loadEventStart > Original loadEventStart

      assert_true: Reload loadEventStart > Original loadEventStart expected true got false
      

  • OK /preload/preload-error.sub.html (#37177)
    • PASS [expected FAIL] subtest: success (fetch): main
    • FAIL [expected PASS] subtest: 404 (fetch): main

      assert_greater_than: http://web-platform.test:8000/preload/resources/dummy.xml?pipe=status%28404%29&label=fetch should be loaded expected a number greater than 0 but got 0
      

    • PASS [expected FAIL] subtest: CORS (fetch): main
  • OK /trusted-types/trusted-types-navigation.html?01-05 (#38975)
    • PASS [expected FAIL] subtest: Navigate a window via anchor with javascript:-urls in enforcing mode.
    • PASS [expected FAIL] subtest: Navigate a window via anchor with javascript:-urls in report-only mode.
  • TIMEOUT [expected OK] /webstorage/localstorage-about-blank-3P-iframe-opens-3P-window.partitioned.html (#29053)
    • TIMEOUT [expected PASS] subtest: StorageKey: test 3P about:blank window opened from a 3P iframe

      Test timed out
      

Stable unexpected results (74)
  • FAIL [expected PASS] /_mozilla/mozilla/webgl/tex_image_2d_mipmap.html
  • FAIL [expected PASS] /_mozilla/mozilla/webgl/tex_image_2d_simple.html
  • OK /_webgl/conformance/context/premultiplyalpha-test.html
    • FAIL [expected PASS] subtest: WebGL test #6

      assert_true: should draw with 64,128,255,128
      at (0, 0) expected: 64,128,255,128 was 32,64,128,128 expected true got false
      

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

      assert_true: should draw with 64,128,255,128
      at (0, 0) expected: 64,128,255,128 was 32,64,128,128 expected true got false
      

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

      assert_true: should draw with 255,192,128,1
      at (0, 0) expected: 255,192,128,1 was 1,1,1,1 expected true got false
      

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

      assert_true: should draw with 255,192,128,1
      at (0, 0) expected: 255,192,128,1 was 1,1,1,1 expected true got false
      

  • OK /_webgl/conformance/textures/image_bitmap_from_blob/tex-2d-luminance-luminance-unsigned_byte.html
    • FAIL [expected PASS] subtest: WebGL test #1

      assert_true: shouldBe 128,128,128 +/-10
      at (20, 8) expected: 128,128,128 was 64,64,64 expected true got false
      

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

      assert_true: shouldBe 128,128,128 +/-10
      at (20, 8) expected: 128,128,128 was 64,64,64 expected true got false
      

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

      assert_true: shouldBe 255,255,255 +/-10
      at (20, 8) expected: 255,255,255 was 128,128,128 expected true got false
      

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

      assert_true: shouldBe 255,255,255 +/-10
      at (20, 8) expected: 255,255,255 was 128,128,128 expected true got false
      

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

      assert_true: shouldBe 128,128,128 +/-10
      at (20, 24) expected: 128,128,128 was 64,64,64 expected true got false
      

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

      assert_true: shouldBe 128,128,128 +/-10
      at (20, 24) expected: 128,128,128 was 64,64,64 expected true got false
      

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

      assert_true: shouldBe 255,255,255 +/-10
      at (20, 24) expected: 255,255,255 was 128,128,128 expected true got false
      

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

      assert_true: shouldBe 255,255,255 +/-10
      at (20, 24) expected: 255,255,255 was 128,128,128 expected true got false
      

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

      assert_true: shouldBe 128,128,128 +/-10
      at (20, 8) expected: 128,128,128 was 64,64,64 expected true got false
      

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

      assert_true: shouldBe 128,128,128 +/-10
      at (20, 8) expected: 128,128,128 was 64,64,64 expected true got false
      

    • And 46 more unexpected results...
  • OK /_webgl/conformance/textures/image_bitmap_from_blob/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
    • FAIL [expected PASS] subtest: WebGL test #1

      assert_true: shouldBe 128,128,128 +/-10
      at (20, 8) expected: 128,128,128 was 64,64,64 expected true got false
      

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

      assert_true: shouldBe 128,128,128 +/-10
      at (20, 8) expected: 128,128,128 was 64,64,64 expected true got false
      

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

      assert_true: shouldBe 255,255,255 +/-10
      at (20, 8) expected: 255,255,255 was 128,128,128 expected true got false
      

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

      assert_true: shouldBe 255,255,255 +/-10
      at (20, 8) expected: 255,255,255 was 128,128,128 expected true got false
      

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

      assert_true: shouldBe 128,128,128 +/-10
      at (20, 24) expected: 128,128,128 was 64,64,64 expected true got false
      

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

      assert_true: shouldBe 128,128,128 +/-10
      at (20, 24) expected: 128,128,128 was 64,64,64 expected true got false
      

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

      assert_true: shouldBe 255,255,255 +/-10
      at (20, 24) expected: 255,255,255 was 128,128,128 expected true got false
      

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

      assert_true: shouldBe 255,255,255 +/-10
      at (20, 24) expected: 255,255,255 was 128,128,128 expected true got false
      

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

      assert_true: shouldBe 128,128,128 +/-10
      at (20, 8) expected: 128,128,128 was 64,64,64 expected true got false
      

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

      assert_true: shouldBe 128,128,128 +/-10
      at (20, 8) expected: 128,128,128 was 64,64,64 expected true got false
      

    • And 46 more unexpected results...
  • OK /_webgl/conformance/textures/image_bitmap_from_blob/tex-2d-rgb-rgb-unsigned_byte.html
    • FAIL [expected PASS] subtest: WebGL test #1

      assert_true: shouldBe 128,0,0 +/-10
      at (20, 8) expected: 128,0,0 was 64,0,0 expected true got false
      

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

      assert_true: shouldBe 0,128,0 +/-10
      at (20, 24) expected: 0,128,0 was 0,64,0 expected true got false
      

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

      assert_true: shouldBe 128,0,0 +/-10
      at (20, 8) expected: 128,0,0 was 64,0,0 expected true got false
      

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

      assert_true: shouldBe 0,128,0 +/-10
      at (20, 24) expected: 0,128,0 was 0,64,0 expected true got false
      

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

      assert_true: shouldBe 255,0,0 +/-10
      at (20, 8) expected: 255,0,0 was 128,0,0 expected true got false
      

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

      assert_true: shouldBe 0,255,0 +/-10
      at (20, 24) expected: 0,255,0 was 0,128,0 expected true got false
      

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

      assert_true: shouldBe 255,0,0 +/-10
      at (20, 8) expected: 255,0,0 was 128,0,0 expected true got false
      

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

      assert_true: shouldBe 0,255,0 +/-10
      at (20, 24) expected: 0,255,0 was 0,128,0 expected true got false
      

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

      assert_true: shouldBe 128,0,0 +/-10
      at (20, 24) expected: 128,0,0 was 64,0,0 expected true got false
      

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

      assert_true: shouldBe 0,128,0 +/-10
      at (20, 8) expected: 0,128,0 was 0,64,0 expected true got false
      

    • And 102 more unexpected results...
  • OK /_webgl/conformance/textures/image_bitmap_from_blob/tex-2d-rgb-rgb-unsigned_short_5_6_5.html
    • FAIL [expected PASS] subtest: WebGL test #1

      assert_true: shouldBe 128,0,0 +/-10
      at (20, 8) expected: 128,0,0 was 66,0,0 expected true got false
      

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

      assert_true: shouldBe 0,128,0 +/-10
      at (20, 24) expected: 0,128,0 was 0,65,0 expected true got false
      

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

      assert_true: shouldBe 128,0,0 +/-10
      at (20, 8) expected: 128,0,0 was 66,0,0 expected true got false
      

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

      assert_true: shouldBe 0,128,0 +/-10
      at (20, 24) expected: 0,128,0 was 0,65,0 expected true got false
      

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

      assert_true: shouldBe 255,0,0 +/-10
      at (20, 8) expected: 255,0,0 was 132,0,0 expected true got false
      

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

      assert_true: shouldBe 0,255,0 +/-10
      at (20, 24) expected: 0,255,0 was 0,130,0 expected true got false
      

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

      assert_true: shouldBe 255,0,0 +/-10
      at (20, 8) expected: 255,0,0 was 132,0,0 expected true got false
      

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

      assert_true: shouldBe 0,255,0 +/-10
      at (20, 24) expected: 0,255,0 was 0,130,0 expected true got false
      

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

      assert_true: shouldBe 128,0,0 +/-10
      at (20, 24) expected: 128,0,0 was 66,0,0 expected true got false
      

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

      assert_true: shouldBe 0,128,0 +/-10
      at (20, 8) expected: 0,128,0 was 0,65,0 expected true got false
      

    • And 102 more unexpected results...
  • OK /_webgl/conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_byte.html
    • FAIL [expected PASS] subtest: WebGL test #1

      assert_true: shouldBe 128,0,0 +/-10
      at (20, 8) expected: 128,0,0 was 64,0,0 expected true got false
      

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

      assert_true: shouldBe 0,128,0 +/-10
      at (20, 24) expected: 0,128,0 was 0,64,0 expected true got false
      

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

      assert_true: shouldBe 128,0,0 +/-10
      at (20, 8) expected: 128,0,0 was 64,0,0 expected true got false
      

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

      assert_true: shouldBe 0,128,0 +/-10
      at (20, 24) expected: 0,128,0 was 0,64,0 expected true got false
      

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

      assert_true: shouldBe 255,0,0 +/-10
      at (20, 8) expected: 255,0,0 was 128,0,0 expected true got false
      

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

      assert_true: shouldBe 0,255,0 +/-10
      at (20, 24) expected: 0,255,0 was 0,128,0 expected true got false
      

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

      assert_true: shouldBe 255,0,0 +/-10
      at (20, 8) expected: 255,0,0 was 128,0,0 expected true got false
      

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

      assert_true: shouldBe 0,255,0 +/-10
      at (20, 24) expected: 0,255,0 was 0,128,0 expected true got false
      

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

      assert_true: shouldBe 128,0,0 +/-10
      at (20, 24) expected: 128,0,0 was 64,0,0 expected true got false
      

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

      assert_true: shouldBe 0,128,0 +/-10
      at (20, 8) expected: 0,128,0 was 0,64,0 expected true got false
      

    • And 102 more unexpected results...
  • OK /_webgl/conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
    • FAIL [expected PASS] subtest: WebGL test #1

      assert_true: shouldBe 128,0,0 +/-10
      at (20, 8) expected: 128,0,0 was 68,0,0 expected true got false
      

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

      assert_true: shouldBe 0,128,0 +/-10
      at (20, 24) expected: 0,128,0 was 0,68,0 expected true got false
      

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

      assert_true: shouldBe 128,0,0 +/-10
      at (20, 8) expected: 128,0,0 was 68,0,0 expected true got false
      

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

      assert_true: shouldBe 0,128,0 +/-10
      at (20, 24) expected: 0,128,0 was 0,68,0 expected true got false
      

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

      assert_true: shouldBe 255,0,0 +/-10
      at (20, 8) expected: 255,0,0 was 136,0,0 expected true got false
      

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

      assert_true: shouldBe 0,255,0 +/-10
      at (20, 24) expected: 0,255,0 was 0,136,0 expected true got false
      

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

      assert_true: shouldBe 255,0,0 +/-10
      at (20, 8) expected: 255,0,0 was 136,0,0 expected true got false
      

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

      assert_true: shouldBe 0,255,0 +/-10
      at (20, 24) expected: 0,255,0 was 0,136,0 expected true got false
      

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

      assert_true: shouldBe 128,0,0 +/-10
      at (20, 24) expected: 128,0,0 was 68,0,0 expected true got false
      

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

      assert_true: shouldBe 0,128,0 +/-10
      at (20, 8) expected: 0,128,0 was 0,68,0 expected true got false
      

    • And 102 more unexpected results...
  • OK /_webgl/conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
    • FAIL [expected PASS] subtest: WebGL test #1

      assert_true: shouldBe 128,0,0 +/-10
      at (20, 8) expected: 128,0,0 was 66,0,0 expected true got false
      

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

      assert_true: shouldBe 0,128,0 +/-10
      at (20, 24) expected: 0,128,0 was 0,66,0 expected true got false
      

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

      assert_true: shouldBe 128,0,0 +/-10
      at (20, 8) expected: 128,0,0 was 66,0,0 expected true got false
      

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

      assert_true: shouldBe 0,128,0 +/-10
      at (20, 24) expected: 0,128,0 was 0,66,0 expected true got false
      

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

      assert_true: shouldBe 255,0,0 +/-10
      at (20, 8) expected: 255,0,0 was 132,0,0 expected true got false
      

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

      assert_true: shouldBe 0,255,0 +/-10
      at (20, 24) expected: 0,255,0 was 0,132,0 expected true got false
      

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

      assert_true: shouldBe 255,0,0 +/-10
      at (20, 8) expected: 255,0,0 was 132,0,0 expected true got false
      

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

      assert_true: shouldBe 0,255,0 +/-10
      at (20, 24) expected: 0,255,0 was 0,132,0 expected true got false
      

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

      assert_true: shouldBe 128,0,0 +/-10
      at (20, 24) expected: 128,0,0 was 66,0,0 expected true got false
      

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

      assert_true: shouldBe 0,128,0 +/-10
      at (20, 8) expected: 0,128,0 was 0,66,0 expected true got false
      

    • And 102 more unexpected results...
  • OK /_webgl/conformance/textures/misc/gl-teximage.html
    • FAIL [expected PASS] subtest: WebGL test #3

      assert_true: should be 255,0,255,255
      at (128, 15) expected: 255,0,255,255 was 0,0,0,255 expected true got false
      

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

      assert_true: should be 0,0,255,255
      at (255, 15) expected: 0,0,255,255 was 0,0,0,255 expected true got false
      

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

      assert_true: should be 128,128,128,255
      at (0, 8) expected: 128,128,128,255 was 0,0,0,255 expected true got false
      

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

      assert_true: should be 255,255,255,255
      at (128, 8) expected: 255,255,255,255 was 0,0,0,255 expected true got false
      

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

      assert_true: should be 0,255,255,255
      at (255, 8) expected: 0,255,255,255 was 0,0,0,255 expected true got false
      

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

      assert_true: should be 255,0,0,255
      at (0, 0) expected: 255,0,0,255 was 0,0,0,255 expected true got false
      

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

      assert_true: should be 255,255,0,255
      at (128, 0) expected: 255,255,0,255 was 0,0,0,255 expected true got false
      

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

      assert_true: should be 0,255,0,255
      at (255, 0) expected: 0,255,0,255 was 0,0,0,255 expected true got false
      

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

      assert_true: There should be 256 unique values in channel 0. Found 192 expected true got false
      

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

      assert_true: There should be 256 unique values in channel 1. Found 192 expected true got false
      

    • And 5 more unexpected results...
  • OK /_webgl/conformance/textures/misc/png-image-types.html
    • FAIL [expected PASS] subtest: WebGL test #49

      assert_true: should be 64,64,64,255
      at (0, 0) expected: 64,64,64,255 was 32,32,32,255 expected true got false
      

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

      assert_true: should be 64,64,64,255
      at (0, 0) expected: 64,64,64,255 was 32,32,32,255 expected true got false
      

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

      assert_true: should be 64,64,64,128
      at (0, 0) expected: 64,64,64,128 was 32,32,32,128 expected true got false
      

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

      assert_true: should be 64,64,64,128
      at (0, 0) expected: 64,64,64,128 was 32,32,32,128 expected true got false
      

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

      assert_true: should be 64,64,64,255
      at (0, 0) expected: 64,64,64,255 was 32,32,32,255 expected true got false
      

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

      assert_true: should be 64,64,64,255
      at (0, 0) expected: 64,64,64,255 was 32,32,32,255 expected true got false
      

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

      assert_true: should be 64,64,64,128
      at (0, 0) expected: 64,64,64,128 was 32,32,32,128 expected true got false
      

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

      assert_true: should be 64,64,64,128
      at (0, 0) expected: 64,64,64,128 was 32,32,32,128 expected true got false
      

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

      assert_true: should be 191,127,255,255
      at (0, 0) expected: 191,127,255,255 was 48,32,64,255 expected true got false
      

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

      assert_true: should be 191,127,255,255
      at (0, 0) expected: 191,127,255,255 was 48,32,64,255 expected true got false
      

    • And 6 more unexpected results...
  • PASS [expected FAIL] /css/css-masking/clip-path/clip-path-contentBox-1a.html
  • PASS [expected FAIL] /css/css-masking/clip-path/clip-path-contentBox-1c.html
  • PASS [expected FAIL] /css/css-masking/clip-path/clip-path-paddingBox-1a.html
  • PASS [expected FAIL] /css/css-masking/clip-path/clip-path-paddingBox-1c.html
  • PASS [expected FAIL] /css/css-transforms/skew-test1.html
  • PASS [expected FAIL] /css/css-transforms/ttwf-transform-skewy-001.html
  • OK /html/canvas/element/compositing/2d.composite.canvas.copy.html
    • FAIL [expected PASS] subtest: Canvas test: 2d.composite.canvas.copy

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 255 +/- 5 but got 190
      

  • OK /html/canvas/element/compositing/2d.composite.canvas.destination-atop.html
    • FAIL [expected PASS] subtest: Canvas test: 2d.composite.canvas.destination-atop

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 128 +/- 5 but got 94
      

  • OK /html/canvas/element/compositing/2d.composite.canvas.destination-over.html
    • FAIL [expected PASS] subtest: Canvas test: 2d.composite.canvas.destination-over

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 109 +/- 5 but got 81
      

  • OK /html/canvas/element/compositing/2d.composite.canvas.lighter.html
    • FAIL [expected PASS] subtest: Canvas test: 2d.composite.canvas.lighter

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 191 +/- 5 but got 143
      

  • OK /html/canvas/element/compositing/2d.composite.canvas.source-atop.html
    • FAIL [expected PASS] subtest: Canvas test: 2d.composite.canvas.source-atop

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 191 +/- 5 but got 143
      

  • OK /html/canvas/element/compositing/2d.composite.canvas.source-in.html
    • FAIL [expected PASS] subtest: Canvas test: 2d.composite.canvas.source-in

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 255 +/- 5 but got 191
      

  • OK /html/canvas/element/compositing/2d.composite.canvas.source-out.html
    • FAIL [expected PASS] subtest: Canvas test: 2d.composite.canvas.source-out

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 255 +/- 5 but got 190
      

  • OK /html/canvas/element/compositing/2d.composite.canvas.source-over.html
    • FAIL [expected PASS] subtest: Canvas test: 2d.composite.canvas.source-over

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 219 +/- 5 but got 163
      

  • OK /html/canvas/element/compositing/2d.composite.canvas.xor.html
    • FAIL [expected PASS] subtest: Canvas test: 2d.composite.canvas.xor

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 191 +/- 5 but got 142
      

  • OK /html/canvas/element/compositing/2d.composite.image.copy.html
    • FAIL [expected PASS] subtest: Canvas test: 2d.composite.image.copy

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 255 +/- 5 but got 190
      

  • OK /html/canvas/element/compositing/2d.composite.image.destination-atop.html
    • FAIL [expected PASS] subtest: Canvas test: 2d.composite.image.destination-atop

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 128 +/- 5 but got 94
      

  • OK /html/canvas/element/compositing/2d.composite.image.destination-over.html
    • FAIL [expected PASS] subtest: Canvas test: 2d.composite.image.destination-over

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 109 +/- 5 but got 81
      

  • OK /html/canvas/element/compositing/2d.composite.image.lighter.html
    • FAIL [expected PASS] subtest: Canvas test: 2d.composite.image.lighter

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 191 +/- 5 but got 143
      

  • OK /html/canvas/element/compositing/2d.composite.image.source-atop.html
    • FAIL [expected PASS] subtest: Canvas test: 2d.composite.image.source-atop

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 191 +/- 5 but got 143
      

  • OK /html/canvas/element/compositing/2d.composite.image.source-in.html
    • FAIL [expected PASS] subtest: Canvas test: 2d.composite.image.source-in

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 255 +/- 5 but got 191
      

  • OK /html/canvas/element/compositing/2d.composite.image.source-out.html
    • FAIL [expected PASS] subtest: Canvas test: 2d.composite.image.source-out

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 255 +/- 5 but got 190
      

  • OK /html/canvas/element/compositing/2d.composite.image.source-over.html
    • FAIL [expected PASS] subtest: Canvas test: 2d.composite.image.source-over

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 219 +/- 5 but got 163
      

  • OK /html/canvas/element/compositing/2d.composite.image.xor.html
    • FAIL [expected PASS] subtest: Canvas test: 2d.composite.image.xor

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 191 +/- 5 but got 142
      

  • OK /html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-Blob.html
    • FAIL [expected PASS] subtest: sRGB-FF0000CC.png, Context srgb, ImageData srgb, cropSource=false

      assert_true: Actual pixel value 203,0,0,204 is approximately equal to 255,0,0,204. expected true got false
      

    • FAIL [expected PASS] subtest: sRGB-FF0000CC.png, Context srgb, ImageData srgb, cropSource=true

      assert_true: Actual pixel value 203,0,0,204 is approximately equal to 255,0,0,204. expected true got false
      

    • FAIL [expected PASS] subtest: sRGB-FF0000CC.png, Context display-p3, ImageData srgb, cropSource=false

      assert_true: Actual pixel value 203,0,0,204 is approximately equal to 255,0,0,204. expected true got false
      

    • FAIL [expected PASS] subtest: sRGB-FF0000CC.png, Context display-p3, ImageData srgb, cropSource=true

      assert_true: Actual pixel value 203,0,0,204 is approximately equal to 255,0,0,204. expected true got false
      

    • FAIL [expected PASS] subtest: sRGB-BB0000CC.png, Context srgb, ImageData srgb, cropSource=false

      assert_true: Actual pixel value 150,0,0,204 is approximately equal to 187,0,0,204. expected true got false
      

    • FAIL [expected PASS] subtest: sRGB-BB0000CC.png, Context srgb, ImageData srgb, cropSource=true

      assert_true: Actual pixel value 150,0,0,204 is approximately equal to 187,0,0,204. expected true got false
      

    • FAIL [expected PASS] subtest: sRGB-BB0000CC.png, Context display-p3, ImageData srgb, cropSource=false

      assert_true: Actual pixel value 150,0,0,204 is approximately equal to 187,1,0,204. expected true got false
      

    • FAIL [expected PASS] subtest: sRGB-BB0000CC.png, Context display-p3, ImageData srgb, cropSource=true

      assert_true: Actual pixel value 150,0,0,204 is approximately equal to 187,1,0,204. expected true got false
      

    • FAIL [expected PASS] subtest: Display-P3-FF0000CC.png, Context srgb, ImageData srgb, cropSource=false

      assert_true: Actual pixel value 203,0,0,204 is approximately equal to 255,0,0,204. expected true got false
      

    • FAIL [expected PASS] subtest: Display-P3-FF0000CC.png, Context srgb, ImageData srgb, cropSource=true

      assert_true: Actual pixel value 203,0,0,204 is approximately equal to 255,0,0,204. expected true got false
      

    • And 26 more unexpected results...
  • OK /html/canvas/offscreen/compositing/2d.composite.canvas.copy.html
    • FAIL [expected PASS] subtest: OffscreenCanvas test: 2d.composite.canvas.copy

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 255 +/- 5 but got 190
      

  • OK /html/canvas/offscreen/compositing/2d.composite.canvas.copy.worker.html
    • FAIL [expected PASS] subtest: 2d

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 255 +/- 5 but got 190
      

  • OK /html/canvas/offscreen/compositing/2d.composite.canvas.destination-atop.html
    • FAIL [expected PASS] subtest: OffscreenCanvas test: 2d.composite.canvas.destination-atop

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 128 +/- 5 but got 94
      

  • OK /html/canvas/offscreen/compositing/2d.composite.canvas.destination-atop.worker.html
    • FAIL [expected PASS] subtest: 2d

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 128 +/- 5 but got 94
      

  • OK /html/canvas/offscreen/compositing/2d.composite.canvas.destination-over.html
    • FAIL [expected PASS] subtest: OffscreenCanvas test: 2d.composite.canvas.destination-over

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 109 +/- 5 but got 81
      

  • OK /html/canvas/offscreen/compositing/2d.composite.canvas.destination-over.worker.html
    • FAIL [expected PASS] subtest: 2d

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 109 +/- 5 but got 81
      

  • OK /html/canvas/offscreen/compositing/2d.composite.canvas.lighter.html
    • FAIL [expected PASS] subtest: OffscreenCanvas test: 2d.composite.canvas.lighter

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 191 +/- 5 but got 143
      

  • OK /html/canvas/offscreen/compositing/2d.composite.canvas.lighter.worker.html
    • FAIL [expected PASS] subtest: 2d

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 191 +/- 5 but got 143
      

  • OK /html/canvas/offscreen/compositing/2d.composite.canvas.source-atop.html
    • FAIL [expected PASS] subtest: OffscreenCanvas test: 2d.composite.canvas.source-atop

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 191 +/- 5 but got 143
      

  • OK /html/canvas/offscreen/compositing/2d.composite.canvas.source-atop.worker.html
    • FAIL [expected PASS] subtest: 2d

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 191 +/- 5 but got 143
      

  • OK /html/canvas/offscreen/compositing/2d.composite.canvas.source-in.html
    • FAIL [expected PASS] subtest: OffscreenCanvas test: 2d.composite.canvas.source-in

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 255 +/- 5 but got 191
      

  • OK /html/canvas/offscreen/compositing/2d.composite.canvas.source-in.worker.html
    • FAIL [expected PASS] subtest: 2d

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 255 +/- 5 but got 191
      

  • OK /html/canvas/offscreen/compositing/2d.composite.canvas.source-out.html
    • FAIL [expected PASS] subtest: OffscreenCanvas test: 2d.composite.canvas.source-out

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 255 +/- 5 but got 190
      

  • OK /html/canvas/offscreen/compositing/2d.composite.canvas.source-out.worker.html
    • FAIL [expected PASS] subtest: 2d

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 255 +/- 5 but got 190
      

  • OK /html/canvas/offscreen/compositing/2d.composite.canvas.source-over.html
    • FAIL [expected PASS] subtest: OffscreenCanvas test: 2d.composite.canvas.source-over

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 219 +/- 5 but got 163
      

  • OK /html/canvas/offscreen/compositing/2d.composite.canvas.source-over.worker.html
    • FAIL [expected PASS] subtest: 2d

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 219 +/- 5 but got 163
      

  • OK /html/canvas/offscreen/compositing/2d.composite.canvas.xor.html
    • FAIL [expected PASS] subtest: OffscreenCanvas test: 2d.composite.canvas.xor

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 191 +/- 5 but got 142
      

  • OK /html/canvas/offscreen/compositing/2d.composite.canvas.xor.worker.html
    • FAIL [expected PASS] subtest: 2d

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 191 +/- 5 but got 142
      

  • OK /html/canvas/offscreen/compositing/2d.composite.image.copy.html
    • FAIL [expected PASS] subtest: OffscreenCanvas test: 2d.composite.image.copy

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 255 +/- 5 but got 190
      

  • OK /html/canvas/offscreen/compositing/2d.composite.image.copy.worker.html
    • FAIL [expected PASS] subtest: 2d

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 255 +/- 5 but got 190
      

  • OK /html/canvas/offscreen/compositing/2d.composite.image.destination-atop.html
    • FAIL [expected PASS] subtest: OffscreenCanvas test: 2d.composite.image.destination-atop

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 128 +/- 5 but got 94
      

  • OK /html/canvas/offscreen/compositing/2d.composite.image.destination-atop.worker.html
    • FAIL [expected PASS] subtest: 2d

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 128 +/- 5 but got 94
      

  • OK /html/canvas/offscreen/compositing/2d.composite.image.destination-over.html
    • FAIL [expected PASS] subtest: OffscreenCanvas test: 2d.composite.image.destination-over

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 109 +/- 5 but got 81
      

  • OK /html/canvas/offscreen/compositing/2d.composite.image.destination-over.worker.html
    • FAIL [expected PASS] subtest: 2d

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 109 +/- 5 but got 81
      

  • OK /html/canvas/offscreen/compositing/2d.composite.image.lighter.html
    • FAIL [expected PASS] subtest: OffscreenCanvas test: 2d.composite.image.lighter

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 191 +/- 5 but got 143
      

  • OK /html/canvas/offscreen/compositing/2d.composite.image.lighter.worker.html
    • FAIL [expected PASS] subtest: 2d

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 191 +/- 5 but got 143
      

  • OK /html/canvas/offscreen/compositing/2d.composite.image.source-atop.html
    • FAIL [expected PASS] subtest: OffscreenCanvas test: 2d.composite.image.source-atop

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 191 +/- 5 but got 143
      

  • OK /html/canvas/offscreen/compositing/2d.composite.image.source-atop.worker.html
    • FAIL [expected PASS] subtest: 2d

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 191 +/- 5 but got 143
      

  • OK /html/canvas/offscreen/compositing/2d.composite.image.source-in.html
    • FAIL [expected PASS] subtest: OffscreenCanvas test: 2d.composite.image.source-in

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 255 +/- 5 but got 191
      

  • OK /html/canvas/offscreen/compositing/2d.composite.image.source-in.worker.html
    • FAIL [expected PASS] subtest: 2d

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 255 +/- 5 but got 191
      

  • OK /html/canvas/offscreen/compositing/2d.composite.image.source-out.html
    • FAIL [expected PASS] subtest: OffscreenCanvas test: 2d.composite.image.source-out

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 255 +/- 5 but got 190
      

  • OK /html/canvas/offscreen/compositing/2d.composite.image.source-out.worker.html
    • FAIL [expected PASS] subtest: 2d

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 255 +/- 5 but got 190
      

  • OK /html/canvas/offscreen/compositing/2d.composite.image.source-over.html
    • FAIL [expected PASS] subtest: OffscreenCanvas test: 2d.composite.image.source-over

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 219 +/- 5 but got 163
      

  • OK /html/canvas/offscreen/compositing/2d.composite.image.source-over.worker.html
    • FAIL [expected PASS] subtest: 2d

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 219 +/- 5 but got 163
      

  • OK /html/canvas/offscreen/compositing/2d.composite.image.xor.html
    • FAIL [expected PASS] subtest: OffscreenCanvas test: 2d.composite.image.xor

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 191 +/- 5 but got 142
      

  • OK /html/canvas/offscreen/compositing/2d.composite.image.xor.worker.html
    • FAIL [expected PASS] subtest: 2d

      assert_approx_equals: Red channel of the pixel at (50, 25) expected 191 +/- 5 but got 142
      

  • PASS [expected FAIL] /png/apng/fdAT-8bit-gray-alpha.html

@github-actions
Copy link

⚠️ Try run (#18800532404) failed.

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

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

@github-actions
Copy link

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

Flaky unexpected result (22)
  • 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
      

  • OK /_webgl/conformance/textures/misc/texture-upload-size.html (#21770)
    • PASS [expected FAIL] subtest: WebGL test #45
    • PASS [expected FAIL] subtest: WebGL test #47
    • PASS [expected FAIL] subtest: WebGL test #49
    • PASS [expected FAIL] subtest: WebGL test #51
    • 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
    • And 10 more unexpected results...
  • 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"
      

  • OK /css/css-fonts/variations/font-weight-matching.html (#38577)
    • FAIL [expected PASS] subtest: Test @font-face matching for weight 470

      assert_approx_equals: @font-face should be mapped to CSSTest Weights 300. expected 90 +/- 2 but got 180
      

    • FAIL [expected PASS] subtest: Test @font-face matching for weight 500

      assert_approx_equals: @font-face should be mapped to CSSTest Weights 300. expected 90 +/- 2 but got 180
      

  • OK /css/css-text/i18n/other-lang/css-text-line-break-de-po-loose.html
    • FAIL [expected PASS] subtest: FE6A SMALL PERCENT SIGN may NOT appear at line start if de and loose

      assert_approx_equals: expected 80 +/- 1 but got 87
      

  • OK /css/css-text/i18n/unknown-lang/css-text-line-break-cpm-loose.html
    • FAIL [expected PASS] subtest: 2049 EXCLAMATION QUESTION MARK may NOT appear at line start if lang unknown and loose

      assert_approx_equals: expected 99 +/- 1 but got 91
      

  • ERROR /fetch/metadata/generated/serviceworker.https.sub.html (#36247)
    • FAIL [expected PASS] subtest: sec-fetch-site - Same origin, no options - registration

      promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
      

  • OK /html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-same-origin-fragment.html (#20768)
    • FAIL [expected PASS] subtest: Tests that a fragment navigation in the unload handler will not block the initial navigation

      assert_equals: expected "" but got "#fragment"
      

  • 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
  • OK /html/browsers/history/the-history-interface/traverse_the_history_3.html (#21383)
    • PASS [expected FAIL] subtest: Multiple history traversals, last would be aborted
  • OK /html/browsers/windows/embedded-opener-remove-frame.html (#23867)
    • FAIL [expected PASS] subtest: opener of discarded auxiliary browsing context

      assert_object_equals: property "get" expected function "function opener() {
          [native code]
      }" got function "function opener() {
          [native code]
      }"
      

  • OK /html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/allow-scripts-flag-changing-1.html (#39694)
    • PASS [expected FAIL] subtest: Meta refresh is blocked by the allow-scripts sandbox flag at its creation time, not when refresh comes due
  • ERROR [expected OK] /html/semantics/embedded-content/media-elements/event_timeupdate_noautoplay.html (#25046)
  • OK /html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-nav-location-assign.html (#32863)
    • FAIL [expected PASS] subtest: Navigating iframe loading='lazy' before it is loaded: location.assign

      uncaught exception: Error: assert_equals: expected "http://web-platform.test:8000/html/semantics/embedded-content/the-iframe-element/support/blank.htm?nav" but got "http://web-platform.test:8000/html/semantics/embedded-content/the-iframe-element/support/blank.htm?src"
      

  • OK /html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-reload-location-reload.html (#32595)
    • FAIL [expected PASS] subtest: Reloading iframe loading='lazy' before it is loaded: location.reload

      uncaught exception: Error: assert_equals: expected "http://web-platform.test:8000/html/semantics/embedded-content/the-iframe-element/support/blank.htm?src" but got "about:blank"
      

  • 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/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 [expected CRASH] /html/semantics/forms/the-fieldset-element/disabled-003.html (#31730, #39631)
  • OK /html/webappapis/user-prompts/print-during-unload.html (#35944)
    • PASS [expected FAIL] subtest: print() during unload
  • OK /webaudio/the-audio-api/the-audiobuffersourcenode-interface/sub-sample-buffer-stitching.html (#22849)
    • FAIL [expected PASS] subtest: buffer-stitching-2

      assert_approx_equals: Stitched sine‑wave buffers at sample rate 43800 sample[29028] |2.3938682434642516e+31 - -0.69260573387146| = 2.3938682434642516e+31 > 0.0038986 expected -0.69260573387146 +/- 0.0038986 but got 2.3938682434642516e+31
      

  • OK /webdriver/tests/classic/dismiss_alert/dismiss.py (#39098)
    • FAIL [expected PASS] subtest: test_dismiss_in_popup_window

      AssertionError: no such alert (404): No user prompt is currently active.
      

  • OK [expected TIMEOUT] /webmessaging/without-ports/017.html (#24486)
    • PASS [expected TIMEOUT] subtest: origin of the script that invoked the method, about:blank
Stable unexpected results that are known to be intermittent (18)
  • 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_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/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
      

  • TIMEOUT [expected FAIL] /dom/xslt/large-cdata.html (#38029)
  • OK /fetch/metadata/generated/css-font-face.https.sub.tentative.html (#32732)
    • PASS [expected FAIL] subtest: sec-fetch-site - Same origin
    • PASS [expected FAIL] subtest: sec-fetch-storage-access - Same site
  • OK /fetch/metadata/generated/css-font-face.sub.tentative.html (#34624)
    • PASS [expected FAIL] subtest: sec-fetch-storage-access - Not sent to non-trustworthy same-site destination
  • OK /html/browsers/browsing-the-web/navigating-across-documents/empty-iframe-load-event.html (#29066)
    • PASS [expected FAIL] subtest: Check execution order on load handler
    • PASS [expected FAIL] subtest: Check execution order from nested timeout
  • OK [expected TIMEOUT] /html/infrastructure/urls/base-url/document-base-url-window-initiator-is-not-opener.https.window.html (#30970)
  • OK [expected TIMEOUT] /html/interaction/focus/the-autofocus-attribute/autofocus-dialog.html (#29087)
  • TIMEOUT /html/interaction/focus/the-autofocus-attribute/supported-elements.html (#24145)
    • FAIL [expected TIMEOUT] subtest: Element with tabindex should support autofocus

      assert_equals: expected "SPAN" but got "BODY"
      

    • PASS [expected NOTRUN] subtest: Non-HTMLElement should not support autofocus
    • TIMEOUT [expected NOTRUN] subtest: Host element with delegatesFocus should support autofocus

      Test timed out
      

  • TIMEOUT [expected OK] /html/semantics/embedded-content/the-iframe-element/iframe_sandbox_navigate_other_frame_popup.sub.html (#39702)
    • TIMEOUT [expected FAIL] subtest: Sandboxed iframe can not navigate other frame's popup

      Test timed out
      

  • OK /navigation-timing/test-navigation-type-reload.html (#33334)
    • PASS [expected FAIL] subtest: Reload domInteractive > Original domInteractive
  • OK /trusted-types/trusted-types-navigation.html?01-05 (#38975)
    • PASS [expected FAIL] subtest: Navigate a window via anchor with javascript:-urls in enforcing mode.
    • PASS [expected FAIL] subtest: Navigate a window via anchor with javascript:-urls in report-only mode.
  • OK /trusted-types/trusted-types-navigation.html?21-25 (#38997)
    • PASS [expected FAIL] subtest: Navigate a window via form-submission with javascript:-urls in enforcing mode.
  • ERROR [expected OK] /workers/baseurl/alpha/sharedworker-in-worker.html (#21315)
Stable unexpected results (10)
  • OK /_webgl/conformance/context/premultiplyalpha-test.html
    • FAIL [expected PASS] subtest: WebGL test #34

      assert_true: should draw with 255,192,128,1
      at (0, 0) expected: 255,192,128,1 was 255,255,255,1 expected true got false
      

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

      assert_true: should draw with 255,192,128,1
      at (0, 0) expected: 255,192,128,1 was 255,255,255,1 expected true got false
      

  • OK /_webgl/conformance/textures/misc/gl-teximage.html
    • FAIL [expected PASS] subtest: WebGL test #3

      assert_true: should be 255,0,255,255
      at (128, 15) expected: 255,0,255,255 was 0,0,0,255 expected true got false
      

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

      assert_true: should be 0,0,255,255
      at (255, 15) expected: 0,0,255,255 was 0,0,0,255 expected true got false
      

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

      assert_true: should be 128,128,128,255
      at (0, 8) expected: 128,128,128,255 was 0,0,0,255 expected true got false
      

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

      assert_true: should be 255,255,255,255
      at (128, 8) expected: 255,255,255,255 was 0,0,0,255 expected true got false
      

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

      assert_true: should be 0,255,255,255
      at (255, 8) expected: 0,255,255,255 was 0,0,0,255 expected true got false
      

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

      assert_true: should be 255,0,0,255
      at (0, 0) expected: 255,0,0,255 was 0,0,0,255 expected true got false
      

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

      assert_true: should be 255,255,0,255
      at (128, 0) expected: 255,255,0,255 was 0,0,0,255 expected true got false
      

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

      assert_true: should be 0,255,0,255
      at (255, 0) expected: 0,255,0,255 was 0,0,0,255 expected true got false
      

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

      assert_true: There should be 256 unique values in channel 0. Found 200 expected true got false
      

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

      assert_true: There should be 256 unique values in channel 1. Found 200 expected true got false
      

    • And 3 more unexpected results...
  • PASS [expected FAIL] /css/css-masking/clip-path/clip-path-contentBox-1a.html
  • PASS [expected FAIL] /css/css-masking/clip-path/clip-path-contentBox-1c.html
  • PASS [expected FAIL] /css/css-masking/clip-path/clip-path-paddingBox-1a.html
  • PASS [expected FAIL] /css/css-masking/clip-path/clip-path-paddingBox-1c.html
  • PASS [expected FAIL] /css/css-transforms/skew-test1.html
  • PASS [expected FAIL] /css/css-transforms/ttwf-transform-skewy-001.html
  • PASS [expected FAIL] /png/apng/fcTL-blend-source-nearly-transparent.html
  • PASS [expected FAIL] /png/apng/fdAT-8bit-gray-alpha.html

@github-actions
Copy link

⚠️ Try run (#18801523051) failed.

@mrobinson
Copy link
Member Author

I added a note in the PR description about the two new WebGL failures. Summary: I think this change is important even though it causes a pretty minor regression in the WebGL comformance suite.

@mrobinson mrobinson marked this pull request as ready for review October 26, 2025 16:33
@mrobinson mrobinson requested a review from gterzian as a code owner October 26, 2025 16:33
@servo-highfive servo-highfive added the S-awaiting-review There is new code that needs to be reviewed. label Oct 26, 2025
@mrobinson mrobinson requested a review from sagudev October 26, 2025 16:34
@sagudev
Copy link
Member

sagudev commented Oct 26, 2025

Testing: This causes 8 tests to start passing and 2 tests to fail in the WebGL conformance suite.
The failures are due to the fact that premultiplying alpha is lossy when alpha is 0. In that case,
the resulting color of a blend operation might be wrong. This is typically only a problem if you
use RGBA data as RGB data, which is pretty unusual. In the case that you are blending with
RGBA the final color values will be 0 or close to 0 anyway. Gecko solves this issue by having a
cacheable surface generation API that can fetch both premulitplied and unpremulitplied data
from things like image elements. We do not have that yet, but I argue that this change
is important anyway due to the amount that it reduces memory and file descriptor usage
as well as the cost of copying image data so much in memory.

I think that's reasonable, but we should document this (losing correctness for performance) in places were we are currently premultiplying and open a new issue about it (also link it in the comments).

Do we have any numbers of performance improvement?

@mrobinson
Copy link
Member Author

Do we have any numbers of performance improvement?

I can try to get some numbers tomorrow. Performance number might be hard to get (and I suspect that other things are dominating as performance is still very bad for canvas), but I can do some simple counting of the conversions that we avoid in Servo.

// to the source rectangle with formatting.
let snapshot = raster_image.as_snapshot();
let Some(bitmap_data) =
ImageBitmap::crop_and_transform_bitmap_data(snapshot, sx, sy, sw, sh, options)
Copy link
Contributor

Choose a reason for hiding this comment

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

ImageBitmap::crop_and_transform_bitmap_data(raster_image.as_snapshot(), ....) ?

Copy link
Member Author

Choose a reason for hiding this comment

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

I could do this though it adds a line of code for every argument of crop_and_transform_bitmap_data due to rustfmt. Normally I'm happy to do this, but this function takes 6 arguments.

@mrobinson
Copy link
Member Author

I think that's reasonable, but we should document this (losing correctness for performance) in places were we are currently premultiplying and open a new issue about it (also link it in the comments).

I've gone ahead and added a comment to the place where we convert image data to premultiplied data with a link to #40257.

Do we have any numbers of performance improvement?

I ran https://cookieclicker.eu/cookieclicker/ before and after this change, placing a print statement right before transform_inplace in snapshot.rs. Then I ran the game for about 5 seconds.

Before: transform_inplace was run 1973 times.
After: transform_inplace was run 8 times.

Unfortunately, Cookie Clicker is still slow with my change, but I think this is a big step on the way toward fixing it.

@mrobinson
Copy link
Member Author

@sagudev I think I've responded to all of your comments. Thanks for the review. PTAL.

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

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

@github-actions
Copy link

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

Flaky unexpected result (20)
  • TIMEOUT /FileAPI/url/url-in-tags-revoke.window.html (#19978)
    • TIMEOUT [expected PASS] subtest: Fetching a blob URL immediately before revoking it works in <script> tags.

      Test timed out
      

  • 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
      

  • OK /css/css-fonts/variations/at-font-face-font-matching.html (#20684)
    • FAIL [expected PASS] subtest: Matching font-style: 'oblique 0deg' should prefer 'oblique 0deg' over 'oblique 5deg'

      assert_equals: Unexpected font on test element expected 487 but got 532
      

  • OK /css/css-text/i18n/unknown-lang/css-text-line-break-pr-loose.html
    • FAIL [expected PASS] subtest: 00B1 PLUS-MINUS SIGN may appear at line start if loose

      assert_approx_equals: expected 62 +/- 1 but got 64
      

  • 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
      

  • TIMEOUT [expected CRASH] /html/anonymous-iframe/indexeddb.tentative.https.window.html (#39254)
  • OK /html/browsers/browsing-the-web/navigating-across-documents/006.html (#21382)
    • PASS [expected FAIL] subtest: Link with onclick form submit and href navigation
  • OK /html/browsers/history/the-history-interface/traverse_the_history_5.html (#21383)
    • PASS [expected FAIL] subtest: Multiple history traversals, last would be aborted
  • FAIL [expected PASS] /html/canvas/element/manual/text/canvas.2d.disconnected.html (#30063)
  • OK /html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/allow-scripts-flag-changing-1.html (#39694)
    • PASS [expected FAIL] subtest: Meta refresh is blocked by the allow-scripts sandbox flag at its creation time, not when refresh comes due
  • OK /html/semantics/forms/historical.html (#28568)
    • PASS [expected FAIL] subtest: <input name=isindex> should not be supported
  • CRASH [expected TIMEOUT] /html/semantics/links/links-created-by-a-and-area-elements/target_blank_implicit_noopener.html
  • OK /html/webappapis/user-prompts/print-during-unload.html (#35944)
    • FAIL [expected PASS] subtest: print() during unload

      assert_array_equals: expected property 1 to be "destination" but got "error: window.print is not a function" (expected array ["start", "destination"] got ["start", "error: window.print is not a function"])
      

  • OK /navigation-timing/test-navigation-type-reload.html (#33334)
    • PASS [expected FAIL] subtest: Reload domComplete > Original domComplete
    • PASS [expected FAIL] subtest: Reload loadEventEnd > Original loadEventEnd
    • PASS [expected FAIL] subtest: Reload loadEventStart > Original loadEventStart
  • PASS [expected FAIL] /png/apng/fcTL-blend-source-nearly-transparent.html
  • OK /preload/preload-invalid-resources.html (#39091)
    • PASS [expected FAIL] subtest: Preloading an invalid image (missing) should preload and not re-fetch
  • OK /preload/preload-xhr.html (#39092)
    • FAIL [expected PASS] subtest: Make an XHR request immediately after creating link rel=preload.

      assert_equals: resources/dummy.xml?token=5264979d-8b75-4000-ad13-0b5ba507e644 expected 1 but got 0
      

  • OK /trusted-types/trusted-types-navigation.html?26-30 (#38807)
    • PASS [expected FAIL] subtest: Navigate a window via form-submission with javascript:-urls in report-only mode.
  • OK [expected TIMEOUT] /webstorage/localstorage-about-blank-3P-iframe-opens-3P-window.partitioned.html (#29053)
    • PASS [expected TIMEOUT] subtest: StorageKey: test 3P about:blank window opened from a 3P iframe
  • ERROR [expected OK] /workers/baseurl/alpha/import-in-moduleworker.html (#21315)
Stable unexpected results that are known to be intermittent (14)
  • 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_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.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] subtest: IDBCursor update() method with throwing/invalid keys

      assert_throws_exactly: throwing getter should rethrow during clone function "() => {
            cursor.update(value);
          }" threw object "TypeError: cursor.update is not a function" but we expected it to throw object "getter: throwing from getter"
      

  • 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/textures/misc/texture-upload-size.html (#21770)
    • PASS [expected FAIL] subtest: WebGL test #45
    • PASS [expected FAIL] subtest: WebGL test #47
    • PASS [expected FAIL] subtest: WebGL test #49
    • PASS [expected FAIL] subtest: WebGL test #51
    • 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
    • And 6 more unexpected results...
  • TIMEOUT [expected FAIL] /dom/xslt/large-cdata.html (#38029)
  • OK /fetch/metadata/generated/css-font-face.https.sub.tentative.html (#32732)
    • PASS [expected FAIL] subtest: sec-fetch-dest
    • FAIL [expected PASS] subtest: sec-fetch-user

      promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
      

  • OK /html/browsers/browsing-the-web/navigating-across-documents/refresh/same-document-refresh.html (#34597)
    • FAIL [expected PASS] subtest: Same-Document Referrer from Refresh

      assert_equals: original page loads expected "http://web-platform.test:8000/html/browsers/browsing-the-web/navigating-across-documents/refresh/resources/refresh-with-section.sub.html?url=%23section" but got "http://web-platform.test:8000/html/browsers/browsing-the-web/navigating-across-documents/refresh/resources/refresh-with-section.sub.html?url=%23section#section"
      

  • OK /html/browsers/history/the-history-interface/traverse_the_history_3.html (#21383)
    • FAIL [expected PASS] subtest: Multiple history traversals, last would be aborted

      assert_array_equals: Pages opened during history navigation expected property 1 to be 3 but got 2 (expected array [6, 3] got [6, 2])
      

  • OK [expected TIMEOUT] /html/interaction/focus/the-autofocus-attribute/supported-elements.html (#24145)
    • PASS [expected NOTRUN] subtest: Non-HTMLElement should not support autofocus
    • FAIL [expected NOTRUN] subtest: Host element with delegatesFocus should support autofocus

      assert_equals: expected Element node <div autofocus=""></div> but got Element node <body><div autofocus=""></div></body>
      

    • FAIL [expected NOTRUN] subtest: Host element with delegatesFocus including no focusable descendants should be skipped

      assert_equals: expected Element node <input autofocus=""></input> but got Element node <body><div autofocus=""></div><input autofocus=""></body>
      

    • FAIL [expected NOTRUN] subtest: Area element should support autofocus

      promise_test: Unhandled rejection with value: object "TypeError: can't access property "appendChild", w.document.querySelector(...) is null"
      

  • OK /trusted-types/trusted-types-navigation.html?01-05 (#38975)
    • PASS [expected FAIL] subtest: Navigate a window via anchor with javascript:-urls in report-only mode.
    • FAIL [expected PASS] subtest: Navigate a frame via anchor with javascript:-urls in enforcing mode.

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

  • TIMEOUT /trusted-types/trusted-types-navigation.html?06-10 (#37920)
    • PASS [expected FAIL] subtest: Navigate a frame via anchor with javascript:-urls in report-only mode.

@github-actions
Copy link

✨ Try run (#18901069038) succeeded.

Comment on lines +402 to +405
bytes.extend_from_slice(&[rgb[2], rgb[1], rgb[0], 0xff]);
}
(
WebRenderImageFormat::BGRA8,
Copy link
Member

Choose a reason for hiding this comment

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

non-blocking: Given that we started preferring RBGA everywhere else, should we use it here too?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, I was thinking that this might be a good idea, but was planning on doing it in a followup in order to minimize the changes in one PR.

Comment on lines +293 to +294
/// Whether or not all of the frames of this image are opaque.
pub is_opaque: bool,
Copy link
Member

Choose a reason for hiding this comment

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

though(non-blocking): Maybe we should make this per frame? Although I am not sure how much that would matter in practice.

Copy link
Member Author

Choose a reason for hiding this comment

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

This is actually a bit tricky, because the value is per ImageKey in WebRender and we share an ImageKey among all frames of an animated image. As many gifs are looping, perhaps the potential performance isn't so important ATM.

Copy link
Member

Choose a reason for hiding this comment

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

This is actually a bit tricky, because the value is per ImageKey in WebRender and we share an ImageKey among all frames of an animated image. As many gifs are looping, perhaps the potential performance isn't so important ATM.

IIRC Every time you update image you also provide the flags (if opaque) so it's per image rather then per ImageKey. But I agree that this might not be really important or worth the complexity.

@servo-highfive servo-highfive removed the S-awaiting-review There is new code that needs to be reviewed. label Oct 30, 2025
Copy link
Member Author

@mrobinson mrobinson left a comment

Choose a reason for hiding this comment

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

Thanks for the review @sagudev!

Comment on lines +402 to +405
bytes.extend_from_slice(&[rgb[2], rgb[1], rgb[0], 0xff]);
}
(
WebRenderImageFormat::BGRA8,
Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, I was thinking that this might be a good idea, but was planning on doing it in a followup in order to minimize the changes in one PR.

@servo-highfive servo-highfive added the S-awaiting-review There is new code that needs to be reviewed. label Oct 31, 2025
@mrobinson mrobinson enabled auto-merge October 31, 2025 09:02
@mrobinson mrobinson added this pull request to the merge queue Oct 31, 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 Oct 31, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Oct 31, 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 Oct 31, 2025
Canvas expects input data to be in RGBA premultiplied format and
WebRender already supports RGBA and BGRA data as long as they are
premultiplied. Pre-multiplying up front allows:

- Avoiding many conversion when painting images to canvas.
- Passing the `RasterImage` IpcSharedMemory of the image instead of creating
  a new one with the premultiplied data every time we upload to
  WebRender. This is a big deal for animated gifs, because before every
  frame was creating a new shared memory segment.

It seems that for rasterized SVGs were were already putting
premultplied data into the `RasterImage` so it's quite likely SVGs were
being composited incorrectly.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
@servo-highfive servo-highfive removed the S-tests-failed The changes caused existing tests to fail. label Oct 31, 2025
@mrobinson mrobinson enabled auto-merge October 31, 2025 10:01
@mrobinson mrobinson added this pull request to the merge queue Oct 31, 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 Oct 31, 2025
Merged via the queue into servo:main with commit ea5929e Oct 31, 2025
32 checks passed
@mrobinson mrobinson deleted the rgba-premultiplied branch October 31, 2025 10:56
@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 Oct 31, 2025
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