WebXR Layers API: Add layer IDs to frame submit sequence [chromium/src : main]

0 views
Skip to first unread message

Evgenii Alekseev (xWF) (Gerrit)

unread,
Oct 10, 2025, 12:25:41 PM (10 days ago) Oct 10
to Chromium LUCI CQ, AyeAye, AI Code Reviewer, chromium...@chromium.org, Dirk Schulze, Stephen Chenney, blink-revie...@chromium.org, blink-reviews-p...@chromium.org, blink-...@chromium.org, drott+bl...@chromium.org, feature-v...@chromium.org, fmalit...@chromium.org, fserb...@chromium.org, kinuko...@chromium.org

Evgenii Alekseev (xWF) added 2 comments

File third_party/blink/renderer/modules/xr/xr_layer.h
Line 58, Patchset 1: bool has_backend_{false};
AI Code Reviewer . resolved

nit: Per the Blink Style Guide, boolean member variables should be prefixed with 'is' or 'did'. Please consider renaming `has_backend_` to something like `is_backend_created_` for consistency with `is_modified_` in this file. (Blink Style Guide: Naming - Precede boolean values with words like “is” and “did”)

_To keep this interaction as brief and non-intrusive as possible, please consider responding with one of following options:
**Done** | **Won't fix**: reason | **b/<bug_id>** | **Invalid:** reason

This comment was generated by [Experimental Blink C++ Code Review Agent](http://go/blink-c++-code-review-agent).AI reviews can sometimes be inaccurate; We appreciate your 🙏 feedback 🙏 to help us improve.[File a bug](http://go/blink-c++-code-review-agent-feedback) | [Provide feedback on chat](https://chat.google.com/room/AAQA0zhQHe0?cls=4) | [Opt-out](https://ganpati2.corp.google.com/group/peep-genai-blink-agent-optout.prod)_

Evgenii Alekseev (xWF)

moved to another CL

File third_party/blink/renderer/modules/xr/xr_layers_controller.h
Line 32, Patchset 1: void OnAddLayer(XRLayer* layer);
AI Code Reviewer . resolved

The parameter name 'layer' is obvious from its type 'XRLayer*' and can be omitted from the function declaration in the header file. (Blink Style Guide: Naming - May leave obvious parameter names out of function declarations)

_To keep this interaction as brief and non-intrusive as possible, please consider responding with one of following options:
**Done** | **Won't fix**: reason | **b/<bug_id>** | **Invalid:** reason

This comment was generated by [Experimental Blink C++ Code Review Agent](http://go/blink-c++-code-review-agent).AI reviews can sometimes be inaccurate; We appreciate your 🙏 feedback 🙏 to help us improve.[File a bug](http://go/blink-c++-code-review-agent-feedback) | [Provide feedback on chat](https://chat.google.com/room/AAQA0zhQHe0?cls=4) | [Opt-out](https://ganpati2.corp.google.com/group/peep-genai-blink-agent-optout.prod)_

Evgenii Alekseev (xWF)

methods are moved to another CL.

Open in Gerrit

Related details

Attention set is empty
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: I68566baec2c3d17499381ca57c5c08e32de0c3ec
Gerrit-Change-Number: 6984541
Gerrit-PatchSet: 11
Gerrit-Owner: Evgenii Alekseev (xWF) <eale...@google.com>
Gerrit-Reviewer: Evgenii Alekseev (xWF) <eale...@google.com>
Gerrit-CC: AI Code Reviewer <peep-gen...@system.gserviceaccount.com>
Gerrit-CC: Dirk Schulze <dsch...@chromium.org>
Gerrit-CC: Stephen Chenney <sche...@chromium.org>
Gerrit-Comment-Date: Fri, 10 Oct 2025 16:25:28 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: AI Code Reviewer <peep-gen...@system.gserviceaccount.com>
satisfied_requirement
unsatisfied_requirement
open
diffy

Evgenii Alekseev (xWF) (Gerrit)

unread,
Oct 10, 2025, 1:02:40 PM (10 days ago) Oct 10
to Alexander Cooper, Brandon Jones, Chromium LUCI CQ, AyeAye, AI Code Reviewer, chromium...@chromium.org, Dirk Schulze, Stephen Chenney, blink-revie...@chromium.org, blink-reviews-p...@chromium.org, blink-...@chromium.org, drott+bl...@chromium.org, feature-v...@chromium.org, fmalit...@chromium.org, fserb...@chromium.org, kinuko...@chromium.org
Attention needed from Alexander Cooper and Brandon Jones

New activity on the change

Open in Gerrit

Related details

Attention is currently required from:
  • Alexander Cooper
  • Brandon Jones
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: I68566baec2c3d17499381ca57c5c08e32de0c3ec
Gerrit-Change-Number: 6984541
Gerrit-PatchSet: 12
Gerrit-Owner: Evgenii Alekseev (xWF) <eale...@google.com>
Gerrit-Reviewer: Alexander Cooper <alco...@chromium.org>
Gerrit-Reviewer: Brandon Jones <baj...@chromium.org>
Gerrit-Reviewer: Evgenii Alekseev (xWF) <eale...@google.com>
Gerrit-CC: AI Code Reviewer <peep-gen...@system.gserviceaccount.com>
Gerrit-CC: Dirk Schulze <dsch...@chromium.org>
Gerrit-CC: Stephen Chenney <sche...@chromium.org>
Gerrit-Attention: Brandon Jones <baj...@chromium.org>
Gerrit-Attention: Alexander Cooper <alco...@chromium.org>
Gerrit-Comment-Date: Fri, 10 Oct 2025 17:02:26 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: No
satisfied_requirement
unsatisfied_requirement
open
diffy

Alexander Cooper (Gerrit)

unread,
Oct 10, 2025, 5:37:29 PM (10 days ago) Oct 10
to Evgenii Alekseev (xWF), Brandon Jones, Chromium LUCI CQ, AyeAye, AI Code Reviewer, chromium...@chromium.org, Dirk Schulze, Stephen Chenney, blink-revie...@chromium.org, blink-reviews-p...@chromium.org, blink-...@chromium.org, drott+bl...@chromium.org, feature-v...@chromium.org, fmalit...@chromium.org, fserb...@chromium.org, kinuko...@chromium.org
Attention needed from Brandon Jones and Evgenii Alekseev (xWF)

Alexander Cooper added 30 comments

Patchset-level comments
File-level comment, Patchset 13 (Latest):
Alexander Cooper . resolved

Highlighted a few places where I think some subtle behavior changes might be taking place that could be causing the test issues, including one place that I think is a non-spec compliant change.

Unfortunately, I think there's a lot of subtleties with some of the `OnFrame` or `updateRenderState` logic.

File third_party/blink/renderer/modules/xr/xr_frame_provider.h
Line 201, Patchset 13 (Latest): // Temporarily store the transport delegate of the last submitted layer as a
// source of the sync token. Will be empty after OnFrameEnd.
Alexander Cooper . unresolved

Not really how it needs to work. The TransportDelegate is technically layer agnostic. I don't think we can (due to code-layering issues), hold onto just the sync token, and really we need the delegate to pass for the actual end-frame logic, so instead I think we should make `OnFrameEnd` require a XRFrameTransportDelegate.

Line 199, Patchset 13 (Latest): HashMap<uint32_t, scoped_refptr<StaticBitmapImage>> current_frame_images_;
Alexander Cooper . unresolved

LayerId ?

Line 72, Patchset 13 (Latest): // SubmitWebGLLyayer or SubmitWebGPULayer to submit layers. Call OnFrameEnd
Alexander Cooper . unresolved

Not accurate anymore.

Line 67, Patchset 13 (Latest): void SubmitLayer(uint32_t layer_id, XrLayerClient*, bool was_changed);
Alexander Cooper . unresolved

LayerId.

But also... maybe queryable from the XrLayerClient?

File third_party/blink/renderer/modules/xr/xr_frame_provider.cc
Line 657, Patchset 13 (Latest):void XRFrameProvider::SubmitLayer(uint32_t layer_id,
Alexander Cooper . unresolved

Use LayerId type.

Line 685, Patchset 13 (Parent): CHECK_NE(client->session()->GraphicsApi(), XRGraphicsBinding::Api::kWebGPU)
<< "WebGPU layers only support shared buffer submission modes";
Alexander Cooper . unresolved

Should still have this after the `DrawingIntoSharedBuffer` if statement would return.

Line 803, Patchset 13 (Latest): if (frame_id_ < 0) {
// There is no valid frame_id_, and the browser side is not currently
// expecting a frame to be submitted. That can happen for the first
// immersive frame if the animation loop submits without a preceding
// immersive GetFrameData response, in that case frame_id_ is -1 (see
// https://crbug.com/855722).
return;
}
Alexander Cooper . unresolved

TBH, this check should probably be left in `SubmitLayer` as well.

Line 814, Patchset 13 (Latest): // Reset an active frame id, since anything we'd want to do (resizing/etc) can
// no-longer happen to this frame.
frame_id_ = -1;
Alexander Cooper . unresolved

While this is technically the correct change; This *may* be the cause of some of the test errors, since it is a change in behavior.

File third_party/blink/renderer/modules/xr/xr_render_state.cc
Line 65, Patchset 13 (Latest): if (!layers_enabled && layers_->size()) {
Alexander Cooper . unresolved

NIT: Prefer an explicit check either empty or > 0.

Line 85, Patchset 13 (Latest): return (base_layer_ || (layers_ && layers_->size() > 0));
Alexander Cooper . unresolved

NIT: Outer parens not needed.

File third_party/blink/renderer/modules/xr/xr_session.h
Line 532, Patchset 13 (Parent): HeapVector<Member<XRRenderStateInit>> pending_render_state_;
Alexander Cooper . unresolved

Alternatively, there may be some tests that relied on some beahvior around this that could be causing test failures.

File third_party/blink/renderer/modules/xr/xr_session.cc
Line 556, Patchset 13 (Parent): pending_render_state_.push_back(init);
Alexander Cooper . unresolved

I think this breaks spec compliant behavior. Essentially, we don't update the render state until after the frame is finished processing, and essentially per the spec, if there's an unset field, then that field shouldn't be updated.

E.g. It's valid behavior to call:
updateRenderState({depthNear: ...});
updateRenderState({depthFar:...});

And have the current state remain unchanged except that *both* depthNear and depthFar get updated. I believe your current logic throws out the ability to do this.

This *might* be the cause of issues with the tests as well, since they could e.g. set a base layer then call `updateRenderState` again, and the base layer gets cleared.

FURTHER, "Valid" doesn't mean what you think it means I think, since technically we still *can* end with no base layer.

Line 560, Patchset 13 (Latest): if (render_state_->IsValid()) {
// Update render state on animation frame submit.
pending_render_state_ = init;
} else {
// Update render state on first frame request.
requested_render_state_ = init;
}
Alexander Cooper . unresolved

I'm not seeing the need to split things between `pending_render_state_` and `requested_render_state_`? The render state doesn't get applied until after the frame exits, and if e.g. `updateRenderState` is called multiple times, we'd really only be applying the last one anyways.

Line 1696, Patchset 13 (Latest): render_state_->IsValid() || requested_render_state_;
Alexander Cooper . unresolved

FWIW, we could have a state where we have a `render_state_` that is invalid, and `requested_render_state_` does not have any layers set yet, as the validation only checks that *if* they are set, they are valid. But not every `updateRenderState` call is required to try to set the layers. So we still need the previous check.
AND In fact, the check in `updateRenderState` *does* allow us to end up with a `null` base layer or empty layers (the check is only that either there isn't a layer or IF THERE IS that the session matches).

Line 1827, Patchset 13 (Latest): ApplyRenderState();
Alexander Cooper . unresolved

So it looks like this is *after* we get a new frame, rather than right before we request a new frame, and that's why we had the `prev_base_layer_` as a member...? This is the other behavior I'd be most suspicious of causing the test failures.

Line 2090, Patchset 13 (Latest): if (!render_state_->baseLayer() && !render_state_->layers().size()) {
Alexander Cooper . unresolved

Here and elsewhere: Prefer checks to empty or comparison to 0.

Line 2110, Patchset 13 (Latest): xr_->frameProvider()->OnFrameEnd();
Alexander Cooper . unresolved

This looks like another potentially subtle change. This never had OnFrameStart/OnFrameEnd called on it in the old flow.

Line 2114, Patchset 13 (Latest): // Return base layer only if 'layers' feature enabled.
XRLayer* frame_base_layer = render_state_->GetFirstLayer(layers_enabled_);
Alexander Cooper . unresolved

That's not really what this method implies to me; so perhaps we should either change our logic based on `layers_enabled_` and let render_state_ have methods that are more explicit about what we want? (GetFirstLayer() or GetBaseLayer()) ?

Line 2128, Patchset 13 (Latest): MaybeRequestFrame();
Alexander Cooper . unresolved

I don't *think* anything has changed in this function that would cause `MaybeRequestFrame()` to change it's mind? Essentially we don't call it here also because the `requestAnimationFrame` call from the page should also cause it to get triggered.

Line 2135, Patchset 13 (Latest): frame_base_layer->OnFrameStart();
Alexander Cooper . unresolved

This parallel with frameProvider() *also* having an OnFrameStarty/OnFrameEnd is a bit confusing. Not sure if one or the other could have a better name here.

Line 2163, Patchset 13 (Latest): if (frame_base_layer) {
frame_base_layer->OnFrameEnd();
} else {
for (XRLayer* layer : render_state_->layers()) {
layer->OnFrameEnd();
}
}
Alexander Cooper . unresolved

As far as these are concerned, they don't really care if it's a base layer or a layer. I wonder if maybe we just have `layers()` handle that internally if it's returning all the layers or a vector of just the base layer? I wonder if that simplifies any other logic as well?

Line 2172, Patchset 13 (Latest): // Request a new render state on animation frame callback copletion.
requested_render_state_ = pending_render_state_;
pending_render_state_ = nullptr;
Alexander Cooper . unresolved

See my other comments about not understanding this and thinking that this *set* isn't actually happening appropriately?

Line 2293, Patchset 13 (Latest): XRLayer* base_layer = render_state_->baseLayer();
Alexander Cooper . unresolved

Why this update?

File third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.h
Line 82, Patchset 13 (Latest): blink::HashMap<uint32_t, scoped_refptr<StaticBitmapImage>> previous_images_;
Alexander Cooper . unresolved

LayerId

Line 56, Patchset 13 (Latest): blink::HashMap<uint32_t, scoped_refptr<StaticBitmapImage>> image_refs,
Alexander Cooper . unresolved

LayerId

File third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.cc
Line 88, Patchset 13 (Latest): vr_presentation_provider->SubmitFrameMissing(
vr_frame_id,
(delegate ? delegate->GenerateSyncToken() : gpu::SyncToken()));
Alexander Cooper . unresolved

If we make the change to require this in OnFrameEnd, we can keep the simplified logic here.

Line 96, Patchset 13 (Latest): blink::HashMap<uint32_t, scoped_refptr<StaticBitmapImage>> image_refs,
Alexander Cooper . unresolved

LayerId

Line 191, Patchset 13 (Latest): ids.reserve(image_refs.size());
std::transform(image_refs.begin(), image_refs.end(),
std::back_inserter(ids),
[](const auto& pair) { return device::LayerId(pair.key); });
Alexander Cooper . unresolved

We should be using device::LayerId throughout blink, the intention is to remove `uint32_t`s, so this becomes less necessary. (May still need it to extract all the keys, not sure if the hashmap has that functionality otherwise).

File third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport_delegate.h
Line 32, Patchset 13 (Latest): virtual void WaitOnFence(gfx::GpuFence* fence) {}
Alexander Cooper . unresolved

This should still be pure virtual?

Open in Gerrit

Related details

Attention is currently required from:
  • Brandon Jones
  • Evgenii Alekseev (xWF)
Submit Requirements:
    • requirement satisfiedCode-Coverage
    • requirement is not satisfiedCode-Owners
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: I68566baec2c3d17499381ca57c5c08e32de0c3ec
    Gerrit-Change-Number: 6984541
    Gerrit-PatchSet: 13
    Gerrit-Owner: Evgenii Alekseev (xWF) <eale...@google.com>
    Gerrit-Reviewer: Alexander Cooper <alco...@chromium.org>
    Gerrit-Reviewer: Brandon Jones <baj...@chromium.org>
    Gerrit-Reviewer: Evgenii Alekseev (xWF) <eale...@google.com>
    Gerrit-CC: AI Code Reviewer <peep-gen...@system.gserviceaccount.com>
    Gerrit-CC: Dirk Schulze <dsch...@chromium.org>
    Gerrit-CC: Stephen Chenney <sche...@chromium.org>
    Gerrit-Attention: Brandon Jones <baj...@chromium.org>
    Gerrit-Attention: Evgenii Alekseev (xWF) <eale...@google.com>
    Gerrit-Comment-Date: Fri, 10 Oct 2025 21:37:04 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Alexander Cooper (Gerrit)

    unread,
    Oct 10, 2025, 5:48:47 PM (10 days ago) Oct 10
    to Evgenii Alekseev (xWF), Brandon Jones, Chromium LUCI CQ, AyeAye, AI Code Reviewer, chromium...@chromium.org, Dirk Schulze, Stephen Chenney, blink-revie...@chromium.org, blink-reviews-p...@chromium.org, blink-...@chromium.org, drott+bl...@chromium.org, feature-v...@chromium.org, fmalit...@chromium.org, fserb...@chromium.org, kinuko...@chromium.org
    Attention needed from Brandon Jones and Evgenii Alekseev (xWF)

    Alexander Cooper added 2 comments

    File third_party/blink/renderer/modules/xr/xr_session.cc
    Line 2135, Patchset 13 (Latest): frame_base_layer->OnFrameStart();
    Alexander Cooper . unresolved

    This parallel with frameProvider() *also* having an OnFrameStarty/OnFrameEnd is a bit confusing. Not sure if one or the other could have a better name here.

    Alexander Cooper

    (But also not a huge deal if nothing is immediately apparent).

    Line 2163, Patchset 13 (Latest): if (frame_base_layer) {
    frame_base_layer->OnFrameEnd();
    } else {
    for (XRLayer* layer : render_state_->layers()) {
    layer->OnFrameEnd();
    }
    }
    Alexander Cooper . unresolved

    As far as these are concerned, they don't really care if it's a base layer or a layer. I wonder if maybe we just have `layers()` handle that internally if it's returning all the layers or a vector of just the base layer? I wonder if that simplifies any other logic as well?

    Alexander Cooper

    Also, if it's too tricky with types, could consider just having render_state_ expose the `OnFrameStart`/`OnFrameEnd` methods.

    Gerrit-Comment-Date: Fri, 10 Oct 2025 21:48:24 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Comment-In-Reply-To: Alexander Cooper <alco...@chromium.org>
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Alexander Cooper (Gerrit)

    unread,
    Oct 13, 2025, 12:58:27 PM (7 days ago) Oct 13
    to Evgenii Alekseev (xWF), Brandon Jones, Chromium LUCI CQ, AyeAye, AI Code Reviewer, chromium...@chromium.org, Dirk Schulze, Stephen Chenney, blink-revie...@chromium.org, blink-reviews-p...@chromium.org, blink-...@chromium.org, drott+bl...@chromium.org, feature-v...@chromium.org, fmalit...@chromium.org, fserb...@chromium.org, kinuko...@chromium.org
    Attention needed from Brandon Jones and Evgenii Alekseev (xWF)

    Alexander Cooper added 1 comment

    Patchset-level comments
    Alexander Cooper . resolved

    BTW, if the WTF maps/sets give you issues you'll likely just need to add a specialization to: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/modules/xr/xr_id_hash_traits.h

    Gerrit-Comment-Date: Mon, 13 Oct 2025 16:58:03 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Evgenii Alekseev (xWF) (Gerrit)

    unread,
    Oct 15, 2025, 2:07:07 PM (5 days ago) Oct 15
    to Alexander Cooper, Brandon Jones, Chromium LUCI CQ, AyeAye, AI Code Reviewer, chromium...@chromium.org, Dirk Schulze, Stephen Chenney, blink-revie...@chromium.org, blink-reviews-p...@chromium.org, blink-...@chromium.org, drott+bl...@chromium.org, feature-v...@chromium.org, fmalit...@chromium.org, fserb...@chromium.org, kinuko...@chromium.org
    Attention needed from Alexander Cooper and Brandon Jones

    Evgenii Alekseev (xWF) added 29 comments

    File third_party/blink/renderer/modules/xr/xr_frame_provider.h
    Line 201, Patchset 13: // Temporarily store the transport delegate of the last submitted layer as a

    // source of the sync token. Will be empty after OnFrameEnd.
    Alexander Cooper . resolved

    Not really how it needs to work. The TransportDelegate is technically layer agnostic. I don't think we can (due to code-layering issues), hold onto just the sync token, and really we need the delegate to pass for the actual end-frame logic, so instead I think we should make `OnFrameEnd` require a XRFrameTransportDelegate.

    Evgenii Alekseev (xWF)

    removed, provided through the OnFrameEnd.

    Line 199, Patchset 13: HashMap<uint32_t, scoped_refptr<StaticBitmapImage>> current_frame_images_;
    Alexander Cooper . resolved

    LayerId ?

    Evgenii Alekseev (xWF)

    Done

    Line 72, Patchset 13: // SubmitWebGLLyayer or SubmitWebGPULayer to submit layers. Call OnFrameEnd
    Alexander Cooper . resolved

    Not accurate anymore.

    Evgenii Alekseev (xWF)

    Thanks, renamed methods and rephrased comment correspondingly.

    Line 67, Patchset 13: void SubmitLayer(uint32_t layer_id, XrLayerClient*, bool was_changed);
    Alexander Cooper . unresolved

    LayerId.

    But also... maybe queryable from the XrLayerClient?

    Evgenii Alekseev (xWF)

    I though about it, but in that case we have to add a static cast to the XRwebGL Layer AND/OR XrCompoistionLayer.

    File third_party/blink/renderer/modules/xr/xr_frame_provider.cc
    Line 657, Patchset 13:void XRFrameProvider::SubmitLayer(uint32_t layer_id,
    Alexander Cooper . resolved

    Use LayerId type.

    Evgenii Alekseev (xWF)

    Done

    Line 685, Patchset 13 (Parent): CHECK_NE(client->session()->GraphicsApi(), XRGraphicsBinding::Api::kWebGPU)
    << "WebGPU layers only support shared buffer submission modes";
    Alexander Cooper . resolved

    Should still have this after the `DrawingIntoSharedBuffer` if statement would return.

    Evgenii Alekseev (xWF)

    Added, thanks.

    Line 803, Patchset 13: if (frame_id_ < 0) {

    // There is no valid frame_id_, and the browser side is not currently
    // expecting a frame to be submitted. That can happen for the first
    // immersive frame if the animation loop submits without a preceding
    // immersive GetFrameData response, in that case frame_id_ is -1 (see
    // https://crbug.com/855722).
    return;
    }
    Alexander Cooper . resolved

    TBH, this check should probably be left in `SubmitLayer` as well.

    Evgenii Alekseev (xWF)

    Good point, added

    Line 814, Patchset 13: // Reset an active frame id, since anything we'd want to do (resizing/etc) can

    // no-longer happen to this frame.
    frame_id_ = -1;
    Alexander Cooper . unresolved

    While this is technically the correct change; This *may* be the cause of some of the test errors, since it is a change in behavior.

    Evgenii Alekseev (xWF)

    I could not see test failures anymore. I suppose that it should be ok.

    File third_party/blink/renderer/modules/xr/xr_render_state.cc
    Line 65, Patchset 13: if (!layers_enabled && layers_->size()) {
    Alexander Cooper . resolved

    NIT: Prefer an explicit check either empty or > 0.

    Evgenii Alekseev (xWF)

    Done

    Line 85, Patchset 13: return (base_layer_ || (layers_ && layers_->size() > 0));
    Alexander Cooper . resolved

    NIT: Outer parens not needed.

    Evgenii Alekseev (xWF)

    Done

    File third_party/blink/renderer/modules/xr/xr_session.h
    Line 532, Patchset 13 (Parent): HeapVector<Member<XRRenderStateInit>> pending_render_state_;
    Alexander Cooper . resolved

    Alternatively, there may be some tests that relied on some beahvior around this that could be causing test failures.

    Evgenii Alekseev (xWF)

    removed the pending render_state.

    File third_party/blink/renderer/modules/xr/xr_session.cc
    Line 556, Patchset 13 (Parent): pending_render_state_.push_back(init);
    Alexander Cooper . resolved

    I think this breaks spec compliant behavior. Essentially, we don't update the render state until after the frame is finished processing, and essentially per the spec, if there's an unset field, then that field shouldn't be updated.

    E.g. It's valid behavior to call:
    updateRenderState({depthNear: ...});
    updateRenderState({depthFar:...});

    And have the current state remain unchanged except that *both* depthNear and depthFar get updated. I believe your current logic throws out the ability to do this.

    This *might* be the cause of issues with the tests as well, since they could e.g. set a base layer then call `updateRenderState` again, and the base layer gets cleared.

    FURTHER, "Valid" doesn't mean what you think it means I think, since technically we still *can* end with no base layer.

    Evgenii Alekseev (xWF)

    Thanks, reverted.

    Line 560, Patchset 13: if (render_state_->IsValid()) {

    // Update render state on animation frame submit.
    pending_render_state_ = init;
    } else {
    // Update render state on first frame request.
    requested_render_state_ = init;
    }
    Alexander Cooper . resolved

    I'm not seeing the need to split things between `pending_render_state_` and `requested_render_state_`? The render state doesn't get applied until after the frame exits, and if e.g. `updateRenderState` is called multiple times, we'd really only be applying the last one anyways.

    Evgenii Alekseev (xWF)

    reverted. Thanks.

    Line 1696, Patchset 13: render_state_->IsValid() || requested_render_state_;
    Alexander Cooper . resolved

    FWIW, we could have a state where we have a `render_state_` that is invalid, and `requested_render_state_` does not have any layers set yet, as the validation only checks that *if* they are set, they are valid. But not every `updateRenderState` call is required to try to set the layers. So we still need the previous check.
    AND In fact, the check in `updateRenderState` *does* allow us to end up with a `null` base layer or empty layers (the check is only that either there isn't a layer or IF THERE IS that the session matches).

    Evgenii Alekseev (xWF)

    Thanks for detailed description. Now it is more clear how to handle it.

    Line 1827, Patchset 13: ApplyRenderState();
    Alexander Cooper . resolved

    So it looks like this is *after* we get a new frame, rather than right before we request a new frame, and that's why we had the `prev_base_layer_` as a member...? This is the other behavior I'd be most suspicious of causing the test failures.

    Evgenii Alekseev (xWF)

    Test are good now, replaced prev_base_layer with prev_transport_delegate.

    Line 2090, Patchset 13: if (!render_state_->baseLayer() && !render_state_->layers().size()) {
    Alexander Cooper . resolved

    Here and elsewhere: Prefer checks to empty or comparison to 0.

    Evgenii Alekseev (xWF)

    Done

    Line 2110, Patchset 13: xr_->frameProvider()->OnFrameEnd();
    Alexander Cooper . resolved

    This looks like another potentially subtle change. This never had OnFrameStart/OnFrameEnd called on it in the old flow.

    Evgenii Alekseev (xWF)

    Thanks. removed.

    Line 2114, Patchset 13: // Return base layer only if 'layers' feature enabled.

    XRLayer* frame_base_layer = render_state_->GetFirstLayer(layers_enabled_);
    Alexander Cooper . resolved

    That's not really what this method implies to me; so perhaps we should either change our logic based on `layers_enabled_` and let render_state_ have methods that are more explicit about what we want? (GetFirstLayer() or GetBaseLayer()) ?

    Evgenii Alekseev (xWF)

    Yeh, it was not good idea to propagate layers_enabled to the method.

    Base on spec, it is possible to add XRWebGLLayer to the base layer OR add it to the layers list.

    So, we do not need to map shared buffer to first layer ID. Added corresponding comment.

    Line 2128, Patchset 13: MaybeRequestFrame();
    Alexander Cooper . resolved

    I don't *think* anything has changed in this function that would cause `MaybeRequestFrame()` to change it's mind? Essentially we don't call it here also because the `requestAnimationFrame` call from the page should also cause it to get triggered.

    Evgenii Alekseev (xWF)

    Removed. Thanks for pointing this out.

    Line 2135, Patchset 13: frame_base_layer->OnFrameStart();
    Alexander Cooper . resolved

    This parallel with frameProvider() *also* having an OnFrameStarty/OnFrameEnd is a bit confusing. Not sure if one or the other could have a better name here.

    Alexander Cooper

    (But also not a huge deal if nothing is immediately apparent).

    Evgenii Alekseev (xWF)

    Moved layers calls to the RenderState, thinking about renaming of the frame provider's methods.

    Line 2163, Patchset 13: if (frame_base_layer) {

    frame_base_layer->OnFrameEnd();
    } else {
    for (XRLayer* layer : render_state_->layers()) {
    layer->OnFrameEnd();
    }
    }
    Alexander Cooper . resolved

    As far as these are concerned, they don't really care if it's a base layer or a layer. I wonder if maybe we just have `layers()` handle that internally if it's returning all the layers or a vector of just the base layer? I wonder if that simplifies any other logic as well?

    Alexander Cooper

    Also, if it's too tricky with types, could consider just having render_state_ expose the `OnFrameStart`/`OnFrameEnd` methods.

    Evgenii Alekseev (xWF)

    Moved to the render state, good point, thanks.

    Line 2172, Patchset 13: // Request a new render state on animation frame callback copletion.

    requested_render_state_ = pending_render_state_;
    pending_render_state_ = nullptr;
    Alexander Cooper . resolved

    See my other comments about not understanding this and thinking that this *set* isn't actually happening appropriately?

    Evgenii Alekseev (xWF)

    reverted.

    Line 2293, Patchset 13: XRLayer* base_layer = render_state_->baseLayer();
    Alexander Cooper . resolved

    Why this update?

    Evgenii Alekseev (xWF)

    Replaced with render_state_ ->onResize.
    According to spce there is no limitations to add multiple XRWebGLLayer instances to the layers list, we need to call onResize for all of them.

    File third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.h
    Line 82, Patchset 13: blink::HashMap<uint32_t, scoped_refptr<StaticBitmapImage>> previous_images_;
    Alexander Cooper . resolved

    LayerId

    Evgenii Alekseev (xWF)

    Done

    Line 56, Patchset 13: blink::HashMap<uint32_t, scoped_refptr<StaticBitmapImage>> image_refs,
    Alexander Cooper . resolved

    LayerId

    Evgenii Alekseev (xWF)

    Done

    File third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.cc
    Line 88, Patchset 13: vr_presentation_provider->SubmitFrameMissing(

    vr_frame_id,
    (delegate ? delegate->GenerateSyncToken() : gpu::SyncToken()));
    Alexander Cooper . resolved

    If we make the change to require this in OnFrameEnd, we can keep the simplified logic here.

    Evgenii Alekseev (xWF)

    Replaced on CHECK for delegate,

    Line 96, Patchset 13: blink::HashMap<uint32_t, scoped_refptr<StaticBitmapImage>> image_refs,
    Alexander Cooper . resolved

    LayerId

    Evgenii Alekseev (xWF)

    Done

    Line 191, Patchset 13: ids.reserve(image_refs.size());

    std::transform(image_refs.begin(), image_refs.end(),
    std::back_inserter(ids),
    [](const auto& pair) { return device::LayerId(pair.key); });
    Alexander Cooper . resolved

    We should be using device::LayerId throughout blink, the intention is to remove `uint32_t`s, so this becomes less necessary. (May still need it to extract all the keys, not sure if the hashmap has that functionality otherwise).

    Evgenii Alekseev (xWF)

    Moved the layer IDs vector to the upper level.

    File third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport_delegate.h
    Line 32, Patchset 13: virtual void WaitOnFence(gfx::GpuFence* fence) {}
    Alexander Cooper . resolved

    This should still be pure virtual?

    Evgenii Alekseev (xWF)

    reverted.

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Alexander Cooper
    • Brandon Jones
    Submit Requirements:
    • requirement satisfiedCode-Coverage
    • requirement is not satisfiedCode-Owners
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: I68566baec2c3d17499381ca57c5c08e32de0c3ec
    Gerrit-Change-Number: 6984541
    Gerrit-PatchSet: 19
    Gerrit-Owner: Evgenii Alekseev (xWF) <eale...@google.com>
    Gerrit-Reviewer: Alexander Cooper <alco...@chromium.org>
    Gerrit-Reviewer: Brandon Jones <baj...@chromium.org>
    Gerrit-Reviewer: Evgenii Alekseev (xWF) <eale...@google.com>
    Gerrit-CC: AI Code Reviewer <peep-gen...@system.gserviceaccount.com>
    Gerrit-CC: Dirk Schulze <dsch...@chromium.org>
    Gerrit-CC: Stephen Chenney <sche...@chromium.org>
    Gerrit-Attention: Brandon Jones <baj...@chromium.org>
    Gerrit-Attention: Alexander Cooper <alco...@chromium.org>
    Gerrit-Comment-Date: Wed, 15 Oct 2025 18:06:49 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Comment-In-Reply-To: Alexander Cooper <alco...@chromium.org>
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Alexander Cooper (Gerrit)

    unread,
    Oct 15, 2025, 6:08:25 PM (5 days ago) Oct 15
    to Evgenii Alekseev (xWF), Brandon Jones, Chromium LUCI CQ, AyeAye, AI Code Reviewer, chromium...@chromium.org, Dirk Schulze, Stephen Chenney, blink-revie...@chromium.org, blink-reviews-p...@chromium.org, blink-...@chromium.org, drott+bl...@chromium.org, feature-v...@chromium.org, fmalit...@chromium.org, fserb...@chromium.org, kinuko...@chromium.org
    Attention needed from Brandon Jones and Evgenii Alekseev (xWF)

    Alexander Cooper voted and added 15 comments

    Votes added by Alexander Cooper

    Code-Review+1

    15 comments

    Patchset-level comments
    File-level comment, Patchset 19 (Latest):
    Alexander Cooper . resolved

    Mostly looks good, a few NITs and a few questions mainly to make sure I understand what's going on (though these may be opportunities for code comments as well).

    File third_party/blink/renderer/modules/xr/xr_frame_provider.h
    Line 199, Patchset 19 (Latest): bool layers_enabled_ = false;
    Alexander Cooper . unresolved

    I believe layers can only be enabled on the immersive session; rather than caching this I'd prefer we either:
    1) Add a method to XrSession like: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/modules/xr/xr_session.h;drc=32ef847d4806639a036e08779c3150e760a5030c;l=360
    or
    2) Query https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/modules/xr/xr_session.h;drc=32ef847d4806639a036e08779c3150e760a5030c;l=404

    Could generate a local method to wrap the call for readability.

    Line 73, Patchset 19 (Latest): // `ClearCachedLayersData()` to begin, then `SubmitLayer()` for each layer,
    Alexander Cooper . unresolved

    Ultra NIT: Sort `SubmitLayer` down here between the two other methods so that all three "lifecycle" methods are together/in-order in the header.

    Line 67, Patchset 13: void SubmitLayer(uint32_t layer_id, XrLayerClient*, bool was_changed);
    Alexander Cooper . unresolved

    LayerId.

    But also... maybe queryable from the XrLayerClient?

    Evgenii Alekseev (xWF)

    I though about it, but in that case we have to add a static cast to the XRwebGL Layer AND/OR XrCompoistionLayer.

    Alexander Cooper

    How so? I think if we want to just use `kInvalidId` for BaseLayer, it's fine and doesn't need a check? (I *would* advocate that it'd be nice if we could start generating IDs for base layers, and just treat them like projection layers, but I think that's beyond the scope of this).

    File third_party/blink/renderer/modules/xr/xr_frame_provider.cc
    Line 120, Patchset 19 (Latest): // TODO(crbug.com/450856064): Add layer_manager initialization.
    layers_enabled_ =
    session->IsFeatureEnabled(device::mojom::XRSessionFeature::LAYERS);
    Alexander Cooper . unresolved

    See other comment about wrapping this in a method rather than a member.

    Line 814, Patchset 13: // Reset an active frame id, since anything we'd want to do (resizing/etc) can
    // no-longer happen to this frame.
    frame_id_ = -1;
    Alexander Cooper . resolved

    While this is technically the correct change; This *may* be the cause of some of the test errors, since it is a change in behavior.

    Evgenii Alekseev (xWF)

    I could not see test failures anymore. I suppose that it should be ok.

    Alexander Cooper

    Acknowledged

    Line 846, Patchset 19 (Latest): if (!was_any_layer_changed || !transport_delegate) {
    Alexander Cooper . unresolved

    This is CHECK'd so should no longer be checked in the if statement.

    Line 858, Patchset 19 (Latest): // The backend expects an empty layer ID list if the 'layers' feature is not
    // enabled.
    if (!layers_enabled_) {
    layer_ids.clear();
    }
    Alexander Cooper . unresolved

    It's kind of a CHECK failure here if this is bigger than size 1 with layers_enabled_ == false right? e.g. there should not be a way to get this to be larger than just the base layer if we don't have the layers feature enabled.

    File third_party/blink/renderer/modules/xr/xr_render_state.cc
    Line 131, Patchset 19 (Latest): XRLayer* last_modified_layer =
    base_layer_ ? base_layer_
    : (layers_ && !layers_->empty() ? layers_->back() : nullptr);
    Alexander Cooper . unresolved

    Why does this need to be the last_modified_layer ? If our main goal is to get the transport delegate, then can we just query `GetFirstLayer()`, since it should be the same for every layer in the array? (e.g. either it's the base layer where there's only one, or it's a composition layer where it comes from the binding?)

    Line 136, Patchset 19 (Latest): if (last_modified_layer->LayerType() == XRLayerType::kWebGLLayer) {
    transport_delegate = static_cast<XRWebGLLayer*>(last_modified_layer)
    ->GetTransportDelegate();
    } else {
    transport_delegate = static_cast<XRCompositionLayer*>(last_modified_layer)
    ->binding()
    ->GetTransportDelegate();
    }
    Alexander Cooper . unresolved

    I don't think I'm opposed to putting this on XrLayer if that simplifies things.

    Line 149, Patchset 19 (Latest):bool XRRenderState::GetAndClearUpdateLayersStatus() {
    bool needs_update = needs_layers_update_;
    needs_layers_update_ = false;
    return needs_update;
    }
    Alexander Cooper . unresolved

    I think this should be split into two methods. `NeedLayersUpdate()` and `OnLayersUpdated()`.

    File third_party/blink/renderer/modules/xr/xr_session.cc
    Line 1698, Patchset 19 (Latest): if (!will_have_valid_render_state) {
    prev_transport_delegate_ = render_state_->GetTransportDelegate();
    }
    Alexander Cooper . unresolved

    Why here instead of relying on ApplyPendingRenderState?

    Line 1836, Patchset 19 (Latest): prev_transport_delegate_ = nullptr;
    ApplyPendingRenderState();
    Alexander Cooper . unresolved

    I think I see what you've been saying. Per the spec, we should do this after we finish processing the callbacks not here probably, per our impl we *probably* need to do this before we submit, and the backend can handle knowing that it should use the "old" value for the pending submit and the "new" value for the next frame it returns. I guess there'd probably be a further backend change needed there on top of moving this towards e.g. the end of OnFrame instead of here (with a few early returns updated/removed). I'd guess that may also remove some `prev_transport_delegate_` logic, but may need to add some logic to e.g. drop the frame request if the render state isn't good.

    I think what you've got now is an okay workaround, but can you file a bug?

    Line 2132, Patchset 19 (Latest): if (should_update_layers_backend_) {
    should_update_layers_backend_ = false;
    if (layers_enabled_) {
    Alexander Cooper . unresolved

    So, IIUC, the issue stems from the fact that we need to have the layers be "viable" before we service the frame to the page, and we aren't currently *actually* updating the render state until we *start* processing the frame? So we essentially intentionally drop a frame and re-request it so that we can get a frame where the layers are valid before we service it to the page?

    If I've got it right, can you add a comment here that this is a workaround for the bug I asked you to file in the other comment?

    Line 2135, Patchset 19 (Latest): // TODO(crbug.com/450856064): Update backend and request frame again.
    Alexander Cooper . unresolved

    I can't remember at the moment, but does the backend not complain about receiving layers it didn't expect? e.g. Shouldn't this CL be making the SetEnabledCompositionLayers call?

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Brandon Jones
    • Evgenii Alekseev (xWF)
    Submit Requirements:
      • requirement satisfiedCode-Coverage
      • requirement is not satisfiedCode-Owners
      • requirement is not satisfiedCode-Review
      • requirement is not satisfiedNo-Unresolved-Comments
      • requirement satisfiedReview-Enforcement
      Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
      Gerrit-MessageType: comment
      Gerrit-Project: chromium/src
      Gerrit-Branch: main
      Gerrit-Change-Id: I68566baec2c3d17499381ca57c5c08e32de0c3ec
      Gerrit-Change-Number: 6984541
      Gerrit-PatchSet: 19
      Gerrit-Owner: Evgenii Alekseev (xWF) <eale...@google.com>
      Gerrit-Reviewer: Alexander Cooper <alco...@chromium.org>
      Gerrit-Reviewer: Brandon Jones <baj...@chromium.org>
      Gerrit-Reviewer: Evgenii Alekseev (xWF) <eale...@google.com>
      Gerrit-CC: AI Code Reviewer <peep-gen...@system.gserviceaccount.com>
      Gerrit-CC: Dirk Schulze <dsch...@chromium.org>
      Gerrit-CC: Stephen Chenney <sche...@chromium.org>
      Gerrit-Attention: Brandon Jones <baj...@chromium.org>
      Gerrit-Attention: Evgenii Alekseev (xWF) <eale...@google.com>
      Gerrit-Comment-Date: Wed, 15 Oct 2025 22:07:45 +0000
      Gerrit-HasComments: Yes
      Gerrit-Has-Labels: Yes
      Comment-In-Reply-To: Alexander Cooper <alco...@chromium.org>
      Comment-In-Reply-To: Evgenii Alekseev (xWF) <eale...@google.com>
      satisfied_requirement
      unsatisfied_requirement
      open
      diffy

      Evgenii Alekseev (xWF) (Gerrit)

      unread,
      Oct 16, 2025, 3:34:29 PM (4 days ago) Oct 16
      to Alexander Cooper, Brandon Jones, Chromium LUCI CQ, AyeAye, AI Code Reviewer, chromium...@chromium.org, Dirk Schulze, Stephen Chenney, blink-revie...@chromium.org, blink-reviews-p...@chromium.org, blink-...@chromium.org, drott+bl...@chromium.org, feature-v...@chromium.org, fmalit...@chromium.org, fserb...@chromium.org, kinuko...@chromium.org
      Attention needed from Alexander Cooper and Brandon Jones

      Evgenii Alekseev (xWF) added 14 comments

      File third_party/blink/renderer/modules/xr/xr_frame_provider.h
      Line 199, Patchset 19: bool layers_enabled_ = false;
      Alexander Cooper . unresolved

      I believe layers can only be enabled on the immersive session; rather than caching this I'd prefer we either:
      1) Add a method to XrSession like: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/modules/xr/xr_session.h;drc=32ef847d4806639a036e08779c3150e760a5030c;l=360
      or
      2) Query https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/modules/xr/xr_session.h;drc=32ef847d4806639a036e08779c3150e760a5030c;l=404

      Could generate a local method to wrap the call for readability.

      Evgenii Alekseev (xWF)

      The problem is that there is no session reference in the current class, we are getting session with argument of the methods.

      I have cherry-pick'ed layer_manager_.is_bound() from the next CL.

      Line 73, Patchset 19: // `ClearCachedLayersData()` to begin, then `SubmitLayer()` for each layer,
      Alexander Cooper . resolved

      Ultra NIT: Sort `SubmitLayer` down here between the two other methods so that all three "lifecycle" methods are together/in-order in the header.

      Evgenii Alekseev (xWF)

      Fixed, thank you for catching it.

      Line 67, Patchset 13: void SubmitLayer(uint32_t layer_id, XrLayerClient*, bool was_changed);
      Alexander Cooper . unresolved

      LayerId.

      But also... maybe queryable from the XrLayerClient?

      Evgenii Alekseev (xWF)

      I though about it, but in that case we have to add a static cast to the XRwebGL Layer AND/OR XrCompoistionLayer.

      Alexander Cooper

      How so? I think if we want to just use `kInvalidId` for BaseLayer, it's fine and doesn't need a check? (I *would* advocate that it'd be nice if we could start generating IDs for base layers, and just treat them like projection layers, but I think that's beyond the scope of this).

      Evgenii Alekseev (xWF)

      I'm sorry, I could not understand your idea. Could you please give more details?

      As I can see we have the following hierarchy for the XrLayerClient:

      class XRWebGLLayer final : public XRLayer, public XrLayerClient 
      class XRCompositionLayer : public XRLayer {
      public:
      XRLayerDrawingContext* drawing_context();
      }
      class XRLayerDrawingContext : public GarbageCollected<XRLayerDrawingContext>,
      public XrLayerClient;


      which means that we have to cast XRLayerClient to the XRWebGLLayer or XRCompositionLayer to make it possible to call the layer_id().

      On the other hand, we have layer_id() at the context of the SubmitLayer() function call.

      1. BaseLayer has a layer id on the blink side, and we do replace kInvalidId with a real layer id for the shared buffer at the XRSession::OnFrame.
      So, we should never get kInvalidId as argument. I can add CHECK if it makes sense.
      2. According to spec layers list could contain any XrLayer type, which means that XrWebGLLayer could be in the list too. So, that's why XrwebGLLayer's backend goes through the LayerManager API when 'layers' enabled, and it has a shared buffer (openxr composition layer) with the corresponding layer id at the backed.

      File third_party/blink/renderer/modules/xr/xr_frame_provider.cc
      Line 120, Patchset 19: // TODO(crbug.com/450856064): Add layer_manager initialization.

      layers_enabled_ =
      session->IsFeatureEnabled(device::mojom::XRSessionFeature::LAYERS);
      Alexander Cooper . unresolved

      See other comment about wrapping this in a method rather than a member.

      Evgenii Alekseev (xWF)

      replaced on layer_manager initialization + XRSession::layers_enabled()

      Line 846, Patchset 19: if (!was_any_layer_changed || !transport_delegate) {
      Alexander Cooper . resolved

      This is CHECK'd so should no longer be checked in the if statement.

      Evgenii Alekseev (xWF)

      Done

      Line 858, Patchset 19: // The backend expects an empty layer ID list if the 'layers' feature is not

      // enabled.
      if (!layers_enabled_) {
      layer_ids.clear();
      }
      Alexander Cooper . unresolved

      It's kind of a CHECK failure here if this is bigger than size 1 with layers_enabled_ == false right? e.g. there should not be a way to get this to be larger than just the base layer if we don't have the layers feature enabled.

      Evgenii Alekseev (xWF)

      1.I've separated layer_ids and image_refs into two distinct vectors.

      2. We only require layer_ids for the shared buffer use case. And there is no CHECK for ids size, only for the image_refs size.

      3. backend will throw an exception if the layer_ids list is non-empty when the session lacks the 'layers' feature.

      File third_party/blink/renderer/modules/xr/xr_render_state.cc
      Line 131, Patchset 19: XRLayer* last_modified_layer =

      base_layer_ ? base_layer_
      : (layers_ && !layers_->empty() ? layers_->back() : nullptr);
      Alexander Cooper . unresolved

      Why does this need to be the last_modified_layer ? If our main goal is to get the transport delegate, then can we just query `GetFirstLayer()`, since it should be the same for every layer in the array? (e.g. either it's the base layer where there's only one, or it's a composition layer where it comes from the binding?)

      Evgenii Alekseev (xWF)

      Good point, I'll try.

      Line 136, Patchset 19: if (last_modified_layer->LayerType() == XRLayerType::kWebGLLayer) {

      transport_delegate = static_cast<XRWebGLLayer*>(last_modified_layer)
      ->GetTransportDelegate();
      } else {
      transport_delegate = static_cast<XRCompositionLayer*>(last_modified_layer)
      ->binding()
      ->GetTransportDelegate();
      }
      Alexander Cooper . unresolved

      I don't think I'm opposed to putting this on XrLayer if that simplifies things.

      Evgenii Alekseev (xWF)

      GetTransportDelegate() defined at the XRLayerClient,

      And XrWebGLLayer implements both XRLayer and XRLayerClient.

      So, I've implemented is via XrLayer::LayerClient()->GetTransportDelegate();

      Please, let me know if it ok?

      Line 149, Patchset 19:bool XRRenderState::GetAndClearUpdateLayersStatus() {

      bool needs_update = needs_layers_update_;
      needs_layers_update_ = false;
      return needs_update;
      }
      Alexander Cooper . unresolved

      I think this should be split into two methods. `NeedLayersUpdate()` and `OnLayersUpdated()`.

      Evgenii Alekseev (xWF)

      Good point. updated.

      File third_party/blink/renderer/modules/xr/xr_session.cc
      Line 1698, Patchset 19: if (!will_have_valid_render_state) {
      prev_transport_delegate_ = render_state_->GetTransportDelegate();
      }
      Alexander Cooper . unresolved

      Why here instead of relying on ApplyPendingRenderState?

      Evgenii Alekseev (xWF)

      removed. Most likely it is not needed at all.

      Line 1836, Patchset 19: prev_transport_delegate_ = nullptr;
      ApplyPendingRenderState();
      Alexander Cooper . unresolved

      I think I see what you've been saying. Per the spec, we should do this after we finish processing the callbacks not here probably, per our impl we *probably* need to do this before we submit, and the backend can handle knowing that it should use the "old" value for the pending submit and the "new" value for the next frame it returns. I guess there'd probably be a further backend change needed there on top of moving this towards e.g. the end of OnFrame instead of here (with a few early returns updated/removed). I'd guess that may also remove some `prev_transport_delegate_` logic, but may need to add some logic to e.g. drop the frame request if the render state isn't good.

      I think what you've got now is an okay workaround, but can you file a bug?

      Evgenii Alekseev (xWF)

      The prev_base_layer and prev_transport_delegate uses to handle the render state transition from when it has at least one layer to the state when there is no any layer in the render state.

      It is mainly related to the XRFrameTransport::FrameSubmitMissing which is required the sync token as a one of the parameters of the mojom call.

      So, it is more or less clear how to avoid extra frame message for the layers, but for the base layer we probably have to extend mojom API too.

      Filed a bug, updated comment with comment:
      https://crbugs.com/452595360

      Line 2132, Patchset 19: if (should_update_layers_backend_) {

      should_update_layers_backend_ = false;
      if (layers_enabled_) {
      Alexander Cooper . unresolved

      So, IIUC, the issue stems from the fact that we need to have the layers be "viable" before we service the frame to the page, and we aren't currently *actually* updating the render state until we *start* processing the frame? So we essentially intentionally drop a frame and re-request it so that we can get a frame where the layers are valid before we service it to the page?

      If I've got it right, can you add a comment here that this is a workaround for the bug I asked you to file in the other comment?

      Evgenii Alekseev (xWF)

      Yes, you are right, there is no pending layers sequence update on the backend.
      I've filed a bug. Updated comment.
      https://crbugs.com/452604976

      Line 2135, Patchset 19: // TODO(crbug.com/450856064): Update backend and request frame again.
      Alexander Cooper . unresolved

      I can't remember at the moment, but does the backend not complain about receiving layers it didn't expect? e.g. Shouldn't this CL be making the SetEnabledCompositionLayers call?

      Evgenii Alekseev (xWF)

      At this point, it should go through the "submit missing frame" API, which does not include any layer.

      I'll add SetEnabledCompositionLayers in the next CL.

      Line 2135, Patchset 19: // TODO(crbug.com/450856064): Update backend and request frame again.
      Alexander Cooper . unresolved

      I can't remember at the moment, but does the backend not complain about receiving layers it didn't expect? e.g. Shouldn't this CL be making the SetEnabledCompositionLayers call?

      Evgenii Alekseev (xWF)

      At this point, it should go through the "submit missing frame" API, which does not include layers sequence.

      Open in Gerrit

      Related details

      Attention is currently required from:
      • Alexander Cooper
      • Brandon Jones
      Submit Requirements:
        • requirement satisfiedCode-Coverage
        • requirement is not satisfiedCode-Owners
        • requirement is not satisfiedCode-Review
        • requirement is not satisfiedNo-Unresolved-Comments
        • requirement is not satisfiedReview-Enforcement
        Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
        Gerrit-MessageType: comment
        Gerrit-Project: chromium/src
        Gerrit-Branch: main
        Gerrit-Change-Id: I68566baec2c3d17499381ca57c5c08e32de0c3ec
        Gerrit-Change-Number: 6984541
        Gerrit-PatchSet: 21
        Gerrit-Owner: Evgenii Alekseev (xWF) <eale...@google.com>
        Gerrit-Reviewer: Alexander Cooper <alco...@chromium.org>
        Gerrit-Reviewer: Brandon Jones <baj...@chromium.org>
        Gerrit-Reviewer: Evgenii Alekseev (xWF) <eale...@google.com>
        Gerrit-CC: AI Code Reviewer <peep-gen...@system.gserviceaccount.com>
        Gerrit-CC: Dirk Schulze <dsch...@chromium.org>
        Gerrit-CC: Stephen Chenney <sche...@chromium.org>
        Gerrit-Attention: Brandon Jones <baj...@chromium.org>
        Gerrit-Attention: Alexander Cooper <alco...@chromium.org>
        Gerrit-Comment-Date: Thu, 16 Oct 2025 19:34:18 +0000
        Gerrit-HasComments: Yes
        Gerrit-Has-Labels: No
        satisfied_requirement
        unsatisfied_requirement
        open
        diffy

        Alexander Cooper (Gerrit)

        unread,
        Oct 16, 2025, 5:53:01 PM (4 days ago) Oct 16
        to Evgenii Alekseev (xWF), Brandon Jones, Chromium LUCI CQ, AyeAye, AI Code Reviewer, chromium...@chromium.org, Dirk Schulze, Stephen Chenney, blink-revie...@chromium.org, blink-reviews-p...@chromium.org, blink-...@chromium.org, drott+bl...@chromium.org, feature-v...@chromium.org, fmalit...@chromium.org, fserb...@chromium.org, kinuko...@chromium.org
        Attention needed from Brandon Jones and Evgenii Alekseev (xWF)

        Alexander Cooper voted and added 11 comments

        Votes added by Alexander Cooper

        Code-Review+1

        11 comments

        File third_party/blink/renderer/modules/xr/xr_frame_provider.h
        Line 199, Patchset 19: bool layers_enabled_ = false;
        Alexander Cooper . unresolved

        I believe layers can only be enabled on the immersive session; rather than caching this I'd prefer we either:
        1) Add a method to XrSession like: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/modules/xr/xr_session.h;drc=32ef847d4806639a036e08779c3150e760a5030c;l=360
        or
        2) Query https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/modules/xr/xr_session.h;drc=32ef847d4806639a036e08779c3150e760a5030c;l=404

        Could generate a local method to wrap the call for readability.

        Evgenii Alekseev (xWF)

        The problem is that there is no session reference in the current class, we are getting session with argument of the methods.

        I have cherry-pick'ed layer_manager_.is_bound() from the next CL.

        Alexander Cooper

        There is. Looks like line 148 after changes there is `Member<XRSession> immersive_session_`.

        (There's also `non_immersive_data_providers_` which has the inline XRSessions, but I don't think we need to worrya bout those).

        Having this store the layer_manager_ and using it's presence instead of a bool is fine too.

        Line 67, Patchset 13: void SubmitLayer(uint32_t layer_id, XrLayerClient*, bool was_changed);
        Alexander Cooper . unresolved

        LayerId.

        But also... maybe queryable from the XrLayerClient?

        Evgenii Alekseev (xWF)

        I though about it, but in that case we have to add a static cast to the XRwebGL Layer AND/OR XrCompoistionLayer.

        Alexander Cooper

        How so? I think if we want to just use `kInvalidId` for BaseLayer, it's fine and doesn't need a check? (I *would* advocate that it'd be nice if we could start generating IDs for base layers, and just treat them like projection layers, but I think that's beyond the scope of this).

        Evgenii Alekseev (xWF)

        I'm sorry, I could not understand your idea. Could you please give more details?

        As I can see we have the following hierarchy for the XrLayerClient:

        class XRWebGLLayer final : public XRLayer, public XrLayerClient 
        class XRCompositionLayer : public XRLayer {
        public:
        XRLayerDrawingContext* drawing_context();
        }
        class XRLayerDrawingContext : public GarbageCollected<XRLayerDrawingContext>,
        public XrLayerClient;


        which means that we have to cast XRLayerClient to the XRWebGLLayer or XRCompositionLayer to make it possible to call the layer_id().

        On the other hand, we have layer_id() at the context of the SubmitLayer() function call.

        1. BaseLayer has a layer id on the blink side, and we do replace kInvalidId with a real layer id for the shared buffer at the XRSession::OnFrame.
        So, we should never get kInvalidId as argument. I can add CHECK if it makes sense.
        2. According to spec layers list could contain any XrLayer type, which means that XrWebGLLayer could be in the list too. So, that's why XrwebGLLayer's backend goes through the LayerManager API when 'layers' enabled, and it has a shared buffer (openxr composition layer) with the corresponding layer id at the backed.

        Alexander Cooper

        I was asking if it was possible to expose a method on `XRLayerClient` to get the `layer_id`; but if it's easier to not, and leave it as you have it, that's fine too.

        File third_party/blink/renderer/modules/xr/xr_frame_provider.cc
        Line 120, Patchset 19: // TODO(crbug.com/450856064): Add layer_manager initialization.
        layers_enabled_ =
        session->IsFeatureEnabled(device::mojom::XRSessionFeature::LAYERS);
        Alexander Cooper . resolved

        See other comment about wrapping this in a method rather than a member.

        Evgenii Alekseev (xWF)

        replaced on layer_manager initialization + XRSession::layers_enabled()

        Alexander Cooper

        Acknowledged

        Line 858, Patchset 19: // The backend expects an empty layer ID list if the 'layers' feature is not
        // enabled.
        if (!layers_enabled_) {
        layer_ids.clear();
        }
        Alexander Cooper . unresolved

        It's kind of a CHECK failure here if this is bigger than size 1 with layers_enabled_ == false right? e.g. there should not be a way to get this to be larger than just the base layer if we don't have the layers feature enabled.

        Evgenii Alekseev (xWF)

        1.I've separated layer_ids and image_refs into two distinct vectors.

        2. We only require layer_ids for the shared buffer use case. And there is no CHECK for ids size, only for the image_refs size.

        3. backend will throw an exception if the layer_ids list is non-empty when the session lacks the 'layers' feature.

        Alexander Cooper

        Right, but I'm saying if the front end is calling `SubmitLayer` more than once in a non-layers enabled session (e.g. layer_ids is bigger than size 1), that's an error isn't it?

        File third_party/blink/renderer/modules/xr/xr_render_state.cc
        Line 131, Patchset 19: XRLayer* last_modified_layer =
        base_layer_ ? base_layer_
        : (layers_ && !layers_->empty() ? layers_->back() : nullptr);
        Alexander Cooper . resolved

        Why does this need to be the last_modified_layer ? If our main goal is to get the transport delegate, then can we just query `GetFirstLayer()`, since it should be the same for every layer in the array? (e.g. either it's the base layer where there's only one, or it's a composition layer where it comes from the binding?)

        Evgenii Alekseev (xWF)

        Good point, I'll try.

        Alexander Cooper

        Done

        Line 136, Patchset 19: if (last_modified_layer->LayerType() == XRLayerType::kWebGLLayer) {
        transport_delegate = static_cast<XRWebGLLayer*>(last_modified_layer)
        ->GetTransportDelegate();
        } else {
        transport_delegate = static_cast<XRCompositionLayer*>(last_modified_layer)
        ->binding()
        ->GetTransportDelegate();
        }
        Alexander Cooper . resolved

        I don't think I'm opposed to putting this on XrLayer if that simplifies things.

        Evgenii Alekseev (xWF)

        GetTransportDelegate() defined at the XRLayerClient,

        And XrWebGLLayer implements both XRLayer and XRLayerClient.

        So, I've implemented is via XrLayer::LayerClient()->GetTransportDelegate();

        Please, let me know if it ok?

        Alexander Cooper

        And XrWebGLLayer implements both XRLayer and XRLayerClient.

        It is technically fine for a class to implement two interfaces with the same method declaration; though it does feel a bit weird, so this is fine.

        Line 149, Patchset 19:bool XRRenderState::GetAndClearUpdateLayersStatus() {
        bool needs_update = needs_layers_update_;
        needs_layers_update_ = false;
        return needs_update;
        }
        Alexander Cooper . resolved

        I think this should be split into two methods. `NeedLayersUpdate()` and `OnLayersUpdated()`.

        Evgenii Alekseev (xWF)

        Good point. updated.

        Alexander Cooper

        Done

        File third_party/blink/renderer/modules/xr/xr_session.cc
        Line 1698, Patchset 19: if (!will_have_valid_render_state) {
        prev_transport_delegate_ = render_state_->GetTransportDelegate();
        }
        Alexander Cooper . resolved

        Why here instead of relying on ApplyPendingRenderState?

        Evgenii Alekseev (xWF)

        removed. Most likely it is not needed at all.

        Alexander Cooper

        Done

        Line 1836, Patchset 19: prev_transport_delegate_ = nullptr;
        ApplyPendingRenderState();
        Alexander Cooper . resolved

        I think I see what you've been saying. Per the spec, we should do this after we finish processing the callbacks not here probably, per our impl we *probably* need to do this before we submit, and the backend can handle knowing that it should use the "old" value for the pending submit and the "new" value for the next frame it returns. I guess there'd probably be a further backend change needed there on top of moving this towards e.g. the end of OnFrame instead of here (with a few early returns updated/removed). I'd guess that may also remove some `prev_transport_delegate_` logic, but may need to add some logic to e.g. drop the frame request if the render state isn't good.

        I think what you've got now is an okay workaround, but can you file a bug?

        Evgenii Alekseev (xWF)

        The prev_base_layer and prev_transport_delegate uses to handle the render state transition from when it has at least one layer to the state when there is no any layer in the render state.

        It is mainly related to the XRFrameTransport::FrameSubmitMissing which is required the sync token as a one of the parameters of the mojom call.

        So, it is more or less clear how to avoid extra frame message for the layers, but for the base layer we probably have to extend mojom API too.

        Filed a bug, updated comment with comment:
        https://crbugs.com/452595360

        Alexander Cooper

        It is mainly related to the XRFrameTransport::FrameSubmitMissing which is required the sync token as a one of the parameters of the mojom call.

        Except that I think we can just pass a default constructed sync token if there's e.g. nothing to actually sync on.

        I think that essentially dropping the frame if we don't have a valid layer setup is fine. But this is all discussion for the feature.

        Line 2132, Patchset 19: if (should_update_layers_backend_) {
        should_update_layers_backend_ = false;
        if (layers_enabled_) {
        Alexander Cooper . unresolved

        So, IIUC, the issue stems from the fact that we need to have the layers be "viable" before we service the frame to the page, and we aren't currently *actually* updating the render state until we *start* processing the frame? So we essentially intentionally drop a frame and re-request it so that we can get a frame where the layers are valid before we service it to the page?

        If I've got it right, can you add a comment here that this is a workaround for the bug I asked you to file in the other comment?

        Evgenii Alekseev (xWF)

        Yes, you are right, there is no pending layers sequence update on the backend.
        I've filed a bug. Updated comment.
        https://crbugs.com/452604976

        Alexander Cooper

        Looks like comment didn't get updated?

        Line 2135, Patchset 19: // TODO(crbug.com/450856064): Update backend and request frame again.
        Alexander Cooper . resolved

        I can't remember at the moment, but does the backend not complain about receiving layers it didn't expect? e.g. Shouldn't this CL be making the SetEnabledCompositionLayers call?

        Evgenii Alekseev (xWF)

        At this point, it should go through the "submit missing frame" API, which does not include layers sequence.

        Alexander Cooper

        Acknowledged

        Open in Gerrit

        Related details

        Attention is currently required from:
        • Brandon Jones
        • Evgenii Alekseev (xWF)
        Submit Requirements:
          • requirement satisfiedCode-Coverage
          • requirement is not satisfiedCode-Owners
          • requirement is not satisfiedCode-Review
          • requirement is not satisfiedNo-Unresolved-Comments
          • requirement satisfiedReview-Enforcement
          Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
          Gerrit-MessageType: comment
          Gerrit-Project: chromium/src
          Gerrit-Branch: main
          Gerrit-Change-Id: I68566baec2c3d17499381ca57c5c08e32de0c3ec
          Gerrit-Change-Number: 6984541
          Gerrit-PatchSet: 21
          Gerrit-Owner: Evgenii Alekseev (xWF) <eale...@google.com>
          Gerrit-Reviewer: Alexander Cooper <alco...@chromium.org>
          Gerrit-Reviewer: Brandon Jones <baj...@chromium.org>
          Gerrit-Reviewer: Evgenii Alekseev (xWF) <eale...@google.com>
          Gerrit-CC: AI Code Reviewer <peep-gen...@system.gserviceaccount.com>
          Gerrit-CC: Dirk Schulze <dsch...@chromium.org>
          Gerrit-CC: Stephen Chenney <sche...@chromium.org>
          Gerrit-Attention: Brandon Jones <baj...@chromium.org>
          Gerrit-Attention: Evgenii Alekseev (xWF) <eale...@google.com>
          Gerrit-Comment-Date: Thu, 16 Oct 2025 21:52:48 +0000
          Gerrit-HasComments: Yes
          Gerrit-Has-Labels: Yes
          satisfied_requirement
          unsatisfied_requirement
          open
          diffy

          Evgenii Alekseev (xWF) (Gerrit)

          unread,
          Oct 17, 2025, 10:46:06 AM (3 days ago) Oct 17
          to Alexander Cooper, Brandon Jones, Chromium LUCI CQ, AyeAye, AI Code Reviewer, chromium...@chromium.org, Dirk Schulze, Stephen Chenney, blink-revie...@chromium.org, blink-reviews-p...@chromium.org, blink-...@chromium.org, drott+bl...@chromium.org, feature-v...@chromium.org, fmalit...@chromium.org, fserb...@chromium.org, kinuko...@chromium.org
          Attention needed from Alexander Cooper and Brandon Jones

          Evgenii Alekseev (xWF) added 4 comments

          File third_party/blink/renderer/modules/xr/xr_frame_provider.h
          Line 199, Patchset 19: bool layers_enabled_ = false;
          Alexander Cooper . unresolved

          I believe layers can only be enabled on the immersive session; rather than caching this I'd prefer we either:
          1) Add a method to XrSession like: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/modules/xr/xr_session.h;drc=32ef847d4806639a036e08779c3150e760a5030c;l=360
          or
          2) Query https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/modules/xr/xr_session.h;drc=32ef847d4806639a036e08779c3150e760a5030c;l=404

          Could generate a local method to wrap the call for readability.

          Evgenii Alekseev (xWF)

          The problem is that there is no session reference in the current class, we are getting session with argument of the methods.

          I have cherry-pick'ed layer_manager_.is_bound() from the next CL.

          Alexander Cooper

          There is. Looks like line 148 after changes there is `Member<XRSession> immersive_session_`.

          (There's also `non_immersive_data_providers_` which has the inline XRSessions, but I don't think we need to worrya bout those).

          Having this store the layer_manager_ and using it's presence instead of a bool is fine too.

          Evgenii Alekseev (xWF)

          Thank you. I've totally missed it.

          Line 67, Patchset 13: void SubmitLayer(uint32_t layer_id, XrLayerClient*, bool was_changed);
          Alexander Cooper . unresolved

          LayerId.

          But also... maybe queryable from the XrLayerClient?

          Evgenii Alekseev (xWF)

          I though about it, but in that case we have to add a static cast to the XRwebGL Layer AND/OR XrCompoistionLayer.

          Alexander Cooper

          How so? I think if we want to just use `kInvalidId` for BaseLayer, it's fine and doesn't need a check? (I *would* advocate that it'd be nice if we could start generating IDs for base layers, and just treat them like projection layers, but I think that's beyond the scope of this).

          Evgenii Alekseev (xWF)

          I'm sorry, I could not understand your idea. Could you please give more details?

          As I can see we have the following hierarchy for the XrLayerClient:

          class XRWebGLLayer final : public XRLayer, public XrLayerClient 
          class XRCompositionLayer : public XRLayer {
          public:
          XRLayerDrawingContext* drawing_context();
          }
          class XRLayerDrawingContext : public GarbageCollected<XRLayerDrawingContext>,
          public XrLayerClient;


          which means that we have to cast XRLayerClient to the XRWebGLLayer or XRCompositionLayer to make it possible to call the layer_id().

          On the other hand, we have layer_id() at the context of the SubmitLayer() function call.

          1. BaseLayer has a layer id on the blink side, and we do replace kInvalidId with a real layer id for the shared buffer at the XRSession::OnFrame.
          So, we should never get kInvalidId as argument. I can add CHECK if it makes sense.
          2. According to spec layers list could contain any XrLayer type, which means that XrWebGLLayer could be in the list too. So, that's why XrwebGLLayer's backend goes through the LayerManager API when 'layers' enabled, and it has a shared buffer (openxr composition layer) with the corresponding layer id at the backed.

          Alexander Cooper

          I was asking if it was possible to expose a method on `XRLayerClient` to get the `layer_id`; but if it's easier to not, and leave it as you have it, that's fine too.

          Evgenii Alekseev (xWF)

          The same case as duplicate of the GetTransportDelegate() in the XRLayer,

          I mean that in that case both XRLayerClient and XRLayer should provide layer_id(),
          and XRWebGLLayer should override them.

          File third_party/blink/renderer/modules/xr/xr_frame_provider.cc
          Line 858, Patchset 19: // The backend expects an empty layer ID list if the 'layers' feature is not
          // enabled.
          if (!layers_enabled_) {
          layer_ids.clear();
          }
          Alexander Cooper . unresolved

          It's kind of a CHECK failure here if this is bigger than size 1 with layers_enabled_ == false right? e.g. there should not be a way to get this to be larger than just the base layer if we don't have the layers feature enabled.

          Evgenii Alekseev (xWF)

          1.I've separated layer_ids and image_refs into two distinct vectors.

          2. We only require layer_ids for the shared buffer use case. And there is no CHECK for ids size, only for the image_refs size.

          3. backend will throw an exception if the layer_ids list is non-empty when the session lacks the 'layers' feature.

          Alexander Cooper

          Right, but I'm saying if the front end is calling `SubmitLayer` more than once in a non-layers enabled session (e.g. layer_ids is bigger than size 1), that's an error isn't it?

          Evgenii Alekseev (xWF)

          Good point, added CHECK and corresponding comment.

          File third_party/blink/renderer/modules/xr/xr_session.cc
          Line 2132, Patchset 19: if (should_update_layers_backend_) {
          should_update_layers_backend_ = false;
          if (layers_enabled_) {
          Alexander Cooper . unresolved

          So, IIUC, the issue stems from the fact that we need to have the layers be "viable" before we service the frame to the page, and we aren't currently *actually* updating the render state until we *start* processing the frame? So we essentially intentionally drop a frame and re-request it so that we can get a frame where the layers are valid before we service it to the page?

          If I've got it right, can you add a comment here that this is a workaround for the bug I asked you to file in the other comment?

          Evgenii Alekseev (xWF)

          Yes, you are right, there is no pending layers sequence update on the backend.
          I've filed a bug. Updated comment.
          https://crbugs.com/452604976

          Alexander Cooper

          Looks like comment didn't get updated?

          Evgenii Alekseev (xWF)

          Great catch. Thanks. I've updated comment, it was pointed at the cube layer support bug number.

          Open in Gerrit

          Related details

          Attention is currently required from:
          • Alexander Cooper
          • Brandon Jones
          Submit Requirements:
            • requirement satisfiedCode-Coverage
            • requirement is not satisfiedCode-Owners
            • requirement is not satisfiedCode-Review
            • requirement is not satisfiedNo-Unresolved-Comments
            • requirement is not satisfiedReview-Enforcement
            Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
            Gerrit-MessageType: comment
            Gerrit-Project: chromium/src
            Gerrit-Branch: main
            Gerrit-Change-Id: I68566baec2c3d17499381ca57c5c08e32de0c3ec
            Gerrit-Change-Number: 6984541
            Gerrit-PatchSet: 23
            Gerrit-Owner: Evgenii Alekseev (xWF) <eale...@google.com>
            Gerrit-Reviewer: Alexander Cooper <alco...@chromium.org>
            Gerrit-Reviewer: Brandon Jones <baj...@chromium.org>
            Gerrit-Reviewer: Evgenii Alekseev (xWF) <eale...@google.com>
            Gerrit-CC: AI Code Reviewer <peep-gen...@system.gserviceaccount.com>
            Gerrit-CC: Dirk Schulze <dsch...@chromium.org>
            Gerrit-CC: Stephen Chenney <sche...@chromium.org>
            Gerrit-Attention: Brandon Jones <baj...@chromium.org>
            Gerrit-Attention: Alexander Cooper <alco...@chromium.org>
            Gerrit-Comment-Date: Fri, 17 Oct 2025 14:45:55 +0000
            Gerrit-HasComments: Yes
            Gerrit-Has-Labels: No
            satisfied_requirement
            unsatisfied_requirement
            open
            diffy

            Alexander Cooper (Gerrit)

            unread,
            Oct 17, 2025, 5:31:24 PM (3 days ago) Oct 17
            to Evgenii Alekseev (xWF), Brandon Jones, Chromium LUCI CQ, AyeAye, AI Code Reviewer, chromium...@chromium.org, Dirk Schulze, Stephen Chenney, blink-revie...@chromium.org, blink-reviews-p...@chromium.org, blink-...@chromium.org, drott+bl...@chromium.org, feature-v...@chromium.org, fmalit...@chromium.org, fserb...@chromium.org, kinuko...@chromium.org
            Attention needed from Brandon Jones, Evgenii Alekseev (xWF) and Joe Mason

            Alexander Cooper voted and added 5 comments

            Votes added by Alexander Cooper

            Code-Review+1

            5 comments

            Patchset-level comments
            File-level comment, Patchset 23 (Latest):
            Alexander Cooper . resolved

            Still LGTM, just one more tweak to the comment.

            File third_party/blink/renderer/modules/xr/xr_frame_provider.h
            Line 199, Patchset 19: bool layers_enabled_ = false;
            Alexander Cooper . resolved

            I believe layers can only be enabled on the immersive session; rather than caching this I'd prefer we either:
            1) Add a method to XrSession like: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/modules/xr/xr_session.h;drc=32ef847d4806639a036e08779c3150e760a5030c;l=360
            or
            2) Query https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/modules/xr/xr_session.h;drc=32ef847d4806639a036e08779c3150e760a5030c;l=404

            Could generate a local method to wrap the call for readability.

            Evgenii Alekseev (xWF)

            The problem is that there is no session reference in the current class, we are getting session with argument of the methods.

            I have cherry-pick'ed layer_manager_.is_bound() from the next CL.

            Alexander Cooper

            There is. Looks like line 148 after changes there is `Member<XRSession> immersive_session_`.

            (There's also `non_immersive_data_providers_` which has the inline XRSessions, but I don't think we need to worrya bout those).

            Having this store the layer_manager_ and using it's presence instead of a bool is fine too.

            Evgenii Alekseev (xWF)

            Thank you. I've totally missed it.

            Alexander Cooper

            Acknowledged

            Line 67, Patchset 13: void SubmitLayer(uint32_t layer_id, XrLayerClient*, bool was_changed);
            Alexander Cooper . resolved
            Alexander Cooper

            Acknowledged

            File third_party/blink/renderer/modules/xr/xr_frame_provider.cc
            Line 858, Patchset 19: // The backend expects an empty layer ID list if the 'layers' feature is not
            // enabled.
            if (!layers_enabled_) {
            layer_ids.clear();
            }
            Alexander Cooper . resolved

            It's kind of a CHECK failure here if this is bigger than size 1 with layers_enabled_ == false right? e.g. there should not be a way to get this to be larger than just the base layer if we don't have the layers feature enabled.

            Evgenii Alekseev (xWF)

            1.I've separated layer_ids and image_refs into two distinct vectors.

            2. We only require layer_ids for the shared buffer use case. And there is no CHECK for ids size, only for the image_refs size.

            3. backend will throw an exception if the layer_ids list is non-empty when the session lacks the 'layers' feature.

            Alexander Cooper

            Right, but I'm saying if the front end is calling `SubmitLayer` more than once in a non-layers enabled session (e.g. layer_ids is bigger than size 1), that's an error isn't it?

            Evgenii Alekseev (xWF)

            Good point, added CHECK and corresponding comment.

            Alexander Cooper

            Done

            File third_party/blink/renderer/modules/xr/xr_session.cc
            Line 2132, Patchset 19: if (should_update_layers_backend_) {
            should_update_layers_backend_ = false;
            if (layers_enabled_) {
            Alexander Cooper . unresolved

            So, IIUC, the issue stems from the fact that we need to have the layers be "viable" before we service the frame to the page, and we aren't currently *actually* updating the render state until we *start* processing the frame? So we essentially intentionally drop a frame and re-request it so that we can get a frame where the layers are valid before we service it to the page?

            If I've got it right, can you add a comment here that this is a workaround for the bug I asked you to file in the other comment?

            Evgenii Alekseev (xWF)

            Yes, you are right, there is no pending layers sequence update on the backend.
            I've filed a bug. Updated comment.
            https://crbugs.com/452604976

            Alexander Cooper

            Looks like comment didn't get updated?

            Evgenii Alekseev (xWF)

            Great catch. Thanks. I've updated comment, it was pointed at the cube layer support bug number.

            Alexander Cooper

            Oh, sorry I meant I'd like a comment along the lines of like "This means that the page has updated the layers since it last received a new frame, but we haven't updated the backend yet, so the page won't be able to use those layers just yet as they expect. For now, drop this frame and request a new one with the updated layers, which we'll then serve to the page." (And then leave the TODO on the line below the comment).

            Open in Gerrit

            Related details

            Attention is currently required from:
            • Brandon Jones
            • Evgenii Alekseev (xWF)
            • Joe Mason
            Submit Requirements:
              • requirement satisfiedCode-Coverage
              • requirement is not satisfiedCode-Owners
              • requirement is not satisfiedCode-Review
              • requirement is not satisfiedNo-Unresolved-Comments
              • requirement satisfiedReview-Enforcement
              Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
              Gerrit-MessageType: comment
              Gerrit-Project: chromium/src
              Gerrit-Branch: main
              Gerrit-Change-Id: I68566baec2c3d17499381ca57c5c08e32de0c3ec
              Gerrit-Change-Number: 6984541
              Gerrit-PatchSet: 23
              Gerrit-Owner: Evgenii Alekseev (xWF) <eale...@google.com>
              Gerrit-Reviewer: Alexander Cooper <alco...@chromium.org>
              Gerrit-Reviewer: Brandon Jones <baj...@chromium.org>
              Gerrit-Reviewer: Evgenii Alekseev (xWF) <eale...@google.com>
              Gerrit-Reviewer: Joe Mason <joenot...@google.com>
              Gerrit-CC: AI Code Reviewer <peep-gen...@system.gserviceaccount.com>
              Gerrit-CC: Dirk Schulze <dsch...@chromium.org>
              Gerrit-CC: Stephen Chenney <sche...@chromium.org>
              Gerrit-Attention: Brandon Jones <baj...@chromium.org>
              Gerrit-Attention: Joe Mason <joenot...@google.com>
              Gerrit-Attention: Evgenii Alekseev (xWF) <eale...@google.com>
              Gerrit-Comment-Date: Fri, 17 Oct 2025 21:31:13 +0000
              Gerrit-HasComments: Yes
              Gerrit-Has-Labels: Yes
              satisfied_requirement
              unsatisfied_requirement
              open
              diffy

              Joe Mason (Gerrit)

              unread,
              Oct 17, 2025, 6:14:16 PM (3 days ago) Oct 17
              to Evgenii Alekseev (xWF), Alexander Cooper, Brandon Jones, Chromium LUCI CQ, AyeAye, AI Code Reviewer, chromium...@chromium.org, Dirk Schulze, Stephen Chenney, blink-revie...@chromium.org, blink-reviews-p...@chromium.org, blink-...@chromium.org, drott+bl...@chromium.org, feature-v...@chromium.org, fmalit...@chromium.org, fserb...@chromium.org, kinuko...@chromium.org
              Attention needed from Brandon Jones and Evgenii Alekseev (xWF)

              Joe Mason voted and added 1 comment

              Votes added by Joe Mason

              Code-Review+1

              1 comment

              Patchset-level comments
              Joe Mason . resolved

              mojom LGTM

              Open in Gerrit

              Related details

              Attention is currently required from:
              • Brandon Jones
              • Evgenii Alekseev (xWF)
              Submit Requirements:
              • requirement satisfiedCode-Coverage
              • requirement satisfiedCode-Owners
              • requirement satisfiedCode-Review
              • requirement is not satisfiedNo-Unresolved-Comments
              • requirement satisfiedReview-Enforcement
              Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
              Gerrit-MessageType: comment
              Gerrit-Project: chromium/src
              Gerrit-Branch: main
              Gerrit-Change-Id: I68566baec2c3d17499381ca57c5c08e32de0c3ec
              Gerrit-Change-Number: 6984541
              Gerrit-PatchSet: 23
              Gerrit-Owner: Evgenii Alekseev (xWF) <eale...@google.com>
              Gerrit-Reviewer: Alexander Cooper <alco...@chromium.org>
              Gerrit-Reviewer: Brandon Jones <baj...@chromium.org>
              Gerrit-Reviewer: Evgenii Alekseev (xWF) <eale...@google.com>
              Gerrit-Reviewer: Joe Mason <joenot...@google.com>
              Gerrit-CC: AI Code Reviewer <peep-gen...@system.gserviceaccount.com>
              Gerrit-CC: Dirk Schulze <dsch...@chromium.org>
              Gerrit-CC: Stephen Chenney <sche...@chromium.org>
              Gerrit-Attention: Brandon Jones <baj...@chromium.org>
              Gerrit-Attention: Evgenii Alekseev (xWF) <eale...@google.com>
              Gerrit-Comment-Date: Fri, 17 Oct 2025 22:14:09 +0000
              Gerrit-HasComments: Yes
              Gerrit-Has-Labels: Yes
              satisfied_requirement
              unsatisfied_requirement
              open
              diffy

              Evgenii Alekseev (xWF) (Gerrit)

              unread,
              10:31 AM (9 hours ago) 10:31 AM
              to Alexander Cooper, Brandon Jones, Chromium LUCI CQ, AyeAye, AI Code Reviewer, chromium...@chromium.org, Dirk Schulze, Stephen Chenney, blink-revie...@chromium.org, blink-reviews-p...@chromium.org, blink-...@chromium.org, drott+bl...@chromium.org, feature-v...@chromium.org, fmalit...@chromium.org, fserb...@chromium.org, kinuko...@chromium.org
              Attention needed from Alexander Cooper and Brandon Jones

              Evgenii Alekseev (xWF) added 1 comment

              File third_party/blink/renderer/modules/xr/xr_session.cc
              Line 2132, Patchset 19: if (should_update_layers_backend_) {
              should_update_layers_backend_ = false;
              if (layers_enabled_) {
              Alexander Cooper . unresolved

              So, IIUC, the issue stems from the fact that we need to have the layers be "viable" before we service the frame to the page, and we aren't currently *actually* updating the render state until we *start* processing the frame? So we essentially intentionally drop a frame and re-request it so that we can get a frame where the layers are valid before we service it to the page?

              If I've got it right, can you add a comment here that this is a workaround for the bug I asked you to file in the other comment?

              Evgenii Alekseev (xWF)

              Yes, you are right, there is no pending layers sequence update on the backend.
              I've filed a bug. Updated comment.
              https://crbugs.com/452604976

              Alexander Cooper

              Looks like comment didn't get updated?

              Evgenii Alekseev (xWF)

              Great catch. Thanks. I've updated comment, it was pointed at the cube layer support bug number.

              Alexander Cooper

              Oh, sorry I meant I'd like a comment along the lines of like "This means that the page has updated the layers since it last received a new frame, but we haven't updated the backend yet, so the page won't be able to use those layers just yet as they expect. For now, drop this frame and request a new one with the updated layers, which we'll then serve to the page." (And then leave the TODO on the line below the comment).

              Evgenii Alekseev (xWF)

              Do you mind if I add comment at the next CL? As far as next CL should modify an absolutely the same code lines.

              Open in Gerrit

              Related details

              Attention is currently required from:
              • Alexander Cooper
              • Brandon Jones
              Gerrit-Attention: Alexander Cooper <alco...@chromium.org>
              Gerrit-Comment-Date: Mon, 20 Oct 2025 14:31:44 +0000
              Gerrit-HasComments: Yes
              Gerrit-Has-Labels: No
              satisfied_requirement
              unsatisfied_requirement
              open
              diffy

              Evgenii Alekseev (xWF) (Gerrit)

              unread,
              1:04 PM (7 hours ago) 1:04 PM
              to Alexander Cooper, Brandon Jones, Chromium LUCI CQ, AyeAye, AI Code Reviewer, chromium...@chromium.org, Dirk Schulze, Stephen Chenney, blink-revie...@chromium.org, blink-reviews-p...@chromium.org, blink-...@chromium.org, drott+bl...@chromium.org, feature-v...@chromium.org, fmalit...@chromium.org, fserb...@chromium.org, kinuko...@chromium.org
              Attention needed from Alexander Cooper, Brandon Jones and Joe Mason

              Evgenii Alekseev (xWF) added 1 comment

              File third_party/blink/renderer/modules/xr/xr_session.cc
              Line 2132, Patchset 19: if (should_update_layers_backend_) {
              should_update_layers_backend_ = false;
              if (layers_enabled_) {
              Alexander Cooper . unresolved

              So, IIUC, the issue stems from the fact that we need to have the layers be "viable" before we service the frame to the page, and we aren't currently *actually* updating the render state until we *start* processing the frame? So we essentially intentionally drop a frame and re-request it so that we can get a frame where the layers are valid before we service it to the page?

              If I've got it right, can you add a comment here that this is a workaround for the bug I asked you to file in the other comment?

              Evgenii Alekseev (xWF)

              Yes, you are right, there is no pending layers sequence update on the backend.
              I've filed a bug. Updated comment.
              https://crbugs.com/452604976

              Alexander Cooper

              Looks like comment didn't get updated?

              Evgenii Alekseev (xWF)

              Great catch. Thanks. I've updated comment, it was pointed at the cube layer support bug number.

              Alexander Cooper

              Oh, sorry I meant I'd like a comment along the lines of like "This means that the page has updated the layers since it last received a new frame, but we haven't updated the backend yet, so the page won't be able to use those layers just yet as they expect. For now, drop this frame and request a new one with the updated layers, which we'll then serve to the page." (And then leave the TODO on the line below the comment).

              Evgenii Alekseev (xWF)

              Do you mind if I add comment at the next CL? As far as next CL should modify an absolutely the same code lines.

              Evgenii Alekseev (xWF)

              Updated the comment.

              Open in Gerrit

              Related details

              Attention is currently required from:
              • Alexander Cooper
              • Brandon Jones
              • Joe Mason
              Submit Requirements:
                • requirement satisfiedCode-Coverage
                • requirement satisfiedCode-Owners
                • requirement is not satisfiedCode-Review
                • requirement is not satisfiedNo-Unresolved-Comments
                • requirement is not satisfiedReview-Enforcement
                Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
                Gerrit-MessageType: comment
                Gerrit-Project: chromium/src
                Gerrit-Branch: main
                Gerrit-Change-Id: I68566baec2c3d17499381ca57c5c08e32de0c3ec
                Gerrit-Change-Number: 6984541
                Gerrit-PatchSet: 24
                Gerrit-Owner: Evgenii Alekseev (xWF) <eale...@google.com>
                Gerrit-Reviewer: Alexander Cooper <alco...@chromium.org>
                Gerrit-Reviewer: Brandon Jones <baj...@chromium.org>
                Gerrit-Reviewer: Evgenii Alekseev (xWF) <eale...@google.com>
                Gerrit-Reviewer: Joe Mason <joenot...@google.com>
                Gerrit-CC: AI Code Reviewer <peep-gen...@system.gserviceaccount.com>
                Gerrit-CC: Dirk Schulze <dsch...@chromium.org>
                Gerrit-CC: Stephen Chenney <sche...@chromium.org>
                Gerrit-Attention: Brandon Jones <baj...@chromium.org>
                Gerrit-Attention: Alexander Cooper <alco...@chromium.org>
                Gerrit-Attention: Joe Mason <joenot...@google.com>
                Gerrit-Comment-Date: Mon, 20 Oct 2025 17:04:23 +0000
                satisfied_requirement
                unsatisfied_requirement
                open
                diffy

                Alexander Cooper (Gerrit)

                unread,
                1:06 PM (7 hours ago) 1:06 PM
                to Evgenii Alekseev (xWF), Brandon Jones, Chromium LUCI CQ, AyeAye, AI Code Reviewer, chromium...@chromium.org, Dirk Schulze, Stephen Chenney, blink-revie...@chromium.org, blink-reviews-p...@chromium.org, blink-...@chromium.org, drott+bl...@chromium.org, feature-v...@chromium.org, fmalit...@chromium.org, fserb...@chromium.org, kinuko...@chromium.org
                Attention needed from Brandon Jones, Evgenii Alekseev (xWF) and Joe Mason

                Alexander Cooper voted and added 1 comment

                Votes added by Alexander Cooper

                Code-Review+1

                1 comment

                File third_party/blink/renderer/modules/xr/xr_session.cc
                Line 2132, Patchset 19: if (should_update_layers_backend_) {
                should_update_layers_backend_ = false;
                if (layers_enabled_) {
                Alexander Cooper . resolved

                So, IIUC, the issue stems from the fact that we need to have the layers be "viable" before we service the frame to the page, and we aren't currently *actually* updating the render state until we *start* processing the frame? So we essentially intentionally drop a frame and re-request it so that we can get a frame where the layers are valid before we service it to the page?

                If I've got it right, can you add a comment here that this is a workaround for the bug I asked you to file in the other comment?

                Evgenii Alekseev (xWF)

                Yes, you are right, there is no pending layers sequence update on the backend.
                I've filed a bug. Updated comment.
                https://crbugs.com/452604976

                Alexander Cooper

                Looks like comment didn't get updated?

                Evgenii Alekseev (xWF)

                Great catch. Thanks. I've updated comment, it was pointed at the cube layer support bug number.

                Alexander Cooper

                Oh, sorry I meant I'd like a comment along the lines of like "This means that the page has updated the layers since it last received a new frame, but we haven't updated the backend yet, so the page won't be able to use those layers just yet as they expect. For now, drop this frame and request a new one with the updated layers, which we'll then serve to the page." (And then leave the TODO on the line below the comment).

                Evgenii Alekseev (xWF)

                Do you mind if I add comment at the next CL? As far as next CL should modify an absolutely the same code lines.

                Alexander Cooper

                Looks like you uploaded it now anyways? UI looks like you still have code owners approval, so we won't need Joe to stamp again, just one other person apart from me.

                Open in Gerrit

                Related details

                Attention is currently required from:
                • Brandon Jones
                • Evgenii Alekseev (xWF)
                • Joe Mason
                Submit Requirements:
                  • requirement satisfiedCode-Coverage
                  • requirement satisfiedCode-Owners
                  • requirement is not satisfiedCode-Review
                  • requirement satisfiedReview-Enforcement
                  Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
                  Gerrit-MessageType: comment
                  Gerrit-Project: chromium/src
                  Gerrit-Branch: main
                  Gerrit-Change-Id: I68566baec2c3d17499381ca57c5c08e32de0c3ec
                  Gerrit-Change-Number: 6984541
                  Gerrit-PatchSet: 24
                  Gerrit-Owner: Evgenii Alekseev (xWF) <eale...@google.com>
                  Gerrit-Reviewer: Alexander Cooper <alco...@chromium.org>
                  Gerrit-Reviewer: Brandon Jones <baj...@chromium.org>
                  Gerrit-Reviewer: Evgenii Alekseev (xWF) <eale...@google.com>
                  Gerrit-Reviewer: Joe Mason <joenot...@google.com>
                  Gerrit-CC: AI Code Reviewer <peep-gen...@system.gserviceaccount.com>
                  Gerrit-CC: Dirk Schulze <dsch...@chromium.org>
                  Gerrit-CC: Stephen Chenney <sche...@chromium.org>
                  Gerrit-Attention: Brandon Jones <baj...@chromium.org>
                  Gerrit-Attention: Joe Mason <joenot...@google.com>
                  Gerrit-Attention: Evgenii Alekseev (xWF) <eale...@google.com>
                  Gerrit-Comment-Date: Mon, 20 Oct 2025 17:05:58 +0000
                  Gerrit-HasComments: Yes
                  Gerrit-Has-Labels: Yes
                  satisfied_requirement
                  unsatisfied_requirement
                  open
                  diffy

                  Brandon Jones (Gerrit)

                  unread,
                  4:20 PM (4 hours ago) 4:20 PM
                  to Evgenii Alekseev (xWF), Alexander Cooper, Chromium LUCI CQ, AyeAye, AI Code Reviewer, chromium...@chromium.org, Dirk Schulze, Stephen Chenney, blink-revie...@chromium.org, blink-reviews-p...@chromium.org, blink-...@chromium.org, drott+bl...@chromium.org, feature-v...@chromium.org, fmalit...@chromium.org, fserb...@chromium.org, kinuko...@chromium.org
                  Attention needed from Evgenii Alekseev (xWF) and Joe Mason

                  Brandon Jones voted Code-Review+1

                  Code-Review+1
                  Open in Gerrit

                  Related details

                  Attention is currently required from:
                  • Evgenii Alekseev (xWF)
                  • Joe Mason
                  Submit Requirements:
                    • requirement satisfiedCode-Coverage
                    • requirement satisfiedCode-Owners
                    • requirement satisfiedCode-Review
                    • requirement satisfiedReview-Enforcement
                    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
                    Gerrit-MessageType: comment
                    Gerrit-Project: chromium/src
                    Gerrit-Branch: main
                    Gerrit-Change-Id: I68566baec2c3d17499381ca57c5c08e32de0c3ec
                    Gerrit-Change-Number: 6984541
                    Gerrit-PatchSet: 24
                    Gerrit-Owner: Evgenii Alekseev (xWF) <eale...@google.com>
                    Gerrit-Reviewer: Alexander Cooper <alco...@chromium.org>
                    Gerrit-Reviewer: Brandon Jones <baj...@chromium.org>
                    Gerrit-Reviewer: Evgenii Alekseev (xWF) <eale...@google.com>
                    Gerrit-Reviewer: Joe Mason <joenot...@google.com>
                    Gerrit-CC: AI Code Reviewer <peep-gen...@system.gserviceaccount.com>
                    Gerrit-CC: Dirk Schulze <dsch...@chromium.org>
                    Gerrit-CC: Stephen Chenney <sche...@chromium.org>
                    Gerrit-Attention: Joe Mason <joenot...@google.com>
                    Gerrit-Attention: Evgenii Alekseev (xWF) <eale...@google.com>
                    Gerrit-Comment-Date: Mon, 20 Oct 2025 20:20:17 +0000
                    Gerrit-HasComments: No
                    Gerrit-Has-Labels: Yes
                    satisfied_requirement
                    open
                    diffy

                    Blink W3C Test Autoroller (Gerrit)

                    unread,
                    4:27 PM (3 hours ago) 4:27 PM
                    to Evgenii Alekseev (xWF), Brandon Jones, Alexander Cooper, Chromium LUCI CQ, AyeAye, AI Code Reviewer, chromium...@chromium.org, Dirk Schulze, Stephen Chenney, blink-revie...@chromium.org, blink-reviews-p...@chromium.org, blink-...@chromium.org, drott+bl...@chromium.org, feature-v...@chromium.org, fmalit...@chromium.org, fserb...@chromium.org, kinuko...@chromium.org
                    Attention needed from Evgenii Alekseev (xWF) and Joe Mason

                    Message from Blink W3C Test Autoroller

                    Exportable changes to web-platform-tests were detected in this CL and a pull request in the upstream repo has been made: https://github.com/web-platform-tests/wpt/pull/55552.

                    When this CL lands, the bot will automatically merge the PR on GitHub if the required GitHub checks pass; otherwise, ecosystem-infra@ team will triage the failures and may contact you.

                    WPT Export docs:
                    https://chromium.googlesource.com/chromium/src/+/main/docs/testing/web_platform_tests.md#Automatic-export-process

                    Gerrit-CC: Blink W3C Test Autoroller <blink-w3c-te...@chromium.org>
                    Gerrit-CC: Dirk Schulze <dsch...@chromium.org>
                    Gerrit-CC: Stephen Chenney <sche...@chromium.org>
                    Gerrit-Attention: Joe Mason <joenot...@google.com>
                    Gerrit-Attention: Evgenii Alekseev (xWF) <eale...@google.com>
                    Gerrit-Comment-Date: Mon, 20 Oct 2025 20:27:22 +0000
                    Gerrit-HasComments: No
                    Gerrit-Has-Labels: No
                    satisfied_requirement
                    open
                    diffy

                    Evgenii Alekseev (xWF) (Gerrit)

                    unread,
                    5:26 PM (3 hours ago) 5:26 PM
                    to Blink W3C Test Autoroller, Brandon Jones, Alexander Cooper, Chromium LUCI CQ, AyeAye, AI Code Reviewer, chromium...@chromium.org, Dirk Schulze, Stephen Chenney, blink-revie...@chromium.org, blink-reviews-p...@chromium.org, blink-...@chromium.org, drott+bl...@chromium.org, feature-v...@chromium.org, fmalit...@chromium.org, fserb...@chromium.org, kinuko...@chromium.org
                    Attention needed from Joe Mason

                    Evgenii Alekseev (xWF) voted Commit-Queue+2

                    Commit-Queue+2
                    Open in Gerrit

                    Related details

                    Attention is currently required from:
                    • Joe Mason
                    Gerrit-Comment-Date: Mon, 20 Oct 2025 21:26:08 +0000
                    Gerrit-HasComments: No
                    Gerrit-Has-Labels: Yes
                    satisfied_requirement
                    open
                    diffy

                    Chromium LUCI CQ (Gerrit)

                    unread,
                    6:14 PM (2 hours ago) 6:14 PM
                    to Evgenii Alekseev (xWF), Blink W3C Test Autoroller, Brandon Jones, Alexander Cooper, AyeAye, AI Code Reviewer, chromium...@chromium.org, Dirk Schulze, Stephen Chenney, blink-revie...@chromium.org, blink-reviews-p...@chromium.org, blink-...@chromium.org, drott+bl...@chromium.org, feature-v...@chromium.org, fmalit...@chromium.org, fserb...@chromium.org, kinuko...@chromium.org

                    Chromium LUCI CQ submitted the change

                    Change information

                    Commit message:
                    WebXR Layers API: Add layer IDs to frame submit sequence

                    This change introduces layer ids to the XR frame submission process via
                    mojom api.

                    The key changes are:
                    - vr_service.mojom: The SubmitFrameDrawnIntoTexture method now includes a layer_ids argument.This allows the VR service to receive a list of layers which modified shared buffer image for the current frame.

                    - XrFrameProvider: The frame submission sequence is now consists of multiple steps: ClearCachedLayersData -> SubmitLayer (for each layer) -> SubmitFrame.This new sequence allow us to collect layer ids, when 'layers' feature enabled and submit frame with a sing gfx::SyncToken.

                    - XRSession: The behavior of updateRenderState has been extended to support a layers feature. On ApplyPendingRenderState, if a modification to the layers composition sequence is detected, the current frame is dropped. The session then should update the layers sequence via the mojom layer manager API and requests a new frame.

                    BYPASS_LARGE_CHANGE_WARNING
                    Bug: 443963000
                    Change-Id: I68566baec2c3d17499381ca57c5c08e32de0c3ec
                    Reviewed-by: Alexander Cooper <alco...@chromium.org>
                    Commit-Queue: Evgenii Alekseev (xWF) <eale...@google.com>
                    Reviewed-by: Brandon Jones <baj...@chromium.org>
                    Cr-Commit-Position: refs/heads/main@{#1532575}
                    Files:
                    • M device/vr/android/arcore/arcore_gl.cc
                    • M device/vr/android/arcore/arcore_gl.h
                    • M device/vr/android/cardboard/cardboard_render_loop.cc
                    • M device/vr/android/cardboard/cardboard_render_loop.h
                    • M device/vr/openxr/openxr_render_loop.cc
                    • M device/vr/openxr/openxr_render_loop.h
                    • M device/vr/public/mojom/vr_service.mojom
                    • M third_party/blink/renderer/modules/xr/DEPS
                    • M third_party/blink/renderer/modules/xr/xr_composition_layer.cc
                    • M third_party/blink/renderer/modules/xr/xr_composition_layer.h
                    • M third_party/blink/renderer/modules/xr/xr_frame_provider.cc
                    • M third_party/blink/renderer/modules/xr/xr_frame_provider.h
                    • M third_party/blink/renderer/modules/xr/xr_gpu_binding.h
                    • M third_party/blink/renderer/modules/xr/xr_graphics_binding.h
                    • M third_party/blink/renderer/modules/xr/xr_id_hash_traits.h
                    • M third_party/blink/renderer/modules/xr/xr_layer.h
                    • M third_party/blink/renderer/modules/xr/xr_layer_shared_image_manager.cc
                    • M third_party/blink/renderer/modules/xr/xr_layer_shared_image_manager.h
                    • M third_party/blink/renderer/modules/xr/xr_render_state.cc
                    • M third_party/blink/renderer/modules/xr/xr_render_state.h
                    • M third_party/blink/renderer/modules/xr/xr_session.cc
                    • M third_party/blink/renderer/modules/xr/xr_session.h
                    • M third_party/blink/renderer/modules/xr/xr_webgl_binding.h
                    • M third_party/blink/renderer/modules/xr/xr_webgl_layer.cc
                    • M third_party/blink/renderer/modules/xr/xr_webgl_layer.h
                    • M third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.cc
                    • M third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.h
                    • M third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport_delegate.h
                    • M third_party/blink/renderer/platform/graphics/gpu/xr_gpu_frame_transport_delegate.cc
                    • M third_party/blink/renderer/platform/graphics/gpu/xr_gpu_frame_transport_delegate.h
                    • M third_party/blink/renderer/platform/graphics/gpu/xr_webgl_frame_transport_delegate.cc
                    • M third_party/blink/renderer/platform/graphics/gpu/xr_webgl_frame_transport_delegate.h
                    • M third_party/blink/web_tests/external/wpt/resources/chromium/webxr-test.js
                    Change size: L
                    Delta: 33 files changed, 440 insertions(+), 122 deletions(-)
                    Branch: refs/heads/main
                    Submit Requirements:
                    • requirement satisfiedCode-Review: +1 by Alexander Cooper, +1 by Brandon Jones
                    Open in Gerrit
                    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
                    Gerrit-MessageType: merged
                    Gerrit-Project: chromium/src
                    Gerrit-Branch: main
                    Gerrit-Change-Id: I68566baec2c3d17499381ca57c5c08e32de0c3ec
                    Gerrit-Change-Number: 6984541
                    Gerrit-PatchSet: 25
                    Gerrit-Owner: Evgenii Alekseev (xWF) <eale...@google.com>
                    Gerrit-Reviewer: Alexander Cooper <alco...@chromium.org>
                    Gerrit-Reviewer: Brandon Jones <baj...@chromium.org>
                    Gerrit-Reviewer: Chromium LUCI CQ <chromiu...@luci-project-accounts.iam.gserviceaccount.com>
                    Gerrit-Reviewer: Evgenii Alekseev (xWF) <eale...@google.com>
                    Gerrit-Reviewer: Joe Mason <joenot...@google.com>
                    Gerrit-CC: AI Code Reviewer <peep-gen...@system.gserviceaccount.com>
                    Gerrit-CC: Blink W3C Test Autoroller <blink-w3c-te...@chromium.org>
                    open
                    diffy
                    satisfied_requirement
                    Reply all
                    Reply to author
                    Forward
                    0 new messages