Question/feedback regarding Windows Hi DPI support and how it will affect applications
james.graham at oracle.com
Wed Feb 18 19:41:42 UTC 2015
Thanks for looking at this Werner!
On 2/18/2015 2:13 AM, Werner Lehmann wrote:
> Hi Jim,
> As to the question of integer vs float
> coordinates, there is a lot of snapToPixel stuff going on. And one of
> the reasons is to get crisp pixel-aligned lines. Snapping to logical
> coordinates could then snap to non-integer physical coordinates (if the
> scaling factor is 125% or somesuch). Which may be ok if hidpi makes up
> for it...
We have a number of "snap-to-pixel" cases within the FX code base for
the very reason you state. I'm also wondering how often those
calculations appear in application code?
Our intention is to (likely not in 8u60) provide a pixelScale attribute
on some class (Scene? Stage? etc) so that snap-to-pixel can do its
work. We may initially (and we must until we provide that API) only
support integer scales (so at least retina gets its 2x and super-hi
screens can get their 3x) since those would not "undo" the calculations
of snap-to-pixel. To embrace non-integer scales in rendering we would
need to expose that pixel scale and then the code that does pixel
snapping would need to use:
snappedCoord = Math.round(rawCoord * pixelScale) / pixelScale;
and all values would have to be floating point (the API tends to use
doubles for numbers).
Unfortunately, when you said:
> Some thoughts. Obviously it is less desirable to require every
> application to do their own scaling. I can't imagine that this
> would work on a larger basis.
That is the Windows model. They tell you how much you should scale your
own content, and then they ask you to tell them how many actual pixels
you want the window to be. You are then supposed to calculate a scaled
version of your rendering, figure out how many pixels it is, and give
that number to them. With FX, this could be as simple as providing a
scaling transform above the root (this is actually how we render the
scene) and letting everything else to its work. Nodes are supposed to
embrace scaling from their ancestry so technically our nodes should
already understand how to do this, but it may be a surprise when the
root node doesn't see IDENTITY in its incoming "localToParent"
transform. Would it?
If we went that way, then snap-to-pixel would work just fine as long as
code that performed that calculation actually checked its full scene
transform instead of just relying on "I know that my app code hasn't set
any transforms in any of my parents so this node must be still at a 1:1
In terms of what you said about "if HiDPI makes up for it"...
Actually retina sort of does this. The user can specify a number of
resolutions in the preferences CP, but they always only use 2x scaling
at the rendering level. The default is a scaling preference where the
screen appears exactly 2 pixels per logical scaled coordinate and there
is no pixel scaling. But, if you specify some other preference for
screen content, then they use pixel stretching to get from the 2x scale
that the application sees to the size on the screen requested by the
user's preference. I have to look at their algorithm, but I've always
been under the impression that it isn't simple linear interpolation.
Personally, I run my retina MBP screen, which has a native resolution of
2880x1800 and a "best for retina" scaling recommendation of "appears as
if it is 1440x900" - but I run it in "appears like 1680x1050" mode so
that I can fit more content on the screen. As a result, I am always
getting some pixel stretching in reality, but I don't really notice it.
This could be chalked up to "very Hi DPI screens cover a lot of pixel
sins", or it could be "Apple chose an incredibly good pixel scaling
filter". I need to look more into that. One thing to note is that this
only works well on retina screens so it would probably not be a good
technique for achieving the 125% scaling that many Windows screens
More information about the openjfx-dev