cef icon indicating copy to clipboard operation
cef copied to clipboard

osr : Browser not correctly refreshing on Resize in CEF 129

Open Hethsron opened this issue 1 year ago • 6 comments

Describe the bug The bug was clearly described in the following post and the following issue

Screenshots For more details, see the video

Expected behavior When the window size is resized, the view should normally be refreshed.

Versions

  • OS: Windows 10, MacOS
  • CEF Version: 129.0.6668.90

Hethsron avatar Nov 08 '24 22:11 Hethsron

Duplicate of #3822.

magreenblatt avatar Nov 08 '24 22:11 magreenblatt

You say:

with the CEF sample cefclient --off-screen-rendering-enabled --multi-threaded-message-loop it does not reproduce the issue because CefRefPtr<CefBrowserHost>::WasResized is still called in the CEF_UIT thread so there is no task posted, the work is executed synchronuously.

This suggests that your timing of calling WasResized and returning updated values from GetViewRect may be incorrect. You need to make sure that GetViewRect is returning the correct value when WasResized actually executes.

magreenblatt avatar Nov 08 '24 22:11 magreenblatt

@magreenblatt Thanks for your quick answer. But after a huge debug session in our side, there is something strange which happens in cef, you can reproduice easily with your cefclient. (see https://magpcss.org/ceforum/viewtopic.php?f=6&t=20038&p=56405&hilit=CEF129#p56405)

Hethsron avatar Nov 13 '24 11:11 Hethsron

Reopening this issue as it seems unrelated to navigation.

magreenblatt avatar Dec 10 '24 14:12 magreenblatt

I can confirm this is a bug, after calling WasResized there is no the expected callback of CefRenderHandler::GetViewRect.

Starts from CEF 127

tishion avatar Feb 01 '25 03:02 tishion

I ran into this problem, since we use --off-screen-rendering-enabled and --enable-gpu. After debugging, here is my understanding of the problem:

Context in Chromium code:

  • From the GPU process, FrameSinkVideoCapturerImpl::MaybeDeliverFrame is called for each frame that will eventually turn into an OnPaint callback.
  • However, it is expected that some frames get dropped. In this event MaybeScheduleRefreshFrame is called. And presumably the expectation is that results in a successful frame delivery.
  • However, this code appears to have an expectation mismatch / bug. In the event of an unsuccessful / dropped frame, the code does not call CompleteCapture. This is the only place the oracle decrements the number of pending frames. (not including "stop rendering" / reset scenarios).
  • The allowance for tracked pending frames to remain > 0 results in kRefreshRequest refreshes to never result in a frame capture.
  • After a frame has been dropped, these refresh requests stop doing anything and the GPU process is stuck in a loop (timer triggered, not synchronous) of scheduling a capture and deciding not to capture.
  • The kRefreshDemand and kCompositorUpdate (dirty rects) will cause a successful re-render.

Context in CEF code:

  • If the dropped frame was the new size, and a resize hold is active for the size, we won't get an OnPaint callback for that size until either a kRefreshDemand or kCompositorUpdate refresh is triggered.
  • WasResized will do nothing, since the resize hold is active.
  • Invalidate(CefPaintElementType.View) will trigger kRefreshDemand which will result in OnPaint and release the resize hold.

In summary, it's a combination of:

  • CEF's resize hold behavior
  • FrameSinkVideoCapturerImpl dropping frames and not accounting for those drops in VideoCaptureOracle

randymarsh77 avatar Feb 26 '25 18:02 randymarsh77