Graphics driver interface design

Discussions on more advanced topics such as monolithic vs micro-kernels, transactional memory models, and paging vs segmentation should go here. Use this forum to expand and improve the wiki!
Craze Frog
Member
Member
Posts: 368
Joined: Sun Sep 23, 2007 4:52 am

Post by Craze Frog »

Scaled bitmaps are NOT acceptable. Not ever. Just try it.

And from -1 to 1??? That will create precision problems even with resolutions as low as 20000 pixels wide!
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Post by Brendan »

Hi,
Craze Frog wrote:Scaled bitmaps are NOT acceptable. Not ever. Just try it.
I did - I took a screen shot of my desktop and zoomed in and out for a while, and also looked at a few high resolution photos. :)

With the "Picture and Fax Viewer" in Windows XP the screenshot looked fine at half the height & width (except the text) and also looked fine at up to four times the height & width. With "Paint" (which can only zoom in) it looked like crap at twice the height & width, but it uses a very simple algorithm.

I couldn't really get the high resolution photo to look bad - I couldn't zoom in enough, and it was higher resolution than my screen so zooming out just meant it wasn't scaled down as much.

Of course this is a bad way to test. What I'd want to do is have the same graphics data being scaled to the same area of the screen in different video modes. For example, scale a 640 * 480 bitmap down so that it takes up a quarter of the screen in 640 * 480 mode, and then scale the same 640 * 480 bitmap up so that it takes up a quarter of the screen in 1280 * 1024 mode.

Then you'd need to look at how common scaled bitmaps would be. Fonts would be variable size and not scaled bitmaps. Things like menus, title bars, status bars, window borders, etc would be done with rectangles and other primitives. Icons would be done with vector graphics, and things like company logos, etc could also be done with vector graphics.

What does this leave - high resolution digital photos (which scale very well), and some bitmaps in html pages?

Then there's the opposite problem - things that look wrong because the bitmaps aren't scaled. A 256 * 48 company logo at the top left of the screen might look right at 1024 * 768, but it'll look too big at 640 * 480 and too small at 2048 * 1536.

OS X Leopard supports resolution independence but the previous version (OS X Tiger) didn't. Windows Vista supports resolution independence, but the previous version (Windows XP) didn't. Is it a coincidence that the 2 largest operating systems developers have adopted resolution independence? I don't think so.


The thing is that not having resolution independance makes writing applications messy - each application needs to have code to handle all resolutions (and all colour depths?) itself. To fix the "256 * 48 company logo" example above you'd probably start with a 512 * 96 bitmap (for 2048 * 1536), and pre-scale it down to suit lower screen resolutions, and then have code to decide which image to use at run-time (and font sizes, etc). After doing this you'd end up with the same result that resolution independance would've given anyway.

Of course it's not just video - there's no reason why printer drivers couldn't rely on the same interface. This would make WYSIWYG easy (just send the same data to the video and the printer)...
Craze Frog wrote:And from -1 to 1??? That will create precision problems even with resolutions as low as 20000 pixels wide!
Nah - 64-bit floating point could easily handle 25000 pixels wide.. ;)


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
os64dev
Member
Member
Posts: 553
Joined: Sat Jan 27, 2007 3:21 pm
Location: Best, Netherlands

Post by os64dev »

And from -1 to 1??? That will create precision problems even with resolutions as low as 20000 pixels wide!
Nah - 64-bit floating point could easily handle 25000 pixels wide.. Wink
lol. Brendan you are really funny.
Author of COBOS
Craze Frog
Member
Member
Posts: 368
Joined: Sun Sep 23, 2007 4:52 am

Post by Craze Frog »

Sure, scaling to half the size or twice the size can look really good. But that's not what we are talking about.
Let's see how scaling a bitmap to 94% and 107% looks:
Image Image Image

That doesn't look to bad (only makes me want to throw up), the problem arises when you move the bitmap from close to one pixel boundary to another. Let's say you move the bitmap 1 virtual unit down. That could be 1.5 pixels. The scaling will then scale as correctly as possible, which in practice means that the bad pixels will be positioned at different places in the picture. In other words, if you move the scaled picture on screen, it will flicker. You can only prevent it by using an incorrect scaling algorithm that snaps the picture to the pixel grid. Essentially this means that if the bitmap is combined with vectors you would get overlapping or gaps even if the vector object and the bitmap is placed correctly next to each other with virtual coordinates.

Also, the scaling show above was done with high quality, way to slow for big pictures realtime. Try using 800x600 on a 1024x768 pixel display to see what I mean. Everything looks bad. Then try using 800x600 on a normal monitor. Everything looks just as good as 1024x768.

Of course 64-bit floats has enough precision, but do you really want to use twice the storage space necessary?
Craze Frog
Member
Member
Posts: 368
Joined: Sun Sep 23, 2007 4:52 am

Post by Craze Frog »

Besides, -1 to 1 will, while enough for one screen, not be sufficient for internal use by vector programs. If you have a vector drawing with small details that are visible on print, but only visible on screen if you zoom in, then the graphic needs to be stored at another scale than -1 to 1.

Basically that means that file coordinates need to be scaled to screen coordinates anyways, so why not scale them directly to pixels instead of scaling down to -1 to 1 and then up?
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

Besides, -1 to 1 will, while enough for one screen, not be sufficient for internal use by vector programs.
Why? You do know that the mantissa used in IEEE floating point (double and single) standard is between the range 0..1? With 32-bit floating point there are 23 bits for the mantissa, and in 64-bit there are 52 bits.

Assuming no usage of the exponent (which would be stupid for small numbers) that gives of 2**23=8 388 608 or 2**52=4.50359963 × 10^15 possible values between 0 and 1. Double that for -1..1.

Plus the algorithm used to scale your bitmap didn't look very good. I would assume an anti-aliasing-like technique would solve the "problem" stated.

The algorithm you're describing seems to be "nearest neighbour", which is piss-poor anyway - bilinear produces much nicer results (which is why scaling on photoshop looks much nicer than on M$ paint).
Craze Frog
Member
Member
Posts: 368
Joined: Sun Sep 23, 2007 4:52 am

Post by Craze Frog »

Bicubic scaling to 94%:
Image

Original:
Image

I don't think that is acceptable, but if you want to do realtime bicubic scaling then go ahead. I'm not stopping you, but the CPU will.
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

It looks acceptable to me, considering the original is horribly aliased.
User avatar
mystran
Member
Member
Posts: 670
Joined: Thu Mar 08, 2007 11:08 am

Post by mystran »

I thought I posted a message arguing that at high DPI settings proper resampling (thought not some cubic-interpolation crap) might actually look fine if the filter ringing becomes invisible (thanks to high DPI) but that the convolutions might not be feasible due to memory bandwidth constrains. I even tried to do some estimates and would expect 5 or 6 zero-crossings of a windowed sinc should be a decent starting point.

I was futher going to say, if we also want to rotate the image, we probably need true 2d resampling (instead of resampling in 2 dimensions separately) and if we need perspective transforms, then it gets messy 'cos we're dealing with non-linear sampling and I'd guess that comes down to transforming the filter kernel (which is sampled once per pixel so it's not cheap).

Then I was futher going to say one would lose some dynamic range (contrast in this case) in the process unless aliasing from non-linear clipping at saturation is accepted, since resampled data tends to overshoot the original range.

Anyway, obviously I must have discarded it all. Not sure why.

In any case, we're talking about billions of multiply-adds just to scale one fullscreen bitmap for a typical desktop monitor (at high DPI, say around 600 might be enough).
The real problem with goto is not with the control transfer, but with environments. Properly tail-recursive closures get both right.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Post by Brendan »

Hi,

To me, the picture with bicubic scaling looks better than the original (JamesM is right - check out the black diagonal lines on the roof in the original).
Craze Frog wrote:I don't think that is acceptable, but if you want to do realtime bicubic scaling then go ahead. I'm not stopping you, but the CPU will.
The funny thing about people's eyes is that they're much slower than they seem...

The video driver could do everything using fast low quality algorithms to begin with and cache the results, and then (over time, as the same data is re-used for later frames) replace the low quality cached data with data from slower higher quality algorithms. These higher quality algorithms could even be done by lower priority thread/s.

The idea is that (depending on a lot of things), the high quality graphics would be displayed before a person realises that the first few frames contained low quality graphics.

Of course it could also depend on things like the user's settings, the video driver, the video card, image sizes and timing.


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
mystran
Member
Member
Posts: 670
Joined: Thu Mar 08, 2007 11:08 am

Post by mystran »

JamesM wrote:
Besides, -1 to 1 will, while enough for one screen, not be sufficient for internal use by vector programs.
Why? You do know that the mantissa used in IEEE floating point (double and single) standard is between the range 0..1? With 32-bit floating point there are 23 bits for the mantissa, and in 64-bit there are 52 bits.
My thoughts exactly, though I'd opt for 0..1 range instead of -1..1 'cos then we can round to zero without having to deal with the rounding direction change near origin, though whether or not this actually matters depends on processing done. Naturally it's a trivial matter to map between coordinate basis, so it really doesn't matter if we'd use polar coordinates on driver level.
The real problem with goto is not with the control transfer, but with environments. Properly tail-recursive closures get both right.
User avatar
mystran
Member
Member
Posts: 670
Joined: Thu Mar 08, 2007 11:08 am

Post by mystran »

Brendan wrote: The video driver could do everything using fast low quality algorithms to begin with and cache the results, and then (over time, as the same data is re-used for later frames) replace the low quality cached data with data from slower higher quality algorithms. These higher quality algorithms could even be done by lower priority thread/s.
Some PDF viewers (say the one in Gnome, not sure if even Acrobat) do this, and trust me, it looks crap.
The real problem with goto is not with the control transfer, but with environments. Properly tail-recursive closures get both right.
User avatar
mystran
Member
Member
Posts: 670
Joined: Thu Mar 08, 2007 11:08 am

Post by mystran »

For good quality scaling, you should be able to scale an image to twice the size in 1% increments recursively (that is, scaling the resulting image again, then the new image again, and so on) and finally discard half the pixels. According to sampling theorem, since we aren't scaling down at any point (except at the final decimation) we shouldn't be losing information (except for the imperfections in the resampling), so you shouldn't be able to tell the difference with the original and the result.

[edit] Obviously, this can't be done in 8-bit though, since the quantization noise would get awful.. but let's not get into that.
The real problem with goto is not with the control transfer, but with environments. Properly tail-recursive closures get both right.
Craze Frog
Member
Member
Posts: 368
Joined: Sun Sep 23, 2007 4:52 am

Post by Craze Frog »

Brendan wrote:Hi,

To me, the picture with bicubic scaling looks better than the original (JamesM is right - check out the black diagonal lines on the roof in the original).
It's supposed to look like that. If the original picture looks like the scaled version then the displayed version will be scaled again and not look like you want it to look anyways...
For good quality scaling, you should be able to scale an image to twice the size in 1% increments recursively (that is, scaling the resulting image again, then the new image again, and so on) and finally discard half the pixels.
The problem is that no such way of scaling exists apart from nearest neighbour, which is THE most ugly scaling method ever. Feel free to invent it.

Edit:
The whole point of device independence is that it should look the same everywhere. By scaling bitmaps it will look more different everywhere than it does now.
User avatar
os64dev
Member
Member
Posts: 553
Joined: Sat Jan 27, 2007 3:21 pm
Location: Best, Netherlands

Post by os64dev »

Unless bitmap scaling is done with a larger bitmap. a 64x64 bitmap displayed has a 256x256 source. You see this a lot in games. textures have a larger resolution than required because downscale is acceptable >2 upscale not.
Author of COBOS
Post Reply