[M3devel] strange problem w/new Image/ImageInit

Jay jay.krell at cornell.edu
Tue Aug 12 12:49:18 CEST 2008


Randy I don't think you need to add a way to use the unscaled data.
I think the fix is
a) go back to Image hardcoding 75
b) Have WinScreenType hardcode 96 or use GetDeviceCaps(LOGPIXELSX Y) -- same thing really.
And then see what happens.

Basically, the scale of pixmaps and the scale of screens has always been close to 1:1.
75:96, close enough.
Therefore, unscaled has been the norm.

Most GUI code uses GetDeviceCaps(LOGPIXELSX Y) I believe.
However, most code is not prepared to get back anything other than 96 from it.

Modula-3, at least for the pixmap code, was computing LOGPIXELSX and Y via a seemingly redundant equivalent way.
However, my believe is that LOGPIXELSX and Y is forced to lie, but the other route is not.
It seems an arbitrary discprecancy, but not beyond imagination.

By switching to the lying method, we will get back the nearly unscaled 75:96 behavior.

Vista adds a way for an application to declare that it is "high dpi aware", which then makes GetDeviceCaps(LOGPIXELX and Y) report the truth presumably. You can see, by the very existance of this ability to declare that you are high dpi aware -- to declare that your code is merely correct -- that most code is not correct.

What remains to be determined is why Modula-3 pixmaps behave "differently" than Modula-3 buttons, text, etc.

I also think there is a likely disconnect between painting and hit testing, but this is gross speculation.
I should fiddle with the numbers myself.

I will go ahead with a+b fairly soon.
I will verify the numbers computed in #b before and after.
I don't have any high dpi systems, so I expect the numbers to be roughly the same either way.
I think the only systems that will see a change are high dpi, and they will see an improvement.

Sorry for the back and forth regarding ImageInit -- a medium size change is going to be completely undone.

 - Jay

________________________________

Date: Tue, 12 Aug 2008 04:25:11 -0400
From: rcoleburn at scires.com
To: jay.krell at cornell.edu
CC: m3devel at elegosoft.com
Subject: Re: [M3devel] strange problem w/new Image/ImageInit



Jay:



For LOGPIXELS X & Y, I get 96 on the hi-res Dell M4300 system and also on my ThinkPad T60.



I've put together revised versions of Image.i3/m3 and my ScrollerVBTClass.m3.  The good news is that I've managed to get the scroll bar to look correct in both scaled and unscaled modes.



I've added a new procedure to Image.i3/m3 that will force subsequent calls to Scaled() to behave like Unscaled().  Using this, I can get the appearance I need on the hi-res monitor without resorting to changes in the original intent of the Image interface.  The advantage of this procedure is that it does not change the Image interface (except for addition of the procedure) and it therefore won't have any affect on pickles or anyone else's code.  Plus, it lets the programmer override use of Scaled() in all library modules without having to modify any source code.



Before I commit any of these changes, I want to do some more testing and to fix the problem with subwindows (ZChassisVBT) not being able to move.



Alas, my problem of the ZChassisVBTs not being able to move on the hi-res monitor persists with these changes, even though I left the xres/yres at 75.  Of course, these numbers are ignored for Unscaled images anyway.



I'm at a loss to explain this behavior.  Here is what I know based on testing:

1.  Using Scaled images and Image.Raw.xres/yres = 75.0, ZChassisVBT movement works on the hi-res monitor.

2.  Using Scaled images and Image.Raw.xres/yres set to 86.xxx or to 147.xxx, ZChassisVBT movement does not work on the hi-res 147.xxx dpi monitor, but it still works on my 86.xxx dpi monitor

3.  Using Unscaled images, ZChassisVBT movement does not work on the hi-res 147.xxx dpi monitor, but it still works on my 86.xxx dpi monitor



So, there seems to be something in the implementation somewhere of ZChassisVBT, or maybe ZMoveVBT, that doesn't like 147.xxx dpi monitors unless you scale all images assuming they were designed at 75 dpi.  At the 147 dpi, the 75 dpi pixmaps will be scaled by a factor of 2, which corresponds to what I am seeing on the screen.



I'm too sleepy to make any more progress for now.  If anyone has an idea on what to do next, please let me know.  I'm stumped at this point.



Regards,

Randy

>>> Jay  8/11/2008 3:52 PM>>>

Hm. Ok then, where does it get the screen resolution from?

Probably here?

WinScreenType.m3:

PROCEDURE InnerNew ((* IN-OUT *) res: T) =
  BEGIN
    WITH pix_hor = WinUser.GetSystemMetrics(WinUser.SM_CXSCREEN),
         pix_ver = WinUser.GetSystemMetrics(WinUser.SM_CYSCREEN),
         mm_hor  = GetDeviceCaps (WinGDI.HORZSIZE),
         mm_ver  = GetDeviceCaps (WinGDI.VERTSIZE) DO
      res.rootDom := Rect.FromSize(pix_hor, pix_ver);
      res.res[Axis.T.Hor] := FLOAT(pix_hor) / FLOAT(mm_hor);
      res.res[Axis.T.Ver] := FLOAT(pix_ver) / FLOAT(mm_ver);

ok.

Perhaps we should accept the numbers that Windows makes up instead?

GetDeviceCaps(LOGPIXELSX)
and GetDeviceCaps(LOGPIXELSY)

Please try that, in the WinScreenType.m3 code.
With removing ImageInit (or just have it hardcoded at 75).

This will most likely be 96 even on your high dpi system, unless you are on Vista
and tell the system you are high dpi aware.

I think there is disagreement in drawing vs. hit test as to where you are clicking.
Try making ImageInit always 75.
Try making the above convert from a hardcoded 96.
And then try GetDeviceCaps(LOGPIXELSX and Y) -- which I expect always returns 96 for you.
You can plug that into my dpi.c to see what it prints.

I think part of what is happening is that Modula-3 was very rare in doing the right thing for high dpi
monitors. But so much code is wrong that Windows has to counteract the wrongness,
which means Modula-3 needs to go along and do things wrong in order for the counteraction
to leave it doing the right thing also.
I'm not sure.
Oh, and presumably other places in Modula-3 are wrong, and the counteraction works for them.
That's a bit of a mystery -- drawing of pixmaps vs. drawing of everything else.

- Jay


________________________________

Date: Mon, 11 Aug 2008 15:23:17 -0400
From: rcoleburn at scires.com
To: jay.krell at cornell.edu
CC: m3devel at elegosoft.com; wagner at elegosoft.com
Subject: RE: strange problem w/new Image/ImageInit



Jay:



I have been experimenting quite a bit and I've come up with some "new old" information.



I say "new old" because, after spending the time to read some of the comments in the original code (before we modified it), I think I now have a better idea of what the designers intended and why I had/have a problem.



If you read carefully, the xres/yres fields in Image.Raw are supposed to represent the resolution at which the pixmap was originally DEVELOPED, not the resolution of the current screen.  It seems the designers went to great lengths to represent everything as screen-independent until it is actually rendered.



The Image interface gives 3 ways of dealing with pixmaps:  (1) unscaled, (2) scaled, and (3) scaled to "most appropriate".  The change you and I conspired actually changes this behavior to make #2 (scaled) work as #1 (unscaled).  (It probably also changes #3.)  This is the behavior I want for my current program, but it changes the intent of the original interface, so I'm afraid we are going to have to revert all those changes.



Digging deeper into Image.m3, I've discovered that it is smart-enough already to deduce the screen resolution.  If you look into the ApplyScaled1 procedure, you see that it converts the current screen resolution in millimeters to pixels in order to scale the pixmap.  The change we introduced, namely making Raw.xres/yres equal to the current screen resolution, effectively caused the Scaled procedure to do nothing since (ScreenDPI / ImageDPI) = 1.



The problem that brought all this on in the first place is that my GUI was looking bad on the 1920x1200 screen.  The reason I have discovered *now* is that FormsVBT apparently uses the #2 (scaled) version for pixmaps.  In the old code, the interface defaulted the developed resolution of the pixmaps to be 75 dpi.  At my 147+ dpi screen, the scaled implementation would effectively double the size of the pixmap when rendered on the screen in an effort to make the pixmap look the same size on the 147dpi screen that it appeared on a 75 dpi screen.



All of this to say that the changes to Image.i3/m3 need to be undone in order to get back the original intent of the developers.



Of course, once these changes are undone, my problem returns with the GUI looking bad on 1920x1200 at 147+ dpi.  So, how to solve it properly now requires more thought.



I need to do some more reading of the code I guess to see if there is a way already to cause FormsVBT to use unscaled for all pixmaps.  Otherwise, a quick fix would be to add a new procedure to the interface that would force use of the unscaled implementation.



Now, back to the problem of not being able to drag the subwindows, I'm still puzzled.  To test my "understanding" as related above, I went back to the original Image.i3/m3, but this time changed the Scaled procedure to effectively do the same thing as Unscaled.  The pixmaps render fine on the 1920x1200 monitor, but the subwindows still can't be dragged.  If I back out my change to Scaled (effectively, revert to the original Image.m3), the subwindows drag with ease on the 1920x1200 monitor, but of course the pixmaps look bad.  I can't explain this behavior yet.  Any ideas?



Regards,

Randy

>>> Jay  8/11/2008 2:41 PM>>>

MemoryBarrier ensures that all the reads and writes before it finish before any reads and writes after it.
Look at winnt.h or MSDN, as well the comment I put in explains it.
It probably has no effect, since our compiler is not aggressive.
What is confusing in these cases is the compiler and processor both need to be informed.
There is a concurrency issue and the barrier should make extra certain to solve it.

Multiple monitors are not considered.
Do you have them?

Randy, please experiment.
Change the code to return hard coded numbers -- like the old 75.
   Either without the globals, or initialize the globals.
And then add in the the various calls one at a time, ignoring their return values.

Furthermore, I guess you could just say:

    IF xres = 0 THEN Init() END;

and

    IF yres = 0 THEN Init() END;

and maybe change the globals to INTEGER.
Though REAL should be 32 bits and be written atomatically.

The idea is, even if the code does run multiple times concurrently, it should always return the same information.

Anyway, like I said, try various or every combination between the two and find
out which part triggers the difference, then we can think more about just that.

I might be able to get an expert friend to give me some help, later.

- Jay


________________________________

Date: Mon, 11 Aug 2008 12:15:40 -0400
From: rcoleburn at scires.com
To: jay.krell at cornell.edu
CC: wagner at elegosoft.com
Subject: RE: strange problem w/new Image/ImageInit



Jay:



I tested your change, but it has no effect on the problem I am having.  I also tried having the accessor functions just return a hardcoded number, but again, no effect on the problem.  This is real strange to me, because if I remove ImageInit and revert Image.i3/m3 back to the way it was before, the problem disappears.



Questions,

1.  What does the WinNT.MemoryBarrier() call do?

2.  What would happen if this code was run by multiple threads?  Are there any concurrency issues that need to be guarded?

3.  What would happen in the case of multiple monitors at different resolutions?



Regards,

Randy

>>> Jay  8/11/2008 6:46 AM>>>

Also try the change I just commited with ReleaseDC.

- Jay


> From: jayk123 at hotmail.com
> To: rcoleburn at scires.com
> CC: wagner at elegosoft.com
> Subject: RE: strange problem w/new Image/ImageInit
> Date: Mon, 11 Aug 2008 07:51:52 +0000
>
>
> Randy, this makes no sense to me.
> What happens if you just hardcode the numbers instead of computing them?
>
>
> - Jay
>
>
>
>
>
>
> ________________________________
>
>
>
> Date: Mon, 11 Aug 2008 02:55:56 -0400
> From: rcoleburn at scires.com
> To: jayk123 at hotmail.com
> CC: Olaf Wagner






More information about the M3devel mailing list