Strange aspect of Skia renderer bounds / How to set renderer to exact size and pos in pixel?

Currently trying to set the skia-renderer position and scale inside the patch.

First thing, I do not get: What is the unit of the width/height-settings rectangle? Can’t be pixel, since my screen is 4k and the renderer is bigger than 100px. One guess could be, that it’s somehoe scaled by windows-scaling settings? Or is it something else?

Second problem: Setting the rectangle to an square (fe. 100 by 100) results in an rectangle but not a perfect square. 100 by 170 gives me in my case a square. Which let me guess, it’s also relative to my resolution aspect (16:9). But why? Shouldn’t it be absolute in pixel no mater which aspect my resolution has.

Did anyone tried the same already and found a solution to set the window to an exact position and scale in pixel?

Doodled a little. Seems to work, but needs some magic numbers I can’t explain.

HowTo set render window size in pixels.vl (44.2 KB)

1 Like

Ha, great! I see many interesting nodes in your patch. :)

I did another version without any borders and without titlebar. in this case everything works as expected without further adding of magic numbers.

Only problem left: because my scaling factor is 1.5 I end up with after-comma-rounding-issue. but tried it with 100% and this was fine. Needed to restart gamma to get the correct new scaling value after changing this in the windows-display-settings.

HowTo set render window size in pixels.vl (49.3 KB)

Tested only with 2560x1440 and 125%.

Not sure if this will return the correct result when the screens don’t have the same resolution and scaling settings:

Unfortunately VL.Skia isn’t open source. But I took a peek at VL.Skia.dll to see what SetSize [Graphics.Skia.SkiaRenderer] is doing.

public void SetSize(Rectangle boundsInDIP)
      Rectangle boundsinPix = DIPHelpers.DIPToPixel(boundsInDIP);
      if (!((IEnumerable<Screen>) Screen.AllScreens).Any<Screen>((Func<Screen, bool>) (s => s.Bounds.IntersectsWith(boundsinPix))))
        boundsInDIP = SkiaRenderer.GetCenteredBoundsInDIP(boundsInDIP.Width, boundsInDIP.Height);
        boundsinPix = DIPHelpers.DIPToPixel(boundsInDIP);
      if (!(boundsinPix != this.Bounds))
      this.Bounds = boundsinPix;

Turns out there is already a class called DIPHelpers (inside VL.UI.Core.dll). So If you reference it you can just use the helpers.

It basically does the same as I did here:

public static float DIPFactor()
      if ((double) DIPHelpers.FDIPFactor == -1.0)
        using (Graphics graphics = Graphics.FromHwnd(IntPtr.Zero))
          DIPHelpers.FDIPFactor = graphics.DpiX / 96f;
      return DIPHelpers.FDIPFactor;

From what I can tell it might also fail when having multiple screens with different scaling settings (and/or resolutions).

Also since some pixel values cannot be set when using fractional scaling and DIP, it would be nice to have something like SetSize(Rectangle boundsInPixel).

HowTo set render window size in pixels 2.vl (40.6 KB)


Sorry for the silence. VL.Skia recently got some love and now upcoming builds will have a node SetBounds that allows setting the size in pixels.

This operation can be connected to the Renderer node like so:

The rectangle type is the standard Stride rectangle.
The white Input pin “Bounds” for now still is the System.Drawing.Rectangle.

I also added an experimental node “RenderWindow”, that has a Stride Rectangle Bounds input pin. But probably you don’t need this as you want to set the size manually. Right?


This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.