添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement . We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What is the expected output? What do you see instead?
There are some glitches when resizing that aren't present when testing with cefclient

Please provide any additional information below.
DPI scale 150%

Does this problem also occur in the CEF Sample Application
No. The CEF Sample application isn't perfect when resizing, there's plenty of times the outer border is blank waiting for the image to resize correctly. The glitches aren't present to the same degree though.

Integrating CEF into the WPF message loop also appears to eliminate the glitches. Further debugging required.

Set multiThreadedMessageLoop = false in the example at https://github.com/cefsharp/CefSharp/blob/cefsharp/83/CefSharp.Wpf.Example/App.xaml.cs#L28

Resize was causing glitches, doesn't reproduce with cefclient
Needs further investigation.
Revert to disabling GPU compositing
Issue #3114
Resize was causing glitches, doesn't reproduce with cefclient
Needs further investigation.
Revert to disabling GPU compositing
Issue #3114

Any update on this bug? I've found that CefSharp 79+ causes significant rendering artifacts when resizing a window. I get the same behavior with or without the --disable-gpu-compositing flag. example:

I can confirm that integrating cef into the wpf message loop gets rid of the rendering issues, but I am unable to do that in my usage of cefsharp as it causes some other issues.

I am able to update my application to 75.1.143 (from 67.0.0) without experiencing this rendering issue. Any higher version and this issue starts occurring.

I would really like to take the latest cefsharp version, as it has a fix for a css grid layout bug that occurs when viewing a page using cefsharp that doesn't occur in browsers ( https://bugs.chromium.org/p/chromium/issues/detail?id=1051039 ). This resize bug is the only issue currently blocking me from taking latest.

What command line args did you tested with?

The second animated gif where the scroll bar disappears and a black box occurs is more than likely a problem with the CEF OSR implementation, we're simplify rendering every frame we're given. Dumping each frame to disk in OnPaint and you should get a better understanding of what the output is.

I don't have any insight into what is causing the initial glitching, the rendering implementation hasn't changed in a long time, something changed in CEF/Chromium.

Resolving whatever issues you have integrating CEF into your apps existing message is possibly the simplest option. Though if you have time by all means have a go at debugging.

You can view the cefclient source on GitHub.
https://github.com/chromiumembedded/cef/blob/8a055593d694b386f46530f81f53ed8b7c5ea284/tests/cefclient/browser/osr_renderer.cc#L280

The CefSharp rendering implentations are in https://github.com/cefsharp/CefSharp/tree/master/CefSharp.Wpf/Rendering
InteropBitmapRenderHandler is used when DPI is 100%
WritableBitmapRenderHandler is used when DPI is greater than 100%
DirectWritableBitmapRenderHandler is used when CEF is integrated into existing message loop.
There are some experiments You can try if you have time.

I've confirmed that this isn't a rendering issue in cef. I updated InteropBitmapRenderHandler to dump each frame to disk. Looking at the images that it output, they had no visual artifacts even though I was seeing the same tearing in the app while resizing.

I also found that forcing the ChromiumWebBrowser to use either the WriteableBitmapRenderHandler or the CompositionTargetRenderHandler under experiments would render without any visual artifacts when resizing.

Looking at the history of InteropBitmapRenderHandler, I found that this resize issue was introduced in this commit - an optimization to only create a new memory mapped file if the current file is smaller than the space needed. I've found that if I change

if (viewAccessor == null || viewAccessor.Capacity < numberOfBytes)
    ReleaseMemoryMappedView(ref mappedFile, ref viewAccessor);
    mappedFile = MemoryMappedFile.CreateNew(null, numberOfBytes, MemoryMappedFileAccess.ReadWrite);
    viewAccessor = mappedFile.CreateViewAccessor();
if (viewAccessor == null || viewAccessor.Capacity < numberOfBytes || currentSize.Width != width)
    ReleaseMemoryMappedView(ref mappedFile, ref viewAccessor);
    mappedFile = MemoryMappedFile.CreateNew(null, numberOfBytes, MemoryMappedFileAccess.ReadWrite);
    viewAccessor = mappedFile.CreateViewAccessor();

it resolves the issue.

before:

after:

I've spent a fair amount of time trying to figure out why reusing the larger memory mapped file for a smaller image is causing this tearing when the width of the image changes, but I'm at a loss.

InteropBitmap is strangely glitching on resize when reusing the same buffer as detailed in #3114 (comment)
Go back to the old method approach of creating a new buffer for every resize operation.
Revert part of commit b1bd749#diff-10ce38e86ac5782d06a15b191dc6216fd098f3e23fe1fa88b3711761d8944055
InteropBitmapRenderHandler will no longer be the default shortly.
Issue #3114
- No longer use InteropBitmapRenderHandler as the default (InteropBitmap doesn't support DPI scaling).
- Remove old IncreaseBufferInteropRenderHandler as reusing the buffer causing glitching as detailed in #3114 (comment)
Issue #3114

Looking at the history of InteropBitmapRenderHandler, I found that this resize issue was introduced in this commit - an optimization to only create a new memory mapped file if the current file is smaller than the space needed. I've found that if I change

Reverted in commit a8119cc a new buffer will be created for every resize (as was previously done)

Subsequently commit 59b8e7f removes the use of InteropBitmapRenderHandler and defaults to WritableBitmapRenderHandler for MultiThreadedMessageLoop = true (the default). At some point I'll add support for notifying an IRenderHandler of a DPI change, so this was something I had planned.

InteropBitmapRenderHandler still exists and can be specified by the user if required.

I've spent a fair amount of time trying to figure out why reusing the larger memory mapped file for a smaller image is causing this tearing when the width of the image changes, but I'm at a loss.

Interestingly I did a quick check at 100% DPI and saw only very very rare glitching with disable-gpu-compositing set (default) nothing like the image you have provided, so there's likely some other environmental factors that exacerbate the problem.

When I remove disable-gpu-compositing I still see glitching until I set WritableBitmapRenderHandler to create a new buffer on each resize (effectively reverting b1bd749).

Doesn't make sense yet, at least it gives some further avenues of investigation. Thanks for your help @rstedman

Copying the data directly into the BackBuffer instead of calling WritePixels still has the same glitching.

// Update whole bitmap
var sourceRect = new Int32Rect(0, 0, width, height);
bitmap.Lock();
NativeMethodWrapper.MemoryCopy(bitmap.BackBuffer, sourceBuffer.DangerousGetHandle(), noOfBytes);
bitmap.AddDirtyRect(sourceRect);
bitmap.Unlock();
A port of WritableBitmapRenderHandler to use Marshal.AllocHGlobal instead of MemoryMappedFile
Remove disable-gpu-compositing command line arg
Resovles #3114
InteropBitmap is strangely glitching on resize when reusing the same buffer as detailed in #3114 (comment)
Go back to the old method approach of creating a new buffer for every resize operation.
Revert part of commit b1bd749#diff-10ce38e86ac5782d06a15b191dc6216fd098f3e23fe1fa88b3711761d8944055
InteropBitmapRenderHandler will no longer be the default shortly.
Issue #3114
- No longer use InteropBitmapRenderHandler as the default (InteropBitmap doesn't support DPI scaling).
- Remove old IncreaseBufferInteropRenderHandler as reusing the buffer causing glitching as detailed in #3114 (comment)
Issue #3114

In version 86 we'll default to WritableBitmapRenderHandler and leave GPU Compositing disabled. InteropBitmapRenderHandler will create a new buffer on resize relevant commits c04c20f and da918d6

Commit fb289d4 switches to using Marshal.AllocHGlobal instead of MemoryMappedFile which appears to resolve the issue. A sample size of one isn't very conclusive so I've enabled by default and will try to test on a few different machines before release. The user can switch to the original WritableBitmapRenderHandler if there are any problems.

If I understand correctly it sounds like you'd be holding reference to memory unnecessarily, perhaps I'm not understanding correctly. You are welcome to submit a PR for review.

The current plan for DPI scaling is to reuse the same buffer regardless of scale. If you need a fine level of control over memory allocations then you can of course implement IRenderHandler

@amaitland Found reason of bug.
I assumed that second CreateOrUpdateBitmap can be raised before first Dispatcher operation is processed.
Now mmf contains new (2nd data), but dispatcher operation uses captured by lambda old parameters (in my case dirty rect).
After i programmatically found this reason (by ids) as i thought i saved image and it was i expected.
Second try

Also, my suggestion about scaled increasing does not apply in any way for "dpi", only reducing of allocates.

Now mmf contains new (2nd data), but dispatcher operation uses captured by lambda old parameters (in my case dirty rect).

Thanks for the feedback, makes sense. That should be easily fixable.

Also, my suggestion about scaled increasing does not apply in any way for "dpi", only reducing of allocates.

@timaiv I'll be honest I find your comments in general very cryptic and lacking in details. I mean no offence by this, I'd just really appreciate it if you'd add more detail. Input is welcomed, it would make my life easier if you'd submit a pull request with your proposed changes, then we have something concrete to discuss.

Now mmf contains new (2nd data), but dispatcher operation uses captured by lambda old parameters (in my case dirty rect).

This occurred to me as well. However, I tried making the dispatch synchronous (dispatcher.Invoke instead of dispatcher.BeginInvoke) as a quick test, but I still experienced the resize issue.

- Remove disable-gpu-compositing command line arg
- WritableBitmapRenderHandler/InteropBitmapRenderHandler ignore update if size doesn't match
It's possible that OnPaint is called multiple times before our BeginInvoke call is marshalled onto the UI Thread.
In those cases we check width/height and ignore the call if it doesn't match
Issue #3114
- WritableBitmapRenderHandler/InteropBitmapRenderHandler ignore update if size doesn't match
It's possible that OnPaint is called multiple times before our BeginInvoke call is marshalled onto the UI Thread.
In those cases we check width/height and ignore the call if it doesn't match
Issue #3114
- WritableBitmapRenderHandler/InteropBitmapRenderHandler ignore update if size doesn't match
- Revert back to using WritableBitmapRenderHandler as the default implementation
- CompositionTargetRenderHandler only update bitmap if buffer is dirty
- AllocHGlobalWritableBitmapRenderHandler only update bitmap if buffer is dirty
It's possible that OnPaint is called multiple times before our BeginInvoke call is marshalled onto the UI Thread.
In those cases we check width/height and ignore the call if it doesn't match
Issue #3114

This should now be resolved in commit b24efd2

Version 86 branch specific changes (commit a83dbc2)

The disable-gpu-compositing command line arg has now been removed.

BeginInvoke calls will now check the size and the call will be ignored if it doesn't match, this should result in slightly improved performance.

If anyone would like to test this out you can download a nightly build from https://www.myget.org/feed/cefsharp/package/nuget/CefSharp.Wpf

- WritableBitmapRenderHandler/InteropBitmapRenderHandler ignore update if size doesn't match
It's possible that OnPaint is called multiple times before our BeginInvoke call is marshalled onto the UI Thread.
In those cases we check width/height and ignore the call if it doesn't match
Issue cefsharp#3114