High DPI Window Size Discrepancy

I’m getting inconsistent window size on HTML5 build when High dpi option is turned on.

Attached is a minimal sample:
WindowSize.zip (208.1 KB)

Tested on Windows 10, Google Chrome (1.2.165 and 1.2.166 beta, same results):
html5 high dpi OFF: reported size is 1280x720
html5 high dpi ON: reported size is 1548x871 (which is approx 1.209x the original size)

Is this expected behavior? Scale mode is default: downscale fit.

Note that the GUI’s adjust reference has been disabled. There’s also different results in the background image inside the gui:
html5 high dpi OFF: the gui background shows exactly 1280x720 of the image only (but there appears to be some scaling going on)
html5 high dpi ON: the gui background shows more of the background, with no scaling whatsoever, which I think is the expected behavior when adjust reference is disabled?

Thoughts?

Use case is filling a gui with a seamless background, which involves cloning a small node to fill up the entire screen based on window size, so the node itself shouldn’t be resized. This used to worked fine on 1.2.163, then it got broken starting on 1.2.164 (when WINDOW_EVENT_RESIZED is not being fired anymore until an actual browser resize happens).

1 Like

It’s not just HTML5. I’ve run into the same thing with a standard Windows build. I’d like to know why this is as well. We probably don’t understand exactly what high dpi is or how it works.

As far as I know this wasnt changed in 1.2.164: Defold 1.2.164 has been released

Can you share a project where this happens?

It’s not listed, but it did change on 1.2.164. Just re-tested this code:

local function window_callback (self, event, data)
	if (event == window.WINDOW_EVENT_RESIZED) then
		print ('CALLBACK SIZE', data.width, data.height)
	end
end

function init (self)
	window.set_listener (window_callback)
end

Windows 10, html5 build. On 1.2.163 you will get a callback immediately. On 1.2.164 onwards, you will not get the initial callback, but it will get called (as expected) whenever you resize the browser manually.

I asked about it here before:

There’s window.get_size() now that ‘fixes’ that part of the problem though.

On HTML5 (with the scale mode you’ve chosen) you will get a canvas that is scaled to fill as much of the available space in the browser window while maintaining aspect ratio. In Chrome I see that the reported size is twice that of the actual size of the canvas:

@AGulev Can you confirm the settings and expected behaviour please?

Yes, everything is right.
In this example, we use scale mode Downscale Fit or Fit, that’s why we have such a strange size (x1.209)

Does this mean we should expect different values from window.get_size() depending on whether high dpi is on/off?

The canvas will initially be given the size set in game.project but depending on the scale mode it might get scaled to fit inside the available space. This means that the size may differ from what you have in game.project. This will happen regardless of high dpi or not.

1 Like

I understand that the window size can change depending on the browser size. However, in this instance the game project size and scale mode remain the same. It’s also the same browser window size, so if the canvas is supposed to fill the browser window, it shouldn’t matter if high dpi is on or not(?) but it does.

dpi on:

dpi off:

If I measure the canvas size that defold is taking up, it’s actually the same for both (1548x871 in my case). That’s the actual pixel dimensions in both screen shots. Yet, the reported size for high dpi off is 1280x720 only (even if the canvas size is 1548x871).

There’s also scaling differences when high dpi is on/off.
ON: more squares are shown, squares are not resized (gui adjust reference is disabled), reported size is 1548x871
OFF: less squares are shown, squares have been resized, reported size is 1280x720 even if the actual canvas size is 1548x871

And the only thing that has changed is whether high dpi is on or off.

I’m probably misunderstanding some things regarding high dpi being on or off… so I will just try to fix things on my end (if I can). Thanks for taking time to look at it though.

Can you add listener for the resized event? If not already. https://defold.com/ref/window/#window.set_listener:callback
And see what numbers does it show.

1 Like

Using this code:

local function window_callback (self, event, data)
	if (event == window.WINDOW_EVENT_RESIZED) then
		print ('CALLBACK SIZE', data.width, data.height)
		local vWidth, vHeight = window.get_size()
		print ('WINDOW SIZE', vWidth, vHeight)
	end
end

function init()
	window.set_listener (window_callback)
	pprint (window.get_size())
end

high dpi off:

high dpi on:

Running 2 different versions on the same browser but different tabs, then resizing the browser manually to trigger the calls, the callback size and window size will actually be the same. But the values between the 2 tabs are different (1st shot is dpi off, 2nd shot is dpi on). Scaling result is also different between them (again, same browser size, same scaling mode, just the difference being high dpi is on or off).

For both versions, the actual defold canvas size in pixels (even if you measure it from the screen shots) are actually the same, but what’s reported and what happens with scaling are different results, which is what’s confusing me because all parameters have been kept the same (except high dpi on or off) but I am getting different results.

Here’s the updated test project if anyone wants to take a look further. You can toggle high dpi on/off to see the difference in html5 output.

WindowSize2.zip (209.8 KB)

Bumping this as I am still experiencing the same issue.

Below is a simpler repro case. Tested on Windows 10, run via Project/Build HTML5.

Game Project:
Display Width = 640
Display Height = 360
HTML5 Scale Mode: No Scale

Expected results: window size should be 640x360 always (because of No Scale setting)
Current results:
high dpi OFF: window size is 640x360 (correct)
high dpi ON: window size is always bigger (like the canvas has been magnified by a certain factor)

I am printing the reported window size in the console. Since this is no-scale, shouldn’t the window size remain the same?

html5_fit.zip (624.7 KB)

1 Like

NOTE: the actual canvas size if I measure in photoshop is actually always bigger (zoomed) in my tests. However, the reported width/height by window.get_size() will vary depending on whether high dpi is on or off.

Pics for reference:


So there are 2 potential issues here:

  1. Despite specifying No Scale, the html5 canvas size is actually bigger.
  2. The reported window size varies depending on the high dpi setting.

Hi, yes, it seems like 2 separate issues.
Let’s start with the first one.
Could you please open and build this project and show me your console result:
html5_no_scale.zip (633.7 KB)
Also, please make sure your zoom settings for the page is 100%

1 Like

Yes, I also just realized that my zoom page was 110% (sorry about that).

I was doing tests with zoom page=100%, but the canvas pixel size is still bigger (exactly 10% more).

I tried your test project, here are the results:

High dpi on (Chrome):

DEBUG:SCRIPT: WINDOW SIZE	w=704	h=396
DEBUG:SCRIPT: devicePixelRatio	1.100000023841858

High dpi off (Chrome):

DEBUG:SCRIPT: WINDOW SIZE	w=640	h=360
DEBUG:SCRIPT: devicePixelRatio	1.100000023841858

For Microsoft Edge (both high dpi on/off):

DEBUG:SCRIPT: WINDOW SIZE	w=640	h=360
DEBUG:SCRIPT: devicePixelRatio	1

So there’s actually no issue with Edge! Canvas pixel size was also correct there when I measured.

Is this just an incorrect Chrome setting on my end then?

It seems like in Chrome you still have 110% zoom.
Try to change init() method to update() and make sure you have zoom 100%.
(using init(), you need to change zoom before the test, but with update, it’s not necessary you will see all the changes.)

Yes it’s already at 100% only.

If I have it at 110%, the results would be:

DEBUG:SCRIPT: WINDOW SIZE	w=640	h=360
DEBUG:SCRIPT: devicePixelRatio	1.2100000381469727

so device pixel ratio is 10% more again (of 110% this time).