Recover mojo frame source after a GPU crash or startup deadlock [chromium/src : main]

0 views
Skip to first unread message

Mitchell Cohen (Gerrit)

unread,
Jun 23, 2026, 11:08:01 AM (6 days ago) Jun 23
to Kyle Charbonneau, Kramer Ge, chromium...@chromium.org, Ian Vollick, cc-...@chromium.org, chromium-a...@chromium.org, extension...@chromium.org, jbauma...@chromium.org, max+watc...@igalia.com, nickdiego+wa...@igalia.com, ozone-...@chromium.org
Attention needed from Kramer Ge and Kyle Charbonneau

Mitchell Cohen added 1 comment

Patchset-level comments
File-level comment, Patchset 4 (Latest):
Mitchell Cohen . unresolved

Hi @kyle...@chromium.org. For some context: I've been working with @fang...@chromium.org on a BFS for Wayland using the mojo impl, and it's hit some subtle timing issues when testing in the wild. I've addressed these on the source side wherever possible but I believe this one needs to be solved on the viz side. (Not sure what the driver can do if a frame issued with `force: true` is never acked.) Appreciate your review and please let me know if this isn't the best approach.

Open in Gerrit

Related details

Attention is currently required from:
  • Kramer Ge
  • Kyle Charbonneau
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: I54dac094fc1f5e3666883dd56eef1af17e2acfe6
Gerrit-Change-Number: 7979228
Gerrit-PatchSet: 4
Gerrit-Owner: Mitchell Cohen <mitc...@agilebits.com>
Gerrit-Reviewer: Kramer Ge <fang...@chromium.org>
Gerrit-Reviewer: Kyle Charbonneau <kyle...@chromium.org>
Gerrit-CC: Ian Vollick <vol...@chromium.org>
Gerrit-Attention: Kyle Charbonneau <kyle...@chromium.org>
Gerrit-Attention: Kramer Ge <fang...@chromium.org>
Gerrit-Comment-Date: Tue, 23 Jun 2026 15:07:50 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
satisfied_requirement
unsatisfied_requirement
open
diffy

Kramer Ge (Gerrit)

unread,
Jun 23, 2026, 3:00:49 PM (6 days ago) Jun 23
to Mitchell Cohen, Kyle Charbonneau, Kramer Ge, chromium...@chromium.org, Ian Vollick, cc-...@chromium.org, chromium-a...@chromium.org, extension...@chromium.org, jbauma...@chromium.org, max+watc...@igalia.com, nickdiego+wa...@igalia.com, ozone-...@chromium.org
Attention needed from Kramer Ge, Kyle Charbonneau and Mitchell Cohen

Kramer Ge added 1 comment

File components/viz/service/frame_sinks/external_begin_frame_source_mojo.cc
Line 148, Patchset 6 (Latest): last_begin_frame_args_ = BeginFrameArgs();
Kramer Ge . unresolved

What is the flow of events that caused this deadlock?

From my understanding a newly connected frame_sink gets issued a `last_begin_frame_args_` after `OnDisplayDidFinishFrame`. so we missed the opportunity to dispatch frame callback.

But does new frame_sinks never `DidFinishFrame`? If it does, `ExternalBeginFrameSourceMojo::OnFrameSinkDidFinishFrame` will call `MaybeProduceFrameCallback`.

Open in Gerrit

Related details

Attention is currently required from:
  • Kramer Ge
  • Kyle Charbonneau
  • Mitchell Cohen
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: I54dac094fc1f5e3666883dd56eef1af17e2acfe6
Gerrit-Change-Number: 7979228
Gerrit-PatchSet: 6
Gerrit-Owner: Mitchell Cohen <mitc...@agilebits.com>
Gerrit-Reviewer: Kramer Ge <fang...@chromium.org>
Gerrit-Reviewer: Kyle Charbonneau <kyle...@chromium.org>
Gerrit-CC: Ian Vollick <vol...@chromium.org>
Gerrit-CC: Kramer Ge <fang...@google.com>
Gerrit-Attention: Kyle Charbonneau <kyle...@chromium.org>
Gerrit-Attention: Mitchell Cohen <mitc...@agilebits.com>
Gerrit-Attention: Kramer Ge <fang...@chromium.org>
Gerrit-Comment-Date: Tue, 23 Jun 2026 19:00:39 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
satisfied_requirement
unsatisfied_requirement
open
diffy

Mitchell Cohen (Gerrit)

unread,
Jun 24, 2026, 10:07:53 AM (5 days ago) Jun 24
to Kramer Ge, Kyle Charbonneau, Kramer Ge, chromium...@chromium.org, Ian Vollick, cc-...@chromium.org, chromium-a...@chromium.org, extension...@chromium.org, jbauma...@chromium.org, max+watc...@igalia.com, nickdiego+wa...@igalia.com, ozone-...@chromium.org
Attention needed from Kramer Ge, Kramer Ge and Kyle Charbonneau

Mitchell Cohen added 1 comment

File components/viz/service/frame_sinks/external_begin_frame_source_mojo.cc
Line 148, Patchset 6 (Latest): last_begin_frame_args_ = BeginFrameArgs();
Kramer Ge . unresolved

What is the flow of events that caused this deadlock?

From my understanding a newly connected frame_sink gets issued a `last_begin_frame_args_` after `OnDisplayDidFinishFrame`. so we missed the opportunity to dispatch frame callback.

But does new frame_sinks never `DidFinishFrame`? If it does, `ExternalBeginFrameSourceMojo::OnFrameSinkDidFinishFrame` will call `MaybeProduceFrameCallback`.

Mitchell Cohen

The deadlock happens if a new sink starts observing after a frame is displayed in `OnDisplayDidFinishFrame` but before the ack callback is dispatched in `MaybeProduceFrameCallback`.

The late sink is sent a missed begin frame and gets added to `pending_frame_sinks_`. But it never reaches `DidFinishFrame`. (It never hears back from its client.) So the sink gets stuck in the list and `MaybeProduceFrameCallback` exits early.

The fix avoids sending frames to new sinks if they have already been displayed.

Open in Gerrit

Related details

Attention is currently required from:
  • Kramer Ge
  • Kramer Ge
  • Kyle Charbonneau
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: I54dac094fc1f5e3666883dd56eef1af17e2acfe6
Gerrit-Change-Number: 7979228
Gerrit-PatchSet: 6
Gerrit-Owner: Mitchell Cohen <mitc...@agilebits.com>
Gerrit-Reviewer: Kramer Ge <fang...@chromium.org>
Gerrit-Reviewer: Kyle Charbonneau <kyle...@chromium.org>
Gerrit-CC: Ian Vollick <vol...@chromium.org>
Gerrit-CC: Kramer Ge <fang...@google.com>
Gerrit-Attention: Kyle Charbonneau <kyle...@chromium.org>
Gerrit-Attention: Kramer Ge <fang...@google.com>
Gerrit-Attention: Kramer Ge <fang...@chromium.org>
Gerrit-Comment-Date: Wed, 24 Jun 2026 14:07:46 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Kramer Ge <fang...@google.com>
satisfied_requirement
unsatisfied_requirement
open
diffy

Kyle Charbonneau (Gerrit)

unread,
Jun 24, 2026, 10:44:32 AM (5 days ago) Jun 24
to Mitchell Cohen, Kramer Ge, Kramer Ge, chromium...@chromium.org, Ian Vollick, cc-...@chromium.org, chromium-a...@chromium.org, extension...@chromium.org, jbauma...@chromium.org, max+watc...@igalia.com, nickdiego+wa...@igalia.com, ozone-...@chromium.org
Attention needed from Kramer Ge, Kramer Ge and Mitchell Cohen

Kyle Charbonneau added 1 comment

File components/viz/service/frame_sinks/external_begin_frame_source_mojo.cc
Line 148, Patchset 6 (Latest): last_begin_frame_args_ = BeginFrameArgs();
Kramer Ge . unresolved

What is the flow of events that caused this deadlock?

From my understanding a newly connected frame_sink gets issued a `last_begin_frame_args_` after `OnDisplayDidFinishFrame`. so we missed the opportunity to dispatch frame callback.

But does new frame_sinks never `DidFinishFrame`? If it does, `ExternalBeginFrameSourceMojo::OnFrameSinkDidFinishFrame` will call `MaybeProduceFrameCallback`.

Mitchell Cohen

The deadlock happens if a new sink starts observing after a frame is displayed in `OnDisplayDidFinishFrame` but before the ack callback is dispatched in `MaybeProduceFrameCallback`.

The late sink is sent a missed begin frame and gets added to `pending_frame_sinks_`. But it never reaches `DidFinishFrame`. (It never hears back from its client.) So the sink gets stuck in the list and `MaybeProduceFrameCallback` exits early.

The fix avoids sending frames to new sinks if they have already been displayed.

Kyle Charbonneau

The deadlock happens if a new sink starts observing after a frame is displayed in OnDisplayDidFinishFrame

If the new sink starts observing after OnDisplayDidFinishFrame() then the ack callback should have already fired. I guess if there is also a sink that is already observing but didn't produce a frame, so pending_frame_sinks isn't empty, that could happen.

The same problem you describe seems like it would happen if any client is sent a begin frame, so it's put in pending_frame_sinks, but never responds. This part of the change doesn't fix that.

In general this logic here to not send an ack back to the other end of the mojo interface was designed for headless mode where it [needs to wait](https://crrev.com/c/3354381) for all clients to respond. That ensures no overlapping frames. That doesn't seem like appropriate behavior for use of this class with wayland?

Open in Gerrit

Related details

Attention is currently required from:
  • Kramer Ge
  • Kramer Ge
  • Mitchell Cohen
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: I54dac094fc1f5e3666883dd56eef1af17e2acfe6
Gerrit-Change-Number: 7979228
Gerrit-PatchSet: 6
Gerrit-Owner: Mitchell Cohen <mitc...@agilebits.com>
Gerrit-Reviewer: Kramer Ge <fang...@chromium.org>
Gerrit-Reviewer: Kyle Charbonneau <kyle...@chromium.org>
Gerrit-CC: Ian Vollick <vol...@chromium.org>
Gerrit-CC: Kramer Ge <fang...@google.com>
Gerrit-Attention: Mitchell Cohen <mitc...@agilebits.com>
Gerrit-Attention: Kramer Ge <fang...@google.com>
Gerrit-Attention: Kramer Ge <fang...@chromium.org>
Gerrit-Comment-Date: Wed, 24 Jun 2026 14:44:13 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Mitchell Cohen <mitc...@agilebits.com>
Comment-In-Reply-To: Kramer Ge <fang...@google.com>
satisfied_requirement
unsatisfied_requirement
open
diffy

Mitchell Cohen (Gerrit)

unread,
Jun 24, 2026, 11:58:59 AM (5 days ago) Jun 24
to Kramer Ge, Kyle Charbonneau, Kramer Ge, chromium...@chromium.org, Ian Vollick, cc-...@chromium.org, chromium-a...@chromium.org, extension...@chromium.org, jbauma...@chromium.org, max+watc...@igalia.com, nickdiego+wa...@igalia.com, ozone-...@chromium.org
Attention needed from Kramer Ge, Kramer Ge and Kyle Charbonneau

Mitchell Cohen added 1 comment

File components/viz/service/frame_sinks/external_begin_frame_source_mojo.cc
Line 148, Patchset 6 (Latest): last_begin_frame_args_ = BeginFrameArgs();
Kramer Ge . unresolved

What is the flow of events that caused this deadlock?

From my understanding a newly connected frame_sink gets issued a `last_begin_frame_args_` after `OnDisplayDidFinishFrame`. so we missed the opportunity to dispatch frame callback.

But does new frame_sinks never `DidFinishFrame`? If it does, `ExternalBeginFrameSourceMojo::OnFrameSinkDidFinishFrame` will call `MaybeProduceFrameCallback`.

Mitchell Cohen

The deadlock happens if a new sink starts observing after a frame is displayed in `OnDisplayDidFinishFrame` but before the ack callback is dispatched in `MaybeProduceFrameCallback`.

The late sink is sent a missed begin frame and gets added to `pending_frame_sinks_`. But it never reaches `DidFinishFrame`. (It never hears back from its client.) So the sink gets stuck in the list and `MaybeProduceFrameCallback` exits early.

The fix avoids sending frames to new sinks if they have already been displayed.

Kyle Charbonneau

The deadlock happens if a new sink starts observing after a frame is displayed in OnDisplayDidFinishFrame

If the new sink starts observing after OnDisplayDidFinishFrame() then the ack callback should have already fired. I guess if there is also a sink that is already observing but didn't produce a frame, so pending_frame_sinks isn't empty, that could happen.

The same problem you describe seems like it would happen if any client is sent a begin frame, so it's put in pending_frame_sinks, but never responds. This part of the change doesn't fix that.

In general this logic here to not send an ack back to the other end of the mojo interface was designed for headless mode where it [needs to wait](https://crrev.com/c/3354381) for all clients to respond. That ensures no overlapping frames. That doesn't seem like appropriate behavior for use of this class with wayland?

Mitchell Cohen

Yes, the repro requires two sinks to deadlock.

Wayland always needs the ack to come after the frame is displayed (especially if issued with `force: true`) and doesn't want to wait for all the clients. Another option I've considered is making sure OnDisplayDidFinishFrame always calls dispatch when it's not in headless mode.

Open in Gerrit

Related details

Attention is currently required from:
  • Kramer Ge
  • Kramer Ge
  • Kyle Charbonneau
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: I54dac094fc1f5e3666883dd56eef1af17e2acfe6
Gerrit-Change-Number: 7979228
Gerrit-PatchSet: 6
Gerrit-Owner: Mitchell Cohen <mitc...@agilebits.com>
Gerrit-Reviewer: Kramer Ge <fang...@chromium.org>
Gerrit-Reviewer: Kyle Charbonneau <kyle...@chromium.org>
Gerrit-CC: Ian Vollick <vol...@chromium.org>
Gerrit-CC: Kramer Ge <fang...@google.com>
Gerrit-Attention: Kyle Charbonneau <kyle...@chromium.org>
Gerrit-Attention: Kramer Ge <fang...@google.com>
Gerrit-Attention: Kramer Ge <fang...@chromium.org>
Gerrit-Comment-Date: Wed, 24 Jun 2026 15:58:44 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Kyle Charbonneau <kyle...@chromium.org>
satisfied_requirement
unsatisfied_requirement
open
diffy

Kyle Charbonneau (Gerrit)

unread,
Jun 24, 2026, 12:02:58 PM (5 days ago) Jun 24
to Mitchell Cohen, Kramer Ge, Kramer Ge, chromium...@chromium.org, Ian Vollick, cc-...@chromium.org, chromium-a...@chromium.org, extension...@chromium.org, jbauma...@chromium.org, max+watc...@igalia.com, nickdiego+wa...@igalia.com, ozone-...@chromium.org
Attention needed from Kramer Ge, Kramer Ge and Mitchell Cohen

Kyle Charbonneau added 1 comment

File components/viz/service/frame_sinks/external_begin_frame_source_mojo.cc
Line 148, Patchset 6 (Latest): last_begin_frame_args_ = BeginFrameArgs();
Kramer Ge . unresolved

What is the flow of events that caused this deadlock?

From my understanding a newly connected frame_sink gets issued a `last_begin_frame_args_` after `OnDisplayDidFinishFrame`. so we missed the opportunity to dispatch frame callback.

But does new frame_sinks never `DidFinishFrame`? If it does, `ExternalBeginFrameSourceMojo::OnFrameSinkDidFinishFrame` will call `MaybeProduceFrameCallback`.

Mitchell Cohen

The deadlock happens if a new sink starts observing after a frame is displayed in `OnDisplayDidFinishFrame` but before the ack callback is dispatched in `MaybeProduceFrameCallback`.

The late sink is sent a missed begin frame and gets added to `pending_frame_sinks_`. But it never reaches `DidFinishFrame`. (It never hears back from its client.) So the sink gets stuck in the list and `MaybeProduceFrameCallback` exits early.

The fix avoids sending frames to new sinks if they have already been displayed.

Kyle Charbonneau

The deadlock happens if a new sink starts observing after a frame is displayed in OnDisplayDidFinishFrame

If the new sink starts observing after OnDisplayDidFinishFrame() then the ack callback should have already fired. I guess if there is also a sink that is already observing but didn't produce a frame, so pending_frame_sinks isn't empty, that could happen.

The same problem you describe seems like it would happen if any client is sent a begin frame, so it's put in pending_frame_sinks, but never responds. This part of the change doesn't fix that.

In general this logic here to not send an ack back to the other end of the mojo interface was designed for headless mode where it [needs to wait](https://crrev.com/c/3354381) for all clients to respond. That ensures no overlapping frames. That doesn't seem like appropriate behavior for use of this class with wayland?

Mitchell Cohen

Yes, the repro requires two sinks to deadlock.

Wayland always needs the ack to come after the frame is displayed (especially if issued with `force: true`) and doesn't want to wait for all the clients. Another option I've considered is making sure OnDisplayDidFinishFrame always calls dispatch when it's not in headless mode.

Kyle Charbonneau

Another option I've considered is making sure OnDisplayDidFinishFrame always calls dispatch when it's not in headless mode.

Let's hear from Kramer but I'm surprised it doesn't work this way now. On Wayland if there is a slow viz client (eg. a slow OOPIF) that often delivers OnBeginFrame response late it's going to throttle the next begin frame for all clients in the same window. That seems undesirable. I'm not sure of the context here and if there is a good reason for this or not.

Open in Gerrit

Related details

Attention is currently required from:
  • Kramer Ge
  • Kramer Ge
  • Mitchell Cohen
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: I54dac094fc1f5e3666883dd56eef1af17e2acfe6
Gerrit-Change-Number: 7979228
Gerrit-PatchSet: 6
Gerrit-Owner: Mitchell Cohen <mitc...@agilebits.com>
Gerrit-Reviewer: Kramer Ge <fang...@chromium.org>
Gerrit-Reviewer: Kyle Charbonneau <kyle...@chromium.org>
Gerrit-CC: Ian Vollick <vol...@chromium.org>
Gerrit-CC: Kramer Ge <fang...@google.com>
Gerrit-Attention: Mitchell Cohen <mitc...@agilebits.com>
Gerrit-Attention: Kramer Ge <fang...@google.com>
Gerrit-Attention: Kramer Ge <fang...@chromium.org>
Gerrit-Comment-Date: Wed, 24 Jun 2026 16:02:21 +0000
satisfied_requirement
unsatisfied_requirement
open
diffy

Kramer Ge (Gerrit)

unread,
Jun 24, 2026, 12:08:21 PM (5 days ago) Jun 24
to Mitchell Cohen, Kramer Ge, Kyle Charbonneau, chromium...@chromium.org, Ian Vollick, cc-...@chromium.org, chromium-a...@chromium.org, extension...@chromium.org, jbauma...@chromium.org, max+watc...@igalia.com, nickdiego+wa...@igalia.com, ozone-...@chromium.org
Attention needed from Kramer Ge and Mitchell Cohen

Kramer Ge added 1 comment

File components/viz/service/frame_sinks/external_begin_frame_source_mojo.cc
Line 148, Patchset 6 (Latest): last_begin_frame_args_ = BeginFrameArgs();
Kramer Ge . unresolved

What is the flow of events that caused this deadlock?

From my understanding a newly connected frame_sink gets issued a `last_begin_frame_args_` after `OnDisplayDidFinishFrame`. so we missed the opportunity to dispatch frame callback.

But does new frame_sinks never `DidFinishFrame`? If it does, `ExternalBeginFrameSourceMojo::OnFrameSinkDidFinishFrame` will call `MaybeProduceFrameCallback`.

Mitchell Cohen

The deadlock happens if a new sink starts observing after a frame is displayed in `OnDisplayDidFinishFrame` but before the ack callback is dispatched in `MaybeProduceFrameCallback`.

The late sink is sent a missed begin frame and gets added to `pending_frame_sinks_`. But it never reaches `DidFinishFrame`. (It never hears back from its client.) So the sink gets stuck in the list and `MaybeProduceFrameCallback` exits early.

The fix avoids sending frames to new sinks if they have already been displayed.

Kyle Charbonneau

The deadlock happens if a new sink starts observing after a frame is displayed in OnDisplayDidFinishFrame

If the new sink starts observing after OnDisplayDidFinishFrame() then the ack callback should have already fired. I guess if there is also a sink that is already observing but didn't produce a frame, so pending_frame_sinks isn't empty, that could happen.

The same problem you describe seems like it would happen if any client is sent a begin frame, so it's put in pending_frame_sinks, but never responds. This part of the change doesn't fix that.

In general this logic here to not send an ack back to the other end of the mojo interface was designed for headless mode where it [needs to wait](https://crrev.com/c/3354381) for all clients to respond. That ensures no overlapping frames. That doesn't seem like appropriate behavior for use of this class with wayland?

Kramer Ge

That doesn't seem like appropriate behavior for use of this class with wayland?

Indeed no. By reading this code I assumed that deadlock can happen other than startup too. It leaves opportunity for a renderer to freeze frame production in viz. We didn't realize it's for headless.

I think we need to use a different mode for `ExternalBeginFrameSourceMojo`, i.e. one that doesn't unnecessarily block on a slow renderer,.

Open in Gerrit

Related details

Attention is currently required from:
  • Kramer Ge
  • Mitchell Cohen
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: I54dac094fc1f5e3666883dd56eef1af17e2acfe6
Gerrit-Change-Number: 7979228
Gerrit-PatchSet: 6
Gerrit-Owner: Mitchell Cohen <mitc...@agilebits.com>
Gerrit-Reviewer: Kramer Ge <fang...@chromium.org>
Gerrit-Reviewer: Kyle Charbonneau <kyle...@chromium.org>
Gerrit-CC: Ian Vollick <vol...@chromium.org>
Gerrit-CC: Kramer Ge <fang...@google.com>
Gerrit-Attention: Mitchell Cohen <mitc...@agilebits.com>
Gerrit-Attention: Kramer Ge <fang...@google.com>
Gerrit-Comment-Date: Wed, 24 Jun 2026 16:08:12 +0000
satisfied_requirement
unsatisfied_requirement
open
diffy

Mitchell Cohen (Gerrit)

unread,
Jun 25, 2026, 10:28:26 AM (4 days ago) Jun 25
to Kramer Ge, Kyle Charbonneau, Kramer Ge, chromium...@chromium.org, Ian Vollick, cc-...@chromium.org, chromium-a...@chromium.org, extension...@chromium.org, jbauma...@chromium.org, max+watc...@igalia.com, nickdiego+wa...@igalia.com, ozone-...@chromium.org
Attention needed from Kramer Ge, Kramer Ge and Kyle Charbonneau

Mitchell Cohen added 1 comment

File components/viz/service/frame_sinks/external_begin_frame_source_mojo.cc
Line 148, Patchset 6 (Latest): last_begin_frame_args_ = BeginFrameArgs();
Kramer Ge . unresolved

What is the flow of events that caused this deadlock?

From my understanding a newly connected frame_sink gets issued a `last_begin_frame_args_` after `OnDisplayDidFinishFrame`. so we missed the opportunity to dispatch frame callback.

But does new frame_sinks never `DidFinishFrame`? If it does, `ExternalBeginFrameSourceMojo::OnFrameSinkDidFinishFrame` will call `MaybeProduceFrameCallback`.

Mitchell Cohen

The deadlock happens if a new sink starts observing after a frame is displayed in `OnDisplayDidFinishFrame` but before the ack callback is dispatched in `MaybeProduceFrameCallback`.

The late sink is sent a missed begin frame and gets added to `pending_frame_sinks_`. But it never reaches `DidFinishFrame`. (It never hears back from its client.) So the sink gets stuck in the list and `MaybeProduceFrameCallback` exits early.

The fix avoids sending frames to new sinks if they have already been displayed.

Kyle Charbonneau

The deadlock happens if a new sink starts observing after a frame is displayed in OnDisplayDidFinishFrame

If the new sink starts observing after OnDisplayDidFinishFrame() then the ack callback should have already fired. I guess if there is also a sink that is already observing but didn't produce a frame, so pending_frame_sinks isn't empty, that could happen.

The same problem you describe seems like it would happen if any client is sent a begin frame, so it's put in pending_frame_sinks, but never responds. This part of the change doesn't fix that.

In general this logic here to not send an ack back to the other end of the mojo interface was designed for headless mode where it [needs to wait](https://crrev.com/c/3354381) for all clients to respond. That ensures no overlapping frames. That doesn't seem like appropriate behavior for use of this class with wayland?

Kramer Ge

That doesn't seem like appropriate behavior for use of this class with wayland?

Indeed no. By reading this code I assumed that deadlock can happen other than startup too. It leaves opportunity for a renderer to freeze frame production in viz. We didn't realize it's for headless.

I think we need to use a different mode for `ExternalBeginFrameSourceMojo`, i.e. one that doesn't unnecessarily block on a slow renderer,.

Mitchell Cohen

Is the "mode" essentially `frame_sink_manager_->run_all_compositor_stages_before_draw()`? Should the callback always be dispatched when it is false even if there are pending sinks?

Open in Gerrit

Related details

Attention is currently required from:
  • Kramer Ge
  • Kramer Ge
  • Kyle Charbonneau
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: I54dac094fc1f5e3666883dd56eef1af17e2acfe6
Gerrit-Change-Number: 7979228
Gerrit-PatchSet: 6
Gerrit-Owner: Mitchell Cohen <mitc...@agilebits.com>
Gerrit-Reviewer: Kramer Ge <fang...@chromium.org>
Gerrit-Reviewer: Kyle Charbonneau <kyle...@chromium.org>
Gerrit-CC: Ian Vollick <vol...@chromium.org>
Gerrit-CC: Kramer Ge <fang...@google.com>
Gerrit-Attention: Kyle Charbonneau <kyle...@chromium.org>
Gerrit-Attention: Kramer Ge <fang...@google.com>
Gerrit-Attention: Kramer Ge <fang...@chromium.org>
Gerrit-Comment-Date: Thu, 25 Jun 2026 14:28:18 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Kyle Charbonneau <kyle...@chromium.org>
Comment-In-Reply-To: Mitchell Cohen <mitc...@agilebits.com>
Comment-In-Reply-To: Kramer Ge <fang...@google.com>
Comment-In-Reply-To: Kramer Ge <fang...@chromium.org>
satisfied_requirement
unsatisfied_requirement
open
diffy

Kramer Ge (Gerrit)

unread,
Jun 25, 2026, 1:47:59 PM (4 days ago) Jun 25
to Mitchell Cohen, Kramer Ge, Kyle Charbonneau, chromium...@chromium.org, Ian Vollick, cc-...@chromium.org, chromium-a...@chromium.org, extension...@chromium.org, jbauma...@chromium.org, max+watc...@igalia.com, nickdiego+wa...@igalia.com, ozone-...@chromium.org
Attention needed from Kramer Ge, Kyle Charbonneau and Mitchell Cohen

Kramer Ge added 1 comment

File components/viz/service/frame_sinks/external_begin_frame_source_mojo.cc
Line 148, Patchset 6 (Latest): last_begin_frame_args_ = BeginFrameArgs();
Kramer Ge . unresolved

What is the flow of events that caused this deadlock?

From my understanding a newly connected frame_sink gets issued a `last_begin_frame_args_` after `OnDisplayDidFinishFrame`. so we missed the opportunity to dispatch frame callback.

But does new frame_sinks never `DidFinishFrame`? If it does, `ExternalBeginFrameSourceMojo::OnFrameSinkDidFinishFrame` will call `MaybeProduceFrameCallback`.

Mitchell Cohen

The deadlock happens if a new sink starts observing after a frame is displayed in `OnDisplayDidFinishFrame` but before the ack callback is dispatched in `MaybeProduceFrameCallback`.

The late sink is sent a missed begin frame and gets added to `pending_frame_sinks_`. But it never reaches `DidFinishFrame`. (It never hears back from its client.) So the sink gets stuck in the list and `MaybeProduceFrameCallback` exits early.

The fix avoids sending frames to new sinks if they have already been displayed.

Kyle Charbonneau

The deadlock happens if a new sink starts observing after a frame is displayed in OnDisplayDidFinishFrame

If the new sink starts observing after OnDisplayDidFinishFrame() then the ack callback should have already fired. I guess if there is also a sink that is already observing but didn't produce a frame, so pending_frame_sinks isn't empty, that could happen.

The same problem you describe seems like it would happen if any client is sent a begin frame, so it's put in pending_frame_sinks, but never responds. This part of the change doesn't fix that.

In general this logic here to not send an ack back to the other end of the mojo interface was designed for headless mode where it [needs to wait](https://crrev.com/c/3354381) for all clients to respond. That ensures no overlapping frames. That doesn't seem like appropriate behavior for use of this class with wayland?

Kramer Ge

That doesn't seem like appropriate behavior for use of this class with wayland?

Indeed no. By reading this code I assumed that deadlock can happen other than startup too. It leaves opportunity for a renderer to freeze frame production in viz. We didn't realize it's for headless.

I think we need to use a different mode for `ExternalBeginFrameSourceMojo`, i.e. one that doesn't unnecessarily block on a slow renderer,.

Mitchell Cohen

Is the "mode" essentially `frame_sink_manager_->run_all_compositor_stages_before_draw()`? Should the callback always be dispatched when it is false even if there are pending sinks?

Kramer Ge

`run_all_compositor_stages_before_draw` is blocking a draw, here it's blocking the next beginframe. I think we should refer to other `external_beginframe_sources`, such as `components/viz/service/frame_sinks/external_begin_frame_source_mojo_ios.h`, They do not wait for frame_sinks to finish, nor do they wait for `OnDisplayDidFinishFrame`.

That would make `begin_frame_source_wayland` simpler. Default logic of `ExternalBeginFrameSourceMojo` is for headless and AR/XR

Open in Gerrit

Related details

Attention is currently required from:
  • Kramer Ge
  • Kyle Charbonneau
  • Mitchell Cohen
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: I54dac094fc1f5e3666883dd56eef1af17e2acfe6
Gerrit-Change-Number: 7979228
Gerrit-PatchSet: 6
Gerrit-Owner: Mitchell Cohen <mitc...@agilebits.com>
Gerrit-Reviewer: Kramer Ge <fang...@chromium.org>
Gerrit-Reviewer: Kyle Charbonneau <kyle...@chromium.org>
Gerrit-CC: Ian Vollick <vol...@chromium.org>
Gerrit-CC: Kramer Ge <fang...@google.com>
Gerrit-Attention: Kyle Charbonneau <kyle...@chromium.org>
Gerrit-Attention: Mitchell Cohen <mitc...@agilebits.com>
Gerrit-Attention: Kramer Ge <fang...@google.com>
Gerrit-Comment-Date: Thu, 25 Jun 2026 17:47:51 +0000
satisfied_requirement
unsatisfied_requirement
open
diffy

Kyle Charbonneau (Gerrit)

unread,
Jun 26, 2026, 3:27:12 PM (3 days ago) Jun 26
to Mitchell Cohen, Kramer Ge, chromium...@chromium.org, Ian Vollick, cc-...@chromium.org, chromium-a...@chromium.org, extension...@chromium.org, jbauma...@chromium.org, max+watc...@igalia.com, nickdiego+wa...@igalia.com, ozone-...@chromium.org
Attention needed from Kramer Ge and Mitchell Cohen

Kyle Charbonneau added 1 comment

Patchset-level comments
File-level comment, Patchset 6 (Latest):
Kyle Charbonneau . resolved

I'm going to be OOO so removing myself from reviewer.

Open in Gerrit

Related details

Attention is currently required from:
  • Kramer Ge
  • Mitchell Cohen
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: I54dac094fc1f5e3666883dd56eef1af17e2acfe6
Gerrit-Change-Number: 7979228
Gerrit-PatchSet: 6
Gerrit-Owner: Mitchell Cohen <mitc...@agilebits.com>
Gerrit-Reviewer: Kramer Ge <fang...@chromium.org>
Gerrit-CC: Ian Vollick <vol...@chromium.org>
Gerrit-CC: Kramer Ge <fang...@google.com>
Gerrit-CC: Kyle Charbonneau <kyle...@chromium.org>
Gerrit-Attention: Mitchell Cohen <mitc...@agilebits.com>
Gerrit-Attention: Kramer Ge <fang...@google.com>
Gerrit-Comment-Date: Fri, 26 Jun 2026 19:27:02 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
satisfied_requirement
unsatisfied_requirement
open
diffy

Mitchell Cohen (Gerrit)

unread,
Jun 28, 2026, 12:49:18 PM (17 hours ago) Jun 28
to Kyle Charbonneau, Kramer Ge, chromium...@chromium.org, Ian Vollick, cc-...@chromium.org, chromium-a...@chromium.org, extension...@chromium.org, jbauma...@chromium.org, max+watc...@igalia.com, nickdiego+wa...@igalia.com, ozone-...@chromium.org
Attention needed from Kramer Ge

Mitchell Cohen added 1 comment

Patchset-level comments
Mitchell Cohen . unresolved

Closing in favour of crrev.com/c/8015303

Open in Gerrit

Related details

Attention is currently required from:
  • Kramer Ge
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: I54dac094fc1f5e3666883dd56eef1af17e2acfe6
Gerrit-Change-Number: 7979228
Gerrit-PatchSet: 6
Gerrit-Owner: Mitchell Cohen <mitc...@agilebits.com>
Gerrit-Reviewer: Kramer Ge <fang...@chromium.org>
Gerrit-CC: Ian Vollick <vol...@chromium.org>
Gerrit-CC: Kramer Ge <fang...@google.com>
Gerrit-CC: Kyle Charbonneau <kyle...@chromium.org>
Gerrit-Attention: Kramer Ge <fang...@google.com>
Gerrit-Comment-Date: Sun, 28 Jun 2026 16:49:11 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
satisfied_requirement
unsatisfied_requirement
open
diffy

Mitchell Cohen (Gerrit)

unread,
Jun 28, 2026, 12:49:34 PM (17 hours ago) Jun 28
to Kyle Charbonneau, Kramer Ge, chromium...@chromium.org, Ian Vollick, cc-...@chromium.org, chromium-a...@chromium.org, extension...@chromium.org, jbauma...@chromium.org, max+watc...@igalia.com, nickdiego+wa...@igalia.com, ozone-...@chromium.org

Mitchell Cohen abandoned this change.

View Change

Abandoned Replaed by crrev.com/c/8015303

Mitchell Cohen abandoned this change

Related details

Attention set is empty
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • 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: abandon
satisfied_requirement
unsatisfied_requirement
open
diffy
Reply all
Reply to author
Forward
0 new messages