Re: /boot/loader graphics support & extensibility



Marcel Moolenaar wrote:
On Feb 22, 2008, at 12:39 PM, Oliver Fromme wrote:
Yes, that'll work well for putting characters on the
screen. But I don't think it is suitable for generic
graphics operations, even (and especially) for drawing
single pixels.

True. What do you envision? How generic do you think
we should make it?

For me the difference between an abstraction solely
based on bitblt and an abstraction that includes a
couple more primitives is minimal. The key aspect is
that we should not have to duplicate 1000 lines of
code, of which less than 10% deals with the hardware.
This, for example, is a problem with syscons and the
keyboard- and video switch interfaces. The keyboard
switch interface alone has 18 functions???? That's a
bad abstraction, nothing else.

Yes, I'm aware of the problem.

All the screenshots that I've made so far use only three
functions: Displaying PCX images, printing characters,
and drawing filled rectangles (e.g. to clear the screen
or parts of it). That's not really much. I'm inclined
to implement specialized versions of these functions for
each of the bitmap formats, which is currently just two:
4bit planar (16 colors) and 8bit linear (256 colors).

Currently I also have implemented several other functions
such as line drawing, filled triangles, circles etc.,
but I'm not sure if it's worth keeping them. I'll have
to think about it a bit more.

At the moment I don't plan to support modes with more
than 8 bits (but of course if someone else wants to do
it, that would be fine with me). Typically you can
dither truecolor images to 8 bit at very good quality
(with gimp, imagemagick, netpbm, whatever), so there's
no need for hicolor or truecolor modes. It should also
be pointed out that there are a lot of variants of
bitmap formats, and different graphics hardware supports
different subset of these: 15 bit hicolor (5-5-5),
16 bit hicolor (5-6-5), 24 bit truecolor, 32 bit true-
color, and each of these with different component orders
(RGB or BGR), resulting in at least eight different
formats. You have to support them all, which is somewhat
complicated (although not difficult).

The situation might be completely different on non-VGA
hardware, of course.

I'm sorry, I should have been clearer, that gfx_rect()
function draws a filled rectangle.

I see. In that case it's a single bitblt operation :-)

But how would it work in reality? I guess you have
something like this in mind; please correct me if I'm
wrong:

- The Forth code calls the rectangle function.
- The hardware-independend gfx_rect function allocates
a sufficiently large temporary memory buffer, then
draws the rectangle into it.
- Then it calls the hardware-dependent bitblt function,
which copies the contents from the temporary buffer
to the graphics frame buffer.

There are two problems that I can see with that approach
(not mentioning performance):

First, what will be the bitmap format of the temporary
memory buffer? The first possibility would be to make
it the same as the graphics frame buffer, so the bitblt
function would just have to shovel bits (except that it
might have to shift bits if the buffer's contents don't
happen to have the right alignment already). But then
we need multiple rectangle functions, one for every
bitmap format supported, so the abstraction doesn't
really buy us much.

The second possibility is to make the temporary buffer
independent from the bitmap format of the graphics mode,
i.e. use a fixed format. In order to be able to support
truecolor modes, that fixed format would have to be a
truecolor format, too. So then the rectangle function
would draw a 24bit or 32bit truecolor rectangle (even
if the graphics mode is only 4 bit), and the bitblt
function would have to convert it back to the actual
bitmap format of the graphics mode, possibly having to
do palette lookups. That is horribly inefficient, and
there's no easy way for optimizations.

The second problem is that some graphics functions need
to work with masks. For example, the function that
prints a character is supposed to overlay the background,
i.e. _not_ clear the rectangular area that the character
occupies (this is to allow things such as ligatures,
accent characters, shadow, bold and outline effects etc).
So the bitblt function would have to take two input
bitmaps (one being the pixel source and one being the
mask) and perform the neccessary logical operations, in
addition to the shifting (which also applies to the mask),
format conversion, palette lookup, ...

Sure, all of that could be implemented, but I fear that
it would be much more complicated and bloated in the end.

The current rectangle function for 4bit planar modes is
about 15 lines of C code (not counting comments). The
PCX display function is basically a straight-forward
loop of about 20 lines of C code. That's not really a
huge amount. And I have to confess that I don't think
it's too bad that I'll have to write another 15 lines
for an 8bit rectangle function, and another 20 lines for
the 8bit PCX display loop. Probably less, because the
8bit linear modes are much simpler than the 4bit planar
modes.

On the other hand, writing bitblt functions that do all
of the things that I explained above would cost several
hundred lines of code. And in the end it would be slower
by an order of magnitude.

These are just my thoughts. I certainly don't want to
dismiss the idea of bitblt completely, but I think the
disadvantages outweigh the benefits in this case.

Agreed. Be aware of making the mistake to separate and
distinguish between variations of a single operation at
too high a level.

Yes, I know what you mean. I try to keep it in mind.

For example: it's much more costly to
separate vertical line drawing from horizontal line
drawing from any other kind of line drawing at the MI
layer, than it is at the hardware level. The hardware
level needs to check the parameters anyway and unless
there's hardware acceleration it'll perform separate
code paths most of the time. The upshot of a single line
drawing primitive is that you don't have to worry about
the coordinates and which API function you must call.
This is important when the coordinates are parameters
to some function and you'll find yourself coding like:

if (isvertical(x1,y1,x2,y2))
drawline_vertical(...)
elif (ishorizontal(x1,y1,x2,y2))
drawline_horizontal(...)
else
drawline_generic(...)

With hardware acceleration you may not have to care at
all and when you need to draw the line in software,
you need to test the coordinates anyway and split the
work based on angle even. In that case you also split
horizontal and vertical.

I do have a generic line drawing function (using the
well-known Bresenham algorithm) as well as specialized
functions for vertical and horizontal lines. However,
there is no code like the one above.

The hline and vline functions are rather intended to be
used for cases where the Forth programmer knows in advance
that the line will be horizontal or vertical, e.g. when
underlining a word, drawing a frame and similar things.

For random lines the generic line function should be used,
even if the line happens to be vertical or horizontal.
It's not worth making a distinction for that case.

Anyway: that's enough out of me. I think what you're
doing is great and I can't wait to see it realized...

Thank you very much for taking part in this discussion,
it helps a lot. I even learned a little bit about EFI. :)

My next steps:
- Find a spare box and install 8-current (so far I'm
using RELENG_7 for development and testing).
- Continue cleaning up and committing to Perforce.
- If I have something that works, I'll prepare diffs for
review and a tarball for people to test and play.

Beware, I'm not working full-time of this, so it might
take a little while (I have a full-time job, a wife,
other hobbies, so my time is a bit limited).

Best regards
Oliver

--
Oliver Fromme, secnetix GmbH & Co. KG, Marktplatz 29, 85567 Grafing b. M.
Handelsregister: Registergericht Muenchen, HRA 74606, Geschäftsfuehrung:
secnetix Verwaltungsgesellsch. mbH, Handelsregister: Registergericht Mün-
chen, HRB 125758, Geschäftsführer: Maik Bachmann, Olaf Erb, Ralf Gebhart

FreeBSD-Dienstleistungen, -Produkte und mehr: http://www.secnetix.de/bsd

"With sufficient thrust, pigs fly just fine. However, this
is not necessarily a good idea. It is hard to be sure where
they are going to land, and it could be dangerous sitting
under them as they fly overhead." -- RFC 1925
_______________________________________________
freebsd-hackers@xxxxxxxxxxx mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@xxxxxxxxxxx"



Relevant Pages

  • Re: How do I turn off write combining programatically?
    ... I should not bother with GDI+ and try the DirectX drawing stuff. ... I just do something like this in paint event ... ... Any exception thrown while drawing with a Graphics will tend to ... >> screensaver, and my posted sample in sheer disgust and destroy all source ...
    (microsoft.public.dotnet.framework.drawing)
  • Re: Text in text boxes: vertical centre
    ... In PowerPoint all you need to do is select the text box, ... > drawing canvas is hidden from the user.) ... Irrespective of whether text boxes and other graphic objects are in a hidden ... > Hit the Help and read up on Graphics. ...
    (microsoft.public.mac.office.word)
  • Re: image maps - word 2007
    ... In Word it's a bit of trying to figure out where 'Escher 2', the new graphics ... Select a WMF file and insert it in the drawing ... Right click on the inserted graphic and choose Edit Picture, ... visible until you click on a segment. ...
    (microsoft.public.word.drawing.graphics)
  • Re: Is the Linux Graphics Stack Backwards?
    ... >GDI32.DLL only does drawing and it thunks down to a graphics driver ... >USER32.DLL handles all the input and also also the windowing. ... >windowing and input is completely abstracted from drawing. ... There are dozens of graphics systems for Linux besides X, ...
    (comp.os.linux.x)

Quantcast