Disclosure Statement: This site contains affiliate links, which means that I may receive a commission if you make a purchase using these links. As an eBay Partner, I earn from qualifying purchases.

OffScreen invalidation logic

Post Reply
maxedi
Posts: 5
Joined: Fri Mar 27, 2020 7:44 am

OffScreen invalidation logic

Post by maxedi »

Hi,

I used the code from the sample about offscreen rendering in my own controls. Bascially when the Resize comes, I change the buffer size, call WasResized and instantly Invalidate(PET_VIEW). It works more or less until some complex cases when, for example, two consecutive requests try to change some of the dimensions (Width:=; Height:=). The final result looks like the CEF didn't catch the second one so the rendering size looks like it did not catch the second size change. The sample CEF4 application about off-screen rendering on the other hand correctly works in similar cases but I found hard to grasp the complex logic behind several flags (FResizing, FPendingResize), reposting messages from the paint thread to repeat resize request and delaying calling Invalidate(PET_VIEW) until some good moment. I suspect that this has something to do with how CEF itself handles border cases so the CEF4 developers had to implement "not so easy to grasp" code. Can this be explained more clearly at least what objective this complex logic tries to reach?

Thanks
User avatar
salvadordf
Posts: 4052
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: OffScreen invalidation logic

Post by salvadordf »

Hi,

Chromium renders the web contents asynchronously. It uses multiple processes and threads which makes it complicated to keep the correct browser size.

In one hand you have the main application thread where the form is resized by the user. On the other hand, Chromium renders the contents asynchronously with the last browser size available, which may have changed by the time Chromium renders the page.

For this reason we need to keep checking the real size and call TChromium.WasResized when we detect that Chromium has an incorrect size.

TChromium.WasResized triggers the TChromium.OnGetViewRect event to let CEF read the current browser size and then it triggers TChromium.OnPaint when the contents are finally rendered.

Code: Select all

TChromium.WasResized --> (time passes) --> TChromium.OnGetViewRect --> (time passes) --> TChromium.OnPaint
You have to assume that the real browser size can change between those calls and events.

I used a couple of fields called "FResizing" and "FPendingResize" to reduce the number of TChromium.WasResized calls.
  • FResizing is set to True before the TChromium.WasResized call and it's set to False at the end of the TChromium.OnPaint event.
  • FPendingResize is set to True when the browser changed its size while FResizing was True. The FPendingResize value is checked at the end of TChromium.OnPaint to check the browser size again because it changed while Chromium was rendering the page.
The TChromium.OnPaint event in the demo also calls TBufferPanel.UpdateBufferDimensions and TBufferPanel.BufferIsResized to check the width and height of the buffer parameter, and the internal buffer size in the TBufferPanel component.

The TBufferPanel.OnWrongSize is redundant and it will probably be removed or updated in future CEF4Delphi versions. TBufferPanel.BufferIsResized does the same but better.
maxedi
Posts: 5
Joined: Fri Mar 27, 2020 7:44 am

Re: OffScreen invalidation logic

Post by maxedi »

salvadordf, thanks for this detailed explanation. I decoded some of the logic myself and glad that it is in sync with the author's thoughts.
I also noticed some pecularities, I can not undestand:
  • I tried a workaround when I programmatically make an extra call to WasResized, but the view stayed the same. So even when all the drawings done and the buffer could not accept both changes (Width:=, Height:=), the call to WasResized didn't manager to force CEF into new size. It seemed like there are incorrectly (not completely) accepted new size and because my extra WasResized leads to the same responded View Size, nothing is repainted. Are you sure WasResized doesn't use some internal comparison in order to avoid unnecessary actions in case of (from its point of view) nothing changed?
  • What is the Invalidate(PET_VIEW) call is for? When I comment this call, everything seems to work as exected, maybe some drawing issues, but nothing game changing.
User avatar
salvadordf
Posts: 4052
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: OffScreen invalidation logic

Post by salvadordf »

maxedi wrote: Fri Mar 27, 2020 3:43 pm I tried a workaround when I programmatically make an extra call to WasResized, but the view stayed the same. So even when all the drawings done and the buffer could not accept both changes (Width:=, Height:=), the call to WasResized didn't manager to force CEF into new size. It seemed like there are incorrectly (not completely) accepted new size and because my extra WasResized leads to the same responded View Size, nothing is repainted. Are you sure WasResized doesn't use some internal comparison in order to avoid unnecessary actions in case of (from its point of view) nothing changed?
The OSR mode still has some issues in the CEF libraries, specially when you enable hardware acceleration with GlobalCEFApp.EnableGPU and you use a high DPI monitor.
https://bitbucket.org/chromiumembedded/ ... y-not-draw
https://bitbucket.org/chromiumembedded/ ... le-onpaint

I've also noticed that some calls to "WasResized" don't trigger the TChromium.OnGetViewRect event and the web page is not resized to the new dimensions.
maxedi wrote: Fri Mar 27, 2020 3:43 pmWhat is the Invalidate(PET_VIEW) call is for? When I comment this call, everything seems to work as exected, maybe some drawing issues, but nothing game changing.
The SimpleOSRBrowser demo calls Invalidate(PET_VIEW) to trigger the TChromium.OnPaint event and refresh the bitmap buffer. As you say, it refreshes the screen to remove those graphic glitches.
User avatar
salvadordf
Posts: 4052
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: OffScreen invalidation logic

Post by salvadordf »

Please, download CEF4Delphi again.

The OSR demos now include a workaround for this resize issue :
https://github.com/salvadordf/CEF4Delphi/issues/271
Post Reply