easier way to ignore DPI on android?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
User avatar
eouppdru
Prole
Posts: 10
Joined: Tue Feb 20, 2018 3:39 pm

easier way to ignore DPI on android?

Post by eouppdru » Sun Jan 06, 2019 5:35 am

apparently as of love 11.0, love for android has DPI scaling on at all times, even when disabled in conf.lua. so if I create a 1920x1080 canvas for my game, it will fail with "Cannot create texture: pixel width of 6727 is too large for this system"
I much prefer just setting pixel sizes manually, and I don't want to add {dpiscale=1} to the end of every single canvas I create, lest I forget it once and get subtle scaling problems or have another crash on android that's hard to debug in addition to the unnecessary clutter that makes adhering to 80 columns more of a chore. at first my canvases were small enough to be below 4096 pixels when scaled, but I couldn't figure out why several shader effects were wrong and the performance was so bad. turns out 800x480 was getting scaled to about 2800x1680.
so is there any way to just disable all the DPI stuff on android?
PGP: 9D05F9CC4FB3DEA617ADCDDA355A9D99CBE1CC1B

Nelvin
Citizen
Posts: 80
Joined: Mon Sep 12, 2016 7:52 am
Location: Germany

Re: easier way to ignore DPI on android?

Post by Nelvin » Sun Jan 06, 2019 9:08 am

Just redefine the newCanvas function to fit your needs (you may add a OS check for Android or whatever else you need)

Code: Select all

do
    local originalNewCanvas = love.graphics.newCanvas
    love.graphics.newCanvas = function( width, height )
        return originalNewCanvas( width, height, { dpiscale = 1 } )
    end
end

User avatar
eouppdru
Prole
Posts: 10
Joined: Tue Feb 20, 2018 3:39 pm

Re: easier way to ignore DPI on android?

Post by eouppdru » Sun Jan 06, 2019 3:00 pm

Nelvin wrote:
Sun Jan 06, 2019 9:08 am
Just redefine the newCanvas function to fit your needs (you may add a OS check for Android or whatever else you need)
I guess that works, though drawing directly to the screen still uses weird coordinates that think my screen is 731x411, and using love.window.toPixels/fromPixels on coordinates makes the screen look like... 2558.5 x 1438.5.
but at least for this game that works after a few fixes, just another thing to add to the top of every main.lua project.
thanks for the snippet, I tried the same earlier but didn't know you needed to define it as a local variable first.
PGP: 9D05F9CC4FB3DEA617ADCDDA355A9D99CBE1CC1B

User avatar
pgimeno
Party member
Posts: 1686
Joined: Sun Oct 18, 2015 2:58 pm

Re: easier way to ignore DPI on android?

Post by pgimeno » Sun Jan 06, 2019 9:03 pm

eouppdru wrote:
Sun Jan 06, 2019 3:00 pm
but at least for this game that works after a few fixes, just another thing to add to the top of every main.lua project.
I'm frustrated by this as well. Wish it could be disabled (or set to 1:1), at least in config.lua. It feels like instead of having love.physics.setMeter(), you had a fixed arbitrary manufacturer-set unit factor that you can't change.
Last edited by pgimeno on Mon Jan 07, 2019 12:33 am, edited 1 time in total.

User avatar
slime
Solid Snayke
Posts: 2820
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

Re: easier way to ignore DPI on android?

Post by slime » Mon Jan 07, 2019 12:06 am

It's not arbitrary, your OS and device manufacturer chose it for all apps and they expect your app to respect it as well. It also allows your app to look consistent across different devices with different DPI scale factors.

User avatar
pgimeno
Party member
Posts: 1686
Joined: Sun Oct 18, 2015 2:58 pm

Re: easier way to ignore DPI on android?

Post by pgimeno » Mon Jan 07, 2019 12:57 am

Thanks for the correction, I've edited my post accordingly. I understand, but most of the time I need to work in pixels, and I can handle DPI myself just fine with just love.window.getDPIScale and no automatic application.

I wish there would be a love.window.setDPIConversion(boolean) that would also be pushed/popped with love.graphics.push("all"), so that I can roughly do love.window.setDPIConversion(true) at the beginning of love.draw and set it to false at the end. That would significantly reduce the burden in my code in the form of calls to fromPixels/toPixels.

User avatar
slime
Solid Snayke
Posts: 2820
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

Re: easier way to ignore DPI on android?

Post by slime » Mon Jan 07, 2019 1:02 am

In what situations - aside from sending coordinates to shaders that use the pixel coordinate argument and operating on imagedata - do you need to operate on pixels instead of DPI-scaled units? (the PixelDimensions set of functions/methods are handy for those cases.)

User avatar
pgimeno
Party member
Posts: 1686
Joined: Sun Oct 18, 2015 2:58 pm

Re: easier way to ignore DPI on android?

Post by pgimeno » Mon Jan 07, 2019 4:16 pm

To round to the correct pixel, avoiding rounding issues, rather than using fromPixels(round(toPixels(value))) every time. To create canvases with the desired dimensions. To create and handle ImageData with the correct resolution. To create apps for myself, taking advantage of the resolution of my own device in order to display pixel-accurate stuff. PixelDimensions could perhaps help with ImageData; custom wrapper functions around LÖVE functions are the only way I can think of to help alleviate the extra burden of dealing with the rest.

User avatar
eouppdru
Prole
Posts: 10
Joined: Tue Feb 20, 2018 3:39 pm

Re: easier way to ignore DPI on android?

Post by eouppdru » Mon Jan 07, 2019 9:58 pm

slime wrote:
Mon Jan 07, 2019 1:02 am
In what situations - aside from sending coordinates to shaders that use the pixel coordinate argument and operating on imagedata - do you need to operate on pixels instead of DPI-scaled units? (the PixelDimensions set of functions/methods are handy for those cases.)
personally I think the DPI scaling thing is useful for a lot of cases, it's just forcing it enabled on android, for my use case, leads to confusion and unnecessary workarounds. even in places where the DPI scaling didn't cause my game to crash, it was making unnecessarily large canvases, slowing the game down. I didn't really know why it ran at ~32fps instead of 60fps, I just assumed that's how it ran on my phone hardware, it wasn't until I was trying to find out why setCanvas(1920,1080) was crashing trying to create a texture size of 6727 that I clawed some performance back with the above hack. all the games I've made with love are either pixel art titles or fixed resolution, so at least for my use cases I've never had a reason to use the DPI functionality. and I do prefer to not have rounding errors when trying to get clean integer scaling for pixel art.
PGP: 9D05F9CC4FB3DEA617ADCDDA355A9D99CBE1CC1B

User avatar
slime
Solid Snayke
Posts: 2820
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

Re: easier way to ignore DPI on android?

Post by slime » Tue Jan 08, 2019 1:26 am

pgimeno wrote:
Mon Jan 07, 2019 4:16 pm
To round to the correct pixel, avoiding rounding issues, rather than using fromPixels(round(toPixels(value))) every time.
I can see some potential use cases for pixel snapping, but also some use cases that are better solved different ways (for example extruding / padding sprite sheets.) What do you use pixel snapping for?
pgimeno wrote:
Mon Jan 07, 2019 4:16 pm
To create canvases with the desired dimensions.
This seems either too vague or an X->Y problem.

For a Canvas that's meant to be used outside of the context of the screen (for example as a texture atlas cache) you can set the dpi scale to 1 if you want, or you can set it to any other number (for example if your textures in the atlas are meant to be DPI-scaled @2x you'd set the dpi scale of that atlas canvas to 2.)

For screen-space / screen resolution-relative use, the majority of situations involve using the screen's native resolution (i.e. not hard-coding numbers), so your desired dimensions usually should be the screen's DPI-scaled size (for sizing/positioning to work best across devices), and in situations where the number of pixels is a performance issue the scale factor can be reduced.
pgimeno wrote:
Mon Jan 07, 2019 4:16 pm
To create apps for myself, taking advantage of the resolution of my own device in order to display pixel-accurate stuff.
The way I see it, I consider it much more preferable for LÖVE's APIs to make something you write work by default across all the different devices, than to make it work well only for the device you own by default – especially since most people don't have a variety of devices to test on and new phones with different DPI scale factors come out all the time.

I understand that updating from a codebase that never used the DPI scale factor to LÖVE 11 will probably cause issues. But for the most part I don't believe LÖVE's approach is incorrect for end-users of games made in LÖVE (especially as an end-user of both macOS and Windows, which are night and day in terms of DPI scaling correctness/brokenness in apps. I really don't want to make the same mistakes that Microsoft did with Windows).

eouppdru wrote:
Mon Jan 07, 2019 9:58 pm
I didn't really know why it ran at ~32fps instead of 60fps, I just assumed that's how it ran on my phone hardware, it wasn't until I was trying to find out why setCanvas(1920,1080) was crashing trying to create a texture size of 6727 that I clawed some performance back with the above hack. all the games I've made with love are either pixel art titles or fixed resolution, so at least for my use cases I've never had a reason to use the DPI functionality. and I do prefer to not have rounding errors when trying to get clean integer scaling for pixel art.
So you're hard-coding your render resolution? Documentation about the units of numbers in love.graphics APIs might be a bit lacking right now, and the fact that the dpi scale value is optional instead of required in newCanvas doesn't help this use-case, but that also doesn't seem very flexible in terms of performance across devices. I know some older / low-end phone GPUs really struggle with 1080p.

I don't consider dpiscale=1 to be a hack FWIW, it's the way you set the DPI scale for anything which has a DPI scale (aside from the screen, which is set by the device manufacturer and OS).

Post Reply

Who is online

Users browsing this forum: No registered users and 8 guests