Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

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

[Question] CanvasVirtualControl, flickering while unzooming #918

Open
leoshusar opened this issue May 1, 2023 · 2 comments
Open

[Question] CanvasVirtualControl, flickering while unzooming #918

leoshusar opened this issue May 1, 2023 · 2 comments

Comments

@leoshusar
Copy link

Hi! I asked this on r/csharp this exact question but nobody helped there, I think the right people haven't seen it.
I'm building an app using WinUI 3 and Win2D and I'm using CanvasVirtualControl, because I need to zoom quite a lot. I'm drawing only shapes like polygons using Win2D geometry methods.

I looked at the official Win2D Gallery Mandelbrot example and implemented zooming like there. That means in ScrollViewer_ViewChanged I'm recalculating DPI scale and setting it to canvas.

However when I'm unzooming (smooth unzoom) those new regions are "flickering". See here:

Recording.2023-04-28.141810.mp4

This is how I'm changing the DPI:

private void PolygonCanvasScrollViewer_ViewChanged(object? sender, ScrollViewerViewChangedEventArgs? e)
{
    var dpiAdjustment = BaseCanvasDpi / _displayDpi;
    var dpiScale = PolygonCanvasScrollViewer.ZoomFactor * dpiAdjustment;

    var ratio = PolygonCanvasControl.DpiScale / dpiScale;

    if (e is null or { IsIntermediate: false } || ratio is <= 0.95f or >= 1.05f)
    {
        PolygonCanvasControl.DpiScale = dpiScale;
    }
}

First I thought my Draw method is too slow, but it takes at most 3 milliseconds, usually 0 or 1.

Then I thought maybe I should be changing the DPI more often, but when I changed it like ratio is <= 0.99f or >= 1.01f, it became even worse. Now even already visible regions are flickering.

And when I remove it completely and change the scale only when IsIntermediate: false, I still see new regions appearing "line by line".

Recording.2023-04-28.145345.mp4

Since my canvas size can be up to 3000 x 3000 and I need at least 12x zoom, I really need to render only the necessary part of it. I was playing with rendering bigger part (calculate the region of all currently visible geometries) and I accidentally managed to freeze my computer for 5 minutes when it filled my whole RAM and GPU memory lol.

What would be the "easiest" way to make it look better?

@asierpn
Copy link

asierpn commented May 10, 2023

We have a similar problem when changing the ScrollViewer's content size very quickly, for some reason the invalidated region is not the whole visible height, so flickering appears in the bottom region of the canvas. It seems to be a bug when determining the invalidated region.

You can see it more clearly if you replay your video step by step or trace the invalidated region while zooming, while the top part was invalidated, the bottom part was not.

image

@asierpn
Copy link

asierpn commented May 15, 2023

I think this issue is the same latency issue commented here: #125, when the scrollviewer content size is changed quickly some calls to RegionsInvalidated do not have the correct region.

We get rid of this problem by putting the CanvasVirtualControl outside the ScrollViewer and handling the scroll view changes manually.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants